feat: calendar diary view on profile (#15)

This commit is contained in:
2026-07-10 22:22:13 +02:00
parent a0c0ba1c5d
commit 0a8b52514d
2 changed files with 133 additions and 0 deletions

View File

@@ -17,6 +17,7 @@ import { useInfiniteDiary } from "@/features/diary"
import { TimeAgo } from "@/components/time-ago"
import { WATCH_MEDIUMS } from "@/lib/watch-mediums"
import { ReviewDetailSheet } from "@/components/review-detail-sheet"
import { DiaryCalendar } from "@/components/diary-calendar"
import type { DiaryEntryDto } from "@/lib/api/common"
import type { UserProfileResponse } from "@/features/users"
@@ -51,6 +52,7 @@ export function ProfileView({
const profileTabs = [
{ value: "recent", label: t("profile.recent") },
{ value: "top_rated", label: t("profile.topRated") },
{ value: "calendar", label: t("profile.calendar", { defaultValue: "Calendar" }) },
{ value: "trends", label: t("profile.trends") },
] as const
@@ -128,6 +130,7 @@ export function ProfileView({
search={search}
/>
)}
{tab === "calendar" && <CalendarTab userId={userId} />}
{tab === "trends" && <TrendsView data={data} />}
</>
)}
@@ -192,6 +195,45 @@ function DiaryTab({ sortBy, userId, search }: { sortBy: string; userId?: string;
)
}
function CalendarTab({ userId }: { userId?: string }) {
const { data, isPending, hasNextPage, fetchNextPage } =
useInfiniteDiary({ sort_by: "date_desc", user_id: userId })
const items = data?.pages.flatMap((p) => p.items) ?? []
const [detailEntries, setDetailEntries] = useState<DiaryEntryDto[] | null>(null)
const [detailEntry, setDetailEntry] = useState<DiaryEntryDto | null>(null)
if (isPending) return <Skeleton className="h-80 w-full rounded-xl" />
if (hasNextPage) fetchNextPage()
return (
<>
<DiaryCalendar
entries={items}
onSelectDate={(entries) => {
if (entries.length === 1) setDetailEntry(entries[0]!)
else setDetailEntries(entries)
}}
/>
{detailEntry && (
<ReviewDetailSheet
open={!!detailEntry}
onOpenChange={(open) => !open && setDetailEntry(null)}
movie={detailEntry.movie}
review={detailEntry.review}
/>
)}
{detailEntries && (
<ReviewDetailSheet
open={!!detailEntries}
onOpenChange={(open) => !open && setDetailEntries(null)}
movie={detailEntries[0]!.movie}
review={detailEntries[0]!.review}
/>
)}
</>
)
}
const trendChartConfig = {
count: { label: "Movies", color: "var(--primary)" },
} satisfies ChartConfig