web client v0.2 (add restaurant OK, settings OK)

This commit is contained in:
2020-09-19 18:16:26 +02:00
parent 732ad74657
commit 68ecf13aa1
16 changed files with 546 additions and 86 deletions

View File

@@ -0,0 +1,50 @@
import React from "react";
import PictogramsSeparate from "../Output/PictogramsSeparate";
import DishList from "../Output/DishList";
import CircularProgress from "@material-ui/core/CircularProgress";
import { extractTags } from "../../Services";
import { useSelector } from "react-redux";
export default function EditRestaurant(props) {
const restaurant = useSelector((state) => state.restaurant);
const showDishList = useSelector((state) => state.data.showDishList);
return (
<div className="restaurant-container">
<div className="restaurant-content">
<div className="restaurant-info">
<div
className="restaurant-hero"
style={{ backgroundImage: "url(" + restaurant.imgUrl + ")" }}
></div>
<h1>{restaurant.name}</h1>
<p>{restaurant.description}</p>
<hr />
<p>
Miejscowość:{" "}
<span className="restaurant-span">{restaurant.city}</span>
</p>
<p>
Godziny pracy:{" "}
<span className="restaurant-span">{restaurant.workingHours}</span>
</p>
{restaurant.phone && (
<p>
Kontakt:{" "}
<span className="restaurant-span">{restaurant.phone}</span>
</p>
)}
<hr />
<div className="restaurant-pictograms">
<PictogramsSeparate pictograms={extractTags(restaurant.tags)} />
</div>
</div>
<div className="restaurant-dishes">
<h3>Menu</h3>
{showDishList === false && <CircularProgress />}
{showDishList === true && <DishList />}
</div>
</div>
</div>
);
}

View File

