Add & display loves on map

This commit is contained in:
2024-10-01 19:33:44 +02:00
parent f2d1eb4289
commit bf42f5c49b
11 changed files with 765 additions and 74 deletions
+75
View File
@@ -0,0 +1,75 @@
import { FormEvent } from 'react';
export const useActions = ({
viewState,
setIsAddLoveOpened,
setIsLoading,
setAddLoveMessage,
}) => {
const toggleLoveMenu = () => {
setIsAddLoveOpened((prev) => !prev);
};
const addPoint = async (ev: FormEvent<HTMLFormElement>) => {
ev.preventDefault();
if (!ev.currentTarget.reportValidity()) {
return;
}
setIsLoading(true);
const formData = new FormData(ev.currentTarget);
const location = formData.get('location');
const comment = formData.get('comment');
const body: { [key: string]: any } = {
location: location.toString(),
};
if (comment && comment.toString().length > 0) {
body.comment = comment.toString();
}
const token = localStorage.getItem('token');
const { latitude, longitude } = viewState;
const point = {
type: 'Point',
coordinates: [longitude, latitude],
};
body.geopoint = point;
try {
const request = await fetch('/api/point', {
method: 'POST',
headers: {
Authorization: token,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (request.status == 403) {
setIsLoading(false);
setAddLoveMessage('Reconnectez-vous pour réessayer');
return;
}
if (request.status == 400) {
setIsLoading(false);
setAddLoveMessage('Erreur interne. Veuillez réessayer');
return;
}
setIsLoading(false);
} catch (error) {
console.error(error);
setAddLoveMessage('Erreur interne. Veuillez réessayer');
setIsLoading(false);
}
};
return { toggleLoveMenu, addPoint };
};
-43
View File
@@ -1,43 +0,0 @@
import { useEffect, useState } from 'react';
export const useData = () => {
const [canUseGeolocation, setCanUseGeolocation] = useState(false);
const [geoError, setGeoError] = useState(null);
const [initialState, setInitialState] = useState({
longitude: 2.209666999999996,
latitude: 46.232192999999995,
zoom: 5,
});
useEffect(() => {
if ('geolocation' in navigator == false) {
setCanUseGeolocation(false);
return;
}
setCanUseGeolocation(true);
navigator.geolocation.getCurrentPosition(
position => {
setInitialState(prev => ({
...prev,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}));
},
error => {
if (error.PERMISSION_DENIED) {
setGeoError('permission_denied');
console.warn(error.message);
}
}
);
}, []);
return {
initialState,
geoError,
canUseGeolocation,
};
};
+119
View File
@@ -0,0 +1,119 @@
import { IconLayer } from 'deck.gl';
import { useEffect, useRef, useState } from 'react';
import { StringifiedPinIcon } from '@/assets/PinIcon';
export const useData = () => {
const deckRef = useRef(null);
const [canUseGeolocation, setCanUseGeolocation] = useState(false);
const [geoError, setGeoError] = useState(null);
const [layers, setLayers] = useState([]);
const [isAddLoveOpened, setIsAddLoveOpened] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [addLoveMessage, setAddLoveMessage] = useState(null);
const [viewState, setViewState] = useState<any>({
longitude: 2.209666999999996,
latitude: 46.232192999999995,
zoom: 5,
});
useEffect(() => {
if ('geolocation' in navigator == false) {
setCanUseGeolocation(false);
return;
}
setCanUseGeolocation(true);
navigator.geolocation.getCurrentPosition(
(position) => {
setViewState((prev) => ({
...prev,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}));
},
(error) => {
if (error.PERMISSION_DENIED) {
setGeoError('permission_denied');
console.warn(error.message);
}
}
);
(async () => {
const dataset = await getDataset();
const datasetLayer = new IconLayer({
id: 'lovePoints',
data: dataset,
iconAtlas: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(
StringifiedPinIcon()
)}`,
iconMapping: {
marker: {
x: 0,
y: 0,
width: 100,
height: 100,
anchorY: 100,
},
},
getIcon: (d) => 'marker',
getSize: (d) => 35,
getPosition: (d) => d.geometry.coordinates,
billboard: true,
pickable: true,
});
setLayers([datasetLayer]);
})();
}, []);
return {
deckRef,
viewState,
setViewState,
geoError,
layers,
canUseGeolocation,
isAddLoveOpened,
setIsAddLoveOpened,
isLoading,
setIsLoading,
addLoveMessage,
setAddLoveMessage,
};
};
const getDataset = async () => {
const token = localStorage.getItem('token');
const request = await fetch('/api/point', {
method: 'GET',
headers: {
Authorization: token,
},
});
const response = await request.json();
if (response) {
const formattedData = response.map((point) => {
const properties = { ...point };
delete properties.geopoint;
return {
type: 'Feature',
geometry: point.geopoint,
properties: properties,
};
});
return formattedData;
}
return [];
};