feat(events): support scheduling public events in advance#429
feat(events): support scheduling public events in advance#429jakehobbs wants to merge 13 commits into
Conversation
Add a richer event model so events can be created ahead of time: start/end time, IANA timezone, description, online flag, public flag, and a deduped Google Place location (new `locations` table). The event form expands into a scheduled-event flow when "Public event" is checked, with a Google Places address autocomplete and timezone-aware time fields. After creating a public event, the user lands on a confirmation page (name/date/time/location summary) offering "Take attendance now", "Edit event", "Create another event", and "Done" instead of being dropped on the attendance page. Adds a new Home hub listing today's events, points the post-login redirect and nav logo at /home, and serves a referrer-restricted Google Places key via the authed user-info endpoint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 27 minutes and 34 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis PR implements scheduled public events with Google Places location integration, timezone-aware event discovery, and a confirmation flow. Changes span database schema (new locations table, extended events), server-side event model and validation, updated API contracts, frontend session/context wiring, timezone utilities, TimeField and PlacesAutocomplete components, refactored event form with schema-driven validation, and a new HomeHub discovery page. ChangesScheduled Public Events Feature
🎯 4 (Complex) | ⏱️ ~60 minutes Possibly Related PRs
Suggested Reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds support for scheduling public events in advance with rich metadata (start/end time, IANA timezone, description, online flag, public flag, and a deduped Google Place location), wires it through the event form (revealed when "Public event" is checked), adds a post-create confirmation page and a Home hub of today's events, and repoints the post-login redirect/nav logo to /home. A new locations table with a (chapter_id, google_place_id) unique key backs location dedup; the Google Places key is served from the authed user-info endpoint.
Changes:
- Schema + model: new
locationstable and additionaleventscolumns;getEventsLEFT JOINs locations;CleanEventDatavalidates time/timezone/description and upserts a location viaGetOrCreateLocation. - Frontend: new
homehub,events/[id]/confirmationpage,PlacesAutocomplete,TimeField, andtimezonehelpers;EventFormextended with a collapsible details panel and scheduled-event fields. - Plumbing:
googlePlacesApiKeyflows through session/AuthedPageProvider; nav logo and post-login redirect now target/home;wipe, seed, and Makefile housekeeping.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/shared/db-migrations/20260530120000_advance_events_and_locations.up.sql | Creates locations table and adds scheduling/location columns to events. |
| pkg/shared/db-migrations/20260530120000_advance_events_and_locations.down.sql | Reverts the up migration. |
| pkg/shared/wipe.go | Drops the new locations table in the correct FK order. |
| server/src/model/event.go | Adds JSON/DB fields, GetOrCreateLocation, time/timezone validation, and updates queries. |
| server/src/main.go | Redirects to /home and exposes googlePlacesApiKey from authed user info. |
| cli/cmd/db.go | Makes seed INSERT INTO events column-explicit for the new schema. |
| Makefile | Sources optional .env alongside debug.env when running the server. |
| frontend-v2/src/lib/api.ts | Adds location/scheduling fields to event schemas and save params; surfaces Places key. |
| frontend-v2/src/lib/timezone.ts | New timezone helpers (browser tz, common zones, range/abbreviation formatting, happening-now). |
| frontend-v2/src/app/session.ts | Threads googlePlacesApiKey through fetchSession. |
| frontend-v2/src/app/authed-page-provider.tsx | Adds googlePlacesApiKey to the authed context. |
| frontend-v2/src/app/(authed)/layout.tsx | Passes googlePlacesApiKey into the context. |
| frontend-v2/src/components/nav.tsx | Makes the brand logo link to /home. |
| frontend-v2/src/components/ui/time-field.tsx | New react-aria-based TimeField with a clear button. |
| frontend-v2/src/app/(authed)/events/places-autocomplete.tsx | New Google Places autocomplete input that submits a deduped place. |
| frontend-v2/src/app/(authed)/events/event-form.tsx | Adds scheduled-event fields, collapsible details, post-create confirmation routing. |
| frontend-v2/src/app/(authed)/events/new/page.tsx | Updates title to "New event". |
| frontend-v2/src/app/(authed)/events/[id]/page.tsx | Supports ?edit=1 to start the form expanded; title now "Event". |
| frontend-v2/src/app/(authed)/events/[id]/confirmation/page.tsx | New confirmation page rendered after creating a public event. |
| frontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsx | Confirmation UI with next-step actions. |
| frontend-v2/src/app/(authed)/home/page.tsx | New Home route container. |
| frontend-v2/src/app/(authed)/home/home-hub.tsx | Today's-events hub with "Happening now" badge and entry points. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend-v2/src/app/`(authed)/events/[id]/page.tsx:
- Around line 41-42: The page at /events/[id] currently always renders EventForm
with mode="event" so the post-create "Take attendance now" CTA (which posts to
/events/${eventId}) lands in the editor instead of starting attendance; fix by
routing the CTA to the actual attendance handler or restoring the attendance
view: either update the confirmation screen to send the CTA to the real
attendance route (e.g. /events/${eventId}/attendance or the route handled by
your AttendancePage/AttendanceView) or change page.tsx to conditionally render
the attendance component (e.g. render AttendanceView when a query param or state
indicates attendance flow) instead of always rendering <EventForm mode="event">
so the CTA starts the intended attendance flow.
In `@frontend-v2/src/app/`(authed)/events/event-form.tsx:
- Around line 32-36: The "Today" shortcut and related logic use the browser's
timezone instead of the event form's selected timezone; update usages that
compute today (notably where eventDate is set and the shortcut handler around
todayInTimezone()) to call todayInTimezone(formValues.timezone) (or the
equivalent helper) so the calendar uses the currently selected timezone; locate
and modify the code paths referencing eventDate and the Today shortcut handler
(and the date comparison/initialization logic that currently relies on new
Date() or getBrowserTimezone()) to pass the form's timezone value from the
timezone dropdown/state into the todayInTimezone helper so the selected event
timezone determines "Today".
In `@frontend-v2/src/app/`(authed)/events/places-autocomplete.tsx:
- Around line 182-187: The onChange handler currently only calls onClear() when
the input is emptied, so a user editing a committed place can change the visible
text while the component still holds the old googlePlaceId/address; update the
onChange in places-autocomplete.tsx to clear the committed place as soon as the
user types (call onClear()) whenever the input value changes from a selected
state (i.e., on any non-selection user edit) — ensure this happens inside the
existing onChange (alongside setText) and avoid interfering with the code path
that sets the text when a suggestion is chosen (so that selection still commits
the place).
In `@frontend-v2/src/app/`(authed)/home/home-hub.tsx:
- Line 30: The memoized today value (const today = useMemo(() =>
todayInTimezone(getBrowserTimezone()), [])) never updates after midnight, so
pages left open show yesterday’s events; modify the logic that computes today
(the today variable / useMemo for todayInTimezone and getBrowserTimezone) to
recompute on a daily tick—either add the existing clock state as a dependency to
the useMemo or schedule a timeout/interval that re-evaluates today at the next
local midnight—so that todayInTimezone(getBrowserTimezone()) is called again
when the date changes.
- Around line 47-50: upcomingHref currently computes the one-year-ahead end by
string-slicing today which produces invalid dates on leap day; change
upcomingHref to parse the today string into a proper Date (or use the project's
timezone helper/date library), add one year via date arithmetic (e.g., add 1
year using date-fns/dayjs/luxon or Date.setFullYear(Date.getFullYear()+1) to
handle leap-year rollover), then format the resulting date back into the same
YYYYMMDD string for the end query param; update the logic in the upcomingHref
useMemo (and any helper that reads/outputs today) to use this date-based
approach instead of string slicing.
In `@frontend-v2/src/lib/timezone.ts`:
- Around line 49-56: todayInTimezone and nowMinutesInTimezone call new
Intl.DateTimeFormat with unvalidated timeZone and can throw RangeError; wrap the
Intl.DateTimeFormat/format calls in try/catch and handle invalid zones by
returning a safe fallback (e.g. for todayInTimezone return the local YYYY-MM-DD
string or empty string, for nowMinutesInTimezone return a sentinel like null or
-1), and update isEventHappeningNow (used by HomeHub when passing
event.timezone) to catch/propagate these fallbacks and return false when the
timezone is invalid so a bad event.timezone cannot crash the render.
In `@pkg/shared/db-migrations/20260530120000_advance_events_and_locations.up.sql`:
- Around line 17-25: The current fk_events_location only checks location_id and
allows cross-chapter links; update the schema so events enforces chapter-scoped
locations by making the FK composite: have events reference (location_id,
chapter_id) -> locations (id, chapter_id) (rename or replace fk_events_location
accordingly), ensure events has a chapter_id column, and add a unique/index on
locations (id, chapter_id) so the composite FK can reference those columns.
In `@server/src/model/event.go`:
- Around line 607-656: The code validates fields in isolation but allows
inconsistent scheduled-public events; after calling cleanEventTime and resolving
Timezone/Location (symbols: cleanEventTime, e.StartTime, e.EndTime, e.Timezone,
e.IsOnline, e.LocationID, e.IsPublic), add a coherent-schedule validation: if
e.IsPublic is true then require a non-empty StartTime and a non-empty Timezone
and require a concrete location choice (either e.IsOnline == true or
e.LocationID != nil); if EndTime is present ensure EndTime >= StartTime by
parsing/comparing the two times in the same day context (use the same
format/parse logic as cleanEventTime) and return a clear fmt.Errorf when any of
these checks fail (e.g. "invalid scheduled public event: missing start_time",
"missing timezone", "must be online or have a physical location", or "end_time
before start_time").
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: fce8d66b-61d7-45d4-930a-a2d67ea091d2
📒 Files selected for processing (22)
Makefilecli/cmd/db.gofrontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsxfrontend-v2/src/app/(authed)/events/[id]/confirmation/page.tsxfrontend-v2/src/app/(authed)/events/[id]/page.tsxfrontend-v2/src/app/(authed)/events/event-form.tsxfrontend-v2/src/app/(authed)/events/new/page.tsxfrontend-v2/src/app/(authed)/events/places-autocomplete.tsxfrontend-v2/src/app/(authed)/home/home-hub.tsxfrontend-v2/src/app/(authed)/home/page.tsxfrontend-v2/src/app/(authed)/layout.tsxfrontend-v2/src/app/authed-page-provider.tsxfrontend-v2/src/app/session.tsfrontend-v2/src/components/nav.tsxfrontend-v2/src/components/ui/time-field.tsxfrontend-v2/src/lib/api.tsfrontend-v2/src/lib/timezone.tspkg/shared/db-migrations/20260530120000_advance_events_and_locations.down.sqlpkg/shared/db-migrations/20260530120000_advance_events_and_locations.up.sqlpkg/shared/wipe.goserver/src/main.goserver/src/model/event.go
- Allow & and other chars in event descriptions (parameterized SQL + React-escaped output, so no injection risk); keep the check on names. - Preserve stored location metadata on upsert instead of clobbering with blanks (IF(... <> '')/COALESCE). - Enforce chapter-scoped location integrity via a composite FK (chapter_id, location_id) -> locations (chapter_id, id). - Validate public events server-side: require start_time, timezone, and (in-person) a location. Overnight (end < start) intentionally deferred. - Clear the committed place on manual edits to the location field so the displayed text and submitted location can't drift apart. - Use the event's selected timezone for the "Today" shortcut. - Roll the home page over to the next day at local midnight; guard invalid timezones in Intl calls; compute the one-year-ahead date via Date math. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The home header date is derived from the current time and browser timezone, so SSR and the client can land on different calendar days near midnight or across zones. Gate the date label on a client mount flag so the server and first client render agree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…atch The "View upcoming events" link's date-range query is derived from the current day, which differs between SSR and client near midnight. Use a stable /events fallback until mounted, then the date-filtered URL. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Frontend (frontend-v2): - timezone.ts: reframe header for "upcoming" events and justify the wall-clock + IANA-zone storage choice over a UTC instant; drop the low-value Intl note; fix the misleading COMMON_TIMEZONES "fallback" wording; convert leading comments to JSDoc; move the en-CA note to its use; take an event object (Pick) instead of four positional strings. - home-hub.tsx: drop a redundant comment, use sortedEvents?.map, and extract a TodayEventRow component. - event-confirmation.tsx: pass the event to the time formatter, inline single-use locals, replace margins with parent gap, and navigate via <Link> buttons instead of router.push. - event-form.tsx: correct the "optional" schema comment, drop a stale comment, rename the ?edit=1 query param to ?expanded=1, clarify the HH:MM slice and the onSubmit attendee check, and trim a verbose note. - places-autocomplete.tsx: toast when Google Maps fails to load. - events/[id]/page.tsx: Promise.all the params/searchParams awaits. - api.ts: explain the empty-string default for googlePlacesApiKey. Backend: - model/event.go: reword "existing" to "older basic" attendance flow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend-v2/src/lib/timezone.ts (1)
107-114:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTighten wall-clock validation before formatting or badge math.
frontend-v2/src/lib/api.ts:293-309only narrowsstart_time/end_timeto nullable strings, so these helpers still need to reject impossible clocks. Right now Line 108 and Line 140 accept values like25:99or09:30junk, which can surface bogus labels informatEventTimeRange()and false positives inisEventHappeningNow().Suggested fix
+function parseWallClock( + time: string, +): { hours: number; minutes: number; minutesText: string } | null { + const match = /^(\d{1,2}):(\d{2})(?::\d{2})?$/.exec(time.trim()) + if (!match) return null + + const hours = Number(match[1]) + const minutes = Number(match[2]) + if (hours > 23 || minutes > 59) return null + + return { hours, minutes, minutesText: match[2] } +} + export function formatWallClock(time: string): string { - const match = /^(\d{1,2}):(\d{2})/.exec(time.trim()) - if (!match) return '' - const hours = Number(match[1]) - const minutes = match[2] + const parsed = parseWallClock(time) + if (!parsed) return '' + const { hours, minutesText } = parsed const period = hours >= 12 ? 'PM' : 'AM' const hour12 = hours % 12 === 0 ? 12 : hours % 12 - return `${hour12}:${minutes} ${period}` + return `${hour12}:${minutesText} ${period}` } ... function toMinutesSinceMidnight(time: string): number | null { - const match = /^(\d{1,2}):(\d{2})/.exec(time.trim()) - if (!match) return null - return Number(match[1]) * 60 + Number(match[2]) + const parsed = parseWallClock(time) + return parsed ? parsed.hours * 60 + parsed.minutes : null }Also applies to: 139-142
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend-v2/src/lib/timezone.ts` around lines 107 - 114, formatWallClock currently accepts invalid inputs like "25:99" or "09:30junk" because it uses a loose regex; tighten validation by requiring a full-string match for 24-hour clocks and valid minutes (e.g. regex like ^([01]?\d|2[0-3]):([0-5]\d)$) and reject non-matching values (return ''). Update formatWallClock to trim the input, run the strict regex, parse hours/minutes only after a match and then convert to 12-hour with AM/PM as before; apply the same strict validation approach to helpers that rely on it such as isEventHappeningNow and formatEventTimeRange so they don't receive or accept bogus times.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@frontend-v2/src/lib/timezone.ts`:
- Around line 107-114: formatWallClock currently accepts invalid inputs like
"25:99" or "09:30junk" because it uses a loose regex; tighten validation by
requiring a full-string match for 24-hour clocks and valid minutes (e.g. regex
like ^([01]?\d|2[0-3]):([0-5]\d)$) and reject non-matching values (return '').
Update formatWallClock to trim the input, run the strict regex, parse
hours/minutes only after a match and then convert to 12-hour with AM/PM as
before; apply the same strict validation approach to helpers that rely on it
such as isEventHappeningNow and formatEventTimeRange so they don't receive or
accept bogus times.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: af29fe85-8bac-460a-9c09-dac49c412740
📒 Files selected for processing (8)
frontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsxfrontend-v2/src/app/(authed)/events/[id]/page.tsxfrontend-v2/src/app/(authed)/events/event-form.tsxfrontend-v2/src/app/(authed)/events/places-autocomplete.tsxfrontend-v2/src/app/(authed)/home/home-hub.tsxfrontend-v2/src/lib/api.tsfrontend-v2/src/lib/timezone.tsserver/src/model/event.go
🚧 Files skipped from review as they are similar to previous changes (6)
- frontend-v2/src/app/(authed)/events/[id]/page.tsx
- frontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsx
- server/src/model/event.go
- frontend-v2/src/lib/api.ts
- frontend-v2/src/app/(authed)/events/places-autocomplete.tsx
- frontend-v2/src/app/(authed)/events/event-form.tsx
Restore timeRange/locationLabel locals so the formatter and the location fallback are each evaluated once rather than inlined twice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
alexsapps
left a comment
There was a problem hiding this comment.
exciting times. thanks Jake!
There was a problem hiding this comment.
since this is only the homepage for people with attendance access, and it's only related to events, how about a path like /events/home or /events/today ?
i also feel like the "Welcome" + name/chapter/date is just more boilerplate on a page that already has boilerplate (today's events being the content, and the "Today's events" title and new event / view future events links being boilerplate).
There was a problem hiding this comment.
Keeping this at /home — it's the post-login landing page (the logo links here), and everything it offers is reachable from the events pages too, so I'd rather not surface 'home'/'today' as a nav concept. I did make it earn its keep though: the events content now only renders for users with attendance access, so others just get the header. Leaving the greeting + date as a light orienting touch.
(posted by claude)
There was a problem hiding this comment.
just for the boilerplate then, how about putting the chapter name and today's date underneath "Today's events" and removing "Welcome, name"? i feel like the current boilerplate is a little cramped and little cheesy lol.
| set -a && . server/debug.env && set +a && \ | ||
| set -a && \ | ||
| . server/debug.env && \ | ||
| { [ -f .env ] && . ./.env || true; } && \ |
There was a problem hiding this comment.
should launch.json be updated too? 🙏:)
There was a problem hiding this comment.
Left this one: the Go Server debug config loads a single envFile (server/debug.env), and the new .env is optional (only needed for the Places key locally). Pointing the debugger at a .env most people won't have would break 'Go Server' for them. If you want Places in the debugger, easiest is to drop GOOGLE_PLACES_API_KEY into your local server/debug.env. I documented the .env route in the README.
(posted by claude)
There was a problem hiding this comment.
so far makefile and launch.json behavior have been kept in sync and i'd like to keep it that way if possible, so we don't have situations where things work depending on how they're launched. perhaps we could have 'make deps' create the file if it's missing so it can be added to launch.json too?
| added_attendees: addedAttendees, | ||
| deleted_attendees: deletedAttendees, | ||
| suppress_survey: value.suppressSurvey, | ||
| // Only send scheduled-event fields when they're in play, keeping the |
There was a problem hiding this comment.
It's a guard rather than an optimization: the conditional keeps the connection and quick-attendance save payloads exactly as they were (no is_public/time/location fields), so those flows — coaching especially, which hits a different endpoint — don't start sending event-only fields. Always including them risks clobbering/confusing those paths, so I'd keep it.
(posted by claude)
There was a problem hiding this comment.
how about guarding with just "!isConnection" and removing the comment? it's just a lot to understand right now with the shape of the json depending on certain fields being set.
Frontend: - Split event-form.tsx (~950 lines) into event-form-schema.ts, a useEventForm hook, and event-form-sections.tsx, plus a shared FieldError component and clearLocation helper. - Group the scheduled-event fields in a nested sub-box (still gated by the "Publicly listed" checkbox); stop force-collapsing details on save. - Show timezone abbreviations in the picker options; drop the redundant "Times are in…" line. Remove the "Event details" eyebrow and assorted help/boilerplate text. - Home hub: only render the events section for users with attendance access. - Rename lib/timezone.ts -> lib/time.ts. - Drop the frontend HH:MM:SS slice now that the backend returns HH:MM. - Convert the mount-gate and places-autocomplete syncs off setState-in-effect to satisfy the react-hooks lint rules. Backend: - Return start_time/end_time as HH:MM from EventJSON. - Use ValidationErrorf for public-event input validation (400 not 500). - Tidy Google Places key comments. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Around line 188-190: The fenced code block containing the environment variable
example (the triple-backtick block around "GOOGLE_PLACES_API_KEY=...") needs a
language tag to satisfy markdownlint MD040; update that fenced block (the code
block with the example env line) to include a language specifier such as "bash"
(e.g., ```bash) so the markdown renderer and linter accept it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7ba07f26-2b82-41c6-9853-b957c186f927
📒 Files selected for processing (13)
README.mdfrontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsxfrontend-v2/src/app/(authed)/events/event-form-schema.tsfrontend-v2/src/app/(authed)/events/event-form-sections.tsxfrontend-v2/src/app/(authed)/events/event-form.tsxfrontend-v2/src/app/(authed)/events/places-autocomplete.tsxfrontend-v2/src/app/(authed)/events/useEventForm.tsfrontend-v2/src/app/(authed)/home/home-hub.tsxfrontend-v2/src/app/authed-page-provider.tsxfrontend-v2/src/lib/time.tsserver/src/config/config.goserver/src/main.goserver/src/model/event.go
💤 Files with no reviewable changes (1)
- frontend-v2/src/app/authed-page-provider.tsx
✅ Files skipped from review due to trivial changes (1)
- server/src/config/config.go
🚧 Files skipped from review as they are similar to previous changes (5)
- server/src/main.go
- frontend-v2/src/app/(authed)/events/[id]/confirmation/event-confirmation.tsx
- frontend-v2/src/app/(authed)/events/places-autocomplete.tsx
- frontend-v2/src/app/(authed)/home/home-hub.tsx
- server/src/model/event.go
Some venues aren't a clean Google Place (an intersection, a patch of public land), so allow entering a location by hand: a free-text name plus optional coordinates. Manual locations are stored on the event itself (new manual_location_name/lat/lng columns) rather than the place-keyed locations table, since there's no google_place_id to dedupe on. An event uses either a location_id (Google Place) or the manual fields, never both; ToJSON surfaces whichever is set as a unified location. The form's location field gains a toggle to switch between Google Places search and manual entry; public in-person events accept either. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pnpm prompts before wiping an out-of-sync node_modules, which hangs forever in non-interactive setups (e.g. the Conductor devcontainer 'make deps' step). Set confirm-modules-purge=false at the repo root and in frontend-v2 so the reinstall proceeds without a TTY. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The .npmrc setting wasn't reliably suppressing pnpm's modules-purge prompt in the Conductor devcontainer setup, so 'make deps' hung. Pass the flag explicitly on the pnpm install commands, which is honored regardless of .npmrc resolution. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| <div className={buefyStyles['navbar-brand']}> | ||
| <div className={buefyStyles['navbar-item']}> | ||
| <Link | ||
| href="/home" |
There was a problem hiding this comment.
please add in Vue nav component too
Adds a richer event model so events can be created ahead of time — start/end time, IANA timezone, description, online flag, public flag, and a deduped Google Place location (new
locationstable) — surfaced in the event form via a scheduled-event flow (Places address autocomplete + timezone-aware time fields) that appears when "Public event" is checked. After creating a public event the user now lands on a confirmation page summarizing the event with next-step choices (take attendance, edit, create another, done) instead of being dropped on the attendance page. Also introduces a Home hub listing today's events, repoints the post-login redirect and nav logo to/home, and serves a referrer-restricted Google Places key through the authed user-info endpoint. Backend changes include the migration, event model read/write of the new fields with aLEFT JOIN locations, andwipe/seed/Makefile housekeeping.🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation