From 732ad74657b9cf57bf344ae86985ca965ea0b621 Mon Sep 17 00:00:00 2001 From: Jonasz Bigda Date: Fri, 18 Sep 2020 18:59:18 +0200 Subject: [PATCH] Add Restaurant almost done --- package-lock.json | 20 ++++++ package.json | 1 + src/App.js | 9 ++- src/components/Dialogs/NewRestaurant.js | 85 +++++++++++++++++++++++-- src/components/Input/ImageUpload.js | 20 +++--- src/components/Input/InputGoogleMaps.js | 47 ++++++++++++++ src/components/Output/InfoDialog.js | 57 +++++++++++++++++ src/components/PrivateRoute.js | 25 ++++++++ 8 files changed, 243 insertions(+), 21 deletions(-) create mode 100644 src/components/Input/InputGoogleMaps.js create mode 100644 src/components/Output/InfoDialog.js create mode 100644 src/components/PrivateRoute.js diff --git a/package-lock.json b/package-lock.json index 87f4dc9..1dbd6d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 84f1acc..fd660c4 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.js b/src/App.js index 6764f00..535630e 100644 --- a/src/App.js +++ b/src/App.js @@ -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) { - - - + } + /> + } /> diff --git a/src/components/Dialogs/NewRestaurant.js b/src/components/Dialogs/NewRestaurant.js index 84532ae..a1ec7c1 100644 --- a/src/components/Dialogs/NewRestaurant.js +++ b/src/components/Dialogs/NewRestaurant.js @@ -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,14 +127,58 @@ export default function NewRestaurant() { // HANDLERS - const handleNextButton = () => { - if (activeStep === 0) { - if (validateForm()) { - setActiveStep(1); - } + 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 = () => { + 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) => { let stringLength = event.target.value.length; let charleft = 400 - stringLength; @@ -168,9 +219,16 @@ export default function NewRestaurant() { return (
+ {!state.open && ( + + )} Dodaj Lokal @@ -390,7 +448,20 @@ export default function NewRestaurant() { {activeStep === 1 && (

Dodaj zdjęcie lokalu.

- + handleImageUploaded(link)} + /> +
+ )} + {activeStep === 2 && ( + + + setCoordinatesAndPlacesID(coordinates, placesID) + } + coordinates={state.coordinates} + /> )} {activeStep !== 0 && ( diff --git a/src/components/Input/ImageUpload.js b/src/components/Input/ImageUpload.js index aaa3a97..e29197c 100644 --- a/src/components/Input/ImageUpload.js +++ b/src/components/Input/ImageUpload.js @@ -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 = ( diff --git a/src/components/Input/InputGoogleMaps.js b/src/components/Input/InputGoogleMaps.js new file mode 100644 index 0000000..1ab4562 --- /dev/null +++ b/src/components/Input/InputGoogleMaps.js @@ -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 ( + + + + + + ); +} + +export default React.memo(InputGoogleMaps); diff --git a/src/components/Output/InfoDialog.js b/src/components/Output/InfoDialog.js new file mode 100644 index 0000000..4768d47 --- /dev/null +++ b/src/components/Output/InfoDialog.js @@ -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 ( + history.push("/")} + open={true} + aria-labelledby="title" + > + {props.title} + history.push("/")} + aria-label="close" + > + + + + +

{props.text}

+ {loading && } + +
+
+ ); +} diff --git a/src/components/PrivateRoute.js b/src/components/PrivateRoute.js new file mode 100644 index 0000000..f48e9d7 --- /dev/null +++ b/src/components/PrivateRoute.js @@ -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 ( + + loggedIn ? ( + component + ) : ( + + ) + } + /> + ); +}