diff --git a/app/components/Map.tsx b/app/components/Map.tsx new file mode 100644 index 0000000..9b2b78d --- /dev/null +++ b/app/components/Map.tsx @@ -0,0 +1,117 @@ +import { useAtomValue, useAtom } from 'jotai' +import 'maplibre-gl/dist/maplibre-gl.css' +import { Map as MapGL } from 'react-map-gl/maplibre' +import { enableEditingAtom, mapStyleAtom, viewStateAtom } from '~/lib/mapStore' +import DrawControl from './drawControl' +import { TerminalsLayer } from './TerminalsLayer' +import { Popup } from 'react-map-gl/maplibre' +import { drawnFeaturesAtom } from '~/lib/mapStore' +import { useState, useEffect } from 'react' +import { useClient } from 'urql' +import { createTerminal } from '~/lib/graphql/mutations' +import centroid from '@turf/centroid' + +export function Map() { + const mapStyle = useAtomValue(mapStyleAtom) + const viewState = useAtomValue(viewStateAtom) + const enableEditing = useAtomValue(enableEditingAtom) + const [drawnFeatures] = useAtom(drawnFeaturesAtom) + const [, setDrawnFeatures] = useAtom(drawnFeaturesAtom) + + const [terminalName, setTerminalName] = useState('') + const [isSubmitting, setIsSubmitting] = useState(false) + const client = useClient() + + const center = drawnFeatures ? centroid(drawnFeatures[0]?.geometry) : null + + const handleCreate = async () => { + if (!terminalName.trim() || !drawnFeatures?.[0] || isSubmitting) return + + setIsSubmitting(true) + try { + const feature = drawnFeatures[0] + const centerPoint = centroid(feature.geometry) + + await client.mutation(createTerminal, { + name: terminalName.trim(), + longitude: centerPoint.geometry.coordinates[0], + latitude: centerPoint.geometry.coordinates[1], + geometry: feature.geometry + }).toPromise() + + // Clear the drawn features and form after successful creation + setDrawnFeatures(null) + setTerminalName('') + } catch (error) { + console.error('Failed to create terminal:', error) + } finally { + setIsSubmitting(false) + } + } + + const handleCancel = () => { + setDrawnFeatures(null) + setTerminalName('') + } + + // Reset form when drawn features change + useEffect(() => { + if (!drawnFeatures) { + setTerminalName('') + } + }, [drawnFeatures]) + + return ( + + {enableEditing ? : null} + + {drawnFeatures && center ? ( + +
+ + setTerminalName(e.target.value)} + placeholder='Enter terminal name' + className='w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent mb-3' + disabled={isSubmitting} + autoFocus + onKeyDown={(e) => { + if (e.key === 'Enter' && terminalName.trim()) { + handleCreate() + } else if (e.key === 'Escape') { + handleCancel() + } + }} + /> +
+ + +
+
+
+ ) : null} +
+ ) +} \ No newline at end of file