Docker Image bauen und veroeffentlichen / typecheck (push) Successful in 2m57s
Docker Image bauen und veroeffentlichen / lint (push) Successful in 3m7s
Docker Image bauen und veroeffentlichen / build-and-push (push) Canceled after 0s
Docker Image bauen und veroeffentlichen / test (push) Canceled after 1m22s
- Oeffentliche Kuendigung: exakte Identifikation, Limits je Vertrag und Adresse, Bestaetigung nur an die Kontoadresse mit Ruecknahme-Link (HMAC) - Vorschau: Body-Grenze beim Lesen, Parallelitaets- und Minutenlimit, Cache - Rabatte gelten nicht fuer Patenschaftspositionen - Abo aktiv erst nach bestaetigter Zahlung, offene Abschluesse zaehlen zum Kontingent und werden nach 24 h aufgeraeumt, Sitzung 58 Minuten - Konto-Loeschung nur ohne laufendes Abo, Urkunden-Dateien werden entfernt - Abo-Lieferungen mit Zahlungszeile (DHL-Marke moeglich) - Shop zeigt freien Bestand nach Abo-Reservierung - Storno/volle Erstattung widerruft die Patenschaft (Status WIDERRUFEN) - Umsatzsteuer der Patenschaft per VAT_RATE_PERCENT_PATENSCHAFT (19 %) - Digitale Bestellungen archivieren sich, Kalendertage in Europe/Berlin, Monatsenden begrenzt, Datenauskunft um Patenschaften ergaenzt Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
348 lines
16 KiB
TypeScript
348 lines
16 KiB
TypeScript
import type { Locale } from "@/i18n/config";
|
||
import type { SubscriptionStatus } from "@/generated/prisma/client";
|
||
|
||
/**
|
||
* Texte des Abos: Dankeseite nach dem Abschluss, Abo-Seite im Konto mit
|
||
* Kuendigungsknopf (§ 312k BGB) und die oeffentliche Seite
|
||
* /vertraege-kuendigen. Eigenes Modul wie die uebrigen Patenschaftstexte,
|
||
* damit parallele Teile sich nicht in die Quere kommen. Ansprache: du.
|
||
*
|
||
* Die Beschriftungen "Verträge hier kündigen" und "Jetzt kündigen" sind vom
|
||
* Gesetz vorgegeben (§ 312k Abs. 2 BGB) und duerfen nicht umformuliert werden.
|
||
*/
|
||
export interface AboStrings {
|
||
footerLink: string;
|
||
status: Record<SubscriptionStatus, string>;
|
||
thanks: {
|
||
metaTitle: string;
|
||
activeTitle: string;
|
||
activeText: string;
|
||
processingTitle: string;
|
||
processingText: string;
|
||
notCompletedTitle: string;
|
||
notCompletedText: string;
|
||
toSubscription: string;
|
||
toAccount: string;
|
||
backToOffer: string;
|
||
};
|
||
detail: {
|
||
metaTitle: string;
|
||
back: string;
|
||
title: (offer: string) => string;
|
||
beeLine: (bee: string) => string;
|
||
contractNumber: string;
|
||
statusLabel: string;
|
||
monthlyPrice: string;
|
||
nextCharge: string;
|
||
endsOn: string;
|
||
paidMonths: string;
|
||
progressTitle: string;
|
||
progress: (paid: number, required: number) => string;
|
||
progressHarvest: (paid: number, required: number) => string;
|
||
sepaHoldNote: string;
|
||
deliveriesTitle: string;
|
||
deliveriesEmpty: string;
|
||
deliveryPrepared: (date: string, jars: number) => string;
|
||
deliveryDeferred: (date: string) => string;
|
||
delinquentNote: string;
|
||
paymentTitle: string;
|
||
paymentText: string;
|
||
paymentButton: string;
|
||
paymentUnavailable: string;
|
||
cancelTitle: string;
|
||
cancelText: string;
|
||
cancelButton: string;
|
||
cancelledNote: (date: string) => string;
|
||
endedNote: (date: string) => string;
|
||
certificateLink: string;
|
||
cancelDone: (date: string) => string;
|
||
cancelFailed: string;
|
||
};
|
||
confirm: {
|
||
metaTitle: string;
|
||
title: string;
|
||
intro: string;
|
||
kindLabel: string;
|
||
kindValue: string;
|
||
contractLabel: string;
|
||
effectiveLabel: string;
|
||
effectiveValue: (date: string) => string;
|
||
confirmationLabel: string;
|
||
confirmationValue: (email: string) => string;
|
||
submit: string;
|
||
back: string;
|
||
};
|
||
publicPage: {
|
||
metaTitle: string;
|
||
title: string;
|
||
intro: string;
|
||
accountHint: string;
|
||
nameLabel: string;
|
||
emailLabel: string;
|
||
emailHint: string;
|
||
referenceLabel: string;
|
||
referenceHint: string;
|
||
messageLabel: string;
|
||
requiredNote: string;
|
||
startButton: string;
|
||
reviewHeading: string;
|
||
reviewIntro: string;
|
||
confirmButton: string;
|
||
editButton: string;
|
||
submitting: string;
|
||
successHeading: string;
|
||
receivedAtLabel: string;
|
||
/** Fuer passende und unpassende Angaben gleich (kein Hinweis, ob eine Mail rausging). */
|
||
successMailNote: string;
|
||
errorMessage: string;
|
||
rateLimited: string;
|
||
invalid: string;
|
||
};
|
||
undoPage: {
|
||
metaTitle: string;
|
||
title: string;
|
||
intro: (end: string) => string;
|
||
button: string;
|
||
successTitle: string;
|
||
successText: string;
|
||
invalidTitle: string;
|
||
invalidText: string;
|
||
notCancelledText: string;
|
||
expiredText: string;
|
||
errorText: string;
|
||
toAccount: string;
|
||
};
|
||
}
|
||
|
||
const de: AboStrings = {
|
||
footerLink: "Verträge hier kündigen",
|
||
status: {
|
||
AUSSTEHEND: "Abschluss offen",
|
||
AKTIV: "Aktiv",
|
||
IM_VERZUG: "Zahlung offen",
|
||
GEKUENDIGT: "Gekündigt",
|
||
BEENDET: "Beendet",
|
||
},
|
||
thanks: {
|
||
metaTitle: "Abo abgeschlossen",
|
||
activeTitle: "Danke für dein Abo!",
|
||
activeText: "Dein Abo ist aktiv – die Urkunde erscheint nach der ersten Zahlung in deinem Konto.",
|
||
processingTitle: "Deine Zahlung wird geprüft",
|
||
processingText:
|
||
"Dein Abo ist abgeschlossen. Bei Lastschrift dauert die Bestätigung der Bank einige Tage – die Urkunde erscheint nach der ersten Zahlung in deinem Konto.",
|
||
notCompletedTitle: "Das Abo wurde nicht abgeschlossen",
|
||
notCompletedText: "Es wurde nichts abgebucht. Du kannst es jederzeit erneut versuchen.",
|
||
toSubscription: "Zum Abo",
|
||
toAccount: "Zu meiner Patenschaft",
|
||
backToOffer: "Zurück zur Patenschaft",
|
||
},
|
||
detail: {
|
||
metaTitle: "Mein Abo",
|
||
back: "Zurück zur Patenschaft",
|
||
title: (offer) => `Abo „${offer}“`,
|
||
beeLine: (bee) => `Patenbiene ${bee}`,
|
||
contractNumber: "Vertragsnummer",
|
||
statusLabel: "Status",
|
||
monthlyPrice: "Monatlicher Betrag",
|
||
nextCharge: "Nächste Abbuchung",
|
||
endsOn: "Endet am",
|
||
paidMonths: "Bezahlte Monate",
|
||
progressTitle: "Bis zur nächsten Honiglieferung",
|
||
progress: (paid, required) => `${paid} von ${required} Monaten bezahlt`,
|
||
progressHarvest: (paid, required) =>
|
||
`${paid} von ${required} Monaten bezahlt – geliefert wird im nächsten Erntefenster`,
|
||
sepaHoldNote:
|
||
"Bei Lastschrift zählt die erste Zahlung erst nach acht Wochen für die Lieferung, weil die Bank sie so lange zurückholen kann.",
|
||
deliveriesTitle: "Honiglieferungen",
|
||
deliveriesEmpty: "Noch keine Lieferung – der Honig kommt, sobald genug Monate bezahlt sind.",
|
||
deliveryPrepared: (date, jars) => `${date}: ${jars} Gläser, in Vorbereitung oder unterwegs`,
|
||
deliveryDeferred: (date) => `${date}: zurückgestellt – wir melden uns bei dir`,
|
||
delinquentNote:
|
||
"Eine Zahlung ist offen. Solange sie nicht ausgeglichen ist, ruhen die Honiglieferungen.",
|
||
paymentTitle: "Zahlungsart",
|
||
paymentText: "Du kannst deine Zahlungsart sicher bei unserem Zahlungsdienstleister Stripe ändern.",
|
||
paymentButton: "Zahlungsart ändern",
|
||
paymentUnavailable: "Das Ändern der Zahlungsart ist gerade nicht möglich. Bitte versuche es später erneut.",
|
||
cancelTitle: "Kündigen",
|
||
cancelText: "Das Abo ist monatlich kündbar und endet zum Ende des bezahlten Monats.",
|
||
cancelButton: "Verträge hier kündigen",
|
||
cancelledNote: (date) => `Gekündigt – das Abo endet am ${date}. Danach wird nichts mehr abgebucht.`,
|
||
endedNote: (date) => `Das Abo ist am ${date} beendet. Urkunde, Medaille und Downloads bleiben in deinem Konto.`,
|
||
certificateLink: "Zur Urkunde",
|
||
cancelDone: (date) => `Deine Kündigung ist eingegangen. Das Abo endet am ${date}. Eine Bestätigung ist per Mail unterwegs.`,
|
||
cancelFailed: "Die Kündigung konnte gerade nicht verarbeitet werden. Bitte versuche es erneut oder nutze die Seite „Verträge hier kündigen“.",
|
||
},
|
||
confirm: {
|
||
metaTitle: "Kündigung bestätigen",
|
||
title: "Kündigung bestätigen",
|
||
intro: "Bitte prüfe deine Angaben. Mit dem Klick auf „Jetzt kündigen“ ist die Kündigung erklärt.",
|
||
kindLabel: "Art der Kündigung",
|
||
kindValue: "Ordentliche Kündigung zum nächstmöglichen Zeitpunkt",
|
||
contractLabel: "Vertrag",
|
||
effectiveLabel: "Wirksam zum",
|
||
effectiveValue: (date) => `${date} (Ende des bezahlten Monats)`,
|
||
confirmationLabel: "Bestätigung an",
|
||
confirmationValue: (email) => email,
|
||
submit: "Jetzt kündigen",
|
||
back: "Abbrechen",
|
||
},
|
||
publicPage: {
|
||
metaTitle: "Verträge hier kündigen",
|
||
title: "Verträge hier kündigen",
|
||
intro:
|
||
"Hier kündigst du dein Abo der Bienenpatenschaft ohne Anmeldung. Die Kündigung wirkt zum Ende des bezahlten Monats. Du bekommst sofort eine Eingangsbestätigung per Mail.",
|
||
accountHint: "Mit Kundenkonto geht es auch direkt dort: Konto → Patenschaft → Abo.",
|
||
nameLabel: "Vor- und Nachname *",
|
||
emailLabel: "E-Mail-Adresse *",
|
||
emailHint: "Die Adresse deines Kundenkontos – dorthin geht die Bestätigung.",
|
||
referenceLabel: "Vertragsnummer *",
|
||
referenceHint: "Die Patenschaftsnummer von der Urkunde (WH-P-…) oder die Vertragsnummer aus deinem Konto.",
|
||
messageLabel: "Nachricht (optional)",
|
||
requiredNote: "* Pflichtangaben",
|
||
startButton: "Verträge hier kündigen",
|
||
reviewHeading: "Kündigung bestätigen",
|
||
reviewIntro: "Bitte prüfe deine Angaben. Mit dem Klick auf „Jetzt kündigen“ ist die Kündigung erklärt.",
|
||
confirmButton: "Jetzt kündigen",
|
||
editButton: "Angaben ändern",
|
||
submitting: "Wird gesendet …",
|
||
successHeading: "Deine Kündigung ist eingegangen",
|
||
receivedAtLabel: "Eingegangen am",
|
||
successMailNote:
|
||
"Die Eingangsbestätigung schicken wir an die E-Mail-Adresse deines Kundenkontos. Bitte bewahre diese Seite als Nachweis auf (Ausdruck oder Bildschirmfoto).",
|
||
errorMessage: "Deine Kündigung konnte nicht gesendet werden. Bitte versuche es erneut oder schreib uns eine Mail.",
|
||
rateLimited: "Zu viele Anfragen. Bitte versuche es später erneut oder schreib uns eine Mail.",
|
||
invalid: "Bitte überprüfe deine Angaben.",
|
||
},
|
||
undoPage: {
|
||
metaTitle: "Kündigung zurücknehmen",
|
||
title: "Kündigung zurücknehmen",
|
||
intro: (end) => `Dein Abo ist zum ${end} gekündigt. Wenn du die Kündigung zurücknimmst, läuft es einfach weiter wie bisher.`,
|
||
button: "Kündigung zurücknehmen",
|
||
successTitle: "Dein Abo läuft weiter",
|
||
successText: "Die Kündigung ist zurückgenommen. Es ändert sich nichts an deinem Abo.",
|
||
invalidTitle: "Dieser Link gilt nicht (mehr)",
|
||
invalidText: "Der Link ist abgelaufen, unvollständig oder die Kündigung wurde schon zurückgenommen. Im Kundenkonto siehst du den aktuellen Stand.",
|
||
notCancelledText: "Für dieses Abo ist keine Kündigung (mehr) vorgemerkt.",
|
||
expiredText: "Der Kündigungstermin ist schon erreicht; zurücknehmen lässt sich die Kündigung nicht mehr.",
|
||
errorText: "Das hat gerade nicht geklappt. Bitte versuche es gleich noch einmal oder schreib uns eine Mail.",
|
||
toAccount: "Zum Kundenkonto",
|
||
},
|
||
};
|
||
|
||
const en: AboStrings = {
|
||
footerLink: "Cancel contracts here",
|
||
status: {
|
||
AUSSTEHEND: "Sign-up pending",
|
||
AKTIV: "Active",
|
||
IM_VERZUG: "Payment outstanding",
|
||
GEKUENDIGT: "Cancelled",
|
||
BEENDET: "Ended",
|
||
},
|
||
thanks: {
|
||
metaTitle: "Subscription confirmed",
|
||
activeTitle: "Thank you for subscribing!",
|
||
activeText: "Your subscription is active – the certificate appears in your account after the first payment.",
|
||
processingTitle: "Your payment is being confirmed",
|
||
processingText:
|
||
"Your subscription is set up. With direct debit, the bank takes a few days to confirm – the certificate appears in your account after the first payment.",
|
||
notCompletedTitle: "The subscription was not completed",
|
||
notCompletedText: "Nothing has been charged. You can try again at any time.",
|
||
toSubscription: "View subscription",
|
||
toAccount: "My sponsorship",
|
||
backToOffer: "Back to bee sponsorship",
|
||
},
|
||
detail: {
|
||
metaTitle: "My subscription",
|
||
back: "Back to sponsorship",
|
||
title: (offer) => `Subscription “${offer}”`,
|
||
beeLine: (bee) => `Sponsored bee ${bee}`,
|
||
contractNumber: "Contract number",
|
||
statusLabel: "Status",
|
||
monthlyPrice: "Monthly amount",
|
||
nextCharge: "Next charge",
|
||
endsOn: "Ends on",
|
||
paidMonths: "Paid months",
|
||
progressTitle: "Until the next honey delivery",
|
||
progress: (paid, required) => `${paid} of ${required} months paid`,
|
||
progressHarvest: (paid, required) => `${paid} of ${required} months paid – delivered in the next harvest window`,
|
||
sepaHoldNote:
|
||
"With direct debit, the first payment only counts towards a delivery after eight weeks, because the bank can reverse it until then.",
|
||
deliveriesTitle: "Honey deliveries",
|
||
deliveriesEmpty: "No delivery yet – the honey comes as soon as enough months are paid.",
|
||
deliveryPrepared: (date, jars) => `${date}: ${jars} jars, being prepared or on the way`,
|
||
deliveryDeferred: (date) => `${date}: on hold – we will get in touch`,
|
||
delinquentNote: "A payment is outstanding. Honey deliveries are paused until it is settled.",
|
||
paymentTitle: "Payment method",
|
||
paymentText: "You can change your payment method securely with our payment provider Stripe.",
|
||
paymentButton: "Change payment method",
|
||
paymentUnavailable: "Changing the payment method is not possible right now. Please try again later.",
|
||
cancelTitle: "Cancel",
|
||
cancelText: "The subscription can be cancelled monthly and ends at the end of the paid month.",
|
||
cancelButton: "Cancel contracts here",
|
||
cancelledNote: (date) => `Cancelled – the subscription ends on ${date}. Nothing will be charged afterwards.`,
|
||
endedNote: (date) => `The subscription ended on ${date}. Your certificate, medal and downloads remain in your account.`,
|
||
certificateLink: "View certificate",
|
||
cancelDone: (date) => `We have received your cancellation. The subscription ends on ${date}. A confirmation is on its way by email.`,
|
||
cancelFailed: "The cancellation could not be processed right now. Please try again or use the “Cancel contracts here” page.",
|
||
},
|
||
confirm: {
|
||
metaTitle: "Confirm cancellation",
|
||
title: "Confirm cancellation",
|
||
intro: "Please check your details. Clicking “Cancel now” submits your cancellation.",
|
||
kindLabel: "Type of cancellation",
|
||
kindValue: "Ordinary cancellation at the earliest possible date",
|
||
contractLabel: "Contract",
|
||
effectiveLabel: "Effective on",
|
||
effectiveValue: (date) => `${date} (end of the paid month)`,
|
||
confirmationLabel: "Confirmation to",
|
||
confirmationValue: (email) => email,
|
||
submit: "Cancel now",
|
||
back: "Back",
|
||
},
|
||
publicPage: {
|
||
metaTitle: "Cancel contracts here",
|
||
title: "Cancel contracts here",
|
||
intro:
|
||
"Cancel your bee sponsorship subscription here without logging in. The cancellation takes effect at the end of the paid month. You receive a confirmation of receipt by email right away.",
|
||
accountHint: "With a customer account you can also do this directly there: Account → Sponsorship → Subscription.",
|
||
nameLabel: "First and last name *",
|
||
emailLabel: "Email address *",
|
||
emailHint: "The address of your customer account – the confirmation goes there.",
|
||
referenceLabel: "Contract number *",
|
||
referenceHint: "The sponsorship number from the certificate (WH-P-…) or the contract number from your account.",
|
||
messageLabel: "Message (optional)",
|
||
requiredNote: "* Required",
|
||
startButton: "Cancel contracts here",
|
||
reviewHeading: "Confirm cancellation",
|
||
reviewIntro: "Please check your details. Clicking “Cancel now” submits your cancellation.",
|
||
confirmButton: "Cancel now",
|
||
editButton: "Edit details",
|
||
submitting: "Sending …",
|
||
successHeading: "We have received your cancellation",
|
||
receivedAtLabel: "Received on",
|
||
successMailNote:
|
||
"We send the confirmation of receipt to the email address of your customer account. Please keep this page as proof (print or screenshot).",
|
||
errorMessage: "Your cancellation could not be sent. Please try again or email us.",
|
||
rateLimited: "Too many requests. Please try again later or email us.",
|
||
invalid: "Please check your details.",
|
||
},
|
||
undoPage: {
|
||
metaTitle: "Withdraw cancellation",
|
||
title: "Withdraw cancellation",
|
||
intro: (end) => `Your subscription is cancelled as of ${end}. If you withdraw the cancellation, it simply continues as before.`,
|
||
button: "Withdraw cancellation",
|
||
successTitle: "Your subscription continues",
|
||
successText: "The cancellation has been withdrawn. Nothing changes about your subscription.",
|
||
invalidTitle: "This link is not (or no longer) valid",
|
||
invalidText: "The link has expired, is incomplete or the cancellation has already been withdrawn. Your customer account shows the current status.",
|
||
notCancelledText: "No cancellation is (any longer) scheduled for this subscription.",
|
||
expiredText: "The cancellation date has already been reached; the cancellation can no longer be withdrawn.",
|
||
errorText: "That did not work just now. Please try again shortly or email us.",
|
||
toAccount: "To your account",
|
||
},
|
||
};
|
||
|
||
export function getAboStrings(locale: Locale): AboStrings {
|
||
return locale === "en" ? en : de;
|
||
}
|