Encartes-web/src/App.js
2023-03-01 09:34:02 +01:00

279 lines
7.7 KiB
JavaScript

import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
import CssBaseline from '@mui/material/CssBaseline';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import Divider from '@mui/material/Divider';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import TextField from '@mui/material/TextField';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import './App.css'
import Map from './Map.js';
import Rooms from './Rooms.js';
function ChangeFloor({ currentFloor, callbackFloorChanged }) {
const handleFloorChanged = (event) => {
callbackFloorChanged(event.target.value);
};
return <>
<div style={{ padding: '24px' }}>
<Typography component="h2" variant="h5" gutterBottom>
Changer d'étage
</Typography>
<Select
value={currentFloor}
label="Étage"
onChange={handleFloorChanged}
fullWidth
>
<MenuItem value={9}>Monod - Premier étage</MenuItem>
<MenuItem value={13}>Monod - Troisième étage</MenuItem>
<MenuItem value={14}>Monod - Quatrième étage</MenuItem>
</Select>
</div>
</>
}
function RoomResearch({ callbackRoomSelected }) {
const [currentRequest, setCurrentRequest] = React.useState("");
const [rooms, setRooms] = React.useState([]);
const startResearch = (event) => {
fetch("https://encartes.aliens-lyon.fr/api/map/find_place_by_name/" + currentRequest)
.then(response => response.json())
.then(data => {
setRooms(data);
});
};
return <>
<div style={{ padding: '24px' }}>
<Typography component="h2" variant="h5" gutterBottom>
Rechercher une salle
</Typography>
<TextField
label="Nom, code, occupants, ..."
value={currentRequest}
onChange={(event) => { setCurrentRequest(event.target.value) }}
variant="outlined"
fullWidth
/>
<Box
marginTop={1}
display="flex"
justifyContent="flex-end"
alignItems="flex-end"
>
<Button variant="contained" onClick={startResearch}>Rechercher</Button>
</Box>
<Rooms rooms={rooms} callbackRoomSelected={callbackRoomSelected} />
</div>
</>
}
function RoomInformation({ roomId, setIsEditDialogOpen }) {
const [names, setNames] = React.useState([]);
const [users, setUsers] = React.useState([]);
React.useEffect(() => {
if (roomId !== null) {
fetch("https://encartes.aliens-lyon.fr/api/map/get_place_info/" + roomId)
.then(response => response.json())
.then(data => {
setNames(data.names);
setUsers(data.users);
});
}
}, [roomId]);
if (roomId === null) {
return;
}
return <div style={{ padding: '24px' }}>
<Typography component="h2" variant="h5" gutterBottom>
Salle sélectionnée
</Typography>
<ul>
<li>{
names.length === 0 ? <em>Aucun nom défini</em> : names.join(', ')
}</li>
<li>{
users.length === 0
? <em>Aucun utilisateur défini</em>
: 'Utilisée par ' + users.join(', ')
}</li>
</ul>
<a onClick={() => { setIsEditDialogOpen(true) }}>Modifier</a>
</div>
}
function TopBar() {
const [openAboutModal, setOpenAboutModal] = React.useState(false);
const handleOpenAboutModal = () => {
setOpenAboutModal(true);
};
const handleCloseAboutModal = () => {
setOpenAboutModal(false);
};
return <>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
ENcarteS
</Typography>
<Button color="inherit" onClick={handleOpenAboutModal}>À propos</Button>
</Toolbar>
</AppBar>
<Dialog
open={openAboutModal}
onClose={handleCloseAboutModal}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
{"À propos d'ENcarteS"}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
ENcarteS permet de rechercher les salles de l'ENS !
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseAboutModal}>Ok</Button>
</DialogActions>
</Dialog>
</>
}
function EditDialog({ isOpen, setIsOpen, room }) {
const [names, setNames] = React.useState([]);
const [users, setUsers] = React.useState([]);
const [newPlaceName, setNewPlaceName] = React.useState("");
// Used to refresh useEffect
const [updatesCount, setupdatesCount] = React.useState(0);
React.useEffect(() => {
if (room !== null) {
fetch("https://encartes.aliens-lyon.fr/api/map/get_place_info/" + room)
.then(response => response.json())
.then(data => {
setNames(data.names);
setUsers(data.users);
});
}
}, [room, updatesCount]);
const refresh = () => {
setupdatesCount(updatesCount + 1);
};
const addName = () => {
fetch("https://encartes.aliens-lyon.fr/api/map/add_place_name/" + room + "/" + encodeURI(newPlaceName))
.then(response => refresh());
};
return <Dialog open={isOpen} onClose={() => { setIsOpen(false) }}>
<DialogTitle>Salle n°{room}</DialogTitle>
<DialogContent>
<DialogContentText>
Noms :<br/>
{names.map(name => {
return <Chip label={name} variant="outlined" onDelete={() => {}} />
})}
<TextField
value={newPlaceName}
onChange={(event) => { setNewPlaceName(event.target.value) }}
label="Nouveau nom"
margin="dense"
fullWidth
/>
<Button onClick={() => { addName() }}>Ajouter</Button>
<Divider/>
Utilisateurs :<br/>
{users.map(name => {
return <Chip label={name} variant="outlined" onDelete={() => {}} />
})}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => { setIsOpen(false) }}>Fermer</Button>
</DialogActions>
</Dialog>
}
export default function App() {
const [currentFloor, setCurrentFloor] = React.useState(13);
const [selectedRoom, setSelectedRoom] = React.useState(null);
const [isEditDialogOpen, setIsEditDialogOpen] = React.useState(false);
return <>
<EditDialog
isOpen={isEditDialogOpen}
setIsOpen={setIsEditDialogOpen}
room={selectedRoom}
/>
<TopBar />
<div style={{ flexGrow: '1', display: 'flex', flexDirection: 'line', flexWrap: 'nowrap' }}>
<Map
selectedRoom={selectedRoom}
callbackRoomSelected={setSelectedRoom}
floorID={currentFloor}
callbackChangeFloor={setCurrentFloor}
/>
<div>
<ChangeFloor currentFloor={currentFloor} callbackFloorChanged={setCurrentFloor} />
<Divider />
<RoomResearch callbackRoomSelected={(floor, room) => {
setCurrentFloor(floor);
setSelectedRoom(room);
}} />
<Divider />
<RoomInformation
roomId={selectedRoom}
setIsEditDialogOpen={setIsEditDialogOpen}
/>
</div>
</div>
</>
}
const darkTheme = createTheme({
palette: {
mode: 'dark',
},
});
function ThemedApp() {
return (
<ThemeProvider theme={darkTheme}>
<CssBaseline />
<App />
</ThemeProvider>
);
}