Commit 16b0e23
feat(calendar): Add conference calendar management (#381)
* feat(calendar): Add conference calendar with days, tracks, and entries
Implement a full calendar system for conferences including:
- Database schema: CalendarDay, CalendarTrack, CalendarEntry models with migrations
- GraphQL resolvers for CRUD operations on all calendar entities
- CASL ability definitions for calendar entity authorization
- Calendar management page with tabs for days, tracks, entries, and preview
- Calendar display components (CalendarDisplay, CalendarDayView, CalendarEntryCard)
- Dashboard calendar section for conference overview
- Color palette system for track styling
- Conference configuration option to show/hide calendar
- Seed data for development
- German and English translations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add reusable Place model for calendar entries
Replace plain place strings on CalendarEntry with a proper Place model
that stores venue name, address, coordinates, directions, info/warnings,
website URL, and site plan PDF. This enables venue reuse across entries
and structured data for maps and navigation.
- Add Place model with Prisma migration and GraphQL CRUD resolver
- Add Places tab to calendar management with full CRUD including PDF upload
- Change entry form place input from text to select dropdown
- Add DaisyUI tooltips showing track descriptions on hover
- Update calendar display components to use place object interface
- Add seed data for Landtag and Kulturzentrum venues
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add clickable calendar entries with detail drawer
- Install vaul-svelte for animated drawer with touch gestures
- Make CalendarEntryCard clickable (div→button with hover feedback)
- Thread onEntryClick callback through CalendarDayView to CalendarDisplay
- Create CalendarEntryDrawer with responsive direction (bottom on mobile,
right on desktop), colored header, time/track info, description,
location details with directions/warnings, interactive map via sveaflet,
and platform-aware map links (Apple Maps, Google Maps, OpenStreetMap)
- Expand place fields in all three calendar GraphQL queries
- Add translateCalendarEntryColor to enumTranslations utility
- Use localized color names in management entries table
- Add translation keys for drawer UI (EN + DE)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add track filter dropdown to entries tab
Allows filtering entries by track when a day has multiple tracks,
improving overview when managing many entries. Filter resets
automatically when switching days.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Improve calendar UX with overlap warnings, today auto-select, and trackless day support
- Add overlap detection and warning indicators in entries table
- Auto-select today's date in calendar preview if it matches a day
- Fix calendar day view to handle days with no tracks (single unnamed column)
- Add site plan download button in entry detail drawer
- Refine entry card styling and color palette
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add bulk copy entries from one day to another
Allows copying all entries from the currently selected day to a target day,
matching tracks by name and preserving times, places, and other properties.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(dashboard): Collapse calendar section by default
Add collapsible support to DashboardSection with a visible toggle button,
and default the calendar to collapsed so users don't have to scroll past it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add Plus Code input and map preview to place modals
Allow users to paste Google Maps Plus Codes (both short codes like
"84W3+7X Kiel" and full codes) to auto-fill latitude/longitude when
creating or editing places. Short codes are resolved via Nominatim
geocoding. A live OpenStreetMap preview shows the marker position
below the coordinate fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add JSON export/import for calendar days
Allows exporting a day's tracks, entries, and places as JSON and
importing them when creating a new day, so schedule structures can
be reused across days or conferences.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(calendar): Resolve lint errors in calendar components
- Use void operator for $effect dependency tracking expressions
- Replace URLSearchParams with manual URL construction in drawer
- Add eslint-disable for non-reactive Date/Set usage in functions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(deps): Bump nodemailer 6.10.1 → 7.0.13 (CVE-2025-14874)
Fixes DoS via crafted email address header causing infinite recursion
in the address parser. Only breaking change in v7 is SES SDK removal
which does not affect this project (uses SMTP transport).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: Increase Node.js heap size for PR build job
The vite build OOMs on the default ~2GB heap in GitHub Actions.
Match the Dockerfile's 8GB setting for the CI build step.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(calendar): Address PR review feedback
- Tighten time regex to reject invalid hours/minutes (e.g. 99:99)
- Use z.nativeEnum(CalendarEntryColor) instead of manual z.enum
- Remove unnecessary type casts (as string, as CalendarEntryColor)
- Replace type assertions with instanceof/typeof narrowing in file upload handlers
- Fix end-time auto-calculation overflow (23:00 + 1h → 00:00 instead of 24:00)
- Parallelize copyDayEntries mutations with Promise.allSettled
- Derive allColors from colorMap keys instead of duplicating enum values
- Add keyboard accessibility to DashboardSection collapsible header
- Prevent headerAction clicks from toggling collapse via stopPropagation
- Use fa-duotone consistently for chevron and info icons
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(calendar): Address second round of PR review feedback
- Wrap JSON.parse in try/catch for consistent error message on malformed input
- Use setUTCHours instead of setHours for timezone-deterministic entry times
- Add aria-expanded attribute to DashboardSection collapsible header
- Add response.ok check before parsing Nominatim geocoding response
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(calendar): Fix export/import timezone round-trip
Export now uses getUTCHours to produce timezone-agnostic time strings,
matching the import mutation's setUTCHours. This ensures entries
survive an export→import cycle without shifting by the browser's
UTC offset.
All other operations (create, edit, copy, move, display, time marker)
consistently use browser-local timezone methods, which is correct for
co-located conference attendees.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add conference timezone for calendar time marker
The CalendarTimeMarker "now" line previously used UTC time, causing it
to show the wrong position for conferences not in UTC. This adds a
timezone field to Conference (defaulting to Europe/Berlin) and threads
it through the component chain so the marker uses Intl.DateTimeFormat
to compute conference-local "now".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(calendar): Address PR review feedback and add PARTICIPANT_CARE permissions
- Grant PARTICIPANT_CARE role CRUD access to all calendar entities
(CalendarDay, CalendarTrack, CalendarEntry, Place) in both CASL
abilities and resolver-level create mutation checks
- Fix CalendarTimeMarker midnight boundary with hourCycle: 'h23'
- Fix CalendarDisplay today-tab selection to use conference timezone
- Add end time > start time validation in entry create/edit modals
- Fix informal "du" in German translation for calendarImportInvalidJSON
- Document Calendar components in CLAUDE-UI.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style(calendar): Adjust calendar entry color palette and fix indentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(calendar): Add edit buttons to calendar entry drawer on management pages
Pass optional onEditEntry/onEditPlace callbacks through CalendarDisplay
to CalendarEntryDrawer, rendering edit buttons in the drawer footer only
on management pages. Dashboard view remains unaffected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent bf279dc commit 16b0e23
File tree
48 files changed
+6247
-10
lines changed- .github/workflows
- messages
- prisma
- migrations
- 20260214092318_add_conference_calendar
- 20260214100129_add_show_calendar_to_conference
- 20260214120000_add_place_model
- 20260215175446_add_conference_timezone
- seed/dev
- src
- api
- abilities
- entities
- resolvers
- modules
- calendar
- conference
- lib
- components
- Calendar
- Dashboard
- queries
- schemata
- services
- routes/(authenticated)
- dashboard/[conferenceId]
- management/[conferenceId]
- calendar
- configuration
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
48 files changed
+6247
-10
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
| 81 | + | |
80 | 82 | | |
81 | 83 | | |
82 | 84 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
185 | 273 | | |
186 | 274 | | |
187 | 275 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
198 | 278 | | |
199 | 279 | | |
200 | 280 | | |
| |||
320 | 400 | | |
321 | 401 | | |
322 | 402 | | |
| 403 | + | |
| 404 | + | |
323 | 405 | | |
324 | 406 | | |
325 | 407 | | |
| |||
378 | 460 | | |
379 | 461 | | |
380 | 462 | | |
| 463 | + | |
381 | 464 | | |
382 | 465 | | |
383 | 466 | | |
| |||
1138 | 1221 | | |
1139 | 1222 | | |
1140 | 1223 | | |
| 1224 | + | |
1141 | 1225 | | |
1142 | 1226 | | |
1143 | 1227 | | |
| |||
0 commit comments