Add Restaurant almost done

This commit is contained in:
2020-09-18 18:59:18 +02:00
parent 1c9d9e2021
commit 732ad74657
8 changed files with 243 additions and 21 deletions

20
package-lock.json generated
View File

@@ -1513,6 +1513,26 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
},
"@react-google-maps/api": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-1.10.1.tgz",
"integrity": "sha512-hb8urUcwZw99Cu3yQnZWUbXjR1Ym/8C21kSX6B02I29l6DXNxDbJ5Jo/T5swhnizPKY7TNhR1oTctC/HY7SQWA==",
"requires": {
"@react-google-maps/infobox": "1.10.0",
"@react-google-maps/marker-clusterer": "1.10.0",
"invariant": "2.2.4"
}
},
"@react-google-maps/infobox": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-1.10.0.tgz",
"integrity": "sha512-MhT2nMmjeG7TCxRv/JdylDyNd/n66ggSQQhTWVjJJTtdB/xqd0T8BHCkBWDN9uF0i0yCZzMFl2P2Y1zJ+xppBg=="
},
"@react-google-maps/marker-clusterer": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-1.10.0.tgz",
"integrity": "sha512-3GLVgeXNStVcdiLMxzi3cBjr32ctlexLPPGQguwcYd6yPLaCcnVCwyzhV68KvL00xqOAD1c3aABV9EGgY8u6Qw=="
},
"@sheerun/mutationobserver-shim": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",

View File

@@ -7,6 +7,7 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.56",
"@material-ui/pickers": "^3.2.10",
"@react-google-maps/api": "^1.10.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",

View File

