feat: enhance list management UI with create, edit, and delete functionality

- Add ListForm component for creating and editing lists with color picker
- Add Modal component for reusable dialog functionality
- Add DeleteListButton with confirmation dialog
- Add NewListButton for creating new lists
- Update ListCard to show edit/delete buttons on hover
- Update home page to use new list creation flow
- All components include proper error handling and loading states

Requirements: 2.1, 2.2, 2.4, 2.5
This commit is contained in:
2025-12-01 19:18:54 +00:00
parent 282a0295ec
commit c1afb2cb6e
7 changed files with 402 additions and 31 deletions

View File

@@ -0,0 +1,88 @@
'use client'
import { useState } from 'react'
import { Trash2 } from 'lucide-react'
import { deleteList } from '@/lib/actions'
import { useRouter } from 'next/navigation'
import Modal from './Modal'
interface DeleteListButtonProps {
listId: string
listTitle: string
itemCount: number
redirectAfterDelete?: boolean
}
export default function DeleteListButton({
listId,
listTitle,
itemCount,
redirectAfterDelete = false
}: DeleteListButtonProps) {
const router = useRouter()
const [isConfirmOpen, setIsConfirmOpen] = useState(false)
const [isDeleting, setIsDeleting] = useState(false)
const handleDelete = async () => {
setIsDeleting(true)
try {
await deleteList(listId)
setIsConfirmOpen(false)
if (redirectAfterDelete) {
router.push('/')
} else {
router.refresh()
}
} catch (err) {
console.error('Failed to delete list:', err)
alert('Failed to delete list. Please try again.')
} finally {
setIsDeleting(false)
}
}
return (
<>
<button
onClick={() => setIsConfirmOpen(true)}
className="text-red-600 hover:text-red-700 transition-colors p-2 hover:bg-red-50 rounded-lg"
aria-label="Delete list"
>
<Trash2 size={20} />
</button>
<Modal
isOpen={isConfirmOpen}
onClose={() => setIsConfirmOpen(false)}
title="Delete List"
>
<div className="space-y-4">
<p className="text-gray-700">
Are you sure you want to delete <strong>{listTitle}</strong>?
</p>
{itemCount > 0 && (
<p className="text-red-600 text-sm">
This will permanently delete {itemCount} {itemCount === 1 ? 'item' : 'items'}.
</p>
)}
<div className="flex gap-2 justify-end pt-2">
<button
onClick={() => setIsConfirmOpen(false)}
disabled={isDeleting}
className="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors disabled:opacity-50"
>
Cancel
</button>
<button
onClick={handleDelete}
disabled={isDeleting}
className="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors disabled:opacity-50"
>
{isDeleting ? 'Deleting...' : 'Delete'}
</button>
</div>
</div>
</Modal>
</>
)
}