Skip to content

Commit fef0f97

Browse files
authored
Merge pull request #117 from kube-js/develop
fix: added cart to redux
2 parents 5def043 + 4cfcb8a commit fef0f97

File tree

21 files changed

+322
-134
lines changed

21 files changed

+322
-134
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.12
5+
appVersion: 1.6.14
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.12
9+
tag: 1.6.14
1010
pullPolicy: Always
1111
containerPort: 80
1212

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"set-value": "3.0.1",
4545
"slick-carousel": "1.8.1",
4646
"store": "2.0.12",
47+
"url-search-params-polyfill": "^7.0.0",
4748
"uuid": "3.3.3",
4849
"yup": "0.27.0"
4950
},

src/atoms/CartDropdown/index.tsx

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import ShoppingCartIcon from '@material-ui/icons/ShoppingCart';
1414
import _isNil from 'ramda/src/isNil';
1515
import React from 'react';
1616
import { useTranslation } from 'react-i18next';
17+
import { useSelector } from 'react-redux';
1718
import { useHistory } from 'react-router';
1819
import courseImagePlaceholder from '../../images/course_400x180.png';
20+
import { State } from '../../redux/rootReducer';
1921
import assetsUrl from '../../utils/helpers/assetsUrl';
2022
import sumBy from '../../utils/helpers/sumBy';
2123

