Apply consistent import ordering and indentation in frontend and backend files. Ensure better maintainability and adherence to code style standards.
138 lines
4.3 KiB
TypeScript
138 lines
4.3 KiB
TypeScript
"use client";
|
|
|
|
import { Calendar, LogIn, LogOut, Settings } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { useSearchParams } from "next/navigation";
|
|
import * as React from "react";
|
|
import { ContentList } from "@/components/content-list";
|
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { Spinner } from "@/components/ui/spinner";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { useAuth } from "@/providers/auth-provider";
|
|
import { ContentService } from "@/services/content.service";
|
|
import { FavoriteService } from "@/services/favorite.service";
|
|
|
|
export default function ProfilePage() {
|
|
const { user, isAuthenticated, isLoading, logout } = useAuth();
|
|
const searchParams = useSearchParams();
|
|
const tab = searchParams.get("tab") || "memes";
|
|
|
|
const fetchMyMemes = React.useCallback(
|
|
(params: { limit: number; offset: number }) =>
|
|
ContentService.getExplore({ ...params, author: user?.username }),
|
|
[user?.username],
|
|
);
|
|
|
|
const fetchMyFavorites = React.useCallback(
|
|
(params: { limit: number; offset: number }) => FavoriteService.list(params),
|
|
[],
|
|
);
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="flex h-[400px] items-center justify-center">
|
|
<Spinner className="h-8 w-8 text-primary" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!isAuthenticated || !user) {
|
|
return (
|
|
<div className="max-w-2xl mx-auto py-8 px-4 text-center">
|
|
<Card className="p-12">
|
|
<CardHeader>
|
|
<div className="mx-auto bg-primary/10 p-4 rounded-full w-fit mb-4">
|
|
<LogIn className="h-8 w-8 text-primary" />
|
|
</div>
|
|
<CardTitle>Profil inaccessible</CardTitle>
|
|
<CardDescription>
|
|
Vous devez être connecté pour voir votre profil, vos mèmes et vos
|
|
favoris.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Button asChild className="w-full sm:w-auto">
|
|
<Link href="/login">Se connecter</Link>
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="max-w-4xl mx-auto py-8 px-4">
|
|
<div className="bg-white dark:bg-zinc-900 rounded-2xl p-8 border shadow-sm mb-8">
|
|
<div className="flex flex-col md:flex-row items-center gap-8">
|
|
<Avatar className="h-32 w-32 border-4 border-primary/10">
|
|
<AvatarImage src={user.avatarUrl} alt={user.username} />
|
|
<AvatarFallback className="text-4xl">
|
|
{user.username.slice(0, 2).toUpperCase()}
|
|
</AvatarFallback>
|
|
</Avatar>
|
|
<div className="flex-1 text-center md:text-left space-y-4">
|
|
<div>
|
|
<h1 className="text-3xl font-bold">
|
|
{user.displayName || user.username}
|
|
</h1>
|
|
<p className="text-muted-foreground">@{user.username}</p>
|
|
</div>
|
|
<div className="flex flex-wrap justify-center md:justify-start gap-4 text-sm text-muted-foreground">
|
|
<span className="flex items-center gap-1">
|
|
<Calendar className="h-4 w-4" />
|
|
Membre depuis{" "}
|
|
{new Date(user.createdAt).toLocaleDateString("fr-FR", {
|
|
month: "long",
|
|
year: "numeric",
|
|
})}
|
|
</span>
|
|
</div>
|
|
<div className="flex flex-wrap justify-center md:justify-start gap-2">
|
|
<Button asChild variant="outline" size="sm">
|
|
<Link href="/settings">
|
|
<Settings className="h-4 w-4 mr-2" />
|
|
Paramètres
|
|
</Link>
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => logout()}
|
|
className="text-red-500 hover:text-red-600 hover:bg-red-50"
|
|
>
|
|
<LogOut className="h-4 w-4 mr-2" />
|
|
Déconnexion
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Tabs value={tab} className="w-full">
|
|
<TabsList className="grid w-full grid-cols-2 mb-8">
|
|
<TabsTrigger value="memes" asChild>
|
|
<Link href="/profile?tab=memes">Mes Mèmes</Link>
|
|
</TabsTrigger>
|
|
<TabsTrigger value="favorites" asChild>
|
|
<Link href="/profile?tab=favorites">Mes Favoris</Link>
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
<TabsContent value="memes">
|
|
<ContentList fetchFn={fetchMyMemes} />
|
|
</TabsContent>
|
|
<TabsContent value="favorites">
|
|
<ContentList fetchFn={fetchMyFavorites} />
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
);
|
|
}
|