summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-migrate/modules/cart/components/Item.tsx4
-rw-r--r--src-migrate/modules/cart/components/ItemSelect.tsx33
-rw-r--r--src-migrate/modules/promo/components/Hero.tsx15
-rw-r--r--src-migrate/pages/shop/cart/index.tsx108
-rw-r--r--src/core/components/elements/Navbar/NavbarDesktop.jsx4
-rw-r--r--src/lib/home/components/CategoryDynamic.jsx115
6 files changed, 140 insertions, 139 deletions
diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx
index 74180fc9..47893498 100644
--- a/src-migrate/modules/cart/components/Item.tsx
+++ b/src-migrate/modules/cart/components/Item.tsx
@@ -20,7 +20,7 @@ type Props = {
pilihSemuaCart?: boolean
}
-const CartItem = ({ item, editable = true, pilihSemuaCart }: Props) => {
+const CartItem = ({ item, editable = true,}: Props) => {
return (
<div className={style.wrapper}>
@@ -46,7 +46,7 @@ const CartItem = ({ item, editable = true, pilihSemuaCart }: Props) => {
<div className={style.mainProdWrapper}>
{editable && (
- <CartItemSelect item={item} itemSelected={pilihSemuaCart} />
+ <CartItemSelect item={item} />
)}
<div className='w-4' />
diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx
index 6b6b8f2b..b904a1de 100644
--- a/src-migrate/modules/cart/components/ItemSelect.tsx
+++ b/src-migrate/modules/cart/components/ItemSelect.tsx
@@ -1,5 +1,5 @@
import { Checkbox, Spinner } from '@chakra-ui/react'
-import React, { useState, useEffect } from 'react'
+import React, { useState } from 'react'
import { getAuth } from '~/libs/auth'
import { CartItem } from '~/types/cart'
@@ -9,17 +9,15 @@ import { useCartStore } from '../stores/useCartStore'
type Props = {
item: CartItem
- itemSelected?: boolean
}
-const CartItemSelect = ({ item, itemSelected }: Props) => {
+const CartItemSelect = ({ item }: Props) => {
const auth = getAuth()
const { loadCart } = useCartStore()
const [isLoad, setIsLoad] = useState<boolean>(false)
- const [isChecked, setIsChecked] = useState<boolean>(itemSelected ?? true)
- const handleChange = async (isChecked: boolean) => {
+ const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (typeof auth !== 'object') return
setIsLoad(true)
@@ -28,40 +26,29 @@ const CartItemSelect = ({ item, itemSelected }: Props) => {
type: item.cart_type,
id: item.id,
qty: item.quantity,
- selected: isChecked,
+ selected: e.target.checked
})
await loadCart(auth.id)
setIsLoad(false)
}
- useEffect(() => {
- if (typeof itemSelected === 'boolean') {
- setIsChecked(itemSelected)
- handleChange(itemSelected)
- }
- }, [itemSelected])
-
- const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- const { checked } = e.target
- setIsChecked(checked)
- handleChange(checked)
- }
-
return (
<div className='w-6 my-auto'>
- {isLoad && <Spinner className='my-auto' size='sm' />}
+ {isLoad && (
+ <Spinner className='my-auto' size='sm' />
+ )}
{!isLoad && (
<Checkbox
borderColor='gray.600'
colorScheme='red'
size='lg'
- isChecked={isChecked}
- onChange={handleCheckboxChange}
+ isChecked={item.selected}
+ onChange={handleChange}
/>
)}
</div>
)
}
-export default CartItemSelect
+export default CartItemSelect \ No newline at end of file
diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx
index 801136e9..110052ba 100644
--- a/src-migrate/modules/promo/components/Hero.tsx
+++ b/src-migrate/modules/promo/components/Hero.tsx
@@ -13,8 +13,8 @@ import DesktopView from '@/core/components/views/DesktopView';
import {bannerApi} from '../../../../src/api/bannerApi'
interface IPromotionProgram {
- headline_banner: string;
- description_banner: string;
+ headlineBanner: string;
+ descriptionBanner: string;
image: string ;
name: string;
}
@@ -43,7 +43,7 @@ const swiperBannerMob = {
};
const Hero = () => {
- const heroBanner = useQuery('heroBannerSecondary', bannerApi({ type: 'banner-semua-promo' }))
+ const heroBanner = useQuery('allPromo', bannerApi({ type: 'banner-semua-promo' }));
const banners: IPromotionProgram[] = useMemo(
() => heroBanner?.data || [],
@@ -55,7 +55,8 @@ const Hero = () => {
pagination: { dynamicBullets: false, clickable: true },
};
-
+ console.log("banner",banners)
+ // console.log("headlineBanner",banners[0].headlineBanner)
return (
<>
<DesktopView>
@@ -64,9 +65,9 @@ const Hero = () => {
{banners.map((banner, index) => (
<SwiperSlide key={index} className='flex flex-row'>
<div className={style['desc-section']}>
- <div className={style['title']}>{banner.headline_banner? banner.headline_banner : "Pasti Hemat & Untung Selama Belanja di Indoteknik.com!"}</div>
+ <div className={style['title']}>{banner.headlineBanner? banner.headlineBanner : "Pasti Hemat & Untung Selama Belanja di Indoteknik.com!"}</div>
<div className='h-4' />
- <div className={style['subtitle']}>{banner.description_banner? banner.description_banner : "Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!"}</div>
+ <div className={style['subtitle']}>{banner.descriptionBanner? banner.descriptionBanner : "Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!"}</div>
</div>
<div className={style['banner-section']}>
<Image
@@ -74,7 +75,7 @@ const Hero = () => {
alt={banner.name}
width={666}
height={450}
- quality={100}
+ quality={90}
className='w-full h-full object-fit object-center rounded-2xl' />
</div>
</SwiperSlide>
diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx
index 2ecf1c03..0eb9c554 100644
--- a/src-migrate/pages/shop/cart/index.tsx
+++ b/src-migrate/pages/shop/cart/index.tsx
@@ -2,29 +2,30 @@ import style from './cart.module.css';
import React, { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
-import { Button, Checkbox, Toast, Tooltip } from '@chakra-ui/react';
+import { Button, Checkbox, Tooltip } from '@chakra-ui/react';
import { toast } from 'react-hot-toast';
import { useRouter } from 'next/router';
import { getAuth } from '~/libs/auth';
import { useCartStore } from '~/modules/cart/stores/useCartStore';
-import CartItem from '~/modules/cart/components/Item';
+import CartItemModule from '~/modules/cart/components/Item';
import CartSummary from '~/modules/cart/components/Summary';
import clsxm from '~/libs/clsxm';
import useDevice from '@/core/hooks/useDevice';
import CartSummaryMobile from '~/modules/cart/components/CartSummaryMobile';
import Image from '~/components/ui/image';
+import { CartItem } from '~/types/cart'
+import { upsertUserCart } from '~/services/cart'
const CartPage = () => {
const router = useRouter();
const auth = getAuth();
- const [isStepApproval, setIsStepApproval] = React.useState(false);
- const [isSelectedAll, setIsSelectedAll] = useState<boolean>(false);
- const [isButtonChek, setIsButtonChek] = useState<boolean>(false);
- const [buttonSelectNow, setButtonSelectNow] = useState<boolean>(true);
+ const [isStepApproval, setIsStepApproval] = useState(false);
+ const [isSelectedAll, setIsSelectedAll] = useState(false);
+ const [isButtonChek, setIsButtonChek] = useState(false);
+ const [buttonSelectNow, setButtonSelectNow] = useState(true);
const { loadCart, cart, summary } = useCartStore();
-
const useDivvice = useDevice();
useEffect(() => {
@@ -32,78 +33,85 @@ const CartPage = () => {
loadCart(auth.id);
setIsStepApproval(auth?.feature?.soApproval);
}
- }, [auth, loadCart, cart, isButtonChek, ]);
-
-
+ }, [auth, loadCart, cart, isButtonChek]);
+
const hasSelectedPromo = useMemo(() => {
if (!cart) return false;
- for (const item of cart.products) {
- if (item.cart_type === 'promotion' && item.selected) return true;
- }
- return false;
+ return cart.products.some(item => item.cart_type === 'promotion' && item.selected);
}, [cart]);
const hasSelected = useMemo(() => {
if (!cart) return false;
- for (const item of cart.products) {
- if (item.selected) return true;
- }
- return false;
+ return cart.products.some(item => item.selected);
}, [cart]);
const hasSelectNoPrice = useMemo(() => {
if (!cart) return false;
- for (const item of cart.products) {
- if (item.selected && item.price.price_discount == 0) return true;
- }
- return false;
+ return cart.products.some(item => item.selected && item.price.price_discount === 0);
}, [cart]);
-
- const handleCheckout = (()=>{
- router.push('/shop/checkout');
- })
- const handleQuotation = (()=>{
- if(hasSelectedPromo || !hasSelected){
+ const hasSelectedAll = useMemo(() => {
+ if (!cart || !Array.isArray(cart.products)) return false;
+ return cart.products.every(item => item.selected);
+ }, [cart]);
+
+ const handleCheckout = () => {
+ router.push('/shop/checkout');
+ }
+
+ const handleQuotation = () => {
+ if (hasSelectedPromo || !hasSelected) {
toast.error('Maaf, Barang promo tidak dapat dibuat quotation');
- }else{
+ } else {
router.push('/shop/quotation');
}
- })
+ }
+
+ const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
+ if (typeof auth !== 'object' || !cart) return;
+
+ const newSelected = e.target.checked;
+ setIsSelectedAll(newSelected);
- const handleChange = (()=>{
- setButtonSelectNow(!buttonSelectNow)
- setIsSelectedAll(!isSelectedAll)
- setIsButtonChek(!isButtonChek)
- })
+ for (const item of cart.products) {
+ await upsertUserCart({
+ userId: auth.id,
+ type: item.cart_type,
+ id: item.id,
+ qty: item.quantity,
+ selected: newSelected
+ });
+ }
+ await loadCart(auth.id);
+ }
return (
<>
<div className={style['title']}>Keranjang Belanja</div>
<div className='h-2' />
- <div className='flex items-center object-center mt-2'>
- <Checkbox
- borderColor='gray.600'
- colorScheme='red'
- size='lg'
- isChecked={isButtonChek}
- onChange={handleChange}
- /> <p className='p-2 text-caption-2'>
- {buttonSelectNow? "Select all" : "Unchek all" }
- </p>
- </div>
+ <div className='flex items-center object-center mt-2'>
+ <Checkbox
+ borderColor='gray.600'
+ colorScheme='red'
+ size='lg'
+ isChecked={hasSelectedAll}
+ onChange={handleChange}
+ />
+ <p className='p-2 text-caption-2'>
+ {hasSelectedAll ? "Unchek all" : "Select all"}
+ </p>
+ </div>
<div className={style['content']}>
<div className={style['item-wrapper']}>
<div className={style['item-skeleton']}>
- {!cart && <CartItem.Skeleton count={5} height='120px' />}
+ {!cart && <CartItemModule.Skeleton count={5} height='120px' />}
</div>
<div className={style['items']}>
{cart?.products.map((item) => (
- <CartItem key={item.id} item={item} pilihSemuaCart={isSelectedAll} />
+ <CartItemModule key={item.id} item={item} />
))}
-
{cart?.products?.length === 0 && (
<div className='flex flex-col items-center'>
@@ -145,7 +153,7 @@ const CartPage = () => {
<CartSummary {...summary} isLoaded={!!cart} />
)}
- <div className={isStepApproval ? style['summary-buttons-step-approval'] : style['summary-buttons'] }>
+ <div className={isStepApproval ? style['summary-buttons-step-approval'] : style['summary-buttons']}>
<Tooltip
label={
hasSelectedPromo &&
diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx
index f157297e..c6e80e87 100644
--- a/src/core/components/elements/Navbar/NavbarDesktop.jsx
+++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx
@@ -213,7 +213,7 @@ const NavbarDesktop = () => {
rel="noreferrer"
>
<p className="absolute inset-0 flex justify-center items-center group-hover:scale-105 group-hover:text-red-500 transition-transform duration-200 z-10">Semua Promo</p>
- <div className='w-full h-full flex justify-end items-start'>
+ {/* <div className='w-full h-full flex justify-end items-start'>
<Image
src='/images/ICON PROMO DISKON.svg'
alt='promo'
@@ -222,7 +222,7 @@ const NavbarDesktop = () => {
quality={100}
className={`inline-block z-20`}
/>
- </div>
+ </div> */}
</Link>
diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx
index 6ab03ec3..f2d1a16f 100644
--- a/src/lib/home/components/CategoryDynamic.jsx
+++ b/src/lib/home/components/CategoryDynamic.jsx
@@ -4,6 +4,7 @@ import NextImage from 'next/image';
import Link from "next/link";
import { createSlug } from '@/core/utils/slug';
import odooApi from '@/core/api/odooApi';
+import { Skeleton} from '@chakra-ui/react'
const CategoryDynamic = () => {
const { categoryManagement } = useCategoryManagement();
@@ -17,14 +18,10 @@ const CategoryDynamic = () => {
const updatedSubCategoryData = {};
for (const category of categoryManagement.data) {
- // Calculate level 1 products
const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`);
- // console.log("countLevel1.child",countLevel1)
updatedCategoryData[category.categoryIdI] = countLevel1?.numFound;
-
- // Calculate level 2 products for each sub-category
for (const subCategory of countLevel1.children) {
updatedSubCategoryData[subCategory.id] = subCategory.numFound;
}
@@ -41,62 +38,70 @@ const CategoryDynamic = () => {
return (
<div>
- {categoryManagement && categoryManagement.data?.map((category) => {
- const countLevel1 = categoryData[category.categoryIdI] || 0;
-
- return (
- <div key={category.id}>
- <div className='bagian-judul flex flex-row justify-start items-center gap-3 mb-4 mt-4'>
- <div className='font-semibold sm:text-h-lg mr-2'>{category.name}</div>
- <p className='text-gray_r-10 text-sm'>{countLevel1} Produk tersedia</p>
- <Link href={createSlug('/shop/category/', category?.name, category?.categoryIdI)} className="!text-red-500 font-semibold">Lihat Semua</Link>
- </div>
- <div className='grid grid-cols-3 gap-2'>
- {category.categories.map((subCategory) => {
- const countLevel2 = subCategoryData[subCategory.idLevel2] || 0;
+ {categoryManagement && categoryManagement.data?.map((category) => {
+ const countLevel1 = categoryData[category.categoryIdI] || 0;
+
+ return (
+ <Skeleton key={category.id} isLoaded={categoryManagement}>
+ <div key={category.id}>
+ <div className='bagian-judul flex flex-row justify-start items-center gap-3 mb-4 mt-4'>
+ <div className='font-semibold sm:text-h-lg mr-2'>{category.name}</div>
+ <Skeleton isLoaded={countLevel1 !=0}>
+ <p className={`text-gray_r-10 text-sm`}>{countLevel1} Produk tersedia</p>
+ </Skeleton>
+ <Link href={createSlug('/shop/category/', category?.name, category?.categoryIdI)} className="!text-red-500 font-semibold">Lihat Semua</Link>
+ </div>
+ <div className='grid grid-cols-3 gap-2'>
+ {category.categories.map((subCategory) => {
+ const countLevel2 = subCategoryData[subCategory.idLevel2] || 0;
- return (
- <div key={subCategory.id} className='border rounded justify-start items-start'>
- <div className='p-3'>
- <div className='flex flex-row border rounded mb-2 justify-start items-center'>
- <NextImage
- src={subCategory.image ? subCategory.image : "/images/noimage.jpeg"}
- alt={subCategory.name}
- width={90}
- height={30}
- className='object-fit'
- />
- <div className='bagian-judul flex flex-col justify-center items-start gap-2 ml-2'>
- <div className='font-semibold text-lg mr-2'>{subCategory.name}</div>
- <p className='text-gray_r-10 text-sm'>{countLevel2} Produk tersedia</p>
- <Link href={createSlug('/shop/category/', subCategory?.name, subCategory?.idLevel2)} className="!text-red-500 font-semibold">Lihat Semua</Link>
- </div>
- </div>
- <div className='grid grid-cols-2 gap-2 overflow-y-auto max-h-[240px]'>
- {subCategory.childFrontendIdI.map((childCategory) => (
- <div key={childCategory.id}>
- <Link href={createSlug('/shop/category/', childCategory?.name, childCategory?.idLevel3)} className="flex flex-row gap-2 border rounded group hover:border-red-500">
- <NextImage
- src={childCategory.image ? childCategory.image : "/images/noimage.jpeg"}
- alt={childCategory.name}
- width={40}
- height={40}
- />
- <div className='bagian-judul flex flex-col justify-center items-center gap-2 break-words line-clamp-2 group-hover:text-red-500'>
- <div className='font-semibold line-clamp-2 group-hover:text-red-500 text-sm mr-2'>{childCategory.name}</div>
- </div>
- </Link>
+ return (
+ <div key={subCategory.id} className='border rounded justify-start items-start'>
+ <div className='p-3'>
+ <div className='flex flex-row border rounded mb-2 justify-start items-center'>
+ <NextImage
+ src={subCategory.image ? subCategory.image : "/images/noimage.jpeg"}
+ alt={subCategory.name}
+ width={90}
+ height={30}
+ className='object-fit'
+ />
+ <div className='bagian-judul flex flex-col justify-center items-start gap-2 ml-2'>
+ <div className='font-semibold text-lg mr-2'>{subCategory.name}</div>
+ <Skeleton isLoaded={countLevel2 != 0}>
+ <p className={`text-gray_r-10 text-sm`}>
+ {countLevel2} Produk tersedia
+ </p>
+ </Skeleton>
+ <Link href={createSlug('/shop/category/', subCategory?.name, subCategory?.idLevel2)} className="!text-red-500 font-semibold">Lihat Semua</Link>
</div>
- ))}
+ </div>
+ <div className='grid grid-cols-2 gap-2 overflow-y-auto max-h-[240px]'>
+ {subCategory.childFrontendIdI.map((childCategory) => (
+ <div key={childCategory.id}>
+ <Link href={createSlug('/shop/category/', childCategory?.name, childCategory?.idLevel3)} className="flex flex-row gap-2 border rounded group hover:border-red-500">
+ <NextImage
+ src={childCategory.image ? childCategory.image : "/images/noimage.jpeg"}
+ alt={childCategory.name}
+ width={40}
+ height={40}
+ />
+ <div className='bagian-judul flex flex-col justify-center items-center gap-2 break-words line-clamp-2 group-hover:text-red-500'>
+ <div className='font-semibold line-clamp-2 group-hover:text-red-500 text-sm mr-2'>{childCategory.name}</div>
+ </div>
+ </Link>
+ </div>
+ ))}
+ </div>
</div>
</div>
- </div>
- );
- })}
+ );
+ })}
+ </div>
</div>
- </div>
- );
- })}
+ </Skeleton>
+ );
+ })}
</div>
);
};