217 lines
7.5 KiB
TypeScript
217 lines
7.5 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter } from "next/navigation";
|
|
import { useAuth } from "@/contexts/auth-context";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
import { LogOut, User, Settings } from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
export default function ProfilePage() {
|
|
const router = useRouter();
|
|
const { user, logout, updatePreferences } = useAuth();
|
|
const [itemsPerPage, setItemsPerPage] = useState(
|
|
user?.preferences.itemsPerPage || 12,
|
|
);
|
|
|
|
if (!user) {
|
|
return (
|
|
<div className="flex min-h-screen items-center justify-center bg-background">
|
|
<Card className="w-full max-w-md">
|
|
<CardHeader>
|
|
<CardTitle>Access Denied</CardTitle>
|
|
<CardDescription>
|
|
Please log in to view your profile
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Button onClick={() => router.push("/login")} className="w-full">
|
|
Go to Login
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const handleLogout = () => {
|
|
logout();
|
|
router.push("/");
|
|
};
|
|
|
|
const handleSavePreferences = () => {
|
|
updatePreferences({ itemsPerPage });
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background">
|
|
<div className="mx-auto max-w-2xl px-4 py-8">
|
|
<div className="mb-8 flex items-center justify-between">
|
|
<h1 className="text-3xl font-bold">Profile</h1>
|
|
<Button
|
|
variant="outline"
|
|
onClick={handleLogout}
|
|
className="gap-2 bg-transparent"
|
|
>
|
|
<LogOut className="h-4 w-4" />
|
|
Logout
|
|
</Button>
|
|
</div>
|
|
|
|
<Tabs defaultValue="account" className="space-y-6">
|
|
<TabsList className="grid w-full grid-cols-3">
|
|
<TabsTrigger value="account" className="gap-2">
|
|
<User className="h-4 w-4" />
|
|
Account
|
|
</TabsTrigger>
|
|
<TabsTrigger value="preferences" className="gap-2">
|
|
<Settings className="h-4 w-4" />
|
|
Preferences
|
|
</TabsTrigger>
|
|
<TabsTrigger value="stats">Stats</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="account" className="space-y-4">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Account Information</CardTitle>
|
|
<CardDescription>Your account details</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div className="space-y-2">
|
|
<label className="text-sm font-medium">Username</label>
|
|
<Input value={user.username} disabled />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<label className="text-sm font-medium">Email</label>
|
|
<Input value={user.email} disabled />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<label className="text-sm font-medium">User ID</label>
|
|
<Input
|
|
value={user.id}
|
|
disabled
|
|
className="font-mono text-xs"
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="preferences" className="space-y-4">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Preferences</CardTitle>
|
|
<CardDescription>Customize your experience</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div className="space-y-2">
|
|
<label htmlFor="itemsPerPage" className="text-sm font-medium">
|
|
Items Per Page
|
|
</label>
|
|
<Input
|
|
id="itemsPerPage"
|
|
type="number"
|
|
min="6"
|
|
max="48"
|
|
step="6"
|
|
value={itemsPerPage}
|
|
onChange={(e) =>
|
|
setItemsPerPage(Number.parseInt(e.target.value))
|
|
}
|
|
/>
|
|
<p className="text-xs text-muted-foreground">
|
|
Number of manga to display per page (6-48)
|
|
</p>
|
|
</div>
|
|
<Button onClick={handleSavePreferences}>
|
|
Save Preferences
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="stats" className="space-y-4">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Reading Statistics</CardTitle>
|
|
<CardDescription>Your manga reading activity</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="rounded-lg bg-card p-4">
|
|
<p className="text-sm text-muted-foreground">
|
|
Favorite Manga
|
|
</p>
|
|
<p className="text-2xl font-bold">
|
|
{user.favorites.length}
|
|
</p>
|
|
</div>
|
|
<div className="rounded-lg bg-card p-4">
|
|
<p className="text-sm text-muted-foreground">
|
|
Manga Reading
|
|
</p>
|
|
<p className="text-2xl font-bold">
|
|
{Object.keys(user.chaptersRead).length}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{user.favorites.length > 0 && (
|
|
<div className="space-y-2">
|
|
<h3 className="font-semibold">Favorite Manga IDs</h3>
|
|
<div className="flex flex-wrap gap-2">
|
|
{user.favorites.map((id) => (
|
|
<span
|
|
key={id}
|
|
className="rounded-full bg-primary/10 px-3 py-1 text-sm"
|
|
>
|
|
#{id}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{Object.keys(user.chaptersRead).length > 0 && (
|
|
<div className="space-y-2">
|
|
<h3 className="font-semibold">Reading Progress</h3>
|
|
<div className="space-y-1 text-sm">
|
|
{Object.entries(user.chaptersRead).map(
|
|
([mangaId, chapter]) => (
|
|
<p key={mangaId} className="text-muted-foreground">
|
|
Manga #{mangaId}: Chapter {chapter}
|
|
</p>
|
|
),
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{user.favorites.length === 0 &&
|
|
Object.keys(user.chaptersRead).length === 0 && (
|
|
<Alert>
|
|
<AlertDescription>
|
|
No reading activity yet. Start adding favorites and
|
|
tracking chapters!
|
|
</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|