Task card: excel-style grid with sharp corners, border cells, no status bg
This commit is contained in:
parent
4852acafda
commit
ae66f931f7
1 changed files with 55 additions and 56 deletions
|
|
@ -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'
|
||||
}`}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue