From 663abc9b9e5d294364fcc9a3c50313b138c8ec5a Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Sat, 28 Mar 2026 19:42:42 +0100 Subject: [PATCH] feat: DashboardShell for all auth pages, site settings modal from home - layout-content wraps integrations/pricing in DashboardShell - GlassTopBar derives title per page (Integrations, Pricing, etc.) - Site card gear icon opens settings modal with siteId context - Removed delete button from site cards (accessible via site settings) - Extended InitialTab to accept optional siteId for cross-page use --- app/page.tsx | 17 +-------- .../settings/unified/UnifiedSettingsModal.tsx | 6 +++- components/sites/SiteList.tsx | 35 ++++++------------- lib/unified-settings-context.tsx | 2 +- 4 files changed, 17 insertions(+), 43 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index c506644..8df1ad6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -33,7 +33,6 @@ export default function HomePage() { const [siteStats, setSiteStats] = useState({}) const [subscription, setSubscription] = useState(null) const [showFinishSetupBanner, setShowFinishSetupBanner] = useState(true) - const [deleteModalSite, setDeleteModalSite] = useState(null) const [deletedSites, setDeletedSites] = useState([]) const [permanentDeleteSiteModal, setPermanentDeleteSiteModal] = useState(null) @@ -119,11 +118,6 @@ export default function HomePage() { } } - const handleDelete = (id: string) => { - const site = sites.find((s) => s.id === id) - if (site) setDeleteModalSite(site) - } - const handleRestore = async (id: string) => { try { await restoreSite(id) @@ -312,18 +306,9 @@ export default function HomePage() { )} {(sitesLoading || sites.length > 0) && ( - + )} - setDeleteModalSite(null)} - onDeleted={loadSites} - siteName={deleteModalSite?.name || ''} - siteDomain={deleteModalSite?.domain || ''} - siteId={deleteModalSite?.id || ''} - /> - setPermanentDeleteSiteModal(null)} diff --git a/components/settings/unified/UnifiedSettingsModal.tsx b/components/settings/unified/UnifiedSettingsModal.tsx index 4cbee82..5b44988 100644 --- a/components/settings/unified/UnifiedSettingsModal.tsx +++ b/components/settings/unified/UnifiedSettingsModal.tsx @@ -303,7 +303,11 @@ export default function UnifiedSettingsModal() { useEffect(() => { if (!isOpen || !user?.org_id) return - if (typeof window !== 'undefined') { + if (initTab?.siteId) { + // Site ID passed explicitly (e.g. from home page site card) + setActiveSiteId(initTab.siteId) + if (!initTab?.context) setContext('site') + } else if (typeof window !== 'undefined') { const match = window.location.pathname.match(/\/sites\/([a-f0-9-]+)/) if (match) { setActiveSiteId(match[1]) diff --git a/components/sites/SiteList.tsx b/components/sites/SiteList.tsx index 8065672..c5344a8 100644 --- a/components/sites/SiteList.tsx +++ b/components/sites/SiteList.tsx @@ -5,8 +5,8 @@ import Image from 'next/image' import { Site } from '@/lib/api/sites' import type { Stats } from '@/lib/api/stats' import { formatNumber } from '@ciphera-net/ui' -import { BarChartIcon, SettingsIcon, TrashIcon, BookOpenIcon, ExternalLinkIcon, Button } from '@ciphera-net/ui' -import { useAuth } from '@/lib/auth/context' +import { BarChartIcon, SettingsIcon, BookOpenIcon, ExternalLinkIcon, Button } from '@ciphera-net/ui' +import { useUnifiedSettings } from '@/lib/unified-settings-context' import { FAVICON_SERVICE_URL } from '@/lib/utils/favicon' export type SiteStatsMap = Record @@ -15,18 +15,16 @@ interface SiteListProps { sites: Site[] siteStats: SiteStatsMap loading: boolean - onDelete: (id: string) => void } interface SiteCardProps { site: Site stats: Stats | null statsLoading: boolean - onDelete: (id: string) => void - canDelete: boolean } -function SiteCard({ site, stats, statsLoading, onDelete, canDelete }: SiteCardProps) { +function SiteCard({ site, stats, statsLoading }: SiteCardProps) { + const { openUnifiedSettings } = useUnifiedSettings() const visitors24h = stats?.visitors ?? 0 const pageviews = stats?.pageviews ?? 0 @@ -104,31 +102,20 @@ function SiteCard({ site, stats, statsLoading, onDelete, canDelete }: SiteCardPr View Dashboard - openUnifiedSettings({ context: 'site', tab: 'general', siteId: site.id })} + className="flex items-center justify-center rounded-lg border border-neutral-200 px-3 hover:bg-neutral-50 dark:border-neutral-700 dark:hover:bg-neutral-800 text-neutral-500 hover:text-neutral-300 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-orange focus-visible:ring-offset-2 cursor-pointer" title="Site Settings" > - - {canDelete && ( - - )} + ) } -export default function SiteList({ sites, siteStats, loading, onDelete }: SiteListProps) { - const { user } = useAuth() - const canDelete = user?.role === 'owner' || user?.role === 'admin' +export default function SiteList({ sites, siteStats, loading }: SiteListProps) { if (loading) { return ( @@ -172,8 +159,6 @@ export default function SiteList({ sites, siteStats, loading, onDelete }: SiteLi site={site} stats={data?.stats ?? null} statsLoading={!data} - onDelete={onDelete} - canDelete={canDelete} /> ) })} diff --git a/lib/unified-settings-context.tsx b/lib/unified-settings-context.tsx index 5711314..fafacc3 100644 --- a/lib/unified-settings-context.tsx +++ b/lib/unified-settings-context.tsx @@ -2,7 +2,7 @@ import { createContext, useContext, useState, useCallback } from 'react' -type InitialTab = { context?: 'site' | 'workspace' | 'account'; tab?: string } | null +type InitialTab = { context?: 'site' | 'workspace' | 'account'; tab?: string; siteId?: string } | null interface UnifiedSettingsContextType { isOpen: boolean