@@ -1,5 +1,6 @@
import React from "react";
import { Router, Switch, Route } from "react-router-dom";
import PrivateRoute from "./components/PrivateRoute";
import "./App.scss";
import TopBar from "./components/TopBar";
import LogoMain from "./components/Output/logoMain";
@@ -61,9 +62,11 @@ function App(props) {
<Route path="/register">
<RegisterDialog />
</Route>
<Route path="/newRestaurant">
<NewRestaurant />
</Route>
<PrivateRoute
path="/newRestaurant"
component={<NewRestaurant />}
/>
<PrivateRoute path="/newDish" component={<NewRestaurant />} />
<Route path="/forgotpassword">
<ForgotPassword />
</Route>

View File

@@ -17,6 +17,8 @@ import InputAdornment from "@material-ui/core/InputAdornment";
import ImageUpload from "../Input/ImageUpload";
import validator from "validator";
import { useHistory } from "react-router-dom";
import InputGoogleMaps from "../Input/InputGoogleMaps";
import InfoDialog from "../Output/InfoDialog";
// ICONS
import FastfoodIcon from "@material-ui/icons/Fastfood";
import LocationCityIcon from "@material-ui/icons/LocationCity";
@@ -89,6 +91,9 @@ export default function NewRestaurant() {
name: "",
city: "",
adress: "",
coordinates: [52.354293, 19.42377],
placesId: "",
imgURL: "",
hoursFrom: "07:00",
hoursTo: "23:00",
description: "",
@@ -102,6 +107,8 @@ export default function NewRestaurant() {
adressError: false,
descriptionError: false,
charLeft: 400,
open: true,
response: "",
};
const steps = ["Informacje", "Zdjęcie", "Lokalizacja"];
const [state, setState] = useState(initialState);
@@ -120,12 +127,56 @@ export default function NewRestaurant() {
// HANDLERS
const sendForm = () => {
// format tags
const formattedTags;
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,
}
};
const setCoordinatesAndPlacesID = (coordinates, placesID) => {
if (!placesID) {
setState({ ...state, coordinates: coordinates });
} else {
setState({ ...state, coordinates: coordinates, placesId: placesID });
}
};
const handleNextButton = () => {
if (activeStep === 0) {
switch (activeStep) {
case 0:
if (validateForm()) {
setActiveStep(1);
}
break;
case 1:
if (!validator.isEmpty(state.imgURL)) {
setActiveStep(2);
}
break;
case 2:
setState({ ...state, open: false });
sendForm();
break;
default:
break;
}
};
const handleImageUploaded = (link) => {
setState({ ...state, imgURL: link });
};
const handleDescriptionChange = (event) => {
@@ -168,9 +219,16 @@ export default function NewRestaurant() {
return (
<div>
{!state.open && (
<InfoDialog
title={"Dodawanie lokalu"}
text={"Dodawanie lokalu, prosimy o chwilę cierpliwości..."}
loading={true}
/>
)}
<Dialog
className={styles.root}
open={true}
open={state.open}
aria-labelledby="newRestaurant-title"
>
<DialogTitle id="newRestaurant-title">Dodaj Lokal</DialogTitle>
@@ -390,7 +448,20 @@ export default function NewRestaurant() {
{activeStep === 1 && (
<Paper>
<h4>Dodaj zdjęcie lokalu.</h4>
<ImageUpload />
<ImageUpload
img={state.imgURL}
onUpload={(link) => handleImageUploaded(link)}
/>
</Paper>
)}
{activeStep === 2 && (
<Paper>
<InputGoogleMaps
setCoordinates={(coordinates, placesID) =>
setCoordinatesAndPlacesID(coordinates, placesID)
}
coordinates={state.coordinates}
/>
</Paper>
)}
{activeStep !== 0 && (

View File

@@ -1,14 +1,16 @@
import React, { useState } from "react";
import CircularProgress from "@material-ui/core/CircularProgress";
import { useSelector } from "react-redux";
import axios from "axios";
export default function ImageUpload() {
const [imagePreviewURL, setPreviewURL] = useState("");
export default function ImageUpload(props) {
const [imagePreviewURL, setPreviewURL] = useState(props.img);
let showCircle = false;
const token = useSelector((state) => state.data.jwt);
const handleInputChange = (event) => {
let data = new FormData();
data.append("menuiImage", new Blob([event.target.files[0]]));
data.append("menuiImage", event.target.files[0]);
axios({
url: "http://localhost:4000/img",
@@ -17,20 +19,16 @@ export default function ImageUpload() {
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
"x-auth-token": token,
},
})
.then((response) => {
console.log(response);
setPreviewURL(response.data.imgURL);
props.onUpload(response.data.imgURL);
})
.catch((error) => {
console.log(error);
console.log("Wystąpił błąd podczas wgrywania pliku.");
});
let reader = new FileReader();
reader.onloadend = () => {
setPreviewURL(reader.result);
};
reader.readAsDataURL(event.target.files[0]);
};
let imagePreview = (

View File

@@ -0,0 +1,47 @@
import React, { useState } from "react";
import { GoogleMap, LoadScript, Marker } from "@react-google-maps/api";
function InputGoogleMaps(props) {
const containerStyle = {
width: "500px",
height: "500px",
};
const center = {
lat: props.coordinates[0],
lng: props.coordinates[1],
};
const [visibility, setVisibility] = useState(true);
const handleMapClick = (event) => {
const location = {
lat: event.latLng.lat(),
lng: event.latLng.lng(),
};
if (event.placeId) {
setVisibility(false);
props.setCoordinates([location.lat, location.lng], event.placeId);
} else {
setVisibility(true);
props.setCoordinates([location.lat, location.lng]);
}
};
return (
<LoadScript googleMapsApiKey="AIzaSyDAlZSiBanP52qpZ1kaH06XkuA2zndLUd8">
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={7}
onClick={handleMapClick}
>
<Marker
position={{ lat: props.coordinates[0], lng: props.coordinates[1] }}
visible={visibility}
/>
</GoogleMap>
</LoadScript>
);
}
export default React.memo(InputGoogleMaps);

View File

@@ -0,0 +1,57 @@
import React from "react";
import CloseIcon from "@material-ui/icons/Close";
import { makeStyles } from "@material-ui/core/styles";
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 ButtonSecondary from "../Input/ButtonSecondary";
import IconButton from "@material-ui/core/IconButton";
import CircularProgress from "@material-ui/core/CircularProgress";
import { useHistory } from "react-router-dom";
export default function InfoDialog(props) {
const history = useHistory();
const loading = props.loading;
const loginStyles = makeStyles((theme) => ({
root: {
textAlign: "center",
"& .MuiPaper-root": {
backgroundColor: "#262626",
color: "#bbbbbb",
},
},
closeButton: {
color: "#bbbbbb",
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
},
}));
const styles = loginStyles();
return (
<Dialog
className={styles.root}
onClose={() => history.push("/")}
open={true}
aria-labelledby="title"
>
<DialogTitle id="title">{props.title}</DialogTitle>
<IconButton
className={styles.closeButton}
onClick={() => history.push("/")}
aria-label="close"
>
<CloseIcon />
</IconButton>
<Divider />
<DialogContent>
<p>{props.text}</p>
{loading && <CircularProgress />}
<ButtonSecondary onClick={history.push("/")} text="Ok" />
</DialogContent>
</Dialog>
);
}

View File

@@ -0,0 +1,25 @@
import React from "react";
import { useSelector } from "react-redux";
import { Redirect, Route } from "react-router-dom";
export default function PrivateRoute({ component, ...rest }) {
const loggedIn = useSelector((state) => state.data.loggedIn);
return (
<Route
{...rest}
render={({ location }) =>
loggedIn ? (
component
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location },
}}
/>
)
}
/>
);
}