diff --git a/src/App.scss b/src/App.scss index 5d95ba1..59352e9 100644 --- a/src/App.scss +++ b/src/App.scss @@ -25,6 +25,12 @@ overflow: auto; } +.clearfix::after { + content: ""; + clear: both; + display: table; +} + .logo { height: 5rem; margin: 16px; diff --git a/src/Services.js b/src/Services.js index da43606..5eb1594 100644 --- a/src/Services.js +++ b/src/Services.js @@ -46,3 +46,8 @@ export const openInNewTab = (url) => { const newWindow = window.open(url, "_blank", "noopener,noreferrer"); if (newWindow) newWindow.opener = null; }; + +export const formatDateBasic = (input) => { + const date = new Date(input); + return date.toLocaleString("pl-PL", { dateStyle: "long" }); +}; diff --git a/src/actions/index.js b/src/actions/index.js index 42416e9..1ba4b02 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -78,7 +78,6 @@ export const fetchRestaurant = (id) => { .then((response) => { dispatch(setRestaurant(response.data)); dispatch(toggles.hideDishes()); - dispatch(push("/restaurant")); dispatch(fetchAllDishes(id)); }) .catch((err) => diff --git a/src/components/Dialogs/EditRestaurant.js b/src/components/Dialogs/EditRestaurant.js index 2417a35..4c7cee9 100644 --- a/src/components/Dialogs/EditRestaurant.js +++ b/src/components/Dialogs/EditRestaurant.js @@ -14,6 +14,7 @@ import RestaurantMenuIcon from "@material-ui/icons/RestaurantMenu"; import AddIcon from "@material-ui/icons/Add"; import Badge from "@material-ui/core/Badge"; import SearchIcon from "@material-ui/icons/Search"; +import { formatDateBasic } from "../../Services.js"; //-------------- import EditRestaurantInfo from "../EditRestaurant/EditRestaurantInfo"; import EditRestaurantLocation from "../EditRestaurant/EditRestaurantLocation"; @@ -66,7 +67,9 @@ export default function EditRestaurant(props) { badgeData.secondaryText = "Nieaktywna"; } else { badgeData.color = "primary"; - badgeData.secondaryText = `Aktywna do: ${restaurant.subscriptionDue}`; + badgeData.secondaryText = `Aktywna do: ${formatDateBasic( + restaurant.subscriptionDue + )}`; } }; dispatch(fetchAllDishes(restaurant._id)); diff --git a/src/components/Dialogs/PaymentDialog.js b/src/components/Dialogs/PaymentDialog.js new file mode 100644 index 0000000..a3062a2 --- /dev/null +++ b/src/components/Dialogs/PaymentDialog.js @@ -0,0 +1,64 @@ +import React from "react"; +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 ButtonPrimary from "../Input/ButtonPrimary"; +import IconButton from "@material-ui/core/IconButton"; +import CloseIcon from "@material-ui/icons/Close"; + +export default function PasswordConfirmation(props) { + const loginStyles = makeStyles((theme) => ({ + root: { + textAlign: "center", + "& .MuiPaper-root": { + backgroundColor: "#262626", + color: "#bbbbbb", + }, + minWidth: "250px", + }, + closeButton: { + color: "#bbbbbb", + position: "absolute", + right: theme.spacing(1), + top: theme.spacing(1), + }, + })); + + const loginClass = loginStyles(); + + return ( + + Aktywacja subskrypcji + + + + + +

+ Płatność została rozpoczęta. Jeżeli chcesz ją zrealizować teraz, + kliknij przycisk "Zapłać" (zostaniesz przekierowany do portalu + Przelewy24). Jeżeli nie masz teraz ochoty zapłacić, na swoim adresie + email znajdziesz ten sam link do płatności oraz fakturę pro-forma. + (Link do płatności jest ważny 7 dni - po upływie tego czasu transakcja + jest automatycznie anulowana) +

+
+ + +
+
+
+ ); +} diff --git a/src/components/EditRestaurant/EditRestaurantSubscription.js b/src/components/EditRestaurant/EditRestaurantSubscription.js index c296558..a6c4bb4 100644 --- a/src/components/EditRestaurant/EditRestaurantSubscription.js +++ b/src/components/EditRestaurant/EditRestaurantSubscription.js @@ -1,9 +1,124 @@ -import React from "react"; +import React, { useState } from "react"; +import ButtonSecondary from "../Input/ButtonSecondary"; +import Divider from "@material-ui/core/Divider"; +import axios from "axios"; +import { useDispatch, useSelector } from "react-redux"; +import { notification, refreshUserData } from "../../actions"; +import { backend } from "../../config.js"; +import { showBackdrop, hideBackdrop } from "../../actions/toggles"; +import PaymentDialog from "../Dialogs/PaymentDialog"; +import { openInNewTab, formatDateBasic } from "../../Services.js"; export default function EditRestaurantSubscription(props) { + const { subscriptionActive, subscriptionDue } = props.restaurant; + const initialState = { + transactionId: "", + open: false, + }; + const [state, setState] = useState(initialState); + const userData = useSelector((state) => state.data.userData); + const token = userData.jwt; + const dispatch = useDispatch(); + + const handleActivateSubscription = (type) => { + const data = { + restaurantId: props.restaurant._id, + userData: { + firstname: userData.firstname, + lastname: userData.lastname, + userId: userData.userId, + userEmail: userData.userEmail, + NIP: userData.billing.NIP, + adress: userData.billing.adress, + companyName: userData.billing.companyName, + }, + type: type, + }; + dispatch(showBackdrop()); + axios({ + method: "POST", + url: backend + "/restaurant/subscription", + data: data, + headers: { + "x-auth-token": token, + }, + }) + .then((response) => { + dispatch(hideBackdrop()); + if (response.status === 200) { + setState({ ...state, open: true }); + } else { + dispatch(notification("Wystąpił błąd, spróbuj ponownie.", "error")); + } + }) + .catch((error) => { + dispatch(hideBackdrop()); + dispatch(notification("Wystąpił błąd, spróbuj ponownie.", "error")); + }); + }; + + const onCancel = () => { + setState({ ...state, open: false }); + }; + + const onAccept = () => { + dispatch(refreshUserData(token)); + openInNewTab("https://secure.przelewy24.pl/trnRequest/0"); + }; + return ( -
-

Subscription

+
+ +
+

Subskrypcja

+ {subscriptionActive ? ( +
Aktywna do: {formatDateBasic(subscriptionDue)}
+ ) : ( +
Nieaktywna
+ )} +
+ {!subscriptionActive && ( +
+
+
+

1 rok

+ +

+ 600zł 500zł (netto) +

+

Aktywuj subskrypcję na 12 miesięcy i zapłać mniej.

+ + handleActivateSubscription(12)} + /> +
+
+

1 miesiąc

+ +

50zł (netto)

+

Aktywuj subskrypcję na jeden miesiąc.

+ + handleActivateSubscription(1)} + /> +
+
+

+ Aktywuj subskrypcję, aby Twoja restauracja była widoczna. Na tydzień + przed końcem subskrypcji wyślemy Ci email z możliwością opłacenia + subskrypcji na kolejny okres. +

+
+ )} + {subscriptionActive && ( +

+ Subskrypcja jest aktywna - Twoja restauracja jest dostępna do + przeglądania dla użytkowników. Jeżeli chcesz żeby restauracja była + niewidoczna, przejdź do zakładki "Informacje" +

+ )}
); } diff --git a/src/components/EditRestaurant/LunchMenu.js b/src/components/EditRestaurant/LunchMenu.js index dfa373e..12de9fb 100644 --- a/src/components/EditRestaurant/LunchMenu.js +++ b/src/components/EditRestaurant/LunchMenu.js @@ -19,6 +19,7 @@ import { notification, refreshUserData } from "../../actions"; import { showBackdrop, hideBackdrop } from "../../actions/toggles.js"; import { backend } from "../../config"; import Tooltip from "@material-ui/core/Tooltip"; +import LunchSetDishList from "../Output/LunchSetDishList"; const useStyles = makeStyles((theme) => ({ root: { @@ -86,6 +87,7 @@ export default function EditCategoriesList(props) { sendForm("delete", selectedSet); setOpen(false); }; + const SetList = props.lunchMenu.map((set) => { return ( @@ -107,6 +109,7 @@ export default function EditCategoriesList(props) {
+ ); }); diff --git a/src/components/Output/EditDishList.js b/src/components/Output/EditDishList.js index 62c856d..9df0abe 100644 --- a/src/components/Output/EditDishList.js +++ b/src/components/Output/EditDishList.js @@ -10,7 +10,7 @@ import Switch from "@material-ui/core/Switch"; import axios from "axios"; import { backend } from "../../config"; import YesNo from "../Dialogs/YesNo"; -import { notification, fetchAllDishes } from "../../actions"; +import { notification, fetchAllDishes, refreshUserData } from "../../actions"; import Tooltip from "@material-ui/core/Tooltip"; import FastfoodIcon from "@material-ui/icons/Fastfood"; import AddToSet from "../Dialogs/AddToSet"; @@ -110,6 +110,7 @@ export default function EditDishList(props) { .then((response) => { dispatch(hideBackdrop()); dispatch(notification("Dodano do zestawu.", "success")); + dispatch(refreshUserData(token)); }) .catch((error) => { dispatch(hideBackdrop()); diff --git a/src/components/Output/GoogleMapStatic.js b/src/components/Output/GoogleMapStatic.js new file mode 100644 index 0000000..907a757 --- /dev/null +++ b/src/components/Output/GoogleMapStatic.js @@ -0,0 +1,24 @@ +import React from "react"; +import { GoogleMap, LoadScript, Marker } from "@react-google-maps/api"; + +function GoogleMapStatic(props) { + const containerStyle = { + width: "50%", + height: "500px", + }; + + const center = { + lat: props.coordinates[0], + lng: props.coordinates[1], + }; + + return ( + + + + + + ); +} + +export default React.memo(GoogleMapStatic); diff --git a/src/components/Output/LunchSetDishList.js b/src/components/Output/LunchSetDishList.js new file mode 100644 index 0000000..370c876 --- /dev/null +++ b/src/components/Output/LunchSetDishList.js @@ -0,0 +1,115 @@ +import React, { useState } from "react"; +import { useSelector, useDispatch } from "react-redux"; +import List from "@material-ui/core/List"; +import ListItem from "@material-ui/core/ListItem"; +import IconButton from "@material-ui/core/IconButton"; +import DeleteIcon from "@material-ui/icons/Delete"; +import axios from "axios"; +import { backend } from "../../config"; +import YesNo from "../Dialogs/YesNo"; +import { notification, refreshUserData } from "../../actions"; +import Tooltip from "@material-ui/core/Tooltip"; +import { hideBackdrop, showBackdrop } from "../../actions/toggles"; + +export default function EditDishList(props) { + const [open, setOpen] = useState(false); + const [selectedDish, setDish] = useState(""); + const dispatch = useDispatch(); + const token = useSelector((state) => state.data.userData.jwt); + + const filterDishes = (dishes, setDishes) => { + let result = []; + dishes.map((dish) => { + if (setDishes.includes(dish._id)) { + result.push(dish); + } + return true; + }); + return result; + }; + + const selectDish = (dishId) => { + setDish(dishId); + setOpen(true); + }; + const onCancel = () => { + setOpen(false); + }; + const onAccept = () => { + setOpen(false); + removeFromSet(); + }; + + const removeFromSet = () => { + const data = { + setName: props.lunchSet.lunchSetName, + restaurantId: props.restaurantId, + dishId: selectedDish, + action: "delete", + }; + dispatch(showBackdrop()); + axios({ + method: "POST", + url: backend + "/restaurant/lunch", + data: data, + headers: { + "x-auth-token": token, + }, + }) + .then((response) => { + dispatch(hideBackdrop()); + dispatch(notification("Zmodyfikowano zestaw.", "success")); + dispatch(refreshUserData(token)); + }) + .catch((error) => { + dispatch(hideBackdrop()); + dispatch(notification("Wystąpił błąd.", "error")); + }); + }; + + const allDishes = useSelector((state) => state.dishes); + const thisSetDishes = filterDishes(allDishes, props.lunchSet.lunchSetDishes); + const Dishes = thisSetDishes.map((dish) => { + return ( + +
+
+
+

{dish.name}

+
+
+ + selectDish(dish._id)} + > + + + +
+
+
+ ); + }); + + return ( + + + {thisSetDishes.length === 0 ? ( + + Zestaw jest pusty. + + ) : ( + Dishes + )} + + ); +} diff --git a/src/components/Output/Restaurant.js b/src/components/Output/Restaurant.js index 891fa1c..9eea5c4 100644 --- a/src/components/Output/Restaurant.js +++ b/src/components/Output/Restaurant.js @@ -1,33 +1,45 @@ -import React from "react"; +import React, { useEffect } from "react"; import PictogramsSeparate from "./PictogramsSeparate"; import DishList from "./DishList"; import CircularProgress from "@material-ui/core/CircularProgress"; +import { useParams } from "react-router-dom"; import { extractTags } from "../../Services"; -import { useSelector } from "react-redux"; +import { useSelector, useDispatch } from "react-redux"; +import { fetchRestaurant } from "../../actions"; +import GoogleMapStatic from "./GoogleMapStatic"; export default function Restaurant(props) { const restaurant = useSelector((state) => state.restaurant); + const { id } = useParams(); + const dispatch = useDispatch(); const showDishList = useSelector((state) => state.data.showDishList); + useEffect(() => { + if (restaurant._id !== id) { + dispatch(fetchRestaurant(id)); + } else { + document.title = restaurant.name; + } + }); + return (
-
+
+
-

{restaurant.name}

{restaurant.description}


- Miejscowość:{" "} - {restaurant.city} -

-

- Godziny pracy:{" "} - {restaurant.workingHours} + Adres:{" "} + + {restaurant.city}, {restaurant.adress} +

+

Godziny pracy:

{restaurant.phone && (

Kontakt:{" "} @@ -39,6 +51,8 @@ export default function Restaurant(props) {

+
+

Menu

{showDishList === false && } @@ -48,3 +62,9 @@ export default function Restaurant(props) {
); } + +// + +/* {restaurant.location !== undefined && ( + +)} */ diff --git a/src/styles/DishList.scss b/src/styles/DishList.scss index 4c8f99f..9d83606 100644 --- a/src/styles/DishList.scss +++ b/src/styles/DishList.scss @@ -32,6 +32,7 @@ h4 { .carddish-img { background-color: $secondary-color; + background-size: cover; width: 150px; height: 150px; border-radius: 10px; diff --git a/src/styles/EditRestaurant.scss b/src/styles/EditRestaurant.scss index 64cfc09..98b92b7 100644 --- a/src/styles/EditRestaurant.scss +++ b/src/styles/EditRestaurant.scss @@ -125,3 +125,62 @@ .editRestaurant-dish:hover { background-color: #3b3b3b; } + +.editSubscription-tab { + padding: 16px; + display: flex; + flex-flow: column; + align-items: center; + width: 100%; + overflow: auto; +} + +.subscription-text { + display: flex; + background-color: #242424; + width: 100%; + justify-content: space-between; + border-radius: 8px; + h3 { + font-weight: 300; + padding-left: 14px; + } + h5 { + color: #c0c0c0; + font-weight: 400; + padding-right: 14px; + font-size: 14px; + } +} + +.subscription-cards { + display: flex; + justify-content: space-around; + margin-top: 18px; +} + +.subscription-card { + background-color: #242424; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + min-width: 260px; + max-width: 300px; + border-radius: 8px; + h1 { + font-weight: 200; + } + h2 { + font-weight: 300; + font-size: 1.2rem; + color: #c0c0c0; + } + p { + font-weight: 400; + font-size: 14px; + padding-left: 16px; + padding-right: 16px; + color: #838383; + } +} diff --git a/src/styles/Footer.scss b/src/styles/Footer.scss index c06f0d5..3454af3 100644 --- a/src/styles/Footer.scss +++ b/src/styles/Footer.scss @@ -2,8 +2,7 @@ position: fixed; bottom: 0; background-color: $dark-gray; - p { - color: white; + color: rgb(180, 180, 180); } } diff --git a/src/styles/Restaurant.scss b/src/styles/Restaurant.scss index 14f7e85..4800b9a 100644 --- a/src/styles/Restaurant.scss +++ b/src/styles/Restaurant.scss @@ -1,15 +1,19 @@ .restaurant-container { - width: 100vw; - height: 100%; + min-width: 70%; + min-height: 600px; + max-height: 80vh; + max-width: 80%; + background-color: $dark-gray; + border-radius: 15px; display: flex; - justify-content: center; - align-items: flex-start; + flex-direction: row; + overflow: auto; h1 { font-weight: 100; color: $gray; background-color: $dark-gray; padding: 15px; - font-size: 3rem; + font-size: 2rem; margin-bottom: 16px; margin-top: 0; } @@ -22,11 +26,16 @@ } } +.restaurant-left { + max-width: 30%; + background-color: #1d1d1d; + height: 100%; +} + .restaurant-hero { width: 100%; - height: 500px; + height: 360px; border-top-left-radius: 15px; - border-top-right-radius: 15px; background-size: cover; } @@ -44,7 +53,7 @@ .restaurant-dishes { min-width: 60%; h3 { - font-size: 1.6rem; + font-size: 1.2rem; font-weight: 400; } } @@ -52,21 +61,18 @@ .restaurant-content { padding-top: 10rem; padding-bottom: 10rem; + width: 100%; display: flex; - justify-content: space-between; + justify-content: center; align-items: flex-start; - min-width: 70%; } .restaurant-info { text-align: center; - max-width: 30%; background-color: #1d1d1d; box-shadow: -2px 10px 20px rgba(0, 0, 0, 0.212); - border-radius: 15px; - p { - font-size: 1rem; + font-size: 0.9rem; font-weight: 300; margin-top: 8px; margin-bottom: 8px; @@ -83,6 +89,6 @@ } .restaurant-span { - font-weight: 500; + font-weight: 400; color: $gray; }