diff --git a/.gitignore b/.gitignore index 4f0fa820..19b06395 100644 --- a/.gitignore +++ b/.gitignore @@ -68,4 +68,6 @@ next-env.d.ts /pages/support /pages/support/* /pages/warranty -/services/config/theme-config.ts \ No newline at end of file +/services/config/theme-config.ts + +kc.code-workspace \ No newline at end of file diff --git a/hooks/AuthHooks/useLoginHook.ts b/hooks/AuthHooks/useLoginHook.ts index f4cce8d3..84fa6f4d 100644 --- a/hooks/AuthHooks/useLoginHook.ts +++ b/hooks/AuthHooks/useLoginHook.ts @@ -14,6 +14,9 @@ import { Option } from '../../store/slices/general_slices/multilingual-slice'; import i18n from '../../i18n/i18n'; import useCurrencyLanguageHandler from '../GeneralHooks/LanguageHandler'; import { currencyOptions } from '../../utils/addon-utils/currency-map'; +import useUserDefaultData from '../addon-hooks/kc-hooks/useUserData'; +import { setCustomer, setDesignBankCount, setScope } from '../../store/slices/general_slices/kc-slice'; +import { resetStore } from '../../store/slices/auth/logout-slice'; const useLoginHook = () => { const { AFTER_LOGIN_REDIRECT_URL } = CONSTANTS; @@ -21,6 +24,7 @@ const useLoginHook = () => { const router = useRouter(); const { t } = useTranslation('common'); const { handleCurrencyShallowUpdate, handleLanguageShallowUpdate } = useCurrencyLanguageHandler(); + const { fetchUserDefaultData } = useUserDefaultData(); const [loginForm, setLoginForm] = useState({ usr: '', pwd: '' }); const [passwordHidden, setPasswordHidden] = useState(true); const [isLoginThroughOTP, setIsLoginThroughOTP] = useState(false); @@ -33,6 +37,7 @@ const useLoginHook = () => { const fetchToken = async (values: TypeLoginForm) => { setLoginBtnLoader(true); + try { const userParams: TypeLoginAPIParams = { values: { ...values }, @@ -40,41 +45,50 @@ const useLoginHook = () => { loginViaOTP: false, LoginViaGoogle: false, }; - - // const tokenData = await getTokenFromLoginAPI(SUMMIT_APP_CONFIG, userParams); - // Need to check below login api logic. Need to make generic. + const tokenData = await emrLogin(userParams); - - if (tokenData?.success === true && tokenData?.msg === 'success' && tokenData?.data?.hasOwnProperty('access_token')) { - localStorage.setItem('isLoggedIn', 'true'); - localStorage.setItem('user', values.usr); - localStorage.setItem('party_name', tokenData?.data?.full_name); - - if (tokenData?.data?.isPwdChg !== 0) { - dispatch(storeToken(tokenData?.data)); - } - - handleLanguageShallowUpdate(languageDisplayOptions.find((opt: Option) => opt?.label === tokenData?.data?.language)!); - handleCurrencyShallowUpdate(currencyOptions.find((opt: Option) => opt?.value === tokenData?.data?.currency)!); - - localStorage.setItem('selected_language', tokenData?.data?.language); - localStorage.setItem('selected_currency', tokenData?.data?.currency); - // Redirect to the home page or any other page after successful login - if (tokenData?.data?.isPwdChg === 0) { - router.push('/forgot_password'); - } else { - if (AFTER_LOGIN_REDIRECT_URL) { - router.push(AFTER_LOGIN_REDIRECT_URL); - } else { - router.push('/') - } + + if ( + tokenData?.success === true && + tokenData?.msg === 'success' && + tokenData?.data?.access_token + ) { + const { access_token, isPwdChg, count, full_name } = tokenData.data; + + if (isPwdChg !== 0) { + dispatch(storeToken(tokenData.data)); } - // toast.success('Login Successfully'); + + const redirectUrl = + isPwdChg === 0 + ? '/forgot_password' + : AFTER_LOGIN_REDIRECT_URL || '/'; + + router.replace(redirectUrl); + + setTimeout(() => { + dispatch(setDesignBankCount(count)); + dispatch(setCustomer(null)); + dispatch( + setScope({ + label: 'New Session (PDCM Design Bank)', + value: 'Database', + }) + ); + + fetchUserDefaultData(access_token); + + localStorage.setItem('isLoggedIn', 'true'); + localStorage.setItem('user', values.usr); + localStorage.setItem('party_name', full_name); + }, 0); } } catch (error: any) { - if (error?.status === 400 && error?.response?.data?.error === "Invalid username or password") { + if ( + error?.status === 400 && + error?.response?.data?.error === 'Invalid username or password' + ) { toast.error(t('invalid_credentials')); - return; } else { toast.error(t('error_while_login')); } diff --git a/hooks/GeneralHooks/KCLanguageHandler.ts b/hooks/GeneralHooks/KCLanguageHandler.ts index f9dd6734..d22b7d1f 100644 --- a/hooks/GeneralHooks/KCLanguageHandler.ts +++ b/hooks/GeneralHooks/KCLanguageHandler.ts @@ -10,14 +10,14 @@ import { Option } from '../../store/slices/general_slices/multilingual-slice'; import { currencyOptions } from '../../utils/addon-utils/currency-map'; import { useEffect } from 'react'; -const useCurrencyLanguageHandler = () => { +const useCurrencyLanguageHandler = (postUserDefaultData?: (token: string, DefCurrency: string, DefLang: string, RefreshRt: string, LabRt: string, RMCtg: string, voucherModeType: string ) => void, userDefaultData?: any) => { const dispatch = useDispatch(); - const languageState = useSelector(SelectedLangFromStore)?.selectedLanguage; + const languageState = useSelector(SelectedLangFromStore)?.selectedLanguage?.trim(); const TokenFromStore: any = useSelector(get_access_token); - const currencyState = useSelector(currency_selector_state)?.selected_currency_value; + const currencyState = useSelector(currency_selector_state)?.selected_currency_value?.trim(); const handleAuthError = useAuthErrorHandler(); - const selectedCurrency = currencyOptions.find((opt) => opt?.value === (currencyState))!; - const selectedLanguage = languageDisplayOptions.find((opt) => opt?.value === languageState)!; + const selectedCurrency = currencyOptions.find((opt) => opt?.value === currencyState || 'INR')!; + const selectedLanguage = languageDisplayOptions.find((opt) => opt?.value === languageState || 'en')!; const updateUserPreference = async (language: Option, currency: Option) => { const languageCode = language?.value.toString(); @@ -42,7 +42,8 @@ const useCurrencyLanguageHandler = () => { const handleLanguageChange = (value: Option) => { dispatch(setLanguage(value?.value)); - updateUserPreference(value, selectedCurrency); + // updateUserPreference(value, selectedCurrency); + postUserDefaultData && postUserDefaultData(TokenFromStore?.token, languageDisplayOptions.find((opt: Option) => opt?.value === value?.value?.toString())?.label!?.trim(), userDefaultData?.DefCurrency, userDefaultData?.RefreshRt, userDefaultData?.LabRt, userDefaultData?.RMCtg, userDefaultData?.voucherModeType); }; const handleLanguageShallowUpdate = (value: Option) => { @@ -52,7 +53,8 @@ const useCurrencyLanguageHandler = () => { const handleCurrencyChange = (value: Option) => { dispatch(setCurrencyValue(value?.value)); - updateUserPreference(selectedLanguage, value); + // updateUserPreference(selectedLanguage, value); + postUserDefaultData && postUserDefaultData(TokenFromStore?.token, userDefaultData?.DefLang, value?.value.toString().trim(), userDefaultData?.RefreshRt, userDefaultData?.LabRt, userDefaultData?.RMCtg, userDefaultData?.voucherModeType); }; const handleCurrencyShallowUpdate = (value: Option) => { @@ -60,8 +62,8 @@ const useCurrencyLanguageHandler = () => { } useEffect(() => { - handleLanguageShallowUpdate(languageDisplayOptions.find((opt) => opt?.value === 'en')!); - handleCurrencyShallowUpdate(currencyOptions.find((opt) => opt?.value === 'RS')!); + handleLanguageShallowUpdate(selectedLanguage); + handleCurrencyShallowUpdate(selectedCurrency); },[selectedCurrency, selectedLanguage]); return { diff --git a/hooks/ProductDetailPageHooks/useProductDetail.ts b/hooks/ProductDetailPageHooks/useProductDetail.ts index e9b1a329..c071183a 100644 --- a/hooks/ProductDetailPageHooks/useProductDetail.ts +++ b/hooks/ProductDetailPageHooks/useProductDetail.ts @@ -11,6 +11,7 @@ import fetchPinCodesListAPI from '../../services/api/general-apis/get-pin-code-l import debounce from 'debounce'; import useAuthErrorHandler from '../AuthHooks/handleAuthError'; import useCurrencyLanguageHandler from '../GeneralHooks/KCLanguageHandler'; + type PinCodeTypes = { name: string; }; @@ -40,6 +41,7 @@ const useProductDetail = () => { quantity: productDetailData?.min_order_qty || 1, }, ]); + const handleMultipleQtyChange = (index: number, itemCode: string, value: string) => { setItemList((prevItemList: any) => { if (!Array.isArray(prevItemList)) { @@ -164,6 +166,7 @@ const useProductDetail = () => { } } }; + const debouncedSetValue = debounce((pinCode: string) => { const found = pinCodeData.some((pin) => pin.name === pinCode); setValidPinCode(found); diff --git a/hooks/ProductListPageHooks/useProductListFilterHook.ts b/hooks/ProductListPageHooks/useProductListFilterHook.ts index 81202db0..ae549887 100644 --- a/hooks/ProductListPageHooks/useProductListFilterHook.ts +++ b/hooks/ProductListPageHooks/useProductListFilterHook.ts @@ -69,17 +69,17 @@ const useProductListingFilterHook = () => { if (existingSectionIndex !== -1) { if (isChecked) { - if (!updatedFilters[existingSectionIndex].value.includes(filterValue)) { - updatedFilters[existingSectionIndex].value.push(filterValue); + if (!updatedFilters?.[existingSectionIndex].value.includes(filterValue)) { + updatedFilters?.[existingSectionIndex].value.push(filterValue); } } else { updatedFilters[existingSectionIndex].value = updatedFilters[existingSectionIndex].value.filter((val: any) => val !== filterValue); - if (updatedFilters[existingSectionIndex].value.length === 0) { - updatedFilters = updatedFilters.filter((filter) => filter.name !== section); + if (updatedFilters?.[existingSectionIndex].value.length === 0) { + updatedFilters = updatedFilters?.filter((filter) => filter?.name !== section); } } } else if (isChecked) { - updatedFilters.push({ name: section, value: [filterValue] }); + updatedFilters?.push({ name: section, value: [filterValue] }); } duplicateFilters = [...updatedFilters]; diff --git a/hooks/ProductListPageHooks/useProductsDataHook.ts b/hooks/ProductListPageHooks/useProductsDataHook.ts index 73667945..18d7b220 100644 --- a/hooks/ProductListPageHooks/useProductsDataHook.ts +++ b/hooks/ProductListPageHooks/useProductsDataHook.ts @@ -96,6 +96,7 @@ const useProductListing = () => { page: '1', currency: 'INR', sort_by: sortBy, + scope: 'Database' }, }); } diff --git a/lib/query-client.ts b/lib/query-client.ts new file mode 100644 index 00000000..139c0e30 --- /dev/null +++ b/lib/query-client.ts @@ -0,0 +1,21 @@ +import { QueryClient } from '@tanstack/react-query'; + +const KC_LISTING_STALE_MS = 5 * 60 * 1000; // 5 minutes – same scope+cmcd won't refetch when navigating back +const KC_SESSION_FILTERS_STALE_MS = 5 * 60 * 1000; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: KC_LISTING_STALE_MS, + gcTime: 10 * 60 * 1000, // 10 min (formerly cacheTime) + }, + }, +}); + +export const KC_QUERY_KEYS = { + products: (cmcd: string, scope: string, filtersSignature: string) => + ['kc-products', cmcd, scope, filtersSignature] as const, + cart: (cmcd: string, odChr: string) => ['kc-cart', cmcd, odChr] as const, + voucher: (cmcd: string, voucherNoKey: string) => ['kc-voucher', cmcd, voucherNoKey] as const, + sessionFilters: (cmcd: string) => ['kc-session-filters', cmcd] as const, +}; diff --git a/next.config.js b/next.config.js index 77c839d6..1885d6d8 100644 --- a/next.config.js +++ b/next.config.js @@ -8,8 +8,17 @@ const nextConfig = { images: { domains: ['summit.8848digitalerp.com', 'staging-twinkle.8848digitalerp.com', 'emr-euro-shine.8848digitalerp.com', 'backend.atelier-reya.com', 'kc-backend.8848digitalcloud.com'], }, - reactStrictMode: false, + reactStrictMode: false, swcMinify: true, + async redirects() { + return [ + { + source: '/', + destination: '/product-category', + permanent: false, + }, + ] + }, }; module.exports = withBundleAnalyzer(nextConfig); diff --git a/package-lock.json b/package-lock.json index 2b3a5438..d5adc901 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,9 @@ "@popperjs/core": "^2.11.8", "@react-oauth/google": "^0.12.1", "@reduxjs/toolkit": "^1.9.5", + "@tanstack/query-async-storage-persister": "^5.90.22", + "@tanstack/react-query": "^5.59.0", + "@tanstack/react-query-persist-client": "^5.90.22", "@types/aos": "^3.0.4", "aos": "^2.3.4", "axios": "^1.4.0", @@ -25,6 +28,7 @@ "next": "13.4.1", "react": "18.2.0", "react-bootstrap": "^2.7.4", + "react-datepicker": "^8.10.0", "react-dom": "18.2.0", "react-ga4": "^2.1.0", "react-i18next": "^15.6.0", @@ -2678,14 +2682,43 @@ } }, "node_modules/@floating-ui/dom": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz", - "integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, + "node_modules/@floating-ui/react": { + "version": "0.27.16", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.16.tgz", + "integrity": "sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.6", + "@floating-ui/utils": "^0.2.10", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@floating-ui/utils": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", @@ -4304,6 +4337,76 @@ "tslib": "^2.4.0" } }, + "node_modules/@tanstack/query-async-storage-persister": { + "version": "5.90.22", + "resolved": "https://registry.npmjs.org/@tanstack/query-async-storage-persister/-/query-async-storage-persister-5.90.22.tgz", + "integrity": "sha512-I8Dbi79aoM2S2VqfuxTG13TkqmiDSiZ95Bi1YRXvwGVMsOnaJ99Ou1dIw53kHY3y10Vgwv3YYThw4TN/FM/N3A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.20", + "@tanstack/query-persist-client-core": "5.91.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", + "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-persist-client-core": { + "version": "5.91.19", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.91.19.tgz", + "integrity": "sha512-whrASqbVq8261Ue+/ZzpHsrLDYVfRaENs4HTdLuYKxawkGWzdMfV7BmOdWl8ZF0mEBEbrQR8V6oE3R635JF2Fw==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.20" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.21", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", + "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.20" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-persist-client": { + "version": "5.90.22", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.22.tgz", + "integrity": "sha512-BrD3Y/SsrSIDl+t/gpYvjvGHXd7m7oF+GIqktKE8LmTgt7bS1lYHd/CLkVxMPixTU53gHHVFfPNGmY7Hv4L/7g==", + "license": "MIT", + "dependencies": { + "@tanstack/query-persist-client-core": "5.91.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.90.20", + "react": "^18 || ^19" + } + }, "node_modules/@testing-library/jest-dom": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", @@ -6388,6 +6491,7 @@ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.1" }, @@ -6823,6 +6927,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debounce": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz", @@ -16342,6 +16456,30 @@ "react": "~0.14.9 || ^15.0.0 || ^16.0.0" } }, + "node_modules/react-datepicker": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-8.10.0.tgz", + "integrity": "sha512-JIXuA+g+qP3c4MVJpx24o7n1gnv3WV/8A/D6964HucY1FlSEc30+ITPNUfbKZXYHl5rruCtxYCwi2lzn7gaz7g==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.15", + "clsx": "^2.1.1", + "date-fns": "^4.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/react-datepicker/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -17587,6 +17725,12 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/tabbable": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", + "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", + "license": "MIT" + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", diff --git a/package.json b/package.json index a87a779e..43386888 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "@popperjs/core": "^2.11.8", "@react-oauth/google": "^0.12.1", "@reduxjs/toolkit": "^1.9.5", + "@tanstack/query-async-storage-persister": "^5.90.22", + "@tanstack/react-query": "^5.59.0", + "@tanstack/react-query-persist-client": "^5.90.22", "@types/aos": "^3.0.4", "aos": "^2.3.4", "axios": "^1.4.0", @@ -32,6 +35,7 @@ "next": "13.4.1", "react": "18.2.0", "react-bootstrap": "^2.7.4", + "react-datepicker": "^8.10.0", "react-dom": "18.2.0", "react-ga4": "^2.1.0", "react-i18next": "^15.6.0", diff --git a/pages/my-orders/[orderId]/index.tsx b/pages/my-orders/[orderId]/index.tsx index 53ec2076..9133a3c0 100644 --- a/pages/my-orders/[orderId]/index.tsx +++ b/pages/my-orders/[orderId]/index.tsx @@ -5,8 +5,8 @@ import OrderDetails from '../../../components/FallbackOrderComponents/OrderDetai const OrderDetail = () => { return ( <> - {/* */} - + + {/* */} ); }; diff --git a/pages/my-orders/index.tsx b/pages/my-orders/index.tsx index aa374169..36f5accd 100644 --- a/pages/my-orders/index.tsx +++ b/pages/my-orders/index.tsx @@ -6,8 +6,8 @@ import OrderListing from '../../components/FallbackOrderComponents/OrderListing' const MyOrder = () => { return ( <> - {/* */} - + + {/* */} ); }; diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 0fa0668b..fa1621ad 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -322,5 +322,40 @@ "Item Selected": "Artikel ausgewählt", "Apply": "Anwenden", "Stock Cart": "Warenkorb", - "profile": "Profil" + "profile": "Profil", + "available_in_stock": "Auf Lager", + "no_item_found": "Kein Artikel gefunden", + "copy_stock_id": "Bestands-ID kopieren", + "refresh": "Aktualisieren", + "refresh_rate": "Aktualisierungsrate", + "copy_with_rate": "Mit Rate kopieren", + "rm_category": "RM-Kategorie", + "date": "Datum", + "copy_lab_rate": "Laborsatz kopieren", + "voucher_odNo": "Beleg OdNr", + "voucher_date": "Belegdatum", + "select": "Auswählen", + "from": "Von", + "to": "Bis", + "grade_change": "Gradänderung", + + "list_view": "Listenansicht", + "grid_view": "Rasteransicht", + "back": "Zurück", + "status": "Status", + "voucher_no": "Belegnummer", + "Stock Ids": "Bestands-IDs", + "Designs": "Designs", + "your_stock_cart_for": "Ihr Stockwagen für", + "for_pricing_and_vouchers": "für Preisgestaltung und Gutscheine", + + "print": "Drucken", + "detailed": "Detailliert", + "overview": "Übersicht", + + "sync_stock": "Bestand synchronisieren", + "select_all_client": "Alle Kunden auswählen", + "client_code": "Kundencode", + "only_for_stock_filtering": "Nur zur Bestandsfilterung", + "sync": "Synchronisieren" } \ No newline at end of file diff --git a/public/locales/en/common.json b/public/locales/en/common.json index ae736c9d..c2104b8f 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -322,5 +322,55 @@ "Item Selected": "Item Selected", "Apply": "Apply", "Stock Cart": "Stock Cart", - "profile": "Profile" + "profile": "Profile", + "available_in_stock": "Available in Stock", + "no_item_found": "No item found", + "copy_stock_id": "Copy Stock Id", + "refresh": "Refresh", + "refresh_rate": "Refresh Rate", + "copy_with_rate" : "Copy With Rate", + "rm_category": "Rm Category", + "date": "Date", + "copy_lab_rate": "Copy Lab Rate", + "voucher_odNo": "Voucher OdNo", + "voucher_date": "Voucher Date", + "select": "Select", + "from": "From", + "to": "To", + "grade_change": "Grade Change", + + "list_view": "List View", + "grid_view": "Grid View", + "back": "Back", + "status": "Status", + "voucher_no": "Voucher No.", + "Stock Ids": "Stock Ids", + "Designs" : "Designs", + "colorstone": "Color Stone", + "your_stock_cart_for": "Your Stock Cart for", + "delete": "Delete", + "go_to_cart": "Go to Cart", + "go_to_stock_cart": "Go to Stock Cart", + "selected_items_moved_to_": "Selected item(s) were successfully moved to", + "metal_grade": "Metal Grade", + "for": "for", + "to_view": "To View", + "scope_for_customer": "for the customer, please select the customer & scope.", + "list_display": "List Display", + "selected": "Selected", + "card_details": "Card Details", + "refresh_from": "Refresh From", + "refreshing_rates": "Refreshing Rates", + "updating_items": "Updating Items", + "for_pricing_and_vouchers": "for Pricing and Voucher", + + "print": "Print", + "detailed": "Detailed", + "overview": "Overview", + + "sync_stock": "Sync Stock", + "select_all_client": "Select All Clients", + "client_code": "Client Code", + "only_for_stock_filtering": "only for Stock filtering", + "sync": "Sync" } \ No newline at end of file diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 3b0cbb0f..b75fe6e9 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -322,5 +322,40 @@ "Item Selected": "Artículo seleccionado", "Apply": "Aplicar", "Stock Cart": "Carrito de stock", - "profile": "Perfil" + "profile": "Perfil", + "available_in_stock": "Disponible en stock", + "no_item_found": "No se encontró ningún artículo", + "copy_stock_id": "Copiar ID de stock", + "refresh": "Actualizar", + "refresh_rate": "Frecuencia de actualización", + "copy_with_rate": "Copiar con tasa", + "rm_category": "Categoría RM", + "date": "Fecha", + "copy_lab_rate": "Copiar tasa de laboratorio", + "voucher_odNo": "Voucher OdNo", + "voucher_date": "Fecha del voucher", + "select": "Seleccionar", + "from": "Desde", + "to": "Hasta", + "grade_change": "Cambio de grado", + + "list_view": "Vista de lista", + "grid_view": "Vista de cuadrícula", + "back": "Atrás", + "status": "Estado", + "voucher_no": "Número de comprobante", + "Stock Ids": "IDs de inventario", + "Designs": "Diseños", + "your_stock_cart_for": "Su carrito de stock para", + "for_pricing_and_vouchers": "para precios y vales", + + "print": "Imprimir", + "detailed": "Detallado", + "overview": "Resumen", + + "sync_stock": "Sincronizar stock", + "select_all_client": "Seleccionar todos los clientes", + "client_code": "Código de cliente", + "only_for_stock_filtering": "Solo para el filtrado de stock", + "sync": "Sincronizar" } \ No newline at end of file diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 2ab5757e..0181909d 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -322,5 +322,40 @@ "Item Selected": "Article sélectionné", "Apply": "Appliquer", "Stock Cart": "Panier de stock", - "profile": "Profil" + "profile": "Profil", + "available_in_stock": "Disponible en stock", + "no_item_found": "Aucun article trouvé", + "copy_stock_id": "Copier l’identifiant du stock", + "refresh": "Rafraîchir", + "refresh_rate": "Taux de rafraîchissement", + "copy_with_rate": "Copier avec taux", + "rm_category": "Catégorie RM", + "date": "Date", + "copy_lab_rate": "Copier le taux de labo", + "voucher_odNo": "Bon OdNo", + "voucher_date": "Date du bon", + "select": "Sélectionner", + "from": "De", + "to": "À", + "grade_change": "Changement de grade", + + "list_view": "Vue en liste", + "grid_view": "Vue en grille", + "back": "Retour", + "status": "Statut", + "voucher_no": "Numéro de reçu", + "Stock Ids": "Identifiants de stock", + "Designs": "Designs", + "your_stock_cart_for": "Votre panier de stock pour", + "for_pricing_and_vouchers": "pour la tarification et les bons", + + "print": "Imprimer", + "detailed": "Détaillé", + "overview": "Aperçu", + + "sync_stock": "Synchroniser le stock", + "select_all_client": "Sélectionner tous les clients", + "client_code": "Code client", + "only_for_stock_filtering": "Uniquement pour le filtrage du stock", + "sync": "Synchroniser" } \ No newline at end of file diff --git a/public/locales/it/common.json b/public/locales/it/common.json index 65a22d2f..9603d884 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -322,5 +322,40 @@ "Item Selected": "Articolo selezionato", "Apply": "Applica", "Stock Cart": "Carrello scorte", - "profile": "Profilo" + "profile": "Profilo", + "available_in_stock": "Disponibile in magazzino", + "no_item_found": "Nessun articolo trovato", + "copy_stock_id": "Copia ID stock", + "refresh": "Aggiorna", + "refresh_rate": "Frequenza di aggiornamento", + "copy_with_rate": "Copia con tariffa", + "rm_category": "Categoria RM", + "date": "Data", + "copy_lab_rate": "Copia tariffa laboratorio", + "voucher_odNo": "Voucher OdNo", + "voucher_date": "Data del voucher", + "select": "Seleziona", + "from": "Da", + "to": "A", + "grade_change": "Cambio di grado", + + "list_view": "Vista elenco", + "grid_view": "Vista griglia", + "back": "Indietro", + "status": "Stato", + "voucher_no": "Numero del voucher", + "Stock Ids": "ID di magazzino", + "Designs": "Design", + "your_stock_cart_for": "Il tuo carrello stock per", + "for_pricing_and_vouchers": "per prezzi e voucher", + + "print": "Stampa", + "detailed": "Dettagliato", + "overview": "Riepilogo", + + "sync_stock": "Sincronizza stock", + "select_all_client": "Seleziona tutti i clienti", + "client_code": "Codice cliente", + "only_for_stock_filtering": "Solo per il filtraggio dello stock", + "sync": "Sincronizza" } \ No newline at end of file diff --git a/services/api-handlers/emr-api-handler.ts b/services/api-handlers/emr-api-handler.ts index b0a86757..eb0e42f7 100644 --- a/services/api-handlers/emr-api-handler.ts +++ b/services/api-handlers/emr-api-handler.ts @@ -1,13 +1,26 @@ -import { executeEMRDeleteAPI, executeEMRGetAPI, executeEMRPostAPI, executeEMRPutAPI } from '../../utils/http-methods'; +import { EMRApiKey } from "../../utils/api-sdk-registry/emr_api_sdk_registry"; +import { + executeEMRDeleteAPI, + executeEMRGetAPI, + executeEMRPostAPI, + executeEMRPutAPI, +} from "../../utils/http-methods"; -const executeEMRAPIHandler = (apiMethod: string, apiName: string, apiData: string, token?: string, path?: string) => { - if (apiMethod === 'GET') { - return executeEMRGetAPI(apiName, apiData, token, path); - } else if (apiMethod === 'POST') { +const executeEMRAPIHandler = ( + apiMethod: string, + apiName: EMRApiKey, + apiData: string, + token?: string, + path?: string, + isBlob?: boolean, +) => { + if (apiMethod === "GET") { + return executeEMRGetAPI(apiName, apiData, token, path, isBlob); + } else if (apiMethod === "POST") { return executeEMRPostAPI(apiName, apiData, token, path); - } else if (apiMethod === 'PUT') { + } else if (apiMethod === "PUT") { return executeEMRPutAPI(apiName, apiData, token, path); - } else if (apiMethod === 'DELETE') { + } else if (apiMethod === "DELETE") { return executeEMRDeleteAPI(apiName, apiData, token, path); } }; diff --git a/store/root-reducer.ts b/store/root-reducer.ts index 701841f6..6723fdf2 100644 --- a/store/root-reducer.ts +++ b/store/root-reducer.ts @@ -2,6 +2,7 @@ import { combineReducers } from '@reduxjs/toolkit'; import { resetStore } from './slices/auth/logout-slice'; import GetAccessTokenReducer from './slices/auth/token-login-slice'; import cartLocalSlice from './slices/cart-slices/cart-local-slice'; +import stockCartLocalSlice from './slices/cart-slices/stock-cart-local-slice'; import catalogLocalSlice from './slices/catalog-slice/catalog-local-slice'; import CurrencyReducer from './slices/general_slices/multi-currency-slice'; import MultiLanguageReducer from './slices/general_slices/multilang-slice'; @@ -23,6 +24,7 @@ const appReducer = combineReducers({ SelectedLangDataReducer: SelectedLangDataScreen, wishlistSlice: wishlistSlice, cart: cartLocalSlice, + stockCart: stockCartLocalSlice, catalogSlice: catalogLocalSlice, quickOrder: quickOrderSlice, KCSlice: kcSlice, diff --git a/store/slices/cart-slices/cart-local-slice.ts b/store/slices/cart-slices/cart-local-slice.ts index a2d12f4b..d841ca56 100644 --- a/store/slices/cart-slices/cart-local-slice.ts +++ b/store/slices/cart-slices/cart-local-slice.ts @@ -25,7 +25,7 @@ const cartSlice = createSlice({ reducers: { addCartList: (state, action) => { state.items = action.payload?.cartData; - state.cartCount = state?.items?.length || 0; + state.cartCount = action.payload.cartCount; state.grandTotal = action.payload.grandTotal; state.quotation_Id = action?.payload?.quotationId; }, diff --git a/store/slices/cart-slices/stock-cart-local-slice.ts b/store/slices/cart-slices/stock-cart-local-slice.ts new file mode 100644 index 00000000..72fb2554 --- /dev/null +++ b/store/slices/cart-slices/stock-cart-local-slice.ts @@ -0,0 +1,71 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { RootState } from '../../root-reducer'; + +interface CartState { + items: any[]; + stockCartCount: any; + grandTotal: number; + error: string | null; + isLoading: 'idle' | 'pending' | 'succeeded' | 'failed'; + quotation_Id: string; +} + +const initialState: CartState = { + items: [], + stockCartCount: 0, + grandTotal: 0, + error: null, + isLoading: 'idle', + quotation_Id: '', +}; + +const cartSlice = createSlice({ + name: 'stockCart', + initialState, + reducers: { + addStockCartList: (state, action) => { + state.items = action.payload?.cartData; + state.stockCartCount = action.payload.stockCartCount; + state.grandTotal = action.payload.grandTotal; + state.quotation_Id = action?.payload?.quotationId; + }, + addItemToStockCart: (state, action) => { + if (!state.items) { + state.items = []; + } + const mergedArray = [...state?.items, ...action?.payload.filter((item: any) => !state?.items.includes(item))]; + state.items = mergedArray; + state.stockCartCount = state?.items?.length || 1; + + state.error = null; + }, + removeItemFromStockCart: (state, action: PayloadAction) => { + state.items = state.items.filter((item) => item !== action.payload); + state.stockCartCount = state.stockCartCount - 1; + state.error = null; + }, + updateItemQuantity: (state, action: PayloadAction<{ id: number; quantity: number }>) => { + const item = state.items.find((item) => item.id === action.payload.id); + if (item) { + item.quantity = action.payload.quantity; + } + state.error = null; + }, + setLoading: (state, action: PayloadAction<'idle' | 'pending' | 'succeeded' | 'failed'>) => { + state.isLoading = action.payload; + }, + setError: (state, action: PayloadAction) => { + state.error = action.payload; + }, + clearCart: (state) => { + state.items = []; + state.error = null; + state.stockCartCount = 0; + }, + }, +}); +export const { addItemToStockCart, removeItemFromStockCart, updateItemQuantity, setLoading, setError, clearCart, addStockCartList } = cartSlice.actions; + +export const selectStockCart = (state: RootState) => state.stockCart; + +export default cartSlice.reducer; diff --git a/store/slices/general_slices/kc-slice.ts b/store/slices/general_slices/kc-slice.ts index e7443f7f..33654e81 100644 --- a/store/slices/general_slices/kc-slice.ts +++ b/store/slices/general_slices/kc-slice.ts @@ -1,39 +1,64 @@ import { createSlice } from "@reduxjs/toolkit"; +interface FiltersState { + currentScope: string; + scope: any; + customer: any; + filters: { [customer: string]: { [scope: string]: any } }; + filtersSetOfAPI: { [customer: string]: { [scope: string]: any } }; + toggleProductView: 'grid' | 'list'; + hideFiltersOnFirstLoad: boolean; + metalRateSidebar: boolean; + userDefaultSidebar: boolean; + prevCSFilters: any; + gridCols: number; + goldRate: number; + palladiumRate: number; + platinumRate: number; + silverRate: number; + userDefaultData: any; + userDefaultLoading: boolean; + designBankCount: number; + gradeChangeList: {label: string, value: string}[]; + diamondChangeList: {label: string, value: string}[]; + colorStoneChangeList: {label: string, value: string}[]; + showProductCardDetails: boolean; + selectAllProducts: boolean; + designSizes: any[] | null, + attributesData: any[] | null, +} + +const initialState: FiltersState = { + hideFiltersOnFirstLoad: true, + metalRateSidebar: false, + userDefaultSidebar: false, + prevCSFilters: {}, + gridCols: 4, + goldRate: 0, + palladiumRate: 0, + platinumRate: 0, + silverRate: 0, + filters: {}, + filtersSetOfAPI: {}, + currentScope: 'Database', + customer: null, + scope: { label: 'New Session (PDCM Design Bank)', value: 'Database' }, + userDefaultData: null, + userDefaultLoading: false, + designBankCount: 0, + gradeChangeList: [], + diamondChangeList: [], + colorStoneChangeList: [], + toggleProductView: 'grid', + showProductCardDetails: false, + selectAllProducts: false, + designSizes: [], + attributesData: [], +}; + export const KCSlice = createSlice({ name: "KC", - initialState: { - // selectedProducts: [], - // hideSelectAllBtn: false, - hideFiltersOnFirstLoad: true, - // actionBtnLoader: false, - // activeScope: "Current Session", - // selectedCustomerCode: { value: "", label: "" }, - // voucherNo: "", - metalRateSidebar: false, - prevCSFilters: {}, - gridCols: 4, - goldRate: 0, - palladiumRate: 0, - platinumRate: 0, - silverRate: 0, - filters: { - Database: { selectedScope: { label: 'New Session', value: 'Database' } }, - Stock: { selectedScope: { label: 'Stock', value: 'Stock' } }, - 'Current Session': { selectedScope: { label: 'Current Session (QT/CS)', value: 'Current Session' } }, - Cart: { selectedScope: { label: 'Cart (QT/CT)', value: 'Cart' } }, - 'Stock Cart': { selectedScope: { label: 'Stock Cart', value: 'Stock Cart' } }, - Voucher: { selectedScope: { label: 'Voucher', value: 'Voucher' } }, - }, - filtersSetOfAPI: { - Database: { selectedScope: { label: 'New Session', value: 'Database' } }, - Stock: { selectedScope: { label: 'Stock', value: 'Stock' } }, - 'Current Session': { selectedScope: { label: 'Current Session (QT/CS)', value: 'Current Session' } }, - Cart: { selectedScope: { label: 'Cart (QT/CT)', value: 'Cart' } }, - 'Stock Cart': { selectedScope: { label: 'Stock Cart', value: 'Stock Cart' } }, - Voucher: { selectedScope: { label: 'Voucher', value: 'Voucher' } }, - }, - }, + initialState, reducers: { setHideFiltersOnFirstLoad: (state, action) => { state.hideFiltersOnFirstLoad = action.payload; @@ -56,18 +81,75 @@ export const KCSlice = createSlice({ setMetalRateSidebar: (state, action) => { state.metalRateSidebar = action.payload; }, + setUserDefaultSidebar: (state, action) => { + state.userDefaultSidebar = action.payload; + }, setPrevCSFilters: (state, action) => { state.prevCSFilters = action.payload; }, + setCurrentScope: (state, action) => { + state.currentScope = action.payload; + }, + setCustomer: (state, action) => { + state.customer = action.payload; + }, + setScope: (state, action) => { + state.scope = action.payload; + }, setFilters: (state, action) => { - state.filters = action.payload; + const { customer, scope, data } = action.payload; + + if (!state.filters?.[customer]) state.filters[customer] = {}; + state.filters[customer][scope] = { + ...(state.filters?.[customer]?.[scope] || {}), + ...data, + }; }, setFiltersSetOfAPI: (state, action) => { - state.filtersSetOfAPI = action.payload; + const { customer, scope, data } = action.payload; + + if (!state.filtersSetOfAPI?.[customer]) state.filtersSetOfAPI[customer] = {}; + state.filtersSetOfAPI[customer][scope] = { + ...(state.filtersSetOfAPI?.[customer]?.[scope] || {}), + ...data, + }; + }, + setUserDefaultData: (state, action) => { + state.userDefaultData = action.payload; + }, + setUserDefaultLoading: (state, action) => { + state.userDefaultLoading = action.payload; + }, + setDesignBankCount: (state, action) => { + state.designBankCount = action.payload; + }, + setGradeChangeList: (state, action) => { + state.gradeChangeList = action.payload; + }, + setDiamondChangeList: (state, action) => { + state.diamondChangeList = action.payload; + }, + setColorStoneChangeList: (state, action) => { + state.colorStoneChangeList = action.payload; + }, + setToggleProductView: (state, action) => { + state.toggleProductView = action.payload; + }, + setShowProductCardDetails: (state, action) => { + state.showProductCardDetails = action.payload; + }, + setSelectAllProducts: (state, action) => { + state.selectAllProducts = action.payload; + }, + setDesignSizes: (state, action) => { + state.designSizes = action.payload; + }, + setAttributesData: (state, action) => { + state.attributesData = action.payload; }, }, }) -export const { setHideFiltersOnFirstLoad, setGridCols, setGoldRate, setPalladiumRate, setPlatinumRate, setSilverRate, setMetalRateSidebar, setPrevCSFilters, setFilters, setFiltersSetOfAPI } = KCSlice.actions; +export const { setHideFiltersOnFirstLoad, setGridCols, setGoldRate, setPalladiumRate, setPlatinumRate, setSilverRate, setMetalRateSidebar, setPrevCSFilters, setFilters, setFiltersSetOfAPI, setCurrentScope, setCustomer, setScope, setUserDefaultData, setUserDefaultLoading, setUserDefaultSidebar, setDesignBankCount, setGradeChangeList, setDiamondChangeList, setColorStoneChangeList, setShowProductCardDetails, setSelectAllProducts, setToggleProductView, setDesignSizes, setAttributesData } = KCSlice.actions; export const KCFromStore = (state: any) => state.KCSlice; export default KCSlice.reducer; \ No newline at end of file diff --git a/utils/api-sdk-registry/emr_api_sdk_registry.ts b/utils/api-sdk-registry/emr_api_sdk_registry.ts index ffb836c3..b807c0fb 100644 --- a/utils/api-sdk-registry/emr_api_sdk_registry.ts +++ b/utils/api-sdk-registry/emr_api_sdk_registry.ts @@ -1,41 +1,62 @@ -const emrAPISDKRegistry: any = { - 'login-api': '/api/login', - 'get-page-components-list-api': '/api/getComponents', - 'get-collections-list-api': '/api/getDsgCollections', - 'get-current-session-filters-api': '/api/getCsFilters', - 'post-insert-current-session-filters-api': '/api/insertCsFltrs', - 'get-product-listing-filters-api': '/api/getCatalogueFilterMasters', - 'get-product-listing-y-filters-api': '/api/getyCatalogueFilterMasters', - 'get-product-list-api': '/api/getDesigns', - 'delete-current-session-filters-api': '/api/delOrdDsg', - 'post-move-current-session-api': '/api/copyDesign', - 'product-detail-api': '/api/getDesignDetails', - 'cart-list': '/api/getOrdDsgList', - 'update-cart': '/api/updateOrdDsg', - 'delete-cart': '/api/clearOrderDsg', - 'place-order-api': '/api/createOrder', - 'price-list-api': '/api/fetchPrice', - 'get-site-map': '/api/collection-urls', - 'refresh-price-api': '/api/refreshPrice', - 'get-voucher-product-list': '/api/getVoucherDetails', - 'get-product-design-y-options': '/api/getyDsgConfg', - 'get-meta-tags-api': '/api/seo-api', - 'delete-current-session-api': '/api/clearUserData', - 'forgot-password-api': '/api/forgotPwd', - 'sign-up-api': '/api/SignUp', - 'order-list-api': '/api/getListViewData', - 'update-user-preferences': '/api/storeUserPreferences', - 'bom-details-api': '/api/bomChange', - 'get-metal-rate-api': '/api/getMetalRT', - 'post-metal-rate-api': '/api/updateMetalRT', - 'get-sizes-api': '/api/getSizes', - 'copy-stock-design': '/api/copyStckDsg', - 'stock-block-api': '/api/stockBlock', - 'get-voucher-headers-details-api': '/api/getVchHeaderDetails', - 'send-reset-password-email-api': '/api/sendEmail', - 'verify-reset-password-token-api': '/api/verifyLink', - 'get-filtered-sales-customer-api' : '/api/getFilteredSalesCustomer', - 'get-rate-look-up-options-api': '/api/getPLlist', -}; +const emrAPISDKRegistry = { + 'login-api': '/api/login', + 'get-page-components-list-api': '/api/getComponents', + 'get-collections-list-api': '/api/getDsgCollections', + 'get-current-session-filters-api': '/api/getCsFilters', + 'post-insert-current-session-filters-api': '/api/insertCsFltrs', + 'get-product-listing-filters-api': '/api/getCatalogueFilterMasters', + 'get-product-listing-y-filters-api': '/api/getyCatalogueFilterMasters', + 'get-product-list-api': '/api/getDesigns', + 'delete-current-session-filters-api': '/api/delOrdDsg', + 'post-move-current-session-api': '/api/copyDesign', + 'product-detail-api': '/api/getDesignDetails', + 'cart-list': '/api/getOrdDsgList', + 'update-cart': '/api/updateOrdDsg', + 'delete-cart': '/api/clearOrderDsg', + 'place-order-api': '/api/createOrder', + 'price-list-api': '/api/fetchPrice', + 'get-site-map': '/api/collection-urls', + 'refresh-price-api': '/api/refreshPrice', + 'get-product-design-y-options': '/api/getyDsgConfg', + 'get-user-default-data': '/api/getUserDeafults', + 'get-list-data-api': '/api/getList', + 'copy-stock-design': '/api/copyStckDsg', + 'get-voucher-product-list': '/api/getVoucherDetails', + 'get-rate-look-up-options-api': '/api/getPLlist', + 'create-customer-api': '/api/duplicate', + 'update-customer-api': '/api/updateFields', + 'get-pos-entry-api': '/api/getYPOS', + 'post-pos-closing-api': '/api/insertOrUpdateYPOS', + 'post-invoice-data-api': '/api/insertYPosInvoice', + 'get-invoice-list-api': '/api/getYPosInvoice', + 'refresh-voucher-rate-api': '/api/refreshRates', + 'order-list-api': '/api/getListViewData', + 'get-buttons-api': '/api/getYPosCTA', + 'get-vouchers-list-to-create-direct-invoice-api': '/api/getVouchersToCreateDirectInvoice', + 'get-report-api': '/api/getJasperReport', + 'get-meta-tags-api': '/api/seo-api', + 'delete-current-session-api': '/api/clearUserData', + 'forgot-password-api': '/api/forgotPwd', + 'sign-up-api': '/api/SignUp', + 'update-user-preferences': '/api/storeUserPreferences', + 'bom-details-api': '/api/bomChange', + 'get-metal-rate-api': '/api/getMetalRT', + 'post-metal-rate-api': '/api/updateMetalRT', + 'get-sizes-api': '/api/getSizes', + 'stock-block-api': '/api/stockBlock', + 'get-voucher-headers-details-api': '/api/getVchHeaderDetails', + 'send-reset-password-email-api': '/api/sendEmail', + 'verify-reset-password-token-api': '/api/verifyLink', + 'get-filtered-sales-customer-api' : '/api/getFilteredSalesCustomer', + 'check-design-stock-for-ct-api': '/api/checkDsgStckforCT', + 'get-param-list-api': '/api/getParamList', + 'post-user-default-data': '/api/postUserDeafults', + 'get-y-param-list-api': '/api/getyParamList', + 'update-item-instruction-api': '/api/updateFields', + "sync-stock-list-api": "/api/manualStockSync", +} as const; + +export type EMRApiKey = keyof typeof emrAPISDKRegistry; +export type EMRApiPath = (typeof emrAPISDKRegistry)[EMRApiKey]; export default emrAPISDKRegistry; diff --git a/utils/engine-runner.ts b/utils/engine-runner.ts index f8977cd3..dcf19621 100644 --- a/utils/engine-runner.ts +++ b/utils/engine-runner.ts @@ -1,7 +1,7 @@ import executeEMRAPIHandler from '../services/api-handlers/emr-api-handler'; import executeSummitAPIHandler from '../services/api-handlers/summit-api-handler'; -const engineRunner = (apiMethod: string, apiName: string, apiData: any, token?: string, path?: string) => { +const engineRunner = (apiMethod: string, apiName: string, apiData: any, token?: string, path?: string, isBlob?: boolean) => { const engineName = process.env.NEXT_PUBLIC_ENGINE_NAME; const handlers: Record = { Summit: executeSummitAPIHandler, @@ -13,7 +13,7 @@ const engineRunner = (apiMethod: string, apiName: string, apiData: any, token?: throw new Error(`Unsupported engine name: ${engineName}`); } - return handler(apiMethod, apiName, apiData, token, path); + return handler(apiMethod, apiName, apiData, token, path, isBlob); }; export default engineRunner; diff --git a/utils/get-api-sdk.ts b/utils/get-api-sdk.ts index a948fbec..1636bb87 100644 --- a/utils/get-api-sdk.ts +++ b/utils/get-api-sdk.ts @@ -1,9 +1,9 @@ import apiSdkRegistry from './api_sdk_registry'; -import emrSdkRegistry from './api-sdk-registry/emr_api_sdk_registry'; +import emrSdkRegistry, { EMRApiKey } from './api-sdk-registry/emr_api_sdk_registry'; const fetchAPISDK = (apiName: string) => { const engineName = process.env.NEXT_PUBLIC_ENGINE_NAME; - if (engineName === 'EMR') return emrSdkRegistry[apiName]; + if (engineName === 'EMR') return emrSdkRegistry[apiName as EMRApiKey]; else if (engineName === 'Summit') return apiSdkRegistry[apiName]; }; diff --git a/utils/http-methods.ts b/utils/http-methods.ts index 79b23f31..e2a5c0bf 100644 --- a/utils/http-methods.ts +++ b/utils/http-methods.ts @@ -1,7 +1,10 @@ -import axios from 'axios'; -import fetchAPISDK from '../utils/get-api-sdk'; -import { CONSTANTS } from '../services/config/app-config'; -import APP_CONFIG from '../interfaces/app-config-interface'; +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { CONSTANTS } from "../services/config/app-config"; +import fetchAPISDK from "../utils/get-api-sdk"; +import axios from "axios"; +import { EMRApiKey } from "./api-sdk-registry/emr_api_sdk_registry"; +import APP_CONFIG from "../interfaces/app-config-interface"; /** * @function getVME - VME stands for Version, Method and Entity for that API function. @@ -17,7 +20,13 @@ const getVME = (frappeAppConfig: APP_CONFIG, apiName: string) => { }; }; -export const executeEMRGetAPI = async (apiName: string, apiData: any, token?: string, path?: string) => { +export const executeEMRGetAPI = async ( + apiName: EMRApiKey, + apiData: any, + token?: string, + _path?: string, + isBlob?: boolean, +) => { const sdkInfo = fetchAPISDK(apiName); let apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value if (apiData && Object.keys(apiData).length !== 0) { @@ -28,30 +37,46 @@ export const executeEMRGetAPI = async (apiName: string, apiData: any, token?: st apiURL = `${CONSTANTS.API_BASE_URL}${sdkInfo}?${storeParams}`; } // Make the API call - const response = await callGetAPI(`${apiURL}`, `token ${token}`); + const response = await callGetAPI(`${apiURL}`, `token ${token}`, isBlob); return response; }; -export const executeEMRPostAPI = async (apiName: string, apiData: any, token?: string, path?: string) => { +export const executeEMRPostAPI = async ( + apiName: EMRApiKey, + apiData: any, + token?: string, + _path?: string +) => { const sdkInfo = fetchAPISDK(apiName); - let apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value + const apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value const response = await callPostAPI(apiURL, apiData, `token ${token}`); return response; }; -export const executeEMRPutAPI = async (apiName: string, apiData: any, token?: string, path?: string) => { +export const executeEMRPutAPI = async ( + apiName: EMRApiKey, + apiData: any, + token?: string, + _path?: string +) => { const sdkInfo = fetchAPISDK(apiName); - let apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value + const apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value const response = await callPutAPI(apiURL, apiData, `token ${token}`); return response; }; -export const executeEMRDeleteAPI = async (apiName: string, apiData: any, token?: string, path?: string) => { +export const executeEMRDeleteAPI = async ( + apiName: EMRApiKey, + apiData: any, + token?: string, + _path?: string +) => { const sdkInfo = fetchAPISDK(apiName); - let apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value + const apiURL: string = `${CONSTANTS.API_BASE_URL}${sdkInfo}`; // Initialize with a default value const response = await callDeleteAPI(apiURL, apiData, `token ${token}`); return response; }; + /** * Fetches data from an API by handling repetitive steps like fetching SDK names, * getting the Frappe app version, constructing the API URL, and making the call. @@ -132,13 +157,14 @@ export const executeDELETEAPI = async (frappeAppConfig: APP_CONFIG, apiName: str return response; }; -export const callGetAPI = async (url: string, token?: any) => { +export const callGetAPI = async (url: string, token?: any, isBlob?: boolean) => { let response: any; - const API_CONFIG = { + const API_CONFIG: any = { headers: { - Accept: 'application/json', + Accept: isBlob ? "*/*" : "application/json", ...(token ? { Authorization: token } : {}), }, + ...(isBlob ? { responseType: "blob" } : {}), // ✅ HERE }; await axios .get(`${url}`, { @@ -149,15 +175,17 @@ export const callGetAPI = async (url: string, token?: any) => { response = res; }) .catch((err: any) => { - if (err.code === 'ECONNABORTED') { - response = 'Request timed out. API took too long to return response.'; - } else if (err.code === 'ERR_BAD_REQUEST') { + if (err.code === "ECONNABORTED") { + response = "Request timed out. API took too long to return response."; + } else if (err.code === "ERR_BAD_REQUEST") { // response = err?.response?.data?.exception ?? `Status Code: ${err.status} Bad Request`; response = err?.response?.data?.exception ?? err?.response; - } else if (err.code === 'ERR_INVALID_URL') { - response = 'Invalid URL'; + } else if (err.code === "ERR_INVALID_URL") { + response = "Invalid URL"; } else { - response = err?.response?.data?.error || `Status Code: ${err.status}. ${err?.message}`; + response = + err?.response?.data?.error || + `Status Code: ${err.status}. ${err?.message}`; } }); return response; @@ -178,13 +206,13 @@ export const callPutAPI = async (url: string, body: any, token?: any) => { response = res; }) .catch((err: any) => { - if (err.code === 'ECONNABORTED') { - response = 'Request timed out. API took too long to return response.'; - } else if (err.code === 'ERR_BAD_REQUEST') { + if (err.code === "ECONNABORTED") { + response = "Request timed out. API took too long to return response."; + } else if (err.code === "ERR_BAD_REQUEST") { // response = err?.response?.data?.exception ?? `Status Code: ${err.status} Bad Request`; response = err?.response?.data?.exception ?? err?.response; - } else if (err.code === 'ERR_INVALID_URL') { - response = 'Invalid URL'; + } else if (err.code === "ERR_INVALID_URL") { + response = "Invalid URL"; } else { response = err; } @@ -208,13 +236,13 @@ export const callPostAPI = async (url: string, body: any, token?: any) => { response = res; }) .catch((err: any) => { - if (err.code === 'ECONNABORTED') { - response = 'Request timed out. API took too long to return response.'; - } else if (err.code === 'ERR_BAD_REQUEST') { + if (err.code === "ECONNABORTED") { + response = "Request timed out. API took too long to return response."; + } else if (err.code === "ERR_BAD_REQUEST") { // response = err?.response?.data?.exception ?? `Status Code: ${err.status} Bad Request`; response = err?.response?.data?.exception ?? err?.response; - } else if (err.code === 'ERR_INVALID_URL') { - response = 'Invalid URL'; + } else if (err.code === "ERR_INVALID_URL") { + response = "Invalid URL"; } else { response = err; } @@ -230,17 +258,17 @@ const callDeleteAPI = async (url: string, body?: any, token?: any) => { }; await axios .delete(`${url}`, { headers: { ...API_CONFIG.headers }, data: { ...body } }) - .then((res) => { + .then((res: any) => { response = res; }) .catch((err: any) => { - if (err.code === 'ECONNABORTED') { - response = 'Request timed out. API took too long to return response.'; - } else if (err.code === 'ERR_BAD_REQUEST') { + if (err.code === "ECONNABORTED") { + response = "Request timed out. API took too long to return response."; + } else if (err.code === "ERR_BAD_REQUEST") { // response = err?.response?.data?.exception ?? `Status Code: ${err.status} Bad Request`; response = err?.response?.data?.exception ?? err?.response; - } else if (err.code === 'ERR_INVALID_URL') { - response = 'Invalid URL'; + } else if (err.code === "ERR_INVALID_URL") { + response = "Invalid URL"; } else { response = err; }