fix(quote-response): compute minutes-remaining for the DE changeWithin string

Previous fix (45f0606) papered over the bug by changing the German
wording from "innerhalb von {{minutes}} Minuten" to "bis {{at}}" —
that worked but changed the UX intent. The original German wording
("you have N minutes left") was deliberate and clearer than an
absolute clock time; the actual bug was that no caller ever computed
`minutes` from `responseLockedAt`.

Revert the DE translation to its original wording, then build a
{ at, minutes } object at the call site so EN ("until {{at}}") and
DE ("innerhalb von {{minutes}} Minuten") each pick up the variable
they need. `minutes` rounds UP so a 14m 32s remainder displays as
"15 Minuten" rather than promising 14 the customer can't actually
hit.
This commit is contained in:
Luca
2026-05-27 16:06:35 +02:00
parent 45f0606ea3
commit 5ce0b6edc3
2 changed files with 17 additions and 2 deletions
+1 -1
View File
@@ -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"
@@ -297,7 +297,22 @@ export const QuoteResponsePage: React.FC = () => {
<>
<p className="text-sm text-neutral-600 dark:text-neutral-400 mb-4">
{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:')}
</p>