'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 */ onToggleOutdoor?: () => void; } // c3nav event URLs const C3NAV_EVENTS: Record = { '39c3': 'https://39c3.c3nav.de', '38c3': 'https://38c3.c3nav.de', '37c3': 'https://37c3.c3nav.de', 'eh2025': 'https://eh2025.c3nav.de', 'eh22': 'https://eh22.c3nav.de', 'camp2023': 'https://camp2023.c3nav.de', }; 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]); return (
{/* c3nav iframe */}