feat(settings): add user settings page and initial SettingsView component
Some checks failed
Deploy Waveform to VPS / deploy (push) Failing after 35s
Some checks failed
Deploy Waveform to VPS / deploy (push) Failing after 35s
This commit is contained in:
parent
4db0a3cd57
commit
6fa8b1f1d4
3 changed files with 86 additions and 4 deletions
38
app/(app)/settings/page.tsx
Normal file
38
app/(app)/settings/page.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* @file app/(app)/settings/page.tsx
|
||||||
|
* @description Settings page for managing user profile, appearance, and account preferences.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { auth } from "@/auth";
|
||||||
|
import { db } from "@/db";
|
||||||
|
import { users } from "@/db/schema";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
import { SettingsView } from "@/components/settings/SettingsView";
|
||||||
|
import AppFooter from "@/components/layout/AppFooter";
|
||||||
|
|
||||||
|
export default async function SettingsPage() {
|
||||||
|
const session = await auth();
|
||||||
|
const currentUserId = session?.user?.id;
|
||||||
|
|
||||||
|
if (!currentUserId) {
|
||||||
|
redirect("/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
const [currentUser] = await db
|
||||||
|
.select()
|
||||||
|
.from(users)
|
||||||
|
.where(eq(users.id, currentUserId))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
redirect("/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-full w-full bg-background p-4">
|
||||||
|
<SettingsView userId={currentUserId} currentUser={currentUser} />
|
||||||
|
<AppFooter />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
43
components/settings/SettingsView.tsx
Normal file
43
components/settings/SettingsView.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* @file components/settings/SettingsView.tsx
|
||||||
|
* @description Main settings container component for managing user profile and preferences.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { UserAvatar } from "@/components/ui/UserAvatar";
|
||||||
|
import { User } from "@/db/schema";
|
||||||
|
|
||||||
|
interface SettingsViewProps {
|
||||||
|
userId: string;
|
||||||
|
currentUser: User;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SettingsView({ userId, currentUser }: SettingsViewProps) {
|
||||||
|
if (!currentUser) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col h-full w-full bg-background text-white gap-6">
|
||||||
|
{/* Header */}
|
||||||
|
<div>
|
||||||
|
<h1 className="text-2xl font-bold text-white">Settings</h1>
|
||||||
|
<p className="text-sm text-muted">
|
||||||
|
Manage your profile, status, and account settings.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Profile Overview Card */}
|
||||||
|
<div className="bg-surface border border-muted/20 rounded-xl p-6 space-y-6">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<UserAvatar user={currentUser} size="md" />
|
||||||
|
<div>
|
||||||
|
<h2 className="text-lg font-bold text-white">
|
||||||
|
{currentUser.username}
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm text-muted">{currentUser.email}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import { LogOut, Settings } from "lucide-react";
|
||||||
import { signOut } from "next-auth/react";
|
import { signOut } from "next-auth/react";
|
||||||
import { UserAvatar } from "@/components/ui/UserAvatar";
|
import { UserAvatar } from "@/components/ui/UserAvatar";
|
||||||
import { UserStatus } from "@/db/schema";
|
import { UserStatus } from "@/db/schema";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Props for the UserPanel component.
|
* Props for the UserPanel component.
|
||||||
|
|
@ -58,13 +59,13 @@ export function UserPanel({ user }: UserPanelProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<button
|
<Link
|
||||||
type="button"
|
href="/settings"
|
||||||
className="p-1.5 text-muted hover:text-foreground focus:outline-none cursor-pointer transition-colors"
|
className="p-1.5 text-muted hover:text-foreground focus:outline-none transition-colors"
|
||||||
aria-label="User Settings"
|
aria-label="User Settings"
|
||||||
>
|
>
|
||||||
<Settings className="w-4 h-4" />
|
<Settings className="w-4 h-4" />
|
||||||
</button>
|
</Link>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue