diff --git a/traque-front/app/team/track/page.js b/traque-front/app/team/track/page.js index eeb12d4..7df6a01 100644 --- a/traque-front/app/team/track/page.js +++ b/traque-front/app/team/track/page.js @@ -3,7 +3,7 @@ import ActionDrawer from '@/components/team/actionDrawer'; import { useTeamConnexion } from '@/context/teamConnexionContext'; import useGame from '@/hook/useGame'; import dynamic from 'next/dynamic'; -import React, { use } from 'react' +import React from 'react' //Load the map without SSR const LiveMap = dynamic(() => import('@/components/team/map'), { diff --git a/traque-front/components/admin/mapPicker.jsx b/traque-front/components/admin/mapPicker.jsx new file mode 100644 index 0000000..fc6fa37 --- /dev/null +++ b/traque-front/components/admin/mapPicker.jsx @@ -0,0 +1,70 @@ +"use client"; +import { useLocation } from "@/hook/useLocation"; +import { use, useEffect, useState } from "react"; +import "leaflet/dist/leaflet.css"; +import { Circle, MapContainer, TileLayer, useMap } from "react-leaflet"; + +function MapPan(props) { + const map = useMap(); + const [initialized, setInitialized] = useState(false); + + useEffect(() => { + if (!initialized && props.center) { + map.flyTo(props.center, props.zoom, { animate: false }); + setInitialized(true) + } + }, [props.center]); + return null; +} + +function MapEventListener({onClick, onMouseMove}) { + const map = useMap(); + useEffect(() => { + map.on('click', onClick); + return () => { + map.off('click', onClick); + } + }, [onClick]); + useEffect(() => { + map.on('mousemove', onMouseMove); + return () => { + map.off('mousemove', onMouseMove); + } + }); + return null; +} + +export function CircularAreaPicker({area, setArea, ...props}) { + const DEFAULT_ZOOM = 17; + const location = useLocation(Infinity); + const [drawing, setDrawing] = useState(false); + const [center, setCenter] = useState(area?.center || null); + const [radius, setRadius] = useState(area?.radius || null); + + function handleClick(e) { + if(!drawing) { + setCenter(e.latlng); + setRadius(null); + setDrawing(true); + } else { + setDrawing(false); + setArea({center, radius}); + } + } + + function handleMouseMove(e) { + if(drawing) { + setRadius(e.latlng.distanceTo(center)); + } + } + return ( + + + {center && radius && } + + + ) +} \ No newline at end of file diff --git a/traque-front/components/admin/teamEdit.jsx b/traque-front/components/admin/teamEdit.jsx index fdc6d2c..8d6eaa8 100644 --- a/traque-front/components/admin/teamEdit.jsx +++ b/traque-front/components/admin/teamEdit.jsx @@ -2,10 +2,15 @@ import React, { useEffect, useState } from 'react' import TextInput from '../util/textInput' import Button from '../util/button'; import useAdmin from '@/hook/useAdmin'; +import dynamic from 'next/dynamic'; -export default function TeamEdit({selectedTeamId, setSelectedTeamId}) { +const CircularAreaPicker = dynamic(() => import('./mapPicker').then((mod) => mod.CircularAreaPicker), { + ssr: false +}); + +export default function TeamEdit({ selectedTeamId, setSelectedTeamId }) { const [newTeamName, setNewTeamName] = React.useState(''); - const {setTeamName, getTeamName, removeTeam, getTeam} = useAdmin(); + const { setTeamName, getTeamName, removeTeam, getTeam } = useAdmin(); const [team, setTeam] = useState({}) useEffect(() => { @@ -13,9 +18,9 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) { if (team != undefined) { setNewTeamName(team.name); } - },[selectedTeamId]) + }, [selectedTeamId]) + - useEffect(() => { let team = getTeam(selectedTeamId); if (team != undefined) { @@ -34,30 +39,37 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) { setSelectedTeamId(null); } - return (team && -
-
-

Actions

-
-
- setNewTeamName(e.target.value)}/> + return (team && +
+ +
+
+

Actions

+ +
+ setNewTeamName(e.target.value)} /> +
+
+ +
+ +
-
- +
+

Team details

+
+

Secret : {String(team.id).padStart(6, '0')}

+

Name : {team.name}

+

Chasing : {getTeamName(team.chasing)}

+

Chased by : {getTeamName(team.chased)}

+

Capture code : {String(team.captureCode).padStart(4, '0')}

+
- - -
-
-

Team details

-
-

Secret : {String(team.id).padStart(6,'0')}

-

Name : {team.name}

-

Chasing : {getTeamName(team.chasing)}

-

Chased by : {getTeamName(team.chased)}

-

Capture code : {String(team.captureCode).padStart(4,'0')}

+
+
+

Starting area

+ setTeam({ ...team, startingArea })} />
-
- ) + ) } diff --git a/traque-front/hook/useLocation.jsx b/traque-front/hook/useLocation.jsx index 70e8c17..37d1272 100644 --- a/traque-front/hook/useLocation.jsx +++ b/traque-front/hook/useLocation.jsx @@ -9,9 +9,12 @@ export function useLocation(interval) { const [location, setLocation] = useState(); useEffect(() => { function update() { + console.log('Updating location'); navigator.geolocation.getCurrentPosition((position) => { setLocation([position.coords.latitude, position.coords.longitude]); - setTimeout(update, interval); + if(interval != Infinity) { + setTimeout(update, interval); + } }, () => { }, { enableHighAccuracy: true, timeout: Infinity, maximumAge: 0 }); } update();