fix(events): coerce expires_in_days to Number before addDays

The "Expires on" preview under the days-after-event input rendered
nonsense dates (e.g. 25.04.2026 + 120 days → 08.01.2095, ~68 years
out). Cause: handleInputChange stores e.target.value verbatim, which is
a string for <input type="number">, so formData.expires_in_days is "120"
not 120. date-fns addDays does:

  _date.setDate(_date.getDate() + amount)

When amount is a string, the + is string concatenation:
25 + "120" = "25120". setDate("25120") then sets day-of-month to 25120,
which carries over by ~68 years.

Fix: cast to Number at the call site. The validation/API-payload
codepaths already work because the comparisons at line 330 and the
JSON payload coerce numerically through different paths — only addDays
was actually broken.

The TypeScript type FormData.expires_in_days: number is a lie because
handleInputChange's [field]: e.target.value sets a string regardless.
Tightening that handler is a separate cleanup; this commit only fixes
the visible date bug.
This commit is contained in:
Paul Nothaft
2026-05-01 23:22:56 +02:00
parent 8f7258bfc8
commit db29d0e278
+6 -1
View File
@@ -780,7 +780,12 @@ export const CreateEventPage: React.FC = () => {
</div>
{formData.event_date && (
<p className="mt-2 text-sm text-neutral-500 dark:text-neutral-400">
{t('events.expiresOn')}: {format(addDays(new Date(formData.event_date), formData.expires_in_days))}
{/* Coerce to Number — handleInputChange stores the
<input type="number"> value as a string, and date-fns
addDays does `_date.setDate(_date.getDate() + amount)`
which string-concatenates (25 + "120" = "25120") and
ends up ~68 years in the future. */}
{t('events.expiresOn')}: {format(addDays(new Date(formData.event_date), Number(formData.expires_in_days)))}
</p>
)}
</div>