Scrum4Me/components/product-docs/product-docs-folder-list.tsx
Madhura68 3c8699f8e7 feat(PBI-96/T-1068): folder-listing page + folder-list + status-badge
- app/(app)/products/[id]/docs/[folder]/page.tsx: server-route die
  folder-segment valideert tegen ProductDocFolder-enum (404 anders),
  docs sorteert op slug ASC, en de tabel + breadcrumb + "Nieuwe doc"-link
  rendert. New-doc-link wordt in T-1070 functioneel via dialog.
- components/product-docs/product-docs-folder-list.tsx: server-tabel
  (slug · title · status-badge · updated_at met nl-NL DateTimeFormat).
- components/product-docs/product-doc-status-badge.tsx: MD3-tokens
  (bg-status-done/20, bg-status-blocked/20, bg-muted) per status.
  Unknown statussen fallbacken naar 'muted'.
- "Nieuwe doc"-knop conditioneel verborgen bij disabled folder; banner
  zelf komt in T-1071.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:27:55 +02:00

94 lines
2.9 KiB
TypeScript

// Folder-listing tabel. Server-component (geen interactiviteit in v1 —
// sorteren komt later via TanStack-table indien nodig). Toont
// slug · title · status-badge · updated_at.
import Link from 'next/link'
import { FileText } from 'lucide-react'
import { debugProps } from '@/lib/debug'
import { ProductDocStatusBadge } from './product-doc-status-badge'
export interface ProductDocListRow {
id: string
slug: string
title: string
status: string
updated_at: Date
}
interface Props {
productId: string
folderApi: string
docs: ProductDocListRow[]
}
const dateFmt = new Intl.DateTimeFormat('nl-NL', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
})
export function ProductDocsFolderList({ productId, folderApi, docs }: Props) {
if (docs.length === 0) {
return (
<div
className="text-sm text-muted-foreground p-6 text-center"
{...debugProps(
'product-docs-folder-list--empty',
'ProductDocsFolderList',
'components/product-docs/product-docs-folder-list.tsx',
)}
>
Nog geen docs in deze folder.
</div>
)
}
const docsUrl = `/products/${productId}/docs/${folderApi}`
return (
<div
className="rounded-lg border border-border bg-surface-container-low overflow-hidden"
{...debugProps(
'product-docs-folder-list',
'ProductDocsFolderList',
'components/product-docs/product-docs-folder-list.tsx',
)}
>
<table className="w-full text-sm">
<thead className="border-b border-border bg-surface-container">
<tr className="text-xs text-muted-foreground">
<th className="text-left px-3 py-2 font-medium">Slug</th>
<th className="text-left px-3 py-2 font-medium">Titel</th>
<th className="text-left px-3 py-2 font-medium">Status</th>
<th className="text-right px-3 py-2 font-medium">Bijgewerkt</th>
</tr>
</thead>
<tbody>
{docs.map((doc) => (
<tr
key={doc.id}
className="border-t border-border first:border-t-0 hover:bg-surface-container/60"
>
<td className="px-3 py-2 font-mono text-xs">
<Link
href={`${docsUrl}/${doc.slug}`}
className="text-primary hover:underline inline-flex items-center gap-1.5"
>
<FileText className="size-3 shrink-0" />
{doc.slug}
</Link>
</td>
<td className="px-3 py-2 truncate max-w-[420px]">{doc.title}</td>
<td className="px-3 py-2">
<ProductDocStatusBadge status={doc.status} />
</td>
<td className="px-3 py-2 text-right text-xs text-muted-foreground tabular-nums">
{dateFmt.format(doc.updated_at)}
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}