# Profile & Devices Page Redesign ## Goal Revamp the profile page from a generic, narrow layout to a full-featured settings hub with password change, passkey management, account linking, and profile editing. Create the initial devices page with aggregated stats and charts. Remove profile photo from the navbar. ## Architecture ### Profile Page (`/profile`) - Switch from `max-w-3xl` to `max-w-7xl` - Remove profile photo/avatar from ProfileHeader (no image upload) - Replace with initials-based avatar or just name display - Settings tab gets 3 sub-tabs: Profile, Security, Linked Accounts - Each settings section uses Better Auth's client-side API methods ### Navbar - Remove profile photo/icon from the authenticated dropdown trigger - Show just "Profile" text link that opens the dropdown (Profile + Saved Games + Sign out) - Mobile sidebar already uses text links, just remove avatar section ### Devices Page (`/devices`) - Grid of device cards with aggregated benchmark statistics - Clicking a card navigates to `/devices/[slug]` for detailed view - Detail page leverages existing EChartWrapper + chart components - New API endpoints for aggregated hardware statistics ### Devices Detail Page (`/devices/[slug]`) - Hero header with device name, type, benchmark count - Charts: Historical FPS, FPS Distribution (boxplot), Top Games, Game count by genre/proton status - Uses same chart components and theme as game page ## Tech Stack - Better Auth client API (changePassword, updateUser, listAccounts, unlinkAccount, linkSocialAccount, passkey.addPasskey, passkey.deletePasskey, listPasskeys) - ECharts (echarts-for-react) for device stats charts - Existing chart components: EChartWrapper, HistoricalAreaChart, FpsBoxplot, DeviceDonut - Framer Motion for animations (consistent with rest of app) - Tailwind v4 with existing theme tokens ## Profile Settings Details ### Profile Sub-Tab - Display name editing (Better Auth `updateUser`) - Email display (read-only, with link to change email — future feature) - Role and member since (read-only) ### Security Sub-Tab - **Password Section**: - If user has password: "Change Password" form with current password + new password + confirm - If user has no password (social-only): "Set Password" form - Uses Better Auth `changePassword` (with currentPassword) or `setPassword` - **Passkey Section**: - List existing passkeys (name, device type, created date) - "Add Passkey" button (Better Auth `addPasskey`) - "Delete" button per passkey (Better Auth `deletePasskey`) - "Rename" per passkey (Better Auth `updatePasskey`) - Safety check: don't allow deleting last auth method ### Linked Accounts Sub-Tab - List linked providers (Google, Discord, password) - Shows provider name, account ID/email, linked date - "Unlink" button with confirmation (Better Auth `unlinkAccount`) - Safety check: don't allow unlinking last auth method - "Link Google" / "Link Discord" buttons (Better Auth `linkSocialAccount`) - Show which providers are available vs already linked ## Devices API ### `GET /api/hardware/stats` Returns array of all devices with aggregated stats: ```json [ { "slug": "steam-deck-oled", "name": "Steam Deck OLED", "deviceType": "handheld", "sortOrder": 0, "totalBenchmarks": 150, "avgFps": 45.2, "gameCount": 35, "verifiedCount": 20, "bestGame": { "id": "...", "title": "...", "fpsAvg": 120 } } ] ``` ### `GET /api/hardware/:slug/stats` Returns detailed stats for one device: ```json { "slug": "steam-deck-oled", "name": "Steam Deck OLED", "deviceType": "handheld", "totalBenchmarks": 150, "avgFps": 45.2, "verifiedCount": 20, "gameCount": 35, "boxplot": [...], "historical": [...], "topGames": [...], "protonBreakdown": [...], "fsrBreakdown": [...] } ``` ## Component File Structure ### New Files - `components/profile/settings-profile-tab.tsx` — Profile sub-tab - `components/profile/settings-security-tab.tsx` — Security sub-tab (password + passkeys) - `components/profile/settings-accounts-tab.tsx` — Linked Accounts sub-tab - `app/devices/page.tsx` — Devices grid page (server component) - `app/devices/page-client.tsx` — Devices grid client component - `app/devices/[slug]/page.tsx` — Device detail page (server component) - `app/devices/[slug]/device-detail-client.tsx` — Device detail client component - `lib/api/hardware-stats.ts` — Hardware stats API routes ### Modified Files - `app/profile/page.tsx` — Redesign layout, widen to max-w-7xl, add settings sub-tabs - `components/profile/profile-header.tsx` — Remove image/avatar, show name-centric layout - `components/navbar.tsx` — Remove profile photo/icon from dropdown trigger, keep text-only "Profile" - `lib/routes.ts` — Add /devices route - `lib/api/hardware.ts` — May need minor updates for new stats endpoints ## Design Patterns (from existing pages) - **Game page** layout pattern: `max-w-7xl mx-auto` with `px-4 md:px-[10svw]` sections - **Chart cards**: `rounded-xl border border-border bg-text/[0.03] p-4` - **Stat cards**: Icon + label + value in `flex items-center gap-3` - **Section headers**: `text-sm font-medium text-text/80 mb-2` - **Tab style**: `border-b border-border` with active state `border-primary text-primary` - **Animations**: `motion.div` with `initial={{ opacity: 0, y: 12 }}` and staggered delays ## Edge Cases & Safety 1. Password section: Users with social-only accounts (no password) see "Set Password" not "Change Password" 2. Unlinking: Prevent removing the last authentication method (must always have at least one way to log in) 3. Passkey deletion: Same safety check — don't allow removing the only auth method 4. Device stats: Handle case where no benchmarks exist for a device (show empty state) 5. Mobile responsive: All new components must work on mobile (single-column layouts)