mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-02-09 10:20:16 +01:00
starting zone element done
This commit is contained in:
@@ -3,7 +3,7 @@ import ActionDrawer from '@/components/team/actionDrawer';
|
|||||||
import { useTeamConnexion } from '@/context/teamConnexionContext';
|
import { useTeamConnexion } from '@/context/teamConnexionContext';
|
||||||
import useGame from '@/hook/useGame';
|
import useGame from '@/hook/useGame';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import React, { use } from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
//Load the map without SSR
|
//Load the map without SSR
|
||||||
const LiveMap = dynamic(() => import('@/components/team/map'), {
|
const LiveMap = dynamic(() => import('@/components/team/map'), {
|
||||||
|
|||||||
70
traque-front/components/admin/mapPicker.jsx
Normal file
70
traque-front/components/admin/mapPicker.jsx
Normal file
@@ -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 (
|
||||||
|
<MapContainer {...props} className='min-h-full w-full ' center={[0, 0]} zoom={0} scrollWheelZoom={true}>
|
||||||
|
<TileLayer
|
||||||
|
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
|
/>
|
||||||
|
{center && radius && <Circle center={center} radius={radius} fillColor="blue"/>}
|
||||||
|
<MapPan center={location} zoom={DEFAULT_ZOOM} />
|
||||||
|
<MapEventListener onClick={handleClick} onMouseMove={handleMouseMove} />
|
||||||
|
</MapContainer>)
|
||||||
|
}
|
||||||
@@ -2,10 +2,15 @@ import React, { useEffect, useState } from 'react'
|
|||||||
import TextInput from '../util/textInput'
|
import TextInput from '../util/textInput'
|
||||||
import Button from '../util/button';
|
import Button from '../util/button';
|
||||||
import useAdmin from '@/hook/useAdmin';
|
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 [newTeamName, setNewTeamName] = React.useState('');
|
||||||
const {setTeamName, getTeamName, removeTeam, getTeam} = useAdmin();
|
const { setTeamName, getTeamName, removeTeam, getTeam } = useAdmin();
|
||||||
const [team, setTeam] = useState({})
|
const [team, setTeam] = useState({})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -13,7 +18,7 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) {
|
|||||||
if (team != undefined) {
|
if (team != undefined) {
|
||||||
setNewTeamName(team.name);
|
setNewTeamName(team.name);
|
||||||
}
|
}
|
||||||
},[selectedTeamId])
|
}, [selectedTeamId])
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -34,30 +39,37 @@ export default function TeamEdit({selectedTeamId, setSelectedTeamId}) {
|
|||||||
setSelectedTeamId(null);
|
setSelectedTeamId(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (team &&
|
return (team &&
|
||||||
<div className='flex flex-row'>
|
<div className='flex flex-col h-full'>
|
||||||
<div className='w-1/2 flex flex-col space-y-3 mx-2'>
|
|
||||||
<h2 className='text-2xl text-center'>Actions</h2>
|
<div className='flex flex-row'>
|
||||||
<form className='flex flex-row' onSubmit={handleSubmit}>
|
<div className='w-1/2 flex flex-col space-y-3 mx-2'>
|
||||||
<div className='w-4/5'>
|
<h2 className='text-2xl text-center'>Actions</h2>
|
||||||
<TextInput name="teamName" label='Team name' value={newTeamName} onChange={(e) => setNewTeamName(e.target.value)}/>
|
<form className='flex flex-row' onSubmit={handleSubmit}>
|
||||||
|
<div className='w-4/5'>
|
||||||
|
<TextInput name="teamName" label='Team name' value={newTeamName} onChange={(e) => setNewTeamName(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div className='w-2/5'>
|
||||||
|
<Button type="submit">Rename</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<Button onClick={handleRemove}>Eliminate</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className='w-2/5'>
|
<div className='w-1/2 flex flex-col space-y-2 mx-2'>
|
||||||
<Button type="submit">Rename</Button>
|
<h2 className='text-2xl text-center'>Team details</h2>
|
||||||
|
<div>
|
||||||
|
<p>Secret : {String(team.id).padStart(6, '0')}</p>
|
||||||
|
<p>Name : {team.name}</p>
|
||||||
|
<p>Chasing : {getTeamName(team.chasing)}</p>
|
||||||
|
<p>Chased by : {getTeamName(team.chased)}</p>
|
||||||
|
<p>Capture code : {String(team.captureCode).padStart(4, '0')}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
<Button onClick={handleRemove}>Eliminate</Button>
|
<div className='m-5 h-full flex flex-col'>
|
||||||
</div>
|
<h2 className='text-2xl text-center'>Starting area</h2>
|
||||||
<div className='w-1/2 flex flex-col space-y-2 mx-2'>
|
<CircularAreaPicker area={team.startingArea} setArea={(startingArea) => setTeam({ ...team, startingArea })} />
|
||||||
<h2 className='text-2xl text-center'>Team details</h2>
|
|
||||||
<div>
|
|
||||||
<p>Secret : {String(team.id).padStart(6,'0')}</p>
|
|
||||||
<p>Name : {team.name}</p>
|
|
||||||
<p>Chasing : {getTeamName(team.chasing)}</p>
|
|
||||||
<p>Chased by : {getTeamName(team.chased)}</p>
|
|
||||||
<p>Capture code : {String(team.captureCode).padStart(4,'0')}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ export function useLocation(interval) {
|
|||||||
const [location, setLocation] = useState();
|
const [location, setLocation] = useState();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function update() {
|
function update() {
|
||||||
|
console.log('Updating location');
|
||||||
navigator.geolocation.getCurrentPosition((position) => {
|
navigator.geolocation.getCurrentPosition((position) => {
|
||||||
setLocation([position.coords.latitude, position.coords.longitude]);
|
setLocation([position.coords.latitude, position.coords.longitude]);
|
||||||
setTimeout(update, interval);
|
if(interval != Infinity) {
|
||||||
|
setTimeout(update, interval);
|
||||||
|
}
|
||||||
}, () => { }, { enableHighAccuracy: true, timeout: Infinity, maximumAge: 0 });
|
}, () => { }, { enableHighAccuracy: true, timeout: Infinity, maximumAge: 0 });
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
|||||||
Reference in New Issue
Block a user