all repos — caroster @ 3624031597790e3743c218dcf0222a43e8965e49

[Octree] Group carpool to your event https://caroster.io

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