From c62f8bc2a28d9b09af5fe0538ac1b6908204dd65 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Sun, 22 Feb 2026 01:33:45 +0800 Subject: [PATCH] Add first day of week setting and fix calendar header alignment - Add first_day_of_week column to settings (0=Sunday, 1=Monday) - Add Calendar section in Settings with toggle button - Pass firstDay to FullCalendar from settings - Align calendar toolbar and sidebar header to h-16 (matches UMBRA header) - Remove border/padding wrapper from calendar grid for full-width layout Co-Authored-By: Claude Opus 4.6 --- .../versions/008_add_first_day_of_week.py | 23 +++++++ backend/app/models/settings.py | 1 + backend/app/schemas/settings.py | 9 +++ .../src/components/calendar/CalendarPage.tsx | 11 ++-- .../components/calendar/CalendarSidebar.tsx | 2 +- .../src/components/settings/SettingsPage.tsx | 62 +++++++++++++++++++ frontend/src/types/index.ts | 1 + 7 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 backend/alembic/versions/008_add_first_day_of_week.py diff --git a/backend/alembic/versions/008_add_first_day_of_week.py b/backend/alembic/versions/008_add_first_day_of_week.py new file mode 100644 index 0000000..d7849d6 --- /dev/null +++ b/backend/alembic/versions/008_add_first_day_of_week.py @@ -0,0 +1,23 @@ +"""Add first_day_of_week to settings + +Revision ID: 008 +Revises: 007 +Create Date: 2026-02-22 +""" +from typing import Sequence, Union +from alembic import op +import sqlalchemy as sa + +# revision identifiers +revision: str = '008' +down_revision: Union[str, None] = '007' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.add_column('settings', sa.Column('first_day_of_week', sa.Integer(), server_default='0', nullable=False)) + + +def downgrade() -> None: + op.drop_column('settings', 'first_day_of_week') diff --git a/backend/app/models/settings.py b/backend/app/models/settings.py index 361741e..cba069c 100644 --- a/backend/app/models/settings.py +++ b/backend/app/models/settings.py @@ -15,5 +15,6 @@ class Settings(Base): weather_city: Mapped[str | None] = mapped_column(String(100), nullable=True, default=None) weather_lat: Mapped[float | None] = mapped_column(Float, nullable=True, default=None) weather_lon: Mapped[float | None] = mapped_column(Float, nullable=True, default=None) + first_day_of_week: Mapped[int] = mapped_column(Integer, default=0) # 0=Sunday, 1=Monday created_at: Mapped[datetime] = mapped_column(default=func.now()) updated_at: Mapped[datetime] = mapped_column(default=func.now(), onupdate=func.now()) diff --git a/backend/app/schemas/settings.py b/backend/app/schemas/settings.py index 65d55da..951ecb7 100644 --- a/backend/app/schemas/settings.py +++ b/backend/app/schemas/settings.py @@ -29,6 +29,14 @@ class SettingsUpdate(BaseModel): weather_city: str | None = None weather_lat: float | None = None weather_lon: float | None = None + first_day_of_week: int | None = None + + @field_validator('first_day_of_week') + @classmethod + def validate_first_day(cls, v: int | None) -> int | None: + if v is not None and v not in (0, 1): + raise ValueError('first_day_of_week must be 0 (Sunday) or 1 (Monday)') + return v @field_validator('weather_lat') @classmethod @@ -53,6 +61,7 @@ class SettingsResponse(BaseModel): weather_city: str | None = None weather_lat: float | None = None weather_lon: float | None = None + first_day_of_week: int = 0 created_at: datetime updated_at: datetime diff --git a/frontend/src/components/calendar/CalendarPage.tsx b/frontend/src/components/calendar/CalendarPage.tsx index a96371f..48d4cfa 100644 --- a/frontend/src/components/calendar/CalendarPage.tsx +++ b/frontend/src/components/calendar/CalendarPage.tsx @@ -10,6 +10,7 @@ import { ChevronLeft, ChevronRight } from 'lucide-react'; import api, { getErrorMessage } from '@/lib/api'; import type { CalendarEvent } from '@/types'; import { useCalendars } from '@/hooks/useCalendars'; +import { useSettings } from '@/hooks/useSettings'; import { Button } from '@/components/ui/button'; import { Dialog, @@ -48,6 +49,7 @@ export default function CalendarPage() { const [scopeEvent, setScopeEvent] = useState(null); const [activeEditScope, setActiveEditScope] = useState<'this' | 'this_and_future' | null>(null); + const { settings } = useSettings(); const { data: calendars = [] } = useCalendars(); const { data: events = [] } = useQuery({ @@ -269,8 +271,8 @@ export default function CalendarPage() {
- {/* Custom toolbar */} -
+ {/* Custom toolbar — h-16 matches sidebar header */} +
{/* Calendar grid */} -
-
+
+
-
+
Calendars + +
+

+ Sets which day the calendar week starts on +

+
+ + + Dashboard diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 6a0dc5e..d69b033 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -6,6 +6,7 @@ export interface Settings { weather_city?: string | null; weather_lat?: number | null; weather_lon?: number | null; + first_day_of_week: number; created_at: string; updated_at: string; }