"use client"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { colorModeFromTheme } from "@/components/theme/use-dark-theme"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { MDEditor } from "@/components/markdown/markdown-widgets"; import { useBoard } from "@/components/board/board-context"; import type { CategoryDTO } from "@/types/board"; const TITLE_MAX = 20; // Same fields and `addTodo` call as TodoCreatePopover's inline form, but as // a controlled Dialog instead of owning its own popover trigger -- this is // opened from the compact view's "+" dropdown menu rather than from an // inline "+ Add to-do" button. export function TodoCreateDialog({ groupId, categoryId, categories, open, onOpenChange, }: { // Default/only target group+category. When `categories` is also passed, // this is just the pre-selected option in the "Group" dropdown below, // not the final destination. groupId: string; categoryId: string; // Pass the full board (or leave undefined) to show a "Group" dropdown // letting the user redirect the to-do elsewhere -- used by the quick-add // button, whose default target is otherwise just "whichever group // happens to be first". Omitted from the per-group "+" menu, where the // group is already unambiguous from context. categories?: CategoryDTO[]; open: boolean; onOpenChange: (open: boolean) => void; }) { const { addTodo } = useBoard(); const colorMode = colorModeFromTheme(); const [title, setTitle] = useState(""); const [details, setDetails] = useState(""); const [selectedGroupId, setSelectedGroupId] = useState(groupId); const [pending, setPending] = useState(false); const groupOptions = categories?.flatMap((c) => c.groups.map((g) => ({ groupId: g.id, categoryId: c.id, label: `${c.name} - ${g.title}` })) ); // Only meaningful when `categories` is passed -- otherwise the dialog's // single fixed target (the props above) is used as-is. const targetCategoryId = groupOptions?.find((o) => o.groupId === selectedGroupId)?.categoryId ?? categoryId; const targetGroupId = groupOptions ? selectedGroupId : groupId; function handleOpenChange(next: boolean) { if (!next) { setTitle(""); setDetails(""); setSelectedGroupId(groupId); } onOpenChange(next); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); const trimmed = title.trim(); if (!trimmed) return; setPending(true); const ok = await addTodo(targetGroupId, targetCategoryId, trimmed, details.trim() || undefined); setPending(false); if (ok) handleOpenChange(false); } return ( Add to-do
{groupOptions && (
)}
setTitle(e.target.value)} placeholder="e.g. Buy milk" />

{title.length}/{TITLE_MAX}

setDetails(v ?? "")} height={160} textareaProps={{ id: `create-todo-details-${groupId}` }} />
); }