// SPDX-FileCopyrightText: 2026 Progmasoft // SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 "use client"; import { type FormEvent, useId, useState } from "react"; import { lines, oauthScopes, signsPeopleIn, type ApplicationKind, type ApplicationSubmission, } from "@/lib/credentials"; import { getCredentialsMessages } from "@/lib/credentials-messages"; import type { Locale } from "@/lib/localization"; export interface ApplicationFormValues { displayName: string; homepage: string; redirectUris: string[]; postLogoutRedirectUris: string[]; scopes: string[]; } interface ApplicationFormProps { locale: Locale; kind: ApplicationKind; initial: ApplicationFormValues; submitLabel: string; /** Sends the submission; answers the messages of refused fields, or none. */ onSubmit: ( submission: ApplicationSubmission, ) => Promise | null>; } /** * The settings of an application of one type. A service has neither addresses * nor scopes; the other types list the scopes the application may request, * which every person still decides on the consent page. */ export function ApplicationForm({ locale, kind, initial, submitLabel, onSubmit, }: ApplicationFormProps) { const { form, scopes } = getCredentialsMessages(locale); const formId = useId(); const [pending, setPending] = useState(false); const [errors, setErrors] = useState>({}); async function submit(event: FormEvent) { event.preventDefault(); const data = new FormData(event.currentTarget); const peopleSignIn = signsPeopleIn(kind); setPending(true); const refused = await onSubmit({ kind, displayName: String(data.get("displayName") ?? ""), homepage: String(data.get("homepage") ?? "").trim(), redirectUris: peopleSignIn ? lines(String(data.get("redirectUris") ?? "")) : [], postLogoutRedirectUris: peopleSignIn ? lines(String(data.get("postLogoutRedirectUris") ?? "")) : [], scopes: peopleSignIn ? data.getAll("scope").map(String) : [], }); setErrors(refused ?? {}); setPending(false); } function fieldError(field: string) { return errors[field] ? (

{errors[field]}

) : null; } return (
{errors.form && (
{errors.form}
)} {fieldError("kind")}
{fieldError("displayName")}
{fieldError("homepage")}
{signsPeopleIn(kind) ? ( <>
{form.hints[kind]} {fieldError("redirectUris")}