Improve /events UI to display full addresses and populate map links correctly

Resolved 💬 1 comment Opened Oct 26, 2025 by njgerner Closed Oct 26, 2025

Problem

The /events page currently shows separate "Google Maps" and "Apple Maps" buttons, which creates clutter and confusion. Additionally, the map links are generated from a potentially incomplete location string field.

Current Issues:

  1. Redundant buttons: Shows both Google Maps and Apple Maps buttons to all users
  2. Incomplete addresses: The location field may not include the full address
  3. Unreliable map links: Links generated from incomplete address strings may not work correctly

Current Behavior

EventCard shows both map buttons:

{mapLinks && (
  <>
    <a href={mapLinks.google}>Google Maps</a>
    <a href={mapLinks.apple}>Apple Maps</a>
  </>
)}

Proposed Solution

Single "Maps" Button with Device Detection

Replace the two map buttons with a single "Maps" button that automatically opens the appropriate map app based on the user's device:

{mapLinks && (
  <a
    href={isIOS || isMacOS ? mapLinks.apple : mapLinks.google}
    target="_blank"
    rel="noopener noreferrer"
    className="flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors font-medium text-gray-700"
  >
    <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={2}
        d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
      />
    </svg>
    View on Maps
  </a>
)}

Device Detection Utility

function useMapProvider() {
  const [provider, setProvider] = useState<'apple' | 'google'>('google');
  
  useEffect(() => {
    const userAgent = navigator.userAgent.toLowerCase();
    const isAppleDevice = 
      /iphone|ipad|ipod|macintosh/.test(userAgent) ||
      (navigator.platform && /mac/i.test(navigator.platform));
    
    setProvider(isAppleDevice ? 'apple' : 'google');
  }, []);
  
  return provider;
}

Optional: Enhance with Full Address Support

If needed, also add structured location fields to the Event model for better address handling:

model Event {
  id              String    @id @default(cuid())
  name            String
  start           DateTime
  end             DateTime
  
  // Enhanced location (optional enhancement)
  location        String    // Keep for backward compatibility
  locationName    String?   // e.g., "The Grand Ballroom"
  address         String?   // Full street address
  city            String?
  state           String?
  zip             String?
  latitude        Float?    // For precise map links
  longitude       Float?
}

Benefits

  • Cleaner UI: Single "Maps" button instead of two
  • Better UX: Automatically uses the right app for each device
  • Less clutter: Simplified button row on event cards
  • Smart defaults: iOS/Mac users get Apple Maps, others get Google Maps
  • Works immediately: No need for database changes (optional enhancement)

Implementation Notes

Files to Update

  • src/components/public/EventCard.tsx - Replace dual buttons with single Maps button
  • src/lib/device-detect.ts (new) - Device detection utility
  • Optional: prisma/schema.prisma - Add structured location fields for better addresses
  • Optional: src/app/admin/events/[id]/edit/page.tsx - Add address input fields

Device Detection Logic

  • Apple Maps: iOS (iPhone, iPad, iPod) and macOS
  • Google Maps: Android, Windows, Linux, and other platforms

Acceptance Criteria

  • [ ] Single "Maps" button replaces Google Maps and Apple Maps buttons
  • [ ] Button automatically links to Apple Maps on iOS/macOS devices
  • [ ] Button automatically links to Google Maps on all other devices
  • [ ] Map links open correctly when clicked
  • [ ] Button styling matches existing design system
  • [ ] Works on all major browsers (Chrome, Safari, Firefox, Edge)
  • [ ] Optional: Support for full addresses if location data is incomplete

Related

Current implementation:

  • src/components/public/EventCard.tsx:113-148 - Dual map buttons
  • src/lib/maps.ts:51 - getMapLinks function

---

Priority: Low
Complexity: Low
Type: Enhancement

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