Skip to content

Online event support with auto country via organizer geolocation#174

Merged
malkoG merged 4 commits into
devfrom
feature/online-events
Apr 17, 2026
Merged

Online event support with auto country via organizer geolocation#174
malkoG merged 4 commits into
devfrom
feature/online-events

Conversation

@malkoG

@malkoG malkoG commented Apr 17, 2026

Copy link
Copy Markdown
Member

Summary

Adds first-class online-event support: organizers toggle In-person / Online on the event form, and online events capture a meeting URL (Zoom/Meet/Discord/etc.) instead of a physical venue. For country discoverability, the browser silently supplies the organizer's geolocation (only when permission is already granted — no fresh prompt), the server reverse-geocodes it to an ISO country code via the existing reverseGeocodeCountry utility, and only the country code is persisted — raw coords are discarded. A bonus fix: country now recomputes when an in-person event's placeId changes (previously went stale).


Assisted-By: Claude Code(claude-opus-4-7)

malkoG added 4 commits April 17, 2026 16:05
Preparing first-class support for online events. Two new columns:

  * event_type varchar(16) NOT NULL DEFAULT 'in_person'
    — effective domain "in_person" | "online". Plain varchar keeps
    migration low-risk; no Postgres enum needed.
  * meeting_url text NULL
    — Zoom/Meet/Discord invite for online events. Kept separate
    from externalUrl (which is still "redirect attendees to external
    registration") to avoid conflating two distinct concepts.

Existing rows read as in_person with meetingUrl NULL thanks to the
NOT NULL DEFAULT — backward compatible. Application code in
subsequent commits.

The migration uses IF NOT EXISTS so replay against a DB that
already has the columns (e.g. applied via raw SQL during development)
is a no-op rather than an error.
Events can now be created and updated as online events. Changes:

  * POST /api/events (create.ts): accepts eventType/meetingUrl +
    optional organizerLat/organizerLng. For online events, validates
    the URL, strips placeId/venueDetail, and reverse-geocodes the
    organizer's coords (browser GPS, sent client-side) into a country
    code via the existing reverseGeocodeCountry utility. No coords
    ⇒ country = NULL ⇒ event surfaces only in global feeds.

  * PATCH /api/events/:id (update.ts): handles transitions in both
    directions (in_person ↔ online), clearing the now-irrelevant
    fields on flip. Also re-derives country on any placeId change,
    fixing a pre-existing bug where country went stale.

  * ICS feed (events/ics.ts + the two projection controllers):
    LOCATION uses meetingUrl for online events, physical-location
    text for in-person. Calendar apps render the URL as free text
    that joiners can copy.

  * GET /api/events/:id (detail.ts) + useEventDetail EventData type:
    include eventType and meetingUrl so the UI can render them.

Coords are consumed only by reverseGeocodeCountry and then
discarded — never persisted anywhere. Only the resolved country
ends up in the DB.
WhereCard now leads with a segmented In-person | Online toggle:

  * In-person (default) — the existing PlacePicker + venueDetail
    stay exactly as they were.
  * Online — hides the picker, shows a single Meeting URL input
    plus a small helper hint (Zoom / Meet / Discord / etc.).

When the user toggles to online, WhereCard silently calls
navigator.geolocation.getCurrentPosition **only if** the browser
already reports permission state "granted" — we never trigger a
fresh permission prompt from inside the event form. Organizers who
have visited /places will have almost certainly granted it.
Coords are plumbed up to the form state but only to be submitted
(server reverse-geocodes to a country code and discards them).

The dashboard edit page now reuses <WhereCard> instead of inline
<PlacePicker>, so the form shape is identical between create and
edit — including the online/in-person transition flow.
When event.eventType === "online", show a dedicated "Online event"
block with the meeting URL as a new-tab link, in the same visual
slot as the physical-location card for in-person events.

The existing location/map block now renders only for non-online
events (it was already guarded on placeLatitude/placeLongitude
being non-null, so no regression — just a clearer condition).
@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@malkoG has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 30 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 30 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 95fbb2ff-33ef-4f0d-a401-349e74c1bcb7

📥 Commits

Reviewing files that changed from the base of the PR and between 61c6963 and a7a224a.

📒 Files selected for processing (15)
  • drizzle/0048_wonderful_nehzno.sql
  • drizzle/meta/0048_snapshot.json
  • drizzle/meta/_journal.json
  • src/components/event-form/WhereCard.tsx
  • src/hooks/useEventDetail.ts
  • src/routes/events/$eventId/dashboard/edit.tsx
  • src/routes/events/$eventId/index.tsx
  • src/routes/events/create.tsx
  • src/server/controllers/events/create.ts
  • src/server/controllers/events/detail.ts
  • src/server/controllers/events/ics.ts
  • src/server/controllers/events/personal-ics.ts
  • src/server/controllers/events/update.ts
  • src/server/db/schema.ts
  • src/server/events/ics.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/online-events

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@malkoG malkoG merged commit 57dfda6 into dev Apr 17, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant