Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion k8s/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v1
description: A Helm chart for kube-ts-react-client
name: kube-ts-react-client
version: 1.0.0
appVersion: 1.6.14
appVersion: 1.6.20
home: https://cloud.docker.com/u/kubejs/repository/docker/kubejs/kube-ts-react-client
icon: https://avatars2.githubusercontent.com/u/47761918?s=200&v=4
sources:
Expand Down
2 changes: 1 addition & 1 deletion k8s/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replicaCount: 2

image:
repository: kubejs/kube-ts-react-client
tag: 1.6.14
tag: 1.6.20
pullPolicy: Always
containerPort: 80

Expand Down
9 changes: 6 additions & 3 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import React, { Fragment, lazy, StrictMode, Suspense } from 'react';
import { Route, Switch } from 'react-router';
import AuthenticatedRoute from './components/Auth/AuthenticatedRoute';
import UnauthenticatedRoute from './components/Auth/UnauthenticatedRoute';
import CartView from './components/Cart';
import CartView from './components/CartView';
import CheckoutView from './components/CheckoutView';
import CourseView from './components/CourseView';
import ErrorBoundary from './components/ErrorBoundaries/Page/index';
import InstructorView from './components/InstructorView';
import Layout from './components/Layout';
import {
CART,
COURSE_VIEW,
CHECKOUT,
COURSE,
DASHBOARD,
INSTRUCTOR_VIEW,
LOGIN,
Expand Down Expand Up @@ -42,7 +44,7 @@ const App = () => (
<ErrorBoundary>
<Switch>
<Route exact path={ROOT} component={Home} />
<Route exact path={COURSE_VIEW} component={CourseView} />
<Route exact path={COURSE} component={CourseView} />
<Route exact path={RESET_PASSWORD} component={ResetPassword} />
<Route exact path={VERIFY} component={VerifyAccount} />
<Route path={INSTRUCTOR_VIEW} component={InstructorView} />
Expand All @@ -66,6 +68,7 @@ const App = () => (
/>

<Route exact path={CART} component={CartView} />
<Route exact path={CHECKOUT} component={CheckoutView} />

<Route component={NotFound} />
</Switch>
Expand Down
14 changes: 14 additions & 0 deletions src/atoms/CartDropdown/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// tslint:disable:no-magic-numbers
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(() => ({
dropdown: {
'&:hover': {
background: 'red',
},
alignItems: 'center',
display: 'flex',
},
}));

export default useStyles;
10 changes: 9 additions & 1 deletion src/components/CartCheckoutSidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@ import Paper from '@material-ui/core/Paper';
import _isNil from 'ramda/src/isNil';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router';
import { CHECKOUT } from '../../constants/routes';
import sumBy from '../../utils/helpers/sumBy';
import useStyles from './styles';

const CartItems = ({ items }: any) => {
const classes = useStyles();
const { t } = useTranslation();
const history = useHistory();
const courses = items.length === 1 ? t('cart.item') : t('cart.items');
const total = sumBy('price')(items);

const goTo = (url: string) => (e: any) => {
e.preventDefault();
history.push(url);
};

return (
<Paper className={classes.paper} square>
<Typography>
{t('cart.total')} ({items.length} {courses}): £{total.toFixed(2)}
</Typography>

<Button variant="contained" fullWidth color="secondary">
<Button variant="contained" fullWidth color="secondary" onClick={goTo(CHECKOUT)}>
{t('cart.proceedToCheckout')}
</Button>
</Paper>
Expand Down
193 changes: 145 additions & 48 deletions src/components/CartItems/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,175 @@ import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
// tslint:disable:no-magic-numbers
import TableRow from '@material-ui/core/TableRow';
import CheckIcon from '@material-ui/icons/Check';
import DeleteIcon from '@material-ui/icons/Delete';
import EditIcon from '@material-ui/icons/Edit';
import ShoppingCartIcon from '@material-ui/icons/ShoppingCart';
import _isNil from 'ramda/src/isNil';
import React from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router';
import { useHistory, useLocation } from 'react-router';
import courseImagePlaceholder from '../../images/course_400x180.png';
import { EnhancedCourse } from '../../redux/discoveryItems/actionCreators';
import assetsUrl from '../../utils/helpers/assetsUrl';
import sumBy from '../../utils/helpers/sumBy';
import useStyles from './styles';

const CartItems = ({ items, removeItem }: any) => {
export interface Options {
readonly items: EnhancedCourse[];
readonly removeItem: (id: string) => (e: any) => void;
}

const CartItems = ({ items, removeItem }: Options) => {
const classes = useStyles();
const history = useHistory();
const { t } = useTranslation();

const goTo = (slug: string) => (e: any) => {
const goTo = (url: string) => (e: any) => {
e.preventDefault();
history.push(`/courses/${slug}`);
history.push(url);
};

const courses = items.length === 1 ? t('cart.item') : t('cart.items');
const total = sumBy('price')(items);

const { search } = useLocation();

const params = new URLSearchParams(search);

const newItemId = params.get('newItemId');

const initialState = !newItemId;

const [isEditable, setIsEditable] = useState(initialState);

const enableEditing = (e: any) => {
e.preventDefault();

return setIsEditable(true);
};

const addedItem = items.find(item => item.id === newItemId);
let addedItemImageUrl;

if (addedItem !== undefined) {
addedItemImageUrl =
addedItem !== undefined && _isNil(addedItem.imageUrl)
? courseImagePlaceholder
: assetsUrl(addedItem.imageUrl);
}

return (
<Paper className={classes.root} square>
<Table className={classes.table} aria-label="table">
<TableHead>
<TableRow>
<TableCell colSpan={3}></TableCell>
<TableCell align="right">{t('cart.price')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{items.map((item: any) => {
const imageUrl = _isNil(item.imageUrl)
? courseImagePlaceholder
: assetsUrl(item.imageUrl);

return (
<TableRow key={item.title}>
<TableCell>
<img
alt={item.title}
src={imageUrl}
className={classes.itemImage}
/>
</TableCell>
<TableCell colSpan={2}>
<a
onClick={goTo(item.slug)}
style={{ cursor: 'pointer' }}
>
{item.title}
</a>
<Button size="small" onClick={removeItem(item.id)}>
<DeleteIcon />
</Button>
</TableCell>
<TableCell align="right">{item.price}</TableCell>
</TableRow>
);
})}
<TableRow>
<TableCell colSpan={3} />
<TableCell align="right">
{t('cart.total')} ({items.length} {courses}): £{total}
</TableCell>
</TableRow>
</TableBody>
{isEditable || addedItem === undefined ? (
<>
{items.length > 0 ? (
<TableHead>
<TableRow>
<TableCell colSpan={3}></TableCell>
<TableCell align="right">{t('cart.price')}</TableCell>
</TableRow>
</TableHead>
) : null}
<TableBody>
{items.map((item: any) => {
const imageUrl = _isNil(item.imageUrl)
? courseImagePlaceholder
: assetsUrl(item.imageUrl);

return (
<TableRow key={item.title}>
<TableCell>
<img
alt={item.title}
src={imageUrl}
className={classes.itemImage}
/>
</TableCell>
<TableCell>
<a
onClick={goTo(`/courses/${item.slug}`)}
style={{ cursor: 'pointer' }}
>
<Typography variant="subtitle1">{item.title}</Typography>
</a>
<p>
{t('cart.instructor')}: {item.user.firstName}{' '}
{item.user.lastName}
</p>
</TableCell>
<TableCell>
<Button size="small" onClick={removeItem(item.id)}>
<DeleteIcon />
</Button>
</TableCell>
<TableCell align="right">{item.price}</TableCell>
</TableRow>
);
})}
{items.length > 0 ? (
<TableRow>
<TableCell colSpan={3} />
<TableCell align="right">
{t('cart.total')} ({items.length} {courses}): £{total}
</TableCell>
</TableRow>
) : null}

{items.length === 0 ? (
<TableRow>
<TableCell>
<Typography variant="h6">
{t('cart.yourCartIsEmpty')}
</Typography>
<Button size="small" onClick={goTo('/')}>
<ShoppingCartIcon /> {t('cart.keepShopping')}
</Button>
</TableCell>
</TableRow>
) : null}
</TableBody>
</>
) : null}
{!isEditable && addedItem !== undefined ? (
<TableBody>
<TableRow>
<TableCell>
<div className={classes.addedToBasket}>
<div className={classes.addedToBasketImageWrapper}>
<img
alt={addedItem.title}
src={addedItemImageUrl}
className={classes.itemImage}
/>
</div>
<div className={classes.addedToBasketContent}>
<CheckIcon />
<Typography>{t('cart.addedToCart')}</Typography>
</div>
</div>
</TableCell>
<TableCell colSpan={2}>
<a onClick={goTo(addedItem.slug)} style={{ cursor: 'pointer' }}>
{addedItem.title}
</a>
</TableCell>
<TableCell align="right">
<Button size="small" onClick={enableEditing}>
<EditIcon /> {t('cart.editCart')}
</Button>
</TableCell>
<TableCell align="right">
{t('cart.total')} ({items.length} {courses}): £{total}
</TableCell>
</TableRow>
</TableBody>
) : null}
</Table>
</Paper>
);
};

// tslint:disable-next-line:max-file-line-count
export default CartItems;
20 changes: 18 additions & 2 deletions src/components/CartItems/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,25 @@ import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
addedToBasket: {
display: 'flex',
flexDirection: 'column',
},
addedToBasketContent: {
'& svg': {
color: 'green',
},
alignItems: 'center',
display: 'flex',
},
addedToBasketImageWrapper: {
'&img': {
minWidth: 150,
},
},
itemImage: {
height: 60,
width: 100,
height: 100,
width: 150,
},
root: {
border: '1px solid rgba(0, 0, 0, .125)',
Expand Down
Loading