'use client'; import { useEffect, useState } from 'react'; import { useParams, useRouter } from 'next/navigation'; import AdminLayout from '../../../components/AdminLayout'; import { getUser } from '../../../lib/api'; export default function UserDetailPage() { const { id } = useParams(); const router = useRouter(); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { if (id) loadUser(); }, [id]); const loadUser = async () => { try { const data = await getUser(id); setUser(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; if (loading) { return (

Loading...

); } if (error || !user) { return (

User not found

); } const userName = user.first_name || user.last_name ? `${user.first_name || ''} ${user.last_name || ''}`.trim() : 'Unnamed User'; return ( {/* Header */}

{userName}

{user.role === 'admin' && } {user.is_beneficiary && } {user.is_caretaker && }

{user.email}

{/* Info Cards */}
{/* Basic Info */}

Basic Information

{/* Stats */}

Statistics

{/* Relationships */} {(user.watched_by?.length > 0 || user.watches?.length > 0) && (

Relationships

{user.watched_by?.length > 0 && (

Watched by ({user.watched_by.length})

{user.watched_by.map((rel, idx) => (
{rel.user?.first_name || rel.user?.last_name ? `${rel.user.first_name || ''} ${rel.user.last_name || ''}`.trim() : rel.user?.email || 'Unknown'}
{rel.user?.email}
))}
)} {user.watches?.length > 0 && (

Watches ({user.watches.length})

{user.watches.map((rel, idx) => (
{rel.user?.first_name || rel.user?.last_name ? `${rel.user.first_name || ''} ${rel.user.last_name || ''}`.trim() : rel.user?.email || 'Unknown'}
{rel.user?.email}
))}
)}
)} {/* Deployments */} {user.deployments?.length > 0 && (

Deployments

ID Address Status Actions
{user.deployments.map((dep) => (
#{dep.deployment_id} {dep.address || '—'}
))}
)} {/* Devices */} {user.devices?.length > 0 && (

Devices

Device ID Type Status Last Seen
{user.devices.map((dev) => (
{dev.device_id} {dev.device_type || '—'} {dev.last_seen_at ? new Date(dev.last_seen_at).toLocaleString() : '—'}
))}
)} {/* Orders */} {user.orders?.length > 0 && (

Orders

Order # Status Amount Date
{user.orders.map((order) => (
{order.order_number} ${((order.total_amount || 0) / 100).toFixed(2)} {new Date(order.created_at).toLocaleDateString()}
))}
)} {/* Subscriptions */} {user.subscriptions?.length > 0 && (

Subscriptions

Plan Status Started Expires
{user.subscriptions.map((sub) => (
{sub.plan} {new Date(sub.created_at).toLocaleDateString()} {sub.expires_at ? new Date(sub.expires_at).toLocaleDateString() : '—'}
))}
)}
); } function InfoRow({ label, value }) { return (
{label} {value}
); } function StatBox({ label, value, color }) { return (
{value}
{label}
); } function Badge({ text, color }) { return ( {text} ); } function RoleBadge({ role }) { const colors = { owner: '#EF4444', caretaker: '#6366F1', installer: '#8B5CF6', }; const color = colors[role] || '#6B7280'; return ( {role} ); } function StatusBadge({ status }) { const colors = { active: '#10B981', paid: '#3B82F6', shipped: '#8B5CF6', delivered: '#10B981', installed: '#059669', canceled: '#EF4444', pending: '#F59E0B', }; const color = colors[status] || '#6B7280'; return ( {status || 'unknown'} ); } const styles = { loading: { textAlign: 'center', padding: '48px', color: 'var(--text-muted)', }, error: { textAlign: 'center', padding: '48px', }, backBtn: { marginTop: '16px', padding: '10px 20px', background: 'var(--primary)', color: 'white', border: 'none', borderRadius: '8px', cursor: 'pointer', }, header: { marginBottom: '24px', }, backLink: { background: 'none', border: 'none', color: 'var(--primary)', fontSize: '14px', cursor: 'pointer', padding: 0, marginBottom: '12px', display: 'block', }, titleRow: { display: 'flex', alignItems: 'center', gap: '16px', flexWrap: 'wrap', }, title: { fontSize: '28px', fontWeight: '700', margin: 0, }, badges: { display: 'flex', gap: '8px', }, email: { color: 'var(--text-secondary)', marginTop: '4px', }, grid: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: '20px', }, card: { background: 'white', borderRadius: '12px', padding: '20px', }, cardTitle: { fontSize: '14px', fontWeight: '600', marginBottom: '16px', color: 'var(--text-secondary)', }, infoRow: { display: 'flex', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid var(--border)', }, infoLabel: { color: 'var(--text-muted)', fontSize: '14px', }, infoValue: { fontWeight: '500', fontSize: '14px', }, statsGrid: { display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '16px', }, statBox: { textAlign: 'center', padding: '12px', background: 'var(--surface)', borderRadius: '8px', }, statValue: { fontSize: '24px', fontWeight: '700', }, statLabel: { fontSize: '12px', color: 'var(--text-muted)', marginTop: '4px', }, section: { marginTop: '32px', }, sectionTitle: { fontSize: '18px', fontWeight: '600', marginBottom: '16px', }, relationList: { display: 'flex', flexDirection: 'column', gap: '12px', }, relationItem: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px', background: 'var(--surface)', borderRadius: '8px', }, relationName: { fontWeight: '500', fontSize: '14px', }, relationEmail: { fontSize: '13px', color: 'var(--text-muted)', }, table: { background: 'white', borderRadius: '12px', overflow: 'hidden', }, tableHeader: { display: 'grid', gridTemplateColumns: '1fr 2fr 1fr 1fr', gap: '16px', padding: '14px 20px', background: 'var(--surface)', fontSize: '12px', fontWeight: '600', color: 'var(--text-muted)', textTransform: 'uppercase', }, tableRow: { display: 'grid', gridTemplateColumns: '1fr 2fr 1fr 1fr', gap: '16px', padding: '14px 20px', borderBottom: '1px solid var(--border)', alignItems: 'center', fontSize: '14px', }, mono: { fontFamily: 'monospace', fontSize: '13px', }, muted: { color: 'var(--text-muted)', fontSize: '13px', }, viewBtn: { padding: '6px 12px', background: 'var(--primary)', color: 'white', border: 'none', borderRadius: '6px', fontSize: '12px', cursor: 'pointer', }, };