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 { UserAvatar } from "@/components/ui/UserAvatar";
|
||||
import { UserStatus } from "@/db/schema";
|
||||
import Link from "next/link";
|
||||
|
||||
/**
|
||||
* Props for the UserPanel component.
|
||||
|
|
@ -58,13 +59,13 @@ export function UserPanel({ user }: UserPanelProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
className="p-1.5 text-muted hover:text-foreground focus:outline-none cursor-pointer transition-colors"
|
||||
<Link
|
||||
href="/settings"
|
||||
className="p-1.5 text-muted hover:text-foreground focus:outline-none transition-colors"
|
||||
aria-label="User Settings"
|
||||
>
|
||||
<Settings className="w-4 h-4" />
|
||||
</button>
|
||||
</Link>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
|||
Loading…
Reference in a new issue