From b0a9dfeedb11097538795a73a25a5aa783a98cf5 Mon Sep 17 00:00:00 2001 From: Till JS Date: Tue, 7 Apr 2026 17:05:20 +0200 Subject: [PATCH] feat(cycles): month calendar view with phase coloring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a CycleCalendar component above the edit sections in the workbench ListView. Shows a 7×6 month grid with each day colored by its derived phase, small flow markers on days with bleeding, the current day outlined, and the edit target highlighted with a ring. - Prev/next month buttons and a clickable header to jump back to the current month - Monday-first week, weekday labels localized via locale store - Clicking any day switches editingDate so the flow/mood/symptom controls below update that day directly - Collapsible via a +/− toggle in the section header - i18n keys for calendar.title/prev/next; de + en translated, it/fr/es mirrored from en Co-Authored-By: Claude Opus 4.6 (1M context) --- .../web/src/lib/i18n/locales/cycles/de.json | 5 + .../web/src/lib/i18n/locales/cycles/en.json | 5 + .../web/src/lib/i18n/locales/cycles/es.json | 5 + .../web/src/lib/i18n/locales/cycles/fr.json | 5 + .../web/src/lib/i18n/locales/cycles/it.json | 5 + .../src/lib/modules/cycles/ListView.svelte | 17 + .../cycles/components/CycleCalendar.svelte | 305 ++++++++++++++++++ 7 files changed, 347 insertions(+) create mode 100644 apps/mana/apps/web/src/lib/modules/cycles/components/CycleCalendar.svelte diff --git a/apps/mana/apps/web/src/lib/i18n/locales/cycles/de.json b/apps/mana/apps/web/src/lib/i18n/locales/cycles/de.json index 4e74b2915..84e70857d 100644 --- a/apps/mana/apps/web/src/lib/i18n/locales/cycles/de.json +++ b/apps/mana/apps/web/src/lib/i18n/locales/cycles/de.json @@ -67,6 +67,11 @@ "emotional": "Emotional", "other": "Sonstiges" }, + "calendar": { + "title": "Kalender", + "prev": "Vorheriger Monat", + "next": "Nächster Monat" + }, "symptomManager": { "title": "Symptome verwalten", "open": "Verwalten", diff --git a/apps/mana/apps/web/src/lib/i18n/locales/cycles/en.json b/apps/mana/apps/web/src/lib/i18n/locales/cycles/en.json index cb89c5822..7a5bee423 100644 --- a/apps/mana/apps/web/src/lib/i18n/locales/cycles/en.json +++ b/apps/mana/apps/web/src/lib/i18n/locales/cycles/en.json @@ -67,6 +67,11 @@ "emotional": "Emotional", "other": "Other" }, + "calendar": { + "title": "Calendar", + "prev": "Previous month", + "next": "Next month" + }, "symptomManager": { "title": "Manage symptoms", "open": "Manage", diff --git a/apps/mana/apps/web/src/lib/i18n/locales/cycles/es.json b/apps/mana/apps/web/src/lib/i18n/locales/cycles/es.json index cb89c5822..7a5bee423 100644 --- a/apps/mana/apps/web/src/lib/i18n/locales/cycles/es.json +++ b/apps/mana/apps/web/src/lib/i18n/locales/cycles/es.json @@ -67,6 +67,11 @@ "emotional": "Emotional", "other": "Other" }, + "calendar": { + "title": "Calendar", + "prev": "Previous month", + "next": "Next month" + }, "symptomManager": { "title": "Manage symptoms", "open": "Manage", diff --git a/apps/mana/apps/web/src/lib/i18n/locales/cycles/fr.json b/apps/mana/apps/web/src/lib/i18n/locales/cycles/fr.json index cb89c5822..7a5bee423 100644 --- a/apps/mana/apps/web/src/lib/i18n/locales/cycles/fr.json +++ b/apps/mana/apps/web/src/lib/i18n/locales/cycles/fr.json @@ -67,6 +67,11 @@ "emotional": "Emotional", "other": "Other" }, + "calendar": { + "title": "Calendar", + "prev": "Previous month", + "next": "Next month" + }, "symptomManager": { "title": "Manage symptoms", "open": "Manage", diff --git a/apps/mana/apps/web/src/lib/i18n/locales/cycles/it.json b/apps/mana/apps/web/src/lib/i18n/locales/cycles/it.json index cb89c5822..7a5bee423 100644 --- a/apps/mana/apps/web/src/lib/i18n/locales/cycles/it.json +++ b/apps/mana/apps/web/src/lib/i18n/locales/cycles/it.json @@ -67,6 +67,11 @@ "emotional": "Emotional", "other": "Other" }, + "calendar": { + "title": "Calendar", + "prev": "Previous month", + "next": "Next month" + }, "symptomManager": { "title": "Manage symptoms", "open": "Manage", diff --git a/apps/mana/apps/web/src/lib/modules/cycles/ListView.svelte b/apps/mana/apps/web/src/lib/modules/cycles/ListView.svelte index d33eac608..50d7749a4 100644 --- a/apps/mana/apps/web/src/lib/modules/cycles/ListView.svelte +++ b/apps/mana/apps/web/src/lib/modules/cycles/ListView.svelte @@ -21,6 +21,7 @@ predictNextPeriodStart, } from './utils/prediction'; import { FLOW_COLORS, MOOD_COLORS, PHASE_COLORS, type Flow, type Mood } from './types'; + import CycleCalendar from './components/CycleCalendar.svelte'; import SymptomManager from './components/SymptomManager.svelte'; import type { ViewProps } from '$lib/app-registry'; @@ -52,6 +53,9 @@ // ─ Symptom manager modal state let symptomManagerOpen = $state(false); + // ─ Calendar visibility toggle + let calendarOpen = $state(true); + // ─ Editing state — defaults to today, can be switched to any past day let editingDate = $state(todayIso); let editingLog = $derived(logs.find((l) => l.logDate === editingDate) ?? null); @@ -177,6 +181,19 @@ + +
+
+ + +
+ {#if calendarOpen} + + {/if} +
+ {#if isEditingPast}
diff --git a/apps/mana/apps/web/src/lib/modules/cycles/components/CycleCalendar.svelte b/apps/mana/apps/web/src/lib/modules/cycles/components/CycleCalendar.svelte new file mode 100644 index 000000000..e38ee82af --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/cycles/components/CycleCalendar.svelte @@ -0,0 +1,305 @@ + + + +
+
+ + + +
+ +
+ {#each weekdays as wd} +
{wd}
+ {/each} +
+ +
+ {#each cells as cell (cell.iso)} + + {/each} +
+
+ +