fixes / register user

This commit is contained in:
2021-02-08 15:48:21 +01:00
parent f25196f57e
commit ab0f65e247
10 changed files with 310 additions and 72 deletions

View File

@@ -21,8 +21,15 @@ axios.interceptors.response.use(
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(logout());
})
});
@@ -196,23 +203,47 @@ export const tryLogin = (username, password) => {
axios
.post(backend + "user/login", data)
.then((response) => {
const jwt = response.headers["x-auth-token"];
dispatch(
if(response.data.isRestaurant === true){
const jwt = response.headers["x-auth-token"];
dispatch(
toggles.setLoggedIn(
response.data.firstname,
response.data.lastname,
jwt,
response.data.id,
response.data.email,
"",
response.data.NIP,
response.data.adress,
response.data.companyName,
response.data.restaurants
response.data.restaurants,
response.data.isRestaurant
)
);
dispatch(toggles.hideBackdrop());
dispatch(notification(`Witaj ${response.data.firstname}!`, "success"));
dispatch(push("/"));
} else {
const jwt = response.headers["x-auth-token"];
dispatch(
toggles.setLoggedIn(
"",
"",
jwt,
response.data.id,
response.data.email,
response.data.login,
"",
"",
"",
[],
response.data.isRestaurant
)
);
dispatch(toggles.hideBackdrop());
dispatch(notification(`Witaj ${response.data.login}!`, "success"));
dispatch(push("/"));
}
})
.catch((err) => {
if (!err.response) {
@@ -220,7 +251,7 @@ export const tryLogin = (username, password) => {
} else if (err.response.status === 404) {
dispatch(toggles.hideBackdrop());
dispatch(notification("Użytkownik nie istnieje :(", "error"));
} else if (err.response.status === 401) {
} else if (err.response.status === 403) {
dispatch(toggles.hideBackdrop());
dispatch(notification("Błędne dane logowania :(", "error"));
} else {
@@ -269,9 +300,13 @@ export const changePassword = (email, password, token) => {
};
};
export const logout = () => {
export const logout = (message, type) => {
return function (dispatch) {
dispatch(notification("Wylogowano.", "info"));
if(message && type){
dispatch(notification(message, type));
} else {
dispatch(notification("Wylogowano.", "info"));
}
dispatch(toggles.hideBackdrop());
dispatch(toggles.setLoggedOut());
dispatch(push("/"));
@@ -292,6 +327,7 @@ export const tryRegister = (data) => {
)
);
dispatch(toggles.hideBackdrop());
dispatch(push("/"))
}
})
.catch((err) => {

View File

@@ -16,10 +16,12 @@ export const setLoggedIn = (
jwt,
userId,
email,
login,
NIP,
adress,
companyName,
restaurants
restaurants,
isRestaurant
) => {
return {
type: "SET_LOGGEDIN",
@@ -29,10 +31,12 @@ export const setLoggedIn = (
jwt: jwt,
userId: userId,
email: email,
login: login,
NIP: NIP,
adress: adress,
companyName: companyName,
restaurants: restaurants,
isRestaurant: isRestaurant
},
};
};

View File

@@ -19,8 +19,13 @@ import LockIcon from "@material-ui/icons/Lock";
import Link from "@material-ui/core/Link";
import validator from "validator";
import { useHistory } from "react-router-dom";
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Checkbox from '@material-ui/core/Checkbox';
export default function RegisterDialog(props) {
const [currentTab, setTab] = useState(0);
const [termsAccepted, setTermsAccepted] = useState(0);
const initialFormData = {
firstname: "",
lastname: "",
@@ -28,8 +33,10 @@ export default function RegisterDialog(props) {
adress: "",
NIP: "",
email: "",
login: "",
password: "",
repeatPassword: "",
isRestaurant: false,
firstnameError: false,
lastnameError: false,
companyNameError: false,
@@ -38,6 +45,7 @@ export default function RegisterDialog(props) {
emailError: false,
passwordError: false,
repeatPasswordError: false,
loginError: false
};
const [formData, setFormData] = useState(initialFormData);
const dispatch = useDispatch();
@@ -92,44 +100,115 @@ export default function RegisterDialog(props) {
const validateForm = () => {
var valid;
const validations = {
firstname: !validator.isEmpty(formData.firstname),
lastname: !validator.isEmpty(formData.lastname),
companyName: !validator.isEmpty(formData.companyName),
adress: !validator.isEmpty(formData.adress),
NIP: !validator.isEmpty(formData.NIP),
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,
companyNameError: !validations.companyName,
adressError: !validations.adress,
NIPError: !validations.NIP,
emailError: !validations.email,
passwordError: !validations.password,
repeatPasswordError: !validations.repeatPassword,
});
valid =
validations.firstname &&
validations.lastname &&
validations.email &&
validations.password &&
validations.repeatPassword &&
validations.companyName &&
validations.adress &&
validations.NIP;
if(currentTab === 1){
const validations = {
firstname: !validator.isEmpty(formData.firstname),
lastname: !validator.isEmpty(formData.lastname),
companyName: !validator.isEmpty(formData.companyName),
adress: !validator.isEmpty(formData.adress),
NIP: !validator.isEmpty(formData.NIP),
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,
companyNameError: !validations.companyName,
adressError: !validations.adress,
NIPError: !validations.NIP,
emailError: !validations.email,
passwordError: !validations.password,
repeatPasswordError: !validations.repeatPassword,
});
valid =
validations.firstname &&
validations.lastname &&
validations.email &&
validations.password &&
validations.repeatPassword &&
validations.companyName &&
validations.adress &&
validations.NIP;
} else {
const validations = {
email: validator.isEmail(formData.email),
login: validator.isLength(formData.login),
password: validator.isLength(formData.password, {
min: 8,
max: 128,
}),
repeatPassword: formData.password === formData.repeatPassword,
};
setFormData({
...formData,
emailError: !validations.email,
loginError: !validations.login,
passwordError: !validations.password,
repeatPasswordError: !validations.repeatPassword,
});
valid =
validations.email &&
validations.password &&
validations.repeatPassword &&
validations.login
}
return valid;
};
const handleTabChange = (event, newValue) => {
if(newValue === 0){
setFormData({
...formData,
firstname: "",
lastname: "",
companyName: "",
adress: "",
NIP: "",
firstnameError: false,
lastnameError: false,
companyNameError: false,
adressError: false,
NIPError: false,
emailError: false,
passwordError: false,
repeatPasswordError: false,
loginError: false,
isRestaurant: false
})
} else if(newValue === 1){
setFormData({
...formData,
firstname: "",
lastname: "",
companyName: "",
adress: "",
NIP: "",
firstnameError: false,
lastnameError: false,
companyNameError: false,
adressError: false,
NIPError: false,
emailError: false,
passwordError: false,
repeatPasswordError: false,
loginError: false,
isRestaurant: true
})
}
setTab(newValue)
}
const handleCheckboxChange = () => {
setTermsAccepted(!termsAccepted);
}
const sendForm = (form) => {
if (validateForm()) {
dispatch(tryRegister(form));
@@ -158,7 +237,84 @@ export default function RegisterDialog(props) {
</IconButton>
<Divider />
<DialogContent>
<div>
<Tabs onChange={handleTabChange} value={currentTab} indicatorColor="primary" textColor="primary" centered>
<Tab label="Użytkownik" value={0}/>
<Tab label="Restauracja" value={1}/>
</Tabs>
<Divider />
{currentTab === 0 && (<div>
<TextField
className={loginClass.textInput}
required
id="login"
label="Nazwa użytkownika"
type="name"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<AccountCircle color="primary" />
</InputAdornment>
),
}}
error={formData.firstnameError}
onChange={(event) => (formData.login = 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>)}
{currentTab === 1 && (<div>
<TextField
className={loginClass.textInput}
required
@@ -297,19 +453,23 @@ export default function RegisterDialog(props) {
(formData.repeatPassword = event.target.value)
}
/>
</div>
</div>)}
<Divider />
<div className="register-dialog-actions">
<div className="register-dialog-checkbox">
<Checkbox checked={termsAccepted} onChange={handleCheckboxChange}/>
<p>
Rejestracja oznacza akceptację{" "}
Przeczytałem i akceptuję postanowienia{" "}
<span>
<Link href="#" onClick={(event) => handleRegulaminClick(event)}>
regulaminu
regulaminu.
</Link>
</span>
</p>
</div>
<div className="register-dialog-button">
<ButtonSecondary
disabled={!termsAccepted}
onClick={() => sendForm(formData)}
text="Zarejestruj"
/>
@@ -319,4 +479,4 @@ export default function RegisterDialog(props) {
</Dialog>
</div>
);
}
}

View File

@@ -83,15 +83,24 @@ export default function Settings() {
});
const history = useHistory();
const style = useStyles();
const isRestaurant = useSelector((store) => store.data.userData.isRestaurant)
const data = useSelector((state) => state.data.userData);
const initialState = {
firstname: data.firstname,
lastname: data.lastname,
email: data.userEmail,
NIP: data.billing.NIP,
adress: data.billing.adress,
companyName: data.billing.companyName,
};
let initialState;
if(isRestaurant === true) {
initialState = {
firstname: data.firstname,
lastname: data.lastname,
email: data.userEmail,
NIP: data.billing.NIP,
adress: data.billing.adress,
companyName: data.billing.companyName,
};
} else {
initialState = {
email: data.userEmail,
login: data.login,
};
}
const [state, setState] = useState(initialState);
return (
<Dialog aria-labelledby="settings-title" className={style.root} open={true}>
@@ -104,7 +113,7 @@ export default function Settings() {
<CloseIcon />
</IconButton>
<Divider />
<DialogContent>
{isRestaurant && (<DialogContent>
<TextField
className={style.textInput}
value={state.firstname}
@@ -202,7 +211,28 @@ export default function Settings() {
<Divider />
<ButtonPrimary onClick={() => history.goBack()} text="Anuluj" />
<ButtonSecondary text="Zapisz" />
</DialogContent>
</DialogContent>)}
{!isRestaurant && (<DialogContent>
<TextField
className={style.textInput}
value={state.email}
onChange={(event) =>
setState({ ...state, email: event.target.value })
}
label="Email"
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<AlternateEmailIcon color="primary"/>
</InputAdornment>
)
}}
/>
<Divider />
<ButtonPrimary onClick={() => history.goBack()} text="Anuluj" />
<ButtonSecondary text="Zapisz" />
</DialogContent>)}
</Dialog>
);
}

View File

@@ -4,7 +4,7 @@ export default class Footer extends React.Component {
render() {
return (
<div className="footer">
<p>Menui (wersja testowa aplikacji)</p>
<p>Bankai Software @2021 | Menui (v0.6.0)</p>
</div>
);
}

View File

@@ -39,7 +39,9 @@ const useStyles = makeStyles((theme) => ({
export default function TopBar() {
const classes = useStyles();
const loggedIn = useSelector((state) => state.data.loggedIn);
const username = useSelector((state) => state.data.userData.firstname);
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 history = useHistory();
const dispatch = useDispatch();
const handleClick = (button) => {
@@ -95,13 +97,13 @@ export default function TopBar() {
onClick={() => history.push("/")}
/>
<div className="vertical-divider"></div>
<h5>Food guide (wersja testowa)</h5>
<h5>Food guide</h5>
</div>
<div className="topBar-hamburger">
{loggedIn && (
<div className="topbar-username">
{" "}
<p>Witaj {username}</p>{" "}
<p>Witaj {isRestaurant ? firstname : login}</p>{" "}
</div>
)}
<IconButton onClick={toggleDrawer(true)} aria-label="menu">

View File

@@ -32,6 +32,7 @@ const useStyles = makeStyles((theme) => ({
export default function UserMenu(props) {
const restaurants = useSelector((state) => state.data.userData.restaurants);
const isRestaurant = useSelector((state) => state.data.userData.isRestaurant);
const [open, setOpen] = useState(true);
const classes = useStyles();
const handleClick = () => {
@@ -74,14 +75,14 @@ export default function UserMenu(props) {
</ListItemIcon>
<ListItemText primary="Ustawienia konta" />
</ListItem>
<ListItem button onClick={handleClick} disableGutters>
{isRestaurant && <ListItem button onClick={handleClick} disableGutters>
<ListItemIcon>
<FastfoodIcon />
</ListItemIcon>
<ListItemText primary="Moje restauracje" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
</ListItem>}
{isRestaurant && <Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button onClick={() => handleButtonClick("/newRestaurant")}>
<ListItemIcon>
@@ -89,9 +90,9 @@ export default function UserMenu(props) {
</ListItemIcon>
<ListItemText primary="Dodaj restaurację" />
</ListItem>
{viewRestaurants}
{isRestaurant && viewRestaurants}
</List>
</Collapse>
</Collapse>}
</List>
);
}

View File

@@ -1,5 +1,5 @@
export const backend = "https://api.menui.pl/";
//export const backend = "http://localhost:4000/";
//export const backend = "https://api.menui.pl/";
export const backend = "http://localhost:4000/";
export const restaurantTypes = [
"afrykańska",

View File

@@ -1,9 +1,6 @@
const initialState = {
showDishList: false,
loggedIn: false,
username: "",
userId: "",
userEmail: "",
userData: {
jwt: "",
firstname: "",
@@ -16,6 +13,7 @@ const initialState = {
companyName: "",
},
restaurants: [],
isRestaurant: false
},
dialogs: {
regulamin: false,
@@ -44,12 +42,14 @@ const data = (state = initialState, action) => {
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":
@@ -68,6 +68,7 @@ const data = (state = initialState, action) => {
companyName: "",
},
restaurants: [],
isRestaurant: false
},
});
case "DIALOG_REGULAMIN_SHOW":

View File

@@ -23,4 +23,8 @@
p {
font-size: 0.8rem;
}
}
.register-dialog-checkbox{
display: flex;
}