-
-
- {
- setName(e.target.value);
- setError(null);
- }}
- placeholder="e.g. Sunday morning standup"
- maxLength={REMINDER_NAME_MAX}
- required
- aria-required="true"
- />
-
-
(null);
+
+ async function handleSave() {
+ const trimmed = name.trim();
+ if (!trimmed) {
+ setError("Give the reminder a name.");
+ return;
+ }
+ setSubmitting(true);
+ setError(null);
+ try {
+ const r = await updateReminderAction({
+ reminderId,
+ accountId,
+ groupIds,
+ name: trimmed,
+ messages,
+ scheduledAtIso,
+ rrule,
+ timezone,
+ });
+ if (r.ok) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ router.push(`/reminders/${reminderId}` as any);
+ } else {
+ setError(r.error);
+ setSubmitting(false);
+ }
+ } catch (e) {
+ setError(e instanceof Error ? e.message : "Unexpected error");
+ setSubmitting(false);
+ }
+ }
+
+ return (
+
+
+
+
{
+ setName(e.target.value);
+ setError(null);
+ }}
+ placeholder="e.g. Sunday morning standup"
+ maxLength={REMINDER_NAME_MAX}
+ required
+ aria-required="true"
+ autoFocus
+ />
+
+ Up to {REMINDER_NAME_MAX} characters. Shown in the reminder list and
+ activity log.
+
+
+
+ {error && (
+
+ )}
+
+
+
+
+
+ );
+}
diff --git a/apps/web/src/test/no-render-warnings.test.tsx b/apps/web/src/test/no-render-warnings.test.tsx
index 62835a6..a16d002 100644
--- a/apps/web/src/test/no-render-warnings.test.tsx
+++ b/apps/web/src/test/no-render-warnings.test.tsx
@@ -130,7 +130,7 @@ describe("SSR render — no React errors or warnings", () => {
scheduledAtIso: "2026-05-13T09:00:00.000+08:00",
rrule: "FREQ=DAILY",
timezone: "Asia/Kuala_Lumpur",
- initialName: "",
+ name: "Existing name",
initialMessages: [
{ kind: "text" as const, textContent: "Hello", mediaId: null },
],
@@ -181,7 +181,7 @@ describe("SSR markup — no inside