mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 03:55:38 -04:00
UX overhaul: motion animations, command palette, warm cinema theme
Add premium "Late Night Screening Room" experience with warm indigo/amber palette, framer-motion spring animations, Cmd+K command palette with TMDB search, keyboard shortcuts (G H, G S, ?, W, M, 1-5), sonner toasts with optimistic updates, skeleton loading states, stats dashboard, search autocomplete with filter tabs, cinematic backdrop with film grain, season progress bars, and staggered card reveal animations throughout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { and, eq, sql } from "drizzle-orm";
|
||||
import { headers } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
import { auth } from "@/lib/auth/server";
|
||||
import { db } from "@/lib/db/client";
|
||||
import {
|
||||
userEpisodeWatches,
|
||||
userMovieWatches,
|
||||
userTitleStatus,
|
||||
} from "@/lib/db/schema";
|
||||
|
||||
export async function GET() {
|
||||
const session = await auth.api.getSession({
|
||||
headers: await headers(),
|
||||
});
|
||||
if (!session)
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const userId = session.user.id;
|
||||
const now = new Date();
|
||||
|
||||
// Start of current month
|
||||
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
// Start of current week (Monday)
|
||||
const dayOfWeek = now.getDay();
|
||||
const weekStart = new Date(now);
|
||||
weekStart.setDate(now.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1));
|
||||
weekStart.setHours(0, 0, 0, 0);
|
||||
|
||||
const [moviesThisMonth] = db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(userMovieWatches)
|
||||
.where(
|
||||
and(
|
||||
eq(userMovieWatches.userId, userId),
|
||||
sql`${userMovieWatches.watchedAt} >= ${Math.floor(monthStart.getTime() / 1000)}`,
|
||||
),
|
||||
)
|
||||
.all();
|
||||
|
||||
const [episodesThisWeek] = db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(userEpisodeWatches)
|
||||
.where(
|
||||
and(
|
||||
eq(userEpisodeWatches.userId, userId),
|
||||
sql`${userEpisodeWatches.watchedAt} >= ${Math.floor(weekStart.getTime() / 1000)}`,
|
||||
),
|
||||
)
|
||||
.all();
|
||||
|
||||
const [librarySize] = db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(userTitleStatus)
|
||||
.where(eq(userTitleStatus.userId, userId))
|
||||
.all();
|
||||
|
||||
const [completedCount] = db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(userTitleStatus)
|
||||
.where(
|
||||
and(
|
||||
eq(userTitleStatus.userId, userId),
|
||||
eq(userTitleStatus.status, "completed"),
|
||||
),
|
||||
)
|
||||
.all();
|
||||
|
||||
return NextResponse.json({
|
||||
moviesThisMonth: moviesThisMonth?.count ?? 0,
|
||||
episodesThisWeek: episodesThisWeek?.count ?? 0,
|
||||
librarySize: librarySize?.count ?? 0,
|
||||
completed: completedCount?.count ?? 0,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user