web client v0.9 (restaurant view)
This commit is contained in:
@@ -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));
|
||||
|
||||
64
src/components/Dialogs/PaymentDialog.js
Normal file
64
src/components/Dialogs/PaymentDialog.js
Normal file
@@ -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 (
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={props.cancel}
|
||||
open={props.open}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Aktywacja subskrypcji</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={props.cancel}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<p>
|
||||
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)
|
||||
</p>
|
||||
<div className="yesno-dialog-buttons">
|
||||
<ButtonPrimary onClick={props.cancel} text="Zamknij" />
|
||||
<ButtonSecondary onClick={props.accept} text="Zapłać" />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -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 (
|
||||
<div className="editRestaurant-tab">
|
||||
<p>Subscription</p>
|
||||
<div className="editSubscription-tab">
|
||||
<PaymentDialog open={state.open} cancel={onCancel} accept={onAccept} />
|
||||
<div className="subscription-text">
|
||||
<h3>Subskrypcja</h3>
|
||||
{subscriptionActive ? (
|
||||
<h5>Aktywna do: {formatDateBasic(subscriptionDue)}</h5>
|
||||
) : (
|
||||
<h5>Nieaktywna</h5>
|
||||
)}
|
||||
</div>
|
||||
{!subscriptionActive && (
|
||||
<div>
|
||||
<div className="subscription-cards">
|
||||
<div className="subscription-card">
|
||||
<h1>1 rok</h1>
|
||||
<Divider style={{ width: "100%" }} />
|
||||
<h2>
|
||||
<strike>600zł</strike> 500zł (netto)
|
||||
</h2>
|
||||
<p>Aktywuj subskrypcję na 12 miesięcy i zapłać mniej.</p>
|
||||
<Divider style={{ width: "100%" }} />
|
||||
<ButtonSecondary
|
||||
text="Aktywuj"
|
||||
onClick={() => handleActivateSubscription(12)}
|
||||
/>
|
||||
</div>
|
||||
<div className="subscription-card">
|
||||
<h1>1 miesiąc</h1>
|
||||
<Divider style={{ width: "100%" }} />
|
||||
<h2>50zł (netto)</h2>
|
||||
<p>Aktywuj subskrypcję na jeden miesiąc.</p>
|
||||
<Divider style={{ width: "100%" }} />
|
||||
<ButtonSecondary
|
||||
text="Aktywuj"
|
||||
onClick={() => handleActivateSubscription(1)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{subscriptionActive && (
|
||||
<p>
|
||||
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"
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<Accordion key={set.id} className={classes.root}>
|
||||
@@ -107,6 +109,7 @@ export default function EditCategoriesList(props) {
|
||||
</Tooltip>
|
||||
</div>
|
||||
</AccordionSummary>
|
||||
<LunchSetDishList lunchSet={set} restaurantId={props.restaurantId} />
|
||||
</Accordion>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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());
|
||||
|
||||
24
src/components/Output/GoogleMapStatic.js
Normal file
24
src/components/Output/GoogleMapStatic.js
Normal file
@@ -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 (
|
||||
<LoadScript googleMapsApiKey="AIzaSyDAlZSiBanP52qpZ1kaH06XkuA2zndLUd8">
|
||||
<GoogleMap mapContainerStyle={containerStyle} center={center} zoom={7}>
|
||||
<Marker position={center} visible={true} />
|
||||
</GoogleMap>
|
||||
</LoadScript>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(GoogleMapStatic);
|
||||
115
src/components/Output/LunchSetDishList.js
Normal file
115
src/components/Output/LunchSetDishList.js
Normal file
@@ -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 (
|
||||
<ListItem key={dish._id}>
|
||||
<div className="editRestaurant-dish">
|
||||
<div className="editRestaurant-dishLeft">
|
||||
<div
|
||||
className="editRestaurant-dishImg"
|
||||
style={
|
||||
dish.imgUrl !== "empty"
|
||||
? { backgroundImage: `url(${dish.imgUrl})` }
|
||||
: { backgroundColor: "#7e7e7e" }
|
||||
}
|
||||
></div>
|
||||
<h3>{dish.name}</h3>
|
||||
</div>
|
||||
<div className="editRestaurant-dishRight">
|
||||
<Tooltip title="Usuń">
|
||||
<IconButton
|
||||
color="primary"
|
||||
component="span"
|
||||
onClick={() => selectDish(dish._id)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<List>
|
||||
<YesNo open={open} cancel={onCancel} accept={onAccept} />
|
||||
{thisSetDishes.length === 0 ? (
|
||||
<ListItem style={{ marginLeft: "14px", fontSize: "12px" }}>
|
||||
Zestaw jest pusty.
|
||||
</ListItem>
|
||||
) : (
|
||||
Dishes
|
||||
)}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
@@ -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 (
|
||||
<div className="restaurant-container">
|
||||
<div className="restaurant-content">
|
||||
<div className="restaurant-left">
|
||||
<div
|
||||
className="restaurant-hero"
|
||||
style={{ backgroundImage: "url(" + restaurant.imgUrl + ")" }}
|
||||
></div>
|
||||
<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>
|
||||
Adres:{" "}
|
||||
<span className="restaurant-span">
|
||||
{restaurant.city}, {restaurant.adress}
|
||||
</span>
|
||||
</p>
|
||||
<p>Godziny pracy: </p>
|
||||
{restaurant.phone && (
|
||||
<p>
|
||||
Kontakt:{" "}
|
||||
@@ -39,6 +51,8 @@ export default function Restaurant(props) {
|
||||
<PictogramsSeparate pictograms={extractTags(restaurant.tags)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="restaurant-content">
|
||||
<div className="restaurant-dishes">
|
||||
<h3>Menu</h3>
|
||||
{showDishList === false && <CircularProgress />}
|
||||
@@ -48,3 +62,9 @@ export default function Restaurant(props) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
/* {restaurant.location !== undefined && (
|
||||
<GoogleMapStatic coordinates={restaurant.location.coordinates} />
|
||||
)} */
|
||||
|
||||
Reference in New Issue
Block a user