From 180513b2e589fb63efb330dec5b5f9c02e87eddd Mon Sep 17 00:00:00 2001 From: Scrum4Me Agent <30029041+madhura68@users.noreply.github.com> Date: Wed, 6 May 2026 11:46:16 +0200 Subject: [PATCH] feat(cleanup): verwijder app/(app)/todos/ en components/todos/ [cmottjvzo000cx3172472cu4g] --- app/(app)/todos/loading.tsx | 19 - app/(app)/todos/page.tsx | 47 --- components/todos/todo-list.tsx | 687 --------------------------------- 3 files changed, 753 deletions(-) delete mode 100644 app/(app)/todos/loading.tsx delete mode 100644 app/(app)/todos/page.tsx delete mode 100644 components/todos/todo-list.tsx diff --git a/app/(app)/todos/loading.tsx b/app/(app)/todos/loading.tsx deleted file mode 100644 index 61d4ec9..0000000 --- a/app/(app)/todos/loading.tsx +++ /dev/null @@ -1,19 +0,0 @@ -export default function Loading() { - return ( -
-
-
-
-
-
-
-
-
- {[1, 2, 3, 4, 5].map(i => ( -
- ))} -
-
-
- ) -} diff --git a/app/(app)/todos/page.tsx b/app/(app)/todos/page.tsx deleted file mode 100644 index 27f07f4..0000000 --- a/app/(app)/todos/page.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { cookies } from 'next/headers' -import { getIronSession } from 'iron-session' -import { SessionData, sessionOptions } from '@/lib/session' -import { prisma } from '@/lib/prisma' -import { productAccessFilter } from '@/lib/product-access' -import { TodoList } from '@/components/todos/todo-list' - -export default async function TodosPage() { - const session = await getIronSession(await cookies(), sessionOptions) - - const todos = await prisma.todo.findMany({ - where: { user_id: session.userId, archived: false }, - orderBy: { created_at: 'asc' }, - include: { product: { select: { name: true } } }, - }) - - const products = await prisma.product.findMany({ - where: { ...productAccessFilter(session.userId), archived: false }, - orderBy: { name: 'asc' }, - include: { - pbis: { orderBy: [{ priority: 'asc' }, { sort_order: 'asc' }], select: { id: true, title: true } }, - }, - }) - - return ( -
-

Todo's

- ({ - id: t.id, - title: t.title, - description: t.description ?? null, - done: t.done, - created_at: t.created_at.toISOString(), - product_id: t.product_id ?? null, - product_name: t.product?.name ?? null, - }))} - products={products.map(p => ({ - id: p.id, - name: p.name, - pbis: p.pbis, - }))} - isDemo={session.isDemo ?? false} - /> -
- ) -} diff --git a/components/todos/todo-list.tsx b/components/todos/todo-list.tsx deleted file mode 100644 index 5db21b3..0000000 --- a/components/todos/todo-list.tsx +++ /dev/null @@ -1,687 +0,0 @@ -'use client' - -import { useState, useTransition, useMemo, useEffect, useRef, useCallback } from 'react' -import { useActionState } from 'react' -import { useFormStatus } from 'react-dom' -import { useRouter } from 'next/navigation' -import { - useReactTable, - getCoreRowModel, - getPaginationRowModel, - flexRender, - type ColumnDef, - type RowSelectionState, - type PaginationState, -} from '@tanstack/react-table' -import { toast } from 'sonner' -import { cn } from '@/lib/utils' -import { Button } from '@/components/ui/button' -import { Badge } from '@/components/ui/badge' -import { Input } from '@/components/ui/input' -import { Textarea } from '@/components/ui/textarea' -import { DemoTooltip } from '@/components/shared/demo-tooltip' -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { - createTodoAction, - updateTodoAction, - archiveSelectedTodosAction, - promoteTodoToPbiAction, - promoteTodoToStoryAction, - promoteTodoToIdeaAction, -} from '@/actions/todos' - -interface Todo { - id: string - title: string - description: string | null - done: boolean - created_at: string - product_id: string | null - product_name: string | null -} - -interface Pbi { - id: string - title: string -} - -interface Product { - id: string - name: string - pbis: Pbi[] -} - -interface TodoListProps { - todos: Todo[] - products: Product[] - isDemo: boolean -} - -// Checkbox with indeterminate support for TanStack row selection -function IndeterminateCheckbox({ - indeterminate, - className, - ...props -}: React.InputHTMLAttributes & { indeterminate?: boolean }) { - const ref = useRef(null) - useEffect(() => { - if (ref.current) ref.current.indeterminate = indeterminate ?? false - }, [indeterminate]) - return ( - - ) -} - -function SaveButton() { - const { pending } = useFormStatus() - return ( - - ) -} - -// --- Promote to PBI dialog --- -function PromotePbiDialog({ - todo, - products, - onClose, -}: { todo: Todo; products: Product[]; onClose: () => void }) { - const handleKey = useCallback((e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }, [onClose]) - useEffect(() => { - document.addEventListener('keydown', handleKey) - return () => document.removeEventListener('keydown', handleKey) - }, [handleKey]) - - const [state, formAction] = useActionState( - async (_prev: unknown, fd: FormData) => { - const result = await promoteTodoToPbiAction(_prev, fd) - if (result?.success) { toast.success('Todo gepromoveerd naar PBI'); onClose() } - return result - }, - undefined - ) - - return ( -
-
-

