all repos — caroster @ 5fa52dfbd467d93ed40542222227bea53bc4dee0

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

frontend/containers/TravelColumns/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 {Travel as TravelType} from '../../generated/graphql';
  6import useEventStore from '../../stores/useEventStore';
  7import useTourStore from '../../stores/useTourStore';
  8import WaitingList from '../WaitingList';
  9import Travel from '../Travel';
 10import AddTravel from './AddTravel';
 11import sliderSettings from './_SliderSettings';
 12
 13interface Props {
 14  toggleNewTravel: () => void;
 15}
 16
 17const TravelColumns = (props: Props) => {
 18  const event = useEventStore(s => s.event);
 19  const {travels = []} = 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          {travels
 38            ?.slice()
 39            .sort(sortTravels)
 40            .map(travel => (
 41              <Container
 42                key={travel.id}
 43                maxWidth="sm"
 44                className={classes.slide}
 45              >
 46                <Travel travel={travel} {...props} />
 47              </Container>
 48            ))}
 49          <Container maxWidth="sm" className={classes.slide}>
 50            <AddTravel {...props} />
 51          </Container>
 52        </Slider>
 53      </div>
 54    </div>
 55  );
 56};
 57
 58const onTourChange = slider => {
 59  const {prev, step, isCreator} = useTourStore.getState();
 60  const fromTo = (step1: number, step2: number) =>
 61    prev === step1 && step === step2;
 62
 63  if (isCreator) {
 64    if (fromTo(2, 3) || fromTo(4, 3)) slider?.slickGoTo(0, true);
 65  } else if (fromTo(0, 1)) slider?.slickGoTo(0, true);
 66};
 67
 68const sortTravels = (a: TravelType, b: TravelType) => {
 69  if (!b) return 1;
 70  const dateA = new Date(a.departure).getTime();
 71  const dateB = new Date(b.departure).getTime();
 72  if (dateA === dateB)
 73    return new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
 74  else return dateA - dateB;
 75};
 76
 77const useStyles = makeStyles(theme => ({
 78  container: {
 79    minHeight: '100vh',
 80    paddingTop: theme.mixins.toolbar.minHeight,
 81    paddingLeft: theme.spacing(6),
 82    paddingRight: theme.spacing(6),
 83    [theme.breakpoints.down('sm')]: {
 84      paddingLeft: theme.spacing(),
 85      paddingRight: theme.spacing(),
 86    },
 87    display: 'flex',
 88    flexDirection: 'column',
 89    overflowX: 'hidden',
 90    overflowY: 'auto',
 91  },
 92  dots: {
 93    height: 32,
 94    overflow: 'auto',
 95    '& overflow': '-moz-scrollbars-none',
 96    '-ms-overflow-style': 'none',
 97    '&::-webkit-scrollbar': {
 98      height: '0 !important',
 99    },
100    '& .slick-dots': {
101      position: 'static',
102      '& li': {
103        display: 'block',
104      },
105    },
106    '& .slick-dots li:first-child button:before, & .slick-dots li:last-child button:before': {
107      color: theme.palette.primary.main,
108    },
109  },
110  slider: {
111    flexGrow: 1,
112    height: 1,
113    '& .slick-slider': {
114      height: '100%',
115      '& .slick-list': {
116        overflow: 'visible',
117      },
118      cursor: 'grab',
119    },
120  },
121  slide: {
122    padding: theme.spacing(1),
123    marginBottom: theme.spacing(12),
124    outline: 'none',
125    '& > *': {
126      cursor: 'default',
127    },
128  },
129}));
130
131export default TravelColumns;