Files
menui_web/src/components/EditRestaurant/EditRestaurantInfo.js
2020-11-20 18:12:52 +01:00

501 lines
15 KiB
JavaScript

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import ButtonPrimary from "../Input/ButtonPrimary";
import ButtonSecondary from "../Input/ButtonSecondary";
import TextField from "@material-ui/core/TextField";
import { makeStyles } from "@material-ui/core/styles";
import InputWorkingHours from "../Input/InputWorkingHours";
import Autocomplete from "@material-ui/lab/Autocomplete";
import InputAdornment from "@material-ui/core/InputAdornment";
import PhoneIcon from "@material-ui/icons/Phone";
import FacebookIcon from "@material-ui/icons/Facebook";
import InstagramIcon from "@material-ui/icons/Instagram";
import LanguageIcon from "@material-ui/icons/Language";
import FastfoodIcon from "@material-ui/icons/Fastfood";
import LocationCityIcon from "@material-ui/icons/LocationCity";
import Divider from "@material-ui/core/Divider";
import { decodeTags } from "../../Services";
import validator from "validator";
import { useSelector, useDispatch } from "react-redux";
import { notification, refreshUserData, updateRestaurant } from "../../actions";
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
import { prepareTags } from "../../Services.js";
import axios from "axios";
import PasswordConfirmation from "../Dialogs/PasswordConfirmation";
import { backend, restaurantTypes } from "../../config";
import InputLunchMenuHours from "../Input/InputLunchMenuHours";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import InputLabel from "@material-ui/core/InputLabel";
import Switch from '@material-ui/core/Switch';
const useStyles = makeStyles((theme) => ({
textInput: {
margin: theme.spacing(2),
"& .MuiInputBase-root": {
color: "#bbbbbb",
},
"& .MuiInputLabel-root": {
color: "#bbbbbb",
},
},
textInputFullWidth: {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
"& .MuiInputBase-root": {
color: "#bbbbbb",
},
"& .MuiInputLabel-root": {
color: "#bbbbbb",
},
"$ .MuiFormHelperText-root": {
color: "#bbbbbb",
},
},
link: {
cursor: "pointer",
},
formControl: {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
minWidth: 100,
maxHeight: 400,
"& .MuiInputBase-root": {
color: "#bbbbbb",
},
"$ .MuiSelect-root": {
color: "#bbbbbb",
},
"& .MuiInputLabel-root": {
color: "#bbbbbb",
},
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
const calculateCharLeft = (from) => {
return 400 - from.length;
};
export default function EditRestaurantInfo(props) {
const history = useHistory();
const initialState = {
name: props.restaurant.name,
city: props.restaurant.city,
adress: props.restaurant.adress,
description: props.restaurant.description,
type: props.restaurant.type,
phone: props.restaurant.phone,
hidden: props.restaurant.hidden,
links: props.restaurant.links,
tags: decodeTags(props.restaurant.tags),
workingHours: props.restaurant.workingHours,
lunchHours: props.lunchHours,
charleft: calculateCharLeft(props.restaurant.description),
nameError: false,
cityError: false,
adressError: false,
descriptionError: false,
typeError: false
};
const [state, setState] = useState(initialState);
const [passwordDialog, setPasswordDialog] = useState(false);
const styles = useStyles();
const dispatch = useDispatch();
const jwt = useSelector((state) => state.data.userData.jwt);
const email = useSelector((state) => state.data.userData.userEmail);
const handleDescriptionChange = (event) => {
let stringLength = event.target.value.length;
let charleft = 400 - stringLength;
setState({ ...state, description: event.target.value, charLeft: charleft });
};
const availableTags = [
"Płatność kartą",
"Lubimy zwierzaki",
"Bezglutenowe",
"Wegańskie",
"Wegetariańskie",
"Podajemy alkohol",
"Dowozimy",
];
const validateForm = () => {
const validation = {
nameValid: validator.isLength(state.name, { min: 1, max: 40 }),
cityValid: validator.isLength(state.city, { min: 1, max: 40 }),
typeValid: validator.isLength(state.type, { min: 1, max: 40 }),
adressValid: validator.isLength(state.name, { min: 1, max: 40 }),
descriptionValid: validator.isLength(state.description, {
min: 1,
max: 400,
}),
};
setState({
...state,
nameError: !validation.nameValid,
cityError: !validation.cityValid,
adressError: !validation.adressValid,
typeError: !validation.typeValid,
descriptionError: !validation.descriptionValid,
});
return (
validation.nameValid &&
validation.cityValid &&
validation.adressValid &&
validation.descriptionValid &&
validation.typeValid
);
};
const availableTypes = restaurantTypes.map((type) => {
return <MenuItem key={type} value={type}>{type}</MenuItem>
});
const cancelChanges = () => {
setState(initialState);
};
const handleSetHidden = () => {
dispatch(showBackdrop());
axios({
url: `${backend}restaurant/visibility`,
method: "POST",
data: {
restaurantId: props.restaurant._id,
visible: state.hidden
},
headers: {
"x-auth-token": jwt,
},
})
.then((response) => {
dispatch(refreshUserData(jwt));
setState({ ...state, hidden: !state.hidden });
dispatch(hideBackdrop());
dispatch(notification("Widoczność zmieniona poprawnie", "success"));
})
.catch((err) => {
console.log(err);
dispatch(hideBackdrop());
dispatch(notification("Wystąpił błąd :(", "error"));
});
}
const handleDelete = (password) => {
dispatch(showBackdrop());
axios({
url: `${backend}restaurant/delete`,
method: "POST",
data: {
restaurantId: props.restaurant._id,
password: password,
email: email,
},
headers: {
"x-auth-token": jwt,
},
})
.then((response) => {
dispatch(refreshUserData(jwt));
dispatch(hideBackdrop());
dispatch(notification("Restauracja została usunięta", "success"));
history.push("/");
})
.catch((err) => {
console.log(err);
dispatch(hideBackdrop());
dispatch(notification("Wystąpił nieoczekiwany błąd :(", "error"));
});
};
const setLunchHours = (hours) => {
setState({ ...state, lunchHours: hours });
}
const handleSendForm = () => {
if (validateForm()) {
const formattedTags = prepareTags(state.tags);
const data = {
restaurantId: props.restaurant._id,
dishes: props.restaurant.dishes,
categories: props.restaurant.categories,
lunchMenu: props.restaurant.lunchMenu,
name: state.name,
city: state.city,
adress: state.adress,
coordinates: props.restaurant.location.coordinates,
placesId: props.restaurant.placesId,
type: state.type,
imgUrl: props.restaurant.imgUrl,
workingHours: state.workingHours,
lunchHours: state.lunchHours,
description: state.description,
tags: formattedTags,
links: state.links,
phone: state.phone,
hidden: props.restaurant.hidden,
};
dispatch(showBackdrop());
axios({
url: backend + "restaurant",
method: "PUT",
data: data,
headers: {
"x-auth-token": jwt,
},
})
.then((response) => {
dispatch(hideBackdrop());
dispatch(notification("Dane zostały zapisane.", "success"));
dispatch(updateRestaurant(response));
})
.catch((err) => {
console.log(err);
dispatch(hideBackdrop());
dispatch(notification("Wystąpił nieoczekiwany błąd :(", "error"));
});
}
};
return (
<div className="editRestaurant-tab">
<PasswordConfirmation
open={passwordDialog}
onCancel={() => setPasswordDialog(false)}
onSubmit={handleDelete}
/>
<div className="editRestaurant-doubleColumn">
<div className="editRestaurant-sectiontitle">
<h4>Podstawowe dane</h4>
<Divider />
</div>
<div className="editRestaurant-fullWidth">
<TextField
className={styles.textInputFullWidth}
fullWidth
value={state.name}
error={state.nameError}
onChange={(event) =>
setState({ ...state, name: event.target.value })
}
InputLabelProps={{ shrink: true }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<FastfoodIcon color="primary" />
</InputAdornment>
),
}}
label="Nazwa lokalu"
variant="outlined"
/>
</div>
<div className="editRestaurant-fullWidth">
<FormControl
variant="outlined"
required
fullWidth
className={styles.formControl}
>
<InputLabel id="category-select">Kuchnia</InputLabel>
<Select
labelId="category-select"
id="category"
value={state.type}
required
onChange={(event) => setState({ ...state, type: event.target.value })}
>
{availableTypes}
</Select>
</FormControl>
</div>
<TextField
className={styles.textInput}
value={state.city}
error={state.cityError}
onChange={(event) => setState({ ...state, city: event.target.value })}
InputLabelProps={{ shrink: true }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<LocationCityIcon color="primary" />
</InputAdornment>
),
}}
label="Miasto"
variant="outlined"
/>
<TextField
className={styles.textInput}
value={state.adress}
error={state.adressError}
onChange={(event) =>
setState({ ...state, adress: event.target.value })
}
InputLabelProps={{ shrink: true }}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<LocationCityIcon color="primary" />
</InputAdornment>
),
}}
label="Adres"
variant="outlined"
/>
<div className="editRestaurant-fullWidth">
<TextField
className={styles.textInputFullWidth}
fullWidth
label="Opis"
value={state.description}
error={state.descriptionError}
onChange={handleDescriptionChange}
multiline
rows={3}
rowsMax={8}
variant="outlined"
helperText={`Pozostałe znaki: ${state.charleft}`}
InputLabelProps={{ shrink: true }}
FormHelperTextProps={{
style: { color: "#bbbbbb" },
}}
/>
<Autocomplete
multiple
options={availableTags}
value={state.tags}
onChange={(event, values) => setState({ ...state, tags: values })}
renderInput={(params) => (
<TextField
{...params}
className={styles.textInputFullWidth}
variant="outlined"
label="Tagi"
placeholder="Wybierz tagi"
/>
)}
/>
</div>
<div className="editRestaurant-sectiontitle">
<h4>Godziny otwarcia</h4>
<Divider />
</div>
<InputWorkingHours
setHours={(hours) => setState({ ...state, workingHours: hours })}
hours={state.workingHours}
/>
<div className="editRestaurant-sectiontitle">
<h4>Dane kontaktowe</h4>
<Divider />
</div>
<TextField
className={styles.textInput}
label="Telefon"
type="tel"
variant="outlined"
value={state.phone}
onChange={(event) =>
setState({ ...state, phone: event.target.value })
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<PhoneIcon color="primary" />
</InputAdornment>
),
}}
/>
<TextField
className={styles.textInput}
label="Facebook"
variant="outlined"
value={state.links.facebook}
onChange={(event) =>
setState({
...state,
links: { ...state.links, facebook: event.target.value },
})
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<FacebookIcon color="primary" />
</InputAdornment>
),
}}
/>
<TextField
className={styles.textInput}
label="Instagram"
variant="outlined"
value={state.links.instagram}
onChange={(event) =>
setState({
...state,
links: { ...state.links, instagram: event.target.value },
})
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<InstagramIcon color="primary" />
</InputAdornment>
),
}}
/>
<TextField
className={styles.textInput}
label="www"
variant="outlined"
value={state.links.www}
onChange={(event) =>
setState({
...state,
links: { ...state.links, www: event.target.value },
})
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<LanguageIcon color="primary" />
</InputAdornment>
),
}}
/>
<div className="editRestaurant-sectiontitle">
<h4>Lunch menu</h4>
<Divider />
<InputLunchMenuHours
nieczynne={!state.lunchHours}
hours={state.lunchHours}
changeValue={setLunchHours}
/>
</div>
<div className="editRestaurant-sectiontitle">
<h4>Zaawansowane</h4>
<Divider />
<div className="editRestaurant-settings">
<h4>Ukryj restaurację (nie wymaga zatwierdzania)</h4>
<Switch checked={state.hidden} color="primary" onChange={handleSetHidden}/>
</div>
<div className="editRestaurant-settings">
<h4>
Usuń restaurację (operacja jest nieodwracalna!)
</h4>
<ButtonPrimary text="Usuń" onClick={() => setPasswordDialog(true)} />
</div>
</div>
</div>
<div className="editRestaurant-bottom">
<ButtonPrimary text="Anuluj" onClick={cancelChanges} />
<ButtonSecondary onClick={handleSendForm} text="Zapisz" />
</div>
</div>
);
}