480 lines
28 KiB
TypeScript
480 lines
28 KiB
TypeScript
import Link from 'next/link'
|
||
import Image from 'next/image'
|
||
import { cookies } from 'next/headers'
|
||
import { getIronSession } from 'iron-session'
|
||
import { AppIcon } from '@/components/shared/app-icon'
|
||
import { SessionData, sessionOptions } from '@/lib/session'
|
||
import packageJson from '@/package.json'
|
||
|
||
const buildDate = process.env.NEXT_PUBLIC_BUILD_DATE
|
||
? new Date(process.env.NEXT_PUBLIC_BUILD_DATE).toLocaleDateString('nl-NL', {
|
||
day: 'numeric',
|
||
month: 'short',
|
||
year: 'numeric',
|
||
})
|
||
: '—'
|
||
|
||
const version = process.env.NEXT_PUBLIC_APP_VERSION ?? packageJson.version
|
||
|
||
export default async function LandingPage() {
|
||
const session = process.env.SESSION_SECRET
|
||
? await getIronSession<SessionData>(await cookies(), sessionOptions)
|
||
: null
|
||
const isLoggedIn = Boolean(session?.userId)
|
||
|
||
return (
|
||
<div className="h-screen bg-background text-foreground flex flex-col overflow-hidden">
|
||
|
||
{/* ── Header ─────────────────────────────────────────────────── */}
|
||
<header className="h-14 border-b border-border bg-surface-container-low flex items-center px-6 gap-4 shrink-0">
|
||
<Link href="/" className="flex items-center gap-2 font-semibold text-primary">
|
||
<AppIcon size={24} />
|
||
Scrum4Me
|
||
</Link>
|
||
{isLoggedIn ? (
|
||
<nav className="flex items-center gap-1 ml-2">
|
||
<Link
|
||
href="/dashboard"
|
||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||
>
|
||
Producten
|
||
</Link>
|
||
<Link
|
||
href="/solo"
|
||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||
>
|
||
Solo
|
||
</Link>
|
||
<Link
|
||
href="/todos"
|
||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||
>
|
||
Todo's
|
||
</Link>
|
||
<Link
|
||
href="/settings"
|
||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||
>
|
||
Instellingen
|
||
</Link>
|
||
</nav>
|
||
) : (
|
||
<nav className="ml-auto flex items-center gap-2">
|
||
<Link
|
||
href="/login"
|
||
className="px-3 py-1.5 rounded-md text-sm text-muted-foreground hover:text-foreground hover:bg-surface-container transition-colors"
|
||
>
|
||
Inloggen
|
||
</Link>
|
||
<Link
|
||
href="/register"
|
||
className="px-4 py-1.5 rounded-md text-sm bg-primary text-primary-foreground hover:opacity-90 transition-opacity font-medium"
|
||
>
|
||
Registreren
|
||
</Link>
|
||
</nav>
|
||
)}
|
||
</header>
|
||
|
||
<main className="flex-1 overflow-y-auto">
|
||
|
||
{/* ── Hero ───────────────────────────────────────────────────── */}
|
||
<section className="bg-primary-container px-6 py-16 text-center">
|
||
<div className="max-w-2xl mx-auto space-y-4">
|
||
<h1 className="text-3xl font-semibold text-primary-container-foreground">
|
||
Scrum planner voor solo developers en kleine teams
|
||
</h1>
|
||
<p className="text-base text-primary-container-foreground/80 leading-relaxed">
|
||
Houd meerdere projecten bij in één overzicht. Plan Product Backlogs, beheer Sprints
|
||
met drag-and-drop en laat Claude Code taken oppakken via een REST API.
|
||
</p>
|
||
<div className="flex gap-3 justify-center pt-2">
|
||
<Link
|
||
href="/register"
|
||
className="px-5 py-2.5 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 transition-opacity"
|
||
>
|
||
Account aanmaken
|
||
</Link>
|
||
<Link
|
||
href="/login"
|
||
className="px-5 py-2.5 rounded-lg border border-primary text-primary bg-transparent text-sm font-medium hover:bg-primary/10 transition-colors"
|
||
>
|
||
Demo bekijken
|
||
</Link>
|
||
</div>
|
||
<p className="text-xs text-primary-container-foreground/60 pt-1">
|
||
Demo-login: gebruikersnaam <code className="font-mono bg-primary-container-foreground/10 px-1 rounded">demo</code> · wachtwoord <code className="font-mono bg-primary-container-foreground/10 px-1 rounded">demo1234</code>
|
||
</p>
|
||
<p className="text-xs text-primary-container-foreground/60">
|
||
Gratis tijdens de beta · desktop-first (1024px+)
|
||
</p>
|
||
<div className="mx-auto max-w-xl rounded-lg border border-primary-container-foreground/20 bg-primary-container-foreground/10 px-4 py-3 text-left">
|
||
<p className="text-xs font-medium text-primary-container-foreground">Beta-versie</p>
|
||
<p className="mt-1 text-xs leading-relaxed text-primary-container-foreground/75">
|
||
Scrum4Me is nog in actieve ontwikkeling. Accounts en ingevoerde gegevens kunnen tijdens deze fase worden aangepast, gereset of verwijderd.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── Tour (screenshots) ─────────────────────────────────────── */}
|
||
<section className="px-6 py-14 bg-background border-b border-border">
|
||
<div className="max-w-6xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">Bekijk Scrum4Me in actie</h2>
|
||
<p className="text-muted-foreground text-sm mb-10 max-w-2xl">
|
||
Drie schermen die de kern van Scrum4Me afdekken — van Product Backlog tot persoonlijk
|
||
Kanban-bord. Elke weergave is desktop-first en gebouwd op MD3-tokens en shadcn-componenten.
|
||
</p>
|
||
|
||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||
{[
|
||
{
|
||
src: '/screenshots/sprint-board.jpg',
|
||
alt: 'Sprint Board met drie panelen: Product Backlog, Sprint Backlog en Taken',
|
||
title: 'Sprint Board',
|
||
caption:
|
||
'Drie panelen op één scherm: Product Backlog links, Sprint Backlog in het midden, taken van de geselecteerde story rechts. Stories slepen tussen panelen werkt via dnd-kit.',
|
||
},
|
||
{
|
||
src: '/screenshots/product-backlog.jpg',
|
||
alt: 'Product Backlog met PBIs gegroepeerd op prioriteit en stories per PBI',
|
||
title: 'Product Backlog',
|
||
caption:
|
||
'PBIs gegroepeerd op prioriteit (Kritiek → Laag) in het linkerpaneel. Klik op een PBI om de stories rechts te zien, gerangschikt per urgentie en versleepbaar.',
|
||
},
|
||
{
|
||
src: '/screenshots/solo-paneel.jpg',
|
||
alt: 'Solo Paneel — persoonlijk Kanban-bord met drie statuskolommen',
|
||
title: 'Solo Paneel',
|
||
caption:
|
||
'Persoonlijk Kanban-bord per product. Toont alleen taken van stories die jij hebt geclaimd, in drie kolommen (To Do, Bezig, Klaar). Drag-and-drop tussen kolommen verandert de status.',
|
||
},
|
||
].map((s) => (
|
||
<figure
|
||
key={s.src}
|
||
className="bg-surface-container-low border border-border rounded-xl overflow-hidden flex flex-col"
|
||
>
|
||
<div className="relative aspect-[16/10] bg-surface-container">
|
||
<Image
|
||
src={s.src}
|
||
alt={s.alt}
|
||
fill
|
||
sizes="(max-width: 1024px) 100vw, 33vw"
|
||
className="object-cover object-top"
|
||
/>
|
||
</div>
|
||
<figcaption className="p-5 space-y-2">
|
||
<div className="text-sm font-medium text-primary">{s.title}</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">{s.caption}</p>
|
||
</figcaption>
|
||
</figure>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── Wat is Scrum4Me ────────────────────────────────────────── */}
|
||
<section className="px-6 py-14 bg-background">
|
||
<div className="max-w-4xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">Wat is Scrum4Me?</h2>
|
||
<p className="text-muted-foreground text-sm mb-10 max-w-2xl">
|
||
Scrum4Me is een desktop-first webapplicatie die Scrum lichtgewicht maakt — zonder
|
||
de overhead van grote tools als Jira of Linear. Ontworpen voor developers die
|
||
zelf de regie willen houden over hun planning.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-2">
|
||
<div className="text-sm font-medium text-primary">Hiërarchisch plannen</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Organiseer werk in producten, Product Backlog Items, stories en taken.
|
||
Alles op één plek, gegroepeerd op prioriteit.
|
||
</p>
|
||
</div>
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-2">
|
||
<div className="text-sm font-medium text-primary">Sprint Board</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Drie-panelen layout: Product Backlog, Sprint Backlog en taken per story op
|
||
één scherm. Slepen, sorteren en statussen wisselen via dnd-kit.
|
||
</p>
|
||
</div>
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-2">
|
||
<div className="text-sm font-medium text-primary">Solo Paneel</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Persoonlijk Kanban-bord per product. Claim stories vanuit de Sprint en werk
|
||
je taken af in drie kolommen — To Do, Bezig, Klaar.
|
||
</p>
|
||
</div>
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-2">
|
||
<div className="text-sm font-medium text-primary">Claude Code-integratie</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Twee opties: native MCP-server (aanbevolen) of REST API met Bearer-token.
|
||
Beide laten Claude Code stories ophalen, taken bijwerken en resultaten vastleggen.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="mt-4 bg-surface-container border border-border rounded-xl p-5 flex items-start gap-4">
|
||
<div className="text-xs font-mono font-semibold text-primary shrink-0 mt-1 px-2 py-0.5 rounded bg-primary-container">
|
||
LIVE
|
||
</div>
|
||
<div className="space-y-1">
|
||
<div className="text-sm font-medium">Realtime Solo Paneel</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Wijzigingen vanuit andere tabs of Claude Code verschijnen binnen 1–2 seconden in je
|
||
Solo Paneel. Geen refresh nodig — gebouwd op Postgres LISTEN/NOTIFY en Server-Sent Events.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── Twee manieren om Claude Code te koppelen ─────────────── */}
|
||
<section className="px-6 py-14 bg-background border-t border-border">
|
||
<div className="max-w-4xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">Twee manieren om Claude Code te koppelen</h2>
|
||
<p className="text-muted-foreground text-sm mb-10 max-w-2xl">
|
||
Kies de aansluiting die bij je workflow past. Beide werken naast elkaar.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-3">
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-sm font-medium text-primary">MCP-server</div>
|
||
<span className="text-xs px-2 py-0.5 rounded bg-primary-container text-primary-container-foreground font-medium">
|
||
Aanbevolen
|
||
</span>
|
||
</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Native Model Context Protocol-tools voor Claude Code. Geen REST-configuratie —
|
||
Claude ziet producten, stories en taken als ingebouwde commando's. Eén prompt
|
||
orkestreert de hele implementatieflow: story ophalen, status updaten, plan loggen,
|
||
commit vastleggen.
|
||
</p>
|
||
<a
|
||
href="https://github.com/madhura68/scrum4me-mcp"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-1 text-xs text-primary hover:underline"
|
||
>
|
||
github.com/madhura68/scrum4me-mcp →
|
||
</a>
|
||
</div>
|
||
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-3">
|
||
<div className="text-sm font-medium text-primary">REST API</div>
|
||
<p className="text-sm text-muted-foreground leading-relaxed">
|
||
Universele HTTP-API met Bearer-token. Werkt vanuit Claude Code, Codex, eigen
|
||
scripts of CI-pipelines. Zelfde rechten als de MCP-server, maar je beheert
|
||
tokens en aanroepen zelf.
|
||
</p>
|
||
<a href="#api" className="inline-flex items-center gap-1 text-xs text-primary hover:underline">
|
||
API-endpoints bekijken ↓
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── Scrum samenvatting ─────────────────────────────────────── */}
|
||
<section className="px-6 py-14 bg-surface-container-low border-y border-border">
|
||
<div className="max-w-4xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">Scrum in Scrum4Me</h2>
|
||
<p className="text-muted-foreground text-sm mb-10 max-w-2xl">
|
||
Scrum4Me past een lichtgewicht versie van Scrum toe — de essentie zonder ceremony-overhead.
|
||
Hieronder staat hoe de kernbegrippen zijn vertaald naar de app.
|
||
</p>
|
||
|
||
{/* Hiërarchie */}
|
||
<div className="mb-10">
|
||
<h3 className="text-sm font-semibold text-foreground mb-4 uppercase tracking-wide">Hiërarchie</h3>
|
||
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-2">
|
||
{[
|
||
{ label: 'Product', sub: 'Een softwareproject of codebase' },
|
||
{ label: 'PBI', sub: 'Product Backlog Item — een feature of verbetering' },
|
||
{ label: 'Story', sub: 'Concrete user story binnen een PBI' },
|
||
{ label: 'Taak', sub: 'Implementatiestap binnen een story' },
|
||
].map((item, i, arr) => (
|
||
<div key={item.label} className="flex items-center gap-2">
|
||
<div className="bg-primary-container border border-primary/20 rounded-lg px-4 py-2.5 min-w-[100px]">
|
||
<div className="text-sm font-medium text-primary-container-foreground">{item.label}</div>
|
||
<div className="text-xs text-primary-container-foreground/60 leading-tight mt-0.5">{item.sub}</div>
|
||
</div>
|
||
{i < arr.length - 1 && (
|
||
<span className="text-muted-foreground text-lg hidden sm:block">→</span>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Terminologie */}
|
||
<div className="mb-10">
|
||
<h3 className="text-sm font-semibold text-foreground mb-4 uppercase tracking-wide">Terminologie</h3>
|
||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||
{[
|
||
{ term: 'Product Backlog', def: 'Geordende lijst van alle PBI\'s per product, gesorteerd op prioriteit (kritiek → laag) en positie.' },
|
||
{ term: 'Sprint', def: 'Actief tijdblok met een Sprint Goal. Per product is er maximaal één actieve Sprint tegelijk.' },
|
||
{ term: 'Sprint Backlog', def: 'De stories die voor deze Sprint zijn geselecteerd. Stories worden vanuit de Product Backlog gesleept.' },
|
||
{ term: 'Sprint Board', def: 'Drie-panelen scherm op één view: Product Backlog, Sprint Backlog en taken per geselecteerde story. Vervangt het oude losse Sprint Planning-scherm.' },
|
||
{ term: 'Solo Paneel', def: 'Persoonlijk Kanban-bord per product. Toont taken van geclaimde stories in drie kolommen (To Do, Bezig, Klaar) — drag-and-drop wijzigt de status.' },
|
||
{ term: 'Story-claim', def: 'Een developer claimt een story uit de Sprint en wordt assignee. Pull-systeem (zelf-organisatie) — niet pushed door een Scrum Master.' },
|
||
{ term: 'Story-status', def: 'OPEN → IN_SPRINT → DONE. Bepaalt zichtbaarheid in backlogs en Sprint-schermen.' },
|
||
{ term: 'Taakstatus', def: 'TO_DO → IN_PROGRESS → DONE. Wordt bijgehouden via UI of REST API door Claude Code.' },
|
||
{ term: 'Activiteitenlog', def: 'Per story worden implementatieplan, testresultaat en commit vastgelegd via de API of UI.' },
|
||
{ term: 'Sprint afronden', def: 'Bij afsluiting wordt per story gekozen: markeer als Done of zet terug naar Backlog.' },
|
||
].map(({ term, def }) => (
|
||
<div key={term} className="bg-background border border-border rounded-lg p-4">
|
||
<div className="text-sm font-medium mb-1">{term}</div>
|
||
<div className="text-xs text-muted-foreground leading-relaxed">{def}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Rollen */}
|
||
<div>
|
||
<h3 className="text-sm font-semibold text-foreground mb-4 uppercase tracking-wide">Rollen</h3>
|
||
<div className="flex flex-wrap gap-3">
|
||
{[
|
||
{ role: 'Product Owner', desc: 'Bepaalt prioriteit van PBI\'s en beheert de Product Backlog.' },
|
||
{ role: 'Scrum Master', desc: 'Bewaakt het Scrum-proces en verwijdert obstakels.' },
|
||
{ role: 'Developer', desc: 'Voert stories en taken uit; werkt via UI of Claude Code.' },
|
||
].map(({ role, desc }) => (
|
||
<div key={role} className="bg-secondary-container border border-secondary/20 rounded-lg px-4 py-3 flex-1 min-w-[180px]">
|
||
<div className="text-sm font-medium text-secondary-container-foreground">{role}</div>
|
||
<div className="text-xs text-secondary-container-foreground/70 mt-1">{desc}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<p className="text-xs text-muted-foreground mt-3">
|
||
In v1 is één account gelijk aan één gebruiker met alle rollen. Teamgebruik met rolscheiding volgt in v2.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── Gebruikershandleiding ─────────────────────────────────── */}
|
||
<section className="px-6 py-14 bg-background">
|
||
<div className="max-w-4xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">Gebruikershandleiding</h2>
|
||
<p className="text-muted-foreground text-sm mb-10 max-w-2xl">
|
||
Volg deze stappen om van een leeg account naar een volledig ingeplande Sprint te gaan.
|
||
</p>
|
||
|
||
<div className="space-y-3">
|
||
{[
|
||
{
|
||
step: '1',
|
||
title: 'Account aanmaken',
|
||
desc: 'Ga naar Registreren en kies een gebruikersnaam en wachtwoord. Na registratie word je direct doorgestuurd naar het dashboard. Wil je eerst rondkijken? Log in met de demo-account (alleen leesrechten).',
|
||
},
|
||
{
|
||
step: '2',
|
||
title: 'Product aanmaken',
|
||
desc: 'Klik op "Nieuw product" op het dashboard. Vul naam, optionele beschrijving, repo-URL en je Definition of Done in. Het product wordt zichtbaar op het dashboard.',
|
||
},
|
||
{
|
||
step: '3',
|
||
title: 'Product Backlog opbouwen',
|
||
desc: 'Open het product en voeg PBI\'s toe via het linkerpaneel. Geef elk PBI een prioriteit (Kritiek / Hoog / Gemiddeld / Laag). Klik op een PBI om in het rechterpaneel stories toe te voegen. Versleep PBI\'s en stories om de volgorde aan te passen.',
|
||
},
|
||
{
|
||
step: '4',
|
||
title: 'Sprint starten',
|
||
desc: 'Klik op "Sprint starten" op de productpagina en voer een Sprint Goal in. Per product is er maximaal één actieve Sprint tegelijk. Het Sprint-scherm wordt zichtbaar via de navigatie.',
|
||
},
|
||
{
|
||
step: '5',
|
||
title: 'Sprint Board — stories slepen en taken aanmaken',
|
||
desc: 'Open het Sprint-scherm. Drie panelen verschijnen op één view: Product Backlog links, Sprint Backlog in het midden, taken rechts. Sleep stories vanuit links naar het midden om ze in de Sprint te plaatsen. Selecteer een story in het middenpaneel om de taken rechts te tonen en aan te maken.',
|
||
},
|
||
{
|
||
step: '6',
|
||
title: 'Solo Paneel — claim stories en werk persoonlijk',
|
||
desc: 'Open Solo via de navigatie. Claim openstaande stories uit de actieve Sprint (knop "Toon openstaande stories") en werk je taken af in drie statuskolommen via drag-and-drop. Klik op een taak voor het detail-dialoog met implementatieplan.',
|
||
},
|
||
{
|
||
step: '7',
|
||
title: 'API-token aanmaken voor Claude Code',
|
||
desc: 'Ga naar Instellingen → Tokens. Maak een nieuw token aan en kopieer de waarde direct — die is daarna niet meer zichtbaar. Gebruik het token als Bearer-token in Claude Code of je eigen scripts.',
|
||
},
|
||
{
|
||
step: '8',
|
||
title: 'Claude Code koppelen',
|
||
desc: 'Configureer Claude Code met je API-token. Claude haalt via GET /api/products/:id/next-story de hoogst geprioriteerde open story op, werkt taken bij via PATCH /api/tasks/:id en legt het implementatieplan, testresultaten en commits vast via POST /api/stories/:id/log.',
|
||
},
|
||
{
|
||
step: '9',
|
||
title: 'Sprint afronden',
|
||
desc: 'Klik op "Sprint afronden" op het Sprint Board. Voor elke story kies je: markeer als Done of zet terug naar de Product Backlog. Daarna is een nieuwe Sprint aanmaakbaar.',
|
||
},
|
||
].map(({ step, title, desc }) => (
|
||
<div key={step} className="flex gap-4 bg-surface-container-low border border-border rounded-xl p-5">
|
||
<div className="shrink-0 w-8 h-8 rounded-full bg-primary text-primary-foreground text-sm font-semibold flex items-center justify-center">
|
||
{step}
|
||
</div>
|
||
<div className="space-y-1">
|
||
<div className="text-sm font-medium">{title}</div>
|
||
<div className="text-sm text-muted-foreground leading-relaxed">{desc}</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* ── API-overzicht ─────────────────────────────────────────── */}
|
||
<section id="api" className="px-6 py-14 bg-surface-container-low border-t border-border">
|
||
<div className="max-w-4xl mx-auto">
|
||
<h2 className="text-xl font-semibold mb-2">REST API voor Claude Code</h2>
|
||
<p className="text-muted-foreground text-sm mb-6 max-w-2xl">
|
||
Alle API-endpoints vereisen een <code className="font-mono bg-surface-container px-1 rounded text-xs">Authorization: Bearer <token></code> header.
|
||
Tokens beheer je via Instellingen → Tokens.
|
||
</p>
|
||
<pre className="bg-background border border-border rounded-lg p-4 text-xs font-mono overflow-x-auto mb-8 max-w-2xl">
|
||
<code className="text-foreground">{`# Volgende story uit de actieve Sprint ophalen
|
||
curl -H "Authorization: Bearer $TOKEN" \\
|
||
https://<jouw-instance>/api/products/<product-id>/next-story`}</code>
|
||
</pre>
|
||
<div className="space-y-2">
|
||
{[
|
||
{ method: 'GET', path: '/api/products', desc: 'Lijst van actieve producten' },
|
||
{ method: 'GET', path: '/api/products/:id/next-story', desc: 'Hoogst geprioriteerde open story van de actieve Sprint' },
|
||
{ method: 'GET', path: '/api/sprints/:id/tasks?limit=10', desc: 'Eerste N taken van de Sprint op volgorde' },
|
||
{ method: 'PATCH', path: '/api/stories/:id/tasks/reorder', desc: 'Taakvolgorde aanpassen (body: { task_ids: string[] })' },
|
||
{ method: 'POST', path: '/api/stories/:id/log', desc: 'Activiteit vastleggen: implementatieplan, testresultaat of commit' },
|
||
{ method: 'PATCH', path: '/api/tasks/:id', desc: 'Taakstatus of implementatieplan bijwerken' },
|
||
{ method: 'POST', path: '/api/todos', desc: 'Todo aanmaken (body: { title, product_id })' },
|
||
].map(({ method, path, desc }) => (
|
||
<div key={path} className="flex items-start gap-3 bg-background border border-border rounded-lg px-4 py-3">
|
||
<span className={`shrink-0 text-xs font-mono font-semibold px-2 py-0.5 rounded ${
|
||
method === 'GET' ? 'bg-tertiary-container text-tertiary-container-foreground' :
|
||
method === 'POST' ? 'bg-success-container text-success-container-foreground' :
|
||
'bg-warning-container text-warning-container-foreground'
|
||
}`}>
|
||
{method}
|
||
</span>
|
||
<code className="text-xs font-mono text-foreground shrink-0">{path}</code>
|
||
<span className="text-xs text-muted-foreground">{desc}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
{/* ── Footer ─────────────────────────────────────────────────── */}
|
||
<footer className="shrink-0 border-t border-border bg-surface-container-low px-6 py-4 flex items-center justify-between text-xs text-muted-foreground">
|
||
<span>© {new Date().getFullYear()} Scrum4Me</span>
|
||
<a
|
||
href="https://github.com/madhura68/Scrum4Me"
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="hover:text-foreground transition-colors"
|
||
>
|
||
GitHub
|
||
</a>
|
||
<span>v{version} · gebouwd op {buildDate}</span>
|
||
</footer>
|
||
|
||
</div>
|
||
)
|
||
}
|