initial: standalone repo from monorepo split
This commit is contained in:
81
src/components/maps/location-picker-modal.tsx
Normal file
81
src/components/maps/location-picker-modal.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { FormModal } from '@/components/ui/form-modal';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { LeafletMap } from './leaflet-map';
|
||||
|
||||
interface LocationPickerModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: (latitude: number, longitude: number) => void;
|
||||
title?: string;
|
||||
description?: string;
|
||||
initialLatitude?: number | null;
|
||||
initialLongitude?: number | null;
|
||||
}
|
||||
|
||||
export function LocationPickerModal({
|
||||
open,
|
||||
onClose,
|
||||
onConfirm,
|
||||
title = 'Pin Client Location',
|
||||
description = 'Click on the map to pin the client location, or use your current location.',
|
||||
initialLatitude,
|
||||
initialLongitude,
|
||||
}: LocationPickerModalProps) {
|
||||
const [latitude, setLatitude] = useState<number | null>(initialLatitude ?? null);
|
||||
const [longitude, setLongitude] = useState<number | null>(initialLongitude ?? null);
|
||||
|
||||
// Reset when modal opens
|
||||
const isOpen = open;
|
||||
if (isOpen && latitude === null && initialLatitude != null) {
|
||||
setLatitude(initialLatitude);
|
||||
setLongitude(initialLongitude ?? null);
|
||||
}
|
||||
|
||||
function handleSelect(lat: number, lng: number) {
|
||||
setLatitude(lat);
|
||||
setLongitude(lng);
|
||||
}
|
||||
|
||||
function handleConfirm() {
|
||||
if (latitude !== null && longitude !== null) {
|
||||
onConfirm(latitude, longitude);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FormModal open={open} onClose={onClose} title={title} description={description} wide>
|
||||
<div className="space-y-4">
|
||||
<LeafletMap
|
||||
latitude={latitude}
|
||||
longitude={longitude}
|
||||
height="350px"
|
||||
interactive
|
||||
onLocationSelect={handleSelect}
|
||||
/>
|
||||
|
||||
{latitude !== null && longitude !== null ? (
|
||||
<div className="flex items-center justify-between rounded-lg bg-surface-50 px-4 py-3">
|
||||
<span className="text-sm text-surface-600">
|
||||
<span className="font-medium text-surface-800">Lat:</span> {latitude.toFixed(6)},{' '}
|
||||
<span className="font-medium text-surface-800">Lng:</span> {longitude.toFixed(6)}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-surface-400 text-center py-2">
|
||||
Click on the map to pin the location
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end gap-3 pt-2">
|
||||
<Button variant="secondary" onClick={onClose}>Cancel</Button>
|
||||
<Button onClick={handleConfirm} disabled={latitude === null || longitude === null}>
|
||||
Confirm Location
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</FormModal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user