diff --git a/__tests__/components/dashboard/product-list.test.tsx b/__tests__/components/dashboard/product-list.test.tsx
new file mode 100644
index 0000000..a532228
--- /dev/null
+++ b/__tests__/components/dashboard/product-list.test.tsx
@@ -0,0 +1,56 @@
+// @vitest-environment jsdom
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import { render, screen, fireEvent } from '@testing-library/react'
+
+const { pushMock } = vi.hoisted(() => ({ pushMock: vi.fn() }))
+vi.mock('next/navigation', () => ({ useRouter: () => ({ push: pushMock, refresh: vi.fn() }) }))
+vi.mock('@/actions/products', () => ({ restoreProductAction: vi.fn() }))
+vi.mock('@/actions/active-product', () => ({ setActiveProductAction: vi.fn() }))
+vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }))
+vi.mock('@/components/dialogs/product-dialog', () => ({
+ ProductDialog: ({ open }: { open: boolean }) => (open ?
ProductDialog
: null),
+}))
+
+import { ProductList } from '@/components/dashboard/product-list'
+
+const PRODUCT = {
+ id: 'p1',
+ name: 'Mijn Product',
+ code: 'MP',
+ description: 'Een product',
+ repo_url: 'https://github.com/foo/bar',
+ definition_of_done: 'klaar als het werkt',
+ auto_pr: false,
+}
+
+beforeEach(() => {
+ pushMock.mockClear()
+})
+
+describe('ProductList — edit-icoon (todo cmoq3ox51)', () => {
+ it('rendert pencil-icoon (Bewerk product) op active card, geen tekstknop "Bewerken"', () => {
+ render()
+ expect(screen.getByLabelText('Bewerk product')).toBeTruthy()
+ // Oude tekstknop is weg
+ expect(screen.queryByText('Bewerken')).toBeNull()
+ })
+
+ it('opent ProductDialog op klik (en stopt propagation zodat card-click niet navigeert)', () => {
+ render()
+ expect(screen.queryByRole('dialog')).toBeNull()
+ fireEvent.click(screen.getByLabelText('Bewerk product'))
+ expect(screen.getByRole('dialog')).toBeTruthy()
+ expect(pushMock).not.toHaveBeenCalled() // card-navigation niet getriggerd
+ })
+
+ it('demo-user: knop is disabled', () => {
+ render()
+ const btn = screen.getByLabelText('Bewerk product') as HTMLButtonElement
+ expect(btn.disabled).toBe(true)
+ })
+
+ it('toont geen edit-icoon bij gearchiveerde producten', () => {
+ render()
+ expect(screen.queryByLabelText('Bewerk product')).toBeNull()
+ })
+})
diff --git a/components/dashboard/product-list.tsx b/components/dashboard/product-list.tsx
index b85390a..587e101 100644
--- a/components/dashboard/product-list.tsx
+++ b/components/dashboard/product-list.tsx
@@ -3,6 +3,7 @@
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useState, useTransition } from 'react'
+import { Pencil } from 'lucide-react'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
@@ -106,14 +107,14 @@ export function ProductList({ products, isDemo, showArchived = false, activeProd
{!showArchived && (
<>
-
+
+
{product.id === activeProductId
? Actief