Skip to content

Commit

Permalink
feat: movido a componentes reutilizables y a ts
Browse files Browse the repository at this point in the history
  • Loading branch information
Roberto Milla Martinez committed Nov 6, 2024
1 parent 0a87c8c commit 7436b89
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 64 deletions.
60 changes: 4 additions & 56 deletions src/app/trying/page.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,11 @@
'use client';

import { useState } from 'react';

// @ts-expect-error
import GeoLocationMap from '@/components/map/geolocationMap';
import AddressMap, { AddressAndTown } from '@/components/AddressMap';

export default function TryingPage() {
const [address, setAddress] = useState('');
const [town, setTown] = useState('');

const onNewPosition = async ([lon, lat]: [string, string]) => {
if (address !== '') {
return;
}

const response = await fetch('/api/address', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
longitude: lon,
latitude: lat,
}),
}).then((res) => res.json());

setAddress(response.address);
setTown(response.town);
const onNewAddress = (addressAndTown: AddressAndTown) => {
console.log(addressAndTown);
};

return (
<>
<GeoLocationMap onNewPositionCallback={onNewPosition} />
<div className="bg-white rounded-lg p-6 w-full relative flex flex-col gap-6 mt-7">
<div className="space-y-6 max-h-[65vh] overflow-y-auto p-2">
{/* Town */}
<div className="grid gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Town</label>
<input
type="text"
value={town}
onChange={(e) => setTown(e.target.value)}
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
</div>
</div>
{/* Address */}
<div className="grid gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Address</label>
<input
type="text"
value={address}
onChange={(e) => setAddress(e.target.value)}
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
</div>
</div>
</div>
</div>
</>
);
return <AddressMap onNewAddressCallback={onNewAddress} />;
}
72 changes: 72 additions & 0 deletions src/components/AddressMap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import GeoLocationMap, { LngLat } from '@/components/map/GeolocationMap';
import { useState } from 'react';

export type AddressAndTown = { address: string; town: string };
export type AddressAndTownCallback = (addressAndTown: AddressAndTown) => void;
export type AddressMapProps = {
onNewAddressCallback: AddressAndTownCallback;
};

export default function AddressMap({ onNewAddressCallback }: AddressMapProps) {
const [address, setAddress] = useState('');
const [town, setTown] = useState('');

const onNewPosition = async (lngLat: LngLat) => {
if (address !== '') {
return;
}

const response = await fetch('/api/address', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
longitude: lngLat.lng,
latitude: lngLat.lat,
}),
}).then((res) => res.json());

setAddress(response.address);
setTown(response.town);
if (typeof onNewAddressCallback === 'function') {
onNewAddressCallback({ address: response.address, town: response.town });
}
};

return (
<>
<GeoLocationMap onNewPositionCallback={onNewPosition} />
<div className="bg-white rounded-lg p-6 w-full relative flex flex-col gap-6 mt-7">
<div className="space-y-6 max-h-[65vh] overflow-y-auto p-2">
{/* Town */}
<div className="grid gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Town</label>
<input
disabled
type="text"
value={town}
onChange={(e) => setTown(e.target.value)}
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
</div>
</div>
{/* Address */}
<div className="grid gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Address</label>
<input
disabled
type="text"
value={address}
onChange={(e) => setAddress(e.target.value)}
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
</div>
</div>
</div>
</div>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ const urgencyToColor = {
baja: '#10b981', //text-emerald-500
};

const PAIPORTA_LAT_LNG = [-0.41667, 39.42333];
const PAIPORTA_LAT_LNG: [number, number] = [-0.41667, 39.42333];

export default function GeoLocationMap({ onNewPositionCallback, zoom = 13 }) {
const mapContainerRef = useRef(null);
const mapRef = useRef(null);
export type LngLat = { lng: number; lat: number };

export type GeoLocationMapProps = {
onNewPositionCallback: (lngLat: LngLat) => void;
zoom?: number;
};

export default function GeoLocationMap({ onNewPositionCallback, zoom = 13 }: GeoLocationMapProps) {
const mapContainerRef = useRef<HTMLDivElement | null>(null);
const mapRef = useRef<maplibregl.Map | null>(null);

// geolocate control
const geolocateControl = new maplibregl.GeolocateControl({
Expand All @@ -21,11 +28,14 @@ export default function GeoLocationMap({ onNewPositionCallback, zoom = 13 }) {
},
trackUserLocation: true,
showAccuracyCircle: true,
showUserHeading: true,
});

useEffect(() => {
if (!mapRef.current) {
if (!mapContainerRef.current) {
return;
}

mapRef.current = new maplibregl.Map({
container: mapContainerRef.current,
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
Expand All @@ -34,20 +44,31 @@ export default function GeoLocationMap({ onNewPositionCallback, zoom = 13 }) {
});

mapRef.current.on('moveend', () => {
if (!mapRef.current) {
return;
}

const center = mapRef.current.getCenter();
if (typeof onNewPositionCallback === 'function') {
onNewPositionCallback([center.lng, center.lat]);
onNewPositionCallback(center);
}
});

mapRef.current.on('move', () => {
if (!mapRef.current) {
return;
}

const center = mapRef.current.getCenter();
marker.setLngLat(center);
});

geolocateControl.on('geolocate', (e) => {
const userLocation = [e.coords.longitude, e.coords.latitude];
if (!mapRef.current) {
return;
}

const userLocation: [number, number] = [e.coords.longitude, e.coords.latitude];
// Center the map on the user's location
mapRef.current.flyTo({
center: userLocation,
Expand All @@ -56,7 +77,7 @@ export default function GeoLocationMap({ onNewPositionCallback, zoom = 13 }) {
});

if (typeof onNewPositionCallback === 'function') {
onNewPositionCallback(userLocation);
onNewPositionCallback({ lng: userLocation[0], lat: userLocation[1] });
}
});

Expand Down

0 comments on commit 7436b89

Please sign in to comment.