components/widgets/SpeedLimitSection/index.tsx

src/ui/components/widgets/SpeedLimitSection/index.tsx
mail@pastecode.io avatar
unknown
typescript
23 days ago
15 kB
4
Indexable
Never
import { Icons } from '@Assets/icons/Icons'
import { useSpeedLimitStore } from '@Contexts'
import { useSearchParams } from '@Hooks'
import { LoadingSpinner, RvTable } from '@Shared'
import { CButton } from '@coreui/react'
import { useCallback, useEffect, useRef, useState } from 'react'

import { useDispatch, useSelector } from 'react-redux'
import PopupModel from './components/PopupModel'
import SpeedLimitFiller from './components/SpeedLimitFiller'
import { useSpeedLimitFilter, useSpeedLimitReviewTable } from './hooks'
import { useSpeedLimitReducer } from './reducer'
import { ActionTypes, speedLimitItemType, SpeedLimitType } from './types'

import {
  fetchSpeedLimitsDataByRouteId,
  fetchTrackCoordinatesByRouteId
} from '@Redux/slices/portalDataSlice'
import SpeedLimitMap from './components/SpeedLimitProfile/Map'
import { getTranslation } from '@Translations'

const SpeedLimitSection = () => {
  const [fakeLoading, setFakeLoading] = useState(false)
  const [isFirstLoad, setIsFirstLoad] = useState(true)
  const mapRef = useRef<HTMLDivElement>(null)

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

  const {
    addNewTSOSpeedLimit: { loading: addTSOLoading }
  } = useSelector((state: any) => state.portalAction)

  const {
    editTSOSpeedLimitById: { loading: editTSOLoading }
  } = useSelector((state: any) => state.portalAction)

  const {
    deleteTSOSpeedLimitById: { loading: deleteTSOSpeedLimitByIdLoading }
  } = useSelector((state: any) => state.portalAction)

  const speedLimitStore = useSpeedLimitStore

  const speedLimitData = useSpeedLimitStore.use.speedLimits()

  const fetchData = useSpeedLimitStore.use.fetchData()
  const addNewTSOSpeedLimit = useSpeedLimitStore.use.addNewTSOSpeedLimit()
  const editTSOSpeedLimit = useSpeedLimitStore.use.editTSOSpeedLimit()
  const deleteTSOSpeedLimit = useSpeedLimitStore.use.deleteTSOSpeedLimit()

  const [state, actions] = useSpeedLimitReducer()
  const { routes } = useSpeedLimitFilter(state, actions)
  const { fields, customCells, data, loading } = useSpeedLimitReviewTable(
    state,
    actions
  )
  const {
    type,
    actionType,
    page,
    routeId,
    isDeleteModal,
    temporarySpeedLimitIdDelete,
    errorModal,
    isAddModal,
    isEditModal,
    addSpeedLimitData,
    editSpeedLimitData
  } = state

  const handleAddSpeedLimit = () => {
    addNewTSOSpeedLimit(addSpeedLimitData)
    actions.onChangeIsOpenModalAdd(false)
  }

  const handleEditSpeedLimit = () => {
    editTSOSpeedLimit(editSpeedLimitData)
    actions.onChangeIsOpenModalEdit(false)
  }

  const handleDeleteSpeedLimit = () => {
    const payload = {
      temporarySpeedLimitIdDelete,
      onSuccess: () => {
        const routeIdParam = searchParams.getSearchParam('route-id')
        const directionParam = searchParams.getSearchParam('direction')
        const startDestinationId = routeIdParam
          ?.split('_')
          .filter(item => item !== directionParam)
        actions.onSelectedDeleteItem(null)
        actions.onChangeIsOpenModalDelete(false)
        if (routeIdParam) {
          dispatch(
            fetchSpeedLimitsDataByRouteId({
              routeId: routeIdParam,
              railroadId: railroadId,
              startDestinationId: startDestinationId?.[0]!,
              endDestinationId: directionParam
            })
          )
          dispatch(
            fetchTrackCoordinatesByRouteId({
              routeId: routeIdParam,
              railroadId: railroadId,
              startDestinationId: startDestinationId?.[0]!,
              endDestinationId: directionParam
            })
          )
        }
        actions.onChangeActionType(ActionTypes.View)
      },
      onFailure: (error: string) => {
        actions.onIsOpenError(error)
        actions.onChangeIsOpenModalDelete(false)
      }
    }
    deleteTSOSpeedLimit(payload)
  }

  const showData = useCallback(() => {
    const typeArr = type?.split(',')
    const updateSpeedLimits =
      data?.filter(
        (speedLimit: speedLimitItemType) =>
          typeArr.includes(speedLimit?.type!) || type === ''
      ) || []
    speedLimitStore.setState({ speedLimits: updateSpeedLimits })
    setFakeLoading(true)
    setTimeout(() => {
      setFakeLoading(false)
    }, 300)
  }, [data, type])

  const onChangePage = useCallback(
    (e: any) => {
      if (!isFirstLoad) {
        setTimeout(() => {
          actions.onChangePage(e.toString())
        }, 20)
      }
    },
    [isFirstLoad]
  )

  const handleRowClick = (
    item: speedLimitItemType,
    index: number,
    cellId: any
  ) => {
    if (
      !['edit', 'changeLog'].includes(cellId) &&
      actionType === ActionTypes.View
    ) {
      actions.onChangeTSOSpeedLimitSelected(item)
      if (item?.type === SpeedLimitType.TSO) {
        mapRef.current?.scrollIntoView({ behavior: 'smooth' })
      }
    }
  }

  useEffect(() => {
    const pageParam = searchParams.getSearchParam('page')
    pageParam && actions.onChangePage(pageParam)
    if (data && isFirstLoad) {
      setTimeout(() => {
        setIsFirstLoad(false)
      }, 500)
    }

    // if (data && !isFirstLoad ) {
    //   setTimeout(() => {
    //     actions.onChangePage('')
    //   }, 100)
    // }
  }, [data])

  useEffect(() => {
    data && showData()
    actions.onChangeActionType(ActionTypes.View)
  }, [data, type])
  useEffect(() => {
    const page = searchParams.getSearchParam('page')
    if (actionType === ActionTypes.Add && data) {
      // onChangePage(1)
      actions.onChangePage('')
      searchParams.delSearchParam('page')
      const newSpeedLimitData = [{}, ...(speedLimitData ?? [])]
      speedLimitStore.setState({ speedLimits: newSpeedLimitData })
      if (page && page !== '1') {
        setFakeLoading(true)
        setTimeout(() => {
          setFakeLoading(false)
        }, 100)
      }
    }
  }, [actionType])

  return (
    <div id="rv-portal">
      <h4>{getTranslation('SpeedLimit.speedLimit')}</h4>
      <SpeedLimitFiller state={state} actions={actions} />

      {loading ? (
        <LoadingSpinner classNames="my-5" />
      ) : fakeLoading ? (
        <LoadingSpinner classNames="my-5" />
      ) : (
        <div className="mb-6">
          <table className={'w-full border'}>
            <thead>
              <tr>
                {fields.map(field => (
                  <th
                    key={field.key}
                    className="bg-white w-full h-12 text-black text-center p-[12px]"
                    style={{ width: field._style.width }}
                  >
                    <span
                      className={`relative `}
                      style={{ right: field._style.right }}
                    >
                      {field.label}
                    </span>
                  </th>
                ))}
              </tr>
            </thead>
          </table>
          <div className="max-h-[340px] overflow-y-auto custom-scrollbar ">
            <RvTable
              items={speedLimitData}
              itemsPerPage={speedLimitData?.length}
              itemsPerPageSelect={false}
              fields={fields}
              sorter={false}
              striped={false}
              pagination={false}
              onRowClick={(item, index, cellId) => {
                handleRowClick(item, index, cellId)
              }}
              clickableRows
              customizedCells={customCells}
              sorterValue={undefined}
              onPageChange={onChangePage}
              // activePage={parseInt(state.page) ?? 1}
            />
          </div>
        </div>
      )}

      <div ref={mapRef}>
        <SpeedLimitMap state={state} actions={actions} />
      </div>
      <PopupModel isOpen={isDeleteModal}>
        <div className="flex flex-col gap-2  px-4 py-4">
          <div className="flex gap-2 justify-start">
            <Icons.Warning className="w-[42px] h-[42px]" />
            <div>
              <div className=" mb-1">
                <span className="font-medium text-2xl ">
                  {getTranslation('SpeedLimit.deleteSpeedLimit')}
                </span>
              </div>
              <div>
                <span className="w-full font-normal text-[16px]">
                  {getTranslation('SpeedLimit.deleteMessage')}
                </span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex justify-end gap-2 px-4 pb-4">
          <CButton
            color="secondary"
            onClick={() => {
              actions.onChangeIsOpenModalDelete(false)
              actions.onSelectedDeleteItem(null)
            }}
          >
            {getTranslation('SpeedLimit.cancel')}
          </CButton>
          <CButton
            color="danger"
            disabled={deleteTSOSpeedLimitByIdLoading}
            onClick={handleDeleteSpeedLimit}
          >
            <div className="flex justify-center items-center gap-2">
              {deleteTSOSpeedLimitByIdLoading && (
                <LoadingSpinner width={20} height={20} color="white" />
              )}
              {getTranslation('SpeedLimit.delete')}
            </div>
          </CButton>
        </div>
      </PopupModel>

      <PopupModel isOpen={!!errorModal}>
        <div className="flex flex-col gap-2  px-4 py-4">
          <div className="flex gap-2 justify-start">
            <div>
              <div className=" flex justify-start items-center gap-2 mb-1">
                <Icons.Error className="w-[42px] h-[42px]" />
                <span className="font-medium text-2xl ">
                  {getTranslation('SpeedLimit.error')}
                </span>
              </div>
              <div>
                <span className="w-full font-normal text-[16px]">
                  {errorModal}
                </span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex justify-end gap-2 px-4 pb-4">
          <CButton
            color="secondary"
            onClick={() => {
              actions.onIsOpenError('')
            }}
          >
            {getTranslation('SpeedLimit.close')}
          </CButton>
        </div>
      </PopupModel>

      <PopupModel isOpen={isAddModal}>
        <div className="flex flex-col gap-2  px-4 py-4">
          <div className="flex gap-3 justify-start">
            <div>
              <div className=" mb-1">
                <span className="font-medium text-xl ">
                  {getTranslation('SpeedLimit.addMessage')}
                </span>
              </div>
              <div>
                <span className="w-full font-normal text-[16px]">
                  {getTranslation('SpeedLimit.limit')}:{' '}
                  <span className="font-semibold">
                    {addSpeedLimitData?.limit} (
                    {getTranslation('SpeedLimit.mph')}){' '}
                  </span>{' '}
                  | {getTranslation('SpeedLimit.fromMP')}{' '}
                  <span className="font-semibold">
                    {addSpeedLimitData?.startMilepost}
                  </span>{' '}
                  {getTranslation('SpeedLimit.toMP')}{' '}
                  <span className="font-semibold">
                    {addSpeedLimitData?.endMilepost}
                  </span>{' '}
                  | {getTranslation('SpeedLimit.subdivision')}:{' '}
                  <span className="font-semibold">
                    {addSpeedLimitData?.subdivision}
                  </span>
                </span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex justify-end gap-2 px-4 pb-4">
          <CButton
            color="success"
            className={'px-[15px]'}
            disabled={addTSOLoading}
            onClick={handleAddSpeedLimit}
          >
            <div className="flex justify-center items-center gap-2">Yes</div>
          </CButton>
          <CButton
            className={'px-3'}
            color="secondary"
            onClick={() => {
              actions.onChangeIsOpenModalAdd(false)
              actions.onChangeAddSpeedLimitData(null)
            }}
          >
            No
          </CButton>
        </div>
      </PopupModel>

      <PopupModel isOpen={isEditModal}>
        <div className="flex flex-col gap-2  px-4 py-4">
          <div className="flex gap-3 justify-start">
            {/* <Icons.Warning className="w-[42px] h-[42px]" /> */}
            <div>
              <div className=" mb-1">
                <span className="font-medium text-xl ">
                  {getTranslation('SpeedLimit.updateMessage')}
                </span>
              </div>
              <div>
                <span className="w-full font-normal text-[16px]">
                  {getTranslation('SpeedLimit.limit')} :{' '}
                  <span className="font-semibold">
                    {editSpeedLimitData?.limit}(
                    {getTranslation('SpeedLimit.mph')}){' '}
                  </span>{' '}
                  | {getTranslation('SpeedLimit.fromMP')}{' '}
                  <span className="font-semibold">
                    {editSpeedLimitData?.startMilepost}
                  </span>{' '}
                  {getTranslation('SpeedLimit.toMP')}{' '}
                  <span className="font-semibold">
                    {editSpeedLimitData?.endMilepost}
                  </span>{' '}
                  | {getTranslation('SpeedLimit.subdivision')}:{' '}
                  <span className="font-semibold">
                    {editSpeedLimitData?.subdivision}
                  </span>{' '}
                  ?
                </span>
              </div>
            </div>
          </div>
        </div>

        <div className="flex justify-end gap-2 px-4 pb-4">
          <CButton
            color="success"
            className={'px-[15px]'}
            disabled={editTSOLoading}
            onClick={handleEditSpeedLimit}
          >
            <div className="flex justify-center items-center gap-2">Yes</div>
          </CButton>
          <CButton
            className={'px-3'}
            color="secondary"
            onClick={() => {
              actions.onChangeIsOpenModalEdit(false)
              actions.onChangeEditSpeedLimitData(null)
            }}
          >
            No
          </CButton>
        </div>
      </PopupModel>
    </div>
  )
}

export default SpeedLimitSection
Leave a Comment