Task card: excel-style grid with sharp corners, border cells, no status bg

This commit is contained in:
lorentz 2026-04-10 14:49:25 +00:00
parent 4852acafda
commit ae66f931f7

View file

@ -270,65 +270,64 @@ function TaskCard({ task: initial }: { task: Task }) {
)}
</div>
{/* Right sidebar: 2-col — data col auto-width, icon col fixed */}
<div className="shrink-0 border-l border-border flex flex-col text-[12px]">
<div className="flex-1 flex">
{/* Left col: Due / Status / Level (data only, fit to content) */}
<div className="flex flex-col justify-center gap-1 px-3 py-2.5 whitespace-nowrap text-xs">
<span className={`font-bold rounded px-1.5 py-0.5 w-fit ${dueBg}`} suppressHydrationWarning>
{formatDate(task.dueDate)}
</span>
<Select value={task.status} onValueChange={handleQuickStatus} disabled={statusUpdating}>
<SelectTrigger className="h-auto border-0 p-0 shadow-none text-xs font-medium hover:underline focus:ring-0 w-auto gap-1">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="NOT_STARTED">Not Started</SelectItem>
<SelectItem value="IN_PROGRESS">In Progress</SelectItem>
<SelectItem value="BLOCKED">Blocked</SelectItem>
<SelectItem value="COMPLETED">Completed</SelectItem>
<SelectItem value="NA">N/A</SelectItem>
</SelectContent>
</Select>
<span className="text-xs text-muted-foreground">
{levelLabel}
</span>
</div>
{/* Right col: Complete / N/A / Edit (icon-only) */}
<div className="flex flex-col items-center justify-center gap-1 px-2 border-l border-border">
<button
onClick={handleToggleStatus}
disabled={toggling}
className="p-1.5 rounded hover:bg-muted transition-colors disabled:opacity-50"
title={isCompleted ? 'Reopen' : 'Complete'}
>
{isCompleted
? <RotateCcw className="h-5 w-5" />
: <CheckCircle2 className="h-5 w-5" />
}
</button>
{task.status !== 'COMPLETED' && task.status !== 'NA' && task.status !== 'CANCELLED' && (
<button
onClick={() => setNaDialogOpen(true)}
className="p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
title="Mark as N/A"
>
<Ban className="h-5 w-5" />
</button>
)}
<button
onClick={() => setEditOpen(true)}
className="p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
title="Edit task"
>
<Pencil className="h-5 w-5" />
</button>
</div>
{/* Right sidebar: excel-style grid */}
<div className="shrink-0 border-l border-border grid grid-cols-[auto_40px] text-xs">
{/* Row 1: Due date | Complete */}
<div className={`px-3 py-1.5 border-b border-border flex items-center whitespace-nowrap ${dueBg}`}>
<span className="font-bold" suppressHydrationWarning>{formatDate(task.dueDate)}</span>
</div>
{/* Notes: full width bottom */}
<button
onClick={handleToggleStatus}
disabled={toggling}
className="border-b border-l border-border flex items-center justify-center hover:bg-muted transition-colors disabled:opacity-50"
title={isCompleted ? 'Reopen' : 'Complete'}
>
{isCompleted
? <RotateCcw className="h-5 w-5" />
: <CheckCircle2 className="h-5 w-5" />
}
</button>
{/* Row 2: Status | N/A */}
<div className="px-3 py-1.5 border-b border-border flex items-center">
<Select value={task.status} onValueChange={handleQuickStatus} disabled={statusUpdating}>
<SelectTrigger className="h-auto border-0 p-0 shadow-none text-xs font-medium hover:underline focus:ring-0 w-auto gap-1">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="NOT_STARTED">Not Started</SelectItem>
<SelectItem value="IN_PROGRESS">In Progress</SelectItem>
<SelectItem value="BLOCKED">Blocked</SelectItem>
<SelectItem value="COMPLETED">Completed</SelectItem>
<SelectItem value="NA">N/A</SelectItem>
</SelectContent>
</Select>
</div>
{task.status !== 'COMPLETED' && task.status !== 'NA' && task.status !== 'CANCELLED' ? (
<button
onClick={() => setNaDialogOpen(true)}
className="border-b border-l border-border flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
title="Mark as N/A"
>
<Ban className="h-5 w-5" />
</button>
) : (
<div className="border-b border-l border-border" />
)}
{/* Row 3: Level | Edit */}
<div className="px-3 py-1.5 border-b border-border flex items-center text-muted-foreground">
{levelLabel}
</div>
<button
onClick={() => setEditOpen(true)}
className="border-b border-l border-border flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
title="Edit task"
>
<Pencil className="h-5 w-5" />
</button>
{/* Row 4: Notes spanning both cols */}
<button
onClick={() => setNoteOpen((o) => !o)}
className={`flex items-center justify-center gap-1.5 py-1.5 border-t border-border text-[11px] font-medium transition-colors ${
className={`col-span-2 flex items-center justify-center gap-1.5 py-1.5 text-[11px] font-medium transition-colors ${
noteOpen ? 'bg-secondary text-foreground' : 'text-muted-foreground hover:text-foreground hover:bg-muted'
}`}
>