client/components/mma/delivery/records/DeliveryRecordsContainer.tsx (133 lines of code) (raw):

import type { Context } from 'react'; import { createContext } from 'react'; import { Navigate, Outlet, useLocation } from 'react-router-dom'; import { dateAddDays, parseDate } from '../../../../../shared/dates'; import type { DeliveryRecordApiItem, MembersDataApiResponse, ProductDetail, } from '../../../../../shared/productResponse'; import { isProduct, MembersDataApiAsyncLoader, } from '../../../../../shared/productResponse'; import type { ProductTypeWithDeliveryRecordsProperties, WithProductType, } from '../../../../../shared/productTypes'; import { createProductDetailFetcher } from '../../../../utilities/productUtils'; import { NAV_LINKS } from '../../../shared/nav/NavConfig'; import { PageContainer } from '../../Page'; import type { DeliveryRecordDetail, DeliveryRecordsResponse, } from './deliveryRecordsApi'; import { createDeliveryRecordsFetcher, DeliveryRecordsApiAsyncLoader, } from './deliveryRecordsApi'; interface ProblemType { category?: string; message?: string; } export interface DeliveryRecordsRouterState { productDetail: ProductDetail; affectedRecords: DeliveryRecordApiItem[]; problemType: ProblemType; showProblemCredit: boolean; } export const checkForExistingDeliveryProblem = ( records: DeliveryRecordDetail[], ) => records.findIndex((deliveryRecord) => { const recordDateEpoch = parseDate( deliveryRecord.deliveryDate, ).date.valueOf(); const startOfToday = new Date(new Date().setHours(0, 0, 0, 0)); const fourteenDaysAgoEpoch = dateAddDays(startOfToday, -14).valueOf(); return ( deliveryRecord.problemCaseId && recordDateEpoch >= fourteenDaysAgoEpoch ); }) > -1; export const DeliveryRecordsContainer = ( props: WithProductType<ProductTypeWithDeliveryRecordsProperties>, ) => { const location = useLocation(); const routerState = location.state as DeliveryRecordsRouterState; const productDetail = routerState?.productDetail; return ( <PageContainer selectedNavItem={NAV_LINKS.accountOverview} pageTitle="Delivery history" > {productDetail ? ( <DeliveryRecordsApiAsyncLoader render={renderContextAndOutletContainer( props.productType, productDetail, )} fetch={createDeliveryRecordsFetcher( productDetail.subscription.subscriptionId, productDetail.isTestUser, )} loadingMessage={'Loading delivery history...'} /> ) : ( <MembersDataApiAsyncLoader fetch={createProductDetailFetcher( props.productType.allProductsProductTypeFilterString, )} render={handleMembersDataResponse(props.productType)} loadingMessage={`Retrieving details of your ${props.productType.friendlyName}...`} /> )} </PageContainer> ); }; const handleMembersDataResponse = (productType: ProductTypeWithDeliveryRecordsProperties) => (mdapiResponse: MembersDataApiResponse) => { const filteredProductDetails = mdapiResponse.products.filter(isProduct); if (filteredProductDetails.length === 1) { const productDetail = filteredProductDetails[0]; return ( <DeliveryRecordsApiAsyncLoader render={renderContextAndOutletContainer( productType, productDetail, )} fetch={createDeliveryRecordsFetcher( productDetail.subscription.subscriptionId, productDetail.isTestUser, )} loadingMessage={'Loading delivery history...'} /> ); } return <Navigate to="/" />; }; export interface DeliveryRecordsContextInterface { productDetail: ProductDetail; productType: ProductTypeWithDeliveryRecordsProperties; data: DeliveryRecordsResponse; } export const DeliveryRecordsContext: Context< DeliveryRecordsContextInterface | object > = createContext({}); const renderContextAndOutletContainer = ( productType: ProductTypeWithDeliveryRecordsProperties, productDetail: ProductDetail, ) => (data: DeliveryRecordsResponse) => { return ( <DeliveryRecordsContext.Provider value={{ productType, productDetail, data, }} > <Outlet /> </DeliveryRecordsContext.Provider> ); };