Files
Jungfraujoch/frontend/src/components/ButtonWithSnackbar.tsx
T
2024-11-17 14:55:09 +01:00

102 lines
2.9 KiB
TypeScript

import React, {Component} from 'react';
import {
Alert, SnackbarCloseReason
} from "@mui/material";
import {OpenAPI} from "../openapi";
import Button from "@mui/material/Button";
import Snackbar from "@mui/material/Snackbar";
type MyProps = {
input?: string,
disabled?: boolean,
path: string,
text: string,
color?: "primary" | "secondary",
method?: "GET" | "POST" | "PUT"
}
type MyState = {
snackbar_open: boolean,
start_success: boolean,
start_error?: string
}
class ButtonWithSnackbar extends Component<MyProps, MyState> {
state : MyState = {
snackbar_open: false,
start_success: true
}
printError = (msg: string) => {
this.setState({
snackbar_open: true,
start_success: false,
start_error: msg
});
}
handleResponse = (response : Response) => {
if (response.ok) {
this.setState({snackbar_open: true, start_success: true});
} else {
if (response.status == 404)
this.printError("404: Service not found");
else if (response.status == 400)
this.printError("400: Input parsing or validation error");
else if (response.status == 500) {
response.text().then((val: string) => {
try {
this.printError(JSON.parse(val).msg);
} catch (e) {
this.printError("500: Unknown error");
}
});
}
}
}
startButton = () => {
const url = OpenAPI.BASE + this.props.path;
fetch(url, {
method: (this.props.method === undefined) ? "POST" : this.props.method,
body: this.props.input
}).then(this.handleResponse);
}
handleClose = (event?: React.SyntheticEvent | Event, reason?: SnackbarCloseReason) => {
if (reason === 'clickaway') {
return;
}
this.setState({snackbar_open: false});
};
render() {
return <>
<Button
color={this.props.color}
onClick={this.startButton}
variant="contained"
disableElevation
disabled={this.props.disabled}
>
{this.props.text}
</Button>
<Snackbar open={this.state.snackbar_open}
autoHideDuration={5000}
onClose={this.handleClose}>
<Alert
onClose={this.handleClose}
severity={this.state.start_success ? "success" : "error"}
variant="filled"
sx={{ width: '100%' }}
>
{this.state.start_success ? "Ok!" : this.state.start_error}
</Alert>
</Snackbar>
</>
}
}
export default ButtonWithSnackbar;