diff --git a/messages/de.json b/messages/de.json index c44e11b7..2161ffd2 100644 --- a/messages/de.json +++ b/messages/de.json @@ -742,6 +742,7 @@ "http404": "Die angeforderte Seite wurde nicht gefunden.", "http500": "Es ist ein interner Serverfehler aufgetreten.", "httpGenericError": "Es ist ein unbekannter Fehler aufgetreten.", + "httpMissingRequiredData": "Erforderliche Daten fehlen. Bitte stellen Sie sicher, dass alle Teilnehmendendaten (Adresse, Geburtstag) vollständig sind.", "iban": "IBAN", "ibanMustBe22Characters": "IBAN muss 22 Zeichen ohne Leerzeichen haben", "identityCheck": "Identitätsprüfung", diff --git a/messages/en.json b/messages/en.json index 9cf9c92c..ffb47f3f 100644 --- a/messages/en.json +++ b/messages/en.json @@ -742,6 +742,7 @@ "http404": "The requested page was not found.", "http500": "An internal server error occurred.", "httpGenericError": "An unknown error has occurred.", + "httpMissingRequiredData": "Required data is missing. Please ensure all participant details (address, birthday) are complete.", "iban": "IBAN", "ibanMustBe22Characters": "IBAN must be 22 characters without spaces", "identityCheck": "Identity Check", diff --git a/src/lib/components/UserCard/UserCardContent.svelte b/src/lib/components/UserCard/UserCardContent.svelte index 7a8f22e3..021cf5b2 100644 --- a/src/lib/components/UserCard/UserCardContent.svelte +++ b/src/lib/components/UserCard/UserCardContent.svelte @@ -180,6 +180,12 @@ startConference endConference title + postalName + postalStreet + postalApartment + postalZip + postalCity + postalCountry } } `); @@ -279,6 +285,7 @@ status={participantStatus} {userId} {conferenceId} + {user} {conference} birthday={user?.birthday} {isConferenceSupervisor} diff --git a/src/lib/components/UserCard/tabs/ParticipantStatusTab.svelte b/src/lib/components/UserCard/tabs/ParticipantStatusTab.svelte index 7499da08..29466897 100644 --- a/src/lib/components/UserCard/tabs/ParticipantStatusTab.svelte +++ b/src/lib/components/UserCard/tabs/ParticipantStatusTab.svelte @@ -18,6 +18,13 @@ import { getBaseDocumentsForPostal } from '$lib/queries/getBaseDocuments'; import { ofAgeAtConference } from '$lib/services/ageChecker'; import GuardianConsentNotNeeded from '$lib/components/GuardianConsentNotNeeded.svelte'; + import { + downloadCompletePostalRegistrationPDF, + downloadCompleteCertificate, + type ParticipantData, + type RecipientData + } from '$lib/services/pdfGenerator'; + import formatNames from '$lib/services/formatNames'; type AdministrativeStatus = 'DONE' | 'PENDING' | 'PROBLEM'; @@ -44,12 +51,32 @@ | undefined; userId: string; conferenceId: string; + user: + | { + id: string; + given_name?: string | null; + family_name?: string | null; + street?: string | null; + apartment?: string | null; + zip?: string | null; + city?: string | null; + country?: string | null; + birthday?: Date | null; + } + | null + | undefined; conference: | { id: string; startConference?: string | null; endConference?: string | null; title?: string | null; + postalName?: string | null; + postalStreet?: string | null; + postalApartment?: string | null; + postalZip?: number | null; + postalCity?: string | null; + postalCountry?: string | null; } | null | undefined; @@ -62,6 +89,7 @@ status, userId, conferenceId, + user, conference, birthday, isConferenceSupervisor, @@ -88,36 +116,102 @@ const downloadPostalDocs = async () => { try { - const result = await getBaseDocumentsForPostal.fetch({ - variables: { visitorId: userId, conferenceId } + const baseContent = await getBaseDocumentsForPostal.fetch({ + variables: { conferenceId } }); - if (result.data?.postalRegistrationPDF) { - const a = document.createElement('a'); - a.href = `data:application/pdf;base64,${result.data.postalRegistrationPDF}`; - a.download = `postal-registration-${userId}.pdf`; - a.click(); - } else { + + if (baseContent.errors) { + toast.error(m.httpGenericError()); + return; + } + + if ( + !conference?.postalName || + !conference?.postalStreet || + !conference?.postalZip || + !conference?.postalCity || + !conference?.postalCountry + ) { toast.error(m.httpGenericError()); + return; } - } catch { + + if (user) { + if (!user.birthday) { + toast.error(m.httpMissingRequiredData()); + return; + } + + const recipientData: RecipientData = { + name: `${conference.postalName}`, + address: `${conference.postalStreet} ${conference.postalApartment ?? ''}`, + zip: conference.postalZip?.toString() ?? '', + city: conference.postalCity ?? '', + country: conference.postalCountry ?? '' + }; + + const participantData: ParticipantData = { + id: user.id, + name: formatNames(user.given_name ?? undefined, user.family_name ?? undefined, { + givenNameFirst: true, + familyNameUppercase: true, + givenNameUppercase: true + }), + address: [ + [user.street, user.apartment].filter(Boolean).join(' '), + [user.zip, user.city].filter(Boolean).join(' '), + user.country + ] + .filter(Boolean) + .join(', '), + birthday: user.birthday.toLocaleDateString() + }; + + await downloadCompletePostalRegistrationPDF( + ofAgeAtConference(conference.startConference, user.birthday), + participantData, + recipientData, + baseContent.data?.findUniqueConference?.contractContent ?? undefined, + baseContent.data?.findUniqueConference?.guardianConsentContent ?? undefined, + baseContent.data?.findUniqueConference?.mediaConsentContent ?? undefined, + baseContent.data?.findUniqueConference?.termsAndConditionsContent ?? undefined, + `${formatNames(user.given_name ?? undefined, user.family_name ?? undefined, { + givenNameFirst: false, + delimiter: '_' + })}_postal_registration.pdf` + ); + } + } catch (error) { + console.error('Error generating PDF:', error); toast.error(m.httpGenericError()); } }; const downloadCertificate = async () => { try { - const result = await certificateQuery.fetch({ - variables: { visitorId: userId, conferenceId } + const certificateData = await certificateQuery.fetch({ + variables: { conferenceId, userId } }); - if (result.data?.certificate) { - const a = document.createElement('a'); - a.href = `data:application/pdf;base64,${result.data.certificate}`; - a.download = `certificate-${userId}.pdf`; - a.click(); - } else { + + const jwtData = certificateData.data?.getCertificateJWT; + + if (!jwtData?.fullName || !jwtData?.jwt) { toast.error(m.certificateDownloadError()); + return; + } + + if (user) { + await downloadCompleteCertificate( + jwtData, + certificateData.data?.findUniqueConference?.certificateContent ?? undefined, + `${formatNames(user.given_name ?? undefined, user.family_name ?? undefined, { + givenNameFirst: false, + delimiter: '_' + })}_certificate.pdf` + ); } - } catch { + } catch (error) { + console.error('Error generating PDF:', error); toast.error(m.certificateDownloadError()); } };