"use client"; import Link from "next/link"; import { useRef, useState, useTransition } from "react"; import type { Project, ProjectExpertScore, RikxRonde } from "../../../lib/db"; import { PROJECT_STATUSES } from "../../../lib/projectStatus"; import { BONUS_MALUS_OPTIONS, EXPERT_COUNT, EXPERT_CRITERIA, calculateRikx, type ExpertScore, } from "../../../lib/rikxCalculatie"; import { parseProjectPlanJson } from "../../../lib/projectPlan"; import { setRikxCalculatie, updateProject } from "../actions"; import { ProjectPlanFields } from "./ProjectPlanFields"; const inputClass = "w-full h-10 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-rikx-orange"; const labelClass = "text-sm font-medium text-zinc-700 dark:text-zinc-300"; const cardClass = "bg-white dark:bg-zinc-900 rounded-xl border border-zinc-200 dark:border-zinc-800 p-6"; function toNumber(value: FormDataEntryValue | null): number | null { if (typeof value !== "string" || value.trim() === "") return null; const n = Number(value.replace(",", ".")); return Number.isFinite(n) ? n : null; } function rondeById(rondes: RikxRonde[], id: number | null) { return rondes.find((r) => r.id === id) ?? null; } function readInput(form: HTMLFormElement, rondes: RikxRonde[]) { const fd = new FormData(form); const ronde = rondeById(rondes, Number(fd.get("ronde_id")) || null); return { ronde_id: ronde?.id ?? null, projectkosten: toNumber(fd.get("projectkosten")), deelnemers_werk: toNumber(fd.get("deelnemers_werk")), deelnemers_skills: toNumber(fd.get("deelnemers_skills")), financiering_extern_pct: toNumber(fd.get("financiering_extern_pct")), bonus_malus: (fd.get("bonus_malus") as string) || null, rikx_waarde: ronde?.rikx_waarde ?? null, rikx_prijs: ronde?.rikx_prijs ?? null, expert_scores: Array.from({ length: EXPERT_COUNT }, (_, i) => Object.fromEntries(EXPERT_CRITERIA.map((c) => [c.id, toNumber(fd.get(`expert_${i + 1}_${c.id}`))])) ) as ExpertScore[], }; } const nl = (digits: number) => new Intl.NumberFormat("nl-NL", { maximumFractionDigits: digits }); const euro = new Intl.NumberFormat("nl-NL", { style: "currency", currency: "EUR" }); const fmt = (v: number | null, kind: "getal" | "euro" | "geheel" = "getal") => v === null ? "—" : kind === "euro" ? euro.format(v) : nl(kind === "geheel" ? 0 : 2).format(v); function Field({ label, hint, children, }: { label: string; hint?: string; children: React.ReactNode; }) { return ( ); } function StepHeading({ step, title, description }: { step: number; title: string; description: string }) { return (
{description}