diff --git a/components/board/group-card.tsx b/components/board/group-card.tsx index 7858017..6c36700 100644 --- a/components/board/group-card.tsx +++ b/components/board/group-card.tsx @@ -6,6 +6,7 @@ import { CSS } from "@dnd-kit/utilities"; import { useTheme } from "next-themes"; import { Archive, + ChevronRight, ClipboardList, GripVertical, MoreVertical, @@ -94,6 +95,7 @@ export function GroupCard({ group }: { group: GroupDTO }) { const [todoAiOpen, setTodoAiOpen] = useState(false); const [todoCreateOpen, setTodoCreateOpen] = useState(false); const [statusUpdateOpen, setStatusUpdateOpen] = useState(false); + const [expandedWhileComplete, setExpandedWhileComplete] = useState(false); const { attributes, @@ -143,6 +145,26 @@ export function GroupCard({ group }: { group: GroupDTO }) { // from the list entirely rather than shown crossed-out. const visibleTodos = compact ? group.todos.filter((t) => !t.completed) : group.todos; + // In the default view, a fully-checked-off group collapses down to just + // its header (title, notes icon, kebab menu) with a disclosure triangle + // in place of the drag-grip dots, so a board full of "done" groups + // doesn't stay as visually loud as one still full of open work. The + // triangle re-expands it back to the normal full card. Compact already + // hides finished groups outright (see CategoryLane), so this only + // applies to the default view. + const showDisclosure = !compact && canArchive; + // Reset back to collapsed each time the group freshly becomes fully + // done, rather than remembering a stale expanded choice from its last + // completion cycle. Adjusting state during render (comparing against + // last render's value) instead of in a useEffect avoids an extra render + // pass -- see https://react.dev/learn/you-might-not-need-an-effect. + const [wasComplete, setWasComplete] = useState(canArchive); + if (canArchive !== wasComplete) { + setWasComplete(canArchive); + if (canArchive) setExpandedWhileComplete(false); + } + const isCollapsed = showDisclosure && !expandedWhileComplete; + return ( <>
- - - + {showDisclosure ? ( + + ) : ( + + + + )}

{group.title}

@@ -207,111 +246,116 @@ export function GroupCard({ group }: { group: GroupDTO }) {
- - {compact ? ( - // Defensive fallback -- shouldn't normally happen, since - // CategoryLane already hides a compact group with zero visible - // to-dos, but keeps the "+" reachable if that ever changes. - visibleTodos.length === 0 && ( -
- setTodoCreateOpen(true)} - onAiClick={() => setTodoAiOpen(true)} - aiConfigured={aiConfigured} - /> -
- ) - ) : ( - <> -
- -
+ {canArchive && ( + + )} - {aiConfigured && ( - + + )} - - {canArchive && ( - - )} - - )}