diff --git a/.kiro/specs/ultimate-lists-app/tasks.md b/.kiro/specs/ultimate-lists-app/tasks.md
index 3cc1251..9d32e6e 100644
--- a/.kiro/specs/ultimate-lists-app/tasks.md
+++ b/.kiro/specs/ultimate-lists-app/tasks.md
@@ -100,7 +100,7 @@
- **Property 7: List retrieval completeness**
- **Validates: Requirements 2.2**
-- [ ] 7. Build list detail page with item management
+- [x] 7. Build list detail page with item management
- Create /list/[id] page showing all items in a list
- Add ItemCard component with completion toggle, priority badge, and due date display
- Implement inline item creation
diff --git a/app/list/[id]/page.tsx b/app/list/[id]/page.tsx
new file mode 100644
index 0000000..92fda00
--- /dev/null
+++ b/app/list/[id]/page.tsx
@@ -0,0 +1,88 @@
+import { getListWithItems } from '@/lib/actions'
+import { notFound } from 'next/navigation'
+import Link from 'next/link'
+import { ArrowLeft, Plus } from 'lucide-react'
+import ItemCard from '@/components/ItemCard'
+import InlineItemCreate from '@/components/InlineItemCreate'
+
+export default async function ListDetailPage({ params }: { params: { id: string } }) {
+ const list = await getListWithItems(params.id)
+
+ if (!list) {
+ notFound()
+ }
+
+ const completedItems = list.items.filter(item => item.completed)
+ const incompleteItems = list.items.filter(item => !item.completed)
+
+ return (
+
+ {/* Header */}
+
+
+
+
Back to Lists
+
+
+
+
+
+ {completedItems.length} of {list.items.length} tasks completed
+
+
+
+ {/* Inline Item Creation */}
+
+
+
+
+ {/* Items List */}
+
+ {/* Incomplete Items */}
+ {incompleteItems.length > 0 && (
+
+
+ To Do ({incompleteItems.length})
+
+
+ {incompleteItems.map((item) => (
+
+ ))}
+
+
+ )}
+
+ {/* Completed Items */}
+ {completedItems.length > 0 && (
+
+
+ Completed ({completedItems.length})
+
+
+ {completedItems.map((item) => (
+
+ ))}
+
+
+ )}
+
+ {/* Empty State */}
+ {list.items.length === 0 && (
+
+
No tasks yet
+
Add your first task to get started
+
+ )}
+
+
+ )
+}
diff --git a/components/DeleteItemButton.tsx b/components/DeleteItemButton.tsx
index 416c1c2..a241778 100644
--- a/components/DeleteItemButton.tsx
+++ b/components/DeleteItemButton.tsx
@@ -7,19 +7,26 @@ import { Trash2 } from 'lucide-react'
interface DeleteItemButtonProps {
itemId: string
- listId: string
+ listId?: string
+ variant?: 'full' | 'icon'
}
-export default function DeleteItemButton({ itemId, listId }: DeleteItemButtonProps) {
+export default function DeleteItemButton({ itemId, listId, variant = 'full' }: DeleteItemButtonProps) {
const router = useRouter()
const [isDeleting, setIsDeleting] = useState(false)
const [showConfirm, setShowConfirm] = useState(false)
- const handleDelete = async () => {
+ const handleDelete = async (e: React.MouseEvent) => {
+ e.preventDefault()
+ e.stopPropagation()
setIsDeleting(true)
try {
await deleteItem(itemId)
- router.push(`/list/${listId}`)
+ if (listId) {
+ router.push(`/list/${listId}`)
+ } else {
+ router.refresh()
+ }
} catch (error) {
console.error('Error deleting item:', error)
setIsDeleting(false)
@@ -27,6 +34,18 @@ export default function DeleteItemButton({ itemId, listId }: DeleteItemButtonPro
}
}
+ const handleShowConfirm = (e: React.MouseEvent) => {
+ e.preventDefault()
+ e.stopPropagation()
+ setShowConfirm(true)
+ }
+
+ const handleCancel = (e: React.MouseEvent) => {
+ e.preventDefault()
+ e.stopPropagation()
+ setShowConfirm(false)
+ }
+
if (showConfirm) {
return (
@@ -38,7 +57,7 @@ export default function DeleteItemButton({ itemId, listId }: DeleteItemButtonPro
{isDeleting ? 'Deleting...' : 'Confirm'}