import { useState, useEffect } from 'react' import { useParams, useNavigate } from 'react-router-dom' import toast from 'react-hot-toast' import client from '../api/client' import LicenseStatus from '../components/LicenseStatus' import ConfirmModal from '../components/ConfirmModal' function fmtDt(dt) { if (!dt) return '—' return new Date(dt).toLocaleString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', }) } function fmtDate(dt) { if (!dt) return '' return new Date(dt).toISOString().slice(0, 10) } export default function SiteDetailPage() { const { siteId } = useParams() const navigate = useNavigate() const [site, setSite] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [modal, setModal] = useState(null) // 'lock' | 'unlock' | 'delete' | 'license' const [lockReason, setLockReason] = useState('') const [newExpiry, setNewExpiry] = useState('') const [acting, setActing] = useState(false) useEffect(() => { async function load() { try { const { data } = await client.get(`/api/sites/${siteId}`) setSite(data) setNewExpiry(fmtDate(data.license_expires_at)) } catch { setError('Site not found') } finally { setLoading(false) } } load() }, [siteId]) async function doLock() { if (!lockReason.trim()) return setActing(true) try { const { data } = await client.post(`/api/sites/${siteId}/lock`, { reason: lockReason.trim() }) setSite(data) setModal(null) setLockReason('') toast.success('Site locked') } catch (e) { toast.error(e.response?.data?.detail || 'Failed to lock site') } finally { setActing(false) } } async function doUnlock() { setActing(true) try { const { data } = await client.post(`/api/sites/${siteId}/unlock`) setSite(data) setModal(null) toast.success('Site unlocked') } catch (e) { toast.error(e.response?.data?.detail || 'Failed to unlock site') } finally { setActing(false) } } async function doExtendLicense() { if (!newExpiry) return setActing(true) try { const { data } = await client.put(`/api/sites/${siteId}`, { license_expires_at: new Date(newExpiry).toISOString(), }) setSite(data) setModal(null) toast.success('License updated') } catch (e) { toast.error(e.response?.data?.detail || 'Failed to update license') } finally { setActing(false) } } async function doDelete() { setActing(true) try { await client.delete(`/api/sites/${siteId}`) toast.success('Site deregistered') navigate('/sites', { replace: true }) } catch (e) { toast.error(e.response?.data?.detail || 'Failed to delete site') setActing(false) } } if (loading) return
{site.owner_name} · {site.contact_email}
{site.lock_reason || 'No reason given'}