feat: implement responsive design enhancements
- Add touch-optimized tap targets (44x44px minimum for iOS) - Enhance mobile responsiveness across all components - Improve button sizing and spacing for touch interactions - Add responsive text sizing and layout adjustments - Implement mobile-first modal behavior (bottom sheet on mobile) - Enhance form controls with better touch targets - Add active states for better touch feedback - Improve grid layouts for various screen sizes - Add smooth scrolling and better focus states - Optimize FilterPanel for mobile with grid layouts - Enhance all interactive elements with tap-target classes Requirements: 7.1, 7.2
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { Calendar, Tag, AlertCircle, Trash2 } from 'lucide-react'
|
||||
import { Calendar, Tag, AlertCircle } from 'lucide-react'
|
||||
import ToggleItemButton from './ToggleItemButton'
|
||||
import DeleteItemButton from './DeleteItemButton'
|
||||
|
||||
@@ -33,24 +32,24 @@ export default function ItemCard({ item, listId }: ItemCardProps) {
|
||||
const priorityColor = priorityColors[item.priority as keyof typeof priorityColors] || priorityColors.medium
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow group">
|
||||
<div className="flex items-start gap-3">
|
||||
<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="flex items-start gap-3 sm:gap-4">
|
||||
{/* Completion Toggle */}
|
||||
<div className="pt-1">
|
||||
<div className="pt-0.5 sm:pt-1 flex-shrink-0">
|
||||
<ToggleItemButton itemId={item.id} completed={item.completed} variant="icon" />
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link href={`/list/${listId}/item/${item.id}`} className="block">
|
||||
<h3 className={`font-medium mb-1 ${
|
||||
<h3 className={`font-medium mb-1 text-sm sm:text-base ${
|
||||
item.completed ? 'text-gray-500 line-through' : 'text-gray-900'
|
||||
}`}>
|
||||
{item.title}
|
||||
</h3>
|
||||
|
||||
{item.description && (
|
||||
<p className={`text-sm mb-2 line-clamp-2 ${
|
||||
<p className={`text-xs sm:text-sm mb-2 line-clamp-2 ${
|
||||
item.completed ? 'text-gray-400' : 'text-gray-600'
|
||||
}`}>
|
||||
{item.description}
|
||||
@@ -58,34 +57,36 @@ export default function ItemCard({ item, listId }: ItemCardProps) {
|
||||
)}
|
||||
|
||||
{/* Metadata */}
|
||||
<div className="flex flex-wrap items-center gap-2 mt-2">
|
||||
<div className="flex flex-wrap items-center gap-1.5 sm:gap-2 mt-2">
|
||||
{/* Priority Badge */}
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded text-xs font-medium border ${priorityColor}`}>
|
||||
<AlertCircle size={12} />
|
||||
{item.priority.charAt(0).toUpperCase() + item.priority.slice(1)}
|
||||
<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>
|
||||
|
||||
{/* Due Date */}
|
||||
{item.dueDate && (
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded text-xs ${
|
||||
<span className={`inline-flex items-center gap-1 px-2 py-1 rounded text-xs whitespace-nowrap ${
|
||||
isOverdue
|
||||
? 'bg-red-100 text-red-700 border border-red-200 font-semibold'
|
||||
: 'bg-gray-100 text-gray-700'
|
||||
}`}>
|
||||
<Calendar size={12} />
|
||||
<Calendar size={12} className="flex-shrink-0" />
|
||||
{new Date(item.dueDate).toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})}
|
||||
{isOverdue && ' (Overdue)'}
|
||||
{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" />
|
||||
<span className="text-xs text-gray-600">
|
||||
<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>
|
||||
@@ -96,7 +97,7 @@ export default function ItemCard({ item, listId }: ItemCardProps) {
|
||||
</div>
|
||||
|
||||
{/* Delete Button */}
|
||||
<div className="opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<div className="opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity flex-shrink-0">
|
||||
<DeleteItemButton itemId={item.id} variant="icon" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user