diff --git a/src/app/[slug]/page.tsx b/src/app/[slug]/page.tsx index d5f60ec..765d6e7 100644 --- a/src/app/[slug]/page.tsx +++ b/src/app/[slug]/page.tsx @@ -13,6 +13,7 @@ import ShareModal from '@/components/room/ShareModal'; import MeetingPointModal from '@/components/room/MeetingPointModal'; import WaypointModal from '@/components/room/WaypointModal'; import InstallBanner from '@/components/room/InstallBanner'; +import JoinForm from '@/components/room/JoinForm'; import type { Participant, ParticipantLocation, Waypoint } from '@/types'; // Dynamic import for map to avoid SSR issues with MapLibre @@ -38,24 +39,31 @@ export default function RoomPage() { const [selectedWaypoint, setSelectedWaypoint] = useState(null); const [shouldAutoStartSharing, setShouldAutoStartSharing] = useState(false); const [zoomToLocation, setZoomToLocation] = useState<{ latitude: number; longitude: number } | null>(null); + const [needsJoin, setNeedsJoin] = useState(false); // Load user and sharing preference from localStorage useEffect(() => { const stored = localStorage.getItem('rmaps_user'); if (stored) { setCurrentUser(JSON.parse(stored)); + // Check if user had location sharing enabled for this room + const sharingPref = localStorage.getItem(`rmaps_sharing_${slug}`); + if (sharingPref === 'true') { + setShouldAutoStartSharing(true); + } } else { - // Redirect to home if no user info - router.push('/'); - return; + // Show join form instead of redirecting + setNeedsJoin(true); } + }, [slug]); - // Check if user had location sharing enabled for this room - const sharingPref = localStorage.getItem(`rmaps_sharing_${slug}`); - if (sharingPref === 'true') { - setShouldAutoStartSharing(true); - } - }, [router, slug]); + // Handle joining from the inline form + const handleJoin = (name: string, emoji: string) => { + const user = { name, emoji }; + localStorage.setItem('rmaps_user', JSON.stringify(user)); + setCurrentUser(user); + setNeedsJoin(false); + }; // Room hook (only initialize when we have user info) const { @@ -276,6 +284,11 @@ export default function RoomPage() { setShowParticipants(false); // Close participant list to show map }; + // Show join form if user hasn't entered their name yet + if (needsJoin) { + return ; + } + // Loading state if (!currentUser || isLoading) { return ( diff --git a/src/components/map/C3NavEmbed.tsx b/src/components/map/C3NavEmbed.tsx index 23e9856..e723117 100644 --- a/src/components/map/C3NavEmbed.tsx +++ b/src/components/map/C3NavEmbed.tsx @@ -1,19 +1,14 @@ 'use client'; -import { useState, useEffect, useRef } from 'react'; import type { Participant } from '@/types'; interface C3NavEmbedProps { /** Event identifier (e.g., '39c3', 'eh2025') */ eventId?: string; - /** Initial location to show */ - initialLocation?: string; /** Participants to show on the map overlay */ participants?: Participant[]; /** Current user ID */ currentUserId?: string; - /** Callback when user taps a location */ - onLocationSelect?: (location: { slug: string; name: string }) => void; /** Show the indoor/outdoor toggle */ showToggle?: boolean; /** Callback when toggling to outdoor mode */ @@ -32,105 +27,37 @@ const C3NAV_EVENTS: Record = { export default function C3NavEmbed({ eventId = '39c3', - initialLocation, participants = [], currentUserId, - onLocationSelect, showToggle = true, onToggleOutdoor, }: C3NavEmbedProps) { - const iframeRef = useRef(null); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); - // Get the c3nav base URL for the event const baseUrl = C3NAV_EVENTS[eventId] || C3NAV_EVENTS['39c3']; - // Build the embed URL - const embedUrl = new URL(baseUrl); - embedUrl.searchParams.set('embed', '1'); - if (initialLocation) { - embedUrl.searchParams.set('o', initialLocation); - } - - // Handle iframe load - const handleLoad = () => { - setIsLoading(false); - setError(null); - }; - - // Handle iframe error - const handleError = () => { - setIsLoading(false); - setError('Failed to load indoor map'); - }; - - // Listen for messages from c3nav iframe - useEffect(() => { - const handleMessage = (event: MessageEvent) => { - // Only accept messages from c3nav - if (!event.origin.includes('c3nav.de')) return; - - try { - const data = event.data; - if (data.type === 'c3nav:location' && onLocationSelect) { - onLocationSelect({ - slug: data.slug, - name: data.name, - }); - } - } catch (e) { - // Ignore invalid messages - } - }; - - window.addEventListener('message', handleMessage); - return () => window.removeEventListener('message', handleMessage); - }, [onLocationSelect]); - + // c3nav blocks iframes, so show fallback UI with link to open in new tab return ( -
- {/* c3nav iframe */} -