import { IconLayer, ScatterplotLayer } 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 [userLocation, setUserLocation] = useState<{ [key: string]: number }>( {} ); const [source, setSource] = useState([]); const [layers, setLayers] = useState([]); const [isAddLoveOpened, setIsAddLoveOpened] = useState(false); const [isLoading, setIsLoading] = useState(false); const [addLoveMessage, setAddLoveMessage] = useState(null); const [viewState, setViewState] = useState({ 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, zoom: 13, })); setUserLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude, }); }, (error) => { if (error.PERMISSION_DENIED) { setGeoError('permission_denied'); console.warn(error.message); } }, { maximumAge: 0, timeout: 5000, enableHighAccuracy: true, } ); (async () => { const dataset = await getDataset(); setSource(dataset); })(); }, []); useEffect(() => { const newLayers = []; if (userLocation) { const userLayer = new ScatterplotLayer({ id: 'userLayer', data: [userLocation], stroked: true, getPosition: (d) => [d.longitude, d.latitude], getRadius: 10, getFillColor: [217, 66, 83], getLineColor: [217, 66, 83, 175], getLineWidth: 5, radiusUnits: 'pixels', lineWidthUnits: 'pixels', pickable: false, }); newLayers.push(userLayer); } const datasetLayer = new IconLayer({ id: 'lovePoints', data: source, 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, }); newLayers.push(datasetLayer); setLayers(newLayers); }, [userLocation, source, isAddLoveOpened]); 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 []; };