Skip to content

Commit a88cc3d

Browse files
feat: updated dashboard's layout with sidebar, topbar, and a user profile page.
1 parent 96e75ba commit a88cc3d

6 files changed

Lines changed: 100 additions & 64 deletions

File tree

apps/web/app/dashboard/profile/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ export default async function ProfilePage() {
1414
return (
1515
<DashboardLayout>
1616
<div className="space-y-8">
17-
<div className="rounded-3xl border border-[var(--fs-border)] bg-[var(--fs-card)] p-8 shadow-[var(--fs-shadow-soft)]">
18-
<p className="text-[11px] font-semibold uppercase tracking-[0.14em] text-[var(--fs-text-muted)]">Profile</p>
19-
<h1 className="text-3xl font-extrabold tracking-tight text-[var(--fs-text-primary)]">Your account</h1>
17+
<div className="rounded-3xl border border-[var(--fs-border)] bg-[var(--fs-card)] p-6 shadow-[var(--fs-shadow-soft)]">
18+
<h1 className="text-3xl font-bold tracking-tight text-[var(--fs-text-primary)]">Your account</h1>
2019
<p className="text-[12px] font-medium text-[var(--fs-text-muted)]">
2120
Mirror the mobile profile: review your identity, hop to settings, and sign out securely.
2221
</p>

apps/web/src/components/layout/DashboardLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { GridBackground } from '../../../components/home';
88
export function DashboardLayout({ children, topbarRight }: { children: ReactNode; topbarRight?: ReactNode }) {
99
return (
1010
<AppLayout>
11-
<div className="relative min-h-screen bg-[#030303] overflow-hidden">
11+
<div className="relative min-h-screen bg-[#030303] overflow-hidden pt-16">
1212
{/* Cinematic Backdrop */}
1313
<GridBackground />
1414
<div className="pointer-events-none absolute inset-0 bg-gradient-to-b from-transparent via-purple-500/[0.01] to-transparent" />

apps/web/src/components/layout/Sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export function Sidebar() {
8282
<span className="text-[10px] font-bold text-emerald-600 dark:text-emerald-400">Stable</span>
8383
</div>
8484
</div>
85-
<p className="text-xs font-bold text-[var(--fs-text-primary)]">FairShare v1.2.0</p>
85+
<p className="text-xs font-bold text-[var(--fs-text-primary)]">FairShare v1.0.0</p>
8686
</div>
8787
</div>
8888
</div>

apps/web/src/components/layout/Topbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function Topbar({ rightSlot }: { rightSlot?: React.ReactNode }) {
2525
<div className="flex items-center gap-2 mt-1.5">
2626
<div className="h-1.5 w-1.5 rounded-full bg-[var(--fs-primary)] opacity-50 shadow-[0_0_8px_var(--fs-primary)]" />
2727
<p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[var(--fs-text-muted)]">
28-
Royal Session Active • {new Date().toLocaleDateString(undefined, { weekday: 'long', hour: '2-digit', minute: '2-digit'})}
28+
Session Active • {new Date().toLocaleDateString(undefined, { weekday: 'long', hour: '2-digit', minute: '2-digit'})}
2929
</p>
3030
</div>
3131
</div>

apps/web/src/components/profile/ProfilePanel.tsx

Lines changed: 94 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import Link from 'next/link';
44
import { AuthUserDto } from '@fairshare/shared-types';
5-
import { LogOut, ShieldCheck, LifeBuoy, Settings } from 'lucide-react';
5+
import { LogOut, ShieldCheck, LifeBuoy, Settings, ChevronRight, User, Command } from 'lucide-react';
66
import { useAuth } from '../auth/AuthProvider';
7-
8-
const cardBase = 'rounded-3xl border border-[var(--fs-border)] bg-[var(--fs-card)] shadow-[var(--fs-shadow-soft)]';
7+
import { motion } from 'framer-motion';
8+
import { GlassCard } from '../../../components/ui/GlassCard';
9+
import { fadeUp, staggerContainer } from '../../../components/home/motion-variants';
910

1011
function initials(name?: string | null) {
1112
if (!name) return 'FS';
@@ -18,79 +19,115 @@ export function ProfilePanel({ fallbackUser }: { fallbackUser: AuthUserDto | nul
1819
const { user, logout, loading } = useAuth();
1920
const currentUser = user ?? fallbackUser;
2021

22+
const actionItems = [
23+
{
24+
title: 'Settings',
25+
desc: 'Appearance, security, and account syncing.',
26+
icon: Settings,
27+
href: '/dashboard/settings',
28+
color: 'text-purple-400',
29+
bg: 'bg-purple-500/10'
30+
},
31+
{
32+
title: 'Privacy',
33+
desc: 'Encryption keys and session hygiene.',
34+
icon: ShieldCheck,
35+
href: '#',
36+
color: 'text-indigo-400',
37+
bg: 'bg-indigo-500/10'
38+
},
39+
{
40+
title: 'Support',
41+
desc: 'Troubleshooting and interface onboarding.',
42+
icon: LifeBuoy,
43+
href: '#',
44+
color: 'text-violet-400',
45+
bg: 'bg-violet-500/10'
46+
}
47+
];
48+
2149
return (
22-
<div className="space-y-8">
23-
<div className={`${cardBase} p-8 relative overflow-hidden`}>
24-
<div className="absolute inset-0 opacity-10 pointer-events-none bg-gradient-to-br from-[var(--fs-primary)] to-[var(--fs-accent)]" />
25-
<div className="relative flex items-center gap-4">
26-
<div className="h-16 w-16 rounded-2xl bg-[var(--fs-primary)] text-white font-black text-2xl flex items-center justify-center shadow-lg border border-white/30">
27-
{initials(currentUser?.name)}
50+
<motion.div
51+
variants={staggerContainer}
52+
initial="hidden"
53+
animate="show"
54+
className="space-y-8 max-w-4xl mx-auto"
55+
>
56+
{/* ── User Identity ── */}
57+
<GlassCard className=" border-white/10 bg-white/[0.02]">
58+
<div className="flex flex-col md:flex-row items-center gap-8 text-center md:text-left">
59+
<div className="h-14 w-14 rounded-2xl bg-gradient-to-br from-purple-500 to-indigo-600 flex items-center justify-center shadow-lg border border-white/20">
60+
<span className="text-2xl font-black italic tracking-tighter text-white">
61+
{initials(currentUser?.name)}
62+
</span>
2863
</div>
2964
<div className="space-y-1">
30-
<p className="text-lg font-extrabold text-[var(--fs-text-primary)]">
31-
{currentUser?.name ?? 'Guest'}
32-
</p>
33-
<p className="text-sm font-medium text-[var(--fs-text-muted)]">
65+
<h1 className="text-2xl font-black italic tracking-tighter text-white uppercase">
66+
{currentUser?.name ?? 'Guest User'}
67+
</h1>
68+
<p className="text-sm font-bold tracking-widest text-zinc-500 uppercase">
3469
{currentUser?.email ?? 'Not signed in'}
3570
</p>
36-
<p className="text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--fs-text-secondary)]">
37-
Parity with mobile profile, now on web.
38-
</p>
3971
</div>
4072
</div>
41-
</div>
73+
</GlassCard>
4274

43-
<div className="grid gap-4 sm:grid-cols-2">
44-
<Link
45-
href="/dashboard/settings"
46-
className={`${cardBase} px-5 py-4 flex items-center gap-3 hover:border-[var(--fs-primary)] transition-colors`}
47-
>
48-
<div className="h-10 w-10 rounded-xl bg-[var(--fs-primary)]/10 text-[var(--fs-primary)] flex items-center justify-center">
49-
<Settings className="w-5 h-5" />
50-
</div>
51-
<div>
52-
<p className="text-sm font-semibold text-[var(--fs-text-primary)]">Settings</p>
53-
<p className="text-[12px] font-medium text-[var(--fs-text-muted)]">Appearance, security, and account</p>
54-
</div>
75+
{/* ── Actions ── */}
76+
<div className="grid gap-4 sm:grid-cols-4">
77+
<Link href="/dashboard/settings" className="block h-full">
78+
<GlassCard className=" border-white/5 bg-white/[0.01] hover:bg-white/[0.03] transition-all group flex items-center gap-4">
79+
<div className="h-10 w-10 rounded-xl bg-purple-500/10 text-purple-400 flex items-center justify-center border border-purple-500/20">
80+
<Settings size={18} />
81+
</div>
82+
<div className='pt-2'>
83+
<p className="text-sm font-black italic tracking-tight text-white uppercase">Settings</p>
84+
<p className="text-[10px] font-semibold text-zinc-600 uppercase tracking-widest">Account & Appearance</p>
85+
</div>
86+
</GlassCard>
5587
</Link>
5688

57-
<div className={`${cardBase} px-5 py-4 flex items-center gap-3`}>
58-
<div className="h-10 w-10 rounded-xl bg-[var(--fs-primary)]/10 text-[var(--fs-primary)] flex items-center justify-center">
59-
<ShieldCheck className="w-5 h-5" />
60-
</div>
61-
<div>
62-
<p className="text-sm font-semibold text-[var(--fs-text-primary)]">Privacy & security</p>
63-
<p className="text-[12px] font-medium text-[var(--fs-text-muted)]">Encryption, session hygiene, audit trails</p>
64-
</div>
89+
<div className="h-full">
90+
<GlassCard className=" border-white/5 bg-white/[0.01] flex items-center gap-4">
91+
<div className="h-10 w-10 rounded-xl bg-indigo-500/10 text-indigo-400 flex items-center justify-center border border-indigo-500/20">
92+
<ShieldCheck size={18} />
93+
</div>
94+
<div className='pt-2'>
95+
<p className="text-sm font-black italic tracking-tight text-white uppercase">Privacy & Security</p>
96+
<p className="text-[10px] font-bold text-zinc-600 uppercase tracking-widest">Data & Encryption</p>
97+
</div>
98+
</GlassCard>
6599
</div>
66100

67-
<div className={`${cardBase} px-5 py-4 flex items-center gap-3`}>
68-
<div className="h-10 w-10 rounded-xl bg-[var(--fs-primary)]/10 text-[var(--fs-primary)] flex items-center justify-center">
69-
<LifeBuoy className="w-5 h-5" />
70-
</div>
71-
<div>
72-
<p className="text-sm font-semibold text-[var(--fs-text-primary)]">Help & support</p>
73-
<p className="text-[12px] font-medium text-[var(--fs-text-muted)]">Troubleshooting and onboarding tips</p>
74-
</div>
101+
<div className="h-full">
102+
<GlassCard className=" border-white/5 bg-white/[0.01] flex items-center gap-4">
103+
<div className="h-10 w-10 rounded-xl bg-zinc-500/10 text-zinc-400 flex items-center justify-center border border-white/5">
104+
<LifeBuoy size={18} />
105+
</div>
106+
<div className='pt-2'>
107+
<p className="text-sm font-black italic tracking-tight text-white uppercase">Support</p>
108+
<p className="text-[10px] font-bold text-zinc-600 uppercase tracking-widest">Help & Documentation</p>
109+
</div>
110+
</GlassCard>
75111
</div>
76112

77113
<button
78114
onClick={() => void logout()}
79115
disabled={loading}
80-
className={`${cardBase} px-5 py-4 flex items-center gap-3 hover:border-rose-400/60 transition-colors`}
116+
className="w-full text-left h-full"
81117
>
82-
<div className="h-10 w-10 rounded-xl bg-rose-500/10 text-rose-500 flex items-center justify-center">
83-
<LogOut className="w-5 h-5" />
84-
</div>
85-
<div className="text-left">
86-
<p className="text-sm font-semibold text-[var(--fs-text-primary)]">Logout</p>
87-
<p className="text-[12px] font-medium text-[var(--fs-text-muted)]">Sign out on web just like mobile</p>
88-
</div>
89-
<span className="ml-auto text-[11px] font-bold uppercase tracking-[0.12em] text-rose-400">
90-
{loading ? '...' : 'Exit'}
91-
</span>
118+
<GlassCard className=" border-white/5 bg-white/[0.01] hover:bg-rose-500/5 hover:border-rose-500/20 transition-all group flex items-center gap-4">
119+
<div className="h-10 w-10 rounded-xl bg-rose-500/10 text-rose-500 flex items-center justify-center border border-rose-500/20">
120+
<LogOut size={18} />
121+
</div>
122+
<div className='pt-2'>
123+
<p className="text-sm font-black italic tracking-tight text-white uppercase">Logout</p>
124+
<p className="text-[10px] font-bold text-zinc-600 uppercase tracking-widest">
125+
{loading ? 'Processing...' : 'Sign out of session'}
126+
</p>
127+
</div>
128+
</GlassCard>
92129
</button>
93130
</div>
94-
</div>
131+
</motion.div>
95132
);
96133
}

apps/web/tsconfig.tsbuildinfo

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)