import React, { useCallback, useMemo, useState } from 'react'; import { connectionConfig, findShortestPath, generateConnections, PathSegment, rawGraphNodes } from './mapUtils'; const UTMapURL = new URL('/src/assets/UT-Map.png', import.meta.url).href; /** * CampusMap component renders an interactive map of the UT campus. * * The map includes: * - An image of the campus map. * - An SVG overlay to draw paths and nodes. * - Building selection controls to highlight specific paths. */ export default function CampusMap() { const [selectedPath, setSelectedPath] = useState([]); const [startBuilding, setStartBuilding] = useState(''); const [endBuilding, setEndBuilding] = useState(''); const [allowThroughBuildings, setAllowThroughBuildings] = useState(false); const [debugInfo, setDebugInfo] = useState(''); // Generate graph with connections once using useMemo const graphNodes = useMemo(() => generateConnections(rawGraphNodes, connectionConfig), []); // Function to draw path between buildings const drawPathBetweenBuildings = useCallback( (start: string, end: string) => { if (!start || !end || start === end) { setSelectedPath([]); setDebugInfo('No path to draw - invalid start/end'); return; } try { const result = findShortestPath(start, end, graphNodes, allowThroughBuildings); setDebugInfo(`Found path: ${result.path.join(' → ')} (distance: ${result.distance.toFixed(2)})`); setSelectedPath(result.path); } catch (error) { setDebugInfo(`Error finding path: ${error instanceof Error ? error.message : 'Unknown error'}`); setSelectedPath([]); } }, [allowThroughBuildings, graphNodes] ); // Update path when selections change React.useEffect(() => { drawPathBetweenBuildings(startBuilding, endBuilding); }, [startBuilding, endBuilding, allowThroughBuildings, drawPathBetweenBuildings]); return (
{/* Map Image: 784x754 */} UT Campus Map {/* SVG Overlay */} {/* Debug visualization of all connections */} {Object.entries(graphNodes).map(([nodeId, node]) => node.connections.map(connectionId => ( )) )} {/* Draw selected path */} {selectedPath.length > 1 && selectedPath .slice(0, -1) .map((nodeId, index) => ( ))} {/* Draw nodes */} {Object.entries(graphNodes).map(([id, node]) => ( {node.type === 'building' && ( {id} )} ))} {/* Controls */}
setAllowThroughBuildings(e.target.checked)} className='rounded' />
{/* Debug info */} {debugInfo && (
{debugInfo}
)} {selectedPath.length > 0 &&
Path: {selectedPath.join(' → ')}
}
); }