diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index d8804c28..11dea9ad 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -3798,7 +3798,7 @@ "acceptedLocked": "Dieses Angebot wurde bereits angenommen.", "declinedLocked": "Dieses Angebot wurde abgelehnt.", "cannotRespond": "Es ist nicht mehr möglich, auf dieses Angebot zu antworten.", - "changeWithin": "Sie können Ihre Antwort bis {{at}} ändern.", + "changeWithin": "Sie können Ihre Antwort innerhalb von {{minutes}} Minuten ändern.", "intro": "Vielen Dank für Ihre Anfrage. Bitte prüfen Sie das folgende Angebot und antworten Sie unten.", "accept": "Angebot annehmen", "decline": "Angebot ablehnen" diff --git a/frontend/src/pages/public/QuoteResponsePage.tsx b/frontend/src/pages/public/QuoteResponsePage.tsx index 212ed383..4d651e18 100644 --- a/frontend/src/pages/public/QuoteResponsePage.tsx +++ b/frontend/src/pages/public/QuoteResponsePage.tsx @@ -297,7 +297,22 @@ export const QuoteResponsePage: React.FC = () => { <>
{quote.respondedAt - ? t('quoteResponse.changeWithin', 'You can change your response until {{at}}.', { at: quote.responseLockedAt ? new Date(quote.responseLockedAt).toLocaleTimeString() : '' }) + ? t('quoteResponse.changeWithin', 'You can change your response until {{at}}.', (() => { + // Provide both variables so EN ("until {{at}}") + // and DE ("innerhalb von {{minutes}} Minuten") + // each render correctly without needing locale- + // specific call sites. `minutes` rounds UP so a + // 14m 32s remainder shows as "15 Minuten" — never + // promise a number the user can't actually hit. + const lockAt = quote.responseLockedAt ? new Date(quote.responseLockedAt) : null; + const minutes = lockAt + ? Math.max(0, Math.ceil((lockAt.getTime() - Date.now()) / 60000)) + : 0; + return { + at: lockAt ? lockAt.toLocaleTimeString() : '', + minutes, + }; + })()) : t('quoteResponse.intro', 'Please accept or decline this quote:')}