frontend/containers/CarColumns/index.tsx (view raw)
1import {useEffect, useRef} from 'react';
2import {makeStyles} from '@material-ui/core/styles';
3import Container from '@material-ui/core/Container';
4import Slider from 'react-slick';
5import {Car as CarType} from '../../generated/graphql';
6import useEventStore from '../../stores/useEventStore';
7import useTourStore from '../../stores/useTourStore';
8import WaitingList from '../WaitingList';
9import Car from '../Car';
10import AddCar from './AddCar';
11import sliderSettings from './_SliderSettings';
12
13interface Props {
14 toggleNewCar: () => void;
15}
16
17const CarColumns = (props: Props) => {
18 const event = useEventStore(s => s.event);
19 const {cars} = event || {};
20 const slider = useRef(null);
21 const tourStep = useTourStore(s => s.step);
22 const classes = useStyles();
23
24 // On tour step changes : component update
25 useEffect(() => {
26 onTourChange(slider.current);
27 }, [tourStep]);
28
29 return (
30 <div className={classes.container}>
31 <div className={classes.dots} id="slider-dots" />
32 <div className={classes.slider}>
33 <Slider ref={slider} {...sliderSettings}>
34 <Container maxWidth="sm" className={classes.slide}>
35 <WaitingList />
36 </Container>
37 {cars
38 ?.slice()
39 .sort(sortCars)
40 .map(car => (
41 <Container key={car.id} maxWidth="sm" className={classes.slide}>
42 <Car car={car} {...props} />
43 </Container>
44 ))}
45 <Container maxWidth="sm" className={classes.slide}>
46 <AddCar {...props} />
47 </Container>
48 </Slider>
49 </div>
50 </div>
51 );
52};
53
54const onTourChange = slider => {
55 const {prev, step, isCreator} = useTourStore.getState();
56 const fromTo = (step1: number, step2: number) =>
57 prev === step1 && step === step2;
58
59 if (isCreator) {
60 if (fromTo(2, 3) || fromTo(4, 3)) slider?.slickGoTo(0, true);
61 } else if (fromTo(0, 1)) slider?.slickGoTo(0, true);
62};
63
64const sortCars = (a: CarType, b: CarType) => {
65 if (!b) return 1;
66 const dateA = new Date(a.departure).getTime();
67 const dateB = new Date(b.departure).getTime();
68 if (dateA === dateB)
69 return new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
70 else return dateA - dateB;
71};
72
73const useStyles = makeStyles(theme => ({
74 container: {
75 minHeight: '100vh',
76 paddingTop: theme.mixins.toolbar.minHeight,
77 paddingLeft: theme.spacing(6),
78 paddingRight: theme.spacing(6),
79 [theme.breakpoints.down('sm')]: {
80 paddingLeft: theme.spacing(),
81 paddingRight: theme.spacing(),
82 },
83 display: 'flex',
84 flexDirection: 'column',
85 overflowX: 'hidden',
86 overflowY: 'auto',
87 },
88 dots: {
89 height: 32,
90 overflow: 'auto',
91 '& overflow': '-moz-scrollbars-none',
92 '-ms-overflow-style': 'none',
93 '&::-webkit-scrollbar': {
94 height: '0 !important',
95 },
96 '& .slick-dots': {
97 position: 'static',
98 '& li': {
99 display: 'block',
100 },
101 },
102 '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': {
103 color: theme.palette.primary.main,
104 },
105 },
106 slider: {
107 flexGrow: 1,
108 height: 1,
109 '& .slick-slider': {
110 height: '100%',
111 '& .slick-list': {
112 overflow: 'visible',
113 },
114 cursor: 'grab',
115 },
116 },
117 slide: {
118 padding: theme.spacing(1),
119 marginBottom: theme.spacing(12),
120 outline: 'none',
121 '& > *': {
122 cursor: 'default',
123 },
124 },
125}));
126
127export default CarColumns;