Skip to content

feat(globe): marker details + live filters + virtual panel (#17, #18)#145

Open
Jose-Gael-Cruz-Lopez wants to merge 3 commits into
mainfrom
feat/globe-browsing-17-18
Open

feat(globe): marker details + live filters + virtual panel (#17, #18)#145
Jose-Gael-Cruz-Lopez wants to merge 3 commits into
mainfrom
feat/globe-browsing-17-18

Conversation

@Jose-Gael-Cruz-Lopez

Copy link
Copy Markdown
Collaborator

Closes #17
Closes #18

Both issues were written against react-globe.gl and Supabase, neither of which exists — the globe is Mapbox and the data comes from listings.json. This delivers what they actually asked for, on the stack we have.

#17 — Marker interactions

Clicking a marker used to fly the camera and open nothing. The detail card existed, but it's a centered modal, and opening it on marker click would cover the very map you just zoomed into — so it was wired to the deck only.

Now a marker click flies the camera and opens a docked sheet: beside the map on desktop, rising from the bottom on mobile. The pin stays visible next to its own details.

  • Hover tooltip: name + city (also on focus, so keyboard users get it too)
  • Click opens details with host / title / format / prize / deadline + REGISTER (open) or VISIT WEBSITE (opens_soon)
  • Escape and a click on empty globe both deselect
  • Keyboard accessible — markers are real <button>s with accessible names, and focus moves into the sheet when it opens
  • Flies/zooms the globe to the selected point

Bonus: SAVE TO MY HQ, so a hackathon found on the globe goes straight into the tracker.

#18 — Search, filters, and the off-map panel

The filter logic is now one shared module (lib/filters.ts), used by the deck and the globe. A second copy would drift: a theme added to one surface's search and not the other's is a hackathon you can find in the deck and not on the globe, with nothing to tell you they disagree.

Three defects my own test caught while building this

Recording them because each was a real bug, not a polish item:

  1. Picking a virtual event from the off-map panel opened nothing. The selection guard checked membership in onMap — and an online hackathon is never on the map. So the panel that exists to make virtual events reachable selected one and immediately discarded it. That is the entire point of Frontend: Search, filters, and Virtual/Online side panel #18, and it was broken.
  2. BACK TO GLOBE sat exactly where the sheet lands (top-6 right-6). The sheet now starts below it on desktop; on mobile the controls run full width, so the button hides while the sheet is open.
  3. The sheet was translucent (glass-dark, 0.55 alpha) and the map and page title read straight through the hackathon's own details. Added a glass-sheet surface.

Verification

Driven with Playwright at 1280px and 375px:

markers on load: 42            marker is a real <button>: yes
search "boston" -> markers: 1  after CLEAR -> markers: 42
filter VIRTUAL -> markers: 0   (online events can never have a pin)
off-map panel: "🌐 19 not on the map · 19 online"  -> 19 entries
sheet opens from the virtual list: true
marker keyboard-focusable: true -> Enter opens the sheet
sheet docked at x=896 of 1280  (map still visible to its left)
focus moves into the sheet: "Close details"
Escape dismisses: true
page errors: none
horizontal overflow: none at 1280px or 375px

npm run test (87 pass, incl. 7 new filter tests), npm run build, npx tsc --noEmit, npm run lint all clean.

The globe needs exactly the rules the deck already has (#18). A second copy
would drift - a theme added to one surface's search and not the other's is a
hackathon a visitor can find in the deck and not on the globe, with nothing to
say the two disagree.

splitByMappability() is the answer to 'online events have no location': a
Virtual hackathon can never have a pin, so filtering the globe would erase it
from the page entirely unless something lists it. It also catches an in-person
event we failed to geocode, so the globe still never drops a listing silently
(#111).
Same rules, one implementation. The deck keeps its own UI; only the matching
logic moves out, so the globe can reuse it without a second copy.
#17 - clicking a marker now flies the camera AND opens the details, in a sheet
docked beside the map (bottom sheet on mobile) rather than the deck's centered
modal, which would cover the very map you just zoomed into. That was the reason
marker-click opened nothing before. Markers are real <button>s with accessible
names, so the whole flow works from the keyboard; Escape and a click on the
globe both dismiss.

#18 - search and status/format filters over the globe, adding and removing
markers live, sharing lib/filters.ts with the deck so the two surfaces cannot
disagree about what a search means. The off-map panel lists everything the
globe cannot pin - online events, which never had a marker to lose, and
anything we failed to geocode - and each one opens the same sheet.

Three defects my own test caught while building this:

- Picking a virtual event from the off-map list opened nothing. The selection
  guard checked membership in onMap, and an online hackathon is never on the
  map, so the panel that exists to make virtual events reachable discarded the
  selection it had just made.
- BACK TO GLOBE sat at top-6 right-6, exactly where the sheet lands. Moved the
  sheet below it on desktop; on mobile the controls run full width, so the
  button hides while the sheet is open.
- The sheet used glass-dark (0.55 alpha) and the map and page title read
  straight through the hackathon's own details. Added glass-sheet.
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.

Frontend: Search, filters, and Virtual/Online side panel Frontend: Marker interactions — tooltip + detail card

1 participant