The dashboard is a personalised briefing, not a list of links
When a client logs into the portal, they do not land on a generic welcome page. They land on a dashboard that knows who they are and shows them exactly where things stand. The PortalDashboard is a server component that calls currentUser from Clerk, fetches the client record with all their projects, bookings, and sessions, pulls their invoices from Stripe, and renders the whole picture in one page load. No client-side fetching, no loading spinners, no skeleton screens. The page renders with real data from the first frame. The layout is three summary cards at the top — active project count, outstanding balance, and total sessions — followed by the next upcoming booking with a Join Meet button, then active projects with milestone progress bars, then the latest session notes, then recent invoices. A client with three active projects sees all three with their milestone timelines. A client with no projects yet sees a single message explaining that James will set things up shortly. The summary cards use a GlassCard component with backdrop blur and a subtle border. The outstanding balance shows emerald green with a checkmark when everything is paid. The projects section links to the full projects list. The invoices section links to the full invoice history. Every link has a 44-pixel minimum touch target. The whole dashboard is one async function, one database query with nested includes, one Stripe API call. No useEffect, no useState, no client-side state management. Server components mean the data is already there when the HTML arrives.
Comments coming soon
Sign in with TikTok to leave a comment. Coming soon.