feat: wrap home page in DashboardShell, remove stat cards

Home page now uses the same sidebar layout as dashboard pages.
Sidebar shows simplified home mode (logo, app switcher, profile)
without site-specific nav groups. Stat cards removed — plan info
lives in settings, site count is self-evident from the list.
This commit is contained in:
Usman Baig
2026-03-28 19:12:45 +01:00
parent 07546576c1
commit a6054469ee
4 changed files with 49 additions and 119 deletions

View File

@@ -41,15 +41,15 @@ const Sidebar = dynamic(() => import('./Sidebar'), {
),
})
function GlassTopBar({ siteId }: { siteId: string }) {
function GlassTopBar({ siteId }: { siteId: string | null }) {
const { collapsed, toggle } = useSidebar()
const { data: realtime } = useRealtime(siteId)
const { data: realtime } = useRealtime(siteId ?? '')
const lastUpdatedRef = useRef<number | null>(null)
const [, setTick] = useState(0)
useEffect(() => {
if (realtime) lastUpdatedRef.current = Date.now()
}, [realtime])
if (siteId && realtime) lastUpdatedRef.current = Date.now()
}, [siteId, realtime])
useEffect(() => {
if (lastUpdatedRef.current == null) return
@@ -57,7 +57,8 @@ function GlassTopBar({ siteId }: { siteId: string }) {
return () => clearInterval(timer)
}, [realtime])
const pageTitle = usePageTitle()
const dashboardTitle = usePageTitle()
const pageTitle = siteId ? dashboardTitle : 'Your Sites'
return (
<div className="hidden md:flex items-center justify-between shrink-0 px-3 pt-1.5 pb-1">
@@ -74,7 +75,7 @@ function GlassTopBar({ siteId }: { siteId: string }) {
</div>
{/* Realtime indicator */}
{lastUpdatedRef.current != null && (
{siteId && lastUpdatedRef.current != null && (
<div className="flex items-center gap-1.5 text-xs text-neutral-500">
<span className="relative flex h-1.5 w-1.5">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-500 opacity-75" />
@@ -91,7 +92,7 @@ export default function DashboardShell({
siteId,
children,
}: {
siteId: string
siteId: string | null
children: React.ReactNode
}) {
const [mobileOpen, setMobileOpen] = useState(false)

View File

@@ -364,7 +364,7 @@ function SettingsButton({
interface SidebarContentProps {
isMobile: boolean
collapsed: boolean
siteId: string
siteId: string | null
sites: Site[]
canEdit: boolean
pendingHref: string | null
@@ -414,32 +414,38 @@ function SidebarContent({
</Link>
{/* Site Picker */}
<SitePicker sites={sites} siteId={siteId} collapsed={c} onExpand={onExpand} onCollapse={onCollapse} wasCollapsed={wasCollapsed} pickerOpenCallback={pickerOpenCallbackRef} />
{siteId && (
<SitePicker sites={sites} siteId={siteId} collapsed={c} onExpand={onExpand} onCollapse={onCollapse} wasCollapsed={wasCollapsed} pickerOpenCallback={pickerOpenCallbackRef} />
)}
{/* Nav Groups */}
<nav className="flex-1 overflow-y-auto overflow-x-hidden px-2 space-y-4">
{NAV_GROUPS.map((group) => (
<div key={group.label}>
{c ? (
<div className="mx-3 my-2 border-t border-white/[0.04]" />
) : (
<div className="h-5 flex items-center overflow-hidden">
<p className="px-2.5 text-[11px] font-semibold text-neutral-400 dark:text-neutral-500 uppercase tracking-wider whitespace-nowrap">
{group.label}
</p>
</div>
)}
<div className="space-y-0.5">
{group.items.map((item) => (
<NavLink key={item.label} item={item} siteId={siteId} collapsed={c} onClick={isMobile ? onMobileClose : undefined} pendingHref={pendingHref} onNavigate={onNavigate} />
))}
{group.label === 'Infrastructure' && canEdit && (
<SettingsButton item={SETTINGS_ITEM} collapsed={c} onClick={isMobile ? onMobileClose : undefined} />
{siteId ? (
<nav className="flex-1 overflow-y-auto overflow-x-hidden px-2 space-y-4">
{NAV_GROUPS.map((group) => (
<div key={group.label}>
{c ? (
<div className="mx-3 my-2 border-t border-white/[0.04]" />
) : (
<div className="h-5 flex items-center overflow-hidden">
<p className="px-2.5 text-[11px] font-semibold text-neutral-400 dark:text-neutral-500 uppercase tracking-wider whitespace-nowrap">
{group.label}
</p>
</div>
)}
<div className="space-y-0.5">
{group.items.map((item) => (
<NavLink key={item.label} item={item} siteId={siteId} collapsed={c} onClick={isMobile ? onMobileClose : undefined} pendingHref={pendingHref} onNavigate={onNavigate} />
))}
{group.label === 'Infrastructure' && canEdit && (
<SettingsButton item={SETTINGS_ITEM} collapsed={c} onClick={isMobile ? onMobileClose : undefined} />
)}
</div>
</div>
</div>
))}
</nav>
))}
</nav>
) : (
<div className="flex-1" />
)}
{/* Bottom — utility items */}
<div className="border-t border-white/[0.06] px-2 py-3 shrink-0">
@@ -488,7 +494,7 @@ function SidebarContent({
export default function Sidebar({
siteId, mobileOpen, onMobileClose, onMobileOpen,
}: {
siteId: string; mobileOpen: boolean; onMobileClose: () => void; onMobileOpen: () => void
siteId: string | null; mobileOpen: boolean; onMobileClose: () => void; onMobileOpen: () => void
}) {
const auth = useAuth()
const { user } = auth