Promoveer naar PBI

-

Let op: dit kan niet ongedaan worden gemaakt.

-
- -
- - -
-
- - {products.length === 0 ? ( -

Maak eerst een product aan.

- ) : ( - - )} -
-
- - -
- {typeof state?.error === 'string' &&

{state.error}

} -
- - -
-
-
-
- ) -} - -// --- Promote to Story dialog --- -function PromoteStoryDialog({ - todo, - products, - onClose, -}: { todo: Todo; products: Product[]; onClose: () => void }) { - const handleKey = useCallback((e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }, [onClose]) - useEffect(() => { - document.addEventListener('keydown', handleKey) - return () => document.removeEventListener('keydown', handleKey) - }, [handleKey]) - - const [selectedProductId, setSelectedProductId] = useState(todo.product_id ?? products[0]?.id ?? '') - const selectedProduct = products.find(p => p.id === selectedProductId) - - const [state, formAction] = useActionState( - async (_prev: unknown, fd: FormData) => { - const result = await promoteTodoToStoryAction(_prev, fd) - if (result?.success) { toast.success('Todo gepromoveerd naar Story'); onClose() } - return result - }, - undefined - ) - - return ( -
-
-

Promoveer naar Story

-

Let op: dit kan niet ongedaan worden gemaakt.

-
- - -
- - -
-
- - {products.length === 0 ? ( -

Maak eerst een product aan.

- ) : ( - - )} -
-
- - {!selectedProduct?.pbis.length ? ( -

Maak eerst een PBI aan in dit product.

- ) : ( - - )} -
-
- - -
- {typeof state?.error === 'string' &&

{state.error}

} -
- - -
-
-
-
- ) -} - -// --- Promote to Idea dialog (M12 T-514) --- -// Geen extra inputs nodig — title/description komen uit de todo, en -// promoteTodoToIdeaAction archiveert de todo automatisch. -function PromoteIdeaDialog({ - todo, - onClose, -}: { todo: Todo; onClose: () => void }) { - const router = useRouter() - const handleKey = useCallback((e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }, [onClose]) - useEffect(() => { - document.addEventListener('keydown', handleKey) - return () => document.removeEventListener('keydown', handleKey) - }, [handleKey]) - - const [pending, startTransition] = useTransition() - - function handleConfirm() { - startTransition(async () => { - const r = await promoteTodoToIdeaAction(todo.id) - if ('error' in r) { - toast.error(r.error) - return - } - toast.success(`Idee aangemaakt (${r.idea_code})`) - onClose() - router.push(`/ideas/${r.idea_id}`) - }) - } - - return ( -
-
-

Promoveer naar Idee

-

- Maak een nieuw idee van ‘{todo.title}’. De Todo wordt - gearchiveerd; je kunt hem later terugvinden in de archief-filter. -

-

- Het idee start als DRAFT. Je kunt het daarna grillen, plannen, en - materialiseren tot een PBI. -

-
- - -
-
-
- ) -} - -// --- Detail card --- -function TodoCard({ - mode, - activeTodo, - products, - isDemo, - defaultProductId, - onSuccess, - onPromotePbi, - onPromoteStory, - onPromoteIdea, -}: { - mode: 'idle' | 'create' | 'edit' - activeTodo: Todo | null - products: Product[] - isDemo: boolean - defaultProductId: string - onSuccess: () => void - onPromotePbi: (todo: Todo) => void - onPromoteStory: (todo: Todo) => void - onPromoteIdea: (todo: Todo) => void -}) { - const [createState, createFormAction] = useActionState(createTodoAction, undefined) - const [editState, editFormAction] = useActionState(updateTodoAction, undefined) - - useEffect(() => { - if (createState && 'success' in createState && createState.success) onSuccess() - }, [createState, onSuccess]) - - useEffect(() => { - if (editState && 'success' in editState && editState.success) onSuccess() - }, [editState, onSuccess]) - - if (mode === 'idle') { - return ( -
-

Selecteer een rij of klik op + om te beginnen.

-
- ) - } - - if (mode === 'create') { - return ( -
-

Nieuwe todo

-
-
- - -
-