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

Loading...

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

Deployment not found

); } const ownerName = deployment.owner?.first_name || deployment.owner?.last_name ? `${deployment.owner.first_name || ''} ${deployment.owner.last_name || ''}`.trim() : deployment.owner?.email || 'No owner'; return ( {/* Header */}

Deployment #{deployment.deployment_id}

{deployment.address && (

{deployment.address}

)}
{/* Info Cards */}
{/* Deployment Info */}

Deployment Information

{/* Owner Info */}

Owner

{deployment.owner ? ( <>
) : (

No owner assigned

)}
{/* Stats */}
{/* Devices */} {deployment.devices?.length > 0 && (

Devices ({deployment.devices.length})

{deployment.devices.map((device) => ( ))}
)} {/* Users with Access */} {deployment.users_with_access?.length > 0 && (

Users with Access

User Email Role Granted
{deployment.users_with_access.map((access, idx) => (
{access.user?.first_name || access.user?.last_name ? `${access.user.first_name || ''} ${access.user.last_name || ''}`.trim() : 'Unnamed'} {access.user?.email || '—'} {access.granted_at ? new Date(access.granted_at).toLocaleDateString() : '—'}
))}
)} {/* Events */} {deployment.events?.length > 0 && (

Recent Events

Type Description Device Time
{deployment.events.map((event, idx) => (
{event.description || '—'} {event.device_id || '—'} {new Date(event.created_at).toLocaleString()}
))}
)}
); } function InfoRow({ label, value }) { return (
{label} {value}
); } function StatCard({ icon, label, value, color }) { return (
{icon}
{value}
{label}
); } function DeviceCard({ device }) { const isOnline = device.status === 'online' || device.status === 'active'; return (
{device.device_id}
{device.device_type || 'Unknown Type'}
Status: {device.status || 'unknown'} {device.last_seen_at && ( Last seen: {new Date(device.last_seen_at).toLocaleString()} )}
); } function StatusBadge({ status }) { const colors = { active: '#10B981', installed: '#059669', pending: '#F59E0B', inactive: '#6B7280', }; const color = colors[status] || '#6B7280'; return ( {status || 'unknown'} ); } function RoleBadge({ role }) { const colors = { owner: '#EF4444', caretaker: '#6366F1', installer: '#8B5CF6', }; const color = colors[role] || '#6B7280'; return ( {role} ); } function EventTypeBadge({ type }) { const colors = { alert: '#EF4444', motion: '#F59E0B', door: '#3B82F6', system: '#6B7280', }; const color = colors[type] || '#6B7280'; return ( {type || 'event'} ); } 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, }, address: { color: 'var(--text-secondary)', marginTop: '8px', fontSize: '15px', }, 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', }, statsRow: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: '16px', marginTop: '24px', }, statCard: { background: 'white', borderRadius: '12px', padding: '20px', display: 'flex', alignItems: 'center', gap: '16px', }, statIcon: { fontSize: '32px', }, statValue: { fontSize: '28px', fontWeight: '700', }, statLabel: { fontSize: '13px', color: 'var(--text-muted)', }, section: { marginTop: '32px', }, sectionTitle: { fontSize: '18px', fontWeight: '600', marginBottom: '16px', }, deviceGrid: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px', }, deviceCard: { background: 'white', borderRadius: '12px', padding: '16px', }, deviceHeader: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px', }, deviceId: { fontFamily: 'monospace', fontSize: '14px', fontWeight: '600', }, statusDot: { width: '10px', height: '10px', borderRadius: '50%', }, deviceType: { fontSize: '15px', fontWeight: '500', marginBottom: '8px', }, deviceMeta: { fontSize: '12px', color: 'var(--text-muted)', display: 'flex', flexDirection: 'column', gap: '4px', }, table: { background: 'white', borderRadius: '12px', overflow: 'hidden', }, tableHeader: { display: 'grid', gridTemplateColumns: '1.5fr 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: '1.5fr 2fr 1fr 1fr', gap: '16px', padding: '14px 20px', borderBottom: '1px solid var(--border)', alignItems: 'center', fontSize: '14px', }, userName: { fontWeight: '500', }, email: { color: 'var(--text-secondary)', }, mono: { fontFamily: 'monospace', fontSize: '13px', }, muted: { color: 'var(--text-muted)', fontSize: '13px', }, viewBtn: { padding: '8px 16px', background: 'var(--primary)', color: 'white', border: 'none', borderRadius: '8px', fontSize: '13px', cursor: 'pointer', }, };