Cleanup / Update
This commit is contained in:
11637
package-lock.json
generated
11637
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -15,15 +15,15 @@
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/jest": "^28.1.6",
|
||||
"@types/node": "^18.0.6",
|
||||
"@types/react": "^17.0.47",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react": "^18.0.29",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"axios": "^0.21.1",
|
||||
"connected-react-router": "^6.8.0",
|
||||
"dotenv": "^16.0.1",
|
||||
"node-sass": "^7.0.1",
|
||||
"node-sass": "^8.0.0",
|
||||
"notistack": "^1.0.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"redux": "^4.0.5",
|
||||
|
||||
28
src/App.js
28
src/App.js
@@ -10,13 +10,9 @@ import Footer from "./components/Output/Footer";
|
||||
import SearchResults from "./components/Output/SearchResults";
|
||||
import Restaurant from "./components/Output/Restaurant";
|
||||
import Dialogs from "./components/Dialogs";
|
||||
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
|
||||
import LoginDialog from "./components/Dialogs/LoginDialog";
|
||||
import { ThemeProvider, createTheme } from "@material-ui/core/styles";
|
||||
import NewRestaurant from "./components/Dialogs/NewRestaurant";
|
||||
import RegisterDialog from "./components/Dialogs/RegisterDialog";
|
||||
import ForgotPassword from "./components/Dialogs/ForgotPassword";
|
||||
import ResetPassword from "./components/Dialogs/ResetPassword";
|
||||
import Contact from "./components/Output/Contact";
|
||||
import Settings from "./components/Dialogs/Settings";
|
||||
import EditRestaurant from "./components/Dialogs/EditRestaurant";
|
||||
import NewDish from "./components/Dialogs/NewDish";
|
||||
@@ -24,9 +20,8 @@ import EditDish from "./components/Dialogs/EditDish";
|
||||
import Dish from "./components/Dialogs/Dish";
|
||||
import HomeScreen from "./components/Output/HomeScreen";
|
||||
import Cookies from "./components/Dialogs/Cookies";
|
||||
import PrivacyPolicy from "./components/Output/PrivacyPolicy"
|
||||
|
||||
const theme = createMuiTheme({
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: "#d68000",
|
||||
@@ -51,7 +46,7 @@ function App(props) {
|
||||
horizontal: "center",
|
||||
}}
|
||||
>
|
||||
<div className="App">
|
||||
<div className="App">
|
||||
<AppBackdrop />
|
||||
<Notifier />
|
||||
<Cookies/>
|
||||
@@ -61,7 +56,7 @@ function App(props) {
|
||||
<Route exact path="/">
|
||||
<HomeScreen/>
|
||||
</Route>
|
||||
<Route path="/results">
|
||||
<Route path="/search/:query">
|
||||
<SearchResults />
|
||||
</Route>
|
||||
<Route path="/restaurant/:id">
|
||||
@@ -74,18 +69,9 @@ function App(props) {
|
||||
<Route path="/dish/:id">
|
||||
<Dish />
|
||||
</Route>
|
||||
<Route path="/login">
|
||||
<LoginDialog />
|
||||
</Route>
|
||||
<Route path="/register">
|
||||
<RegisterDialog />
|
||||
</Route>
|
||||
<Route path="/kontakt">
|
||||
<Contact />
|
||||
</Route>
|
||||
<Route path="/privacy">
|
||||
<PrivacyPolicy />
|
||||
</Route>
|
||||
<PrivateRoute
|
||||
path="/newRestaurant"
|
||||
component={<NewRestaurant />}
|
||||
@@ -96,12 +82,6 @@ function App(props) {
|
||||
component={<EditRestaurant />}
|
||||
/>
|
||||
<PrivateRoute path="/editDish/:id" component={<EditDish />} />
|
||||
<Route path="/forgotpassword">
|
||||
<ForgotPassword />
|
||||
</Route>
|
||||
<Route path="/resetpassword">
|
||||
<ResetPassword />
|
||||
</Route>
|
||||
</Switch>
|
||||
</div>
|
||||
<Dialogs />
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import axios from "axios";
|
||||
import { push } from "connected-react-router";
|
||||
import { backend } from "../config.js";
|
||||
import store from "../index.js";
|
||||
import * as restaurant from "../redux/slices/restaurantSlice";
|
||||
import * as toggle from "../redux/slices/togglesSlice";
|
||||
import * as notifications from "../redux/slices/notificationsSlice";
|
||||
import store from "../redux/store.ts";
|
||||
import * as restaurant from "../redux/slices/restaurantSlice.ts";
|
||||
import * as view from "../redux/slices/viewDataSlice.ts";
|
||||
import * as notifications from "../redux/slices/notificationsSlice.ts";
|
||||
import * as user from "../redux/slices/userSlice.ts";
|
||||
|
||||
axios.defaults.withCredentials = true;
|
||||
|
||||
@@ -13,74 +14,10 @@ axios.interceptors.response.use(
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
return new Promise((resolve) => {
|
||||
if (
|
||||
error.response &&
|
||||
error.response.status === 401 &&
|
||||
error.config &&
|
||||
!error.config.__isRetryRequest
|
||||
) {
|
||||
const response = axios
|
||||
.post(backend + "user/refreshtoken", { withCredentials: true })
|
||||
.then((res) => {
|
||||
const jwt = res.headers["x-auth-token"];
|
||||
store.dispatch(setNewToken(jwt));
|
||||
error.config.__isRetryRequest = true;
|
||||
error.config.headers["x-auth-token"] = jwt;
|
||||
return axios(error.config);
|
||||
});
|
||||
resolve(response);
|
||||
} else {
|
||||
if (error.response && error.response.status === 403) {
|
||||
store.dispatch(
|
||||
logout("Podany użytkownik, lub hasło nie istnieje.", "error")
|
||||
);
|
||||
} else if (error.response && error.response.status === 400) {
|
||||
store.dispatch(logout("Dane nieprawidłowe.", "error"));
|
||||
} else {
|
||||
store.dispatch(logout("Sesja wygasła", "info"));
|
||||
}
|
||||
}
|
||||
});
|
||||
store.dispatch(notification("Wystąpił błąd, przepraszamy.", "error"));
|
||||
}
|
||||
);
|
||||
|
||||
const autocomplete = (input) => {
|
||||
return {
|
||||
type: "AUTOCOMPLETE_ADD",
|
||||
payload: input,
|
||||
};
|
||||
};
|
||||
|
||||
export const clearAutocomplete = () => {
|
||||
return {
|
||||
type: "AUTOCOMPLETE_CLEAR",
|
||||
};
|
||||
};
|
||||
|
||||
export const setNewToken = (token) => {
|
||||
return {
|
||||
type: "SET_NEW_TOKEN",
|
||||
payload: token,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAutocomplete = (input) => {
|
||||
return function (dispatch) {
|
||||
axios
|
||||
.get(backend + "search/autocomplete?string=" + encodeURI(input))
|
||||
.then((response) => {
|
||||
const cities = Array.from(response.data.cities);
|
||||
const restaurants = Array.from(response.data.restaurants);
|
||||
const options = cities.concat(restaurants);
|
||||
dispatch(autocomplete(options));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchSearch = (input) => {
|
||||
return function (dispatch) {
|
||||
axios
|
||||
@@ -88,7 +25,7 @@ export const fetchSearch = (input) => {
|
||||
.then((response) => {
|
||||
const data = response.data;
|
||||
if (Object.keys(data).length > 0) {
|
||||
dispatch(setSearchResults(data));
|
||||
dispatch(view.setSearchResults(data));
|
||||
dispatch(push("/results"));
|
||||
}
|
||||
})
|
||||
@@ -98,27 +35,12 @@ export const fetchSearch = (input) => {
|
||||
};
|
||||
};
|
||||
|
||||
const setSearchResults = (input) => {
|
||||
return {
|
||||
type: "SEARCH_RESULTS",
|
||||
payload: input,
|
||||
};
|
||||
};
|
||||
|
||||
export const setSearchQuery = (input) => {
|
||||
return {
|
||||
type: "SEARCH_QUERY_SET",
|
||||
payload: input,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchRestaurant = (id) => {
|
||||
return function (dispatch) {
|
||||
axios
|
||||
.get(backend + "restaurant?restaurantId=" + id)
|
||||
.then((response) => {
|
||||
dispatch(restaurant.setRestaurant(response.data));
|
||||
dispatch(toggle.hideDishes());
|
||||
dispatch(fetchAllDishes(id));
|
||||
})
|
||||
.catch((err) =>
|
||||
@@ -127,27 +49,12 @@ export const fetchRestaurant = (id) => {
|
||||
};
|
||||
};
|
||||
|
||||
const setDishes = (data) => {
|
||||
return {
|
||||
type: "SET_DISHES",
|
||||
payload: data,
|
||||
};
|
||||
};
|
||||
|
||||
const setDish = (data) => {
|
||||
return {
|
||||
type: "SET_DISH",
|
||||
payload: data,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAllDishes = (id) => {
|
||||
return function (dispatch) {
|
||||
axios
|
||||
.get(backend + "restaurant/dishes?restaurantId=" + id)
|
||||
.then((response) => {
|
||||
dispatch(setDishes(response.data));
|
||||
dispatch(toggle.showDishes());
|
||||
dispatch(view.setDishes(response.data));
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -157,43 +64,30 @@ export const fetchDish = (id) => {
|
||||
axios
|
||||
.get(backend + "dish/?dishId=" + id)
|
||||
.then((response) => {
|
||||
dispatch(setDish(response.data));
|
||||
//dispatch(setDish(response.data));
|
||||
})
|
||||
.catch((err) => {
|
||||
dispatch(notification("Nie udało się pobrać :(", "error"));
|
||||
dispatch(push("/"));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const refreshUserData = () => {
|
||||
return function (dispatch) {
|
||||
const state = store.getState();
|
||||
axios({
|
||||
url: backend + "user/refresh",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"x-auth-token": state.data.userData.jwt,
|
||||
"x-auth-token": "",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
dispatch(
|
||||
toggle.setLoggedIn(
|
||||
response.data.firstname,
|
||||
response.data.lastname,
|
||||
state.data.userData.jwt,
|
||||
response.data.id,
|
||||
response.data.email,
|
||||
response.data.NIP,
|
||||
response.data.adress,
|
||||
response.data.companyName,
|
||||
response.data.restaurants
|
||||
)
|
||||
);
|
||||
console.log(response.data);
|
||||
dispatch(user.setUserData(response.data));
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.status === 401 || err.status === 500) {
|
||||
dispatch(logout());
|
||||
dispatch(notification("Nie udało się pobrać danych.", "error"));
|
||||
}
|
||||
console.log(err);
|
||||
});
|
||||
@@ -203,7 +97,7 @@ export const refreshUserData = () => {
|
||||
export const notification = (message, type) => {
|
||||
return function (dispatch) {
|
||||
dispatch(
|
||||
toggle.enqueueSnackbar({
|
||||
notifications.addNotification({
|
||||
message: message,
|
||||
options: {
|
||||
key: new Date().getTime() + Math.random(),
|
||||
@@ -213,24 +107,3 @@ export const notification = (message, type) => {
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const updateRestaurant = (restaurant) => {
|
||||
return {
|
||||
type: "UPDATE_RESTAURANT",
|
||||
payload: restaurant,
|
||||
};
|
||||
};
|
||||
|
||||
export const setTags = (tags) => {
|
||||
return {
|
||||
type: "SET_TAGS",
|
||||
payload: tags,
|
||||
};
|
||||
};
|
||||
|
||||
export const setTypes = (types) => {
|
||||
return {
|
||||
type: "SET_TYPES",
|
||||
payload: types,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
export const setLoggedIn = (
|
||||
firstname,
|
||||
lastname,
|
||||
jwt,
|
||||
userId,
|
||||
email,
|
||||
login,
|
||||
NIP,
|
||||
adress,
|
||||
companyName,
|
||||
restaurants,
|
||||
isRestaurant
|
||||
) => {
|
||||
return {
|
||||
type: "SET_LOGGEDIN",
|
||||
payload: {
|
||||
firstname: firstname,
|
||||
lastname: lastname,
|
||||
jwt: jwt,
|
||||
userId: userId,
|
||||
email: email,
|
||||
login: login,
|
||||
NIP: NIP,
|
||||
adress: adress,
|
||||
companyName: companyName,
|
||||
restaurants: restaurants,
|
||||
isRestaurant: isRestaurant,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const setLoggedOut = () => {
|
||||
return {
|
||||
type: "SET_LOGGEDOUT",
|
||||
};
|
||||
};
|
||||
|
||||
export const enqueueSnackbar = (notification) => {
|
||||
const key = notification.options && notification.options.key;
|
||||
|
||||
return {
|
||||
type: "ENQUEUE_SNACKBAR",
|
||||
notification: {
|
||||
...notification,
|
||||
key: key || new Date().getTime() + Math.random(),
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,116 +0,0 @@
|
||||
import React, { useState } 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 IconButton from "@material-ui/core/IconButton";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import ListItemText from "@material-ui/core/ListItemText";
|
||||
import AddIcon from '@material-ui/icons/Add';
|
||||
import RemoveIcon from '@material-ui/icons/Remove';
|
||||
import ButtonPrimary from "../Input/ButtonPrimary";
|
||||
import ButtonSecondary from "../Input/ButtonSecondary";
|
||||
|
||||
export default function AddToSet(props) {
|
||||
const [quantity, setQuantity] = useState(1);
|
||||
const [selectedSet, setName] = useState("");
|
||||
const loginStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
textAlign: "center",
|
||||
"& .MuiPaper-root": {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
minWidth: "360px",
|
||||
borderRadius: "24px"
|
||||
},
|
||||
zIndex: "5 !important"
|
||||
},
|
||||
closeButton: {
|
||||
color: "#bbbbbb",
|
||||
position: "absolute",
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(1),
|
||||
},
|
||||
set: {
|
||||
width: "100%",
|
||||
"& .Mui-selected": {
|
||||
backgroundColor: "#b46c00",
|
||||
},
|
||||
"& .MuiListItem-root": {
|
||||
borderRadius: "12px"
|
||||
}
|
||||
},
|
||||
quantity: {
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center"
|
||||
},
|
||||
h4: {
|
||||
margin: "12px auto 12px auto"
|
||||
}
|
||||
}));
|
||||
|
||||
const loginClass = loginStyles();
|
||||
|
||||
const Sets = props.lunchMenu.map((lunchSet) => {
|
||||
return (
|
||||
<ListItem
|
||||
button
|
||||
key={lunchSet.lunchSetName}
|
||||
onClick={() => setName(lunchSet.lunchSetName)}
|
||||
selected={selectedSet === lunchSet.lunchSetName}
|
||||
>
|
||||
<ListItemText primary={lunchSet.lunchSetName} />
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
|
||||
const increment = () => {
|
||||
setQuantity(quantity + 1);
|
||||
}
|
||||
|
||||
const decrement = () => {
|
||||
if(quantity > 1){
|
||||
setQuantity(quantity - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={props.cancel}
|
||||
open={props.open}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Dodaj do zestawu</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={props.cancel}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<h4 className={loginClass.h4}>Ilość</h4>
|
||||
<div className={loginClass.quantity}>
|
||||
<IconButton onClick={decrement}>
|
||||
<RemoveIcon/>
|
||||
</IconButton>
|
||||
<h3>{quantity}</h3>
|
||||
<IconButton onClick={increment}>
|
||||
<AddIcon/>
|
||||
</IconButton>
|
||||
</div>
|
||||
<h4 className={loginClass.h4}>Zestaw</h4>
|
||||
<List className={loginClass.set}>{Sets}</List>
|
||||
<Divider />
|
||||
<ButtonPrimary text="Anuluj" onClick={() => props.cancel()}/>
|
||||
<ButtonSecondary disabled={!(selectedSet.length > 0)} text="Dodaj" onClick={() => props.add(selectedSet, quantity)}/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import FitnessCenterIcon from "@material-ui/icons/FitnessCenter";
|
||||
import LocalHospitalIcon from "@material-ui/icons/LocalHospital";
|
||||
import FavoriteBorderIcon from "@material-ui/icons/FavoriteBorder";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import Checkboxes from "../Input/Checkboxes";
|
||||
|
||||
@@ -35,7 +35,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
},
|
||||
},
|
||||
secondary: {
|
||||
"& .MuiListItemText-secondary": {
|
||||
"& .MuiListItemText-secondary": {
|
||||
color: "#868686",
|
||||
fontSize: "13px",
|
||||
},
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
import React, { useState, useEffect } 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 IconButton from "@material-ui/core/IconButton";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { useDispatch } from "react-redux";
|
||||
import Link from "@material-ui/core/Link";
|
||||
import validator from "validator";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import AccountCircle from "@material-ui/icons/AccountCircle";
|
||||
import { remindPassword, notification } from "../../actions";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
export default function ForgotPassword(props) {
|
||||
useEffect(() => {
|
||||
document.title = "Menui - Odzyskiwanie hasła";
|
||||
});
|
||||
const initialData = {
|
||||
email: "",
|
||||
emailError: false,
|
||||
};
|
||||
const [data, setData] = useState(initialData);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
|
||||
const loginStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
zIndex: "5 !important",
|
||||
textAlign: "center",
|
||||
"& .MuiPaper-root": {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "24px"
|
||||
},
|
||||
},
|
||||
closeButton: {
|
||||
color: "#bbbbbb",
|
||||
position: "absolute",
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(1),
|
||||
},
|
||||
textInput: {
|
||||
marginTop: "20px",
|
||||
marginBottom: "10px",
|
||||
width: "90%",
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#01c3a9",
|
||||
borderRadius: "14px"
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
link: {
|
||||
fontSize: "0.9rem",
|
||||
},
|
||||
}));
|
||||
|
||||
const loginClass = loginStyles();
|
||||
|
||||
const validateLogin = () => {
|
||||
var valid;
|
||||
var validation = {
|
||||
email: validator.isEmail(data.email),
|
||||
};
|
||||
setData({
|
||||
...data,
|
||||
emailError: !validation.email,
|
||||
});
|
||||
valid = validation.email;
|
||||
return valid;
|
||||
};
|
||||
|
||||
const handleRemind = () => {
|
||||
if (validateLogin()) {
|
||||
dispatch(remindPassword(data.email));
|
||||
} else {
|
||||
dispatch(notification("Podaj poprawne dane.", "error"));
|
||||
}
|
||||
};
|
||||
|
||||
// CODE
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={() => history.push("/")}
|
||||
open={true}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Odzyskiwanie hasła</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={() => history.push("/")}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<p>
|
||||
Podaj adres email do swojego konta. Link do zmiany hasła powinien
|
||||
dotrzeć do Ciebie w ciągu maksymalnie 15 minut (sprawdź również
|
||||
folder SPAM). Jeśli nie pamiętasz również adresu email, skontaktuj
|
||||
się z obsługą klienta.
|
||||
</p>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="email"
|
||||
label="Email"
|
||||
type="email"
|
||||
variant="outlined"
|
||||
error={data.emailError}
|
||||
onChange={(event) => (data.email = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className="login-dialog-buttons">
|
||||
<ButtonSecondary
|
||||
onClick={() => handleRemind()}
|
||||
text="Wyślij email"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
Nie masz konta?{" "}
|
||||
<span>
|
||||
<Link href="#" onClick={() => history.push("/register")}>
|
||||
Zarejestruj się.
|
||||
</Link>
|
||||
</span>
|
||||
</p>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
import React, { useState, useEffect } 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 IconButton from "@material-ui/core/IconButton";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { useDispatch } from "react-redux";
|
||||
import Link from "@material-ui/core/Link";
|
||||
import LockIcon from "@material-ui/icons/Lock";
|
||||
import validator from "validator";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import AccountCircle from "@material-ui/icons/AccountCircle";
|
||||
import { tryLogin, notification } from "../../actions";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
export default function LoginDialog(props) {
|
||||
useEffect(() => {
|
||||
document.title = "Menui - Logowanie";
|
||||
});
|
||||
const initialData = {
|
||||
email: "",
|
||||
password: "",
|
||||
emailError: false,
|
||||
passwordError: false,
|
||||
};
|
||||
const [loginData, setLoginData] = useState(initialData);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
|
||||
const loginStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
textAlign: "center",
|
||||
"& .MuiPaper-root": {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "24px"
|
||||
},
|
||||
zIndex: "5 !important"
|
||||
},
|
||||
closeButton: {
|
||||
color: "#bbbbbb",
|
||||
position: "absolute",
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(1),
|
||||
},
|
||||
textInput: {
|
||||
marginTop: "20px",
|
||||
marginBottom: "10px",
|
||||
width: "90%",
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#01c3a9",
|
||||
borderRadius: "14px"
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
link: {
|
||||
fontSize: "0.9rem",
|
||||
},
|
||||
}));
|
||||
|
||||
const loginClass = loginStyles();
|
||||
|
||||
const validateLogin = () => {
|
||||
var valid;
|
||||
var validation = {
|
||||
email: validator.isEmail(loginData.email),
|
||||
password: !validator.isEmpty(loginData.password),
|
||||
};
|
||||
setLoginData({
|
||||
...loginData,
|
||||
emailError: !validation.email,
|
||||
passwordError: !validation.password,
|
||||
});
|
||||
valid = validation.email && validation.password;
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
||||
const handleLogin = () => {
|
||||
if (validateLogin()) {
|
||||
dispatch(tryLogin(loginData.email, loginData.password));
|
||||
} else {
|
||||
dispatch(notification("Podaj poprawne dane logowania.", "error"));
|
||||
}
|
||||
};
|
||||
|
||||
// CODE
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={() => history.push("/")}
|
||||
open={true}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Logowanie</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={() => history.push("/")}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="email"
|
||||
label="Email"
|
||||
type="email"
|
||||
variant="outlined"
|
||||
error={loginData.emailError}
|
||||
onChange={(event) => (loginData.email = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="password"
|
||||
label="Hasło"
|
||||
type="password"
|
||||
variant="outlined"
|
||||
error={loginData.passwordError}
|
||||
onChange={(event) => (loginData.password = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<LockIcon color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className="login-dialog-buttons">
|
||||
<ButtonSecondary onClick={() => handleLogin()} text="Zaloguj" />
|
||||
</div>
|
||||
<Link
|
||||
className={loginClass.link}
|
||||
href="#"
|
||||
onClick={() => history.push("/forgotpassword")}
|
||||
>
|
||||
Nie pamiętam hasła.
|
||||
</Link>
|
||||
<p>
|
||||
Nie masz konta?{" "}
|
||||
<span>
|
||||
<Link href="#" onClick={() => history.push("/register")}>
|
||||
Zarejestruj się.
|
||||
</Link>
|
||||
</span>
|
||||
</p>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import { useHistory, useParams } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import Checkboxes from "../Input/Checkboxes";
|
||||
|
||||
@@ -22,9 +22,8 @@ import { prepareTags } from "../../Services.js";
|
||||
import axios from "axios";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import InputWorkingHours from "../Input/InputWorkingHours";
|
||||
import InputLunchMenuHours from "../Input/InputLunchMenuHours";
|
||||
import { backend, restaurantTypes } from "../../config";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import React, { useState } 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 IconButton from "@material-ui/core/IconButton";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import LockIcon from "@material-ui/icons/Lock";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
|
||||
export default function PasswordConfirmation(props) {
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const loginStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
zIndex: "5 !important",
|
||||
textAlign: "center",
|
||||
"& .MuiPaper-root": {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
closeButton: {
|
||||
color: "#bbbbbb",
|
||||
position: "absolute",
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(1),
|
||||
},
|
||||
textInput: {
|
||||
marginTop: "20px",
|
||||
marginBottom: "10px",
|
||||
width: "90%",
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#01c3a9",
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const loginClass = loginStyles();
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={props.onCancel}
|
||||
open={props.open}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Potwierdź hasłem</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={props.onCancel}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
id="password"
|
||||
label="Hasło"
|
||||
type="password"
|
||||
value={password}
|
||||
variant="outlined"
|
||||
onChange={(event) => setPassword(event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<LockIcon color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className="login-dialog-buttons">
|
||||
<ButtonSecondary
|
||||
onClick={() => props.onSubmit(password)}
|
||||
text="Potwierdź"
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -9,8 +9,6 @@ import IconButton from "@material-ui/core/IconButton";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { showRegulamin } from "../../actions/toggles";
|
||||
import { tryRegister, notification } from "../../actions";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import AccountCircle from "@material-ui/icons/AccountCircle";
|
||||
import BusinessIcon from "@material-ui/icons/Business";
|
||||
|
||||
@@ -9,7 +9,7 @@ import CloseIcon from "@material-ui/icons/Close";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Regulamin from "./Regulamin";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { hideRegulamin } from "../../actions/toggles";
|
||||
//import { hideRegulamin } from "../../actions/toggles";
|
||||
|
||||
export default function RegulaminDialog(props) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
import React, { useState, useEffect } 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 IconButton from "@material-ui/core/IconButton";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { useDispatch } from "react-redux";
|
||||
import validator from "validator";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import AccountCircle from "@material-ui/icons/AccountCircle";
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import { changePassword, notification } from "../../actions/index";
|
||||
|
||||
function useQuery() {
|
||||
return new URLSearchParams(useLocation().search);
|
||||
}
|
||||
|
||||
export default function ResetPassword(props) {
|
||||
useEffect(() => {
|
||||
document.title = "Menui - Resetowanie hasła";
|
||||
});
|
||||
const initialData = {
|
||||
email: "",
|
||||
emailError: false,
|
||||
password: "",
|
||||
passwordError: false,
|
||||
passwordRepeat: "",
|
||||
passwordRepeatError: false,
|
||||
};
|
||||
const [data, setData] = useState(initialData);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const query = useQuery();
|
||||
const token = query.get("token");
|
||||
|
||||
const loginStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
zIndex: "5 !important",
|
||||
textAlign: "center",
|
||||
"& .MuiPaper-root": {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
closeButton: {
|
||||
color: "#bbbbbb",
|
||||
position: "absolute",
|
||||
right: theme.spacing(1),
|
||||
top: theme.spacing(1),
|
||||
},
|
||||
textInput: {
|
||||
marginTop: "20px",
|
||||
marginBottom: "10px",
|
||||
width: "90%",
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#01c3a9",
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
link: {
|
||||
fontSize: "0.9rem",
|
||||
},
|
||||
}));
|
||||
|
||||
const loginClass = loginStyles();
|
||||
|
||||
const validateLogin = () => {
|
||||
var valid;
|
||||
var validation = {
|
||||
email: validator.isEmail(data.email),
|
||||
password: validator.isLength(data.password, { min: 6 }),
|
||||
passwordRepeat: data.passwordRepeat === data.password,
|
||||
};
|
||||
setData({
|
||||
...data,
|
||||
emailError: !validation.email,
|
||||
passwordError: !validation.password,
|
||||
passwordRepeatError: !validation.passwordRepeat,
|
||||
});
|
||||
valid =
|
||||
validation.password && validation.passwordRepeat && validation.email;
|
||||
return valid;
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
if (validateLogin()) {
|
||||
dispatch(changePassword(data.email, data.password, token));
|
||||
} else {
|
||||
dispatch(notification("Popraw dane.", "error"));
|
||||
}
|
||||
};
|
||||
|
||||
// CODE
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
className={loginClass.root}
|
||||
onClose={() => history.push("/")}
|
||||
open={true}
|
||||
aria-labelledby="login-title"
|
||||
>
|
||||
<DialogTitle id="login-title">Ustaw nowe hasło</DialogTitle>
|
||||
<IconButton
|
||||
className={loginClass.closeButton}
|
||||
onClick={() => history.push("/")}
|
||||
aria-label="close"
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Divider />
|
||||
<DialogContent>
|
||||
<p>Podaj nowe bezpieczne hasło do konta.</p>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="email"
|
||||
label="Email"
|
||||
type="email"
|
||||
variant="outlined"
|
||||
error={data.emailError}
|
||||
onChange={(event) => (data.email = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="password"
|
||||
label="Nowe hasło"
|
||||
type="password"
|
||||
variant="outlined"
|
||||
error={data.passwordError}
|
||||
onChange={(event) => (data.password = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
className={loginClass.textInput}
|
||||
required
|
||||
id="passwordRepeat"
|
||||
label="Powtórz nowe hasło"
|
||||
type="password"
|
||||
variant="outlined"
|
||||
error={data.passwordRepeatError}
|
||||
onChange={(event) => (data.passwordRepeat = event.target.value)}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AccountCircle color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div className="login-dialog-buttons">
|
||||
<ButtonSecondary onClick={() => handleReset()} text="Zmień hasło" />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -17,25 +17,24 @@ import Divider from "@material-ui/core/Divider";
|
||||
import { decodeTags } from "../../Services";
|
||||
import validator from "validator";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { notification, refreshUserData, updateRestaurant } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { updateRestaurant } from "../../redux/slices/userSlice.ts";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import { prepareTags } from "../../Services.js";
|
||||
import axios from "axios";
|
||||
import PasswordConfirmation from "../Dialogs/PasswordConfirmation";
|
||||
import { backend, restaurantTypes } from "../../config";
|
||||
import InputLunchMenuHours from "../Input/InputLunchMenuHours";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import FormControl from "@material-ui/core/FormControl";
|
||||
import Select from "@material-ui/core/Select";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import Switch from "@material-ui/core/Switch";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
textInput: {
|
||||
margin: theme.spacing(2),
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
borderRadius: "14px",
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
@@ -46,7 +45,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
marginBottom: theme.spacing(2),
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
borderRadius: "14px",
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
@@ -65,7 +64,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
maxHeight: 400,
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
borderRadius: "14px",
|
||||
},
|
||||
"$ .MuiSelect-root": {
|
||||
color: "#bbbbbb",
|
||||
@@ -102,7 +101,7 @@ export default function EditRestaurantInfo(props) {
|
||||
cityError: false,
|
||||
adressError: false,
|
||||
descriptionError: false,
|
||||
typeError: false
|
||||
typeError: false,
|
||||
};
|
||||
const [state, setState] = useState(initialState);
|
||||
const [passwordDialog, setPasswordDialog] = useState(false);
|
||||
@@ -113,10 +112,20 @@ export default function EditRestaurantInfo(props) {
|
||||
const handleDescriptionChange = (event) => {
|
||||
const stringLength = event.target.value.length;
|
||||
const charleft = 400 - stringLength;
|
||||
if(stringLength <= 400){
|
||||
setState({ ...state, description: event.target.value, charleft: charleft, descriptionError: false });
|
||||
if (stringLength <= 400) {
|
||||
setState({
|
||||
...state,
|
||||
description: event.target.value,
|
||||
charleft: charleft,
|
||||
descriptionError: false,
|
||||
});
|
||||
} else {
|
||||
setState({ ...state, description: event.target.value, charleft: charleft, descriptionError: true });
|
||||
setState({
|
||||
...state,
|
||||
description: event.target.value,
|
||||
charleft: charleft,
|
||||
descriptionError: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
const availableTags = [
|
||||
@@ -159,7 +168,11 @@ export default function EditRestaurantInfo(props) {
|
||||
};
|
||||
|
||||
const availableTypes = restaurantTypes.map((type) => {
|
||||
return <MenuItem key={type} value={type}>{type}</MenuItem>
|
||||
return (
|
||||
<MenuItem key={type} value={type}>
|
||||
{type}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
|
||||
const cancelChanges = () => {
|
||||
@@ -173,7 +186,7 @@ export default function EditRestaurantInfo(props) {
|
||||
method: "POST",
|
||||
data: {
|
||||
restaurantId: props.restaurant._id,
|
||||
visible: state.hidden
|
||||
visible: state.hidden,
|
||||
},
|
||||
headers: {
|
||||
"x-auth-token": jwt,
|
||||
@@ -191,7 +204,7 @@ export default function EditRestaurantInfo(props) {
|
||||
dispatch(notification("Wystąpił błąd :(", "error"));
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (password) => {
|
||||
dispatch(showBackdrop());
|
||||
@@ -223,7 +236,7 @@ export default function EditRestaurantInfo(props) {
|
||||
|
||||
const setLunchHours = (hours) => {
|
||||
setState({ ...state, lunchHours: hours });
|
||||
}
|
||||
};
|
||||
|
||||
const handleSendForm = () => {
|
||||
if (validateForm()) {
|
||||
@@ -305,23 +318,25 @@ export default function EditRestaurantInfo(props) {
|
||||
/>
|
||||
</div>
|
||||
<div className="editRestaurant-fullWidth">
|
||||
<FormControl
|
||||
variant="outlined"
|
||||
required
|
||||
fullWidth
|
||||
className={styles.formControl}
|
||||
>
|
||||
<InputLabel id="category-select">Kuchnia</InputLabel>
|
||||
<Select
|
||||
labelId="category-select"
|
||||
id="category"
|
||||
value={state.type}
|
||||
required
|
||||
onChange={(event) => setState({ ...state, type: event.target.value })}
|
||||
>
|
||||
{availableTypes}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
variant="outlined"
|
||||
required
|
||||
fullWidth
|
||||
className={styles.formControl}
|
||||
>
|
||||
<InputLabel id="category-select">Kuchnia</InputLabel>
|
||||
<Select
|
||||
labelId="category-select"
|
||||
id="category"
|
||||
value={state.type}
|
||||
required
|
||||
onChange={(event) =>
|
||||
setState({ ...state, type: event.target.value })
|
||||
}
|
||||
>
|
||||
{availableTypes}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
<TextField
|
||||
className={styles.textInput}
|
||||
@@ -491,13 +506,18 @@ export default function EditRestaurantInfo(props) {
|
||||
<Divider />
|
||||
<div className="editRestaurant-settings">
|
||||
<h4>Ukryj restaurację (nie wymaga zatwierdzania)</h4>
|
||||
<Switch checked={state.hidden} color="primary" onChange={handleSetHidden}/>
|
||||
<Switch
|
||||
checked={state.hidden}
|
||||
color="primary"
|
||||
onChange={handleSetHidden}
|
||||
/>
|
||||
</div>
|
||||
<div className="editRestaurant-settings">
|
||||
<h4>
|
||||
Usuń restaurację (operacja jest nieodwracalna!)
|
||||
</h4>
|
||||
<ButtonPrimary text="Usuń" onClick={() => setPasswordDialog(true)} />
|
||||
<h4>Usuń restaurację (operacja jest nieodwracalna!)</h4>
|
||||
<ButtonPrimary
|
||||
text="Usuń"
|
||||
onClick={() => setPasswordDialog(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import InputGoogleMaps from "../Input/InputGoogleMaps";
|
||||
import ButtonSecondary from "../Input/ButtonSecondary";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { notification } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import axios from "axios";
|
||||
import { backend } from "../../config";
|
||||
|
||||
|
||||
@@ -10,11 +10,10 @@ import { makeStyles } from "@material-ui/core/styles";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import TextFieldsIcon from "@material-ui/icons/TextFields";
|
||||
import validator from "validator";
|
||||
import LunchMenu from "./LunchMenu";
|
||||
import axios from "axios";
|
||||
import EditCategoriesList from "../Output/EditCategoriesList";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
//import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import { backend } from "../../config";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
@@ -145,11 +144,6 @@ export default function EditRestaurantMenu(props) {
|
||||
<ButtonSecondary onClick={addCategory} text="Dodaj" />
|
||||
</div>
|
||||
</Accordion>
|
||||
<div className="editRestaurant-sectiontitle">
|
||||
<h4>Lunch menu</h4>
|
||||
<Divider />
|
||||
</div>
|
||||
<LunchMenu restaurantId={props.restaurant._id} lunchMenu={lunchMenu} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import ImageUploadWide from "../Input/ImageUploadWide";
|
||||
import ButtonSecondary from "../Input/ButtonSecondary";
|
||||
import ButtonPrimary from "../Input/ButtonPrimary";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../actions/toggles.js";
|
||||
//import { notification, refreshUserData } from "../../actions";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
import axios from "axios";
|
||||
import { backend } from "../../config";
|
||||
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Accordion from "@material-ui/core/Accordion";
|
||||
import AccordionSummary from "@material-ui/core/AccordionSummary";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import YesNo from "../Dialogs/YesNo";
|
||||
import ButtonSecondary from "../Input/ButtonSecondary";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import AddIcon from "@material-ui/icons/Add";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import AttachMoneyIcon from "@material-ui/icons/AttachMoney";
|
||||
import TextFieldsIcon from "@material-ui/icons/TextFields";
|
||||
import axios from "axios";
|
||||
import validator from "validator";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
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: {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
width: "100%",
|
||||
maxWidth: "800px",
|
||||
},
|
||||
expandIcon: {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
textInput: {
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
"$ .MuiFormHelperText-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
textInputWide: {
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2),
|
||||
marginRight: theme.spacing(1),
|
||||
marginLeft: theme.spacing(2),
|
||||
flexGrow: 5,
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
"$ .MuiFormHelperText-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default function EditCategoriesList(props) {
|
||||
const dispatch = useDispatch();
|
||||
const [open, setOpen] = useState(false);
|
||||
const initialSet = {
|
||||
lunchSetName: "",
|
||||
lunchSetPrice: "",
|
||||
lunchSetDishes: [],
|
||||
nameError: false,
|
||||
priceError: false,
|
||||
};
|
||||
const [newSet, setNewSet] = useState(initialSet);
|
||||
const [selectedSet, setSelectedSet] = useState(initialSet);
|
||||
const token = useSelector((state) => state.data.userData.jwt);
|
||||
const classes = useStyles();
|
||||
const handleDeleteButton = (set) => {
|
||||
setSelectedSet(set);
|
||||
setOpen(true);
|
||||
};
|
||||
const onCancel = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
const onAccept = () => {
|
||||
sendForm("delete", selectedSet);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const SetList = props.lunchMenu.map((set) => {
|
||||
return (
|
||||
<Accordion key={set.id} className={classes.root}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon className={classes.expandIcon} />}
|
||||
>
|
||||
<h4>
|
||||
{set.lunchSetName} ({set.lunchSetPrice}zł)
|
||||
</h4>
|
||||
<div className="editRestaurant-categorySpan">
|
||||
<Tooltip title="Usuń">
|
||||
<IconButton
|
||||
color="primary"
|
||||
component="span"
|
||||
onClick={() => handleDeleteButton(set)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</AccordionSummary>
|
||||
<LunchSetDishList lunchSet={set} restaurantId={props.restaurantId} />
|
||||
</Accordion>
|
||||
);
|
||||
});
|
||||
|
||||
// HANDLERS
|
||||
|
||||
const validateForm = () => {
|
||||
const validation = {
|
||||
nameValid: validator.isLength(newSet.lunchSetName, { min: 1, max: 30 }),
|
||||
priceValid: validator.isLength(newSet.lunchSetPrice, { min: 1, max: 12 }),
|
||||
};
|
||||
setNewSet({
|
||||
...newSet,
|
||||
nameError: !validation.nameValid,
|
||||
priceError: !validation.priceValid,
|
||||
});
|
||||
|
||||
return validation.nameValid && validation.priceValid;
|
||||
};
|
||||
|
||||
const sendForm = (action, set) => {
|
||||
let valid = false;
|
||||
if (action === "add") {
|
||||
valid = validateForm();
|
||||
} else {
|
||||
valid = true;
|
||||
}
|
||||
if (valid) {
|
||||
const data = {
|
||||
restaurantId: props.restaurantId,
|
||||
action: action,
|
||||
set: {
|
||||
lunchSetName: set.lunchSetName,
|
||||
lunchSetPrice: set.lunchSetPrice,
|
||||
lunchSetDishes: set.lunchSetDishes,
|
||||
},
|
||||
};
|
||||
dispatch(showBackdrop());
|
||||
axios({
|
||||
method: "POST",
|
||||
url: backend + "restaurant/lunchSet",
|
||||
data: data,
|
||||
headers: {
|
||||
"x-auth-token": token,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
dispatch(hideBackdrop());
|
||||
dispatch(notification("Zmieniono zestaw.", "success"));
|
||||
dispatch(refreshUserData());
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(hideBackdrop());
|
||||
dispatch(notification("Wystąpił błąd.", "error"));
|
||||
throw error;
|
||||
});
|
||||
} else {
|
||||
dispatch(notification("Popraw dane.", "error"));
|
||||
}
|
||||
};
|
||||
|
||||
// COMPONENT
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%", display: "flex", flexFlow: "column", alignItems: "center" }}>
|
||||
<YesNo open={open} cancel={onCancel} accept={onAccept} />
|
||||
{props.lunchMenu.length === 0 ? <p>Lunch menu puste</p> : SetList}
|
||||
<Accordion className={classes.root}>
|
||||
<AccordionSummary
|
||||
expandIcon={<AddIcon className={classes.expandIcon} />}
|
||||
>
|
||||
<h4>Dodaj zestaw</h4>
|
||||
</AccordionSummary>
|
||||
<div className="editRestaurant-addCategory">
|
||||
<TextField
|
||||
className={classes.textInputWide}
|
||||
value={newSet.lunchSetName}
|
||||
onChange={(event) =>
|
||||
setNewSet({ ...newSet, lunchSetName: event.target.value })
|
||||
}
|
||||
label="Nazwa zestawu"
|
||||
variant="outlined"
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<TextFieldsIcon color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
></TextField>
|
||||
<TextField
|
||||
className={classes.textInput}
|
||||
value={newSet.lunchSetPrice}
|
||||
onChange={(event) =>
|
||||
setNewSet({ ...newSet, lunchSetPrice: event.target.value })
|
||||
}
|
||||
label="Cena"
|
||||
variant="outlined"
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<AttachMoneyIcon color="primary" />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
></TextField>
|
||||
<ButtonSecondary
|
||||
onClick={() => sendForm("add", newSet)}
|
||||
text="Dodaj"
|
||||
/>
|
||||
</div>
|
||||
</Accordion>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import React from "react";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Checkbox from "@material-ui/core/Checkbox";
|
||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
timePicker: {
|
||||
"& .MuiInputBase-root": {
|
||||
color: "#bbbbbb",
|
||||
borderRadius: "14px"
|
||||
},
|
||||
"& .MuiInputLabel-root": {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
},
|
||||
checkbox: {
|
||||
marginLeft: theme.spacing(1),
|
||||
"& .MuiFormControlLabel-label": {
|
||||
color: "#979797",
|
||||
fontSize: "14px",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default function InputWorkingHoursSingle(props) {
|
||||
const handleChangeValue = (event) => {
|
||||
props.changeValue(event.target.value);
|
||||
};
|
||||
const handleCheckbox = () => {
|
||||
if (!props.nieczynne) {
|
||||
props.changeValue("");
|
||||
} else {
|
||||
props.changeValue("12:30 - 13:30");
|
||||
}
|
||||
};
|
||||
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<div className="workingHours-day">
|
||||
<h5>Lunch hours</h5>
|
||||
<TextField
|
||||
value={props.hours}
|
||||
variant="outlined"
|
||||
onChange={handleChangeValue}
|
||||
className={classes.timePicker}
|
||||
margin="dense"
|
||||
/>
|
||||
<FormControlLabel
|
||||
className={classes.checkbox}
|
||||
control={
|
||||
<Checkbox
|
||||
onClick={handleCheckbox}
|
||||
checked={props.nieczynne}
|
||||
name="nieczynne"
|
||||
/>
|
||||
}
|
||||
label="Brak"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import SearchIcon from '@material-ui/icons/Search';
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Autocomplete from "@material-ui/lab/Autocomplete";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { fetchAutocomplete, setSearchQuery, fetchSearch } from "../../actions";
|
||||
import { fetchSearch } from "../../actions";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useSnackbar } from "notistack";
|
||||
import { removeSnackbar } from "../actions/toggles.js";
|
||||
import { removeNotification } from "../redux/slices/notificationsSlice.ts";
|
||||
|
||||
let displayed = [];
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ import YesNo from "../Dialogs/YesNo";
|
||||
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";
|
||||
import { hideBackdrop, showBackdrop } from "../../actions/toggles";
|
||||
import { showBackdrop, hideBackdrop } from "../../redux/slices/viewDataSlice.ts";
|
||||
|
||||
export default function EditDishList(props) {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import KeyboardArrowRightIcon from "@material-ui/icons/KeyboardArrowRight";
|
||||
|
||||
export default function LunchCardDish(props) {
|
||||
const history = useHistory();
|
||||
const {
|
||||
name,
|
||||
imgUrl,
|
||||
_id,
|
||||
} = props.dish;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="carddish-container"
|
||||
onClick={() => history.push(`/dish/${_id}`)}
|
||||
>
|
||||
<div className="carddish-left">
|
||||
<h3>{props.quantity}x</h3>
|
||||
<div
|
||||
className="lunch-carddish-img"
|
||||
style={{ backgroundImage: "url(" + imgUrl + ")" }}
|
||||
/>
|
||||
<div className="carddish-left-info">
|
||||
<h2>{name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div className="lunch-carddish-right">
|
||||
<KeyboardArrowRightIcon color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import React from "react";
|
||||
import Accordion from "@material-ui/core/Accordion";
|
||||
import AccordionSummary from "@material-ui/core/AccordionSummary";
|
||||
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
||||
import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import LunchCardDish from "./LunchCardDish";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
backgroundColor: "#262626",
|
||||
color: "#bbbbbb",
|
||||
"& .MuiListItem-gutters": {
|
||||
padding: "2px"
|
||||
},
|
||||
},
|
||||
expandIcon: {
|
||||
color: "#bbbbbb",
|
||||
},
|
||||
}));
|
||||
|
||||
const filterDishes = (dishes, setDishes) => {
|
||||
const ids = setDishes.map((dish) => {
|
||||
return dish.dishId
|
||||
})
|
||||
let result = [];
|
||||
dishes.map((dish) => {
|
||||
if (ids.includes(dish._id)) {
|
||||
const lunchSetDish = setDishes.filter((thisDish) => thisDish.dishId === dish._id)[0]
|
||||
result.push({...dish, quantity: lunchSetDish.quantity});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
export default function LunchDishesCategory(props) {
|
||||
const classes = useStyles();
|
||||
const dishes = props.dishes;
|
||||
const filtered = filterDishes(dishes, props.lunchSetDishes)
|
||||
const dishCards = filtered.map((dish) => {
|
||||
return (
|
||||
<ListItem key={dish._id}>
|
||||
<LunchCardDish dish={dish} quantity={dish.quantity}></LunchCardDish>
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Accordion className={classes.root}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon className={classes.expandIcon} />}
|
||||
>
|
||||
<h4>
|
||||
{props.name} <span>{props.price && `(${props.price}zł)`}</span>
|
||||
</h4>
|
||||
</AccordionSummary>
|
||||
<List>{dishCards}</List>
|
||||
</Accordion>
|
||||
);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
import LunchDishesCategory from "./LunchDishesCategory";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export default function LunchMenu(props) {
|
||||
const dishes = useSelector((state) => state.dishes)
|
||||
const { restaurant } = props;
|
||||
const lunchMenu = restaurant.lunchMenu;
|
||||
const sets = lunchMenu.map((set) => {
|
||||
if(set.lunchSetDishes.length > 0){
|
||||
return (
|
||||
<LunchDishesCategory
|
||||
key={set.lunchSetName}
|
||||
name={set.lunchSetName}
|
||||
price={set.lunchSetPrice}
|
||||
hidePrice={true}
|
||||
lunchSetDishes={set.lunchSetDishes}
|
||||
dishes={dishes}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <div key={set.lunchSetName}></div>;
|
||||
}
|
||||
});
|
||||
|
||||
return <div className="dishlist-container">{sets && sets}</div>;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
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) => {
|
||||
const ids = setDishes.map((dish) => {
|
||||
return dish.dishId
|
||||
})
|
||||
let result = [];
|
||||
dishes.map((dish) => {
|
||||
if (ids.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());
|
||||
})
|
||||
.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) => {
|
||||
const thisDishInSet = props.lunchSet.lunchSetDishes.filter((dishInSet) => {
|
||||
return dishInSet.dishId === dish._id;
|
||||
})[0]
|
||||
return (
|
||||
<ListItem key={dish._id}>
|
||||
<div className="editRestaurant-dish">
|
||||
<div className="editRestaurant-dishLeft">
|
||||
<h3 className="editRestaurant-dishLeft-header">{thisDishInSet.quantity}x</h3>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import DishList from "./DishList";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { extractTags } from "../../Services";
|
||||
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
|
||||
import { useAppDispatch, useAppSelector } from "../../redux/hooks.ts";
|
||||
import { fetchRestaurant } from "../../actions";
|
||||
import GoogleMapStatic from "./GoogleMapStatic";
|
||||
import WorkingHours from "./WorkingHours";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { IconButton } from "@material-ui/core";
|
||||
import TuneIcon from '@material-ui/icons/Tune';
|
||||
import Chip from '@material-ui/core/Chip';
|
||||
import { restaurantTypes } from '../../config.js';
|
||||
import { setTags, setTypes } from "../../actions";
|
||||
//import { setTags, setTypes } from "../../actions";
|
||||
import { decodeTags, compareArrays } from "../../Services"
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
|
||||
@@ -13,7 +13,6 @@ import ListItemText from "@material-ui/core/ListItemText";
|
||||
import ListItemIcon from "@material-ui/core/ListItemIcon";
|
||||
import HomeIcon from "@material-ui/icons/Home";
|
||||
import MailIcon from "@material-ui/icons/Mail";
|
||||
import { logout } from "../actions";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import ButtonSecondary from "./Input/ButtonSecondary";
|
||||
import ListSubheader from "@material-ui/core/ListSubheader";
|
||||
@@ -37,10 +36,7 @@ const useStyles = makeStyles((theme) => ({
|
||||
|
||||
export default function TopBar() {
|
||||
const classes = useStyles();
|
||||
const loggedIn = useSelector((state) => state.data.loggedIn);
|
||||
const firstname = useSelector((state) => state.data.userData.firstname);
|
||||
const login = useSelector((state) => state.data.userData.login);
|
||||
const isRestaurant = useSelector((state) => state.data.userData.isRestaurant)
|
||||
const loggedIn = false;
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const handleClick = (button) => {
|
||||
@@ -102,7 +98,7 @@ export default function TopBar() {
|
||||
{loggedIn && (
|
||||
<div className="topbar-username">
|
||||
{" "}
|
||||
<p>Witaj {isRestaurant ? firstname : login}</p>{" "}
|
||||
<p>Witaj</p>{" "}
|
||||
</div>
|
||||
)}
|
||||
<IconButton onClick={toggleDrawer(true)} aria-label="menu">
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import React from "react";
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
import ReactDOM from "react-dom";
|
||||
import { Auth0Provider } from "@auth0/auth0-react";
|
||||
import "./index.scss";
|
||||
import { Provider } from "react-redux";
|
||||
import store from "./redux/store";
|
||||
import store from "./redux/store.ts";
|
||||
import App from "./App";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
ReactDOM.render(
|
||||
<Auth0Provider
|
||||
domain={process.env.AUTH0_DOMAIN as string}
|
||||
clientId={process.env.AUTH0_CLIENTID as string}
|
||||
domain={process.env.AUTH0_DOMAIN}
|
||||
clientId={process.env.AUTH0_CLIENTID}
|
||||
redirectUri={window.location.origin}
|
||||
>
|
||||
<Provider store={store}>
|
||||
@@ -1,81 +0,0 @@
|
||||
const data = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case "SET_LOGGEDIN":
|
||||
return (state = {
|
||||
...state,
|
||||
loggedIn: true,
|
||||
userData: {
|
||||
jwt: action.payload.jwt,
|
||||
firstname: action.payload.firstname,
|
||||
lastname: action.payload.lastname,
|
||||
userId: action.payload.userId,
|
||||
userEmail: action.payload.email,
|
||||
login: action.payload.login,
|
||||
billing: {
|
||||
NIP: action.payload.NIP,
|
||||
adress: action.payload.adress,
|
||||
companyName: action.payload.companyName,
|
||||
},
|
||||
restaurants: action.payload.restaurants,
|
||||
isRestaurant: action.payload.isRestaurant,
|
||||
},
|
||||
});
|
||||
case "SET_LOGGEDOUT":
|
||||
return (state = {
|
||||
...state,
|
||||
loggedIn: false,
|
||||
userData: {
|
||||
jwt: "",
|
||||
firstname: "",
|
||||
lastname: "",
|
||||
userId: "",
|
||||
userEmail: "",
|
||||
billing: {
|
||||
NIP: "",
|
||||
adress: "",
|
||||
companyName: "",
|
||||
},
|
||||
restaurants: [],
|
||||
isRestaurant: false,
|
||||
},
|
||||
});
|
||||
case "SET_TEMP_DATA":
|
||||
return (state = { ...state, tempData: action.payload });
|
||||
case "CLEAR_TEMP_DATA":
|
||||
return (state = { ...state, tempData: {} });
|
||||
case "UPDATE_RESTAURANT":
|
||||
const index = state.userData.restaurants.findIndex(
|
||||
(restaurant) => restaurant._id === action.payload._id
|
||||
);
|
||||
return (state = {
|
||||
...state,
|
||||
userData: {
|
||||
...state.userData,
|
||||
restaurants: [
|
||||
...state.userData.restaurants.slice(0, index),
|
||||
action.payload,
|
||||
...state.userData.restaurants.slice(index + 1),
|
||||
],
|
||||
},
|
||||
});
|
||||
case "SET_NEW_TOKEN":
|
||||
return (state = {
|
||||
...state,
|
||||
userData: { ...state.userData, jwt: action.payload },
|
||||
});
|
||||
case "SET_TYPES":
|
||||
return (state = {
|
||||
...state,
|
||||
filters: { ...state.filters, types: action.payload },
|
||||
});
|
||||
case "SET_TAGS":
|
||||
return (state = {
|
||||
...state,
|
||||
filters: { ...state.filters, tags: action.payload },
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default data;
|
||||
@@ -1,16 +0,0 @@
|
||||
const dishes = (state = [], action) => {
|
||||
switch (action.type) {
|
||||
case "SET_DISHES":
|
||||
return (state = action.payload);
|
||||
case "SET_DISH":
|
||||
return [action.payload];
|
||||
case "ADD_DISH":
|
||||
return [...state, action.payload];
|
||||
case "CLEAR_DISHES":
|
||||
return (state = []);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default dishes;
|
||||
@@ -1,23 +0,0 @@
|
||||
import { combineReducers } from "redux";
|
||||
import { connectRouter } from "connected-react-router";
|
||||
import autoCompleteReducer from "./autoComplete";
|
||||
import searchResults from "./searchResults";
|
||||
import searchQuery from "./searchQuery";
|
||||
import restaurant from "./restaurant";
|
||||
import dishes from "./dishes";
|
||||
import data from "./data";
|
||||
import notifications from "./notifications";
|
||||
|
||||
const rootReducer = (history) =>
|
||||
combineReducers({
|
||||
router: connectRouter(history),
|
||||
autocomplete: autoCompleteReducer,
|
||||
searchResults: searchResults,
|
||||
searchQuery: searchQuery,
|
||||
restaurant: restaurant,
|
||||
dishes: dishes,
|
||||
data: data,
|
||||
notifications: notifications,
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
@@ -1,12 +0,0 @@
|
||||
const notifications = (state = [], action) => {
|
||||
switch (action.type) {
|
||||
case "ENQUEUE_SNACKBAR":
|
||||
return [...state, { key: action.key, ...action.notification }];
|
||||
case "REMOVE_SNACKBAR":
|
||||
return state.filter((notification) => notification.key !== action.key);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default notifications;
|
||||
@@ -1,12 +0,0 @@
|
||||
const restaurant = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case "SET_RESTAURANT":
|
||||
return (state = action.payload);
|
||||
case "CLEAR_RESTAURANT":
|
||||
return (state = {});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default restaurant;
|
||||
@@ -1,12 +0,0 @@
|
||||
const searchQuery = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case "SEARCH_QUERY_SET":
|
||||
return (state = action.payload);
|
||||
case "SEARCH_QUERY_CLEAR":
|
||||
return (state = "");
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default searchQuery;
|
||||
@@ -1,12 +0,0 @@
|
||||
const searchResults = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case "SEARCH_RESULTS":
|
||||
return action.payload;
|
||||
case "SEARCH_CLEAR":
|
||||
return (state = {});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default searchResults;
|
||||
@@ -1,6 +1,5 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { Restaurant } from "../../typescript/interfaces";
|
||||
import axios from "axios";
|
||||
import { Restaurant } from "../../typescript";
|
||||
|
||||
const initialState: Restaurant = {} as Restaurant;
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
backdrop: false,
|
||||
showDishList: false,
|
||||
regulamin: false,
|
||||
};
|
||||
|
||||
export const togglesSlice = createSlice({
|
||||
name: "toggles",
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
showBackdrop: (state) => {
|
||||
state = { ...state, backdrop: true };
|
||||
},
|
||||
hideBackdrop: (state) => {
|
||||
state = { ...state, backdrop: false };
|
||||
},
|
||||
showDishes: (state) => {
|
||||
state = { ...state, showDishList: true };
|
||||
},
|
||||
hideDishes: (state) => {
|
||||
state = { ...state, showDishList: false };
|
||||
},
|
||||
showRegulamin: (state) => {
|
||||
state = { ...state, showDishList: true };
|
||||
},
|
||||
hideRegulamin: (state) => {
|
||||
state = { ...state, showDishList: false };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
showBackdrop,
|
||||
hideBackdrop,
|
||||
showDishes,
|
||||
hideDishes,
|
||||
showRegulamin,
|
||||
hideRegulamin,
|
||||
} = togglesSlice.actions;
|
||||
export default togglesSlice.reducer;
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Restaurant, User } from "../../typescript/interfaces";
|
||||
import { Restaurant, User } from "../../typescript";
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState: User = {
|
||||
id: "",
|
||||
username: "",
|
||||
email: "",
|
||||
isRestaurant: true,
|
||||
isBusiness: true,
|
||||
trialUsed: false,
|
||||
billing: {
|
||||
NIP: "",
|
||||
@@ -22,6 +22,9 @@ export const userSlice = createSlice({
|
||||
clearUserData: (state) => {
|
||||
state = initialState;
|
||||
},
|
||||
setUserData: (state, action) => {
|
||||
state = action.payload as User;
|
||||
},
|
||||
updateRestaurant: (state, action) => {
|
||||
const index = state.restaurants?.findIndex(
|
||||
(restaurant) => restaurant.id === action.payload.id
|
||||
@@ -43,5 +46,6 @@ export const userSlice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const { clearUserData, updateRestaurant } = userSlice.actions;
|
||||
export const { clearUserData, updateRestaurant, setUserData } =
|
||||
userSlice.actions;
|
||||
export default userSlice.reducer;
|
||||
|
||||
105
src/redux/slices/viewDataSlice.ts
Normal file
105
src/redux/slices/viewDataSlice.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import { RestaurantTag, Dish } from "../../typescript";
|
||||
|
||||
interface initState {
|
||||
backdrop: boolean;
|
||||
showDishList: boolean;
|
||||
regulamin: boolean;
|
||||
types: string[];
|
||||
tags: RestaurantTag[];
|
||||
searchResults: {};
|
||||
dishes: Dish[];
|
||||
}
|
||||
|
||||
const initialState: initState = {
|
||||
backdrop: false,
|
||||
showDishList: false,
|
||||
regulamin: false,
|
||||
types: [],
|
||||
tags: [],
|
||||
searchResults: {},
|
||||
dishes: [],
|
||||
};
|
||||
|
||||
export const togglesSlice = createSlice({
|
||||
name: "toggles",
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
showBackdrop: (state) => {
|
||||
state = { ...state, backdrop: true };
|
||||
},
|
||||
hideBackdrop: (state) => {
|
||||
state = { ...state, backdrop: false };
|
||||
},
|
||||
showDishes: (state) => {
|
||||
state = { ...state, showDishList: true };
|
||||
},
|
||||
hideDishes: (state) => {
|
||||
state = { ...state, showDishList: false };
|
||||
},
|
||||
showRegulamin: (state) => {
|
||||
state = { ...state, showDishList: true };
|
||||
},
|
||||
hideRegulamin: (state) => {
|
||||
state = { ...state, showDishList: false };
|
||||
},
|
||||
addTypeFilter: (state, action) => {
|
||||
let tempTypes = state.types;
|
||||
tempTypes.push(action.payload as string);
|
||||
state = { ...state, types: tempTypes };
|
||||
},
|
||||
removeTypeFilter: (state, action) => {
|
||||
let tempTypes = state.types;
|
||||
state = {
|
||||
...state,
|
||||
types: tempTypes.filter((temp) => temp != action.payload),
|
||||
};
|
||||
},
|
||||
clearTypeFilter: (state) => {
|
||||
state = { ...state, types: initialState.types };
|
||||
},
|
||||
addTagFilter: (state, action) => {
|
||||
let tempTags = state.tags;
|
||||
tempTags.push(action.payload as RestaurantTag);
|
||||
state = { ...state, tags: tempTags };
|
||||
},
|
||||
removeTagFilter: (state, action) => {
|
||||
let tempTags = state.tags;
|
||||
state = {
|
||||
...state,
|
||||
tags: tempTags.filter((tag) => tag != action.payload),
|
||||
};
|
||||
},
|
||||
clearTagFilter: (state) => {
|
||||
state = { ...state, tags: initialState.tags };
|
||||
},
|
||||
setSearchResults: (state, action) => {
|
||||
state = { ...state, searchResults: action.payload };
|
||||
},
|
||||
clearSearchResults: (state) => {
|
||||
state = { ...state, searchResults: initialState.searchResults };
|
||||
},
|
||||
setDishes: (state, action) => {
|
||||
state = { ...state, dishes: action.payload };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
showBackdrop,
|
||||
hideBackdrop,
|
||||
showDishes,
|
||||
hideDishes,
|
||||
showRegulamin,
|
||||
hideRegulamin,
|
||||
addTypeFilter,
|
||||
removeTypeFilter,
|
||||
clearTypeFilter,
|
||||
addTagFilter,
|
||||
removeTagFilter,
|
||||
clearTagFilter,
|
||||
setSearchResults,
|
||||
clearSearchResults,
|
||||
setDishes,
|
||||
} = togglesSlice.actions;
|
||||
export default togglesSlice.reducer;
|
||||
@@ -1,14 +1,18 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import userReducer from "./slices/userSlice";
|
||||
import restaurantReducer from "./slices/restaurantSlice";
|
||||
import togglesReducer from "./slices/togglesSlice";
|
||||
import notificationsReducer from "./slices/notificationsSlice";
|
||||
// @ts-ignore
|
||||
import userReducer from "./slices/userSlice.ts";
|
||||
// @ts-ignore
|
||||
import restaurantReducer from "./slices/restaurantSlice.ts";
|
||||
// @ts-ignore
|
||||
import viewDataReducer from "./slices/viewDataSlice.ts";
|
||||
// @ts-ignore
|
||||
import notificationsReducer from "./slices/notificationsSlice.ts";
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
user: userReducer,
|
||||
restaurant: restaurantReducer,
|
||||
toggles: togglesReducer,
|
||||
viewData: viewDataReducer,
|
||||
notifications: notificationsReducer,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ export interface User {
|
||||
username: string;
|
||||
email: string;
|
||||
billing: BillingData;
|
||||
isRestaurant: boolean;
|
||||
isBusiness: boolean;
|
||||
restaurants?: Restaurant[];
|
||||
trialUsed: boolean;
|
||||
}
|
||||
@@ -21,16 +21,28 @@ export interface Restaurant {
|
||||
type: string;
|
||||
city: string;
|
||||
adress: string;
|
||||
location: number[];
|
||||
location: {
|
||||
lon: number,
|
||||
lat: number
|
||||
};
|
||||
placesId: string;
|
||||
imgURL: string;
|
||||
phone: string;
|
||||
social: Social;
|
||||
tags: RestaurantTags;
|
||||
tags: RestaurantTag[];
|
||||
hours: WorkingHours;
|
||||
hidden: boolean;
|
||||
categories: string[];
|
||||
dishes: Dish[];
|
||||
reviews: Review[];
|
||||
subscriptionActive: boolean;
|
||||
subscriptionDue: Date;
|
||||
}
|
||||
|
||||
export interface Review {
|
||||
author: string,
|
||||
score: number,
|
||||
note: string
|
||||
}
|
||||
|
||||
export interface Social {
|
||||
@@ -39,14 +51,14 @@ export interface Social {
|
||||
www: string;
|
||||
}
|
||||
|
||||
export interface RestaurantTags {
|
||||
cardPayments: boolean;
|
||||
petFriendly: boolean;
|
||||
glutenFree: boolean;
|
||||
vegan: boolean;
|
||||
vegetarian: boolean;
|
||||
alcohol: boolean;
|
||||
delivery: boolean;
|
||||
export enum RestaurantTag {
|
||||
cardPayments,
|
||||
petFriendly,
|
||||
glutenFree,
|
||||
vegan,
|
||||
vegetarian,
|
||||
alcohol,
|
||||
delivery,
|
||||
}
|
||||
|
||||
export interface WorkingHours {
|
||||
@@ -69,7 +81,7 @@ export interface Dish {
|
||||
notes: string;
|
||||
hidden: boolean;
|
||||
weight: string;
|
||||
allergens: Allergens;
|
||||
allergens: Allergen[];
|
||||
ingredients: string;
|
||||
glicemicIndex: string;
|
||||
kcal: string;
|
||||
@@ -77,14 +89,14 @@ export interface Dish {
|
||||
vegetarian: boolean;
|
||||
}
|
||||
|
||||
export interface Allergens {
|
||||
gluten: boolean;
|
||||
lactose: boolean;
|
||||
soy: boolean;
|
||||
eggs: boolean;
|
||||
seaFood: boolean;
|
||||
peanuts: boolean;
|
||||
sesame: boolean;
|
||||
export enum Allergen {
|
||||
gluten,
|
||||
lactose,
|
||||
soy,
|
||||
eggs,
|
||||
seaFood,
|
||||
peanuts,
|
||||
sesame,
|
||||
}
|
||||
|
||||
export interface DishPrices {
|
||||
Reference in New Issue
Block a user