Formulaire public : encart de paiement de la cotisation via Yapla

FormTemplate.yapla_url (lien vers la page de cotisation Yapla, doit
commencer par http(s)://, PATCH .../form comme description/is_open)
fait apparaître un encart « Payer ma cotisation » sous la case
WILLING_TO_PAY_FEE, sur le formulaire public. Configurable depuis le
panneau « Personnalisation » de l'écran /inscriptions. La case reste
une simple déclaration : rien ne vérifie que le paiement a eu lieu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-09-23 21:10:38 +02:00
co-authored by Claude Sonnet 5
parent 8f8350aa1b
commit 5f80f167c8
14 changed files with 181 additions and 17 deletions
+4 -1
View File
@@ -56,6 +56,7 @@ export interface MockState {
logo: string | null; // data URL
logoType: string | null;
description: string | null;
yaplaUrl: string | null;
};
/** volunteerId -> photo (formulaire public), data URL. */
photos: Map<string, string>;
@@ -445,7 +446,9 @@ export function buildMockState(): MockState {
backImageType: null,
fields: [],
},
formTemplate: { isOpen: true, fields: [], logo: null, logoType: null, description: null },
formTemplate: {
isOpen: true, fields: [], logo: null, logoType: null, description: null, yaplaUrl: null,
},
photos: new Map(),
seq,
};
+8
View File
@@ -128,6 +128,7 @@ const formTemplateRead = (): FormTemplateRead => ({
fields: state.formTemplate.fields,
has_logo: state.formTemplate.logo !== null,
description: state.formTemplate.description,
yapla_url: state.formTemplate.yaplaUrl,
});
// PDF valide minimal (une page blanche) — remplace la vraie génération
@@ -1483,6 +1484,12 @@ export function createMockApi(): PlanningApi {
setOpen: (_edition, body: FormTemplateUpdate) => {
if (body.is_open !== undefined) state.formTemplate.isOpen = body.is_open;
if (body.description !== undefined) state.formTemplate.description = body.description;
if (body.yapla_url !== undefined) {
if (body.yapla_url && !/^https?:\/\//.test(body.yapla_url)) {
throw new ApiError(422, 'form.invalid_yapla_url');
}
state.formTemplate.yaplaUrl = body.yapla_url;
}
return delay<FormTemplateRead>(formTemplateRead());
},
uploadLogo: async (_edition, file: File) => {
@@ -1511,6 +1518,7 @@ export function createMockApi(): PlanningApi {
: [],
has_logo: state.formTemplate.logo !== null,
description: state.formTemplate.description,
yapla_url: state.formTemplate.yaplaUrl,
});
},
submitPublic: async (_edition, body: PublicFormSubmission) => {
+3
View File
@@ -573,12 +573,14 @@ export interface FormTemplateRead {
fields: FormFieldType[];
has_logo: boolean;
description: string | null;
yapla_url: string | null;
}
/** `undefined`/absent = inchangé pour chaque champ. */
export interface FormTemplateUpdate {
is_open?: boolean;
description?: string | null;
yapla_url?: string | null;
}
export interface PublicPositionOption {
@@ -600,6 +602,7 @@ export interface PublicFormConfig {
artists: PublicArtistOption[];
has_logo: boolean;
description: string | null;
yapla_url: string | null;
}
export interface FormSubmissionResult {