add website
This commit is contained in:
204
prefs_page/src/App.tsx
Normal file
204
prefs_page/src/App.tsx
Normal file
@@ -0,0 +1,204 @@
|
||||
import "./App.css";
|
||||
import names from "./players.json";
|
||||
import * as React from "react";
|
||||
import { Theme, useTheme } from "@mui/material/styles";
|
||||
import Box from "@mui/material/Box";
|
||||
import OutlinedInput from "@mui/material/OutlinedInput";
|
||||
import InputLabel from "@mui/material/InputLabel";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import FormControl from "@mui/material/FormControl";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import Chip from "@mui/material/Chip";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
FormHelperText,
|
||||
Stack,
|
||||
} from "@mui/material";
|
||||
|
||||
function getStyles(name: string, players: readonly string[], theme: Theme) {
|
||||
return {
|
||||
fontWeight: players.includes(name)
|
||||
? theme.typography.fontWeightMedium
|
||||
: theme.typography.fontWeightRegular,
|
||||
};
|
||||
}
|
||||
|
||||
async function submit(
|
||||
person: string,
|
||||
players: string[],
|
||||
setResponseStatus: (value: number) => void
|
||||
) {
|
||||
// console.log(JSON.stringify({ person: person, players: players }));
|
||||
const response = await fetch("https://0124816.xyz/team/submit/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ person: person, players: players }),
|
||||
});
|
||||
setResponseStatus(response.status);
|
||||
}
|
||||
|
||||
type SubmitButtonProps = {
|
||||
person: string;
|
||||
players: string[];
|
||||
};
|
||||
|
||||
function SubmitButton(props: SubmitButtonProps) {
|
||||
const [responseStatus, setResponseStatus] = React.useState(0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color={responseStatus === 200 ? "success" : "primary"}
|
||||
onClick={() => submit(props.person, props.players, setResponseStatus)}
|
||||
>
|
||||
submit
|
||||
</Button>
|
||||
<Dialog open={responseStatus === 200}>
|
||||
<DialogTitle>thank you. please leave now.</DialogTitle>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type MultiSelectProps = {
|
||||
person: string;
|
||||
setPerson: (value: string) => void;
|
||||
players: string[];
|
||||
setPlayers: (value: string[]) => void;
|
||||
};
|
||||
|
||||
function MultipleSelectChip(props: MultiSelectProps) {
|
||||
const ITEM_HEIGHT = 48;
|
||||
const ITEM_PADDING_TOP = 8;
|
||||
const MenuProps = {
|
||||
PaperProps: {
|
||||
style: {
|
||||
maxHeight: ITEM_HEIGHT * 6.5 + ITEM_PADDING_TOP,
|
||||
width: 250,
|
||||
},
|
||||
},
|
||||
};
|
||||
const [alert, setAlert] = React.useState<string>("none");
|
||||
const maxLimit = 9;
|
||||
const theme = useTheme();
|
||||
|
||||
const handlePersonChange = (
|
||||
event: SelectChangeEvent<typeof props.person>
|
||||
) => {
|
||||
const {
|
||||
target: { value },
|
||||
} = event;
|
||||
props.setPerson(value);
|
||||
const index = props.players.indexOf(value);
|
||||
if (index > -1) {
|
||||
props.players.splice(index, 1);
|
||||
}
|
||||
props.setPlayers(props.players);
|
||||
};
|
||||
|
||||
const handleChange = (event: SelectChangeEvent<typeof props.players>) => {
|
||||
const {
|
||||
target: { value },
|
||||
} = event;
|
||||
if (value.length <= maxLimit) {
|
||||
setAlert("none");
|
||||
props.setPlayers(
|
||||
// On autofill we get a stringified value.
|
||||
typeof value === "string" ? value.split(",") : value
|
||||
);
|
||||
} else {
|
||||
setAlert("");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ maxWidth: "60vw" }}>
|
||||
<Stack direction="column">
|
||||
<FormControl sx={{ m: "8px auto", width: 200 }}>
|
||||
<InputLabel id="demo-multiple-chip-label">who are you?</InputLabel>
|
||||
<Select
|
||||
labelId="demo-chip-label"
|
||||
id="demo-multiple-chip"
|
||||
value={props.person}
|
||||
onChange={handlePersonChange}
|
||||
input={<OutlinedInput id="select-chip" label="who are you?" />}
|
||||
MenuProps={MenuProps}
|
||||
>
|
||||
{names.map((name) => (
|
||||
<MenuItem key={name} value={name}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<Alert
|
||||
severity="warning"
|
||||
sx={{ display: alert, width: 200, m: "8px auto" }}
|
||||
>
|
||||
do not select more than {maxLimit} players
|
||||
</Alert>
|
||||
|
||||
<FormControl sx={{ m: "8px auto", width: 200 }}>
|
||||
<InputLabel id="demo-multiple-chip-label">players</InputLabel>
|
||||
<Select
|
||||
labelId="demo-multiple-chip-label"
|
||||
id="demo-multiple-chip"
|
||||
multiple
|
||||
value={props.players}
|
||||
onChange={handleChange}
|
||||
input={<OutlinedInput id="select-multiple-chip" label="players" />}
|
||||
renderValue={(selected) => (
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
|
||||
{selected.map((value) => (
|
||||
<Chip key={value} label={value} />
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
MenuProps={MenuProps}
|
||||
>
|
||||
{names.map((name) =>
|
||||
name !== props.person ? (
|
||||
<MenuItem
|
||||
key={name}
|
||||
value={name}
|
||||
style={getStyles(name, props.players, theme)}
|
||||
>
|
||||
{name}
|
||||
</MenuItem>
|
||||
) : null
|
||||
)}
|
||||
</Select>
|
||||
<FormHelperText>max. {maxLimit}</FormHelperText>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [person, setPerson] = React.useState<string>("");
|
||||
const [players, setPlayers] = React.useState<string[]>([]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>choose your best buddies for the Igloo</h1>
|
||||
<div className="card">
|
||||
{MultipleSelectChip({ person, setPerson, players, setPlayers })}
|
||||
{SubmitButton({ person, players })}
|
||||
<p>now: click submit.</p>
|
||||
</div>
|
||||
<p className="read-the-docs">
|
||||
something not working? message <a href="https://t.me/x0124816">me</a>.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user