diff --git a/app/(dashboard)/shot-status/ShotStatusClient.tsx b/app/(dashboard)/shot-status/ShotStatusClient.tsx index 700c730..a8230ca 100644 --- a/app/(dashboard)/shot-status/ShotStatusClient.tsx +++ b/app/(dashboard)/shot-status/ShotStatusClient.tsx @@ -65,6 +65,7 @@ interface ShotStatusClientProps { selectedProjectId: string | null; selectedProject: Project | null; shots: ShotRow[]; + episodeDueDates: { episode: string; dueDate: Date | string }[]; canManage: boolean; } @@ -388,11 +389,23 @@ export function ShotStatusClient({ selectedProjectId, selectedProject, shots, + episodeDueDates, canManage, }: ShotStatusClientProps) { const router = useRouter(); const { toast } = useToast(); + // Restore last selected project if no project is currently selected + useEffect(() => { + if (!selectedProjectId) { + const saved = localStorage.getItem("shotStatus:lastProjectId"); + if (saved && projects.some((p) => p.id === saved)) { + router.replace(`/shot-status?projectId=${saved}`); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const [collapsedEpisodes, setCollapsedEpisodes] = useState>(new Set()); const [selectedIds, setSelectedIds] = useState>(new Set()); const [dueDateDialogOpen, setDueDateDialogOpen] = useState(false); @@ -405,6 +418,7 @@ export function ShotStatusClient({ }); const handleProjectChange = (id: string) => { + localStorage.setItem("shotStatus:lastProjectId", id); setSelectedIds(new Set()); router.push(`/shot-status?projectId=${id}`); }; @@ -454,6 +468,10 @@ export function ShotStatusClient({ })() : []; + const episodeDueDateMap = new Map( + episodeDueDates.map((e) => [e.episode, new Date(e.dueDate)]) + ); + const statusCounts = shots.reduce( (acc, s) => { acc[s.status] = (acc[s.status] ?? 0) + 1; @@ -557,6 +575,8 @@ export function ShotStatusClient({ const episodeIds = episodeShots.map((s) => s.id); const allEpSelected = episodeIds.every((id) => selectedIds.has(id)); const someEpSelected = episodeIds.some((id) => selectedIds.has(id)); + const epDueDate = episodeDueDateMap.get(episode); + const epIsOverdue = epDueDate && epDueDate < new Date(); return (
@@ -581,6 +601,15 @@ export function ShotStatusClient({ {episodeShots.length} shot{episodeShots.length !== 1 ? "s" : ""} + {epDueDate && ( + + + {format(epDueDate, "d MMM yyyy")} + + )}
{!collapsed && ( diff --git a/app/(dashboard)/shot-status/page.tsx b/app/(dashboard)/shot-status/page.tsx index dac62e7..e086fea 100644 --- a/app/(dashboard)/shot-status/page.tsx +++ b/app/(dashboard)/shot-status/page.tsx @@ -11,6 +11,14 @@ async function getProjects() { }); } +async function getEpisodeDueDatesForProject(projectId: string) { + return db.episodeDueDate.findMany({ + where: { projectId }, + select: { episode: true, dueDate: true }, + orderBy: { episode: "asc" }, + }); +} + async function getShotsForProject(projectId: string) { return db.shot.findMany({ where: { projectId }, @@ -47,9 +55,10 @@ export default async function ShotStatusPage({ const { projectId } = await searchParams; const canManage = ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(session.user.role); - const [projects, shots] = await Promise.all([ + const [projects, shots, episodeDueDates] = await Promise.all([ getProjects(), projectId ? getShotsForProject(projectId) : Promise.resolve([]), + projectId ? getEpisodeDueDatesForProject(projectId) : Promise.resolve([]), ]); const selectedProject = projects.find((p) => p.id === projectId) ?? null; @@ -60,6 +69,7 @@ export default async function ShotStatusPage({ selectedProjectId={projectId ?? null} selectedProject={selectedProject} shots={shots as any} + episodeDueDates={episodeDueDates} canManage={canManage} /> );