Skip to content

Commit ecfc079

Browse files
authored
Merge pull request #120 from kube-js/develop
fix: added loginForm modal to cart page
2 parents 6e4d127 + 19e0341 commit ecfc079

File tree

20 files changed

+187
-137
lines changed

20 files changed

+187
-137
lines changed

k8s/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v1
22
description: A Helm chart for kube-ts-react-client
33
name: kube-ts-react-client
44
version: 1.0.0
5-
appVersion: 1.6.20
5+
appVersion: 1.6.22
66
home: https://cloud.docker.com/u/kubejs/repository/docker/kubejs/kube-ts-react-client
77
icon: https://avatars2.githubusercontent.com/u/47761918?s=200&v=4
88
sources:

k8s/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ replicaCount: 2
66

77
image:
88
repository: kubejs/kube-ts-react-client
9-
tag: 1.6.20
9+
tag: 1.6.22
1010
pullPolicy: Always
1111
containerPort: 80
1212

src/app.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ import {
2222
ROOT,
2323
VERIFY,
2424
} from './constants/routes';
25-
import Home from './containers/Home';
26-
import Loading from './containers/Loading';
27-
import Login from './containers/Login';
28-
import NotFound from './containers/NotFound';
29-
import Notifier from './containers/Notifier';
30-
import Register from './containers/Register';
25+
import Home from './pages/Home';
26+
import Loading from './pages/Loading';
27+
import Login from './pages/Login';
28+
import NotFound from './pages/NotFound';
29+
import Notifier from './pages/Notifier';
30+
import Register from './pages/Register';
3131

32-
const RemindPassword = lazy(() => import('./containers/RemindPassword'));
33-
const ResetPassword = lazy(() => import('./containers/ResetPassword'));
34-
const VerifyAccount = lazy(() => import('./containers/VerifyAccount'));
35-
const Dashboard = lazy(() => import('./containers/Dashboard'));
32+
const RemindPassword = lazy(() => import('./pages/RemindPassword'));
33+
const ResetPassword = lazy(() => import('./pages/ResetPassword'));
34+
const VerifyAccount = lazy(() => import('./pages/VerifyAccount'));
35+
const Dashboard = lazy(() => import('./pages/Dashboard'));
3636

