diff --git a/frontend/src/components/CreateStreamForm.tsx b/frontend/src/components/CreateStreamForm.tsx index 460d4a4..e252449 100644 --- a/frontend/src/components/CreateStreamForm.tsx +++ b/frontend/src/components/CreateStreamForm.tsx @@ -168,6 +168,39 @@ export function CreateStreamForm({ const parsedApiError = apiError ? humaniseApiError(apiError) : null; + const startInMinsNum = Number(values.startInMinutes); + const durationHoursNum = Number(values.durationHours); + const estimatedEndLabel: string | null = (() => { + if ( + values.startInMinutes === "" || + values.durationHours === "" || + isNaN(startInMinsNum) || + isNaN(durationHoursNum) || + durationHoursNum < 1 || + !Number.isInteger(durationHoursNum) + ) { + return null; + } + const nowSeconds = Math.floor(Date.now() / 1000); + const startAt = + startInMinsNum > 0 ? nowSeconds + Math.floor(startInMinsNum * 60) : nowSeconds; + const endAt = startAt + Math.floor(durationHoursNum * 3600); + const endDate = new Date(endAt * 1000); + const datePart = new Intl.DateTimeFormat("en-US", { + month: "short", + day: "numeric", + year: "numeric", + timeZone: "UTC", + }).format(endDate); + const timePart = new Intl.DateTimeFormat("en-US", { + hour: "2-digit", + minute: "2-digit", + hour12: false, + timeZone: "UTC", + }).format(endDate); + return `Ends: ${datePart} at ${timePart} UTC`; + })(); + return (
{parsedApiError && ( @@ -304,6 +337,78 @@ export function CreateStreamForm({ + {/* Duration */} +
+ + { + if (["e", "E", "+", "-", "."].includes(e.key)) e.preventDefault(); + }} + aria-describedby={ + errors.durationHours ? "duration-error" : "duration-hint" + } + aria-invalid={!!errors.durationHours} + required + /> + {estimatedEndLabel && ( + + {estimatedEndLabel} + + )} + {errors.durationHours && ( + + {errors.durationHours} + + )} +
+ + {/* Start In Minutes */} +
+ + { + if (["e", "E", "+", "-", "."].includes(e.key)) e.preventDefault(); + }} + aria-describedby={ + errors.startInMinutes ? "start-error" : "start-hint" + } + aria-invalid={!!errors.startInMinutes} + required + /> + + Enter 0 to start immediately + + {errors.startInMinutes && ( + + {errors.startInMinutes} {/* Duration & Start In Minutes */}