Redesign ItemCard with smaller height and right-aligned priority

- Reduced padding from p-4/p-5 to p-3/p-3.5 for more compact cards
- Moved priority badge to the right side next to title
- Changed items-start to items-center for better alignment
- Description now limited to 1 line instead of 2
- Metadata section only shows if there's a due date or tags
- Cleaner, more compact layout
This commit is contained in:
2025-12-03 00:49:10 +00:00
parent bdff38c9a5
commit 6c5f2fbc1e

View File

@@ -33,24 +33,33 @@ function ItemCard({ item, listId }: ItemCardProps) {
const priorityColor = priorityColors[item.priority as keyof typeof priorityColors] || priorityColors.medium const priorityColor = priorityColors[item.priority as keyof typeof priorityColors] || priorityColors.medium
return ( return (
<div className="bg-white rounded-lg border border-gray-200 p-4 sm:p-5 hover:shadow-md active:shadow-lg transition-all group"> <div className="bg-white rounded-lg border border-gray-200 p-3 sm:p-3.5 hover:shadow-md active:shadow-lg transition-all group">
<div className="flex items-start gap-3 sm:gap-4"> <div className="flex items-center gap-2 sm:gap-3">
{/* Completion Toggle */} {/* Completion Toggle */}
<div className="pt-0.5 sm:pt-1 flex-shrink-0"> <div className="flex-shrink-0">
<ToggleItemButton itemId={item.id} completed={item.completed} variant="icon" /> <ToggleItemButton itemId={item.id} completed={item.completed} variant="icon" />
</div> </div>
{/* Content */} {/* Content */}
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<Link href={`/list/${listId}/item/${item.id}`} className="block"> <Link href={`/list/${listId}/item/${item.id}`} className="block">
<h3 className={`font-medium mb-1 text-sm sm:text-base ${ <div className="flex items-center justify-between gap-2">
item.completed ? 'text-gray-500 line-through' : 'text-gray-900' <h3 className={`font-medium text-sm sm:text-base ${
}`}> item.completed ? 'text-gray-500 line-through' : 'text-gray-900'
{item.title} }`}>
</h3> {item.title}
</h3>
{/* Priority Badge - moved to right */}
<span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium border flex-shrink-0 ${priorityColor}`}>
<AlertCircle size={12} className="flex-shrink-0" />
<span className="hidden xs:inline sm:inline">{item.priority.charAt(0).toUpperCase() + item.priority.slice(1)}</span>
<span className="xs:hidden sm:hidden">{item.priority.charAt(0).toUpperCase()}</span>
</span>
</div>
{item.description && ( {item.description && (
<p className={`text-xs sm:text-sm mb-2 line-clamp-2 ${ <p className={`text-xs sm:text-sm mt-1 line-clamp-1 ${
item.completed ? 'text-gray-400' : 'text-gray-600' item.completed ? 'text-gray-400' : 'text-gray-600'
}`}> }`}>
{item.description} {item.description}
@@ -58,42 +67,37 @@ function ItemCard({ item, listId }: ItemCardProps) {
)} )}
{/* Metadata */} {/* Metadata */}
<div className="flex flex-wrap items-center gap-1.5 sm:gap-2 mt-2"> {(item.dueDate || tags.length > 0) && (
{/* Priority Badge */} <div className="flex flex-wrap items-center gap-1.5 sm:gap-2 mt-1.5">
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded text-xs font-medium border ${priorityColor}`}> {/* Due Date */}
<AlertCircle size={12} className="flex-shrink-0" /> {item.dueDate && (
<span className="hidden xs:inline sm:inline">{item.priority.charAt(0).toUpperCase() + item.priority.slice(1)}</span> <span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs whitespace-nowrap ${
<span className="xs:hidden sm:hidden">{item.priority.charAt(0).toUpperCase()}</span> isOverdue
</span> ? 'bg-red-100 text-red-700 border border-red-200 font-semibold'
: 'bg-gray-100 text-gray-700'
{/* Due Date */} }`}>
{item.dueDate && ( <Calendar size={12} className="flex-shrink-0" />
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded text-xs whitespace-nowrap ${ {new Date(item.dueDate).toLocaleDateString('en-US', {
isOverdue month: 'short',
? 'bg-red-100 text-red-700 border border-red-200 font-semibold' day: 'numeric',
: 'bg-gray-100 text-gray-700' })}
}`}> {isOverdue && <span className="hidden sm:inline"> (Overdue)</span>}
<Calendar size={12} className="flex-shrink-0" /> {isOverdue && <span className="sm:hidden">!</span>}
{new Date(item.dueDate).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
})}
{isOverdue && <span className="hidden sm:inline"> (Overdue)</span>}
{isOverdue && <span className="sm:hidden">!</span>}
</span>
)}
{/* Tags */}
{tags.length > 0 && (
<div className="inline-flex items-center gap-1">
<Tag size={12} className="text-gray-400 flex-shrink-0" />
<span className="text-xs text-gray-600 truncate max-w-[120px] sm:max-w-none">
{tags.slice(0, 2).join(', ')}
{tags.length > 2 && ` +${tags.length - 2}`}
</span> </span>
</div> )}
)}
</div> {/* Tags */}
{tags.length > 0 && (
<div className="inline-flex items-center gap-1">
<Tag size={12} className="text-gray-400 flex-shrink-0" />
<span className="text-xs text-gray-600 truncate max-w-[120px] sm:max-w-none">
{tags.slice(0, 2).join(', ')}
{tags.length > 2 && ` +${tags.length - 2}`}
</span>
</div>
)}
</div>
)}
</Link> </Link>
</div> </div>