3737
const App = () => (
3838
<Fragment>

src/components/CartCheckoutSidebar/index.tsx

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,29 @@
22
import { Button, Typography } from '@material-ui/core';
33
import Paper from '@material-ui/core/Paper';
44
import _isNil from 'ramda/src/isNil';
5-
import React from 'react';
5+
import React, { useRef } from 'react';
66
import { useTranslation } from 'react-i18next';
7-
import { useHistory } from 'react-router';
7+
import { useSelector } from 'react-redux';
8+
import { Redirect, useHistory } from 'react-router';
89
import { CHECKOUT } from '../../constants/routes';
10+
import { State } from '../../redux/rootReducer';
911
import sumBy from '../../utils/helpers/sumBy';
12+
import LoginForm from '../LoginForm';
13+
import Modal from '../Modal';
1014
import useStyles from './styles';
1115

1216
const CartItems = ({ items }: any) => {
1317
const classes = useStyles();
1418
const { t } = useTranslation();
1519
const history = useHistory();
20+
const noUser = useRef({});
21+
22+
const { user } = useSelector(({ auth }: State) => auth);
23+
24+
if (!user) {
25+
noUser.current = true;
26+
}
27+
1628
const courses = items.length === 1 ? t('cart.item') : t('cart.items');
1729
const total = sumBy('price')(items);
1830

@@ -21,15 +33,41 @@ const CartItems = ({ items }: any) => {
2133
history.push(url);
2234
};
2335

36+
if (noUser.current === true && !_isNil(user)) {
37+
return <Redirect push to={CHECKOUT} />;
38+
}
39+
2440
return (
2541
<Paper className={classes.paper} square>
2642
<Typography>
2743
{t('cart.total')} ({items.length} {courses}): £{total.toFixed(2)}
2844
</Typography>
2945

30-
<Button variant="contained" fullWidth color="secondary" onClick={goTo(CHECKOUT)}>
31-
{t('cart.proceedToCheckout')}
32-
</Button>
46+
{!_isNil(user) ? (
47+
<Button
48+
variant="contained"
49+
fullWidth
50+
color="secondary"
51+
onClick={goTo(CHECKOUT)}
52+
>
53+
{t('cart.proceedToCheckout')}
54+
</Button>
55+
) : (
56+
<Modal
57+
renderCta={({ handleClickOpen }: any) => (
58+
<Button
59+
variant="contained"
60+
fullWidth
61+
color="secondary"
62+
onClick={handleClickOpen}
63+
>
64+
{t('cart.proceedToCheckout')}
65+
</Button>
66+
)}
67+
>
68+
<LoginForm />
69+
</Modal>
70+
)}
3371
</Paper>
3472
);
3573
};

src/components/CartView/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// tslint:disable:no-magic-numbers
22
import { Container, Grid, Typography } from '@material-ui/core';
33
import _isNil from 'ramda/src/isNil';
4-
import React, { memo } from 'react';
4+
import React from 'react';
55
import { useTranslation } from 'react-i18next';
66
import { useDispatch, useSelector } from 'react-redux';
77
import { removeCartItem } from '../../redux/cart/actionCreators';
@@ -59,4 +59,4 @@ const CartView = () => {
5959
};
6060

6161
// tslint:disable-next-line:max-file-line-count
62-
export default memo(CartView);
62+
export default CartView;

src/components/LoginForm/index.tsx

Lines changed: 88 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,119 @@
1-
// tslint:disable:no-magic-numbers
2-
/* istanbul ignore next */
31
import Avatar from '@material-ui/core/Avatar';
42
import Button from '@material-ui/core/Button';
5-
import Container from '@material-ui/core/Container';
6-
import CssBaseline from '@material-ui/core/CssBaseline';
73
import Grid from '@material-ui/core/Grid';
84
import TextField from '@material-ui/core/TextField';
95
import Typography from '@material-ui/core/Typography';
106
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
117
import { Formik } from 'formik';
8+
import _isNil from 'ramda/src/isNil';
129
import React from 'react';
1310
import { useTranslation } from 'react-i18next';
14-
import { RouteProps } from 'react-router';
11+
import { useDispatch, useSelector } from 'react-redux';
1512
import { Link } from 'react-router-dom';
1613
import PasswordField from '../../atoms/PasswordField';
1714
import { REGISTER, REMIND_PASSWORD } from '../../constants/routes';
1815
import { LoginOptions, loginRequested } from '../../redux/auth/actionCreators';
19-
import { AuthState } from '../../redux/auth/reducer';
16+
import { State } from '../../redux/rootReducer';
2017
import loginSchema from '../../utils/schemas/login';
2118
import useStyles from './styles';
2219

23-
interface LoginFormProps extends AuthState, RouteProps {
24-
readonly login: (options: LoginOptions) => ReturnType<typeof loginRequested>;
25-
}
26-
27-
const LoginForm = (props: LoginFormProps) => {
20+
const LoginForm = () => {
2821
const classes = useStyles();
22+
2923
const { t } = useTranslation();
3024

31-
const { loginLoading, login } = props;
25+
const { loginLoading } = useSelector(({ auth }: State) => auth);
26+
27+
const dispatch = useDispatch();
28+
29+
const login = (options: LoginOptions) => dispatch(loginRequested(options));
3230

3331
return (
34-
<Container component="main" maxWidth="xs">
35-
<CssBaseline />
36-
<div className={classes.paper}>
37-
<Avatar className={classes.avatar}>
38-
<LockOutlinedIcon />
39-
</Avatar>
32+
<div className={classes.paper}>
33+
<Avatar className={classes.avatar}>
34+
<LockOutlinedIcon />
35+
</Avatar>
4036

41-
<Typography component="h1" variant="h5">
42-
{t('auth.login')}
43-
</Typography>
37+
<Typography component="h1" variant="h5">
38+
{t('auth.login')}
39+
</Typography>
4440

45-
<Formik
46-
validationSchema={loginSchema}
47-
initialValues={{ email: '', password: '' }}
48-
validateOnChange={false}
49-
onSubmit={login}
50-
render={({
51-
handleSubmit,
52-
handleChange,
53-
handleBlur,
54-
values,
55-
errors,
56-
touched,
57-
}) => {
58-
const hasEmailError = Boolean(errors.email && touched.email);
59-
const hasPasswordError = Boolean(
60-
errors.password && touched.password
61-
);
41+
<Formik
42+
validationSchema={loginSchema}
43+
initialValues={{ email: '', password: '' }}
44+
validateOnChange={false}
45+
onSubmit={login}
46+
render={({
47+
handleSubmit,
48+
handleChange,
49+
handleBlur,
50+
values,
51+
errors,
52+
touched,
53+
}) => {
54+
const hasEmailError = Boolean(errors.email && touched.email);
55+
const hasPasswordError = Boolean(errors.password && touched.password);
6256

63-
return (
64-
<form className={classes.form} noValidate onSubmit={handleSubmit}>
65-
<TextField
66-
helperText={errors.email}
67-
error={hasEmailError}
68-
variant="outlined"
69-
margin="normal"
70-
required
71-
fullWidth
72-
id="email"
73-
label={t('auth.email')}
74-
name="email"
75-
autoComplete="email"
76-
autoFocus
77-
value={values.email}
78-
onChange={handleChange}
79-
onBlur={handleBlur}
80-
/>
57+
return (
58+
<form className={classes.form} noValidate onSubmit={handleSubmit}>
59+
<TextField
60+
helperText={errors.email}
61+
error={hasEmailError}
62+
variant="outlined"
63+
margin="normal"
64+
required
65+
fullWidth
66+
id="email"
67+
label={t('auth.email')}
68+
name="email"
69+
autoComplete="email"
70+
autoFocus
71+
value={values.email}
72+
onChange={handleChange}
73+
onBlur={handleBlur}
74+
/>
8175

82-
<PasswordField
83-
helperText={errors.password}
84-
error={hasPasswordError}
85-
variant="outlined"
86-
margin="normal"
87-
required
88-
fullWidth
89-
name="password"
90-
label={t('auth.password')}
91-
id="password"
92-
autoComplete="current-password"
93-
value={values.password}
94-
onChange={handleChange}
95-
onBlur={handleBlur}
96-
/>
76+
<PasswordField
77+
helperText={errors.password}
78+
error={hasPasswordError}
79+
variant="outlined"
80+
margin="normal"
81+
required
82+
fullWidth
83+
name="password"
84+
label={t('auth.password')}
85+
id="password"
86+
autoComplete="current-password"
87+
value={values.password}
88+
onChange={handleChange}
89+
onBlur={handleBlur}
90+
/>
9791

98-
<Button
99-
disabled={loginLoading}
100-
type="submit"
101-
fullWidth
102-
variant="contained"
103-
color="primary"
104-
size="large"
105-
className={classes.submit}
106-
>
107-
{t('auth.loginAction')}
108-
</Button>
92+
<Button
93+
disabled={loginLoading}
94+
type="submit"
95+
fullWidth
96+
variant="contained"
97+
color="primary"
98+
size="large"
99+
className={classes.submit}
100+
>
101+
{t('auth.loginAction')}
102+
</Button>
109103

110-
<Grid container>
111-
<Grid item xs>
112-
<Link to={REMIND_PASSWORD}>
113-
{t('auth.forgotPassword')}
114-
</Link>
115-
</Grid>
116-
<Grid item>
117-
<Link to={REGISTER}>{t('auth.dontHaveAccount')}</Link>
118-
</Grid>
104+
<Grid container>
105+
<Grid item xs>
106+
<Link to={REMIND_PASSWORD}>{t('auth.forgotPassword')}</Link>
107+
</Grid>
108+
<Grid item>
109+
<Link to={REGISTER}>{t('auth.dontHaveAccount')}</Link>
119110
</Grid>
120-
</form>
121-
);
122-
}}
123-
/>
124-
</div>
125-
</Container>
111+
</Grid>
112+
</form>
113+
);
114+
}}
115+
/>
116+
</div>
126117
);
127118
};
128119
// tslint:disable-next-line:max-file-line-count

src/components/LoginForm/styles.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const useStyles = makeStyles((theme: Theme) => ({
1919
alignItems: 'center',
2020
display: 'flex',
2121
flexDirection: 'column',
22-
marginTop: theme.spacing(8),
2322
},
2423
submit: {
2524
margin: theme.spacing(3, 0, 2),

src/components/Modal/index.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Dialog, DialogContent } from '@material-ui/core';
2+
import React from 'react';
3+
4+
const Modal = ({ children, renderCta }: any) => {
5+
const [open, setOpen] = React.useState(false);
6+
7+
const handleClickOpen = () => {
8+
setOpen(true);
9+
};
10+
11+
const handleClose = () => {
12+
setOpen(false);
13+
};
14+
15+
return (
16+
<div>
17+
{renderCta({ handleClickOpen })}
18+
<Dialog
19+
open={open}
20+
maxWidth="xs"
21+
onClose={handleClose}
22+
aria-labelledby="form-dialog-title"
23+
>
24+
<DialogContent>{children}</DialogContent>
25+
</Dialog>
26+
</div>
27+
);
28+
};
29+
30+
export default Modal;

0 commit comments

Comments
 (0)