Skip to content

Commit

Permalink
refactor: Move getSaleStatus to utils
Browse files Browse the repository at this point in the history
  • Loading branch information
abrasseu committed Dec 13, 2020
1 parent 46ac0dc commit ce994cf
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 175 deletions.
36 changes: 9 additions & 27 deletions src/components/sales/SaleCard.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
import { shorten } from 'utils/format';
import { getCountdown, saleIsOpen } from 'utils/api';
import {isPast} from "date-fns";
import { getSaleState } from "utils/api";

import { makeStyles } from '@material-ui/core/styles';
import {
Box, Grid, Card, CardContent, CardActions,
Chip, LinearProgress, Typography,
} from '@material-ui/core';
import { Grid, Card, CardContent, CardActions, Chip } from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { NavButton } from 'components/common/Nav';

Expand Down Expand Up @@ -63,16 +59,7 @@ export function SaleCardSkeleton() {

export default function SaleCard({sale, ...props}) {
const classes = useStyles();
function currentSaleState() {
if (!sale)
return null;
if (sale.end_at && isPast(new Date(sale.end_at)))
return {label: 'Terminée !', color: 'red'};
if (sale.begin_at && isPast(new Date(sale.begin_at)))
return {label: 'En cours !', color: 'green'};
return {label: 'Ouverte prochaine ... ', color: 'orange'};
}

const currentSaleState = getSaleState(sale);
return (
<Grid item xs={12} sm={6} md={4} lg={3}>
<Card className={classes.card}>
Expand All @@ -81,27 +68,22 @@ export default function SaleCard({sale, ...props}) {
{sale.name}
</h4>
<span className={classes.subtitle}>
Par {sale.association?.shortname}
Par {sale.association?.shortname || "..."}
</span>
<p className={classes.description}>
{shorten(sale.description, 150)}
</p>
<b>
<Chip style={{backgroundColor: currentSaleState().color}}
label={currentSaleState().label}
color="primary"
/>
</b>


<Chip
style={{backgroundColor: currentSaleState.color}}
label={currentSaleState.label}
color="primary"
/>
</CardContent>
<CardActions>
<NavButton className="go-to-sale" to={`/sales/${sale.id}`}>
Accéder à la vente
</NavButton>
</CardActions>


</Card>
</Grid>
);
Expand Down
172 changes: 74 additions & 98 deletions src/pages/public/SaleDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import apiActions from 'redux/actions/api';
import messagesActions from 'redux/actions/messages';
import { apiAxios } from 'utils/api';

import { isPast } from 'date-fns';
import { differenceInSeconds } from 'date-fns'
import { formatDate } from 'utils/format';
import { getCountdown } from 'utils/api';
import { getSaleState } from 'utils/api';
import { getButtonColoredVariant } from 'utils/styles';

import Loader from 'components/common/Loader';
Expand All @@ -19,35 +19,13 @@ import { Link } from 'components/common/Nav';
import {withStyles} from '@material-ui/core/styles';
import {
Container, Box, Grid, Button, Paper, FormControlLabel, Checkbox,
Collapse, LinearProgress,Typography,
Collapse, LinearProgress,
} from '@material-ui/core';
import {ShoppingCart, Delete} from '@material-ui/icons';
import {Alert, AlertTitle} from '@material-ui/lab';


function LinearProgressWithLabel(props) {
return (
<Box display="flex" alignItems="center" direction="row">
{props.value ? (
<Box width="100%" mr={1} ml={1}>
<LinearProgress variant="determinate" {...props} />
<LinearProgress variant="determinate" {...props} />
</Box>
) : (
<Box width="100%" mr={1} ml={1}>
<LinearProgress {...props} />
<LinearProgress/>
</Box>
)}
<Box mr={1}>
<Typography variant="body2" color="textSecondary" display="inline">
{props.text}
</Typography>
</Box>
</Box>
);
}

const COUNTDOWN_MAX = 12 * 3600; // Countdown 12h before

const connector = connect((store, props) => {
const saleId = props.match.params.sale_id;
Expand All @@ -66,8 +44,10 @@ class SaleDetail extends React.Component{
quantities: {},
buying: false,
cgvAccepted: false,
progress: 0,
timeLeft: "Chargement...",
countdown: undefined,
// progress: 0,
// timeLeft: "Chargement...",
saleState: null,
}

componentDidMount() {
Expand All @@ -81,21 +61,16 @@ class SaleDetail extends React.Component{
if (!this.props.items)
this.props.dispatch(apiActions.sales(saleId).items.all());

this.interval = setInterval(() => {
if (document.getElementById(this.props.sale.id)) {
const countdown = getCountdown(this.props.sale.begin_at);
if (!countdown.timer)
window.location.reload(false);

this.setState(prevState => ({...prevState, progress: countdown.nbSeconds, timeLeft: countdown.timer}))
}
}, 1000);
if (this.props.sale)
this.updateSaleState();
}

componentDidUpdate(prevProps) {
const order = this.props.order;
if (prevProps.sale !== this.props.sale)
this.updateSaleState();

// Update quantities from current order
const order = this.props.order;
if (prevProps.order !== order && order?.orderlines?.length) {
this.setState({
quantities: order.orderlines.reduce((acc, orderline) => {
Expand All @@ -106,9 +81,31 @@ class SaleDetail extends React.Component{
}
}

componentWillUnmount() {
clearInterval(this.interval);
}
componentWillUnmount() {
if (this.interval)
clearInterval(this.interval);
}

updateSaleState = () => {
if (this.interval)
clearInterval(this.interval);

const saleState = getSaleState(this.props.sale);
this.setState({ saleState, countdown: undefined });

// Start countdown if not begun and less than 24 hours to go
const start = new Date(this.props.sale.begin_at);
if (saleState?.key === 'NOT_BEGUN' && differenceInSeconds(start, new Date()) < COUNTDOWN_MAX) {
this.interval = setInterval(() => {
const secondsLeft = differenceInSeconds(start, new Date());
const countdown = (COUNTDOWN_MAX - secondsLeft) / COUNTDOWN_MAX * 100;
if (secondsLeft <= 0)
this.updateSaleState();
else
this.setState(prevState => ({ ...prevState, countdown }));
}, 1000);
}
}

// -----------------------------------------------------
// Order handlers
Expand Down Expand Up @@ -217,17 +214,6 @@ class SaleDetail extends React.Component{
// Display
// -----------------------------------------------------

currentSaleState = () => {
const sale = this.props.sale;
if (!sale)
return null;
if (sale.end_at && isPast(new Date(sale.end_at)))
return 'FINISHED';
if (sale.begin_at && isPast(new Date(sale.begin_at)))
return 'ONGOING';
return 'NOT_BEGUN';
}

hasUnpaidOrder = () => Boolean(this.props.order && this.props.order.status === 3)

areItemsDisabled = () => Boolean(!this.props.authenticated || this.hasUnpaidOrder())
Expand All @@ -237,17 +223,16 @@ class SaleDetail extends React.Component{
canBuy = () => (
this.props.authenticated
&& this.state.cgvAccepted
&& this.currentSaleState() === 'ONGOING'
&& this.state.saleState?.key === 'ONGOING'
&& this.hasItemsInCart()
)

render() {
const { classes, sale } = this.props;
const { cgvAccepted } = this.state;
const { cgvAccepted, saleState } = this.state;
if (!sale || this.props.fetchingSale)
return <Loader fluid text="Loading sale..." />

const saleState = this.currentSaleState()
const CGVLink = props => <Link href={sale.cgv} rel="noopener" target="_blank" {...props} />
return (
<React.Fragment>
Expand Down Expand Up @@ -279,23 +264,29 @@ class SaleDetail extends React.Component{
<Grid item xs={12} sm={8}>
<h3>Articles en ventes</h3>

{saleState === 'NOT_BEGUN' && (
{saleState?.key === 'NOT_BEGUN' && (
<Alert severity="warning" color="info">
<AlertTitle>La vente n'a pas encore commencée</AlertTitle>
<span>
Revenez d'ici {sale.begin_at && formatDate(sale.begin_at, 'fromNowStrict')} pour pouvoir commander.
Encore un peu de patience&nbsp;!
Revenez d'ici <b>{sale.begin_at && formatDate(sale.begin_at, 'fromNowStrict')}</b> pour pouvoir commander.
</span>
{this.state.countdown && (
<Box mt={1}>
<LinearProgress variant="determinate" value={this.state.countdown} />
</Box>
)}
</Alert>
)}
{saleState === 'FINISHED' && (
{saleState?.key === 'FINISHED' && (
<Alert severity="warning" color="info">
<AlertTitle>La vente est terminée</AlertTitle>
<span>
Vous pouvez retrouver vos commandes liées à cette vente, <Link to="/orders">sur votre compte</Link>.
</span>
</Alert>
)}
{saleState === 'ONGOING' && (
{saleState?.key === 'ONGOING' && (
<React.Fragment>
<FormControlLabel
control={(
Expand Down Expand Up @@ -341,54 +332,39 @@ class SaleDetail extends React.Component{
</Paper>
</Box>

{saleState === 'NOT_BEGUN' ? (
<Box style={{width: '100%'}}>
<Alert severity="success" variant="outlined" icon={false}>
<AlertTitle>La vente n'a pas encore commencée, encore un peu de patience
!</AlertTitle>
<LinearProgressWithLabel id={sale.id} value={this.state.progress}
text={this.state.timeLeft}/>
</Alert>

</Box>
) : (
<Box display="flex" justifyContent="flex-end">
<Button
onClick={this.handleReset}
disabled={!this.hasItemsInCart()}
startIcon={<Delete/>}
className={classes.buttonEmpty}
variant="outlined"
>
Vider
</Button>
{/* SAVE BUTTON, utile ??
<Box display="flex" justifyContent="flex-end">
<Button
onClick={this.saveOrder}
// disabled={!canBuy}
// startIcon={<Save />}
className={classes.button}
onClick={this.handleReset}
disabled={!this.hasItemsInCart()}
startIcon={<Delete/>}
className={classes.buttonEmpty}
variant="outlined"
>
Sauvegarder
Vider
</Button>
*/}
{/* SAVE BUTTON, utile ??
<Button
onClick={this.handleBuy}
disabled={!this.canBuy()}
startIcon={<ShoppingCart/>}
className={classes.buttonBuy}
variant="contained"
onClick={this.saveOrder}
// disabled={!canBuy}
// startIcon={<Save />}
className={classes.button}
variant="outlined"
>
Acheter
Sauvegarder
</Button>
</Box>


)}
*/}
<Button
onClick={this.handleBuy}
disabled={!this.canBuy()}
startIcon={<ShoppingCart/>}
className={classes.buttonBuy}
variant="contained"
>
Acheter
</Button>
</Box>

</Grid>

</Grid>

<UnpaidOrderDialog
Expand Down
1 change: 0 additions & 1 deletion src/pages/public/Sales.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from "react";
import { Container, Box } from "@material-ui/core";
import { getCountdown} from 'utils/api';

import APIDataTable from "components/common/APIDataTable";
import { Link } from "components/common/Nav";
Expand Down
Loading

0 comments on commit ce994cf

Please sign in to comment.