diff --git a/app/page.tsx b/app/page.tsx index 4501e98..caa5ee6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,12 +5,13 @@ import Link from 'next/link' import { motion } from 'framer-motion' import { useAuth } from '@/lib/auth/context' import { initiateOAuthFlow, initiateSignupFlow } from '@/lib/api/oauth' -import { listSites, deleteSite, type Site } from '@/lib/api/sites' +import { listSites, listDeletedSites, restoreSite, permanentDeleteSite, type Site } from '@/lib/api/sites' import { getStats } from '@/lib/api/stats' import type { Stats } from '@/lib/api/stats' import { getSubscription, type SubscriptionDetails } from '@/lib/api/billing' import { LoadingOverlay } from '@ciphera-net/ui' import SiteList from '@/components/sites/SiteList' +import DeleteSiteModal from '@/components/sites/DeleteSiteModal' import { Button } from '@ciphera-net/ui' import Image from 'next/image' import { BarChartIcon, LockIcon, ZapIcon, CheckCircleIcon, XIcon, GlobeIcon } from '@ciphera-net/ui' @@ -118,6 +119,8 @@ export default function HomePage() { const [subscription, setSubscription] = useState(null) const [subscriptionLoading, setSubscriptionLoading] = useState(false) const [showFinishSetupBanner, setShowFinishSetupBanner] = useState(true) + const [deleteModalSite, setDeleteModalSite] = useState(null) + const [deletedSites, setDeletedSites] = useState([]) useEffect(() => { if (user?.org_id) { @@ -178,6 +181,12 @@ export default function HomePage() { setSitesLoading(true) const data = await listSites() setSites(Array.isArray(data) ? data : []) + try { + const deleted = await listDeletedSites() + setDeletedSites(deleted) + } catch { + setDeletedSites([]) + } } catch (error: unknown) { toast.error(getAuthErrorMessage(error) || 'Failed to load your sites') setSites([]) @@ -198,14 +207,26 @@ export default function HomePage() { } } - const handleDelete = async (id: string) => { - if (!confirm('Are you sure you want to delete this site? This action cannot be undone.')) { - return - } + const handleDelete = (id: string) => { + const site = sites.find((s) => s.id === id) + if (site) setDeleteModalSite(site) + } + const handleRestore = async (id: string) => { try { - await deleteSite(id) - toast.success('Site deleted successfully') + await restoreSite(id) + toast.success('Site restored successfully') + loadSites() + } catch (error: unknown) { + toast.error(getAuthErrorMessage(error) || 'Failed to restore site') + } + } + + const handlePermanentDelete = async (id: string) => { + if (!confirm('Permanently delete this site and all data? This cannot be undone.')) return + try { + await permanentDeleteSite(id) + toast.success('Site permanently deleted') loadSites() } catch (error: unknown) { toast.error(getAuthErrorMessage(error) || 'Failed to delete site') @@ -512,6 +533,51 @@ export default function HomePage() { {(sitesLoading || sites.length > 0) && ( )} + + setDeleteModalSite(null)} + onDeleted={loadSites} + siteName={deleteModalSite?.name || ''} + siteDomain={deleteModalSite?.domain || ''} + siteId={deleteModalSite?.id || ''} + /> + + {deletedSites.length > 0 && ( +
+

Scheduled for Deletion

+
+ {deletedSites.map((site) => { + const purgeAt = site.deleted_at ? new Date(new Date(site.deleted_at).getTime() + 7 * 24 * 60 * 60 * 1000) : null + const daysLeft = purgeAt ? Math.max(0, Math.ceil((purgeAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24))) : 0 + + return ( +
+
+ {site.name} + {site.domain} + Deleting in {daysLeft} day{daysLeft !== 1 ? 's' : ''} +
+
+ + +
+
+ ) + })} +
+
+ )} ) }