Login / Register / SideMenu / Fixes

This commit is contained in:
2020-08-09 17:50:53 +02:00
parent e5a68f4b85
commit 769be397e5
19 changed files with 960 additions and 160 deletions

View File

@@ -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 (
<div>
<Dialog
className={loginClass.root}
onClose={() => dispatch(hideLoginDialog())}
open={loginDialog}
aria-labelledby="login-title"
>
<DialogTitle id="login-title">Logowanie</DialogTitle>
<IconButton
className={loginClass.closeButton}
onClick={() => dispatch(hideLoginDialog())}
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>
),
}}
/>
<p>{loginResult}</p>
<div className="login-dialog-buttons">
<ButtonSecondary onClick={() => handleLogin()} text="Zaloguj" />
</div>
<Link
className={loginClass.link}
href="#"
onClick={() => handleRegisterClick()}
>
Nie pamiętam hasła.
</Link>
<p>
Nie masz konta?{" "}
<span>
<Link href="#" onClick={() => handleRegisterClick()}>
Zarejestruj się.
</Link>
</span>
</p>
</DialogContent>
</Dialog>
</div>
);
}

View File

@@ -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 (
<div>
<Dialog
className={loginClass.root}
onClose={() => dispatch(hideRegisterDialog())}
open={registerDialog}
aria-labelledby="login-title"
>
<DialogTitle id="login-title">Rejestracja</DialogTitle>
<IconButton
className={loginClass.closeButton}
onClick={() => dispatch(hideRegisterDialog())}
aria-label="close"
>
<CloseIcon />
</IconButton>
<Divider />
<DialogContent>
{registerForm && (
<div>
<TextField
className={loginClass.textInput}
required
id="firstname"
label="Imię"
type="name"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<AccountCircle color="primary" />
</InputAdornment>
),
}}
error={formData.firstnameError}
onChange={(event) => (formData.firstname = event.target.value)}
/>
<TextField
className={loginClass.textInput}
required
id="lastname"
label="Nazwisko"
type="name"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<AccountCircle color="primary" />
</InputAdornment>
),
}}
error={formData.lastnameError}
onChange={(event) => (formData.lastname = event.target.value)}
/>
<TextField
className={loginClass.textInput}
required
id="email"
label="Email"
type="email"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<EmailIcon color="primary" />
</InputAdornment>
),
}}
error={formData.emailError}
onChange={(event) => (formData.email = event.target.value)}
/>
<TextField
className={loginClass.textInput}
required
id="password"
label="Hasło (min. 8 znaków)"
type="password"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<LockIcon color="primary" />
</InputAdornment>
),
}}
error={formData.passwordError}
onChange={(event) => (formData.password = event.target.value)}
/>
<TextField
className={loginClass.textInput}
required
id="repeat-password"
label="Powtórz hasło"
type="password"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<LockIcon color="primary" />
</InputAdornment>
),
}}
error={formData.repeatPasswordError}
onChange={(event) =>
(formData.repeatPassword = event.target.value)
}
/>
</div>
)}
<p>{registerResult}</p>
<Divider />
<div className="register-dialog-actions">
{circularProgress && <CircularProgress />}
{registerForm && (
<p>
Rejestracja oznacza akceptację{" "}
<span>
<Link
href="#"
onClick={(event) => handleRegulaminClick(event)}
>
regulaminu
</Link>
</span>
</p>
)}
<div className="register-dialog-button">
{registerForm ? (
<ButtonSecondary
onClick={() => sendForm(formData)}
text="Zarejestruj"
/>
) : (
<ButtonSecondary onClick={() => openLogin()} text="Logowanie" />
)}
</div>
</div>
</DialogContent>
</Dialog>
</div>
);
}

View File

@@ -0,0 +1,53 @@
import React from "react";
export default function Regulamin() {
return (
<div className="regulamin">
<h3>1. Postanowienia ogólne</h3>
<p>
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.
</p>
<h3>2. Zwroty i reklamacje</h3>
<p>
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.
</p>
<h3>3. Dane osobowe</h3>
<p>
Informujemy, że dane osobowe podane na formularzu zamówienia w sklepie
internetowym Nazwa Sklepu, 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 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.
</p>
<h3>4. Postanowienia końcowe</h3>
<p>
Wszystkie ceny podawane 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.
</p>
</div>
);
}

View File

@@ -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 (
<div>
<Dialog
className={styles.root}
open={regulaminDialog}
onClose={() => dispatch(hideRegulaminDialog())}
aria-labelledby="regulamin-title"
>
<DialogTitle id="regulamin-title">Regulamin</DialogTitle>
<IconButton
className={styles.closeButton}
onClick={() => dispatch(hideRegulaminDialog())}
aria-label="close"
>
<CloseIcon />
</IconButton>
<Divider />
<DialogContent>
<Paper className={styles.paper}>{<Regulamin />}</Paper>
</DialogContent>
</Dialog>
</div>
);
}