From 7966f67569d01c25f7a337962d7d0bb1a0c57808 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Wed, 13 Nov 2024 14:46:59 +0700 Subject: get couries, mapping couries and service --- src/core/api/biteShip.js | 20 +- src/lib/checkout/api/ExpedisiList.js | 18 +- src/lib/checkout/api/getRatesCourier.js | 22 ++ src/lib/checkout/components/Checkout.jsx | 53 +++-- src/lib/checkout/components/SectionExpedition.tsx | 256 +++++++++++++++++++++- src/lib/checkout/stores/useAdress.js | 23 +- src/pages/api/biteship-service.js | 24 ++ 7 files changed, 363 insertions(+), 53 deletions(-) create mode 100644 src/lib/checkout/api/getRatesCourier.js create mode 100644 src/pages/api/biteship-service.js (limited to 'src') diff --git a/src/core/api/biteShip.js b/src/core/api/biteShip.js index 9e9e8567..f18421d8 100644 --- a/src/core/api/biteShip.js +++ b/src/core/api/biteShip.js @@ -2,23 +2,27 @@ import axios from 'axios'; const biteShipAPI = async (method, url, body = {}) => { try { - const key = process.env.NEXT_PUBLIC_BITE_SHIP_KEY; - let axiosParameter = { + const key = process.env.NEXT_PUBLIC_BITSEHIP_KEY; + const baseUrl = process.env.NEXT_PUBLIC_BITE_SHIP_HOST; + + const axiosParameter = { method, - url: process.env.NEXT_PUBLIC_BITE_SHIP_HOST + url, - headers: { Authorization: key, 'Content-Type': 'application/json' }, + url: baseUrl + url, + headers: { + Authorization: `Bearer ${key}`, // Tambahkan "Bearer " di depan key + 'Content-Type': 'application/json', + }, + data: body, // Tidak perlu JSON.stringify }; - if (Object.keys(body).length > 0) - axiosParameter.data = JSON.stringify(body); const data = await axios(axiosParameter); - return { success: true, data: data}; + return { success: true, data: data }; } catch (error) { console.log(error); return { success: false, - data : {} + data: {}, }; } }; diff --git a/src/lib/checkout/api/ExpedisiList.js b/src/lib/checkout/api/ExpedisiList.js index 110295b7..67ef93e2 100644 --- a/src/lib/checkout/api/ExpedisiList.js +++ b/src/lib/checkout/api/ExpedisiList.js @@ -1,23 +1,7 @@ import odooApi from '@/core/api/odooApi'; -import axios from 'axios'; -import biteShipAPI from '../../../core/api/biteShip'; - const ExpedisiList = async () => { const dataExpedisi = await odooApi('GET', '/api/v1/courier'); return dataExpedisi; }; -const GetRatesCourierBiteship = async ({ destination, items }) => { - const couriers = process.env.NEXT_PUBLIC_BITESHIP_CODE_COURIERS; - let body = { - destination, - couriers: couriers, - items - }; - - const featch = await biteShipAPI('POST', '/v1/rates/couriers', body); - - return featch; -}; - -export { GetRatesCourierBiteship, ExpedisiList} ; +export default ExpedisiList; diff --git a/src/lib/checkout/api/getRatesCourier.js b/src/lib/checkout/api/getRatesCourier.js new file mode 100644 index 00000000..8db02d50 --- /dev/null +++ b/src/lib/checkout/api/getRatesCourier.js @@ -0,0 +1,22 @@ +import axios from "axios"; +import biteShipAPI from "../../../core/api/biteShip"; + +const GetRatesCourierBiteship = async ({ destination, items }) => { + const couriers = process.env.NEXT_PUBLIC_BITESHIP_CODE_COURIERS; + let body = { + ...destination, + couriers: 'gojek, grab, deliveree, lalamove, jne, tiki, ninja, lion, rara, sicepat, jnt, pos, idexpress, rpx, wahana, jdl, pos, anteraja, sap, paxel, borzo', + items: items, + }; + + const response = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/biteship-service?method=POST&url=/v1/rates/couriers&body=` + JSON.stringify(body)); + + // const featch = await biteShipAPI('POST', '/v1/rates/couriers', body); + console.log('ini featch', response); + + + return response; +}; + + +export default GetRatesCourierBiteship \ No newline at end of file diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 6da27745..b4c311a9 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -1,4 +1,4 @@ -import { Button, Skeleton, Spinner } from '@chakra-ui/react'; +import { Skeleton, Spinner } from '@chakra-ui/react'; import { BanknotesIcon, ChevronLeftIcon, @@ -28,10 +28,12 @@ import getFileBase64 from '@/core/utils/getFileBase64'; import { gtagPurchase } from '@/core/utils/googleTag'; import whatsappUrl from '@/core/utils/whatsappUrl'; import addressesApi from '@/lib/address/api/addressesApi'; +import { MapPinIcon } from 'lucide-react'; import CartItem from '~/modules/cart/components/Item.tsx'; import ExpedisiList from '../api/ExpedisiList'; -import { findVoucher, getVoucher, getVoucherNew } from '../api/getVoucher'; -import { MapPinIcon } from 'lucide-react'; +import { getVoucher } from '../api/getVoucher'; +import { useAddress } from '../stores/useAdress'; +import SectionExpedition from './SectionExpedition'; const SELF_PICKUP_ID = 32; @@ -57,11 +59,15 @@ const Checkout = () => { }) ); - const [selectedAddress, setSelectedAddress] = useState({ - shipping: null, - invoicing: null, - }); - const [addresses, setAddresses] = useState(null); + const { + selectedAddress, + setSelectedAddress, + addresses, + setAddresses, + setAddressMaps, + setCoordinate, + setPostalCode, + } = useAddress(); useEffect(() => { if (!auth) return; @@ -91,10 +97,20 @@ const Checkout = () => { return addresses[0]; }; + let ship = matchAddress('shipping'); + setSelectedAddress({ shipping: matchAddress('shipping'), invoicing: matchAddress('invoicing'), }); + setPostalCode(ship?.zip); + if (ship?.addressMap) { + setAddressMaps(ship?.addressMap); + setCoordinate({ + destination_latitude: ship?.latitude, + destination_longitude: ship?.longtitude, + }); + } }, [addresses]); const [products, setProducts] = useState(null); @@ -1340,6 +1356,7 @@ const Checkout = () => { /> )} + {products && } ( {address.street}, {address?.city?.name}

- - {address.addressMap ? : } + + {address.addressMap ? ( + + ) : ( + + )}
)} - + ); const SectionValidation = ({ address }) => @@ -1647,11 +1674,9 @@ const SectionValidation = ({ address }) => ); const SectionExpedisiBiteship = ({ listExpedisi, setSelectedExpedisi }) => ( - <> - + <> ); - const SectionExpedisi = ({ address, listExpedisi, diff --git a/src/lib/checkout/components/SectionExpedition.tsx b/src/lib/checkout/components/SectionExpedition.tsx index d2dd5763..a6e05893 100644 --- a/src/lib/checkout/components/SectionExpedition.tsx +++ b/src/lib/checkout/components/SectionExpedition.tsx @@ -1,12 +1,248 @@ -import React from 'react'; -import { GetRatesCourierBiteship } from '../api/ExpedisiList'; +import React, { useEffect, useState } from 'react'; import { useQuery } from 'react-query'; +import GetRatesCourierBiteship from '../api/getRatesCourier'; +import { useAddress } from '../stores/useAdress'; +import axios, { AxiosResponse } from 'axios'; +import { useForm, Controller } from 'react-hook-form'; +import { AnimatePresence, motion } from 'framer-motion'; +import { Spinner } from '@chakra-ui/react'; -export default function SectionExpedition() { - let destination = {} - let items = {} - const fetchExpedition = async () => await GetRatesCourierBiteship({destination, items}); - const {data : coursers, isLoading} = useQuery('expedition-'+destination, fetchExpedition) - - return
SectionExpedition
; -} \ No newline at end of file +function mappingItems(products) { + return products?.map((item) => ({ + name: item.parent.name, + description: `${item.code} - ${item.name}`, + value: item.price.priceDiscount, + weight: item.weight, + quantity: item.quantity, + })); +} + +function mappingCourier(couriers) { + return couriers?.reduce((result, item) => { + const { courier_code, courier_service_code } = item; + + // Jika courier_code belum ada di result, buat objek baru untuknya + if (!result[courier_code]) { + result[courier_code] = { + courier_name: item.courier_name, + courier_code: courier_code, + service_type: { + [courier_service_code]: { + service_name: item.courier_service_name, + duration: item.duration, + shipment_duration: item.duration, + price: item.price, + service_type: item.service_type, + description: item.description, + }, + }, + }; + } else { + result[courier_code].service_type[courier_service_code] = { + service_name: item.courier_service_name, + duration: item.duration, + shipment_duration: item.duration, + price: item.price, + service_type: item.service_type, + description: item.description, + }; + } + + return result; + }, {}); +} + +interface CourierService { + courier_name: string; + courier_code: string; + service_type: { + [key: string]: { + service_name: string; + duration: number; + shipment_duration: number; + price: number; + service_type: string; + description: string; + }; + }; +} + +export default function SectionExpedition({ products }) { + const { addressMaps, coordinate, postalCode } = useAddress(); + const { control, handleSubmit } = useForm(); + const [selectedCourier, setSelectedCourier] = useState(''); + const [serviceOptions, setServiceOptions] = useState([]); + + let destination = {}; + let items = mappingItems(products); + if (addressMaps) { + destination = { + origin_latitude: -6.3031123, + origin_longitude: 106.7794934999, + ...coordinate, + }; + } else if (postalCode) { + destination = { + origin_postal_code: 12440, + destination_postal_code: postalCode, + }; + } + + const fetchExpedition = async () => { + let body = { + ...destination, + couriers: + 'gojek, grab, deliveree, lalamove, jne, tiki, ninja, lion, rara, sicepat, jnt, pos, idexpress, rpx, wahana, jdl, pos, anteraja, sap, paxel, borzo', + items: items, + }; + try { + const response = await axios.get(`/api/biteship-service`, { + params: { body: JSON.stringify(body) }, + }); + return response; + } catch (error) { + console.error('Failed to fetch expedition rates:', error); + } + }; + + // const fetchExpedition = async () => await GetRatesCourierBiteship({ destination, items }); + const { data, isLoading } = useQuery( + ['expedition', JSON.stringify(destination), JSON.stringify(items)], + fetchExpedition, + { + enabled: Boolean(Object.keys(destination).length) && items?.length > 0, + staleTime: Infinity, + cacheTime: Infinity, + } + ); + + const couriers: CourierService = mappingCourier(data?.data?.pricing); + + console.log('couriers', couriers); + + const onCourierChange = (e) => { + const courier = e.target.value; + console.log('courier', courier); + setSelectedCourier(courier); + // Menentukan layanan berdasarkan pengiriman yang dipilih + if (courier && couriers[courier]) { + setServiceOptions(Object.values(couriers[courier]?.service_type)); + } else { + setServiceOptions([]); + } + }; + + console.log( + 'serviceOptions', + couriers[selectedCourier]?.service_type, + selectedCourier + ); + const onSubmit = (data) => { + console.log(data); + }; + + return ( +
+ {/* Dropdown untuk memilih jenis pengiriman */} +
+
+
Pilih Ekspedisi:
+
+
+ + + + {isLoading && ( + + + + )} + +
+ {/* {checkoutValidation && ( + + *silahkan pilih expedisi + + )} */} +
+ {/* */} +
+ {/* {checkWeigth == true && ( +

+ Mohon maaf, pengiriman hanya tersedia untuk self pickup karena + terdapat barang yang belum diatur beratnya. Mohon atur berat barang + dengan menghubungi admin melalui{' '} + + tautan ini + +

+ )} */} +
+ + {selectedCourier && ( +
+
+
Tipe Layanan Ekspedisi:
+
+ +
+
+
+ )} +
+ ); +} diff --git a/src/lib/checkout/stores/useAdress.js b/src/lib/checkout/stores/useAdress.js index 1c17258d..5274ecfe 100644 --- a/src/lib/checkout/stores/useAdress.js +++ b/src/lib/checkout/stores/useAdress.js @@ -1,6 +1,21 @@ -import { create } from "zustand"; +import { create } from 'zustand'; export const useAddress = create((set) => ({ - address: {}, - setAddress: (address) => set({ address }), -})); \ No newline at end of file + selectedAddress: { + shipping: null, + invoicing: null, + }, + addresses: null, + addressMaps : null, + coordinate : { + destination_latitude : null, + destination_longitude : null + }, + postalCode : null, + setAddresses: (addresses) => set({ addresses }), + setSelectedAddress: (selectedAddress) => set({ selectedAddress }), + setCoordinate: (coordinate) => set({ coordinate }), + setPostalCode: (postalCode) => set({ postalCode }), + setAddressMaps: (addressMaps) => set({ addressMaps }), + +})); diff --git a/src/pages/api/biteship-service.js b/src/pages/api/biteship-service.js new file mode 100644 index 00000000..ed9e2a9f --- /dev/null +++ b/src/pages/api/biteship-service.js @@ -0,0 +1,24 @@ +import biteShipAPI from '../../core/api/biteShip'; + +export default async function handler(req, res) { + const { body } = req.query; + + const parsedBody = JSON.parse(body); + console.log(parsedBody); + + try { + let result = await biteShipAPI('POST', '/v1/rates/couriers', parsedBody); + console.log('ini result', result); + + if (result && result.data && result.data.data) { + res.status(200).json(result.data.data); + } else { + res + .status(500) + .json({ error: 'Unexpected response structure from Biteship API' }); + } + } catch (error) { + console.error('Error:', error); + res.status(400).json({ error: error.message }); + } +} -- cgit v1.2.3