diff --git a/.gitignore b/.gitignore
index 4d29575..8692cf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
# misc
.DS_Store
+.env
.env.local
.env.development.local
.env.test.local
diff --git a/package-lock.json b/package-lock.json
index 681953e..4fcbc75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "web_client",
- "version": "0.1.0",
+ "version": "0.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -13624,6 +13624,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "validator": {
+ "version": "13.1.1",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.1.1.tgz",
+ "integrity": "sha512-8GfPiwzzRoWTg7OV1zva1KvrSemuMkv07MA9TTl91hfhe+wKrsrgVN4H2QSFd/U/FhiU3iWPYVgvbsOGwhyFWw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/package.json b/package.json
index 9d23972..c1c8c08 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "web_client",
- "version": "0.1.0",
+ "version": "0.3.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.0",
@@ -16,7 +16,8 @@
"react-redux": "^7.2.0",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
- "redux-thunk": "^2.3.0"
+ "redux-thunk": "^2.3.0",
+ "validator": "^13.1.1"
},
"scripts": {
"start": "react-scripts start",
diff --git a/src/App.js b/src/App.js
index 1e1d2d4..5d3ff54 100644
--- a/src/App.js
+++ b/src/App.js
@@ -13,7 +13,7 @@ import { useSelector } from "react-redux";
const theme = createMuiTheme({
palette: {
primary: {
- main: "#0e8496",
+ main: "#d68000",
},
secondary: {
light: "#ffffff",
diff --git a/src/actions/index.js b/src/actions/index.js
index cf4d133..236c4e9 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -1,5 +1,6 @@
import axios from "axios";
import * as toggles from "./toggles";
+const backend = "http://localhost:4000/";
const autocomplete = (input) => {
return {
@@ -17,9 +18,7 @@ export const clearAutocomplete = () => {
export const fetchAutocomplete = (input) => {
return function (dispatch) {
axios
- .get(
- "http://localhost:4000/search/autocomplete?string=" + encodeURI(input)
- )
+ .get(backend + "search/autocomplete?string=" + encodeURI(input))
.then((response) => {
const cities = Array.from(response.data.cities);
const restaurants = Array.from(response.data.restaurants);
@@ -36,7 +35,7 @@ export const fetchAutocomplete = (input) => {
export const fetchSearch = (input) => {
return function (dispatch) {
axios
- .get("http://localhost:4000/search?string=" + encodeURI(input))
+ .get(backend + "search?string=" + encodeURI(input))
.then((response) => {
const data = response.data;
if (Object.keys(data).length > 0) {
@@ -80,7 +79,7 @@ export const setRestaurant = (restaurant) => {
export const fetchRestaurant = (id) => {
return function (dispatch) {
axios
- .get("http://localhost:4000/restaurant?restaurantId=" + id)
+ .get(backend + "restaurant?restaurantId=" + id)
.then((response) => {
dispatch(setRestaurant(response.data));
dispatch(toggles.hideDishes());
@@ -101,7 +100,7 @@ const setDishes = (data) => {
export const fetchAllDishes = (id) => {
return function (dispatch) {
axios
- .get("http://localhost:4000/restaurant/dishes?restaurantId=" + id)
+ .get(backend + "restaurant/dishes?restaurantId=" + id)
.then((response) => {
dispatch(setDishes(response.data));
dispatch(toggles.showDishes());
@@ -109,10 +108,38 @@ export const fetchAllDishes = (id) => {
};
};
-export const tryLogin = (username) => {
+export const tryLogin = (username, password) => {
+ const data = { email: username, password: password };
+
return function (dispatch) {
- dispatch(toggles.setLoggedIn(username));
- dispatch(toggles.hideLoginDialog());
+ axios
+ .post(backend + "user/login", data)
+ .then((response) => {
+ const jwt = response.headers["x-auth-token"];
+ console.log(response.headers);
+ dispatch(
+ toggles.setLoggedIn(
+ response.data.firstname,
+ jwt,
+ response.data.id,
+ response.data.email
+ )
+ );
+ dispatch(toggles.hideLoginDialog());
+ })
+ .catch((err) => {
+ if (err.response.status === 404) {
+ dispatch(
+ toggles.setLoginResult(
+ "Użytkownik o podanym adresie email nie istnieje."
+ )
+ );
+ } else if (err.response.status === 401) {
+ dispatch(toggles.setLoginResult("Podane hasło jest nieprawidłowe"));
+ } else {
+ dispatch(toggles.setLoginResult("Błąd serwera..."));
+ }
+ });
};
};
@@ -121,3 +148,39 @@ export const logout = () => {
dispatch(toggles.setLoggedOut());
};
};
+
+export const tryRegister = (data) => {
+ return function (dispatch) {
+ dispatch(toggles.showRegisterCircle());
+ axios
+ .post(backend + "user/register", data)
+ .then((response) => {
+ if (response.status === 201) {
+ dispatch(
+ toggles.setRegisterResult(
+ "Dziękujemy za rejestrację. Teraz możesz zalogować się do swojego konta."
+ )
+ );
+ dispatch(toggles.hideRegisterCircle());
+ dispatch(toggles.hideRegisterForm());
+ }
+ })
+ .catch((err) => {
+ if (err.response.status === 500) {
+ dispatch(
+ toggles.setRegisterResult(
+ "Wystąpił nieoczekiwany błąd serwera, przepraszamy..."
+ )
+ );
+ dispatch(toggles.hideRegisterCircle());
+ } else if (err.response.status === 409) {
+ dispatch(
+ toggles.setRegisterResult(
+ "Adres email jest już zajęty, proszę użyć innego."
+ )
+ );
+ dispatch(toggles.hideRegisterCircle());
+ }
+ });
+ };
+};
diff --git a/src/actions/toggles.js b/src/actions/toggles.js
index c035003..9abcc9d 100644
--- a/src/actions/toggles.js
+++ b/src/actions/toggles.js
@@ -22,10 +22,10 @@ export const hideLoginDialog = () => {
};
};
-export const setLoggedIn = (username) => {
+export const setLoggedIn = (username, jwt, id, email) => {
return {
type: "SET_LOGGEDIN",
- payload: username,
+ payload: { username: username, jwt: jwt, id: id, email: email },
};
};
@@ -34,3 +34,59 @@ export const setLoggedOut = () => {
type: "SET_LOGGEDOUT",
};
};
+
+export const showRegisterDialog = () => {
+ return {
+ type: "DIALOG_REGISTER_VISIBLE",
+ };
+};
+
+export const hideRegisterDialog = () => {
+ return {
+ type: "DIALOG_REGISTER_HIDDEN",
+ };
+};
+
+export const showRegulaminDialog = () => {
+ return {
+ type: "DIALOG_REGULAMIN_VISIBLE",
+ };
+};
+
+export const hideRegulaminDialog = () => {
+ return {
+ type: "DIALOG_REGULAMIN_HIDDEN",
+ };
+};
+
+export const showRegisterCircle = () => {
+ return {
+ type: "DIALOG_REGISTER_CIRCLE_SHOW",
+ };
+};
+
+export const hideRegisterCircle = () => {
+ return {
+ type: "DIALOG_REGISTER_CIRCLE_HIDE",
+ };
+};
+
+export const hideRegisterForm = () => {
+ return {
+ type: "DIALOG_REGISTER_FORM_HIDE",
+ };
+};
+
+export const setRegisterResult = (text) => {
+ return {
+ type: "DIALOG_REGISTER_SET_RESULT",
+ payload: text,
+ };
+};
+
+export const setLoginResult = (text) => {
+ return {
+ type: "DIALOG_LOGIN_SET_RESULT",
+ payload: text,
+ };
+};
diff --git a/src/components/ButtonSecondary.js b/src/components/ButtonSecondary.js
index 91d29be..2dd8cdc 100644
--- a/src/components/ButtonSecondary.js
+++ b/src/components/ButtonSecondary.js
@@ -4,13 +4,13 @@ import Button from "@material-ui/core/Button";
const StylizedButton = withStyles({
root: {
- background: "#01c3a9",
+ background: "#d68000",
color: "#262626",
margin: "16px 16px 16px 16px",
padding: "8px 16px 8px 16px",
borderColor: "white",
"&:hover": {
- backgroundColor: "#00af98",
+ backgroundColor: "#b46c00",
},
},
label: {
diff --git a/src/components/CardDish.js b/src/components/CardDish.js
index 616bcab..f8c35ab 100644
--- a/src/components/CardDish.js
+++ b/src/components/CardDish.js
@@ -7,10 +7,10 @@ export default function CardDish(props) {
name,
price,
imgUrl,
- notes,
+ //notes,
weight,
- vegan,
- vegetarian,
+ //vegan,
+ //vegetarian,
allergens,
} = props.dish;
diff --git a/src/components/Dialogs.js b/src/components/Dialogs.js
index ad851bb..f4fea98 100644
--- a/src/components/Dialogs.js
+++ b/src/components/Dialogs.js
@@ -1,98 +1,14 @@
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 "./ButtonSecondary";
-import IconButton from "@material-ui/core/IconButton";
-import TextField from "@material-ui/core/TextField";
-import CloseIcon from "@material-ui/icons/Close";
-import { useSelector, useDispatch } from "react-redux";
-import { hideLoginDialog } from "../actions/toggles";
-import { tryLogin } from "../actions";
+import LoginDialog from "./Dialogs/LoginDialog";
+import RegisterDialog from "./Dialogs/RegisterDialog";
+import RegulaminDialog from "./Dialogs/RegulaminDialog";
export default function (props) {
- var loginDialog = useSelector((state) => state.data.dialogs.logIn);
- const dispatch = useDispatch();
-
- const loginStyles = makeStyles((theme) => ({
- root: {
- textAlign: "center",
- "& .MuiPaper-root": {
- backgroundColor: "#262626",
- color: "#bbbbbb",
- },
- },
- closeButton: {
- color: "#bbbbbb",
- position: "absolute",
- right: theme.spacing(1),
- top: theme.spacing(1),
- },
- textInput: {
- marginTop: "20px",
- marginBottom: "10px",
- width: "90%",
- "& .MuiInputBase-root": {
- color: "#01c3a9",
- },
- "& .MuiInputLabel-root": {
- color: "#bbbbbb",
- },
- },
- }));
-
- const loginClass = loginStyles();
-
return (
-
dispatch(hideLoginDialog())}
- open={loginDialog}
- aria-labelledby="login-title"
- >
- Logowanie
- dispatch(hideLoginDialog())}
- aria-label="close"
- >
-
-
-
-
-
-
-
- dispatch(tryLogin("jonasz@bankai.pl"))}
- text="Zaloguj"
- />
-
-
- Nie masz konta?
-
- Zarejestruj się.
-
-
-
-
+
+
+
);
}
diff --git a/src/components/Dialogs/LoginDialog.js b/src/components/Dialogs/LoginDialog.js
new file mode 100644
index 0000000..166fa53
--- /dev/null
+++ b/src/components/Dialogs/LoginDialog.js
@@ -0,0 +1,174 @@
+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 ".././ButtonSecondary";
+import IconButton from "@material-ui/core/IconButton";
+import TextField from "@material-ui/core/TextField";
+import CloseIcon from "@material-ui/icons/Close";
+import { useSelector, useDispatch } from "react-redux";
+import {
+ hideLoginDialog,
+ showRegisterDialog,
+ setLoginResult,
+} from "../../actions/toggles";
+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 } from "../../actions";
+
+export default function LoginDialog(props) {
+ const initialData = {
+ email: "",
+ password: "",
+ emailError: false,
+ passwordError: false,
+ };
+ const [loginData, setLoginData] = useState(initialData);
+ const loginDialog = useSelector((state) => state.data.dialogs.logIn);
+ const loginResult = useSelector((state) => state.data.dialogs.loginResult);
+ const dispatch = useDispatch();
+
+ const loginStyles = makeStyles((theme) => ({
+ root: {
+ textAlign: "center",
+ "& .MuiPaper-root": {
+ backgroundColor: "#262626",
+ color: "#bbbbbb",
+ },
+ },
+ closeButton: {
+ color: "#bbbbbb",
+ position: "absolute",
+ right: theme.spacing(1),
+ top: theme.spacing(1),
+ },
+ textInput: {
+ marginTop: "20px",
+ marginBottom: "10px",
+ width: "90%",
+ "& .MuiInputBase-root": {
+ color: "#01c3a9",
+ },
+ "& .MuiInputLabel-root": {
+ color: "#bbbbbb",
+ },
+ },
+ link: {
+ fontSize: "0.9rem",
+ },
+ }));
+
+ const handleRegisterClick = () => {
+ dispatch(hideLoginDialog());
+ dispatch(showRegisterDialog());
+ };
+
+ 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(setLoginResult("Podaj poprawne dane logowania."));
+ }
+ };
+
+ // CODE
+
+ return (
+
+
dispatch(hideLoginDialog())}
+ open={loginDialog}
+ aria-labelledby="login-title"
+ >
+ Logowanie
+ dispatch(hideLoginDialog())}
+ aria-label="close"
+ >
+
+
+
+
+ (loginData.email = event.target.value)}
+ InputProps={{
+ startAdornment: (
+
+
+
+ ),
+ }}
+ />
+ (loginData.password = event.target.value)}
+ InputProps={{
+ startAdornment: (
+
+
+
+ ),
+ }}
+ />
+ {loginResult}
+
+ handleLogin()} text="Zaloguj" />
+
+ handleRegisterClick()}
+ >
+ Nie pamiętam hasła.
+
+
+ Nie masz konta?{" "}
+
+ handleRegisterClick()}>
+ Zarejestruj się.
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Dialogs/RegisterDialog.js b/src/components/Dialogs/RegisterDialog.js
new file mode 100644
index 0000000..eb1c6ac
--- /dev/null
+++ b/src/components/Dialogs/RegisterDialog.js
@@ -0,0 +1,281 @@
+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 ".././ButtonSecondary";
+import IconButton from "@material-ui/core/IconButton";
+import TextField from "@material-ui/core/TextField";
+import CloseIcon from "@material-ui/icons/Close";
+import { useSelector, useDispatch } from "react-redux";
+import {
+ hideRegisterDialog,
+ showRegulaminDialog,
+ setRegisterResult,
+ showLoginDialog,
+} from "../../actions/toggles";
+import { tryRegister } from "../../actions";
+import InputAdornment from "@material-ui/core/InputAdornment";
+import AccountCircle from "@material-ui/icons/AccountCircle";
+import EmailIcon from "@material-ui/icons/Email";
+import LockIcon from "@material-ui/icons/Lock";
+import Link from "@material-ui/core/Link";
+import validator from "validator";
+import CircularProgress from "@material-ui/core/CircularProgress";
+
+export default function RegisterDialog(props) {
+ // SETUP
+
+ const initialFormData = {
+ firstname: "",
+ lastname: "",
+ email: "",
+ password: "",
+ repeatPassword: "",
+ firstnameError: false,
+ lastnameError: false,
+ emailError: false,
+ passwordError: false,
+ repeatPasswordError: false,
+ };
+ const [formData, setFormData] = useState(initialFormData);
+ var registerDialog = useSelector((state) => state.data.dialogs.register);
+ var circularProgress = useSelector(
+ (state) => state.data.dialogs.registerCircularProgress
+ );
+ var registerForm = useSelector((state) => state.data.dialogs.registerForm);
+ var registerResult = useSelector(
+ (state) => state.data.dialogs.registerResult
+ );
+ const dispatch = useDispatch();
+
+ // STYLES
+
+ const loginStyles = makeStyles((theme) => ({
+ root: {
+ textAlign: "center",
+ "& .MuiPaper-root": {
+ backgroundColor: "#262626",
+ color: "#bbbbbb",
+ },
+ "& .MuiFormHelperText-root": {
+ color: "#606060",
+ textAlign: "center",
+ },
+ },
+ 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();
+
+ // HANDLERS
+
+ const handleRegulaminClick = (event) => {
+ event.preventDefault();
+ dispatch(showRegulaminDialog());
+ };
+
+ const validateForm = () => {
+ var valid;
+ const validations = {
+ firstname: !validator.isEmpty(formData.firstname),
+ lastname: !validator.isEmpty(formData.lastname),
+ email: validator.isEmail(formData.email),
+ password: validator.isLength(formData.password, {
+ min: 8,
+ max: 128,
+ }),
+ repeatPassword: formData.password === formData.repeatPassword,
+ };
+
+ setFormData({
+ ...formData,
+ firstnameError: !validations.firstname,
+ lastnameError: !validations.lastname,
+ emailError: !validations.email,
+ passwordError: !validations.password,
+ repeatPasswordError: !validations.repeatPassword,
+ });
+ valid =
+ validations.firstname &&
+ validations.lastname &&
+ validations.email &&
+ validations.password &&
+ validations.repeatPassword;
+
+ return valid;
+ };
+
+ const sendForm = (form) => {
+ if (validateForm()) {
+ dispatch(tryRegister(form));
+ } else {
+ dispatch(setRegisterResult("Proszę poprawić poprawić formularz."));
+ }
+ };
+
+ const openLogin = () => {
+ dispatch(hideRegisterDialog());
+ dispatch(showLoginDialog());
+ };
+
+ // CODE
+
+ return (
+
+
dispatch(hideRegisterDialog())}
+ open={registerDialog}
+ aria-labelledby="login-title"
+ >
+ Rejestracja
+ dispatch(hideRegisterDialog())}
+ aria-label="close"
+ >
+
+
+
+
+ {registerForm && (
+
+
+
+
+ ),
+ }}
+ error={formData.firstnameError}
+ onChange={(event) => (formData.firstname = event.target.value)}
+ />
+
+
+
+ ),
+ }}
+ error={formData.lastnameError}
+ onChange={(event) => (formData.lastname = event.target.value)}
+ />
+
+
+
+ ),
+ }}
+ error={formData.emailError}
+ onChange={(event) => (formData.email = event.target.value)}
+ />
+
+
+
+ ),
+ }}
+ error={formData.passwordError}
+ onChange={(event) => (formData.password = event.target.value)}
+ />
+
+
+
+ ),
+ }}
+ error={formData.repeatPasswordError}
+ onChange={(event) =>
+ (formData.repeatPassword = event.target.value)
+ }
+ />
+
+ )}
+ {registerResult}
+
+
+ {circularProgress &&
}
+ {registerForm && (
+
+ Rejestracja oznacza akceptację{" "}
+
+ handleRegulaminClick(event)}
+ >
+ regulaminu
+
+
+
+ )}
+
+ {registerForm ? (
+ sendForm(formData)}
+ text="Zarejestruj"
+ />
+ ) : (
+ openLogin()} text="Logowanie" />
+ )}
+
+
+
+
+
+ );
+}
diff --git a/src/components/Dialogs/Regulamin.js b/src/components/Dialogs/Regulamin.js
new file mode 100644
index 0000000..e24c2e5
--- /dev/null
+++ b/src/components/Dialogs/Regulamin.js
@@ -0,0 +1,53 @@
+import React from "react";
+
+export default function Regulamin() {
+ return (
+
+
1. Postanowienia ogólne
+
+ Sklep Internetowy "Nazwa Sklepu" działający pod adresem
+ www.twoja-domena.pl, prowadzony jest przez "nazwa -Firmy" Sp. z o.o. z
+ siedzibą w Bielsku-Białej, ul. Cieszyńska 367, wpisaną przez Sąd
+ Rejonowy w Bielsku-Białej, VIII Wydział Gospodarczy Krajowego Rejestru
+ Sądowego pod numerem KRS: 00000000001. NIP: numer 547-000-00-00. Regon
+ numer: 000000001.
+
+
2. Zwroty i reklamacje
+
+ Zwrot towaru. Zgodnie z Ustawą z 2 marca 2000 roku „o ochronie
+ niektórych praw konsumentów oraz o odpowiedzialności za szkodę
+ wyrządzoną przez produkt niebezpieczny”, klient może zrezygnować z
+ towaru kupionego w naszym sklepie bez podania przyczyny w ciągu 10 dni
+ od dnia odebrania przesyłki. Wzór oświadczenia o odstąpieniu stanowi
+ załącznik do niniejszego regulaminu. Jest to możliwe tylko wówczas, gdy
+ towar nie nosi śladów użytkowania, jest kompletny i nie został w żaden
+ sposób zniszczony. Zwracany towar należy odesłać razem z otrzymaną wraz
+ z nim fakturą. Sklep gwarantuje zwrot kwoty równej cenie towaru.
+ Pieniądze zostaną zwrócone w ciągu 5 dni roboczych przelewem bankowym na
+ konto wskazane przez klienta lub przekazem pocztowym na adres wskazany w
+ zamówieniu. Koszt odesłania towaru nie podlega zwrotowi.
+
+
3. Dane osobowe
+
+ Informujemy, że dane osobowe podane na formularzu zamówienia w sklepie
+ internetowym „Nazwa Sklepu”, są gromadzone i przetwarzane zgodnie z
+ Ustawą z dn. 29 sierpnia 1997r. o ochronie danych osobowych (Dz.U. z
+ 2002 roku nr 101 poz. 926 z późniejszymi zmianami). Zgromadzone dane
+ osobowe są wykorzystywane tylko i wyłącznie do celów realizacji
+ złożonych zamówień oraz informowania o promocjach i w żadnym wypadku nie
+ będą udostępniane osobom trzecim. Każdy klient naszego sklepu ma prawo
+ do wglądu, modyfikacji oraz usunięcia swoich danych osobowych z naszej
+ bazy danych.
+
+
4. Postanowienia końcowe
+
+ Wszystkie ceny podawane są w złotych polskich i zawierają podatek VAT.
+ Cena podana przy każdym towarze jest wiążąca w chwili złożenia
+ zamówienia przez klienta. Sklep zastrzega sobie prawo do zmiany cen
+ towarów znajdujących się w ofercie, wprowadzania nowych towarów do
+ oferty sklepu internetowego, przeprowadzania i odwoływania akcji
+ promocyjnych na stronach sklepu bądź wprowadzania w nich zmian.
+
+
+ );
+}
diff --git a/src/components/Dialogs/RegulaminDialog.js b/src/components/Dialogs/RegulaminDialog.js
new file mode 100644
index 0000000..5f98828
--- /dev/null
+++ b/src/components/Dialogs/RegulaminDialog.js
@@ -0,0 +1,69 @@
+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 IconButton from "@material-ui/core/IconButton";
+import CloseIcon from "@material-ui/icons/Close";
+import Paper from "@material-ui/core/Paper";
+import { useSelector, useDispatch } from "react-redux";
+import { hideRegulaminDialog } from "../../actions/toggles";
+import Regulamin from "./Regulamin";
+
+export default function RegulaminDialog(props) {
+ var regulaminDialog = useSelector((state) => state.data.dialogs.regulamin);
+ const dispatch = useDispatch();
+
+ const loginStyles = makeStyles((theme) => ({
+ root: {
+ textAlign: "center",
+ "& .MuiPaper-root": {
+ backgroundColor: "#262626",
+ color: "#bbbbbb",
+ },
+ "& .MuiFormHelperText-root": {
+ color: "#606060",
+ textAlign: "center",
+ },
+ },
+ closeButton: {
+ color: "#bbbbbb",
+ position: "absolute",
+ right: theme.spacing(1),
+ top: theme.spacing(1),
+ },
+ paper: {
+ textAlign: "left",
+ padding: "18px",
+ maxHeight: "50vh",
+ overflow: "auto",
+ },
+ }));
+
+ const styles = loginStyles();
+
+ return (
+
+
dispatch(hideRegulaminDialog())}
+ aria-labelledby="regulamin-title"
+ >
+ Regulamin
+ dispatch(hideRegulaminDialog())}
+ aria-label="close"
+ >
+
+
+
+
+ { }
+
+
+
+ );
+}
diff --git a/src/components/Social.js b/src/components/Social.js
new file mode 100644
index 0000000..8bcbdd1
--- /dev/null
+++ b/src/components/Social.js
@@ -0,0 +1,21 @@
+import React from "react";
+import FacebookIcon from "@material-ui/icons/Facebook";
+import TwitterIcon from "@material-ui/icons/Twitter";
+import InstagramIcon from "@material-ui/icons/Instagram";
+import IconButton from "@material-ui/core/IconButton";
+
+export default function Social(props) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/TopBar.js b/src/components/TopBar.js
index 0494655..cdbf970 100644
--- a/src/components/TopBar.js
+++ b/src/components/TopBar.js
@@ -1,4 +1,6 @@
import React from "react";
+import UserMenu from "./UserMenu";
+import Social from "./Social";
import logo from "../public/logo_white.svg";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";
@@ -13,24 +15,25 @@ import ListItemIcon from "@material-ui/core/ListItemIcon";
import HomeIcon from "@material-ui/icons/Home";
import MailIcon from "@material-ui/icons/Mail";
import PaymentIcon from "@material-ui/icons/Payment";
-import FastfoodIcon from "@material-ui/icons/Fastfood";
-import AddCircleIcon from "@material-ui/icons/AddCircle";
-import FacebookIcon from "@material-ui/icons/Facebook";
-import TwitterIcon from "@material-ui/icons/Twitter";
-import InstagramIcon from "@material-ui/icons/Instagram";
-import { showLoginDialog } from "../actions/toggles";
+import { showLoginDialog, showRegisterDialog } from "../actions/toggles";
import { logout } from "../actions";
import { makeStyles } from "@material-ui/core/styles";
import ButtonSecondary from "./ButtonSecondary";
+import ListSubheader from "@material-ui/core/ListSubheader";
const useStyles = makeStyles((theme) => ({
paper: {
backgroundColor: "#262626",
color: "#bbbbbb",
"& .MuiListItemIcon-root": {
- color: "#01c3a9",
+ color: "#d68000",
},
},
+ subheader: {
+ color: "#767676",
+ fontSize: "0.8rem",
+ fontWeight: "400",
+ },
}));
export default function TopBar() {
@@ -50,6 +53,9 @@ export default function TopBar() {
case "logIn":
dispatch(showLoginDialog());
break;
+ case "register":
+ dispatch(showRegisterDialog());
+ break;
case "logOut":
dispatch(logout());
break;
@@ -108,7 +114,14 @@ export default function TopBar() {
onClose={toggleDrawer(false)}
PaperProps={{ className: classes.paper }}
>
-
+
+ Nawigacja
+
+ }
+ >
handleClick("menui")}>
@@ -119,7 +132,7 @@ export default function TopBar() {
-
+
handleClick("pricing")}>
@@ -128,47 +141,30 @@ export default function TopBar() {
- {loggedIn && (
- handleClick("myRestaurant")}>
-
-
-
-
-
- )}
- {loggedIn && (
- handleClick("addDish")}>
-
-
-
-
-
- )}
+ {loggedIn && }
-
- {!loggedIn && (
- handleClick("logIn")}
- text="Zaloguj się"
- />
- )}
- {loggedIn && (
- handleClick("logOut")}
- text="Wyloguj"
- />
- )}
-
-
-
-
-
-
-
-
-
-
+
+ {!loggedIn && (
+ handleClick("logIn")}
+ text="Logowanie"
+ />
+ )}
+ {!loggedIn && (
+ handleClick("register")}
+ text="Rejestracja"
+ />
+ )}
+ {loggedIn && (
+ handleClick("logOut")}
+ text="Wyloguj"
+ />
+ )}
+
+
diff --git a/src/components/UserMenu.js b/src/components/UserMenu.js
new file mode 100644
index 0000000..743ed6f
--- /dev/null
+++ b/src/components/UserMenu.js
@@ -0,0 +1,71 @@
+import React, { useState } from "react";
+import Collapse from "@material-ui/core/Collapse";
+import { makeStyles } from "@material-ui/core/styles";
+import List from "@material-ui/core/List";
+import ListItem from "@material-ui/core/ListItem";
+import ListSubheader from "@material-ui/core/ListSubheader";
+import ListItemIcon from "@material-ui/core/ListItemIcon";
+import ListItemText from "@material-ui/core/ListItemText";
+import ExpandLess from "@material-ui/icons/ExpandLess";
+import ExpandMore from "@material-ui/icons/ExpandMore";
+import FastfoodIcon from "@material-ui/icons/Fastfood";
+import AddIcon from "@material-ui/icons/Add";
+import SettingsIcon from "@material-ui/icons/Settings";
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ width: "100%",
+ },
+ nested: {
+ paddingLeft: theme.spacing(4),
+ },
+ subheader: {
+ color: "#767676",
+ fontSize: "0.8rem",
+ fontWeight: "400",
+ paddingLeft: 0,
+ },
+}));
+
+export default function UserMenu(props) {
+ const [open, setOpen] = useState(false);
+ const classes = useStyles();
+ const handleClick = () => {
+ setOpen(!open);
+ };
+
+ return (
+
+ Menu użytkownika
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+ {open ? : }
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/reducers/data.js b/src/reducers/data.js
index 8e3ff29..09c699d 100644
--- a/src/reducers/data.js
+++ b/src/reducers/data.js
@@ -3,11 +3,18 @@ const initialState = {
loggedIn: false,
jwt: "",
username: "",
+ userId: "",
+ userEmail: "",
dialogs: {
logIn: false,
register: false,
contact: false,
pricing: false,
+ regulamin: false,
+ registerCircularProgress: false,
+ registerForm: true,
+ registerResult: "",
+ loginResult: "",
},
};
@@ -20,14 +27,73 @@ const data = (state = initialState, action) => {
case "DIALOG_LOGIN_VISIBLE":
return (state = { ...state, dialogs: { ...state.dialogs, logIn: true } });
case "SET_LOGGEDIN":
- return (state = { ...state, loggedIn: true, username: action.payload });
+ return (state = {
+ ...state,
+ loggedIn: true,
+ username: action.payload.username,
+ jwt: action.payload.jwt,
+ userEmail: action.payload.email,
+ userId: action.payload.id,
+ });
case "SET_LOGGEDOUT":
- return (state = { ...state, loggedIn: false, username: "" });
+ return (state = {
+ ...state,
+ loggedIn: false,
+ username: "",
+ jwt: "",
+ userEmail: "",
+ userId: "",
+ });
case "DIALOG_LOGIN_HIDDEN":
return (state = {
...state,
dialogs: { ...state.dialogs, logIn: false },
});
+ case "DIALOG_REGISTER_VISIBLE":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, register: true },
+ });
+ case "DIALOG_REGISTER_HIDDEN":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, register: false },
+ });
+ case "DIALOG_REGULAMIN_VISIBLE":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, regulamin: true },
+ });
+ case "DIALOG_REGULAMIN_HIDDEN":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, regulamin: false },
+ });
+ case "DIALOG_REGISTER_CIRCLE_SHOW":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, registerCircularProgress: true },
+ });
+ case "DIALOG_REGISTER_CIRCLE_HIDE":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, registerCircularProgress: false },
+ });
+ case "DIALOG_REGISTER_FORM_HIDE":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, registerForm: false },
+ });
+ case "DIALOG_REGISTER_SET_RESULT":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, registerResult: action.payload },
+ });
+ case "DIALOG_LOGIN_SET_RESULT":
+ return (state = {
+ ...state,
+ dialogs: { ...state.dialogs, loginResult: action.payload },
+ });
default:
return state;
}
diff --git a/src/styles/Dialogs.scss b/src/styles/Dialogs.scss
index 8c9abf0..0d4284c 100644
--- a/src/styles/Dialogs.scss
+++ b/src/styles/Dialogs.scss
@@ -4,4 +4,22 @@
.login-dialog-buttons {
display: flex;
justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ p {
+ font-size: 0.8rem;
+ }
+}
+
+.register-dialog-actions {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ p {
+ font-size: 0.8rem;
+ }
+}
+
+.regulamin {
}
diff --git a/src/styles/TopBar.scss b/src/styles/TopBar.scss
index 6e9c272..a92e53d 100644
--- a/src/styles/TopBar.scss
+++ b/src/styles/TopBar.scss
@@ -50,6 +50,7 @@
margin-bottom: 20px;
display: flex;
justify-content: center;
+ flex-direction: column;
position: absolute;
bottom: 0;
}
@@ -58,3 +59,11 @@
margin-left: auto;
margin-right: auto;
}
+
+.social-container {
+ width: 100%;
+ margin-bottom: 20px;
+ margin-top: 20px;
+ display: flex;
+ justify-content: center;
+}