import { Avatar, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, List, ListItem, ListItemAvatar, TextField } from "@mui/material"; import { grey } from '@mui/material/colors' import { Check, Close, CloseOutlined, PortraitOutlined } from '@mui/icons-material' import React from "react"; import { messageChannelContext } from "../provider/MessageChannel"; import Require from "./Require"; import { useSnackbar } from "notistack"; const AuthButton: React.FC = () => { const snackbar = useSnackbar(); const [open, setOpen] = React.useState(false); const [username, setUsername] = React.useState(''); const [password, setPassword] = React.useState(''); const [usernameError, setUsernameError] = React.useState(false); const [passwordError, setPasswordError] = React.useState(false); const messageChannel = React.useContext(messageChannelContext); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState<Error|undefined>(undefined); const [authed, setAuthed] = React.useState(false); const checkAuth = async () => { console.log(await messageChannel?.checkToken()); setAuthed((await messageChannel?.checkToken())?.isOk ?? false); } React.useEffect(() => { checkAuth() }, []); const handleSubmit = async () => { if (!messageChannel) throw new Error('Invalid state'); //The components to confirm only render if the messageChannel is not undefinded if (username.trim().length === 0) return setUsernameError(true); if (password.trim().length === 0) return setPasswordError(true); setUsernameError(false); setPasswordError(false); setLoading(true); const res = await messageChannel.auth({ username, password }); if (res.isOk) { setOpen(false); snackbar.enqueueSnackbar('Logged in', { variant: 'success' }); setUsername(''); setPassword(''); } else { setError(res.reason); } await checkAuth(); setLoading(false); } return <Require value={messageChannel}> <Dialog open={open}> <Dialog open={!!error}> <DialogTitle>Error during Authentication</DialogTitle> <DialogContentText> {error?.name} {error?.message} </DialogContentText> <DialogActions> <Button onClick={() => setError(undefined)}>Close</Button> </DialogActions> </Dialog> <DialogTitle sx={{ flexGrow: 1 }}>Authentication</DialogTitle> <DialogContent> <DialogContentText> Here, you need to enter your username (most likely your Email) and your password.<br /> These information are not stored anywhere and are only used to authenticate with the service once. </DialogContentText> <TextField error={usernameError} helperText={usernameError ? 'Please enter something before submiting' : undefined} margin="dense" id="username" label="Username" type="text" fullWidth variant="standard" value={username} onChange={(e) => setUsername(e.target.value)} disabled={loading} /> <TextField error={passwordError} helperText={passwordError ? 'Please enter something before submiting' : undefined} margin="dense" id="password" label="Password" type="password" fullWidth variant="standard" value={password} onChange={(e) => setPassword(e.target.value)} disabled={loading} /> </DialogContent> <DialogActions> {loading && <CircularProgress size={30}/>} <Button disabled={loading} onClick={() => setOpen(false)}>Close</Button> <Button disabled={loading} onClick={() => handleSubmit()}>Authenticate</Button> </DialogActions> </Dialog> <Button startIcon={authed ? <Check />: <Close />} variant="contained" onClick={() => setOpen(true)}>Authenticate</Button> </Require> } export default AuthButton;