TripReviewSection\components\TripReviewFilter.tsx

mail@pastecode.io avatar
unknown
typescript
8 days ago
14 kB
2
Indexable
Never
import { useEffect, createRef } from 'react'
import moment from 'moment'
import momenttz from 'moment-timezone'
import {
  CCardBody,
  CCol,
  CButton,
  CLabel,
  CRow,
  CFormGroup,
  CSelect
} from '@coreui/react'
import { getTranslation } from '@Translations'
import { ErrorMessage } from '@Shared'
import { useDispatch, useSelector } from 'react-redux'
import { fetchTrips } from '@Redux/slices/portalDataSlice'
import { actionCreatorsProps, tripReviewStates } from '../types'
import { useTripReviewFilter } from '../hooks'
import { date_to_YYYY_MM_DD, getNthDatePriorGivenDate } from '@Utils'
import { useLocation } from 'react-router-dom'
import { DateRangePicker, DateRangePickerRefs } from '@Shared'
import { useSearchParams } from '@Hooks'
import { useTripReviewStore } from '@Contexts'

interface TripReviewFilterProps {
  error: string
  state: tripReviewStates
  actions: actionCreatorsProps
  onFilter: any
}

export const TripReviewFilter = ({
  error,
  state,
  actions,
  onFilter
}: TripReviewFilterProps) => {
  const tripReviewStore = useTripReviewStore()
  const tripsDataVersion = tripReviewStore.use.tripsDataVersion()

  const { trips } = useSelector((state: any) => state.portalData)
  const { railroadId } = useSelector((state: any) => state.userInfo.data)
  const dispatch = useDispatch()

  const {
    userList,
    trainIdList,
    crewIdList,
    locomotiveIdList,
    startDate,
    endDate,
    inputUser,
    inputTrainId,
    inputCrewId,
    inputLocomotiveId,
    fromDetail
  } = state

  const searchParams = useSearchParams<
    | 'start-date'
    | 'end-date'
    | 'train-id'
    | 'user'
    | 'page'
    | 'crew-id'
    | 'loco_id'
  >()
  const location = useLocation()
  const dateRangePickerRef = createRef<DateRangePickerRefs>()

  const { latestDate } = useTripReviewFilter()

  useEffect(() => {
    const startDateParam = searchParams.getSearchParam('start-date')
    const endDateParam = searchParams.getSearchParam('end-date')
    const pageParam = searchParams.getSearchParam('page')
    actions.onInitStates(momenttz(latestDate).format('YYYY-MM-DD'))
    startDateParam && moment(startDateParam).isValid()
      ? actions.onChangeStartDate(startDateParam)
      : searchParams.setSearchParam({
          k: 'start-date',
          v: date_to_YYYY_MM_DD(
            getNthDatePriorGivenDate(new Date(latestDate), 10)
          )
        })
    endDateParam && moment(endDateParam).isValid()
      ? actions.onChangeEndDate(endDateParam)
      : searchParams.setSearchParam({
          k: 'end-date',
          v: date_to_YYYY_MM_DD(new Date(latestDate))
        })
    pageParam && actions.onChangePage(pageParam)

    startDateParam &&
      endDateParam &&
      dateRangePickerRef.current?.refresh(
        moment(startDateParam).toDate(),
        moment(endDateParam).toDate()
      )
  }, [])

  useEffect(() => {
    actions.onPopulateTrainAndCrewIds(trips?.data || [])

    const userParam = searchParams.getSearchParam('user')
    const trainIdParam = searchParams.getSearchParam('train-id')
    const crewIdParam = searchParams.getSearchParam('crew-id')
    const locoIdParam = searchParams.getSearchParam('loco_id')

    userParam &&
      actions.onChangeUser({
        selectedUser: userParam,
        trips: trips.data ?? []
      })
    trainIdParam &&
      actions.onChangeTrainID({
        selectedTrainId: trainIdParam,
        trips: trips.data ?? []
      })
    crewIdParam &&
      actions.onChangeCrewID({
        selectedCrewId: crewIdParam,
        trips: trips.data ?? []
      })

    locoIdParam &&
      actions.onChangeLocomotiveId({
        selectedLocoId: locoIdParam,
        trips: trips.data ?? []
      })
  }, [trips])

  useEffect(() => {
    if (location.search.length === 0) {
      searchParams.resetSeachParams({
        'start-date': date_to_YYYY_MM_DD(startDate),
        'end-date': date_to_YYYY_MM_DD(endDate),
        user: inputUser,
        'train-id': inputTrainId,
        'crew-id': inputCrewId,
        loco_id: inputLocomotiveId,
        page: date_to_YYYY_MM_DD(startDate) && state.page
      })
    }
  }, [location])

  useEffect(() => {
    state.page !== ''
      ? searchParams.setSearchParam({ k: 'page', v: state.page })
      : searchParams.delSearchParam('page')
  }, [state.page])

  useEffect(() => {
    if (fromDetail) {
      actions.onChangeFromDetail(false)
      return
    }
    if (isNaN(Date.parse(startDate)) || isNaN(Date.parse(endDate))) return

    const time_zone = momenttz.tz.guess()
    const slocale_time = momenttz(startDate).format()
    const sutc_time = momenttz(slocale_time).utc().format()
    const elocale_time = momenttz(endDate).format()
    const eutc_time = momenttz(elocale_time).utc().format()

    console.log(
      '%c_____________________________________________________________\n\nFetch trips:',
      'background: #80A8CD22; color: #FFF; font-weight: bold;'
    )

    console.log(
      `%cStart date picked: ${slocale_time} (${time_zone})\nEnd date picked: ${elocale_time} (${time_zone})`,
      'background: #80A8CD22; color: #bada55'
    )
    console.log(
      `%cStart date send api: ${sutc_time} (UTC)\nEnd date send api: ${eutc_time} (UTC)`,
      'background: #80A8CD22; color: #E45050'
    )
    console.log(tripsDataVersion)
    dispatch(
      fetchTrips({
        railroadId,
        startDate: sutc_time,
        endDate: eutc_time
      })
    )
  }, [startDate, endDate, tripsDataVersion])

  const onClickClearFilter = () => {
    dateRangePickerRef.current?.refresh(
      moment(latestDate).isValid()
        ? momenttz(latestDate).subtract(10, 'days').toDate()
        : null,
      moment(latestDate).isValid() ? momenttz(latestDate).toDate() : null
    )
    searchParams.clearSearchParams()

    actions.onClearFilter()
    actions.onInitStates(momenttz(latestDate).format('YYYY-MM-DD'))
  }

  return (
    <CCardBody>
      <CRow>
        <CCol>
          <DateRangePicker
            ref={dateRangePickerRef}
            initStartDate={new Date(startDate)}
            initEndDate={new Date(endDate)}
            disabled={trips.loading}
            onPickStartDate={e => {
              const v = e
              searchParams.setSearchParam({
                k: 'start-date',
                v: date_to_YYYY_MM_DD(v)
              })
              searchParams.delSearchParam('crew-id')
              searchParams.delSearchParam('train-id')
              setTimeout(() => {
                actions.onChangePage('')
              }, 100)
              actions.onChangeStartDate(date_to_YYYY_MM_DD(v))
            }}
            onPickEndDate={e => {
              const v = e
              searchParams.setSearchParam({
                k: 'end-date',
                v: date_to_YYYY_MM_DD(v)
              })
              searchParams.delSearchParam('crew-id')
              searchParams.delSearchParam('train-id')
              setTimeout(() => {
                actions.onChangePage('')
              }, 100)
              actions.onChangeEndDate(date_to_YYYY_MM_DD(v))
            }}
            onClose={(setStartDate, setEndDate) => {
              setStartDate(new Date(startDate))
              setEndDate(new Date(endDate))
            }}
          />
          <CCol>
            <CRow>
              <CCol lg="3" md="3" sm="6" xs="6">
                <CFormGroup>
                  <CLabel htmlFor="loco-number">
                    {getTranslation('TripReview.user')}
                  </CLabel>
                  <CSelect
                    value={inputUser}
                    disabled={trips.loading}
                    onChange={e => {
                      const v = (e.target as HTMLInputElement).value
                      console.log('🚀 ~ v:', v)
                      v !== ''
                        ? searchParams.setSearchParam({ k: 'user', v: v })
                        : searchParams.delSearchParam('user')
                      setTimeout(() => {
                        actions.onChangePage('')
                      }, 50)
                      actions.onChangeUser({
                        selectedUser: v,
                        trips: trips.data
                      })
                    }}
                  >
                    <option value="">Any</option>
                    {userList.sort().map((email: string) => (
                      <option key={email} value={email.split('@')[0]}>
                        {email.split('@')[0]}
                      </option>
                    ))}
                  </CSelect>
                </CFormGroup>
              </CCol>
              <CCol lg="3" md="3" sm="6" xs="6">
                <CFormGroup>
                  <CLabel htmlFor="loco-number">
                    {getTranslation('TripReview.train')}
                  </CLabel>
                  <CSelect
                    value={inputTrainId}
                    disabled={trips.loading}
                    onChange={e => {
                      const v = (e.target as HTMLInputElement).value
                      console.log('🚀 ~ v:', v)
                      v !== ''
                        ? searchParams.setSearchParam({ k: 'train-id', v: v })
                        : searchParams.delSearchParam('train-id')
                      setTimeout(() => {
                        actions.onChangePage('')
                      }, 50)
                      actions.onChangeTrainID({
                        selectedTrainId: v,
                        trips: trips.data
                      })
                    }}
                  >
                    <option value="">Any</option>
                    {trainIdList.sort().map((trainId: string) => (
                      <option key={trainId} value={trainId}>
                        {trainId}
                      </option>
                    ))}
                  </CSelect>
                </CFormGroup>
              </CCol>
              <CCol lg="3" md="3" sm="6" xs="6">
                <CFormGroup>
                  <CLabel htmlFor="loco-number">Crew</CLabel>
                  <CSelect
                    value={inputCrewId}
                    disabled={trips.loading}
                    onChange={e => {
                      const v = (e.target as HTMLInputElement).value
                      console.log('🚀 ~ v:', v)
                      v !== ''
                        ? searchParams.setSearchParam({ k: 'crew-id', v: v })
                        : searchParams.delSearchParam('crew-id')
                      setTimeout(() => {
                        actions.onChangePage('')
                      }, 50)
                      actions.onChangeCrewID({
                        selectedCrewId: v,
                        trips: trips.data
                      })
                    }}
                  >
                    <option value="">Any</option>
                    {crewIdList.sort().map((crewId: string) => (
                      <option key={crewId} value={crewId}>
                        {crewId}
                      </option>
                    ))}
                  </CSelect>
                </CFormGroup>
              </CCol>
              <CCol lg="3" md="3" sm="6" xs="6">
                <CFormGroup>
                  <CLabel htmlFor="loco-number">Locomotive</CLabel>
                  <CSelect
                    value={inputLocomotiveId}
                    disabled={trips.loading}
                    onChange={e => {
                      const v = (e.target as HTMLInputElement).value
                      console.log('🚀 ~ v:', v)
                      v !== ''
                        ? searchParams.setSearchParam({ k: 'loco_id', v: v })
                        : searchParams.delSearchParam('loco_id')
                      setTimeout(() => {
                        actions.onChangePage('')
                      }, 50)
                      actions.onChangeLocomotiveId({
                        selectedLocoId: v,
                        trips: trips.data
                      })
                    }}
                  >
                    <option value="">Any</option>
                    {locomotiveIdList.sort().map((locoId: string) => (
                      <option key={locoId} value={locoId}>
                        {locoId}
                      </option>
                    ))}
                  </CSelect>
                </CFormGroup>
              </CCol>
            </CRow>
          </CCol>
        </CCol>
      </CRow>

      {/* Fetch trips loading texts */}
      <CRow style={{ height: 30 }}>
        <CCol>
          {trips.loading && (
            <p>
              <i className="text-primary">
                {getTranslation('TripReview.tripsLoadingText')}
              </i>
            </p>
          )}
        </CCol>
      </CRow>

      {/* Filters button */}
      <CRow>
        <CCol lg="4">
          <CButton
            color="danger"
            disabled={trips.loading}
            onClick={onClickClearFilter}
          >
            {getTranslation('FilterLabels.ClearFilters')}
          </CButton>
        </CCol>
      </CRow>
      <ErrorMessage error={error} message={''} />
    </CCardBody>
  )
}
Leave a Comment