@@ -49,6 +51,7 @@ const CartDropdown = () => {
4951
// TODO: refactor component
5052
const [anchorEl, setAnchorEl] = React.useState(null);
5153
const { t } = useTranslation();
54+
const { items } = useSelector((state: State) => state.cart);
5255
const history = useHistory();
5356

5457
const handleClick = (event: any) => {
@@ -70,31 +73,10 @@ const CartDropdown = () => {
7073
history.push(`/courses/${slug}`);
7174
};
7275

73-
const items: any[] = [
74-
{
75-
author: 'Martin Cook',
76-
id: 1,
77-
price: 19.99,
78-
slug: 'designing-microservices-architecture',
79-
title: 'Designing microservices architecture',
80-
},
81-
{
82-
author: 'Thomas Tik',
83-
id: 2,
84-
price: 19.99,
85-
slug: 'designing-microservices-architecture',
86-
title: 'Designing microservices architecture',
87-
},
88-
{
89-
author: 'Thomas Tik',
90-
id: 3,
91-
price: 19.99,
92-
slug: 'designing-microservices-architecture',
93-
title: 'Designing microservices architecture',
94-
},
95-
];
76+
// TODO: implements pricing on server
77+
const courseItems = items.map(item => ({ ...item, price: 19.99 }));
9678

97-
const total = sumBy('price')(items);
79+
const total = sumBy('price')(courseItems);
9880

9981
return (
10082
<div style={{ display: 'flex', alignItems: 'center' }}>
@@ -106,7 +88,7 @@ const CartDropdown = () => {
10688
onClick={goToCart}
10789
onMouseEnter={handleClick}
10890
>
109-
<Badge badgeContent={items.length || null} color="secondary">
91+
<Badge badgeContent={items.length} color="secondary">
11092
<ShoppingCartIcon />
11193
</Badge>
11294
</Button>
@@ -122,7 +104,7 @@ const CartDropdown = () => {
122104
disablePadding
123105
style={{ maxWidth: 400, width: '100%' }}
124106
>
125-
{items.map(item => {
107+
{courseItems.map(item => {
126108
const imageUrl = _isNil(item.imageUrl)
127109
? courseImagePlaceholder
128110
: assetsUrl(item.imageUrl);
@@ -141,7 +123,8 @@ const CartDropdown = () => {
141123
secondary={
142124
<>
143125
<span>
144-
{t('cart.instructor')}: {item.author}
126+
{t('cart.instructor')}: {item.user.firstName}{' '}
127+
{item.user.lastName}
145128
</span>
146129
<br />
147130
{t('cart.price')}:
@@ -163,7 +146,7 @@ const CartDropdown = () => {
163146
})}
164147
<li style={{ padding: 10 }}>
165148
<Typography variant="h6" style={{ marginBottom: 10 }}>
166-
{t('cart.total')}: £{total}
149+
{t('cart.total')}: £{total.toFixed(2)}
167150
</Typography>
168151

169152
<Button

src/components/Cart/index.tsx

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
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, { memo, useState } from 'react';
55
import { useTranslation } from 'react-i18next';
6+
import { useDispatch, useSelector } from 'react-redux';
7+
import { useLocation } from 'react-router';
8+
import { removeCartItem } from '../../redux/cart/actionCreators';
9+
import { State } from '../../redux/rootReducer';
610
import CartCheckoutSidebar from '../CartCheckoutSidebar';
711
import CartItems from '../CartItems';
812
import useStyles from './styles';
913

10-
// TODO: get data from redux
11-
const items: any[] = [
12-
{
13-
author: 'Martin Cook',
14-
id: 1,
15-
price: 19.99,
16-
slug: 'designing-microservices-architecture',
17-
title: 'Designing microservices architecture',
18-
},
19-
{
20-
author: 'Thomas Tik',
21-
id: 2,
22-
price: 19.99,
23-
slug: 'designing-microservices-architecture',
24-
title: 'Designing microservices architecture',
25-
},
26-
{
27-
author: 'Thomas Tik',
28-
id: 3,
29-
price: 19.99,
30-
slug: 'designing-microservices-architecture',
31-
title: 'Designing microservices architecture',
32-
},
33-
];
34-
3514
const CartView = () => {
3615
const classes = useStyles();
3716
const { t } = useTranslation();
3817

39-
// const { course, getCourseDetailsLoading } = useSelector(
40-
// (state: State) => state.courseDetails
41-
// );
18+
const { search } = useLocation();
19+
20+
const params = new URLSearchParams(search);
21+
22+
const newItemId = params.get('newItemId');
23+
24+
const initialState = !newItemId;
25+
26+
const [editMode, setEditMode] = useState(initialState);
27+
28+
const toggleEditMode = (e: any) => {
29+
e.preventDefault();
4230

43-
// const dispatch = useDispatch();
31+
return setEditMode(!editMode);
32+
};
33+
34+
const { items } = useSelector((state: State) => state.cart);
35+
36+
const dispatch = useDispatch();
37+
38+
const courseItems = items.map(item => ({ ...item, price: 19.99 }));
39+
40+
const removeItem = (id: string) => (e: any) => {
41+
e.preventDefault();
42+
dispatch(removeCartItem(id));
43+
};
4444

4545
return (
4646
<div className={classes.root}>
@@ -61,12 +61,16 @@ const CartView = () => {
6161
</Container>
6262
<Container>
6363
<Grid container spacing={3}>
64-
<Grid item xs={12} sm={9}>
65-
<CartItems items={items} />
66-
</Grid>
67-
<Grid item xs={12} sm={3}>
68-
<CartCheckoutSidebar items={items} />
69-
</Grid>
64+
{editMode ? (
65+
<>
66+
<Grid item xs={12} sm={9}>
67+
<CartItems items={courseItems} removeItem={removeItem} />
68+
</Grid>
69+
<Grid item xs={12} sm={3}>
70+
<CartCheckoutSidebar items={courseItems} />
71+
</Grid>
72+
</>
73+
) : null}
7074
</Grid>
7175
</Container>
7276
</div>

src/components/CartCheckoutSidebar/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const CartItems = ({ items }: any) => {
1616
return (
1717
<Paper className={classes.paper} square>
1818
<Typography>
19-
{t('cart.total')} ({items.length} {courses}): £{total}
19+
{t('cart.total')} ({items.length} {courses}): £{total.toFixed(2)}
2020
</Typography>
2121

2222
<Button variant="contained" fullWidth color="secondary">

src/components/CartItems/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import assetsUrl from '../../utils/helpers/assetsUrl';
1616
import sumBy from '../../utils/helpers/sumBy';
1717
import useStyles from './styles';
1818

19-
const CartItems = ({ items }: any) => {
19+
const CartItems = ({ items, removeItem }: any) => {
2020
const classes = useStyles();
2121
const history = useHistory();
2222
const { t } = useTranslation();
@@ -60,7 +60,7 @@ const CartItems = ({ items }: any) => {
6060
>
6161
{item.title}
6262
</a>
63-
<Button size="small">
63+
<Button size="small" onClick={removeItem(item.id)}>
6464
<DeleteIcon />
6565
</Button>
6666
</TableCell>

src/components/CourseSlide/index.tsx

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,54 @@ import _isNil from 'ramda/src/isNil';
1111
import _propEq from 'ramda/src/propEq';
1212
import React from 'react';
1313
import { useTranslation } from 'react-i18next';
14-
import { Link } from 'react-router-dom';
14+
import { useDispatch, useSelector } from 'react-redux';
15+
import { Link, useHistory } from 'react-router-dom';
1516
// tslint:disable:no-import-side-effect
1617
import 'slick-carousel/slick/slick-theme.css';
1718
import 'slick-carousel/slick/slick.css';
1819
// TODO: check slow rendering issue
1920
// import CourseRating from '../../atoms/CourseRating';
2021
import courseImagePlaceholder from '../../images/course_400x180.png';
22+
import { addCartItem } from '../../redux/cart/actionCreators';
2123
import { EnhancedCourse } from '../../redux/discoveryItems/actionCreators';
24+
import { State } from '../../redux/rootReducer';
2225
import assetsUrl from '../../utils/helpers/assetsUrl';
26+
import useStyles from './styles';
2327

24-
const Slide = ({
25-
course,
26-
classes,
27-
}: {
28-
classes: any;
29-
course: EnhancedCourse;
30-
}) => {
28+
const Slide = ({ course }: { course: EnhancedCourse }) => {
3129
const { t } = useTranslation();
30+
const { items } = useSelector((state: State) => state.cart);
31+
const classes = useStyles();
3232
// TODO: get real rating and price
3333
// const courseRating = Number((Math.random() * 5).toFixed(1));
3434
// tslint:disable-next-line:no-magic-numbers
3535
const coursePrice = Number(Math.random() * 10 + 9).toFixed(2);
3636

37-
const imageUrl = !_isNil(course.imageUrl) ? assetsUrl(course.imageUrl) : courseImagePlaceholder;
37+
const imageUrl = !_isNil(course.imageUrl)
38+
? assetsUrl(course.imageUrl)
39+
: courseImagePlaceholder;
40+
41+
const dispatch = useDispatch();
42+
const history = useHistory();
43+
44+
const addItem = (item: EnhancedCourse) => (e: any) => {
45+
e.preventDefault();
46+
dispatch(addCartItem(item));
47+
history.push({ pathname: '/cart', search: `?newItemId=${item.id}` });
48+
};
49+
50+
const hasAddedToCart =
51+
items.find(item => item.id === course.id) !== undefined;
3852

3953
return (
40-
<Card className={classes.card}>
41-
<Link className={classes.courseLink} to={`/courses/${course.slug}`}>
42-
<CardMedia
43-
className={classes.cardMedia}
44-
image={imageUrl}
45-
title={course.title}
46-
/>
47-
<CardContent className={classes.cardContent}>
54+
<Card>
55+
<CardMedia
56+
className={classes.cardMedia}
57+
image={imageUrl}
58+
title={course.title}
59+
/>
60+
<CardContent className={classes.cardContent}>
61+
<Link className={classes.courseLink} to={`/courses/${course.slug}`}>
4862
<Typography
4963
variant="subtitle1"
5064
component="div"
@@ -65,19 +79,29 @@ const Slide = ({
6579
{/* <CourseRating value={courseRating} /> */}
6680

6781
<div className={classes.cardPrice}>{${coursePrice}`}</div>
68-
</CardContent>
69-
<CardActions>
82+
</Link>
83+
</CardContent>
84+
<CardActions className={classes.cardActions}>
85+
{!hasAddedToCart ? (
7086
<Button
7187
size="small"
7288
color="primary"
73-
style={{ textTransform: 'capitalize' }}
89+
onClick={addItem(course)}
90+
className={classes.cartAction}
7491
>
7592
{t('cart.addToCart')}
7693
</Button>
77-
</CardActions>
78-
</Link>
94+
) : null}
95+
96+
{hasAddedToCart ? (
97+
<Typography className={classes.cartAction}>
98+
{t('cart.addedToCart')}
99+
</Typography>
100+
) : null}
101+
</CardActions>
79102
</Card>
80103
);
81104
};
82105

83-
export default Slide;
106+
// tslint:disable-next-line:max-file-line-count
107+
export default Slide;

0 commit comments

Comments
 (0)