"use client"; import { useCallback } from "react"; import Link from "next/link"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { toast } from "sonner"; import type { Issue, UpdateIssueRequest } from "@/shared/types"; import { CalendarDays } from "lucide-react"; import { ActorAvatar } from "@/components/common/actor-avatar"; import { api } from "@/shared/api"; import { useIssueStore } from "@/features/issues/store"; import { PriorityIcon } from "./priority-icon"; import { PriorityPicker, AssigneePicker, DueDatePicker } from "./pickers"; import { PRIORITY_CONFIG } from "@/features/issues/config"; import { useIssueViewStore, type CardProperties } from "@/features/issues/stores/view-store"; function formatDate(date: string): string { return new Date(date).toLocaleDateString("en-US", { month: "short", day: "numeric", }); } /** Stops event from bubbling to Link/drag handlers */ function PickerWrapper({ children }: { children: React.ReactNode }) { const stop = (e: React.SyntheticEvent) => { e.stopPropagation(); e.preventDefault(); }; return (
{children}
); } export function BoardCardContent({ issue, editable = false, }: { issue: Issue; editable?: boolean; }) { const storeProperties = useIssueViewStore((s) => s.cardProperties); const priorityCfg = PRIORITY_CONFIG[issue.priority]; const handleUpdate = useCallback( (updates: Partial) => { useIssueStore.getState().updateIssue(issue.id, updates); api.updateIssue(issue.id, updates).catch(() => { toast.error("Failed to update issue"); }); }, [issue.id] ); const showPriority = storeProperties.priority; const showDescription = storeProperties.description && issue.description; const showAssignee = storeProperties.assignee && issue.assignee_type && issue.assignee_id; const showDueDate = storeProperties.dueDate && issue.due_date; const showBottom = showAssignee || showDueDate; return (
{/* Priority */} {showPriority && (editable ? ( {priorityCfg.label} } /> ) : (
{priorityCfg.label}
))} {/* Title */}

{issue.title}

{/* Description */} {showDescription && (

{issue.description}

)} {/* Bottom: assignee + due date */} {showBottom && (
{showAssignee && (editable ? ( } /> ) : ( ))}
{showDueDate && (editable ? ( {formatDate(issue.due_date!)} } /> ) : ( {formatDate(issue.due_date!)} ))}
)}
); } export function DraggableBoardCard({ issue }: { issue: Issue }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: issue.id, data: { status: issue.status }, }); const style = { transform: CSS.Transform.toString(transform), transition, }; return (
); }