table displays and memory
Deploy / deploy (push) Failing after 2m48s

This commit is contained in:
twotalesanimation
2026-06-07 14:39:21 +02:00
parent fcd19d2ca0
commit ecaa963055
2 changed files with 35 additions and 8 deletions
@@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useTransition } from "react"; import { useState, useTransition, useEffect } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { ShotCard } from "@/components/shots/ShotCard"; import { ShotCard } from "@/components/shots/ShotCard";
@@ -89,8 +89,16 @@ export function ProjectTabsClient({
const [showImportShots, setShowImportShots] = useState(false); const [showImportShots, setShowImportShots] = useState(false);
const [showNewAsset, setShowNewAsset] = useState(false); const [showNewAsset, setShowNewAsset] = useState(false);
const [showNewTask, setShowNewTask] = useState(false); const [showNewTask, setShowNewTask] = useState(false);
const [collapsedEpisodes, setCollapsedEpisodes] = useState<Set<string>>(new Set()); const [expandedEpisodes, setExpandedEpisodes] = useState<Set<string>>(new Set());
const [editingEpisode, setEditingEpisode] = useState<string | null>(null); const [editingEpisode, setEditingEpisode] = useState<string | null>(null);
// Load saved episode expand state from localStorage on mount
useEffect(() => {
try {
const saved = localStorage.getItem(`project:${projectId}:episodeExpand`);
if (saved) setExpandedEpisodes(new Set(JSON.parse(saved) as string[]));
} catch {}
}, [projectId]);
const [episodeDateInput, setEpisodeDateInput] = useState(""); const [episodeDateInput, setEpisodeDateInput] = useState("");
const [isPendingDate, startDateTransition] = useTransition(); const [isPendingDate, startDateTransition] = useTransition();
@@ -118,9 +126,12 @@ export function ProjectTabsClient({
}; };
const toggleEpisode = (ep: string) => const toggleEpisode = (ep: string) =>
setCollapsedEpisodes((prev) => { setExpandedEpisodes((prev) => {
const next = new Set(prev); const next = new Set(prev);
next.has(ep) ? next.delete(ep) : next.add(ep); next.has(ep) ? next.delete(ep) : next.add(ep);
try {
localStorage.setItem(`project:${projectId}:episodeExpand`, JSON.stringify([...next]));
} catch {}
return next; return next;
}); });
@@ -243,7 +254,7 @@ export function ProjectTabsClient({
) : projectType === "EPISODIC" ? ( ) : projectType === "EPISODIC" ? (
<div className="space-y-4"> <div className="space-y-4">
{episodeGroups.map(([episode, episodeShots]) => { {episodeGroups.map(([episode, episodeShots]) => {
const collapsed = collapsedEpisodes.has(episode); const collapsed = !expandedEpisodes.has(episode);
const dueDate = episodeDueDateMap.get(episode); const dueDate = episodeDueDateMap.get(episode);
const isOverdue = dueDate && dueDate < new Date(); const isOverdue = dueDate && dueDate < new Date();
const isEditing = editingEpisode === episode; const isEditing = editingEpisode === episode;
@@ -350,7 +361,7 @@ export function ProjectTabsClient({
) : standardGroups.length > 0 ? ( ) : standardGroups.length > 0 ? (
<div className="space-y-4"> <div className="space-y-4">
{standardGroups.map(([groupName, groupShots]) => { {standardGroups.map(([groupName, groupShots]) => {
const collapsed = collapsedEpisodes.has(groupName); const collapsed = !expandedEpisodes.has(groupName);
return ( return (
<div key={groupName}> <div key={groupName}>
<button <button
@@ -406,14 +406,30 @@ export function ShotStatusClient({
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
const [collapsedEpisodes, setCollapsedEpisodes] = useState<Set<string>>(new Set()); const [expandedEpisodes, setExpandedEpisodes] = useState<Set<string>>(new Set());
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set()); const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
// Load saved episode expand state when project changes
useEffect(() => {
if (!selectedProjectId) return;
try {
const saved = localStorage.getItem(`shotStatus:${selectedProjectId}:episodeExpand`);
setExpandedEpisodes(saved ? new Set(JSON.parse(saved) as string[]) : new Set());
} catch {
setExpandedEpisodes(new Set());
}
}, [selectedProjectId]);
const [dueDateDialogOpen, setDueDateDialogOpen] = useState(false); const [dueDateDialogOpen, setDueDateDialogOpen] = useState(false);
const toggleEpisode = (ep: string) => const toggleEpisode = (ep: string) =>
setCollapsedEpisodes((prev) => { setExpandedEpisodes((prev) => {
const next = new Set(prev); const next = new Set(prev);
next.has(ep) ? next.delete(ep) : next.add(ep); next.has(ep) ? next.delete(ep) : next.add(ep);
if (selectedProjectId) {
try {
localStorage.setItem(`shotStatus:${selectedProjectId}:episodeExpand`, JSON.stringify([...next]));
} catch {}
}
return next; return next;
}); });
@@ -571,7 +587,7 @@ export function ShotStatusClient({
{isEpisodic ? ( {isEpisodic ? (
<div className="divide-y divide-zinc-800"> <div className="divide-y divide-zinc-800">
{episodeGroups.map(([episode, episodeShots]) => { {episodeGroups.map(([episode, episodeShots]) => {
const collapsed = collapsedEpisodes.has(episode); const collapsed = !expandedEpisodes.has(episode);
const episodeIds = episodeShots.map((s) => s.id); const episodeIds = episodeShots.map((s) => s.id);
const allEpSelected = episodeIds.every((id) => selectedIds.has(id)); const allEpSelected = episodeIds.every((id) => selectedIds.has(id));
const someEpSelected = episodeIds.some((id) => selectedIds.has(id)); const someEpSelected = episodeIds.some((id) => selectedIds.has(id));