mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-02-09 02:10:18 +01:00
Interface d'attente + logout
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
import ActionDrawer from '@/components/team/actionDrawer';
|
||||
import PlacementOverlay from '@/components/team/placementOverlay';
|
||||
import { WaitingScreen } from '@/components/team/waitingScreen';
|
||||
import { useTeamConnexion } from '@/context/teamConnexionContext';
|
||||
import useGame from '@/hook/useGame';
|
||||
import { GameState } from '@/util/gameState';
|
||||
@@ -15,10 +17,11 @@ const PlacementMap = dynamic(() => import('@/components/team/map').then((mod) =>
|
||||
});
|
||||
|
||||
export default function Track() {
|
||||
const { gameState, name, ready } = useGame();
|
||||
const { gameState} = useGame();
|
||||
const { useProtect } = useTeamConnexion();
|
||||
useProtect();
|
||||
return <>
|
||||
{gameState == GameState.SETUP && <WaitingScreen />}
|
||||
{gameState == GameState.PLAYING && <div className='h-full'>
|
||||
<LiveMap />
|
||||
<ActionDrawer />
|
||||
@@ -26,13 +29,7 @@ export default function Track() {
|
||||
}
|
||||
{gameState == GameState.PLACEMENT &&
|
||||
<div className='h-full'>
|
||||
<div className='fixed t-0 p-3 w-full bg-gray-300 shadow-xl rounded-b-xl flex flex-col z-10 justify-center items-center'>
|
||||
<div className='text-2xl my-3'>Placement</div>
|
||||
<div className='text-m'>{name}</div>
|
||||
{!ready && <div className='text-lg font-semibold text-red-700'>Positionez vous dans le cercle</div>}
|
||||
{ready && <div className='text-lg font-semibold text-green-700 text-center'>Restez dans le cercle en attendant que la partie commence</div>}
|
||||
|
||||
</div>
|
||||
<PlacementOverlay />
|
||||
<PlacementMap />
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -5,13 +5,16 @@ import TextInput from "../util/textInput";
|
||||
|
||||
export default function ActionDrawer() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { sendCurrentPosition } = useGame();
|
||||
const { sendCurrentPosition, name } = useGame();
|
||||
|
||||
return (
|
||||
<div className={"fixed w-screen bottom-0 z-10 bg-gray-100 flex justify-center rounded-t-2xl transition-all duration-200 flex flex-col " + (visible ? "h-full" : "h-20")}>
|
||||
<img src="/icons/arrow_up.png" className={"w-full object-scale-down h-ful max-h-20 transition-all cursor-pointer duration-200 " + (visible && "rotate-180")} onClick={() => setVisible(!visible)} />
|
||||
{visible && <div className="flex flex-col w-full h-full">
|
||||
<div className='shadow-lg mt-0 p-1 flex flex-col text-center mb-1 mt-auto mx-auto w-4/5 rounded'>
|
||||
<div>
|
||||
<span className='text-xl text-black'>{name}</span>
|
||||
</div>
|
||||
<div className='text-gray-700'>
|
||||
<span className='text-lg text-black'>30min</span>
|
||||
<span> before penalty</span>
|
||||
|
||||
@@ -82,7 +82,7 @@ export function PlacementMap({ ...props}) {
|
||||
</Popup>
|
||||
</Marker>}
|
||||
<MapPan center={currentPosition}/>
|
||||
<Circle center={startingArea?.center} radius={startingArea?.radius} color='blue' />
|
||||
{startingArea && <Circle center={startingArea?.center} radius={startingArea?.radius} color='blue' />}
|
||||
</MapContainer>
|
||||
)
|
||||
}
|
||||
|
||||
19
traque-front/components/team/placementOverlay.jsx
Normal file
19
traque-front/components/team/placementOverlay.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
||||
import useGame from "@/hook/useGame"
|
||||
|
||||
export default function PlacementOverlay() {
|
||||
const { name, ready } = useGame();
|
||||
const {logout} = useTeamConnexion();
|
||||
return (
|
||||
<>
|
||||
<img src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
||||
<div className='fixed top-0 p-3 w-full bg-gray-300 shadow-xl rounded-b-xl flex flex-col z-10 justify-center items-center'>
|
||||
<div className='text-2xl my-3'>Placement</div>
|
||||
<div className='text-md'>{name}</div>
|
||||
{!ready && <div className='text-lg font-semibold text-red-700'>Positionez vous dans le cercle</div>}
|
||||
{ready && <div className='text-lg font-semibold text-green-700 text-center'>Restez dans le cercle en attendant que la partie commence</div>}
|
||||
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
21
traque-front/components/team/waitingScreen.jsx
Normal file
21
traque-front/components/team/waitingScreen.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
||||
import useGame from "@/hook/useGame"
|
||||
|
||||
export function WaitingScreen() {
|
||||
const { name } = useGame();
|
||||
const { logout } = useTeamConnexion();
|
||||
return (
|
||||
<div className='h-full flex flex-col items-center justify-center'>
|
||||
<div className='text-4xl text-center'>
|
||||
Equipe : {name}
|
||||
</div>
|
||||
<div className='text-2xl text-center'>
|
||||
Jeu en préparation, veuillez patienter...
|
||||
</div>
|
||||
<div className="bottom-0 absolute text-sm text-center">
|
||||
Vous avez perdu Le Jeu
|
||||
</div>
|
||||
<img src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -7,10 +7,10 @@ import { usePasswordProtect } from "@/hook/usePasswordProtect";
|
||||
const teamConnexionContext = createContext();
|
||||
const TeamConnexionProvider = ({ children }) => {
|
||||
const { teamSocket } = useSocket();
|
||||
const { login, password: teamId, loggedIn, loading } = useSocketAuth(teamSocket, "team_password");
|
||||
const { login, password: teamId, loggedIn, loading, logout } = useSocketAuth(teamSocket, "team_password");
|
||||
const useProtect = () => usePasswordProtect("/team", "/team/track", loading, loggedIn);
|
||||
|
||||
const value = useMemo(() => ({ teamId, login, loggedIn, loading, useProtect}), [teamId, login, loggedIn, loading]);
|
||||
const value = useMemo(() => ({ teamId, login, logout, loggedIn, loading, useProtect}), [teamId, login, loggedIn, loading]);
|
||||
|
||||
return (
|
||||
<teamConnexionContext.Provider value={value}>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useLocalStorage } from './useLocalStorage';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
const LOGIN_MESSAGE = "login";
|
||||
const LOGOUT_MESSAGE = "logout";
|
||||
const LOGIN_RESPONSE_MESSAGE = "login_response";
|
||||
|
||||
export function useSocketAuth(socket, passwordName) {
|
||||
@@ -13,15 +14,24 @@ export function useSocketAuth(socket, passwordName) {
|
||||
const [savedPassword, setSavedPassword, savedPasswordLoading] = useLocalStorage(passwordName, null);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Checking saved password", savedPassword, loggedIn);
|
||||
if (savedPassword && !loggedIn) {
|
||||
console.log("Logging in with saved password", savedPassword);
|
||||
socket.emit(LOGIN_MESSAGE, savedPassword);
|
||||
}
|
||||
}, [savedPassword]);
|
||||
|
||||
function login(password) {
|
||||
console.log("Logging", password);
|
||||
setSavedPassword(password)
|
||||
}
|
||||
|
||||
function logout() {
|
||||
setSavedPassword(null);
|
||||
setLoggedIn(false);
|
||||
socket.emit(LOGOUT_MESSAGE)
|
||||
}
|
||||
|
||||
useSocketListener(socket, LOGIN_RESPONSE_MESSAGE,(loginResponse) => {
|
||||
setWaitingForResponse(false);
|
||||
setLoggedIn(loginResponse);
|
||||
@@ -39,5 +49,5 @@ export function useSocketAuth(socket, passwordName) {
|
||||
}, [waitingForResponse, savedPasswordLoading, savedPassword]);
|
||||
|
||||
|
||||
return {login,password: savedPassword, loggedIn, loading};
|
||||
return {login,logout,password: savedPassword, loggedIn, loading};
|
||||
}
|
||||
BIN
traque-front/public/icons/logout.png
Normal file
BIN
traque-front/public/icons/logout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Reference in New Issue
Block a user