style: apply soft dashboard card visual design
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,11 +12,11 @@ import type { Task } from '../../types';
|
||||
|
||||
|
||||
const STATUS_STYLE: Record<string, string> = {
|
||||
IN_PROGRESS: 'bg-blue-500 text-white',
|
||||
REVIEW: 'bg-orange-400 text-white',
|
||||
TODO: 'bg-gray-300 text-gray-700',
|
||||
DONE: 'bg-emerald-500 text-white',
|
||||
CANCELLED: 'bg-gray-200 text-gray-500',
|
||||
IN_PROGRESS: 'bg-blue-500 text-white shadow-blue-500/20',
|
||||
REVIEW: 'bg-amber-400 text-white shadow-amber-400/20',
|
||||
TODO: 'bg-slate-200 text-slate-600 shadow-slate-300/20',
|
||||
DONE: 'bg-emerald-500 text-white shadow-emerald-500/20',
|
||||
CANCELLED: 'bg-slate-200 text-slate-400 shadow-slate-300/20',
|
||||
};
|
||||
|
||||
const STATUS_LABEL: Record<string, string> = {
|
||||
@@ -163,7 +163,7 @@ export function TaskCard({
|
||||
style={dragStyle}
|
||||
{...dragAttributes}
|
||||
{...dragListeners}
|
||||
className="bg-white rounded-2xl px-5 py-3 mb-3 shadow-sm border border-gray-100 hover:shadow-md hover:border-gray-200 transition-all select-none cursor-grab active:cursor-grabbing overflow-hidden"
|
||||
className="mb-3 cursor-grab select-none overflow-hidden rounded-[1.35rem] border border-white/80 bg-white px-5 py-4 shadow-[0_10px_28px_rgba(15,23,42,0.08)] ring-1 ring-slate-200/60 transition-all hover:-translate-y-0.5 hover:shadow-[0_18px_34px_rgba(15,23,42,0.14)] active:cursor-grabbing"
|
||||
onPointerDown={(e) => {
|
||||
// 우클릭(button !== 0)을 dnd-kit에 전달하지 않음
|
||||
// dnd-kit은 pointerdown→pointerup 시 synthetic click을 발화하는데
|
||||
@@ -177,11 +177,11 @@ export function TaskCard({
|
||||
{/* ── 상단: 제목 + 진행률 ── */}
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex items-start gap-2 min-w-0 flex-1">
|
||||
<span className="text-2xl font-bold text-gray-900 leading-snug min-w-0 truncate">
|
||||
<span className="min-w-0 truncate text-2xl font-black leading-snug text-slate-900">
|
||||
{task.title}
|
||||
</span>
|
||||
</div>
|
||||
<span className={`shrink-0 text-2xl font-black mt-0.5 min-w-[4rem] text-right ${
|
||||
<span className={`mt-0.5 min-w-[4rem] shrink-0 text-right text-2xl font-black ${
|
||||
task.progress >= 70 ? 'text-emerald-500' :
|
||||
task.progress >= 40 ? 'text-blue-400' :
|
||||
'text-orange-400'
|
||||
@@ -193,26 +193,26 @@ export function TaskCard({
|
||||
|
||||
{/* ── 기간 + 상태 ── */}
|
||||
<div className="mt-1 flex items-center gap-2">
|
||||
<span className="text-sm text-gray-400 font-medium flex-1 truncate">
|
||||
<span className="flex-1 truncate text-sm font-semibold text-slate-400">
|
||||
{task.showDate && (task.startDate || task.dueDate)
|
||||
? `${task.startDate ? fmtDate(task.startDate) : '?'} ~ ${task.dueDate ? fmtDate(task.dueDate) : '?'}`
|
||||
: ''}
|
||||
</span>
|
||||
<span className={`text-sm font-bold px-2.5 py-0.5 rounded-full ${STATUS_STYLE[task.status]} shrink-0`}>
|
||||
<span className={`shrink-0 rounded-full px-2.5 py-0.5 text-sm font-black shadow-sm ${STATUS_STYLE[task.status]}`}>
|
||||
{STATUS_LABEL[task.status]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* ── description ── */}
|
||||
{task.description && (
|
||||
<div className="mt-1.5 text-2xl text-gray-700 truncate">
|
||||
<div className="mt-2 truncate text-2xl text-slate-700">
|
||||
{task.description}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ── 이슈 메모 ── */}
|
||||
{task.issueNote && (
|
||||
<div className="mt-1 flex gap-2 text-2xl text-red-500 min-w-0">
|
||||
<div className="mt-1.5 flex min-w-0 gap-2 rounded-xl bg-red-50/80 px-2 py-1 text-2xl text-red-500">
|
||||
<span className="shrink-0">▶</span>
|
||||
<span className="truncate">{task.issueNote}</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user