@@ -19,12 +19,15 @@ import validator from "validator";
import { useHistory } from "react-router-dom";
import InputGoogleMaps from "../Input/InputGoogleMaps";
import InfoDialog from "../Output/InfoDialog";
import { prepareTags } from "../../Services.js";
import axios from "axios";
import { useSelector } from "react-redux";
// ICONS
import FastfoodIcon from "@material-ui/icons/Fastfood";
import LocationCityIcon from "@material-ui/icons/LocationCity";
import PhoneIcon from "@material-ui/icons/Phone";
import FacebookIcon from "@material-ui/icons/Facebook";
import TwitterIcon from "@material-ui/icons/Twitter";
import InstagramIcon from "@material-ui/icons/Instagram";
import LanguageIcon from "@material-ui/icons/Language";
import ButtonPrimary from "../Input/ButtonPrimary";
@@ -100,18 +103,19 @@ export default function NewRestaurant() {
tags: [],
phone: "",
facebook: "",
twitter: "",
instagram: "",
www: "",
nameError: false,
cityError: false,
adressError: false,
descriptionError: false,
charLeft: 400,
open: true,
response: "",
response: "Dodawanie lokalu, prosimy o chwilę cierpliwości...",
};
const steps = ["Informacje", "Zdjęcie", "Lokalizacja"];
const [state, setState] = useState(initialState);
const [open, setOpen] = useState(true);
const [loading, setLoading] = useState(true);
const [activeStep, setActiveStep] = React.useState(0);
const styles = useStyles();
const availableTags = [
@@ -124,26 +128,59 @@ export default function NewRestaurant() {
"Dowozimy",
];
const history = useHistory();
const token = useSelector((state) => state.data.jwt);
// HANDLERS
const sendForm = () => {
// format tags
const formattedTags;
const formattedTags = prepareTags(state.tags);
const data = {
name: state.name,
city: state.city,
adress: state.adress,
coordinates: state.coordinates,
placesId: state.placesId,
imgURL: state.imgURL,
workingHours: `${state.hoursFrom} - ${state.hoursTo}`,
description: state.description,
tags: formattedTags,
links: {},
phone: request.phone,
hidden: request.hidden,
}
city: state.city,
adress: state.adress,
coordinates: state.coordinates,
placesId: state.placesId,
imgURL: state.imgURL,
workingHours: `${state.hoursFrom} - ${state.hoursTo}`,
description: state.description,
tags: formattedTags,
facebook: state.facebook,
instagram: state.instagram,
www: state.www,
phone: state.phone,
hidden: false,
};
setOpen(false);
axios({
url: "http://localhost:4000/restaurant",
method: "POST",
data: data,
headers: {
"x-auth-token": token,
},
})
.then((response) => {
setLoading(false);
setState({
...state,
response:
"Lokal został dodany, aktywuj subskrypcję, aby był widoczny w wynikach wyszukiwania.",
});
setTimeout(() => {
history.push("/");
}, 5000);
})
.catch((error) => {
setLoading(false);
setState({
...state,
response:
"Wystąpił nieoczekiwany błąd, przepraszamy za utrudnienia. Spróbuj ponownie za chwilę.",
});
setTimeout(() => {
history.push("/");
}, 5000);
});
};
const setCoordinatesAndPlacesID = (coordinates, placesID) => {
@@ -167,7 +204,6 @@ export default function NewRestaurant() {
}
break;
case 2:
setState({ ...state, open: false });
sendForm();
break;
default:
@@ -219,16 +255,16 @@ export default function NewRestaurant() {
return (
<div>
{!state.open && (
{!open && (
<InfoDialog
title={"Dodawanie lokalu"}
text={"Dodawanie lokalu, prosimy o chwilę cierpliwości..."}
loading={true}
text={state.response}
loading={loading}
/>
)}
<Dialog
className={styles.root}
open={state.open}
open={open}
aria-labelledby="newRestaurant-title"
>
<DialogTitle id="newRestaurant-title">Dodaj Lokal</DialogTitle>
@@ -372,7 +408,7 @@ export default function NewRestaurant() {
className={styles.textInputFullWidth}
variant="outlined"
label="Tagi"
placeholder="Dodaj tagi"
placeholder="Wybierz tagi"
/>
)}
/>
@@ -412,16 +448,16 @@ export default function NewRestaurant() {
/>
<TextField
className={styles.textInput}
label="Twitter"
label="Instagram"
variant="outlined"
value={state.twitter}
value={state.instagram}
onChange={(event) =>
setState({ ...state, twitter: event.target.value })
setState({ ...state, instagram: event.target.value })
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<TwitterIcon color="primary" />
<InstagramIcon color="primary" />
</InputAdornment>
),
}}
@@ -456,6 +492,11 @@ export default function NewRestaurant() {
)}
{activeStep === 2 && (
<Paper>
<p>
Kliknij w miejscu, w którym znajduje się Twoja restauracja, by
dodać marker. <br />
Jeżeli lokal znajduje się na mapie - kliknij jego ikonkę.
</p>
<InputGoogleMaps
setCoordinates={(coordinates, placesID) =>
setCoordinatesAndPlacesID(coordinates, placesID)

View File

@@ -0,0 +1,153 @@
import React, { useState } from "react";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogContent from "@material-ui/core/DialogContent";
import Dialog from "@material-ui/core/Dialog";
import Divider from "@material-ui/core/Divider";
import { makeStyles } from "@material-ui/core/styles";
import ButtonSecondary from "../Input/ButtonSecondary";
import ButtonPrimary from "../Input/ButtonPrimary";
import IconButton from "@material-ui/core/IconButton";
import TextField from "@material-ui/core/TextField";
import CloseIcon from "@material-ui/icons/Close";
import { useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
const useStyles = makeStyles((theme) => ({
root: {
textAlign: "center",
"& .MuiPaper-root": {
minWidth: "30%",
backgroundColor: "#262626",
color: "#bbbbbb",
},
},
closeButton: {
color: "#bbbbbb",
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
},
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",
},
},
timePicker: {
margin: theme.spacing(2),
"& .MuiInputBase-root": {
color: "#bbbbbb",
},
"& .MuiInputLabel-root": {
color: "#bbbbbb",
},
},
stepLabel: {
"& .MuiStepLabel-label": {
color: "#bbbbbb",
},
"& .MuiStepLabel-active": {
color: "#bbbbbb",
},
},
}));
export default function Settings() {
const history = useHistory();
const style = useStyles();
const data = useSelector((state) => state.data.userData);
const initialState = {
firstname: data.firstname,
lastname: data.lastname,
email: data.userEmail,
NIP: data.billing.NIP,
adress: data.billing.adress,
companyName: data.billing.companyName,
};
const [state, setState] = useState(initialState);
return (
<Dialog aria-labelledby="settings-title" className={style.root} open={true}>
<DialogTitle id="settings-title">Ustawienia konta</DialogTitle>
<IconButton
className={style.closeButton}
onClick={() => {}}
aria-label="close"
>
<CloseIcon />
</IconButton>
<Divider />
<DialogContent>
<TextField
className={style.textInput}
value={state.firstname}
onChange={(event) =>
setState({ ...state, firstname: event.target.value })
}
label="Imię"
variant="outlined"
/>
<TextField
className={style.textInput}
value={state.lastname}
onChange={(event) =>
setState({ ...state, lastname: event.target.value })
}
label="Nazwisko"
variant="outlined"
/>
<TextField
className={style.textInput}
value={state.email}
onChange={(event) =>
setState({ ...state, email: event.target.value })
}
label="Email"
variant="outlined"
/>
<TextField
className={style.textInput}
value={state.companyName}
onChange={(event) =>
setState({ ...state, companyName: event.target.value })
}
label="Nazwa firmy"
variant="outlined"
/>
<TextField
className={style.textInput}
value={state.NIP}
onChange={(event) => setState({ ...state, NIP: event.target.value })}
label="NIP"
variant="outlined"
/>
<TextField
className={style.textInput}
value={state.adress}
onChange={(event) =>
setState({ ...state, adress: event.target.value })
}
label="Adres firmy"
variant="outlined"
/>
<ButtonPrimary onClick={() => history.push("/")} text="Anuluj" />
<ButtonSecondary text="Zapisz" />
</DialogContent>
</Dialog>
);
}