Files
homeschool/backend/app/schemas/activity.py
derekc 823260cdd8 Add timezone selector to Admin settings with full-stack support
- Add `timezone` column to User model (VARCHAR 64, default UTC) with
  idempotent startup migration
- Expose and persist timezone via PATCH /api/users/me
- Fix TimerEvent.occurred_at serialization to include UTC offset marker
  (+00:00) so JavaScript correctly parses timestamps as UTC
- Add frontend utility (src/utils/time.js) with timezone-aware
  formatTime, getHHMM, getDateInTZ, tzDateTimeToUTC helpers and a
  curated IANA timezone list
- Add Settings section to Admin page with timezone dropdown; saves to
  both the API and localStorage for the unauthenticated TV view
- Update Activity Log to display and edit times in the user's timezone
- Update TV dashboard clock to respect the saved timezone
- Update README: features, setup steps, usage table, WebSocket events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 14:16:37 -08:00

54 lines
1.3 KiB
Python

from datetime import date, datetime, timezone
from pydantic import BaseModel, field_serializer
class ActivityLogCreate(BaseModel):
child_id: int
subject_id: int | None = None
session_id: int | None = None
log_date: date
notes: str | None = None
duration_minutes: int | None = None
class ActivityLogUpdate(BaseModel):
notes: str | None = None
duration_minutes: int | None = None
subject_id: int | None = None
class ActivityLogOut(BaseModel):
id: int
child_id: int
subject_id: int | None
session_id: int | None
log_date: date
notes: str | None
duration_minutes: int | None
model_config = {"from_attributes": True}
class TimelineEventUpdate(BaseModel):
event_type: str | None = None
occurred_at: datetime | None = None
class TimelineEventOut(BaseModel):
id: int
event_type: str
occurred_at: datetime
session_date: date
child_id: int
child_name: str
block_label: str | None = None
subject_name: str | None = None
subject_icon: str | None = None
subject_color: str | None = None
@field_serializer("occurred_at")
def serialize_occurred_at(self, dt: datetime) -> str:
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return dt.isoformat()