Advertisement
ronaldkwandy

riwayat-pembelian\index

Jul 14th, 2022
1,099
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import TabScrollable from 'Components/molecules/tab/tab-scrollable';
  2. import HeaderBack from 'Components/organism/header/header-back';
  3. import { useRouter, NextRouter } from 'next/router';
  4. import React, { useState } from 'react';
  5. import { CardTransactionHistory } from 'Components/organism/order/card-transaction-history';
  6. import SearchBar from 'components-update/molecules/search-bar/search-bar';
  7. import ChipGroup from 'Components/organism/chip-group/chip-group';
  8. import Banner from 'Components/organism/banner/banner';
  9. import { transactionComponentHelper, TRANSACTION_STATUS } from 'Helpers/transaction-helper';
  10. import { OrderHandler } from 'handlers/order-handler';
  11. import { orderComponentHelper, ORDER_STATUS } from 'Helpers/order-helper';
  12. import { ShoppingCartHandler } from 'handlers/shopping-cart-handler';
  13. import { ProductHandler } from 'handlers/product-handler';
  14. import { ParsedUrlQuery } from 'querystring';
  15. import Pagination from 'Components/organism/pagination';
  16. import { useSelector, useDispatch, shallowEqual } from 'react-redux';
  17. import { IReducers } from 'Redux/reducers';
  18. import transactionObject from 'Redux/reducers/transaction';
  19. import Head from 'next/head';
  20. import statusObject from 'Redux/reducers/status';
  21. import { ERR_TYPES } from 'Helpers/error-helper';
  22. import shoppingCartObject, { IAddShoppingCartRequestPayload } from 'Redux/reducers/shopping-cart';
  23. import orderObject from 'Redux/reducers/order';
  24. import CheckLogin from 'Components/templates/check-login';
  25. import Dialog from 'Components/organism/dialog';
  26. import navigationObject from 'Redux/reducers/navigation';
  27. import { ROUTER_NAME } from 'Helpers/navigation-helper';
  28. import { IProductDetail } from 'Helpers/product-helper';
  29. import CoachMark from 'Components/templates/coachmark';
  30. import { useLogin, usePersistentLocalStorage } from 'Helpers/hook-helper';
  31. import TransactionTabSkeleton from 'Components/atoms/skeleton/transaction-tab-sekeleton';
  32. import OrderTabSkeleton from 'Components/atoms/skeleton/order-tab-skeleton';
  33. import dynamic from 'next/dynamic';
  34. import NotificationPermission from 'components-update/organism/dialogs/notification-permission';
  35. import { IMAGE_PRODUCT } from 'Metadata/image';
  36. import { REGION_CODE, useLanguage } from 'Helpers/translation-helper';
  37. import paymentObject from 'Redux/reducers/payment';
  38. import DivHtmlContent from 'Components/atoms/div-html-content';
  39. import { CurrencyHandler } from 'handlers/currency-handler';
  40. import { exchangeRateConversionHelper } from 'Helpers/common-helper';
  41. const SurveyEngagement = dynamic(() => import('components-update/organism/engagement/survey-engagement'));
  42.  
  43. interface IDialogProps {
  44.   message: string | any;
  45.   title: string;
  46.   main_action_label: string;
  47.   cancel_action_label: string;
  48.   main_action_func: () => void;
  49.   cancel_action_func: () => void;
  50. }
  51.  
  52. interface ISurveyStorageData {
  53.   [key: string]: {
  54.     surveyName: string;
  55.     fillCount: number;
  56.     token: string;
  57.   }
  58. }
  59.  
  60. const tabIdxToOrderStatus: { [tabIdx: number]: ORDER_STATUS } = {
  61.   1: ORDER_STATUS.WAITING_FOR_SELLER,
  62.   2: ORDER_STATUS.WAITING_FOR_BUYER,
  63.   3: ORDER_STATUS.DONE,
  64.   4: ORDER_STATUS.COMPLAINED,
  65.   5: ORDER_STATUS.REFUNDED,
  66. };
  67. export const orderStatusToTabIdx: { [status: number]: number } = {
  68.   [tabIdxToOrderStatus[1]]: 1,
  69.   [tabIdxToOrderStatus[2]]: 2,
  70.   [tabIdxToOrderStatus[3]]: 3,
  71.   [tabIdxToOrderStatus[4]]: 4,
  72.   [tabIdxToOrderStatus[5]]: 5,
  73. };
  74. const tabIdxToTrxStatus: { [tabIdx: number]: TRANSACTION_STATUS } = {
  75.   0: TRANSACTION_STATUS.PENDING,
  76.   6: TRANSACTION_STATUS.CANCELED,
  77. };
  78. export const trxStatusToTabIdx: { [status: number]: number } = {
  79.   [tabIdxToTrxStatus[0]]: 0,
  80.   [tabIdxToTrxStatus[6]]: 6,
  81. };
  82.  
  83. const TransactionHistoryContainer = (props: { router: NextRouter }) => {
  84.   const dispatch = useDispatch();
  85.   const router = props.router;
  86.   const urlPage = router.query.page as string | undefined;
  87.   const urlTab = router.query.tab as string | undefined;
  88.  
  89.   // Hooks
  90.   const transactionsLoading = useSelector(
  91.     (globalState: IReducers) => globalState.statusReducers.loadingState[transactionObject.names.requestTransactions],
  92.   );
  93.   const pendingTransactionsLoading = useSelector(
  94.     (globalState: IReducers) => globalState.statusReducers.loadingState[transactionObject.names.requestTransactionsWithPendingOrder],
  95.   );
  96.   const cacheKey = useSelector((globalState: IReducers) => globalState.transactionReducers.transactionsKey);
  97.   const transactions =
  98.     useSelector((globalState: IReducers) => globalState.transactionReducers.transactions)[cacheKey] || [];
  99.   const transactionsPage =
  100.     useSelector((globalState: IReducers) => globalState.transactionReducers.transactionsPage)[cacheKey] || 1;
  101.   const transactionsAllCount =
  102.     useSelector((globalState: IReducers) => globalState.transactionReducers.transactionsAllCount)[cacheKey] || 0;
  103.  
  104.   const perPage = 10;
  105.   const maxPage = Math.ceil(transactionsAllCount / perPage);
  106.  
  107.   const [isFetchStart, setIsFetchStart] = React.useState(false);
  108.   React.useEffect(() => {
  109.     if (urlTab !== undefined && urlTab !== null) {
  110.       const status = tabIdxToTrxStatus[parseInt(urlTab)];
  111.       setIsFetchStart(true);
  112.       if (status != TRANSACTION_STATUS.PENDING) {
  113.         dispatch(
  114.           transactionObject.actions.requestTransactions({
  115.             status: status,
  116.             is_include_payment: 1,
  117.             per_page: 10,
  118.             page: urlPage ? parseInt(urlPage) : undefined,
  119.           }),
  120.         );
  121.       } else {
  122.         dispatch(
  123.           orderObject.actions.requestPendingOrders({
  124.             page: urlPage ? parseInt(urlPage) : undefined,
  125.             loadedTimes: 1,
  126.           }),
  127.         );
  128.       }
  129.     }
  130.   }, [urlTab, urlPage]);
  131.  
  132.   const region = useSelector((state: IReducers) => state.regionReducers.regionData);
  133.   const isGlobal: boolean = region !== REGION_CODE.INDONESIA;
  134.   const { foreignExchangeRate } = CurrencyHandler.useForeignExchangeRate();
  135.   const transactionList = transactionComponentHelper(transactions, region).map((transaction) => {
  136.     if (transaction.differentiator == 'waitingSend' || transaction.differentiator == 'done') {
  137.       transaction.differentiator = 'verifyingPayment';
  138.     }
  139.     return transaction;
  140.   });
  141.  
  142.   function handlePagination(param: 'plus' | 'minus' | 'last' | 'first') {
  143.     const goToPage = (page: number) => {
  144.       const query: ParsedUrlQuery = router.query;
  145.       if (page === 1) delete query.page;
  146.       else query.page = page.toString();
  147.       dispatch(
  148.         navigationObject.actions.routeNavigateReplaceTo({
  149.           routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  150.           query: query,
  151.         }),
  152.       );
  153.     };
  154.     param == 'plus' && transactionsPage < maxPage && goToPage(transactionsPage + 1);
  155.     param == 'minus' && transactionsPage > 1 && goToPage(transactionsPage - 1);
  156.     param == 'last' && transactionsPage < maxPage && goToPage(maxPage);
  157.     param == 'first' && transactionsPage > 1 && goToPage(1);
  158.   }
  159.  
  160.   const noBillsTranslation = useLanguage('belum_ada_tagihan_yang_masuk_nih');
  161.   const completeGameNeedsByShoppingInItemkuTranslation = useLanguage('ayoo_lengkapi_kebutuhan_item_game_kamu_dengan_belanja_di_itemku');
  162.  
  163.   return transactionsLoading || pendingTransactionsLoading || !isFetchStart ? (
  164.     <TransactionTabSkeleton />
  165.   ) : (
  166.     <div className='px-4 pt-4 space-y-4'>
  167.       {transactionList.length === 0 ? (
  168.         <div className='mt-4'>
  169.           <img src={IMAGE_PRODUCT.HISTORY_EMPTY} className='mx-auto' width={200} />
  170.           <h2 className='font-bold text-xl leading-6 text-center mt-3'>{noBillsTranslation}</h2>
  171.           <p className='mt-2 text-lg leading-5 text-center text-zambesi'>
  172.             {completeGameNeedsByShoppingInItemkuTranslation}
  173.           </p>
  174.         </div>
  175.       ) : (
  176.         <>
  177.           {transactionList.map((transac) => {
  178.             const convertedPrice = exchangeRateConversionHelper(foreignExchangeRate, region, transac.products[0].itemPrice);
  179.             const convertedTotalPrice = convertedPrice * transac.products[0].totalItemType;
  180.             return (
  181.               <CardTransactionHistory
  182.                 key={transac.id}
  183.                 differentiator={transac.differentiator}
  184.                 products={transac.products}
  185.                 orderDate={transac.orderDate}
  186.                 paymentDueDate={transac.paymentDueDate || '-'}
  187.                 paymentNumber={transac.paymentNumber || undefined}
  188.                 paymentImage={transac.paymentImage || ''}
  189.                 paymentName={transac.paymentName || '-'}
  190.                 totalPrice={!isGlobal ? transac.totalPrice : convertedTotalPrice}
  191.                 onClick={() => {
  192.                   transac.onClick();
  193.                 }}
  194.                 isCreditCard={!!transac.isCreditCard}
  195.               />
  196.             );
  197.           })}
  198.           {transactionList && transactionList.length ? (
  199.             <div className='w-full bg-transparent py-13'>
  200.               <Pagination currentPage={transactionsPage} handlePage={handlePagination} max={maxPage} />
  201.             </div>
  202.           ) : null}
  203.         </>
  204.       )}
  205.     </div>
  206.   );
  207. };
  208.  
  209. const OrderHistoryContainer = (props: { router: NextRouter }) => {
  210.   const dispatch = useDispatch();
  211.   const perPage = 10;
  212.   const router = props.router;
  213.   const urlChipIdx = router.query.chip as string | undefined;
  214.   const urlTab = router.query.tab as string | undefined;
  215.   const urlPage = router.query.page as string | undefined;
  216.   const urlQuery = router.query.query as string | undefined;
  217.  
  218.   const { loadOrders, orders, ordersPage, ordersAllCount, ordersLoading } = OrderHandler.useOrders();
  219.   const { latestBuyAgainProduct } = ProductHandler.useLatestBuyAgainProduct();
  220.  
  221.   const chipListAll = [useLanguage('semua'), useLanguage('10_menit_kirim'), useLanguage('pengiriman_instan')];
  222.   const chipListWaiting = chipListAll.slice(0, 2);
  223.   const chipParamMap = {
  224.     [chipListAll[0]]: undefined,
  225.     [chipListAll[1]]: 'is_delivery_guarantee',
  226.     [chipListAll[2]]: 'use_auto_delivery',
  227.   };
  228.  
  229.   // Translation
  230.   const priceChangeInfoTranslation = useLanguage('info_perubahan_harga');
  231.   const [latestBuyAgainProductName, setLatestBuyAgainProductName] = useState('');
  232.   React.useEffect(() => {
  233.     setLatestBuyAgainProductName(latestBuyAgainProduct?.name as string);
  234.   }, [latestBuyAgainProduct]);
  235.   const priceChangeProductTranslation = useLanguage('telah_terjadi_perubahan_harga_pada_produk_{{name}}_tetap_ingin_lanjutkan_pembelian', { name: latestBuyAgainProductName });
  236.   const cancelTranslation = useLanguage('batalkan');
  237.   const continueTranslation = useLanguage('lanjutkan');
  238.  
  239.   // All Payment Method Media Image
  240.   const paymentMethodMediaImage = useSelector((state: IReducers) => state.persistReducers.paymentMethodMediaImage, shallowEqual);
  241.  
  242.   React.useEffect(() => {
  243.     if (paymentMethodMediaImage == null) {
  244.       dispatch(paymentObject.actions.reqPaymentMethodMediaImage());
  245.     }
  246.   }, [paymentMethodMediaImage]);
  247.  
  248.   // Important values
  249.   const chipList = urlTab ? (parseInt(urlTab) === 1 ? chipListWaiting : chipListAll) : [];
  250.   const maxPage = Math.ceil(ordersAllCount / perPage);
  251.  
  252.   const [searchValue, setSearchValue] = React.useState('');
  253.   const [isFetchStart, setIsFetchStart] = React.useState(false);
  254.   React.useEffect(() => {
  255.     if (urlTab) {
  256.       if (urlQuery) setSearchValue(urlQuery);
  257.       const param: any = {
  258.         statuses:
  259.           tabIdxToOrderStatus[parseInt(urlTab)] === ORDER_STATUS.WAITING_FOR_SELLER
  260.             ? [ORDER_STATUS.WAITING_FOR_SELLER, ORDER_STATUS.WAITING_FOR_CONFIRMATION_DELIVERY_GUARANTEE]
  261.             : [tabIdxToOrderStatus[parseInt(urlTab)]],
  262.         keyword: urlQuery,
  263.         per_page: perPage,
  264.       };
  265.       let guaranteeParamName;
  266.       if (urlChipIdx) guaranteeParamName = chipParamMap[chipList[parseInt(urlChipIdx)]];
  267.       if (guaranteeParamName) {
  268.         param[guaranteeParamName] = 1;
  269.       }
  270.       if (urlPage) param.page = parseInt(urlPage);
  271.       loadOrders(param);
  272.       setIsFetchStart(true);
  273.     }
  274.   }, [urlTab, urlChipIdx, urlPage, urlQuery]);
  275.  
  276.   // Buy Again Dialog
  277.   const [showDialog, setShowDialog] = React.useState(false);
  278.   const [dialogStatusCode, setDialogStatusCode] = React.useState<string | undefined>(undefined);
  279.   const [dialogProperty, setDialogProperty] = React.useState<IDialogProps>({
  280.     message: '',
  281.     title: '',
  282.     main_action_label: '',
  283.     cancel_action_label: '',
  284.     main_action_func: () => {},
  285.     cancel_action_func: () => setShowDialog(false),
  286.   });
  287.   React.useEffect(() => {
  288.     if (dialogStatusCode === ERR_TYPES.PRICE_ALREADY_CHANGED && latestBuyAgainProduct) {
  289.       setDialogProperty({
  290.         ...dialogProperty,
  291.         title: priceChangeInfoTranslation,
  292.         message: (
  293.           <p>
  294.             {priceChangeProductTranslation}
  295.           </p>
  296.         ),
  297.         cancel_action_label: cancelTranslation,
  298.         main_action_label: continueTranslation,
  299.         main_action_func: () => {
  300.           const addCartParam: IAddShoppingCartRequestPayload = {
  301.             product_id: latestBuyAgainProduct.id,
  302.             price: latestBuyAgainProduct.price,
  303.             quantity: latestBuyAgainProduct.quantity,
  304.             game_id: latestBuyAgainProduct.game_id,
  305.           };
  306.           if (latestBuyAgainProduct.note) addCartParam.note = latestBuyAgainProduct.note;
  307.           if (latestBuyAgainProduct.required_information) { addCartParam.required_information = latestBuyAgainProduct.required_information; }
  308.           dispatch(shoppingCartObject.actions.requestAddToShoppingCart(addCartParam));
  309.           setShowDialog(false);
  310.         },
  311.       });
  312.     }
  313.   }, [cancelTranslation, continueTranslation, dialogProperty, dialogStatusCode, dispatch, latestBuyAgainProduct, priceChangeInfoTranslation, priceChangeProductTranslation]);
  314.  
  315.   function handleSearchEnter(e: any) {
  316.     const searchQuery: string = e.target.value;
  317.     const routerQuery = router.query;
  318.     if (searchQuery.length === 0) {
  319.       delete routerQuery.query;
  320.     } else {
  321.       routerQuery.query = searchQuery.toLocaleLowerCase();
  322.     }
  323.     dispatch(
  324.       navigationObject.actions.routeNavigateReplaceTo({
  325.         routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  326.         query: routerQuery,
  327.       }),
  328.     );
  329.   }
  330.  
  331.   function handleSearchChange(e: any) {
  332.     setSearchValue(e);
  333.     if (e.length === 0) {
  334.       const routerQuery = router.query;
  335.       delete routerQuery.query;
  336.       dispatch(
  337.         navigationObject.actions.routeNavigateReplaceTo({
  338.           routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  339.           query: routerQuery,
  340.         }),
  341.       );
  342.     }
  343.   }
  344.  
  345.   function handleNavigationChip(e: any) {
  346.     if (urlTab) {
  347.       document.body.scrollIntoView({ behavior: 'smooth' });
  348.       const query: ParsedUrlQuery = {
  349.         tab: router.query.tab,
  350.       };
  351.       const chipIdx = chipList.indexOf(e);
  352.       if (chipIdx !== 0) query.chip = chipIdx.toString();
  353.       else delete query.chip;
  354.       dispatch(
  355.         navigationObject.actions.routeNavigateReplaceTo({
  356.           routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  357.           query: query,
  358.         }),
  359.       );
  360.     }
  361.   }
  362.  
  363.   function handleConfirm(orderId: number) {
  364.     dispatch(
  365.       navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.ORDER_TESTIMONY, params: { id: orderId } }),
  366.     );
  367.   }
  368.  
  369.   function handleBuyAgainClick(order: any) {
  370.     const callback = (
  371.       isSuccess: boolean,
  372.       data: { statusCode: string; data: IProductDetail; required_information: string; note: string },
  373.     ) => {
  374.       if (!isSuccess) {
  375.         setDialogStatusCode(data.statusCode);
  376.         setShowDialog(true);
  377.       }
  378.     };
  379.     const buyAgainParam: IAddShoppingCartRequestPayload = {
  380.       product_id: order.productId,
  381.       price: order.productPrice,
  382.       game_id: order.gameId,
  383.     };
  384.     if (order.note) buyAgainParam.note = order.note;
  385.     if (order.productRequiredInformation) buyAgainParam.required_information = order.productRequiredInformation;
  386.     dispatch(shoppingCartObject.actions.requestBuyAgain(buyAgainParam, callback));
  387.   }
  388.  
  389.   function handlePagination(param: 'plus' | 'minus' | 'last' | 'first') {
  390.     if (urlTab) {
  391.       const goToPage = (page: number) => {
  392.         const query: ParsedUrlQuery = router.query;
  393.         if (page === 1) delete query.page;
  394.         else query.page = page.toString();
  395.         dispatch(
  396.           navigationObject.actions.routeNavigateReplaceTo({
  397.             routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  398.             query: query,
  399.           }),
  400.         );
  401.       };
  402.       param == 'plus' && ordersPage < maxPage && goToPage(ordersPage + 1);
  403.       param == 'minus' && ordersPage > 1 && goToPage(ordersPage - 1);
  404.       param == 'last' && ordersPage < maxPage && goToPage(maxPage);
  405.       param == 'first' && ordersPage > 1 && goToPage(1);
  406.     }
  407.   }
  408.  
  409.   const status = urlTab ? tabIdxToOrderStatus[parseInt(urlTab)] : ORDER_STATUS.WAITING_FOR_PAYMENT;
  410.   const region = useSelector((state: IReducers) => state.regionReducers.regionData);
  411.   const isGlobal: boolean = region !== REGION_CODE.INDONESIA;
  412.   const { foreignExchangeRate } = CurrencyHandler.useForeignExchangeRate();
  413.   const orderList = orderComponentHelper(orders, region);
  414.  
  415.   // Order Info Coachmark //
  416.   let coachmarkOrder: typeof orderList[number] | undefined;
  417.   const [onboardedOrderInfo, setOnboardedOrderInfo] = usePersistentLocalStorage('onboardedOrderInfo', false);
  418.   function onCloseCoachmark() {
  419.     setOnboardedOrderInfo(true);
  420.   }
  421.   if (!onboardedOrderInfo) {
  422.     for (const order of orderList) {
  423.       if (order?.hasOrderInfo && order?.differentiator === 'sended') {
  424.         coachmarkOrder = order;
  425.         break;
  426.       }
  427.     }
  428.   }
  429.   // End Order Info Coachmark //
  430.  
  431.   const searchProductNameTranslation = useLanguage('cari_nama_produk');
  432.   const orderDoesNotExistTranslation = useLanguage('hm_pesanan_yang_kamu_cari_tidak_ada');
  433.   const noOrderProcessedTranslation = useLanguage('belum_ada_pesanan_yang_diproses');
  434.   const resetOrChangeAnotherKeywordTranslation = useLanguage('coba_reset_atau_ganti_kata_kunci_lain_ya');
  435.   const viewOrderDetailTranslation = useLanguage('lihat_rincian_pesanan_kamu_di_sini');
  436.   const viewVoucherCodeOrAccountDataTranslation = useLanguage('buka_untuk_melihat_kode_voucher_atau_data_akun');
  437.   const coachmarkMainButtonText = useLanguage('mengerti');
  438.  
  439.   const watingEngagementTexts = [
  440.     <>
  441.       <DivHtmlContent data={useLanguage('produk_top_up_voucher_currency_item_skin_akun_pulsa_dikirim_dalam_12_48_jam_produk_item_gift_butuh_berteman_dalam_game_dikirim_maksimal_10_hari')} draggable={false} />
  442.     </>,
  443.     <>
  444.       <DivHtmlContent data={useLanguage('produk_bertanda_khusus_10_menit_kirim_dikirim_dalam_10_menit_atau_kamu_bisa_langsung_mengajukan_pengembalian_dana')} draggable={false} />
  445.     </>,
  446.   ];
  447.   const sendedEngagementText = (
  448.     <>
  449.       {useLanguage('mulai_24_juni_2021_informasi_produk_dalam_bentuk_data_seperti_voucher_dan_akun_dituliskan_oleh_penjual_di_dalam_rincian_pesanan')}
  450.     </>
  451.   );
  452.   return !isFetchStart || ordersLoading ? (
  453.     <OrderTabSkeleton />
  454.   ) : (
  455.     <div>
  456.       <div className='px-4 pt-4'>
  457.         <SearchBar
  458.           placeholder={searchProductNameTranslation}
  459.           onBlur={handleSearchEnter}
  460.           onEnter={handleSearchEnter}
  461.           value={searchValue}
  462.           onChange={handleSearchChange}
  463.         />
  464.         <ChipGroup
  465.           className='mt-3'
  466.           chips={chipList}
  467.           handleNavigationChip={handleNavigationChip}
  468.           activeChip={urlChipIdx ? chipList[parseInt(urlChipIdx)] : chipList[0]}
  469.         />
  470.         {status === ORDER_STATUS.WAITING_FOR_SELLER ? (
  471.           <div className='mt-3'>
  472.             <Banner
  473.               border
  474.               button={false}
  475.               icon={false}
  476.               message={urlChipIdx ? watingEngagementTexts[parseInt(urlChipIdx)] : watingEngagementTexts[0]}
  477.             />
  478.           </div>
  479.         ) : status === ORDER_STATUS.WAITING_FOR_BUYER ? (
  480.           <div className='mt-3'>
  481.             <Banner border button={false} icon={false} message={sendedEngagementText} />
  482.           </div>
  483.         ) : null}
  484.         {orderList.length == 0 ? (
  485.           <div className='mt-4'>
  486.             <img src={IMAGE_PRODUCT.HISTORY_EMPTY} className='mx-auto' width={250} />
  487.             <h2 className='font-bold text-xl leading-6 text-center mt-3'>
  488.               {searchValue !== '' ? orderDoesNotExistTranslation : noOrderProcessedTranslation}
  489.             </h2>
  490.             {searchValue !== '' ? (
  491.               <p className='text-lg leading-5 text-zambesi text-center'>{resetOrChangeAnotherKeywordTranslation}</p>
  492.             ) : null}
  493.           </div>
  494.         ) : (
  495.           <div className='mt-6 space-y-4'>
  496.             {orderList.map((order, i: number) => {
  497.               const convertedPrice = exchangeRateConversionHelper(foreignExchangeRate, region, order.productPrice);
  498.               const convertedTotalPrice = convertedPrice * order.products[0].totalItemType;
  499.               return (
  500.                 <CardTransactionHistory
  501.                   key={i}
  502.                   dot={order.hasOrderInfo}
  503.                   doneClick={() => handleConfirm(order.id)}
  504.                   buyAgainClick={() => handleBuyAgainClick(order)}
  505.                   differentiator={order.differentiator}
  506.                   products={order.products}
  507.                   paymentImage={paymentMethodMediaImage?.[order.paymentName] || ''}
  508.                   paymentName={order.paymentName}
  509.                   orderDate={order.orderDate}
  510.                   totalPrice={!isGlobal ? order.totalPrice : convertedTotalPrice}
  511.                   onClick={() => {
  512.                     dispatch(shoppingCartObject.actions.clearShoppingCartStatus());
  513.                     dispatch(statusObject.actions.errorClear());
  514.                     dispatch(orderObject.actions.clearSelectedOrder());
  515.                     dispatch(
  516.                       navigationObject.actions.routeNavigateTo({
  517.                         routeName: ROUTER_NAME.ORDER_DETAIL,
  518.                         params: { id: order.id },
  519.                       }),
  520.                     );
  521.                   }}
  522.                   isSubscription={order.isFromSubscription}
  523.                 />
  524.               );
  525.             })}
  526.           </div>
  527.         )}
  528.       </div>
  529.       {orderList && orderList.length ? (
  530.         <div className='w-full bg-transparent py-13'>
  531.           <Pagination currentPage={ordersPage} handlePage={handlePagination} max={maxPage} />
  532.         </div>
  533.       ) : null}
  534.       <Dialog
  535.         title={dialogProperty.title}
  536.         description={dialogProperty.message}
  537.         isActive={showDialog}
  538.         mainActionTitle={dialogProperty.main_action_label}
  539.         cancelActionTitle={dialogProperty.cancel_action_label}
  540.         cancelAction={dialogProperty.cancel_action_func}
  541.         mainAction={dialogProperty.main_action_func}
  542.         getChildrenActiveState={(e: boolean) => setShowDialog(e)}
  543.       />
  544.       <CoachMark
  545.         differentiator={coachmarkOrder?.differentiator}
  546.         dot={coachmarkOrder?.hasOrderInfo}
  547.         orderDate={coachmarkOrder?.orderDate}
  548.         products={coachmarkOrder?.products}
  549.         totalPrice={coachmarkOrder?.totalPrice}
  550.         title={viewOrderDetailTranslation}
  551.         description={viewVoucherCodeOrAccountDataTranslation}
  552.         isActive={!!coachmarkOrder}
  553.         mainAction={onCloseCoachmark}
  554.         mainActionTitle={coachmarkMainButtonText}
  555.       />
  556.     </div>
  557.   );
  558. };
  559.  
  560. export const OrderHistory = () => {
  561.   const dispatch = useDispatch();
  562.   const router = useRouter();
  563.   const isLoggedIn = useLogin();
  564.   const { addToShoppingCartSuccess } = ShoppingCartHandler.useAddShoppingCart();
  565.   const { latestBuyAgainProduct } = ProductHandler.useLatestBuyAgainProduct();
  566.   const urlTabIndex = router.query.tab as string | '0';
  567.   const tabParamExist = !!router.asPath.match(new RegExp('[&?]tab=(.*)(&|$)'));
  568.  
  569.   const tabNames = [
  570.     useLanguage('menunggu_pembayaran'),
  571.     useLanguage('menunggu_dikirim'),
  572.     useLanguage('sudah_terkirim'),
  573.     useLanguage('selesai'),
  574.     useLanguage('pengembalian_dana'),
  575.     useLanguage('dana_dikembalikan'),
  576.     useLanguage('transaksi_dibatalkan'),
  577.   ];
  578.  
  579.   const [latestBuyAgainProductQuantity, setLatestBuyAgainProductQuantity] = useState<number>();
  580.   const [latestBuyAgainProductName, setLatestBuyAgainProductName] = useState<string>('');
  581.   React.useEffect(() => {
  582.     setLatestBuyAgainProductQuantity(latestBuyAgainProduct?.quantity as number);
  583.     setLatestBuyAgainProductName(latestBuyAgainProduct?.name as string);
  584.   }, [latestBuyAgainProduct]);
  585.   const productWithQuantityAddedToCartTranslation = useLanguage(
  586.     '{{count}}_produk_{{name}}_berhasil_dimasukkan_ke_troli',
  587.     { count: latestBuyAgainProductQuantity as number, name: latestBuyAgainProductName }
  588.   );
  589.   const productAddedToCartTranslation = useLanguage('produk_{{name}}_berhasil_dimasukkan_ke_troli', { name: latestBuyAgainProductName });
  590.  
  591.   // Reset selectOrder
  592.   React.useEffect(() => {
  593.     dispatch(orderObject.actions.clearSelectedOrder());
  594.     dispatch(orderObject.actions.clearOrderInfos());
  595.   }, []);
  596.   // End Reset selectOrder
  597.  
  598.   // Intercept browser back button //
  599.   React.useEffect(() => {
  600.     const onBackButtonEvent = () => {
  601.       dispatch(navigationObject.actions.routeInterceptReplaceTo({ routeName: ROUTER_NAME.AKUN }));
  602.     };
  603.     window.addEventListener('popstate', onBackButtonEvent);
  604.     return () => {
  605.       const timeout = setTimeout(() => {
  606.         window.removeEventListener('popstate', onBackButtonEvent);
  607.         clearTimeout(timeout);
  608.       }, 500);
  609.     };
  610.   }, [router]);
  611.   // End intercept browser back button //
  612.  
  613.   React.useEffect(() => {
  614.     if (!tabParamExist) {
  615.       dispatch(
  616.         navigationObject.actions.routeNavigateReplaceTo({
  617.           routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY,
  618.           query: { tab: 0 },
  619.         }),
  620.       );
  621.     }
  622.   }, []);
  623.  
  624.   React.useEffect(() => {
  625.     if (addToShoppingCartSuccess) {
  626.       dispatch(
  627.         statusObject.actions.errorSetNew({
  628.           errorCode: ERR_TYPES.ORDER_ADD_TO_CART_SUCCESS,
  629.           errorMessage: latestBuyAgainProduct?.quantity ? productWithQuantityAddedToCartTranslation : productAddedToCartTranslation,
  630.         }),
  631.       );
  632.     }
  633.   }, [addToShoppingCartSuccess]);
  634.  
  635.   function handleNavigationTab(tab: any) {
  636.     document.body.scrollIntoView({ behavior: 'smooth' });
  637.     dispatch(
  638.       navigationObject.actions.routeNavigateReplaceTo(
  639.         { routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY, query: { tab: tabNames.indexOf(tab) } },
  640.         undefined,
  641.         { shallow: true },
  642.       ),
  643.     );
  644.   }
  645.  
  646.   // Tab logic
  647.   const activeTabName = urlTabIndex ? tabNames[parseInt(urlTabIndex)] || '' : '';
  648.   React.useEffect(() => {
  649.     if (tabParamExist) {
  650.       if (urlTabIndex !== undefined) {
  651.         if (document.getElementById('tab')) {
  652.           const element = document.getElementsByClassName('tab');
  653.           if (element && urlTabIndex) {
  654.             element[parseInt(urlTabIndex)]?.scrollIntoView({
  655.               behavior: 'smooth',
  656.               inline: 'start',
  657.             });
  658.           }
  659.         }
  660.       }
  661.     }
  662.   }, [urlTabIndex]);
  663.  
  664.   // Component selection
  665.   let tabView = null;
  666.   if (activeTabName === tabNames[0] || activeTabName === tabNames[6]) { tabView = <TransactionHistoryContainer router={router} />; } else if (
  667.     activeTabName === tabNames[1] ||
  668.     activeTabName === tabNames[2] ||
  669.     activeTabName === tabNames[3] ||
  670.     activeTabName === tabNames[4] ||
  671.     activeTabName === tabNames[5]
  672.   ) { tabView = <OrderHistoryContainer router={router} />; }
  673.  
  674.   // BEGIN SELLER ACTIVITY SURVEY ENGAGEMENT
  675.   const surveyName: string = '';
  676.   const surveyUrl: string = '';
  677.   const loginToken = useSelector((state: IReducers) => state.loginReducers.token);
  678.   const loginId = useSelector((state: IReducers) => state.loginReducers.userData.id);
  679.   const defaultSurveyCardStyle = { transition: 'transform 1s', transform: 'translate(0px, 128px)' };
  680.  
  681.   const [isSurveyEngagementShown, setIsSurveyEngagementShown] = React.useState<boolean>(false);
  682.   const [surveyCardStyle, setSurveyCardStyle] = React.useState(defaultSurveyCardStyle);
  683.   const [surveyActivity, setSurveyActivity] = usePersistentLocalStorage<ISurveyStorageData>('surveyActivity', {});
  684.  
  685.   React.useEffect(() => {
  686.     if (isLoggedIn && surveyName && activeTabName === tabNames[1]) {
  687.       const userId = loginId ? loginId.toString() : '0';
  688.       let currentSurveyActivity = { ...surveyActivity };
  689.  
  690.       if (currentSurveyActivity[userId] === undefined || currentSurveyActivity[userId]?.surveyName !== surveyName) {
  691.         currentSurveyActivity[userId] = {
  692.           surveyName: surveyName,
  693.           fillCount: 0,
  694.           token: '',
  695.         };
  696.  
  697.         setSurveyActivity(currentSurveyActivity);
  698.         setIsSurveyEngagementShown(true);
  699.       } else {
  700.         const surveyFillCount = surveyActivity[userId].fillCount;
  701.         const surveySavedToken = surveyActivity[userId].token;
  702.  
  703.         if (surveyFillCount < 2 && surveySavedToken !== loginToken) {
  704.           setIsSurveyEngagementShown(true);
  705.         }
  706.       }
  707.     } else {
  708.       setIsSurveyEngagementShown(false);
  709.     }
  710.   }, [activeTabName]);
  711.  
  712.   React.useEffect(() => {
  713.     let transformVal = '';
  714.     if (activeTabName === tabNames[1]) {
  715.       transformVal = 'translate(0px, -16px)';
  716.     } else {
  717.       transformVal = 'translate(0px, 128px)';
  718.     }
  719.  
  720.     setTimeout(() => {
  721.       setSurveyCardStyle({ transition: 'transform 1s', transform: transformVal });
  722.     }, 1000);
  723.   }, [isSurveyEngagementShown, activeTabName]);
  724.  
  725.   const handleAbort = () => {
  726.     const userId = loginId ? loginId.toString() : '0';
  727.     const saveToken = loginToken ? loginToken.toString() : '';
  728.  
  729.     let surveyActivityStore = { ...surveyActivity };
  730.     surveyActivityStore[userId].token = saveToken;
  731.  
  732.     setSurveyActivity(surveyActivityStore);
  733.     setIsSurveyEngagementShown(false);
  734.   };
  735.  
  736.   const handleContinue = () => {
  737.     window.open(surveyUrl, '_blank');
  738.  
  739.     const userId = loginId ? loginId.toString() : '0';
  740.     const saveToken = loginToken ? loginToken.toString() : '';
  741.     const fillCount = surveyActivity[userId].fillCount + 1;
  742.  
  743.     let surveyActivityStore = { ...surveyActivity };
  744.     surveyActivityStore[userId].token = saveToken;
  745.     surveyActivityStore[userId].fillCount = fillCount;
  746.  
  747.     setSurveyActivity(surveyActivityStore);
  748.     setIsSurveyEngagementShown(false);
  749.   };
  750.   // END SELLER ACTIVITY SURVEY ENGAGEMENT
  751.  
  752.   return (
  753.     <CheckLogin requireLogin={true}>
  754.       <>
  755.         <Head>
  756.           <title>Riwayat Pembelian | itemku</title>
  757.         </Head>
  758.         <NotificationPermission withScroll={false} page={'TH-OH'} />
  759.         <div>
  760.           {/* {addToShoppingCartloading ? <p>Loading Indicator...</p> : null} TODO: Add add to card loading indicator here */}
  761.           <div className='sticky top-0 z-10'>
  762.             <HeaderBack
  763.               title={useLanguage('riwayat_pembelian')}
  764.               shadow={false}
  765.               leftOnClick={() => dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.AKUN }))}
  766.             />
  767.             <TabScrollable tabs={tabNames} activeTab={activeTabName} handleNavigationTab={handleNavigationTab} />
  768.           </div>
  769.           <div>{tabView}</div>
  770.         </div>
  771.         {/* Show survey engagement only if active tab is `Menunggu Dikirim`*/}
  772.         <SurveyEngagement
  773.           isShown={isSurveyEngagementShown}
  774.           title={useLanguage('undangan_spesial_untuk_kamu')}
  775.           description={
  776.             <>
  777.               {
  778.                 useLanguage('yuk_bantu_pengembangan_itemku_dengan_isi_survey_pengguna')
  779.               }
  780.               <br />
  781.               {
  782.                 useLanguage('ada_hadiah_rp_50_000_loh')
  783.               }
  784.             </>
  785.           }
  786.           onAbort={handleAbort}
  787.           onContinue={handleContinue}
  788.           style={surveyCardStyle}
  789.         />
  790.       </>
  791.     </CheckLogin>
  792.   );
  793. };
  794.  
  795. export default OrderHistory;
  796.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement