From 3df71573895a151968ee6c54f93810cd15e9dc8e Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Mon, 26 Jan 2026 21:20:29 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(calendar):=20fix=20app=20han?= =?UTF-8?q?ging=20and=20layout=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix $effect infinite loop causing app to hang after guest mode - Track viewType and currentDate primitives instead of derived viewRange - Fix root layout to use h-screen flex container for full height - Fix guest banner offset using padding instead of margin - Calendar now fills entire screen with UI floating on top - Simplify i18n initialization --- apps/calendar/apps/web/src/lib/i18n/index.ts | 9 +--- .../apps/web/src/routes/(app)/+layout.svelte | 19 +++++--- .../apps/web/src/routes/(app)/+page.svelte | 43 ++++++++++--------- .../apps/web/src/routes/+layout.svelte | 37 ++++------------ 4 files changed, 47 insertions(+), 61 deletions(-) diff --git a/apps/calendar/apps/web/src/lib/i18n/index.ts b/apps/calendar/apps/web/src/lib/i18n/index.ts index 4928d3441..87c65a934 100644 --- a/apps/calendar/apps/web/src/lib/i18n/index.ts +++ b/apps/calendar/apps/web/src/lib/i18n/index.ts @@ -35,17 +35,12 @@ function getInitialLocale(): SupportedLocale { } // Initialize i18n at module scope (required for SSR) -// Always set initialLocale to ensure it's never undefined +// getInitialLocale() internally checks for browser and falls back to defaultLocale init({ fallbackLocale: defaultLocale, - initialLocale: browser ? getInitialLocale() : defaultLocale, + initialLocale: getInitialLocale(), }); -// On browser, also explicitly set locale to ensure it's loaded -if (browser) { - locale.set(getInitialLocale()); -} - // Set locale and persist to localStorage export function setLocale(newLocale: SupportedLocale) { locale.set(newLocale); diff --git a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte index 2e5d29ecd..0d6a179ab 100644 --- a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte @@ -854,13 +854,11 @@ } /* Offset content when guest banner is visible */ - .layout-container:has(.guest-banner) .main-content { - margin-top: 40px; + .layout-container:has(.guest-banner) { + padding-top: 40px; } - .layout-container:has(.guest-banner) .main-content.floating-mode { - padding-top: calc(70px + 40px); - } + /* Floating mode already has padding-top, no extra adjustment needed since container handles banner offset */ /* Mobile: Fixed viewport, no scroll */ @media (max-width: 768px) { @@ -869,6 +867,12 @@ max-height: 100vh; overflow: hidden; } + + .layout-container:has(.guest-banner) { + height: calc(100vh - 40px); + margin-top: 40px; + padding-top: 0; + } } .main-content { @@ -979,6 +983,11 @@ min-height: 0; } + /* Calendar fills entire screen - UI elements float on top */ + .main-content:has(.content-wrapper.calendar-expanded) { + padding-bottom: 0 !important; + } + /* Immersive Mode - fullscreen, no UI elements visible */ .main-content.immersive { padding: 0 !important; diff --git a/apps/calendar/apps/web/src/routes/(app)/+page.svelte b/apps/calendar/apps/web/src/routes/(app)/+page.svelte index dd6802b61..c0e994ca2 100644 --- a/apps/calendar/apps/web/src/routes/(app)/+page.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/+page.svelte @@ -76,15 +76,25 @@ // Event is automatically removed from store } + // Track view changes to refetch events + let lastViewType = $state(viewStore.viewType); + let lastDateKey = $state(viewStore.currentDate.toDateString()); + onMount(async () => { // Fetch events for current view range (works in both guest and authenticated mode) await eventsStore.fetchEvents(viewStore.viewRange.start, viewStore.viewRange.end); initialized = true; }); - // Refetch events when view changes + // Refetch events when view type or date changes $effect(() => { - if (initialized) { + const currentViewType = viewStore.viewType; + const currentDateKey = viewStore.currentDate.toDateString(); + + // Only refetch if view actually changed + if (initialized && (currentViewType !== lastViewType || currentDateKey !== lastDateKey)) { + lastViewType = currentViewType; + lastDateKey = currentDateKey; eventsStore.fetchEvents(viewStore.viewRange.start, viewStore.viewRange.end); } }); @@ -224,20 +234,20 @@ width: 24px; height: 24px; border-radius: var(--radius-full); - background: hsl(var(--color-surface)); - border: 1px solid hsl(var(--color-border)); + background: var(--color-surface); + border: 1px solid var(--color-border); display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 10; transition: all 150ms ease; - color: hsl(var(--color-muted-foreground)); + color: var(--color-muted-foreground); } .sidebar-collapse-btn:hover { - background: hsl(var(--color-muted)); - color: hsl(var(--color-foreground)); + background: var(--color-muted); + color: var(--color-foreground); } .calendar-main { @@ -247,9 +257,9 @@ min-width: 0; min-height: 0; overflow: hidden; - background: hsl(var(--color-surface)); + background: var(--color-surface); border-radius: var(--radius-lg); - border: 1px solid hsl(var(--color-border)); + border: 1px solid var(--color-border); transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1); } @@ -268,8 +278,8 @@ .calendar-sidebar-mobile { width: 100%; flex-direction: column; - background: hsl(var(--color-surface)); - border-top: 1px solid hsl(var(--color-border)); + background: var(--color-surface); + border-top: 1px solid var(--color-border); padding: 0.75rem; overflow-y: auto; transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1); @@ -290,22 +300,19 @@ flex-direction: column; gap: 0; flex: 1; - height: 100%; /* Fill parent container */ + height: 100%; min-height: 0; overflow: hidden; } - /* Hide desktop elements on mobile */ .desktop-only { display: none !important; } - /* Show mobile elements */ .mobile-only { display: flex; } - /* Calendar container */ .calendar-main { border-radius: 0; border: none; @@ -313,25 +320,21 @@ overflow: hidden; } - /* When todos are visible: 50/50 split */ .calendar-layout:has(.calendar-sidebar-mobile:not(.collapsed)) .calendar-main { flex: 0 0 50%; height: 50%; } - /* When todos are collapsed: calendar takes full space */ .calendar-layout:has(.calendar-sidebar-mobile.collapsed) .calendar-main { flex: 1; height: 100%; } - /* Calendar content must scroll internally */ .calendar-content { height: 100%; overflow-y: auto; } - /* Todos section takes other half */ .calendar-sidebar-mobile { display: flex; flex-direction: column; @@ -345,7 +348,6 @@ overflow: hidden; } - /* Make TodoSidebarSection fill the container */ .calendar-sidebar-mobile > :global(*) { flex: 1; min-height: 0; @@ -359,7 +361,6 @@ } } - /* Tablet: Keep desktop layout but smaller sidebar */ @media (min-width: 769px) and (max-width: 1024px) { .calendar-sidebar { width: 220px; diff --git a/apps/calendar/apps/web/src/routes/+layout.svelte b/apps/calendar/apps/web/src/routes/+layout.svelte index 2256dee79..fd0b34400 100644 --- a/apps/calendar/apps/web/src/routes/+layout.svelte +++ b/apps/calendar/apps/web/src/routes/+layout.svelte @@ -1,51 +1,32 @@ - - -{#if loading} +{#if !appReady} {:else} -
+
{@render children()}
{/if} + +