298 lines
7.2 KiB
JavaScript
298 lines
7.2 KiB
JavaScript
import {
|
|
Container,
|
|
Box,
|
|
Alert,
|
|
Snackbar,
|
|
Button,
|
|
TextField,
|
|
TableContainer,
|
|
Table,
|
|
TableHead,
|
|
TableRow,
|
|
TableCell,
|
|
TableBody,
|
|
} from "@mui/material";
|
|
import { useEffect, useState } from "react";
|
|
import { useRouter } from "next/router";
|
|
|
|
export default function Time(props) {
|
|
const [ranges, setRanges] = useState([]);
|
|
const [range, setRange] = useState("");
|
|
const [newName, setNewName] = useState("");
|
|
const [snackbarError, setSnackbarError] = useState(false);
|
|
const [snackbarErrorMessage, setSnackbarErrorMessage] = useState("");
|
|
const [snackbarSuccess, setSnackbarSuccess] = useState(false);
|
|
const [limit, setLimit] = useState(1);
|
|
const [token, setToken] = useState("");
|
|
|
|
const router = useRouter();
|
|
|
|
const isAdmin = () => {
|
|
if (props.username === "admin") {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
const addRange = () => {
|
|
fetch("/api/time/ranges", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
name: newName,
|
|
range,
|
|
token,
|
|
}),
|
|
}).then((res) =>
|
|
res.json().then((res) => {
|
|
if (res.error) {
|
|
setSnackbarError(true);
|
|
setSnackbarErrorMessage(res.error);
|
|
} else {
|
|
setSnackbarSuccess(true);
|
|
refreshRanges();
|
|
}
|
|
})
|
|
);
|
|
};
|
|
|
|
const refreshRanges = () => {
|
|
fetch("/api/time/ranges")
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
if (res.error) {
|
|
setSnackbarError(true);
|
|
setSnackbarErrorMessage(res.error);
|
|
} else {
|
|
setSnackbarSuccess(true);
|
|
setRanges(res);
|
|
}
|
|
});
|
|
};
|
|
|
|
const deleteRange = (id) => {
|
|
fetch(`/api/time/ranges/${id}`, {
|
|
method: "DELETE",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ token }),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
if (res.error) {
|
|
setSnackbarError(true);
|
|
setSnackbarErrorMessage(res.error);
|
|
} else {
|
|
setSnackbarSuccess(true);
|
|
refreshRanges();
|
|
}
|
|
});
|
|
};
|
|
|
|
const updateUsername = (id, username) => {
|
|
fetch(`/api/time/ranges/${id}`, {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ username }),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
if (res.error) {
|
|
setSnackbarError(true);
|
|
setSnackbarErrorMessage(res.error);
|
|
} else {
|
|
setSnackbarSuccess(true);
|
|
refreshRanges();
|
|
}
|
|
});
|
|
};
|
|
|
|
const updateLimit = (limit) => {
|
|
fetch("/api/time/limit", {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ limit, token }),
|
|
})
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
if (res.error) {
|
|
setSnackbarError(true);
|
|
setSnackbarErrorMessage(res.error);
|
|
} else {
|
|
setSnackbarSuccess(true);
|
|
refreshRanges();
|
|
}
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!props.username) {
|
|
router.push("/");
|
|
}
|
|
});
|
|
|
|
/*
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
refreshRanges();
|
|
}, 1000);
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
*/
|
|
|
|
useEffect(() => {
|
|
refreshRanges();
|
|
}, []);
|
|
|
|
return (
|
|
<Container>
|
|
{isAdmin() && (
|
|
<Box>
|
|
<Box
|
|
sx={{
|
|
my: 2,
|
|
}}
|
|
>
|
|
<TextField
|
|
label="Token"
|
|
value={token}
|
|
onChange={(e) => setToken(e.target.value)}
|
|
/>
|
|
<Box
|
|
sx={{
|
|
my: 2,
|
|
}}
|
|
>
|
|
<TextField
|
|
label="Name"
|
|
value={newName}
|
|
onChange={(e) => setNewName(e.target.value)}
|
|
/>
|
|
<TextField
|
|
label="Range"
|
|
value={range}
|
|
onChange={(e) => setRange(e.target.value)}
|
|
placeholder="2022-01-01 00:00:00"
|
|
/>
|
|
</Box>
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={() => addRange()}
|
|
>
|
|
Add
|
|
</Button>
|
|
<Box
|
|
sx={{
|
|
my: 2,
|
|
}}
|
|
>
|
|
<TextField
|
|
label="Limit"
|
|
value={limit}
|
|
onChange={(e) => setLimit(e.target.value)}
|
|
/>
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={() => {
|
|
updateLimit(limit);
|
|
}}
|
|
>
|
|
Update Limit
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
)}
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={() => refreshRanges()}
|
|
>
|
|
Refresh
|
|
</Button>
|
|
<TableContainer>
|
|
<Table>
|
|
<TableHead>
|
|
<TableRow>
|
|
<TableCell>Name</TableCell>
|
|
<TableCell>Range</TableCell>
|
|
<TableCell>Taken</TableCell>
|
|
<TableCell>Action</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{ranges.map((range) => (
|
|
<TableRow key={range.id}>
|
|
<TableCell>{range.name}</TableCell>
|
|
<TableCell>{range.range}</TableCell>
|
|
<TableCell>{range.username}</TableCell>
|
|
<TableCell>
|
|
<Button
|
|
sx={{
|
|
userSelect: "none",
|
|
}}
|
|
disabled={range.username !== ""}
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={() => updateUsername(range.id, props.username)}
|
|
>
|
|
Take
|
|
</Button>
|
|
{isAdmin() && (
|
|
<Button
|
|
sx={{
|
|
userSelect: "none",
|
|
}}
|
|
variant="contained"
|
|
color="secondary"
|
|
onClick={() => deleteRange(range.id)}
|
|
>
|
|
Delete
|
|
</Button>
|
|
)}
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
<Snackbar
|
|
open={snackbarError}
|
|
autoHideDuration={1000}
|
|
onClose={() => setSnackbarError(false)}
|
|
>
|
|
<Alert
|
|
variant="filled"
|
|
onClose={() => setSnackbarError(false)}
|
|
severity="error"
|
|
>
|
|
{snackbarErrorMessage}
|
|
</Alert>
|
|
</Snackbar>
|
|
<Snackbar
|
|
open={snackbarSuccess}
|
|
autoHideDuration={1000}
|
|
onClose={() => setSnackbarSuccess(false)}
|
|
>
|
|
<Alert
|
|
variant="filled"
|
|
onClose={() => setSnackbarSuccess(false)}
|
|
severity="success"
|
|
>
|
|
Success!
|
|
</Alert>
|
|
</Snackbar>
|
|
</Container>
|
|
);
|
|
}
|