summaryrefslogtreecommitdiff
path: root/src/lib/checkout
diff options
context:
space:
mode:
authortrisusilo48 <tri.susilo@altama.co.id>2024-11-26 09:46:07 +0700
committertrisusilo48 <tri.susilo@altama.co.id>2024-11-26 09:46:07 +0700
commit821d218ff687a585c99937948989408541b596e4 (patch)
tree6254c5088a05a091427dca495b7a8b93601164a0 /src/lib/checkout
parentf7dad0695d83a4e59b9423d6e7aedb554f716b52 (diff)
filter biteship courier sesuikan dengan courier dari odoo
Diffstat (limited to 'src/lib/checkout')
-rw-r--r--src/lib/checkout/components/Checkout.jsx185
-rw-r--r--src/lib/checkout/components/SectionExpedition.jsx118
-rw-r--r--src/lib/checkout/stores/stateCheckout.js12
-rw-r--r--src/lib/checkout/utils/functionCheckouit.js79
4 files changed, 250 insertions, 144 deletions
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index 92a94834..38e11038 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -35,6 +35,7 @@ import { getVoucher } from '../api/getVoucher';
import { useAddress } from '../stores/useAdress';
import SectionExpedition from './SectionExpedition';
import { useCheckout } from '../stores/stateCheckout';
+import { formatShipmentRange, getToDate } from '../utils/functionCheckouit';
const SELF_PICKUP_ID = 32;
@@ -128,15 +129,14 @@ const Checkout = () => {
const [totalWeight, setTotalWeight] = useState(0);
const [priceCheck, setPriceCheck] = useState(false);
- const [listExpedisi, setExpedisi] = useState([]);
const [listserviceExpedisi, setListServiceExpedisi] = useState([]);
const [selectedExpedisi, setSelectedExpedisi] = useState(0);
const [selectedCarrierId, setselectedCarrierId] = useState(0);
const [selectedCarrier, setselectedCarrier] = useState(0);
const [selectedServiceType, setSelectedServiceType] = useState(null);
const [selectedExpedisiService, setselectedExpedisiService] = useState(null);
- const [etd, setEtd] = useState(null);
- const [etdFix, setEtdFix] = useState(null);
+ // const [etd, setEtd] = useState(null);
+ // const [etdFix, setEtdFix] = useState(null);
const [bottomPopup, SetBottomPopup] = useState(null);
const [bottomPopupTnC, SetBottomPopupTnC] = useState(null);
const [itemTnC, setItemTnC] = useState(null);
@@ -151,7 +151,7 @@ const Checkout = () => {
const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false);
const [grandTotal, setGrandTotal] = useState(0);
- const {checkWeigth, setCheckWeight, hasFlashSale, setHasFlashSale, checkoutValidation, setCheckoutValidation, biayaKirim, setBiayaKirim, products, setProducts} = useCheckout();
+ const {checkWeigth, setCheckWeight, hasFlashSale, setHasFlashSale, checkoutValidation, setCheckoutValidation, biayaKirim, products, setProducts, etd, unit, selectedCourier, selectedService, listExpedisi, setExpedisi} = useCheckout();
const expedisiValidation = useRef(null);
@@ -290,6 +290,7 @@ const Checkout = () => {
window.onpopstate = handlePopState;
+
return () => {
window.onpopstate = null;
};
@@ -312,70 +313,70 @@ const Checkout = () => {
setHasFlashSale(hasFlashSale);
}, [cartCheckout]);
- useEffect(() => {
- setCheckoutValidation(false);
- const loadServiceRajaOngkir = async () => {
- setLoadingRajaOngkir(true);
- const body = {
- origin: 2127,
- destination: selectedAddress.shipping.rajaongkirCityId,
- weight: totalWeight,
- courier: selectedCarrier,
- originType: 'subdistrict',
- destinationType: 'subdistrict',
- };
- setBiayaKirim(0);
- const dataService = await axios(
- '/api/rajaongkir-service?body=' + JSON.stringify(body)
- );
- setLoadingRajaOngkir(false);
- setListServiceExpedisi(dataService.data[0].costs);
- if (dataService.data[0].costs[0]) {
- setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value);
- setselectedExpedisiService(
- dataService.data[0].costs[0]?.description +
- '-' +
- dataService.data[0].costs[0]?.service
- );
- setEtd(dataService.data[0].costs[0]?.cost[0].etd);
- toast.success('Harap pilih tipe layanan pengiriman');
- } else {
- toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.');
- }
- };
- if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) {
- loadServiceRajaOngkir();
- } else {
- setListServiceExpedisi();
- setBiayaKirim(0);
- setselectedExpedisiService();
- setEtd();
- }
- }, [selectedCarrier, selectedAddress, totalWeight]);
-
- useEffect(() => {
- if (selectedServiceType) {
- let serviceType = selectedServiceType.split(',');
- setBiayaKirim(serviceType[0]);
- setselectedExpedisiService(serviceType[1]);
- setEtd(serviceType[2]);
- }
- }, [selectedServiceType]);
-
- useEffect(() => {
- if (etd) setEtdFix(calculateEstimatedArrival(etd));
- }, [etd]);
-
- useEffect(() => {
- if (selectedExpedisi) {
- let serviceType = selectedExpedisi.split(',');
- if (serviceType[0] === 0) return;
-
- setselectedCarrier(serviceType[0]);
- setselectedCarrierId(serviceType[1]);
- setListServiceExpedisi([]);
- }
- }, [selectedExpedisi]);
+ // useEffect(() => {
+ // setCheckoutValidation(false);
+ // const loadServiceRajaOngkir = async () => {
+ // setLoadingRajaOngkir(true);
+ // const body = {
+ // origin: 2127,
+ // destination: selectedAddress.shipping.rajaongkirCityId,
+ // weight: totalWeight,
+ // courier: selectedCarrier,
+ // originType: 'subdistrict',
+ // destinationType: 'subdistrict',
+ // };
+ // setBiayaKirim(0);
+ // const dataService = await axios(
+ // '/api/rajaongkir-service?body=' + JSON.stringify(body)
+ // );
+ // setLoadingRajaOngkir(false);
+ // setListServiceExpedisi(dataService.data[0].costs);
+ // if (dataService.data[0].costs[0]) {
+ // setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value);
+ // setselectedExpedisiService(
+ // dataService.data[0].costs[0]?.description +
+ // '-' +
+ // dataService.data[0].costs[0]?.service
+ // );
+ // setEtd(dataService.data[0].costs[0]?.cost[0].etd);
+ // toast.success('Harap pilih tipe layanan pengiriman');
+ // } else {
+ // toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.');
+ // }
+ // };
+ // if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) {
+ // loadServiceRajaOngkir();
+ // } else {
+ // setListServiceExpedisi();
+ // setBiayaKirim(0);
+ // setselectedExpedisiService();
+ // setEtd();
+ // }
+ // }, [selectedCarrier, selectedAddress, totalWeight]);
+
+ // useEffect(() => {
+ // if (selectedServiceType) {
+ // let serviceType = selectedServiceType.split(',');
+ // setBiayaKirim(serviceType[0]);
+ // setselectedExpedisiService(serviceType[1]);
+ // setEtd(serviceType[2]);
+ // }
+ // }, [selectedServiceType]);
+
+ // useEffect(() => {
+ // if (etd) setEtdFix(calculateEstimatedArrival(etd));
+ // }, [etd]);
+
+ // useEffect(() => {
+ // if (selectedExpedisi) {
+ // let serviceType = selectedExpedisi.split(',');
+ // if (serviceType[0] === 0) return;
+
+ // setselectedCarrier(serviceType[0]);
+ // setselectedCarrierId(serviceType[1]);
+ // setListServiceExpedisi([]);
+ // }
+ // }, [selectedExpedisi]);
const poNumber = useRef(null);
const poFile = useRef(null);
@@ -403,7 +404,7 @@ const Checkout = () => {
});
return;
}
- if (selectedExpedisi === 0) {
+ if (selectedCourier === 0 || !selectedCourier) {
setCheckoutValidation(true);
if (expedisiValidation.current) {
const position = expedisiValidation.current.getBoundingClientRect();
@@ -414,7 +415,11 @@ const Checkout = () => {
}
return;
}
- if (selectedCarrier != 1 && biayaKirim == 0) {
+ if(!selectedService){
+ toast.error('Harap pilih tipe layanan pengiriman');
+ return;
+ }
+ if (selectedCourier != 1 && biayaKirim == 0) {
toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.');
return;
}
@@ -432,15 +437,14 @@ const Checkout = () => {
user_id: auth.id,
order_line: JSON.stringify(productOrder),
delivery_amount: biayaKirim,
- carrier_id: selectedCarrierId,
- estimated_arrival_days: splitDuration(etd),
- delivery_service_type: selectedExpedisiService,
+ carrier_id: selectedCourier,
+ estimated_arrival_days: getToDate(etd, unit),
+ delivery_service_type: selectedService?.service_type,
flash_sale: hasFlashSale, // dibuat negasi untuk ngetest kebalikan nilai false
voucher: activeVoucher,
voucher_shipping: activeVoucherShipping,
type: 'sale_order',
};
-
if (query) {
data.source = 'buy';
}
@@ -487,24 +491,6 @@ const Checkout = () => {
)}`;
}
}
-
- /* const midtrans = async () => {
- for (const product of products) deleteItemCart({ productId: product.id });
- if (grandTotal > 0) {
- const payment = await axios.post(
- `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/midtrans-payment?transactionId=${isCheckouted.id}`
- );
- setIsLoading(false);
- window.location.href = payment.data.redirectUrl;
- } else {
- window.location.href = `${
- process.env.NEXT_PUBLIC_SELF_HOST
- }/shop/checkout/success?order_id=${isCheckouted.name.replace(
- /\//g,
- '-'
- )}`;
- }
- };*/
};
const handlingActivateCode = async () => {
@@ -569,9 +555,6 @@ const Checkout = () => {
cartCheckout?.discountVoucher +
(cartCheckout?.discountVoucherShipping || 0);
-
- console.log('etd', etd, calculateEstimatedArrival(etd), splitDuration(etd));
-
return (
<>
<BottomPopup
@@ -1068,7 +1051,7 @@ const Checkout = () => {
)}
<Divider />
<SectionValidation address={selectedAddress.invoicing} />
- <SectionExpedisi
+ {/* <SectionExpedisi
address={selectedAddress.shipping}
listExpedisi={listExpedisi}
setSelectedExpedisi={setSelectedExpedisi}
@@ -1081,7 +1064,7 @@ const Checkout = () => {
<SectionListService
listserviceExpedisi={listserviceExpedisi}
setSelectedServiceType={setSelectedServiceType}
- />
+ /> */}
<div className='p-4 flex flex-col gap-y-4'>
{!!products &&
@@ -1168,7 +1151,7 @@ const Checkout = () => {
</div>
<div className='flex gap-x-2 justify-between'>
<div className='text-gray_r-11'>
- Biaya Kirim <p className='text-xs mt-1'>{etdFix}</p>
+ Biaya Kirim <p className='text-xs mt-1'>{formatShipmentRange(etd, unit)}</p>
</div>
<div>
{currencyFormat(
@@ -1367,7 +1350,7 @@ const Checkout = () => {
{products && <SectionExpedition products={products} />}
<Divider />
<SectionValidation address={selectedAddress.invoicing} />
- <SectionExpedisi
+ {/* <SectionExpedisi
address={selectedAddress.shipping}
listExpedisi={listExpedisi}
setSelectedExpedisi={setSelectedExpedisi}
@@ -1380,7 +1363,7 @@ const Checkout = () => {
<SectionListService
listserviceExpedisi={listserviceExpedisi}
setSelectedServiceType={setSelectedServiceType}
- />
+ /> */}
<div className='p-4'>
<div className='font-medium mb-6'>Detail Pesanan</div>
@@ -1474,7 +1457,7 @@ const Checkout = () => {
<div className='flex gap-x-2 justify-between'>
<div className='text-gray_r-11'>
Biaya Kirim
- <p className='text-xs mt-1'>{etdFix}</p>
+ <p className='text-xs mt-1'>{formatShipmentRange(etd, unit)}</p>
</div>
<div>
{currencyFormat(
diff --git a/src/lib/checkout/components/SectionExpedition.jsx b/src/lib/checkout/components/SectionExpedition.jsx
index 27224e5b..be40a577 100644
--- a/src/lib/checkout/components/SectionExpedition.jsx
+++ b/src/lib/checkout/components/SectionExpedition.jsx
@@ -1,4 +1,4 @@
-import { Spinner } from '@chakra-ui/react';
+import { Skeleton, Spinner } from '@chakra-ui/react';
import axios from 'axios';
import { AnimatePresence, motion } from 'framer-motion';
import React, { useState } from 'react';
@@ -14,15 +14,25 @@ function mappingItems(products) {
name: item.parent.name,
description: `${item.code} - ${item.name}`,
value: item.price.priceDiscount,
- weight: item.weight * 1000 * item.quantity,
+ weight: item.weight * 1000,
quantity: item.quantity,
canInstant: item.availableQuantity > item.quantity ? true : false,
}));
}
-function mappingCourier(couriers, notIncludeInstant = false) {
+function mappingCourier(couriersOdoo, couriers, notIncludeInstant = false) {
+ const validCourierMap = couriersOdoo.reduce((acc, courier) => {
+ acc[courier.label.toLowerCase()] = courier.carrierId;
+ return acc;
+ }, {});
+
return couriers?.reduce((result, item) => {
- const { courier_code, courier_service_code } = item;
+ const { courier_name, courier_code, courier_service_code } = item;
+ if (!validCourierMap[courier_name.toLowerCase()]) {
+ return result; // Jika tidak ada, lewati item ini
+ }
+
+
if (
notIncludeInstant &&
['hours'].includes(item.shipment_duration_unit.toLowerCase())
@@ -30,16 +40,20 @@ function mappingCourier(couriers, notIncludeInstant = false) {
return result;
}
+ const carrierId = validCourierMap[courier_name];
+
// 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,
+ courier_id_odoo : carrierId,
service_type: {
[courier_service_code]: {
service_name: item.courier_service_name,
duration: item.duration,
- shipment_duration: item.duration,
+ shipment_range: item.shipment_duration_range,
+ shipment_unit: item.shipment_duration_unit,
price: item.price,
service_type: item.service_type,
description: item.description,
@@ -50,6 +64,8 @@ function mappingCourier(couriers, notIncludeInstant = false) {
result[courier_code].service_type[courier_service_code] = {
service_name: item.courier_service_name,
duration: item.duration,
+ shipment_range: item.shipment_duration_range,
+ shipment_unit: item.shipment_duration_unit,
shipment_duration: item.duration,
price: item.price,
service_type: item.service_type,
@@ -92,18 +108,27 @@ function hasCanInstantFalse(items) {
export default function SectionExpedition({ products }) {
const { addressMaps, coordinate, postalCode } = useAddress();
const { control, handleSubmit } = useForm();
- const [selectedCourier, setSelectedCourier] = useState('');
const [serviceOptions, setServiceOptions] = useState([]);
- const [selectedService, setSelectedService] = useState(null);
const [isOpen, setIsOpen] = useState(false);
+ const [onFocusSelectedCourier, setOnFocuseSelectedCourier] = useState(false);
- const { checkWeigth, checkoutValidation } = useCheckout();
+ const {
+ checkWeigth,
+ checkoutValidation,
+ setBiayaKirim,
+ setUnit,
+ setEtd,
+ selectedCourier,
+ setSelectedCourier,
+ selectedService,
+ setSelectedService,
+ listExpedisi,
+ } = useCheckout();
let destination = {};
let items = mappingItems(products);
let notIncludeInstant = hasCanInstantFalse(items);
- console.log('instanCourier', items);
if (addressMaps) {
destination = {
origin_latitude: -6.3031123,
@@ -112,7 +137,7 @@ export default function SectionExpedition({ products }) {
};
} else if (postalCode) {
destination = {
- origin_postal_code: 12440,
+ origin_postal_code: 14440,
destination_postal_code: postalCode,
};
}
@@ -141,23 +166,26 @@ export default function SectionExpedition({ products }) {
enabled:
Boolean(Object.keys(destination).length) &&
items?.length > 0 &&
- !checkWeigth,
+ !checkWeigth &&
+ onFocusSelectedCourier,
staleTime: Infinity,
cacheTime: Infinity,
}
);
- console.log('data', data);
+ const couriers =
+ mappingCourier(listExpedisi, data?.data?.pricing, notIncludeInstant) ||
+ null;
- const couriers = mappingCourier(data?.data?.pricing, true) || null;
+ console.log('ini scourier', data?.data?.pricing)
const onCourierChange = (e) => {
setIsOpen(false);
const courier = e.target.value;
setSelectedService(null);
setSelectedCourier(courier);
- console.log('courier', courier);
- // Menentukan layanan berdasarkan pengiriman yang dipilih
+ // setSelectedCourierId(Object.values(couriers[courier]?.courier_id_odoo);
+ setBiayaKirim(0);
if (courier && courier !== '0' && courier !== '32' && couriers[courier]) {
setServiceOptions(Object.values(couriers[courier]?.service_type));
} else {
@@ -165,12 +193,15 @@ export default function SectionExpedition({ products }) {
}
};
- const onSubmit = (data) => {
+ const onSubmit = (data) => {1
console.log(data);
};
const handleSelect = (service) => {
setSelectedService(service);
+ setBiayaKirim(service?.price);
+ setEtd(service?.shipment_range);
+ setUnit(service?.shipment_unit);
setIsOpen(false);
};
@@ -184,37 +215,38 @@ export default function SectionExpedition({ products }) {
<select
className={`form-input `}
onChange={onCourierChange}
+ onMouseDown={() => setOnFocuseSelectedCourier(true)}
required
>
- <option value='0'>Pilih Pengiriman</option>
- <option value='32'>SELF PICKUP</option>
- {couriers &&
- Object.values(couriers)?.map((expedisi) => (
- <option
- value={expedisi.courier_code}
- key={expedisi.courier_name}
- >
- {' '}
- {expedisi.courier_name}
+ {!isLoading ? (
+ <>
+ <option value='0'>Pilih Pengiriman</option>
+ <option value='32'>SELF PICKUP</option>
+ {couriers &&
+ Object.values(couriers)?.map((expedisi) => (
+ <option
+ value={expedisi.courier_code}
+ key={expedisi.courier_name}
+ >
+ {' '}
+ {expedisi.courier_name}
+ </option>
+ ))}
+ </>
+ ) : (
+ <>
+ <option disabled className='skeleton-option'>
+ <Skeleton height={40} containerClassName='w-full' />
</option>
- ))}
- </select>
-
- <AnimatePresence>
- {isLoading && (
- <motion.div
- initial={{ opacity: 0, width: 0 }}
- animate={{ opacity: 1, width: '28px' }}
- exit={{ opacity: 0, width: 0 }}
- transition={{
- duration: 0.25,
- }}
- className='overflow-hidden'
- >
- <Spinner thickness='3px' speed='0.5s' color='red.500' />
- </motion.div>
+ <option disabled className='skeleton-option'>
+ <Skeleton height={40} containerClassName='w-full' />
+ </option>
+ <option disabled className='skeleton-option'>
+ <Skeleton height={40} containerClassName='w-full' />
+ </option>
+ </>
)}
- </AnimatePresence>
+ </select>
</div>
{checkoutValidation && (
<span className='text-sm text-red-500'>
diff --git a/src/lib/checkout/stores/stateCheckout.js b/src/lib/checkout/stores/stateCheckout.js
index 97b0c64e..4fefbbed 100644
--- a/src/lib/checkout/stores/stateCheckout.js
+++ b/src/lib/checkout/stores/stateCheckout.js
@@ -7,10 +7,22 @@ export const useCheckout = create((set) => ({
checkoutValidation : false,
biayaKirim : 0,
etd : null,
+ unit : null,
+ selectedCourier : null,
+ selectedCourierId : null,
+ selectedService : null,
+ listExpedisi : [],
setCheckWeight : (checkWeigth) => set({ checkWeigth }),
setHasFlashSale : (hasFlashSale) => set({ hasFlashSale }),
setCheckoutValidation : (checkoutValidation) => set({ checkoutValidation }),
setBiayaKirim : (biayaKirim) => set({ biayaKirim }),
setProducts : (products) => set({ products }),
+ setEtd : (etd) => set({ etd }),
+ setUnit : (unit) => set({ unit }),
+ setSelectedCourier : (selectedCourier) => set({ selectedCourier }),
+ setSelectedService : (selectedService) => set({ selectedService }),
+ setSelectedCourierId : (selectedCourierId) => set({ selectedCourierId }),
+ setExpedisi : (listExpedisi) => set({ listExpedisi })
+
})) \ No newline at end of file
diff --git a/src/lib/checkout/utils/functionCheckouit.js b/src/lib/checkout/utils/functionCheckouit.js
new file mode 100644
index 00000000..b299f289
--- /dev/null
+++ b/src/lib/checkout/utils/functionCheckouit.js
@@ -0,0 +1,79 @@
+export function formatShipmentRange(
+ shipmentDurationRange,
+ shipmentDurationUnit
+) {
+ if (!shipmentDurationRange || !shipmentDurationUnit) {
+ return '';
+ }
+ let minRange, maxRange;
+
+ // Cek apakah durasi berupa range atau angka tunggal
+ if (shipmentDurationRange.includes('-')) {
+ [minRange, maxRange] = shipmentDurationRange.split(' - ').map(Number);
+ } else {
+ minRange = maxRange = Number(shipmentDurationRange); // Jika angka tunggal
+ }
+
+ const start = new Date(); // Tanggal saat ini
+
+ let minDate, maxDate;
+
+ // Hitung estimasi berdasarkan unit waktu
+ if (shipmentDurationUnit === 'days' || shipmentDurationUnit === 'day') {
+ minDate = new Date(start);
+ minDate.setDate(start.getDate() + (minRange + 3));
+
+ maxDate = new Date(start);
+ maxDate.setDate(start.getDate() + (maxRange + 3));
+ } else if (shipmentDurationUnit === 'hours') {
+ minDate = new Date(start.getTime() + (minRange + 3) * 60 * 60 * 1000);
+ maxDate = new Date(start.getTime() + (maxRange + 3) * 60 * 60 * 1000);
+ } else {
+ throw new Error("Unsupported unit. Please use 'days' or 'hours'.");
+ }
+
+ console.log('min max', minDate, maxDate);
+
+ const minDateStr = formatDate(minDate);
+ const maxDateStr = formatDate(maxDate);
+ if (minDateStr === maxDateStr) {
+ return `Estimasi tiba ${minDateStr}`;
+ }
+ return `Estimasi tiba ${minDateStr} - ${maxDateStr}`;
+}
+
+export function getToDate(shipmentDurationRange, shipmentDurationUnit) {
+ if (!shipmentDurationRange || !shipmentDurationUnit) {
+ return '';
+ }
+ const start = new Date(); // Tanggal saat ini
+
+ let maxRange;
+
+ // Cek apakah durasi berupa range atau angka tunggal
+ if (shipmentDurationRange.includes('-')) {
+ [, maxRange] = shipmentDurationRange.split(' - ').map(Number);
+ } else {
+ maxRange = Number(shipmentDurationRange); // Jika angka tunggal
+ }
+
+ let maxDate;
+
+ // Hitung estimasi berdasarkan unit waktu
+ if (shipmentDurationUnit === 'days' || shipmentDurationUnit === 'day') {
+ maxDate = new Date(start);
+ maxDate.setDate(start.getDate() + (maxRange + 3));
+ } else if (shipmentDurationUnit === 'hours') {
+ maxDate = new Date(start.getTime() + (maxRange + 3) * 60 * 60 * 1000);
+ } else {
+ throw new Error("Unsupported unit. Please use 'days' or 'hours'.");
+ }
+
+ return formatDate(maxDate);
+}
+
+function formatDate(date) {
+ const day = date.getDate();
+ const month = date.toLocaleString('default', { month: 'short' });
+ return `${day} ${month}`;
+}