"use client"; import * as React from "react"; import { useEffect, useState } from "react"; import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, type DragEndEvent, } from "@dnd-kit/core"; import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, } from "@dnd-kit/sortable"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { Input } from "~/components/ui/input"; import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { DatePicker } from "~/components/ui/date-picker"; import { NumberInput } from "~/components/ui/number-input"; import { Textarea } from "~/components/ui/textarea"; import { Trash2, GripVertical, ChevronUp, ChevronDown } from "lucide-react"; interface InvoiceItem { id: string; date: Date; description: string; hours: number; rate: number; amount: number; } interface EditableInvoiceItemsProps { items: InvoiceItem[]; onItemsChange: (items: InvoiceItem[]) => void; onRemoveItem: (index: number) => void; } function SortableItem({ item, index, onItemChange, onRemove, onMoveUp, onMoveDown, canMoveUp, canMoveDown, }: { item: InvoiceItem; index: number; onItemChange: ( index: number, field: string, value: string | number | Date, ) => void; onRemove: (index: number) => void; onMoveUp: (index: number) => void; onMoveDown: (index: number) => void; canMoveUp: boolean; canMoveDown: boolean; }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: item.id }); const style = { transform: CSS.Transform.toString(transform), transition, }; const handleItemChange = (field: string, value: string | number | Date) => { onItemChange(index, field, value); }; return (
{/* Desktop Layout - Hidden on Mobile */}
{/* Drag Handle */}
{/* Date */}
handleItemChange("date", date ?? new Date()) } size="sm" className="w-full" />
{/* Description */}
handleItemChange("description", e.target.value)} placeholder="Work description" className="h-9" />
{/* Hours */}
handleItemChange("hours", value)} min={0} step={0.25} placeholder="0" width="full" />
{/* Rate */}
handleItemChange("rate", value)} min={0} step={0.01} placeholder="0.00" prefix="$" width="full" />
{/* Amount */}
${item.amount.toFixed(2)}
{/* Remove Button */}
{/* Mobile Layout - Visible on Mobile Only */}
{/* Header with Item Number and Controls */}
Item {index + 1}
{/* Description */}