From a68b6c7b8c1c7c2d338b191883a6827b35fbadcb Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 15 Feb 2026 18:49:10 +0200 Subject: [PATCH] feat: add board view with columns, headers, and inline card creation --- src/components/board/AddCardInput.tsx | 53 ++++++++++ src/components/board/BoardView.tsx | 102 ++++++++++++++++++ src/components/board/ColumnHeader.tsx | 142 ++++++++++++++++++++++++++ src/components/board/KanbanColumn.tsx | 72 +++++++++++++ 4 files changed, 369 insertions(+) create mode 100644 src/components/board/AddCardInput.tsx create mode 100644 src/components/board/BoardView.tsx create mode 100644 src/components/board/ColumnHeader.tsx create mode 100644 src/components/board/KanbanColumn.tsx diff --git a/src/components/board/AddCardInput.tsx b/src/components/board/AddCardInput.tsx new file mode 100644 index 0000000..8a02beb --- /dev/null +++ b/src/components/board/AddCardInput.tsx @@ -0,0 +1,53 @@ +import { useState, useRef, useEffect } from "react"; +import { useBoardStore } from "@/stores/board-store"; + +interface AddCardInputProps { + columnId: string; + onClose: () => void; +} + +export function AddCardInput({ columnId, onClose }: AddCardInputProps) { + const [value, setValue] = useState(""); + const textareaRef = useRef(null); + const addCard = useBoardStore((s) => s.addCard); + + useEffect(() => { + textareaRef.current?.focus(); + }, []); + + function handleSubmit() { + const trimmed = value.trim(); + if (trimmed) { + addCard(columnId, trimmed); + setValue(""); + // Keep the input open for quick multi-add + textareaRef.current?.focus(); + } + } + + function handleKeyDown(e: React.KeyboardEvent) { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSubmit(); + } else if (e.key === "Escape") { + onClose(); + } + } + + return ( +
+