Workflow-App/Workflow/components/ActionButton.tsx
sjcoetzeesj-coder 11d0178ab1 feat: commit Workflow app source; move CIPC credentials to env
Adds the full Next.js app (app/, components/, lib/, scripts/, assets/,
docs/, Dockerfile, compose, configs) to version control.

Security:
- CIPC BizPortal customer-code logins (Login 1 + Login 3) now read
  CIPC_LOGIN1_CODE / CIPC_LOGIN1_PASSWORD / CIPC_LOGIN3_CODE /
  CIPC_LOGIN3_PASSWORD from .env.local instead of source.
- BizPortal personal login in apply-bizportal route reads
  BIZPORTAL_ID_NO / BIZPORTAL_PASSWORD.
- Added .env.example as the committed template.

.gitignore excludes .env*, node_modules, .next, logs, sqlite, Playwright
storage_state.json (live CIPC cookies), scratch dirs, client PDFs and
debug screenshots.
2026-10-18 15:21:45 +02:00

51 lines
1.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
interface ActionButtonProps {
label: string;
description: string;
status: string;
variant?: "blue" | "green" | "purple" | "red";
id: string;
}
const VARIANT = {
blue: "border-blue-300 bg-blue-50 text-blue-700 hover:bg-blue-100",
green: "border-green-300 bg-green-50 text-green-700 hover:bg-green-100",
purple: "border-purple-300 bg-purple-50 text-purple-700 hover:bg-purple-100",
red: "border-red-300 bg-red-50 text-red-700 hover:bg-red-100",
};
export default function ActionButton({ label, description, status, variant = "blue", id }: ActionButtonProps) {
const router = useRouter();
const [loading, setLoading] = useState(false);
async function handle() {
if (!confirm(`Set status to "${status}"?`)) return;
setLoading(true);
await fetch("/api/register/update-status", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id, status }),
});
router.refresh();
}
return (
<button
onClick={handle}
disabled={loading}
className={`w-full text-left p-5 rounded-lg border-2 transition-colors disabled:opacity-50 ${VARIANT[variant]}`}
>
<div className="flex items-start justify-between gap-3">
<div>
<p className="font-bold text-sm">{loading ? "…" : label}</p>
<p className="text-xs mt-1 opacity-75">{description}</p>
</div>
{!loading && <span className="text-lg mt-0.5">→</span>}
</div>
</button>
);
}