'use client'; import React, { useEffect, useState, useCallback } from 'react'; import { useParams, useRouter } from 'next/navigation'; import Image from 'next/image'; import AdminLayout from '../../../components/AdminLayout'; import { Card, CardContent, LoadingSpinner, ErrorMessage, Button, Tabs, TabsList, TabsTrigger, TabsContent, StatusBadge, SensorStatusBadge, } from '../../../components/ui'; import { getBeneficiary, getDevices } from '../../../lib/api'; interface Beneficiary { id: number; first_name: string | null; last_name: string | null; email: string; phone: string | null; address_street: string | null; address_city: string | null; address_country: string | null; created_at: string; updated_at: string; subscription_status?: string; subscription_plan?: string; devices_count?: number; avatar_url?: string | null; } interface Device { id: number; name: string; mac_address: string; device_type: string; status: 'online' | 'offline' | 'warning' | 'error'; last_seen: string | null; firmware_version: string | null; } interface SensorData { motion_detected: boolean; last_motion: string | null; door_status: 'open' | 'closed' | null; temperature: number | null; humidity: number | null; } export default function BeneficiaryDetailPage() { const params = useParams(); const router = useRouter(); const beneficiaryId = params?.id as string; const [beneficiary, setBeneficiary] = useState(null); const [devices, setDevices] = useState([]); const [sensorData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const loadBeneficiaryData = useCallback(async () => { if (!beneficiaryId) return; setLoading(true); setError(null); try { const [beneficiaryData, devicesData] = await Promise.all([ getBeneficiary(beneficiaryId), getDevices(beneficiaryId).catch(() => ({ devices: [] })), ]); setBeneficiary(beneficiaryData.beneficiary || beneficiaryData); setDevices(devicesData.devices || []); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load beneficiary'); } finally { setLoading(false); } }, [beneficiaryId]); useEffect(() => { loadBeneficiaryData(); }, [loadBeneficiaryData]); const getDisplayName = (ben: Beneficiary) => { const name = [ben.first_name, ben.last_name].filter(Boolean).join(' '); return name || 'Unknown'; }; const getInitials = (ben: Beneficiary) => { const first = ben.first_name?.[0] || ''; const last = ben.last_name?.[0] || ''; return (first + last).toUpperCase() || '?'; }; const getAddress = (ben: Beneficiary) => { return [ben.address_street, ben.address_city, ben.address_country] .filter(Boolean) .join(', '); }; const formatDate = (dateString: string | null) => { if (!dateString) return 'N/A'; return new Date(dateString).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', }); }; const formatDateTime = (dateString: string | null) => { if (!dateString) return 'Never'; return new Date(dateString).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); }; if (loading) { return ( ); } if (error || !beneficiary) { return (
); } return ( {/* Header with back button */}
{/* Beneficiary Info Header */}
{/* Avatar */} {beneficiary.avatar_url ? ( {getDisplayName(beneficiary)} ) : (
{getInitials(beneficiary)}
)}

{getDisplayName(beneficiary)}

{beneficiary.email}

{beneficiary.phone && (

{beneficiary.phone}

)}
{/* Status Badge */}
{beneficiary.subscription_status && ( {beneficiary.subscription_status} )} 0 && devices.some(d => d.status === 'online') ? 'online' : 'offline'} />
{/* Tabs */} Overview Sensors ({devices.length}) Activity History {/* Overview Tab */}
{/* Personal Information */}

Personal Information

{/* Subscription Info */}

Subscription

{beneficiary.subscription_status || 'Inactive'} } />
{/* Live Sensor Data */}

Live Sensor Data

{sensorData ? (
) : (

No sensor data available

{devices.length === 0 ? 'Connect sensors to see live data' : 'Waiting for sensor data...'}

)}
{/* Sensors Tab */} {devices.length === 0 ? (

No Sensors Connected

This beneficiary doesn't have any sensors connected yet.

) : (
{devices.map((device) => (

{device.name}

{device.device_type}

MAC Address {device.mac_address}
Last Seen {formatDateTime(device.last_seen)}
{device.firmware_version && (
Firmware {device.firmware_version}
)}
))}
)}
{/* Activity History Tab */}

Activity History

Activity history will be available in a future update.

); } // Helper Components interface InfoRowProps { label: string; value: React.ReactNode; } function InfoRow({ label, value }: InfoRowProps) { return (
{label} {typeof value === 'string' ? value : value}
); } interface SensorCardProps { icon: string; label: string; value: string; subValue?: string; status?: 'success' | 'warning' | 'default'; } function SensorCard({ icon, label, value, subValue, status = 'default' }: SensorCardProps) { const statusColors = { success: 'bg-green-50 border-green-200', warning: 'bg-yellow-50 border-yellow-200', default: 'bg-gray-50 border-gray-200', }; return (
{icon}
{label}
{value}
{subValue &&
{subValue}
}
); } interface DeviceIconProps { type: string; } function DeviceIcon({ type }: DeviceIconProps) { const icons: Record = { motion: '🚶', door: '🚪', temperature: '🌡️', humidity: '💧', camera: '📷', default: '📡', }; return {icons[type.toLowerCase()] || icons.default}; }