import { Link } from "@tanstack/react-router" import { useCallback } from "react" import { useTranslation } from "react-i18next" import { Bar, BarChart, XAxis, YAxis } from "recharts" import { User } from "lucide-react" import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from "@/components/ui/chart" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Skeleton } from "@/components/ui/skeleton" import { MovieCard } from "@/components/movie-card" import { EmptyState } from "@/components/empty-state" import { SwipeTabs } from "@/components/swipe-tabs" import { VirtualList } from "@/components/virtual-list" import { useInfiniteDiary } from "@/hooks/use-diary" import type { UserProfileResponse } from "@/lib/api/users" type ProfileViewProps = { data: UserProfileResponse actions?: React.ReactNode headerRight?: React.ReactNode userId?: string } export function ProfileView({ data, actions, headerRight, userId, }: ProfileViewProps) { const { t } = useTranslation() const initial = (data.username || "?")[0]?.toUpperCase() ?? "?" const avatar = data.avatar_url const profileTabs = [ { value: "recent", label: t("profile.recent") }, { value: "top_rated", label: t("profile.topRated") }, { value: "trends", label: t("profile.trends") }, ] as const return (
{avatar && } {initial}

{data.username}

{headerRight}
{actions} {(tab) => ( <> {tab === "recent" && ( )} {tab === "top_rated" && ( )} {tab === "trends" && } )}
) } function StatCell({ label, value }: { label: string; value: string | number }) { return (

{value}

{label}

) } function DiaryTab({ sortBy }: { sortBy: string; userId?: string }) { const { t } = useTranslation() const { data, isPending, hasNextPage, isFetchingNextPage, fetchNextPage } = useInfiniteDiary({ sort_by: sortBy, movie_id: undefined }) const items = data?.pages.flatMap((p) => p.items) ?? [] const loadMore = useCallback(() => fetchNextPage(), [fetchNextPage]) if (isPending) return if (!items.length) return return ( ( )} /> ) } const trendChartConfig = { count: { label: "Movies", color: "var(--primary)" }, } satisfies ChartConfig function TrendsView({ data, }: { data: { trends?: { top_directors: { director: string; count: number }[] monthly_ratings: { month_label: string avg_rating: number count: number }[] } } }) { const { t } = useTranslation() if (!data.trends) return return (
{data.trends.top_directors.length > 0 && ( {t("profile.topDirectors")} {data.trends.top_directors.map((d) => (
{d.director} {t("common.films", { count: d.count })}
))}
)} {data.trends.monthly_ratings.length > 0 && ( {t("profile.monthlyActivity")} v.slice(0, 3)} tick={{ fontSize: 10, fill: "rgba(255,255,255,0.85)" }} tickLine={false} axisLine={false} /> } /> )}
) } export function ProfileSkeleton() { return (
{[1, 2, 3, 4].map((i) => ( ))}
{[1, 2, 3].map((i) => ( ))}
) }