Make /dashboard adapt to realm and accept ?realm= param

cgen-7f688d6c275d4868b3b0bfedf5a8f6aa
This commit is contained in:
Builder.io 2025-10-18 21:28:49 +00:00
parent e821ad1513
commit 94a9c05842

View file

@ -128,6 +128,35 @@ export default function Dashboard() {
}
}, [searchParams, activeTab]);
// Accept ?realm=<id> to switch dashboards via Realms page
useEffect(() => {
const paramRealm = (searchParams.get("realm") || "").trim() as RealmKey;
const validRealms: RealmKey[] = [
"game_developer",
"client",
"community_member",
"customer",
"staff",
];
const current = ((profile as any)?.user_type as RealmKey) ?? null;
if (paramRealm && validRealms.includes(paramRealm) && paramRealm !== current) {
(async () => {
try {
await updateProfile({ user_type: paramRealm } as any);
setUserRealm(paramRealm);
} catch {}
// remove query param after applying
const next = new URLSearchParams(searchParams.toString());
next.delete("realm");
setSearchParams(next, { replace: true });
})();
} else if (paramRealm) {
const next = new URLSearchParams(searchParams.toString());
next.delete("realm");
setSearchParams(next, { replace: true });
}
}, [searchParams, profile?.user_type, updateProfile, setSearchParams]);
useEffect(() => {
if (typeof window === "undefined" || !user) {
return;
@ -633,6 +662,9 @@ export default function Dashboard() {
);
}
// Determine active realm for dashboard personalization
const activeRealm: RealmKey = (userRealm || ((profile as any)?.user_type as RealmKey) || "community_member") as RealmKey;
return (
<Layout>
<div className="min-h-screen bg-aethex-gradient py-8">
@ -686,20 +718,19 @@ export default function Dashboard() {
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4">
<div>
<h1 className="text-3xl font-bold text-gradient-purple">
Welcome back,{" "}
{profile?.full_name || user.email?.split("@")[0]}
{activeRealm === "game_developer" && "Developer Dashboard"}
{activeRealm === "client" && "Client Dashboard"}
{activeRealm === "community_member" && "Community Dashboard"}
{activeRealm === "customer" && "Customer Dashboard"}
{activeRealm === "staff" && "Staff Dashboard"}
</h1>
<p className="text-muted-foreground">
{profile?.role || "Member"} Level {profile?.level || 1} {" "}
{streakLabel} 🔥
Welcome back, {profile?.full_name || user.email?.split("@")[0]} {streakLabel}
</p>
{longestStreak > 0 && (
<div className="mt-3 flex flex-wrap gap-2">
<Badge
variant="outline"
className="border-aethex-400/40 text-aethex-200"
>
Longest streak: {longestStreak}d
<Badge variant="outline" className="border-aethex-400/40 text-aethex-200">
Realm: {activeRealm.replace("_", " ")}
</Badge>
</div>
)}
@ -820,7 +851,7 @@ export default function Dashboard() {
{/* Main Content */}
<div className="lg:col-span-9 space-y-6">
{/* Stats Grid */}
{/* Stats Grid (adapts per realm by labels) */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 animate-slide-up">
{statsDisplay.map((stat, index) => {
const Icon = stat.icon;
@ -852,18 +883,74 @@ export default function Dashboard() {
})}
</div>
{/* Central Post Composer */}
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Create a Post</CardTitle>
<CardDescription>
Share updates, images, or videos
</CardDescription>
</CardHeader>
<CardContent>
<PostComposer onPosted={loadDashboardData} />
</CardContent>
</Card>
{/* Realm spotlight */}
{activeRealm === "game_developer" && (
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Create a Post</CardTitle>
<CardDescription>Share updates, images, or videos</CardDescription>
</CardHeader>
<CardContent>
<PostComposer onPosted={loadDashboardData} />
</CardContent>
</Card>
)}
{activeRealm === "community_member" && (
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Community actions</CardTitle>
<CardDescription>Post to the feed and explore trending topics</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<PostComposer onPosted={() => {}} />
<div className="flex gap-2">
<Button variant="outline" onClick={() => navigate("/feed")}>Open Feed</Button>
<Button variant="outline" onClick={() => navigate("/community/mentorship")}>Mentorship</Button>
</div>
</CardContent>
</Card>
)}
{activeRealm === "client" && (
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Project workspace</CardTitle>
<CardDescription>Kick off engagements and track delivery</CardDescription>
</CardHeader>
<CardContent className="flex flex-wrap gap-2">
<Button onClick={() => navigate("/projects/new")}>Start New Project</Button>
<Button variant="outline" onClick={() => navigate("/teams")}>Create Team</Button>
<Button variant="outline" onClick={() => navigate("/consulting")}>Consulting Overview</Button>
</CardContent>
</Card>
)}
{activeRealm === "customer" && (
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Get started</CardTitle>
<CardDescription>Explore products and manage access</CardDescription>
</CardHeader>
<CardContent className="flex flex-wrap gap-2">
<Button onClick={() => navigate("/get-started")}>Product onboarding</Button>
<Button variant="outline" onClick={() => navigate("/support")}>Support</Button>
</CardContent>
</Card>
)}
{activeRealm === "staff" && (
<Card className="bg-card/50 border-border/50 animate-fade-in">
<CardHeader>
<CardTitle className="text-gradient">Operations</CardTitle>
<CardDescription>Moderation and internal tools</CardDescription>
</CardHeader>
<CardContent className="flex flex-wrap gap-2">
<Button onClick={() => navigate("/staff")}>Open Staff Console</Button>
<Button variant="outline" onClick={() => navigate("/feed")}>Community Feed</Button>
</CardContent>
</Card>
)}
{/* Settings Section */}
<Card