From c57fdaf8562f2b40fd88bf09d74a2a863ce3a7e0 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 30 Oct 2023 10:04:02 +0700 Subject: Remove captcha validation on submit button --- src-migrate/modules/register/components/Form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/register/components/Form.tsx b/src-migrate/modules/register/components/Form.tsx index 3227a549..33df1389 100644 --- a/src-migrate/modules/register/components/Form.tsx +++ b/src-migrate/modules/register/components/Form.tsx @@ -150,7 +150,7 @@ const Form = () => { -- cgit v1.2.3 From 3f849355048e5c280a35a5747577e5296b90e9fd Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 25 Jan 2024 15:27:27 +0700 Subject: Add all promo page --- src-migrate/modules/promo/components/Hero.tsx | 55 ++++++++++++++++++++++ src-migrate/modules/promo/components/Voucher.tsx | 11 +++++ src-migrate/modules/promo/styles/hero.module.css | 27 +++++++++++ .../modules/promo/styles/voucher.module.css | 3 ++ src-migrate/pages/shop/promo/index.tsx | 17 +++++++ src-migrate/services/banner.ts | 13 +++++ src-migrate/types/banner.ts | 8 ++++ 7 files changed, 134 insertions(+) create mode 100644 src-migrate/modules/promo/components/Hero.tsx create mode 100644 src-migrate/modules/promo/components/Voucher.tsx create mode 100644 src-migrate/modules/promo/styles/hero.module.css create mode 100644 src-migrate/modules/promo/styles/voucher.module.css create mode 100644 src-migrate/pages/shop/promo/index.tsx create mode 100644 src-migrate/services/banner.ts create mode 100644 src-migrate/types/banner.ts (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx new file mode 100644 index 00000000..63524509 --- /dev/null +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -0,0 +1,55 @@ +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import style from '../styles/hero.module.css'; +import 'swiper/css' +import Image from 'next/image'; +import { useQuery } from 'react-query'; +import { getBanner } from '~/services/banner'; + +const swiperBanner: SwiperProps = { + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + // modules: [Pagination, Autoplay], + loop: true, + className: 'h-[400px] w-full', + slidesPerView: 1.1, + spaceBetween: 10 +} + +const Hero = () => { + const bannerQuery = useQuery({ + queryKey: ['banner.all-promo'], + queryFn: () => getBanner({ type: 'all-promo' }) + }) + + const banners = bannerQuery.data || [] + + return ( +
+
+
Pasti Hemat & Untung Selama Belanja di Indoteknik.com!
+
+
Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!
+
+ +
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+ ) +} + +export default Hero \ No newline at end of file diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx new file mode 100644 index 00000000..11742f9a --- /dev/null +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -0,0 +1,11 @@ +import style from '../styles/voucher.module.css' + +const Voucher = () => { + return ( + <> +
Pakai Voucher Belanja
+ + ) +} + +export default Voucher \ No newline at end of file diff --git a/src-migrate/modules/promo/styles/hero.module.css b/src-migrate/modules/promo/styles/hero.module.css new file mode 100644 index 00000000..70d725be --- /dev/null +++ b/src-migrate/modules/promo/styles/hero.module.css @@ -0,0 +1,27 @@ +.wrapper { + @apply bg-warning-100/50 rounded-xl w-full h-[460px] flex; +} + +.desc-section { + @apply w-full md:w-5/12 + flex flex-col + md:justify-center + p-6 md:pl-10; +} + +.title { + @apply text-title-sm md:text-title-lg + leading-[30px] md:leading-[42px] + font-semibold; +} + +.subtitle { + @apply text-body-2 leading-7 text-gray-700; +} + +.banner-section { + @apply md:w-7/12 + flex flex-col + md:justify-center + md:pr-10; +} diff --git a/src-migrate/modules/promo/styles/voucher.module.css b/src-migrate/modules/promo/styles/voucher.module.css new file mode 100644 index 00000000..22a3a0ac --- /dev/null +++ b/src-migrate/modules/promo/styles/voucher.module.css @@ -0,0 +1,3 @@ +.title { + @apply text-h-sm md:text-h-lg font-semibold; +} diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx new file mode 100644 index 00000000..df2e9dcb --- /dev/null +++ b/src-migrate/pages/shop/promo/index.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import Hero from '~/modules/promo/components/Hero' +import Voucher from '~/modules/promo/components/Voucher' + +const PromoPage = () => { + return ( + <> + + +
+ + + + ) +} + +export default PromoPage \ No newline at end of file diff --git a/src-migrate/services/banner.ts b/src-migrate/services/banner.ts new file mode 100644 index 00000000..cb7b19cc --- /dev/null +++ b/src-migrate/services/banner.ts @@ -0,0 +1,13 @@ +import odooApi from '~/libs/odooApi'; +import { IBanner } from '~/types/banner'; + +type GetBannerProps = { + type: string; +}; + +export const getBanner = async (params: GetBannerProps): Promise => { + const url = `/api/v1/banner`; + const searchParams = new URLSearchParams(params); + + return await odooApi('GET', `${url}?${searchParams}`); +}; diff --git a/src-migrate/types/banner.ts b/src-migrate/types/banner.ts new file mode 100644 index 00000000..e1604ad4 --- /dev/null +++ b/src-migrate/types/banner.ts @@ -0,0 +1,8 @@ +export interface IBanner { + image: string; + name: string; + sequence: number; + url: string | false; + group_by_week: number | false; + background_color: string | false; +} -- cgit v1.2.3 From 8d8c43d90373aab6238773e291a48d65d55c52a2 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Sat, 17 Feb 2024 10:23:23 +0700 Subject: Add voucher section --- src-migrate/modules/promo/components/Hero.tsx | 23 ++++--- src-migrate/modules/promo/components/Voucher.tsx | 73 ++++++++++++++++++++++ .../modules/promo/styles/voucher.module.css | 40 ++++++++++++ src-migrate/pages/shop/promo/index.tsx | 9 ++- src-migrate/services/voucher.ts | 8 +++ src-migrate/types/voucher.ts | 8 +++ 6 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 src-migrate/services/voucher.ts create mode 100644 src-migrate/types/voucher.ts (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index 63524509..5470b93b 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -1,19 +1,21 @@ -import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; -import style from '../styles/hero.module.css'; -import 'swiper/css' +import 'swiper/css'; + import Image from 'next/image'; +import { useEffect, useMemo } from 'react'; import { useQuery } from 'react-query'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; + import { getBanner } from '~/services/banner'; +import style from '../styles/hero.module.css'; const swiperBanner: SwiperProps = { autoplay: { delay: 6000, disableOnInteraction: false }, - // modules: [Pagination, Autoplay], - loop: true, + loop: false, className: 'h-[400px] w-full', - slidesPerView: 1.1, + slidesPerView: 1, spaceBetween: 10 } @@ -23,7 +25,14 @@ const Hero = () => { queryFn: () => getBanner({ type: 'all-promo' }) }) - const banners = bannerQuery.data || [] + const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]); + + useEffect(() => { + if (banners.length > 1) { + swiperBanner.slidesPerView = 1.1; + swiperBanner.loop = true; + } + }, [banners]); return (
diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 11742f9a..0706f044 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -1,9 +1,82 @@ +import { useMemo } from 'react' +import { useQuery } from 'react-query' +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react' +import { getVoucher } from '~/services/voucher' import style from '../styles/voucher.module.css' +import Image from 'next/image' +import { useToast } from '@chakra-ui/react' + +const swiperVoucher: SwiperProps = { + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + loop: false, + className: 'h-[160px] w-full', + slidesPerView: 3, + spaceBetween: 16 +} const Voucher = () => { + const toast = useToast(); + const voucherQuery = useQuery({ + queryKey: ['voucher.all-voucher'], + queryFn: getVoucher + }) + + const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); + + const copyText = (text: string) => { + navigator.clipboard.writeText(text) + toast({ + title: 'Salin ke papan klip', + description: 'Kode voucher berhasil disalin', + status: 'success', + duration: 3000, + isClosable: true, + position: 'bottom', + }) + } + return ( <>
Pakai Voucher Belanja
+ +
+ + {voucherQuery.isLoading && ( +
+ {Array.from({ length: 3 }).map((_, index) => ( +
+ ))} +
+ )} + {!voucherQuery.isLoading && ( +
+ + {vouchers.map((voucher) => ( + +
+ {voucher.name} + +
+
{voucher.name}
+
{voucher.description} Lorem ipsum dolor sit, amet consectetur adipisicing elit. Officiis magni nobis sint aspernatur soluta deserunt excepturi delectus corporis libero, voluptate odit! Cupiditate, quibusdam ipsa saepe voluptas repudiandae eum quaerat suscipit.
+
+
+
Kode Promo
+
{voucher.code}
+
+ +
+
+
+
+ ))} +
+
+ )} + ) } diff --git a/src-migrate/modules/promo/styles/voucher.module.css b/src-migrate/modules/promo/styles/voucher.module.css index 22a3a0ac..24d3aac2 100644 --- a/src-migrate/modules/promo/styles/voucher.module.css +++ b/src-migrate/modules/promo/styles/voucher.module.css @@ -1,3 +1,43 @@ .title { @apply text-h-sm md:text-h-lg font-semibold; } + +.voucher-section { + @apply w-full; +} + +.voucher-card { + @apply w-full h-full rounded-xl border border-gray-200 shadow-md p-4 flex gap-x-4; +} + +.voucher-image { + @apply bg-gray-100 rounded-lg w-4/12 h-full object-contain object-center; +} + +.voucher-content { + @apply flex-1 flex flex-col; +} + +.voucher-title { + @apply font-medium text-body-1 leading-6 mb-1; +} + +.voucher-desc { + @apply text-gray-800 line-clamp-2 text-caption-1; +} + +.voucher-bottom { + @apply flex justify-between mt-auto; +} + +.voucher-code-desc { + @apply text-gray-500 text-caption-1; +} + +.voucher-code { + @apply text-red-700 font-medium; +} + +.voucher-copy { + @apply bg-gray-200 hover:bg-danger-500 text-danger-500 hover:text-white transition-colors rounded-lg flex items-center justify-center px-6; +} diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index df2e9dcb..f293bbe3 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -1,15 +1,20 @@ import React from 'react' +import { LazyLoadComponent } from 'react-lazy-load-image-component' import Hero from '~/modules/promo/components/Hero' import Voucher from '~/modules/promo/components/Voucher' const PromoPage = () => { return ( <> - + + +
- + + + ) } diff --git a/src-migrate/services/voucher.ts b/src-migrate/services/voucher.ts new file mode 100644 index 00000000..447b448e --- /dev/null +++ b/src-migrate/services/voucher.ts @@ -0,0 +1,8 @@ +import odooApi from '~/libs/odooApi'; +import { IVoucher } from '~/types/voucher'; + +export const getVoucher = async (): Promise => { + const url = `/api/v1/voucher`; + + return await odooApi('GET', url); +}; diff --git a/src-migrate/types/voucher.ts b/src-migrate/types/voucher.ts new file mode 100644 index 00000000..3e90f449 --- /dev/null +++ b/src-migrate/types/voucher.ts @@ -0,0 +1,8 @@ +export interface IVoucher { + id: number; + image: string; + name: string; + code: string; + description: string | false; + remaining_time: string; +} -- cgit v1.2.3 From ed0d0293f88adf3c5312cb556bc464e330b3672a Mon Sep 17 00:00:00 2001 From: "HATEC\\SPVDEV001" Date: Fri, 26 Apr 2024 09:44:31 +0700 Subject: hide button checkout if is step approval is true --- src-migrate/pages/shop/cart/index.tsx | 39 ++++++++++++++++++++--------------- src-migrate/types/auth.ts | 4 ++++ 2 files changed, 26 insertions(+), 17 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 4b4de92b..9866be46 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -16,13 +16,17 @@ import Image from '~/components/ui/image'; const CartPage = () => { const auth = getAuth(); + const [isStepApproval, setIsStepApproval] = React.useState(false); const { loadCart, cart, summary } = useCartStore(); const useDivvice = useDevice(); useEffect(() => { - if (typeof auth === 'object' && !cart) loadCart(auth.id); + if (typeof auth === 'object' && !cart) { + loadCart(auth.id); + setIsStepApproval(auth?.feature?.soApproval); + } }, [auth, loadCart, cart]); const hasSelectedPromo = useMemo(() => { @@ -123,23 +127,24 @@ const CartPage = () => { Quotation - - - - + + + )}
diff --git a/src-migrate/types/auth.ts b/src-migrate/types/auth.ts index 02e3623d..e93a475a 100644 --- a/src-migrate/types/auth.ts +++ b/src-migrate/types/auth.ts @@ -15,6 +15,10 @@ export type AuthProps = { company: boolean; pricelist: string | null; token: string; + feature : { + onlyReadyStock : boolean, + soApproval : boolean + } }; export type AuthApiProps = OdooApiRes; -- cgit v1.2.3 From 145f9edfd32b385771483b9b95a9fa0fa24c2dec Mon Sep 17 00:00:00 2001 From: "HATEC\\SPVDEV001" Date: Fri, 26 Apr 2024 13:57:55 +0700 Subject: css --- src-migrate/pages/shop/cart/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 9866be46..e101b5ad 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -110,7 +110,7 @@ const CartPage = () => { )} -
+
Date: Wed, 8 May 2024 13:23:10 +0700 Subject: change wa number --- src-migrate/libs/whatsappUrl.ts | 2 +- src-migrate/modules/header/components/HeaderDesktop.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/libs/whatsappUrl.ts b/src-migrate/libs/whatsappUrl.ts index 66879585..a3fcf8ad 100644 --- a/src-migrate/libs/whatsappUrl.ts +++ b/src-migrate/libs/whatsappUrl.ts @@ -44,5 +44,5 @@ export const whatsappUrl = ({ result = greetingText + result; } - return `https://wa.me/628128080622?text=${encodeURIComponent(result)}`; + return `https://wa.me/6281717181922?text=${encodeURIComponent(result)}`; }; diff --git a/src-migrate/modules/header/components/HeaderDesktop.tsx b/src-migrate/modules/header/components/HeaderDesktop.tsx index 8f5a8efa..131fa7da 100644 --- a/src-migrate/modules/header/components/HeaderDesktop.tsx +++ b/src-migrate/modules/header/components/HeaderDesktop.tsx @@ -54,7 +54,7 @@ const HeaderDesktop = () => { Whatsapp
Whatsapp
- 0812 8080 622 (Chat) + 0817 1718 1922 (Chat)
-- cgit v1.2.3 From 040657403a01205b22e1028d8ebea971f5df9ac5 Mon Sep 17 00:00:00 2001 From: "HATEC\\SPVDEV001" Date: Tue, 4 Jun 2024 13:28:20 +0700 Subject: promo line --- src-migrate/modules/promo/components/PromotinProgram.tsx | 9 +++++++++ src-migrate/modules/promo/components/Voucher.tsx | 2 +- src-migrate/pages/shop/promo/index.tsx | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src-migrate/modules/promo/components/PromotinProgram.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromotinProgram.tsx b/src-migrate/modules/promo/components/PromotinProgram.tsx new file mode 100644 index 00000000..19f228ea --- /dev/null +++ b/src-migrate/modules/promo/components/PromotinProgram.tsx @@ -0,0 +1,9 @@ +const PromotionProgram = () => { + return ( + <> +
Serba Serbi Promo
+ + ) +} + +export default PromotionProgram \ No newline at end of file diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 0706f044..14d3c301 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -61,7 +61,7 @@ const Voucher = () => {
{voucher.name}
-
{voucher.description} Lorem ipsum dolor sit, amet consectetur adipisicing elit. Officiis magni nobis sint aspernatur soluta deserunt excepturi delectus corporis libero, voluptate odit! Cupiditate, quibusdam ipsa saepe voluptas repudiandae eum quaerat suscipit.
+
{voucher.description}
Kode Promo
diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index f293bbe3..133be6df 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -1,6 +1,7 @@ import React from 'react' import { LazyLoadComponent } from 'react-lazy-load-image-component' import Hero from '~/modules/promo/components/Hero' +import PromotionProgram from '~/modules/promo/components/PromotinProgram' import Voucher from '~/modules/promo/components/Voucher' const PromoPage = () => { @@ -12,6 +13,12 @@ const PromoPage = () => {
+ + + + +
+ -- cgit v1.2.3 From f9f1fdf83c2b6ed5c1d85d7418d45aeed9b05c77 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 5 Jun 2024 15:24:42 +0700 Subject: add feature SNI-TKDR --- src-migrate/modules/cart/components/Item.tsx | 59 ++++++++++++- .../product-card/components/ProductCard.tsx | 72 +++++++++++++++- .../modules/product-detail/components/Image.tsx | 89 +++++++++++++++++--- .../modules/product-promo/components/Item.tsx | 97 +++++++++++++++++----- 4 files changed, 280 insertions(+), 37 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index 6ded6373..fed11eb0 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -4,7 +4,8 @@ import { Skeleton, SkeletonProps, Tooltip } from '@chakra-ui/react' import { InfoIcon } from 'lucide-react' import Image from 'next/image' import Link from 'next/link' - +import ImageNext from 'next/image'; +import { useEffect, useState } from 'react'; import { PROMO_CATEGORY } from '~/constants/promotion' import formatCurrency from '~/libs/formatCurrency' import { createSlug } from '~/libs/slug' @@ -20,6 +21,31 @@ type Props = { } const CartItem = ({ item, editable = true }: Props) => { + const [isSni, setIsSni] = useState(false); + const [isTkdn, setTkdn] = useState(false); + + useEffect(() => { + const fetchData = async () => { + try { + const responseSni = await fetch('URL_API_SNI'); + const dataSni = await responseSni.json(); + setIsSni(dataSni && dataSni.sni); + + const responseTkdn = await fetch('URL_API_TKDN'); + const dataTkdn = await responseTkdn.json(); + setTkdn(dataTkdn && dataTkdn.tkdn); + } catch (error) { + console.error('Error fetching data:', error); + setIsSni(false); + setTkdn(false); + } + }; + + fetchData(); + + return () => {}; + }, []); + return (
{item.cart_type === 'promotion' && ( @@ -46,7 +72,7 @@ const CartItem = ({ item, editable = true }: Props) => { {editable && }
- +
@@ -98,7 +124,7 @@ const CartItem = ({ item, editable = true }: Props) => { ) } -CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { +CartItem.Image = function CartItemImage({ item, isSni, isTkdn }: { item: CartItemProps, isSni: boolean, isTkdn: boolean }) { const image = item?.image || item?.parent?.image return ( @@ -116,6 +142,31 @@ CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { className={style.image} > {image && {item.name}} + +
+ {/*
*/} + {!isSni && ( + + )} + {/*
*/} + {/*
*/} + {!isTkdn && ( + + )} + {/*
*/} +
{!image &&
No Image
} )} @@ -153,4 +204,4 @@ CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: nu )) } -export default CartItem \ No newline at end of file +export default CartItem diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx index 4ddebda5..c3f05176 100644 --- a/src-migrate/modules/product-card/components/ProductCard.tsx +++ b/src-migrate/modules/product-card/components/ProductCard.tsx @@ -1,8 +1,8 @@ import style from '../styles/product-card.module.css' - +import ImageNext from 'next/image'; import clsx from 'clsx' import Link from 'next/link' -import { useMemo } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import Image from '~/components/ui/image' import useUtmSource from '~/hooks/useUtmSource' import clsxm from '~/libs/clsxm' @@ -18,6 +18,46 @@ type Props = { const ProductCard = ({ product, layout = 'vertical' }: Props) => { const utmSource = useUtmSource() + const [isSni, setIsSni] = useState(false); + const [isTkdn, setTkdn] = useState(false); + + useEffect(() => { + // Lakukan pemanggilan API untuk memeriksa isSni + const fetchSniData = async () => { + try { + const response = await fetch('URL_API_SNI'); + const data = await response.json(); + if (data && data.sni) { + setIsSni(true); + } else { + setIsSni(false); + } + } catch (error) { + console.error('Error fetching SNI data:', error); + setIsSni(false); + } + }; + + // Lakukan pemanggilan API untuk memeriksa isTkdn + const fetchTkdnData = async () => { + try { + const response = await fetch('URL_API_TKDN'); + const data = await response.json(); + if (data && data.tkdn) { + setTkdn(true); + } else { + setTkdn(false); + } + } catch (error) { + console.error('Error fetching TKDN data:', error); + setTkdn(false); + } + }; + fetchSniData(); + fetchTkdnData(); + return () => { + }; + }, []); const URL = { product: createSlug('/shop/product/', product.name, product.id.toString()) + `?utm_source=${utmSource}`, @@ -40,6 +80,8 @@ const ProductCard = ({ product, layout = 'vertical' }: Props) => { [style['image-h']]: layout === 'horizontal', })}> + +
{product.name} { height={128} className='object-contain object-center h-full w-full' /> +
+
+ {!isSni && ( + + )} +
+
+ {!isTkdn && ( + + )} +
+
+
+ {product.variant_total > 1 && (
{product.variant_total} Varian
)} diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx index 3d7777f8..1b80efa8 100644 --- a/src-migrate/modules/product-detail/components/Image.tsx +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -1,5 +1,5 @@ import style from '../styles/image.module.css'; - +import ImageNext from 'next/image'; import React, { useEffect, useMemo, useState } from 'react' import { InfoIcon } from 'lucide-react' import { Tooltip } from '@chakra-ui/react' @@ -17,6 +17,47 @@ const Image = ({ product }: Props) => { const [count, setCount] = useState(flashSale?.remaining_time || 0); + const [isSni, setIsSni] = useState(false); + const [isTkdn, setTkdn] = useState(false); + + useEffect(() => { + // Lakukan pemanggilan API untuk memeriksa isSni + const fetchSniData = async () => { + try { + const response = await fetch('URL_API_SNI'); + const data = await response.json(); + if (data && data.sni) { + setIsSni(true); + } else { + setIsSni(false); + } + } catch (error) { + console.error('Error fetching SNI data:', error); + setIsSni(false); + } + }; + + // Lakukan pemanggilan API untuk memeriksa isTkdn + const fetchTkdnData = async () => { + try { + const response = await fetch('URL_API_TKDN'); + const data = await response.json(); + if (data && data.tkdn) { + setTkdn(true); + } else { + setTkdn(false); + } + } catch (error) { + console.error('Error fetching TKDN data:', error); + setTkdn(false); + } + }; + fetchSniData(); + fetchTkdnData(); + return () => { + }; + }, []); + useEffect(() => { let interval: NodeJS.Timeout; @@ -42,15 +83,43 @@ const Image = ({ product }: Props) => { return (
- + {/*
*/} + +
+
+ {!isSni && ( + + )} +
+
+ {!isTkdn && ( + + )} +
+
+ {/*
*/} + +
{ + variant: IProductVariantPromo; + isFree?: boolean; +}; + +const ProductPromoItem = ({ variant, isFree = false }: Props) => { + const [isSni, setIsSni] = useState(false); + const [isTkdn, setTkdn] = useState(false); + + useEffect(() => { + // Lakukan pemanggilan API untuk memeriksa isSni dan isTkdn + const fetchData = async () => { + try { + const responseSni = await fetch('URL_API_SNI'); + const dataSni = await responseSni.json(); + setIsSni(dataSni && dataSni.sni); + + const responseTkdn = await fetch('URL_API_TKDN'); + const dataTkdn = await responseTkdn.json(); + setTkdn(dataTkdn && dataTkdn.tkdn); + } catch (error) { + console.error('Error fetching data:', error); + setIsSni(false); + setTkdn(false); + } + }; + + fetchData(); + + return () => {}; + }, []); + return (
- {variant.display_name} +
+ {variant.display_name} +
+ {!isSni && ( +
+ +
+ )} + {!isTkdn && ( +
+ +
+ )} +
+
+
{variant.qty} pcs {isFree ? '(free)' : ''}
- -
- {variant.name} -
+ +
{variant.name}
- ) -} + ); +}; -export default ProductPromoItem \ No newline at end of file +export default ProductPromoItem; -- cgit v1.2.3 From 755b61a8a7a082cc13f7ecb4a79807f90e60b3d6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 5 Jun 2024 16:50:38 +0700 Subject: add feature SNI-TKDN --- .../product-card/components/ProductCard.tsx | 45 ++------------------- .../modules/product-detail/components/Image.tsx | 46 ++-------------------- src-migrate/types/product.ts | 2 + 3 files changed, 8 insertions(+), 85 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx index c3f05176..0febfadb 100644 --- a/src-migrate/modules/product-card/components/ProductCard.tsx +++ b/src-migrate/modules/product-card/components/ProductCard.tsx @@ -18,46 +18,7 @@ type Props = { const ProductCard = ({ product, layout = 'vertical' }: Props) => { const utmSource = useUtmSource() - const [isSni, setIsSni] = useState(false); - const [isTkdn, setTkdn] = useState(false); - - useEffect(() => { - // Lakukan pemanggilan API untuk memeriksa isSni - const fetchSniData = async () => { - try { - const response = await fetch('URL_API_SNI'); - const data = await response.json(); - if (data && data.sni) { - setIsSni(true); - } else { - setIsSni(false); - } - } catch (error) { - console.error('Error fetching SNI data:', error); - setIsSni(false); - } - }; - - // Lakukan pemanggilan API untuk memeriksa isTkdn - const fetchTkdnData = async () => { - try { - const response = await fetch('URL_API_TKDN'); - const data = await response.json(); - if (data && data.tkdn) { - setTkdn(true); - } else { - setTkdn(false); - } - } catch (error) { - console.error('Error fetching TKDN data:', error); - setTkdn(false); - } - }; - fetchSniData(); - fetchTkdnData(); - return () => { - }; - }, []); + const URL = { product: createSlug('/shop/product/', product.name, product.id.toString()) + `?utm_source=${utmSource}`, @@ -91,7 +52,7 @@ const ProductCard = ({ product, layout = 'vertical' }: Props) => { />
- {!isSni && ( + {product.isSni && ( { )}
- {!isTkdn && ( + {product.isTkdn && ( { const flashSale = product.flash_sale - const [count, setCount] = useState(flashSale?.remaining_time || 0); - const [isSni, setIsSni] = useState(false); - const [isTkdn, setTkdn] = useState(false); - - useEffect(() => { - // Lakukan pemanggilan API untuk memeriksa isSni - const fetchSniData = async () => { - try { - const response = await fetch('URL_API_SNI'); - const data = await response.json(); - if (data && data.sni) { - setIsSni(true); - } else { - setIsSni(false); - } - } catch (error) { - console.error('Error fetching SNI data:', error); - setIsSni(false); - } - }; - - // Lakukan pemanggilan API untuk memeriksa isTkdn - const fetchTkdnData = async () => { - try { - const response = await fetch('URL_API_TKDN'); - const data = await response.json(); - if (data && data.tkdn) { - setTkdn(true); - } else { - setTkdn(false); - } - } catch (error) { - console.error('Error fetching TKDN data:', error); - setTkdn(false); - } - }; - fetchSniData(); - fetchTkdnData(); - return () => { - }; - }, []); + useEffect(() => { let interval: NodeJS.Timeout; @@ -95,7 +55,7 @@ const Image = ({ product }: Props) => { />
- {!isSni && ( + {product.isSni && ( { )}
- {!isTkdn && ( + {product.isTkdn && ( Date: Thu, 6 Jun 2024 09:42:23 +0700 Subject: add feature SNI-TKDN --- src-migrate/modules/cart/components/Item.tsx | 59 +------------ .../modules/product-promo/components/Item.tsx | 97 +++++----------------- 2 files changed, 25 insertions(+), 131 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index fed11eb0..6ded6373 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -4,8 +4,7 @@ import { Skeleton, SkeletonProps, Tooltip } from '@chakra-ui/react' import { InfoIcon } from 'lucide-react' import Image from 'next/image' import Link from 'next/link' -import ImageNext from 'next/image'; -import { useEffect, useState } from 'react'; + import { PROMO_CATEGORY } from '~/constants/promotion' import formatCurrency from '~/libs/formatCurrency' import { createSlug } from '~/libs/slug' @@ -21,31 +20,6 @@ type Props = { } const CartItem = ({ item, editable = true }: Props) => { - const [isSni, setIsSni] = useState(false); - const [isTkdn, setTkdn] = useState(false); - - useEffect(() => { - const fetchData = async () => { - try { - const responseSni = await fetch('URL_API_SNI'); - const dataSni = await responseSni.json(); - setIsSni(dataSni && dataSni.sni); - - const responseTkdn = await fetch('URL_API_TKDN'); - const dataTkdn = await responseTkdn.json(); - setTkdn(dataTkdn && dataTkdn.tkdn); - } catch (error) { - console.error('Error fetching data:', error); - setIsSni(false); - setTkdn(false); - } - }; - - fetchData(); - - return () => {}; - }, []); - return (
{item.cart_type === 'promotion' && ( @@ -72,7 +46,7 @@ const CartItem = ({ item, editable = true }: Props) => { {editable && }
- +
@@ -124,7 +98,7 @@ const CartItem = ({ item, editable = true }: Props) => { ) } -CartItem.Image = function CartItemImage({ item, isSni, isTkdn }: { item: CartItemProps, isSni: boolean, isTkdn: boolean }) { +CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { const image = item?.image || item?.parent?.image return ( @@ -142,31 +116,6 @@ CartItem.Image = function CartItemImage({ item, isSni, isTkdn }: { item: CartIte className={style.image} > {image && {item.name}} - -
- {/*
*/} - {!isSni && ( - - )} - {/*
*/} - {/*
*/} - {!isTkdn && ( - - )} - {/*
*/} -
{!image &&
No Image
} )} @@ -204,4 +153,4 @@ CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: nu )) } -export default CartItem +export default CartItem \ No newline at end of file diff --git a/src-migrate/modules/product-promo/components/Item.tsx b/src-migrate/modules/product-promo/components/Item.tsx index 4d1808c2..b396160f 100644 --- a/src-migrate/modules/product-promo/components/Item.tsx +++ b/src-migrate/modules/product-promo/components/Item.tsx @@ -1,89 +1,34 @@ -import style from '../styles/item.module.css'; -import ImageNext from 'next/image'; -import { useEffect, useState } from 'react'; -import { Tooltip } from '@chakra-ui/react'; +import style from '../styles/item.module.css' -import Image from '~/components/ui/image'; -import { IProductVariantPromo } from '~/types/promotion'; +import { Tooltip } from '@chakra-ui/react' -type Props = { - variant: IProductVariantPromo; - isFree?: boolean; -}; - -const ProductPromoItem = ({ variant, isFree = false }: Props) => { - const [isSni, setIsSni] = useState(false); - const [isTkdn, setTkdn] = useState(false); - - useEffect(() => { - // Lakukan pemanggilan API untuk memeriksa isSni dan isTkdn - const fetchData = async () => { - try { - const responseSni = await fetch('URL_API_SNI'); - const dataSni = await responseSni.json(); - setIsSni(dataSni && dataSni.sni); - - const responseTkdn = await fetch('URL_API_TKDN'); - const dataTkdn = await responseTkdn.json(); - setTkdn(dataTkdn && dataTkdn.tkdn); - } catch (error) { - console.error('Error fetching data:', error); - setIsSni(false); - setTkdn(false); - } - }; - - fetchData(); - - return () => {}; - }, []); +import Image from '~/components/ui/image' +import { IProductVariantPromo } from '~/types/promotion' +type Props = { + variant: IProductVariantPromo, + isFree?: boolean +} + +const ProductPromoItem = ({ + variant, + isFree = false +}: Props) => { return (
-
- {variant.display_name} -
- {!isSni && ( -
- -
- )} - {!isTkdn && ( -
- -
- )} -
-
- + {variant.display_name}
{variant.qty} pcs {isFree ? '(free)' : ''}
- -
{variant.name}
+ +
+ {variant.name} +
- ); -}; + ) +} -export default ProductPromoItem; +export default ProductPromoItem \ No newline at end of file -- cgit v1.2.3 From 6ac1792ee37e5a5a9438f61e708966c944b61914 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 6 Jun 2024 10:21:39 +0700 Subject: " add feature SNI-TKDN" --- src-migrate/types/product.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts index 428b6e45..681cdc8e 100644 --- a/src-migrate/types/product.ts +++ b/src-migrate/types/product.ts @@ -11,8 +11,8 @@ export interface IProduct { stock_total: number; variant_total: number; description: string; - is_sni: boolean; - is_tkdn: boolean; + isSni: boolean; + isTkdn: boolean; categories: { id: string; name: string; -- cgit v1.2.3 From c88d98f06a6301bad6dd6d2e58b4908d8562638c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 7 Jun 2024 17:08:09 +0700 Subject: add promotion program --- .../modules/product-promo/components/Card.tsx | 144 ++++++++++++--------- 1 file changed, 80 insertions(+), 64 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index 59110098..be7d5b6e 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -18,36 +18,47 @@ import ProductPromoCardCountdown from "./CardCountdown" type Props = { promotion: IPromotion + slug?: string } -const ProductPromoCard = ({ promotion }: Props) => { +const ProductPromoCard = ({ promotion, slug }: Props) => { const [products, setProducts] = useState([]) + const [freeProducts, setFreeProducts] = useState([]) + const [error, setError] = useState(null) useEffect(() => { const getProducts = async () => { - const datas = [] - for (const product of promotion.products) { - const res = await getVariantById(product.product_id) - res.data.qty = product.qty - datas.push(res.data) + try { + const datas = [] + for (const product of promotion.products) { + const res = await getVariantById(product.product_id) + res.data.qty = product.qty + datas.push(res.data) + } + setProducts(datas) + } catch (err) { + setError('Failed to fetch product variants.') + console.error(err) } - setProducts(datas) } getProducts() }, [promotion.products]) - const [freeProducts, setFreeProducts] = useState([]) - useEffect(() => { const getFreeProducts = async () => { - const datas = [] - for (const product of promotion.free_products) { - const res = await getVariantById(product.product_id) - res.data.qty = product.qty - datas.push(res.data) + try { + const datas = [] + for (const product of promotion.free_products) { + const res = await getVariantById(product.product_id) + res.data.qty = product.qty + datas.push(res.data) + } + setFreeProducts(datas) + } catch (err) { + setError('Failed to fetch free product variants.') + console.error(err) } - setFreeProducts(datas) } getFreeProducts() @@ -63,62 +74,67 @@ const ProductPromoCard = ({ promotion }: Props) => { const allProducts = [...products, ...freeProducts] - return ( -
- + const shouldRender = !slug || promotion.type.value === slug -
-
-
{promotion.name}
+ return ( + shouldRender && ( +
+ + +
+
+
{promotion.name}
+ + +
+ Paket {PROMO_CATEGORY[promotion.type.value].alias} + +
+
+
- -
- Paket {PROMO_CATEGORY[promotion.type.value].alias} - + 0}> + {allProducts.map((product, index) => ( + + + products.length && promotion.type.value === 'merchandise'} + // isFree={index + 1 > products.length } + /> + + + {index + 1 < allProducts.length && ( +
+ +
+ )} +
+
+ ))} +
+ +
+
+ 0}> + Rp{formatCurrency(priceTotal)} + Hemat Rp {formatCurrency(priceTotal - promotion.price)} + + +
+ Rp{formatCurrency(promotion.price)} + (Total {promotion.total_qty} barang) +
- -
- - 0}> - {allProducts.map((product, index) => ( - <> - - products.length && promotion.type.value === 'merchandise'} - /> - - - {index + 1 < allProducts.length && ( -
- -
- )} -
- - ))} -
- -
-
- 0}> - Rp{formatCurrency(priceTotal)} - Hemat Rp {formatCurrency(priceTotal - promotion.price)} - - -
- Rp{formatCurrency(promotion.price)} - (Total {promotion.total_qty} barang) +
+
-
-
- -
+
-
+ ) ) } -export default ProductPromoCard \ No newline at end of file +export default ProductPromoCard -- cgit v1.2.3 From 9565ddf794165e297acf511a108f9a9643ee615d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 11 Jun 2024 13:40:23 +0700 Subject: update promotion program --- src-migrate/modules/product-promo/components/Card.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index be7d5b6e..0be27af2 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -77,7 +77,7 @@ const ProductPromoCard = ({ promotion, slug }: Props) => { const shouldRender = !slug || promotion.type.value === slug return ( - shouldRender && ( + // shouldRender && (
@@ -133,7 +133,7 @@ const ProductPromoCard = ({ promotion, slug }: Props) => {
- ) + // ) ) } -- cgit v1.2.3 From 0a87455727114468c216fbcd74266ea928eaec37 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 13 Jun 2024 09:34:24 +0700 Subject: update promotion-program --- src-migrate/modules/product-promo/components/Card.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index 0be27af2..e927508f 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -18,10 +18,10 @@ import ProductPromoCardCountdown from "./CardCountdown" type Props = { promotion: IPromotion - slug?: string + } -const ProductPromoCard = ({ promotion, slug }: Props) => { +const ProductPromoCard = ({ promotion}: Props) => { const [products, setProducts] = useState([]) const [freeProducts, setFreeProducts] = useState([]) const [error, setError] = useState(null) @@ -74,7 +74,7 @@ const ProductPromoCard = ({ promotion, slug }: Props) => { const allProducts = [...products, ...freeProducts] - const shouldRender = !slug || promotion.type.value === slug + return ( // shouldRender && ( -- cgit v1.2.3 From e3e3fe8d87130fcd1872046de0160272b6ea9763 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 14 Jun 2024 15:15:30 +0700 Subject: update promotion-program --- src-migrate/modules/product-promo/components/Section.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/Section.tsx b/src-migrate/modules/product-promo/components/Section.tsx index 5fc0da4c..4e8a7dd5 100644 --- a/src-migrate/modules/product-promo/components/Section.tsx +++ b/src-migrate/modules/product-promo/components/Section.tsx @@ -50,7 +50,7 @@ const ProductPromoSection = ({ productId }: Props) => { > {promotions?.data.map((promotion) => (
- +
))} -- cgit v1.2.3 From ba84659f27c84d0d2c0cc3275e211a865e416bf7 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 19 Jun 2024 11:31:02 +0700 Subject: update responsive promotion program --- .../modules/product-promo/components/AddToCart.tsx | 52 ++++++++++++----- .../modules/product-promo/components/Card.tsx | 68 +++++++++++++++++++++- .../modules/product-promo/styles/card.module.css | 12 ++++ 3 files changed, 117 insertions(+), 15 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/AddToCart.tsx b/src-migrate/modules/product-promo/components/AddToCart.tsx index 192dd231..87017c14 100644 --- a/src-migrate/modules/product-promo/components/AddToCart.tsx +++ b/src-migrate/modules/product-promo/components/AddToCart.tsx @@ -7,6 +7,9 @@ import { getAuth } from '~/libs/auth' import { upsertUserCart } from '~/services/cart' import { IPromotion } from '~/types/promotion' +import DesktopView from '../../../../src/core/components/views/DesktopView'; +import MobileView from '../../../../src/core/components/views/MobileView'; + type Props = { promotion: IPromotion } @@ -55,21 +58,42 @@ const ProductPromoAddToCart = ({ promotion }: Props) => { }, [status]) return ( - + + + + {status === 'success' && Berhasil} + {status !== 'success' && Keranjang} + + +
) } diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index e927508f..56e29e38 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -16,6 +16,9 @@ import ProductPromoItem from './Item' import ProductPromoAddToCart from "./AddToCart" import ProductPromoCardCountdown from "./CardCountdown" +import MobileView from '../../../../src/core/components/views/MobileView'; +import DesktopView from '../../../../src/core/components/views/DesktopView'; + type Props = { promotion: IPromotion @@ -77,7 +80,66 @@ const ProductPromoCard = ({ promotion}: Props) => { return ( - // shouldRender && ( +
+ +
+ + +
+
+
{promotion.name}
+ + + {/*
*/} + {/* Paket {PROMO_CATEGORY[promotion.type.value].alias} */} + + {/*
*/} +
+
+ + 0}> + {allProducts.map((product, index) => ( + + + products.length && promotion.type.value === 'merchandise'} + // isFree={index + 1 > products.length } + /> + + + {index + 1 < allProducts.length && ( +
+ +
+ )} +
+
+ ))} +
+ +
+
+ 0}> + Rp{formatCurrency(priceTotal)} + Hemat Rp {formatCurrency(priceTotal - promotion.price)} + + +
+ Rp{formatCurrency(promotion.price)} + (Total {promotion.total_qty} barang) +
+ +
+
+ +
+ +
+
+
+
+
@@ -133,6 +195,10 @@ const ProductPromoCard = ({ promotion}: Props) => {
+ +
+ // shouldRender && ( + // ) ) } diff --git a/src-migrate/modules/product-promo/styles/card.module.css b/src-migrate/modules/product-promo/styles/card.module.css index a2ad9af6..29db13f3 100644 --- a/src-migrate/modules/product-promo/styles/card.module.css +++ b/src-migrate/modules/product-promo/styles/card.module.css @@ -44,3 +44,15 @@ .totalItems { @apply text-gray_r-9; } + +/* @media only screen and (max-width: 384px) { + .basePrice { + @apply text-[13px]; + } + .price{ + @apply text-[15px]; + } + .totalItems{ + @apply text-[11px]; + } + } */ -- cgit v1.2.3 From 2de8d24f2d9850ae7578e5bf40f50c8157093625 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 19 Jun 2024 11:35:11 +0700 Subject: update responsive promotion program --- src-migrate/modules/product-promo/styles/card.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/styles/card.module.css b/src-migrate/modules/product-promo/styles/card.module.css index 29db13f3..faa3b370 100644 --- a/src-migrate/modules/product-promo/styles/card.module.css +++ b/src-migrate/modules/product-promo/styles/card.module.css @@ -45,7 +45,7 @@ @apply text-gray_r-9; } -/* @media only screen and (max-width: 384px) { +@media only screen and (max-width: 384px) { .basePrice { @apply text-[13px]; } @@ -55,4 +55,4 @@ .totalItems{ @apply text-[11px]; } - } */ + } \ No newline at end of file -- cgit v1.2.3 From 208b234320b6c42491a4e87a1c3db3abab9c1715 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 21 Jun 2024 10:52:28 +0700 Subject: update all-promotion --- src-migrate/modules/promo/components/Hero.tsx | 14 +- src-migrate/modules/promo/components/PromoList.jsx | 194 +++++++++++++++++++++ .../modules/promo/components/PromotinProgram.jsx | 95 ++++++++++ src-migrate/pages/shop/promo/index.tsx | 12 +- 4 files changed, 307 insertions(+), 8 deletions(-) create mode 100644 src-migrate/modules/promo/components/PromoList.jsx create mode 100644 src-migrate/modules/promo/components/PromotinProgram.jsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index 5470b93b..d8bb0be4 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -3,26 +3,30 @@ import 'swiper/css'; import Image from 'next/image'; import { useEffect, useMemo } from 'react'; import { useQuery } from 'react-query'; -import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; import { getBanner } from '~/services/banner'; import style from '../styles/hero.module.css'; +import 'swiper/css/navigation'; +import { Navigation, Pagination } from 'swiper'; const swiperBanner: SwiperProps = { + modules:[Navigation, Pagination], autoplay: { delay: 6000, disableOnInteraction: false }, - loop: false, + loop: true, className: 'h-[400px] w-full', slidesPerView: 1, - spaceBetween: 10 + spaceBetween: 10, + navigation:true, } const Hero = () => { const bannerQuery = useQuery({ queryKey: ['banner.all-promo'], - queryFn: () => getBanner({ type: 'all-promo' }) + queryFn: () => getBanner({ type: 'banner-promotion' }) }) const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]); @@ -47,7 +51,7 @@ const Hero = () => { {banners.map((banner, index) => ( {banner.name} { + // let query = type ? `type_value_s:${type}` : '*:*'; + let start = 0 + let rows = 100 + try { + const queryParams = new URLSearchParams({ q: type }); + const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=${rows}&start=${start}`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const promotions = await map(data.response.docs); + return promotions; + } catch (error) { + console.error("Error fetching promotion data:", error); + return []; + } +}; + + +const PromoList = ({ selectedPromo }) => { + + useEffect(() => { + const loadPromo = async () => { + setLoading(true); + + + try { + const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`); + setPromoItems(items); + + if (items.length === 0) { + setPromoData([]) + setLoading(false); + return; + } + + const brandArray = Array.isArray(brand) ? brand : brand.split(','); + const categoryArray = Array.isArray(category) ? category : category.split(','); + + const promoDataPromises = items.map(async (item) => { + + try { + let brandQuery = ''; + if (brand) { + brandQuery = brandArray.map(b => `manufacture_name_s:${b}`).join(' OR '); + brandQuery = `(${brandQuery})`; + } + + let categoryQuery = ''; + if (category) { + categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); + categoryQuery = `(${categoryQuery})`; + } + + let priceQuery = ''; + if (priceFrom && priceTo) { + priceQuery = `price_f:[${priceFrom} TO ${priceTo}]`; + } else if (priceFrom) { + priceQuery = `price_f:[${priceFrom} TO *]`; + } else if (priceTo) { + priceQuery = `price_f:[* TO ${priceTo}]`; + } + + let combinedQuery = ''; + let combinedQueryPrice = `${priceQuery}`; + if (brand && category && priceFrom || priceTo) { + combinedQuery = `${brandQuery} AND ${categoryQuery} `; + } else if (brand && category) { + combinedQuery = `${brandQuery} AND ${categoryQuery}`; + } else if (brand && priceFrom || priceTo) { + combinedQuery = `${brandQuery}`; + } else if (category && priceFrom || priceTo) { + combinedQuery = `${categoryQuery}`; + } else if (brand) { + combinedQuery = brandQuery; + } else if (category) { + combinedQuery = categoryQuery; + } + + if (combinedQuery && priceFrom || priceTo) { + const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); + const product = response.response.docs[0]; + const product_id = product.id; + const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} AND ${combinedQueryPrice}`); + return response2; + }else if(combinedQuery){ + const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); + const product = response.response.docs[0]; + const product_id = product.id; + const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} `); + return response2; + } else { + const response = await fetchPromoItemsSolr(`id:${item.id}`); + return response; + } + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + + const dataBrandCategoryPromises = promoDataArray.map(async (promoData) => { + if (promoData) { + const dataBrandCategory = promoData.map(async (item) => { + let response; + if(category){ + const categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); + response = await fetchVariantSolr(`id:${item.products[0].product_id} AND (${categoryQuery})`); + }else{ + response = await fetchVariantSolr(`id:${item.products[0].product_id}`) + } + + + if (response.response?.docs?.length > 0) { + const product = response.response.docs[0]; + const manufactureNameS = product.manufacture_name; + if (Array.isArray(manufactureNameS)) { + for (let i = 0; i < manufactureNameS.length; i += 2) { + const brand = manufactureNameS[i]; + const qty = 1; + const existingBrandIndex = brandsData.findIndex(b => b.brand === brand); + if (existingBrandIndex !== -1) { + brandsData[existingBrandIndex].qty += qty; + } else { + brandsData.push({ brand, qty }); + } + } + } + + const categoryNameS = product.category_name; + if (Array.isArray(categoryNameS)) { + for (let i = 0; i < categoryNameS.length; i += 2) { + const name = categoryNameS[i]; + const qty = 1; + const existingCategoryIndex = categoriesData.findIndex(c => c.name === name); + if (existingCategoryIndex !== -1) { + categoriesData[existingCategoryIndex].qty += qty; + } else { + categoriesData.push({ name, qty }); + } + } + } + } + }); + + return Promise.all(dataBrandCategory); + } + }); + + await Promise.all(dataBrandCategoryPromises); + setBrands(brandsData); + setCategories(categoriesData); + setLoading(false); + + } catch (loadError) { + // console.error("Error loading promo items:", loadError) + setLoading(false); + } + } + + if (slug) { + loadPromo() + } + },[slug, brand, category, priceFrom, priceTo, currentPage]); + + let title = ''; + + if (selectedPromo === 'Bundling') { + title = 'Kombinasi Kilat Pilihan Kami!'; + } else if (selectedPromo === 'Loading') { + title = 'Belanja Borong Pilihan Kami!'; + } else if (selectedPromo === 'Merchandise') { + title = 'Gratis Merchandise Spesial Indoteknik'; + } + + return ( +
+

{title}

+
DISINI CARD {selectedPromo}
+
+ ); +} + +export default PromoList; diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx new file mode 100644 index 00000000..a7e5dfef --- /dev/null +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -0,0 +1,95 @@ +import React from 'react'; +import Image from 'next/image'; +import { InfoIcon } from "lucide-react" + +const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { + return ( + <> +
Serba Serbi Promo
+
+
+
+
onSelectPromo('Bundling')} + className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Silat

+ +
+

+ Pilihan bundling barang kombinasi Silat. +

+
+
+
+
+
onSelectPromo('Loading')} + className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Barong

+ +
+

+ Beli banyak barang/partai barang borong. +

+
+
+
+
+
onSelectPromo('Merchandise')} + className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Angklung

+ +
+

+ Gratis barang promosi/merchandise menang langsung. +

+
+
+
+
+
+ + ); +}; + +export default PromotionProgram; diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index 133be6df..5fdd80aa 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -1,10 +1,13 @@ -import React from 'react' +import dynamic from 'next/dynamic' +import React, { useState } from 'react' import { LazyLoadComponent } from 'react-lazy-load-image-component' import Hero from '~/modules/promo/components/Hero' import PromotionProgram from '~/modules/promo/components/PromotinProgram' import Voucher from '~/modules/promo/components/Voucher' +const PromoList = dynamic(() => import('../../../modules/promo/components/PromoList')); const PromoPage = () => { + const [selectedPromo, setSelectedPromo] = useState('Bundling'); return ( <> @@ -14,9 +17,12 @@ const PromoPage = () => {
- + - +
-- cgit v1.2.3 From 7b08c9358888148bf6f6c2c7145d75e466550298 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 21 Jun 2024 11:04:57 +0700 Subject: update after marge --- src-migrate/modules/promo/components/PromoList.jsx | 170 --------------------- .../modules/promo/components/PromotinProgram.tsx | 9 -- 2 files changed, 179 deletions(-) delete mode 100644 src-migrate/modules/promo/components/PromotinProgram.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index af2958aa..ed758fbc 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -1,178 +1,8 @@ import Image from 'next/image'; import Link from '@/core/components/elements/Link/Link'; import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card' -// import { fetchPromoItemsSolr, fetchVariantSolr } from '../../../api/promoApi' - - -export const fetchPromoItemsSolr = async (type) => { - // let query = type ? `type_value_s:${type}` : '*:*'; - let start = 0 - let rows = 100 - try { - const queryParams = new URLSearchParams({ q: type }); - const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=${rows}&start=${start}`); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const data = await response.json(); - const promotions = await map(data.response.docs); - return promotions; - } catch (error) { - console.error("Error fetching promotion data:", error); - return []; - } -}; - const PromoList = ({ selectedPromo }) => { - - useEffect(() => { - const loadPromo = async () => { - setLoading(true); - - - try { - const items = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug}`); - setPromoItems(items); - - if (items.length === 0) { - setPromoData([]) - setLoading(false); - return; - } - - const brandArray = Array.isArray(brand) ? brand : brand.split(','); - const categoryArray = Array.isArray(category) ? category : category.split(','); - - const promoDataPromises = items.map(async (item) => { - - try { - let brandQuery = ''; - if (brand) { - brandQuery = brandArray.map(b => `manufacture_name_s:${b}`).join(' OR '); - brandQuery = `(${brandQuery})`; - } - - let categoryQuery = ''; - if (category) { - categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); - categoryQuery = `(${categoryQuery})`; - } - - let priceQuery = ''; - if (priceFrom && priceTo) { - priceQuery = `price_f:[${priceFrom} TO ${priceTo}]`; - } else if (priceFrom) { - priceQuery = `price_f:[${priceFrom} TO *]`; - } else if (priceTo) { - priceQuery = `price_f:[* TO ${priceTo}]`; - } - - let combinedQuery = ''; - let combinedQueryPrice = `${priceQuery}`; - if (brand && category && priceFrom || priceTo) { - combinedQuery = `${brandQuery} AND ${categoryQuery} `; - } else if (brand && category) { - combinedQuery = `${brandQuery} AND ${categoryQuery}`; - } else if (brand && priceFrom || priceTo) { - combinedQuery = `${brandQuery}`; - } else if (category && priceFrom || priceTo) { - combinedQuery = `${categoryQuery}`; - } else if (brand) { - combinedQuery = brandQuery; - } else if (category) { - combinedQuery = categoryQuery; - } - - if (combinedQuery && priceFrom || priceTo) { - const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); - const product = response.response.docs[0]; - const product_id = product.id; - const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} AND ${combinedQueryPrice}`); - return response2; - }else if(combinedQuery){ - const response = await fetchVariantSolr(`id:${item.product_id} AND ${combinedQuery}`); - const product = response.response.docs[0]; - const product_id = product.id; - const response2 = await fetchPromoItemsSolr(`type_value_s:${Array.isArray(slug) ? slug[0] : slug} AND product_ids:${product_id} `); - return response2; - } else { - const response = await fetchPromoItemsSolr(`id:${item.id}`); - return response; - } - } catch (fetchError) { - return []; - } - }); - - const promoDataArray = await Promise.all(promoDataPromises); - const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); - setPromoData(mergedPromoData); - - const dataBrandCategoryPromises = promoDataArray.map(async (promoData) => { - if (promoData) { - const dataBrandCategory = promoData.map(async (item) => { - let response; - if(category){ - const categoryQuery = categoryArray.map(c => `category_name:${c}`).join(' OR '); - response = await fetchVariantSolr(`id:${item.products[0].product_id} AND (${categoryQuery})`); - }else{ - response = await fetchVariantSolr(`id:${item.products[0].product_id}`) - } - - - if (response.response?.docs?.length > 0) { - const product = response.response.docs[0]; - const manufactureNameS = product.manufacture_name; - if (Array.isArray(manufactureNameS)) { - for (let i = 0; i < manufactureNameS.length; i += 2) { - const brand = manufactureNameS[i]; - const qty = 1; - const existingBrandIndex = brandsData.findIndex(b => b.brand === brand); - if (existingBrandIndex !== -1) { - brandsData[existingBrandIndex].qty += qty; - } else { - brandsData.push({ brand, qty }); - } - } - } - - const categoryNameS = product.category_name; - if (Array.isArray(categoryNameS)) { - for (let i = 0; i < categoryNameS.length; i += 2) { - const name = categoryNameS[i]; - const qty = 1; - const existingCategoryIndex = categoriesData.findIndex(c => c.name === name); - if (existingCategoryIndex !== -1) { - categoriesData[existingCategoryIndex].qty += qty; - } else { - categoriesData.push({ name, qty }); - } - } - } - } - }); - - return Promise.all(dataBrandCategory); - } - }); - - await Promise.all(dataBrandCategoryPromises); - setBrands(brandsData); - setCategories(categoriesData); - setLoading(false); - - } catch (loadError) { - // console.error("Error loading promo items:", loadError) - setLoading(false); - } - } - - if (slug) { - loadPromo() - } - },[slug, brand, category, priceFrom, priceTo, currentPage]); - let title = ''; if (selectedPromo === 'Bundling') { diff --git a/src-migrate/modules/promo/components/PromotinProgram.tsx b/src-migrate/modules/promo/components/PromotinProgram.tsx deleted file mode 100644 index 19f228ea..00000000 --- a/src-migrate/modules/promo/components/PromotinProgram.tsx +++ /dev/null @@ -1,9 +0,0 @@ -const PromotionProgram = () => { - return ( - <> -
Serba Serbi Promo
- - ) -} - -export default PromotionProgram \ No newline at end of file -- cgit v1.2.3 From 3ada88f0faf901e05bd56ecff8c4bcb209c06787 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 21 Jun 2024 15:31:12 +0700 Subject: update all-promotion --- src-migrate/modules/promo/components/FlashSale.tsx | 21 +++++ src-migrate/modules/promo/components/PromoList.jsx | 98 ++++++++++++++++++---- .../modules/promo/components/PromotinProgram.jsx | 2 +- src-migrate/pages/shop/promo/index.tsx | 19 +++-- 4 files changed, 117 insertions(+), 23 deletions(-) create mode 100644 src-migrate/modules/promo/components/FlashSale.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/FlashSale.tsx b/src-migrate/modules/promo/components/FlashSale.tsx new file mode 100644 index 00000000..dac0365c --- /dev/null +++ b/src-migrate/modules/promo/components/FlashSale.tsx @@ -0,0 +1,21 @@ +import dynamic from "next/dynamic"; +import React from "react"; +import { FlashSaleSkeleton } from "@/lib/flashSale/skeleton/FlashSaleSkeleton"; + +const FlashSale = dynamic( + () => import('@/lib/flashSale/components/FlashSale'), + { + loading: () => , + } + ); + + const FlashSalePromo = ()=> { + return( + <> +

Bayar Setengahnya!

+ + + ) + } + + export default FlashSalePromo \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index ed758fbc..fb4b6ee3 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -1,24 +1,92 @@ -import Image from 'next/image'; -import Link from '@/core/components/elements/Link/Link'; -import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card' +import React, { useState, useEffect } from 'react'; +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; +import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import useDevice from '@/core/hooks/useDevice'; +import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner' const PromoList = ({ selectedPromo }) => { - let title = ''; - - if (selectedPromo === 'Bundling') { - title = 'Kombinasi Kilat Pilihan Kami!'; - } else if (selectedPromo === 'Loading') { - title = 'Belanja Borong Pilihan Kami!'; - } else if (selectedPromo === 'Merchandise') { - title = 'Gratis Merchandise Spesial Indoteknik'; - } + const [title, setTitle] = useState(''); + const [slug, setSlug] = useState(''); + const [promoItems, setPromoItems] = useState([]); + const [promoData, setPromoData] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const { isMobile } = useDevice(); + + useEffect(() => { + if (selectedPromo === 'Bundling') { + setTitle('Kombinasi Kilat Pilihan Kami!'); + setSlug('bundling'); + } else if (selectedPromo === 'Loading') { + setTitle('Belanja Borong Pilihan Kami!'); + setSlug('discount_loading'); + } else if (selectedPromo === 'Merchandise') { + setTitle('Gratis Merchandise Spesial Indoteknik'); + setSlug('merchandise'); + } + }, [selectedPromo]); + + useEffect(() => { + const fetchPromotions = async () => { + setIsLoading(true); + try { + const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 50); + setPromoItems(items); + + console.log("selectedPromo",selectedPromo) + console.log("slug",slug) + console.log("items",items) + console.log("promoItems",promoItems) + + const promoDataPromises = items.map(async (item) => { + try { + const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); + return response; + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + } catch (error) { + console.error('Error fetching promo items:', error); + } finally { + setIsLoading(false); + } + }; + + if (slug) { + setIsLoading(true); + // Reset the promoItems and promoData when slug changes + setPromoItems([]); + setPromoData([]); + fetchPromotions(); + } + }, [slug]); return (
-

{title}

-
DISINI CARD {selectedPromo}
+

{title}

+ {isLoading ? ( +
+ +
+ ) : ( + + + {promoData?.map((promotion) => ( + +
+ +
+
+ ))} +
+ )}
); -} +}; export default PromoList; diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index a7e5dfef..13a8405b 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -5,7 +5,7 @@ import { InfoIcon } from "lucide-react" const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { return ( <> -
Serba Serbi Promo
+
Serba Serbi Promo
diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index 5fdd80aa..d1d6d70a 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -4,8 +4,11 @@ import { LazyLoadComponent } from 'react-lazy-load-image-component' import Hero from '~/modules/promo/components/Hero' import PromotionProgram from '~/modules/promo/components/PromotinProgram' import Voucher from '~/modules/promo/components/Voucher' +import FlashSale from '../../../modules/promo/components/FlashSale' const PromoList = dynamic(() => import('../../../modules/promo/components/PromoList')); + + const PromoPage = () => { const [selectedPromo, setSelectedPromo] = useState('Bundling'); return ( @@ -14,16 +17,18 @@ const PromoPage = () => { -
- + + + + + + - -
-- cgit v1.2.3 From 8b7db0f3ef5058f6e41996fd162a805ab9147cc6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 21 Jun 2024 16:16:34 +0700 Subject: update side banner & footer banner search --- src-migrate/modules/footer-banner/index.tsx | 6 +++++- src-migrate/modules/side-banner/index.tsx | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/footer-banner/index.tsx b/src-migrate/modules/footer-banner/index.tsx index 7db1363c..c829b91e 100644 --- a/src-migrate/modules/footer-banner/index.tsx +++ b/src-migrate/modules/footer-banner/index.tsx @@ -1,7 +1,9 @@ import Link from "next/link" +import React, { useMemo } from "react"; import { useQuery } from "react-query" import Image from "~/components/ui/image" import { getBanner } from "~/services/banner" +import { getRandomInt } from '@/utils/getRandomInt' const FooterBanner = () => { const fetchFooterBanner = useQuery({ @@ -9,7 +11,9 @@ const FooterBanner = () => { queryFn: () => getBanner({ type: 'bottom-search-promotion' }) }) - const banner = fetchFooterBanner?.data?.[0] || false + const length = useMemo(() => fetchFooterBanner.data?.length, [fetchFooterBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchFooterBanner?.data?.[randomIndex] || false; return banner && ( <> diff --git a/src-migrate/modules/side-banner/index.tsx b/src-migrate/modules/side-banner/index.tsx index be52c554..80a57a00 100644 --- a/src-migrate/modules/side-banner/index.tsx +++ b/src-migrate/modules/side-banner/index.tsx @@ -1,29 +1,31 @@ -import Link from "next/link" -import { useQuery } from "react-query" -import Image from "~/components/ui/image" -import { getBanner } from "~/services/banner" +import React, { useMemo } from "react"; +import Link from "next/link"; +import { useQuery } from "react-query"; +import Image from "~/components/ui/image"; +import { getBanner } from "~/services/banner"; +import { getRandomInt } from '@/utils/getRandomInt'; const SideBanner = () => { const fetchSideBanner = useQuery({ queryKey: 'sideBanner', queryFn: () => getBanner({ type: 'side-banner-search' }) - }) + }); - const banner = fetchSideBanner?.data?.[0] || false + const length = useMemo(() => fetchSideBanner.data?.length, [fetchSideBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchSideBanner?.data?.[randomIndex] || false; return banner && ( <> - {banner.url && ( + {banner.url ? ( {banner.name} - )} - - {!banner.url && ( + ) : ( {banner.name} )} - ) + ); } -export default SideBanner \ No newline at end of file +export default SideBanner; -- cgit v1.2.3 From 1583acec4f8d97633594ad5f0973a4d1235dc586 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 22 Jun 2024 12:37:46 +0700 Subject: add diskon di all promotion --- .../modules/promo/components/PromotinProgram.jsx | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index 13a8405b..7e042a4a 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -8,6 +8,32 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => {
Serba Serbi Promo
+ {/*
+
onSelectPromo('Diskon')} + className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Diskon' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Spesial Diskon

+ +
+

+ Harga lebih murah dan pasti makin hemat belinya.. +

+
+
+
*/}
onSelectPromo('Bundling')} -- cgit v1.2.3 From 8456bd17207e349c717d062fcc6fe4d032da1334 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 22 Jun 2024 12:39:22 +0700 Subject: update bagian footer untuk penawaran(baru tampilan saja) all promotion --- src-migrate/modules/promo/components/PromoList.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index fb4b6ee3..9b1a30a4 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -67,7 +67,7 @@ const PromoList = ({ selectedPromo }) => { }, [slug]); return ( -
+

{title}

{isLoading ? (
-- cgit v1.2.3 From 138206777970e2a2659d4de0a1a9722038851a14 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 22 Jun 2024 12:40:16 +0700 Subject: update bagian navbar dan judul halaman all promotion --- src-migrate/constants/menu.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src-migrate') diff --git a/src-migrate/constants/menu.ts b/src-migrate/constants/menu.ts index d1adebca..e3e7b0c6 100644 --- a/src-migrate/constants/menu.ts +++ b/src-migrate/constants/menu.ts @@ -2,6 +2,9 @@ import { SecondaryNavItemProps } from '~/types/nav'; export const SECONDARY_MENU_ITEMS: SecondaryNavItemProps[] = [ { + label: 'Semua Promo', + href: '/shop/promo', + },{ label: 'Semua Brand', href: '/shop/brands', }, -- cgit v1.2.3 From bfeb27c25e416db41e211de54e7f7d0cac4ad792 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 24 Jun 2024 09:13:24 +0700 Subject: update all promotion add zustand --- src-migrate/modules/promo/components/PromoList.jsx | 35 ++++++++++++---------- src-migrate/modules/promo/components/promoStore.js | 16 ++++++++++ src-migrate/pages/shop/promo/index.tsx | 2 +- 3 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 src-migrate/modules/promo/components/promoStore.js (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index 9b1a30a4..a21ba188 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -1,16 +1,25 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; import { Swiper, SwiperSlide } from 'swiper/react'; import useDevice from '@/core/hooks/useDevice'; -import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner' +import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; +import usePromoStore from './promoStore'; // Adjust the path accordingly const PromoList = ({ selectedPromo }) => { - const [title, setTitle] = useState(''); - const [slug, setSlug] = useState(''); - const [promoItems, setPromoItems] = useState([]); - const [promoData, setPromoData] = useState([]); - const [isLoading, setIsLoading] = useState(true); + const { + title, + slug, + promoItems, + promoData, + isLoading, + setTitle, + setSlug, + setPromoItems, + setPromoData, + setIsLoading, + } = usePromoStore(); + const { isMobile } = useDevice(); useEffect(() => { @@ -24,7 +33,7 @@ const PromoList = ({ selectedPromo }) => { setTitle('Gratis Merchandise Spesial Indoteknik'); setSlug('merchandise'); } - }, [selectedPromo]); + }, [selectedPromo, setTitle, setSlug]); useEffect(() => { const fetchPromotions = async () => { @@ -33,11 +42,6 @@ const PromoList = ({ selectedPromo }) => { const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 50); setPromoItems(items); - console.log("selectedPromo",selectedPromo) - console.log("slug",slug) - console.log("items",items) - console.log("promoItems",promoItems) - const promoDataPromises = items.map(async (item) => { try { const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); @@ -64,17 +68,16 @@ const PromoList = ({ selectedPromo }) => { setPromoData([]); fetchPromotions(); } - }, [slug]); + }, [slug, setPromoItems, setPromoData, setIsLoading]); return (
-

{title}

+

{title}

{isLoading ? (
) : ( - {promoData?.map((promotion) => ( diff --git a/src-migrate/modules/promo/components/promoStore.js b/src-migrate/modules/promo/components/promoStore.js new file mode 100644 index 00000000..c232de00 --- /dev/null +++ b/src-migrate/modules/promo/components/promoStore.js @@ -0,0 +1,16 @@ +import create from 'zustand'; + +const usePromoStore = create((set) => ({ + title: '', + slug: '', + promoItems: [], + promoData: [], + isLoading: true, + setTitle: (title) => set({ title }), + setSlug: (slug) => set({ slug }), + setPromoItems: (promoItems) => set({ promoItems }), + setPromoData: (promoData) => set({ promoData }), + setIsLoading: (isLoading) => set({ isLoading }), +})); + +export default usePromoStore; diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index d1d6d70a..7c4df2c1 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -29,7 +29,7 @@ const PromoPage = () => { - +

-- cgit v1.2.3 From 6f05ae8199603c7c8502987cc01ba7d0b31b27c2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 24 Jun 2024 14:36:06 +0700 Subject: add tampilkan lebih banyak pada card --- src-migrate/modules/promo/components/PromoList.jsx | 36 ++++++++++++++++++---- .../modules/promo/components/PromotinProgram.jsx | 8 ++--- 2 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index a21ba188..7187e9d7 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -1,10 +1,11 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; import { Swiper, SwiperSlide } from 'swiper/react'; import useDevice from '@/core/hooks/useDevice'; import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; -import usePromoStore from './promoStore'; // Adjust the path accordingly +import usePromoStore from './promoStore'; // Sesuaikan dengan path yang sesuai +import { ChevronRightIcon } from '@heroicons/react/24/outline'; const PromoList = ({ selectedPromo }) => { const { @@ -39,7 +40,7 @@ const PromoList = ({ selectedPromo }) => { const fetchPromotions = async () => { setIsLoading(true); try { - const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 50); + const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); setPromoItems(items); const promoDataPromises = items.map(async (item) => { @@ -54,6 +55,7 @@ const PromoList = ({ selectedPromo }) => { const promoDataArray = await Promise.all(promoDataPromises); const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); setPromoData(mergedPromoData); + } catch (error) { console.error('Error fetching promo items:', error); } finally { @@ -63,13 +65,19 @@ const PromoList = ({ selectedPromo }) => { if (slug) { setIsLoading(true); - // Reset the promoItems and promoData when slug changes setPromoItems([]); setPromoData([]); fetchPromotions(); } }, [slug, setPromoItems, setPromoData, setIsLoading]); + + + const navigateToPromoPage = () => { + // Fungsi untuk menavigasikan pengguna ke halaman promo yang sesuai dengan slug + window.location.href = '/shop/promo/' + slug; + }; + return (

{title}

@@ -78,14 +86,26 @@ const PromoList = ({ selectedPromo }) => {
) : ( - - {promoData?.map((promotion) => ( + + {promoData?.map((promotion) => (
))} + +
+ + + Lihat lebih banyak + + + {/* */} +
+
+
)}
@@ -93,3 +113,7 @@ const PromoList = ({ selectedPromo }) => { }; export default PromoList; +// border-radius: 0.5rem; +// border-width: 1px; +// --tw-border-opacity: 1; +// border-color: rgb(219 219 219 / var(--tw-border-opacity)); \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index 7e042a4a..5b91d82f 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -20,7 +20,7 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { quality={100} src='/images/icon_promo/diskon.svg' alt='' - className='h-20 w-20 rounded' + className='h-12 w-12 rounded' />
@@ -46,7 +46,7 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { quality={100} src='/images/icon_promo/silat.svg' alt='' - className='h-20 w-20 rounded' + className='h-12 w-12 rounded' />
@@ -72,7 +72,7 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { quality={100} src='/images/icon_promo/barong.svg' alt='' - className='h-20 w-20 rounded' + className='h-12 w-12 rounded' />
@@ -98,7 +98,7 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { quality={100} src='/images/icon_promo/angklung.svg' alt='' - className='h-20 w-20 rounded' + className='h-12 w-12 rounded' />
-- cgit v1.2.3 From 7c61c990c7987f7c3991e74ce53eb3204e268c75 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 26 Jun 2024 11:01:06 +0700 Subject: add sample for all promotion --- .../modules/promo/components/HeroDiskon.tsx | 137 +++++++++++++++++++++ .../modules/promo/components/PromotinProgram.jsx | 16 +-- 2 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 src-migrate/modules/promo/components/HeroDiskon.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/HeroDiskon.tsx b/src-migrate/modules/promo/components/HeroDiskon.tsx new file mode 100644 index 00000000..6d38c763 --- /dev/null +++ b/src-migrate/modules/promo/components/HeroDiskon.tsx @@ -0,0 +1,137 @@ +import 'swiper/css'; + +import Image from 'next/image'; +import { useEffect, useMemo } from 'react'; +import { useQuery } from 'react-query'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; + +import { getBanner } from '~/services/banner'; +import style from '../styles/hero.module.css'; +import 'swiper/css/navigation'; +import { Autoplay, Navigation, Pagination } from 'swiper'; + +const swiperBanner: SwiperProps = { + modules:[Navigation, Pagination, Autoplay], + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + loop: true, + className: 'h-[400px] w-full', + slidesPerView: 1, + spaceBetween: 10, + navigation:true, +} +const swiperBanner2: SwiperProps = { + modules: [Pagination, Autoplay], + autoplay: { + delay: 5000, + }, + loop: true, + className: 'h-[400px] w-full', + slidesPerView: 1, + spaceBetween: 10, +} + +const Hero = () => { + const bannerQuery = useQuery({ + queryKey: ['banner.all-promo'], + queryFn: () => getBanner({ type: 'banner-promotion' }) + }) + + const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]); + + useEffect(() => { + if (banners.length > 1) { + swiperBanner.slidesPerView = 1; + swiperBanner.loop = true; + } + }, [banners]); + + return ( + +
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+ +
+ + + + ) +} + +export default Hero \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index 5b91d82f..8df99099 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -7,8 +7,8 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { <>
Serba Serbi Promo
-
- {/*
+
+ {/*
onSelectPromo('Diskon')} className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Diskon' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} @@ -34,10 +34,10 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => {
*/} -
+
onSelectPromo('Bundling')} - className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + className={`border h-full p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} >
{
-
+
onSelectPromo('Loading')} - className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} >
{
-
+
onSelectPromo('Merchandise')} - className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} >
Date: Wed, 26 Jun 2024 11:19:27 +0700 Subject: bug fix side & footer banner --- src-migrate/modules/footer-banner/index.tsx | 9 ++++++--- src-migrate/modules/side-banner/index.tsx | 29 +++++++++++++++-------------- 2 files changed, 21 insertions(+), 17 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/footer-banner/index.tsx b/src-migrate/modules/footer-banner/index.tsx index 7db1363c..b214493d 100644 --- a/src-migrate/modules/footer-banner/index.tsx +++ b/src-migrate/modules/footer-banner/index.tsx @@ -1,15 +1,19 @@ import Link from "next/link" +import React, { useMemo } from "react"; import { useQuery } from "react-query" import Image from "~/components/ui/image" import { getBanner } from "~/services/banner" +import { getRandomInt } from '@/utils/getRandomInt' const FooterBanner = () => { const fetchFooterBanner = useQuery({ queryKey: 'footerBanner', queryFn: () => getBanner({ type: 'bottom-search-promotion' }) }) - - const banner = fetchFooterBanner?.data?.[0] || false + // ubah dari static menjadid dynamic dengan menggunakan random index + const length = useMemo(() => fetchFooterBanner.data?.length, [fetchFooterBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchFooterBanner?.data?.[randomIndex] || false; return banner && ( <> @@ -25,5 +29,4 @@ const FooterBanner = () => { ) } - export default FooterBanner \ No newline at end of file diff --git a/src-migrate/modules/side-banner/index.tsx b/src-migrate/modules/side-banner/index.tsx index be52c554..6214edfb 100644 --- a/src-migrate/modules/side-banner/index.tsx +++ b/src-migrate/modules/side-banner/index.tsx @@ -1,29 +1,30 @@ -import Link from "next/link" -import { useQuery } from "react-query" -import Image from "~/components/ui/image" -import { getBanner } from "~/services/banner" +import React, { useMemo } from "react"; +import Link from "next/link"; +import { useQuery } from "react-query"; +import Image from "~/components/ui/image"; +import { getBanner } from "~/services/banner"; +import { getRandomInt } from '@/utils/getRandomInt'; const SideBanner = () => { const fetchSideBanner = useQuery({ queryKey: 'sideBanner', queryFn: () => getBanner({ type: 'side-banner-search' }) - }) - - const banner = fetchSideBanner?.data?.[0] || false + }); + // ubah dari static menjadid dynamic dengan menggunakan random index + const length = useMemo(() => fetchSideBanner.data?.length, [fetchSideBanner.data]); + const randomIndex = useMemo(() => getRandomInt(length), [length]); + const banner = fetchSideBanner?.data?.[randomIndex] || false; return banner && ( <> - {banner.url && ( + {banner.url ? ( {banner.name} - )} - - {!banner.url && ( + ) : ( {banner.name} )} - ) + ); } - -export default SideBanner \ No newline at end of file +export default SideBanner; -- cgit v1.2.3 From eec3440fe52db85b325c600fdd393590dee906fe Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 26 Jun 2024 15:30:48 +0700 Subject: update all promotion --- src-migrate/modules/promo/components/Hero.tsx | 4 +-- src-migrate/modules/promo/components/PromoList.jsx | 37 +++++++--------------- src-migrate/modules/promo/styles/hero.module.css | 2 +- 3 files changed, 14 insertions(+), 29 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index d8bb0be4..ad1d0046 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -8,10 +8,10 @@ import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; import { getBanner } from '~/services/banner'; import style from '../styles/hero.module.css'; import 'swiper/css/navigation'; -import { Navigation, Pagination } from 'swiper'; +import { Navigation, Pagination, Autoplay } from 'swiper'; const swiperBanner: SwiperProps = { - modules:[Navigation, Pagination], + modules:[Navigation, Pagination, Autoplay], autoplay: { delay: 6000, disableOnInteraction: false diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index 7187e9d7..529d54a1 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -4,8 +4,9 @@ import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; import { Swiper, SwiperSlide } from 'swiper/react'; import useDevice from '@/core/hooks/useDevice'; import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; -import usePromoStore from './promoStore'; // Sesuaikan dengan path yang sesuai +import usePromoStore from './promoStore'; import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import Link from '@/core/components/elements/Link/Link' const PromoList = ({ selectedPromo }) => { const { @@ -71,16 +72,16 @@ const PromoList = ({ selectedPromo }) => { } }, [slug, setPromoItems, setPromoData, setIsLoading]); - - - const navigateToPromoPage = () => { - // Fungsi untuk menavigasikan pengguna ke halaman promo yang sesuai dengan slug - window.location.href = '/shop/promo/' + slug; - }; - return (
-

{title}

+
+

{title}

+
+ + Lihat Semua + +
+
{isLoading ? (
@@ -94,26 +95,10 @@ const PromoList = ({ selectedPromo }) => {
))} - -
- - - Lihat lebih banyak - - - {/* */} -
-
- )}
); }; -export default PromoList; -// border-radius: 0.5rem; -// border-width: 1px; -// --tw-border-opacity: 1; -// border-color: rgb(219 219 219 / var(--tw-border-opacity)); \ No newline at end of file +export default PromoList; \ No newline at end of file diff --git a/src-migrate/modules/promo/styles/hero.module.css b/src-migrate/modules/promo/styles/hero.module.css index 70d725be..a5ba6ecc 100644 --- a/src-migrate/modules/promo/styles/hero.module.css +++ b/src-migrate/modules/promo/styles/hero.module.css @@ -1,5 +1,5 @@ .wrapper { - @apply bg-warning-100/50 rounded-xl w-full h-[460px] flex; + @apply rounded-xl w-full h-[460px] flex; } .desc-section { -- cgit v1.2.3 From 595c5cd7b371c61874db47ae42819acca5fc5d16 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 29 Jun 2024 13:46:30 +0700 Subject: update mobile view --- src-migrate/modules/promo/components/Hero.tsx | 86 +++++-- .../modules/promo/components/PromotinProgram.jsx | 280 ++++++++++++++------- 2 files changed, 250 insertions(+), 116 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index ad1d0046..2701250d 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -8,7 +8,10 @@ import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; import { getBanner } from '~/services/banner'; import style from '../styles/hero.module.css'; import 'swiper/css/navigation'; +import 'swiper/css/pagination'; import { Navigation, Pagination, Autoplay } from 'swiper'; +import MobileView from '../../../../src/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; const swiperBanner: SwiperProps = { modules:[Navigation, Pagination, Autoplay], @@ -20,8 +23,18 @@ const swiperBanner: SwiperProps = { className: 'h-[400px] w-full', slidesPerView: 1, spaceBetween: 10, - navigation:true, + pagination:true, } +const swiperBannerMob = { + autoplay: { + delay: 6000, + disableOnInteraction: false, + }, + modules: [Pagination, Autoplay], + loop: true, + className: 'border border-gray_r-6 min-h-full', + slidesPerView: 1, +}; const Hero = () => { const bannerQuery = useQuery({ @@ -35,33 +48,60 @@ const Hero = () => { if (banners.length > 1) { swiperBanner.slidesPerView = 1.1; swiperBanner.loop = true; + swiperBannerMobile.loop = true; } }, [banners]); + const swiperBannerMobile = { + ...swiperBannerMob, + pagination: { dynamicBullets: false, clickable: true }, + }; + return ( -
-
-
Pasti Hemat & Untung Selama Belanja di Indoteknik.com!
-
-
Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!
-
+ <> + +
+
+
Pasti Hemat & Untung Selama Belanja di Indoteknik.com!
+
+
Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!
+
-
- - {banners.map((banner, index) => ( - - {banner.name} - - ))} - -
-
+
+ + {banners.map((banner, index) => ( + + {banner.name} + + ))} + +
+
+
+ + + {banners?.map((banner, index) => ( + + {banner.name} + + ))} + + + + ) } diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index 8df99099..7770d372 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -1,118 +1,212 @@ import React from 'react'; import Image from 'next/image'; -import { InfoIcon } from "lucide-react" +import { InfoIcon } from "lucide-react"; +import MobileView from '../../../../src/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { return ( <>
Serba Serbi Promo
-
- {/*
-
onSelectPromo('Diskon')} - className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Diskon' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- + +
+ {/*
+
onSelectPromo('Diskon')} + className={`border p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Diskon' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Spesial Diskon

+ +
+

+ Harga lebih murah dan pasti makin hemat belinya.. +

+
-
-
-

Spesial Diskon

- +
*/} +
+
onSelectPromo('Bundling')} + className={`border h-full p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Silat

+ +
+

+ Pilihan bundling barang kombinasi Silat. +

-

- Harga lebih murah dan pasti makin hemat belinya.. -

-
*/} -
-
onSelectPromo('Bundling')} - className={`border h-full p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- -
-
-
-

Paket Silat

- +
+
onSelectPromo('Loading')} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Barong

+ +
+

+ Beli banyak barang/partai barang borong. +

-

- Pilihan bundling barang kombinasi Silat. -

-
-
-
onSelectPromo('Loading')} - className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- -
-
-
-

Paket Barong

- +
+
onSelectPromo('Merchandise')} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Angklung

+ +
+

+ Gratis barang promosi/merchandise menang langsung. +

-

- Beli banyak barang/partai barang borong. -

-
-
onSelectPromo('Merchandise')} - className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- + + + + +
+
onSelectPromo('Bundling')} + className={`border h-full p-1 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Silat

+ +
+

+ Pilihan bundling barang kombinasi Silat. +

+
+
-
-
-

Paket Angklung

- + + +
+
onSelectPromo('Loading')} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Barong

+ +
+

+ Beli banyak barang/partai barang borong. +

+
-

- Gratis barang promosi/merchandise menang langsung. -

-
-
-
+ + +
+
onSelectPromo('Merchandise')} + className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+ +
+
+
+

Paket Angklung

+ +
+

+ Gratis barang promosi/merchandise menang langsung. +

+
+
+
+
+ +
); -- cgit v1.2.3 From 556cbc1e5ea1c1ef0170c9a1b8f470a3d92d888e Mon Sep 17 00:00:00 2001 From: "HATEC\\SPVDEV001" Date: Tue, 2 Jul 2024 10:40:06 +0700 Subject: IS SO APPROVAL --- .../product-detail/components/PriceAction.tsx | 75 +++++++++++++++------- .../product-detail/components/ProductDetail.tsx | 12 +++- .../product-detail/stores/useProductDetail.ts | 6 ++ src-migrate/pages/shop/cart/cart.module.css | 4 ++ src-migrate/pages/shop/cart/index.tsx | 2 +- 5 files changed, 73 insertions(+), 26 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index f25847a5..d91ea49c 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -1,15 +1,16 @@ -import style from '../styles/price-action.module.css' +import style from '../styles/price-action.module.css'; -import React, { useEffect } from 'react' -import formatCurrency from '~/libs/formatCurrency' -import { IProductDetail } from '~/types/product' -import { useProductDetail } from '../stores/useProductDetail' -import AddToCart from './AddToCart' -import Link from 'next/link' +import React, { useEffect } from 'react'; +import formatCurrency from '~/libs/formatCurrency'; +import { IProductDetail } from '~/types/product'; +import { useProductDetail } from '../stores/useProductDetail'; +import AddToCart from './AddToCart'; +import Link from 'next/link'; +import { getAuth } from '~/libs/auth'; type Props = { - product: IProductDetail -} + product: IProductDetail; +}; const PriceAction = ({ product }: Props) => { const { @@ -18,15 +19,22 @@ const PriceAction = ({ product }: Props) => { activeVariantId, quantityInput, setQuantityInput, - askAdminUrl - } = useProductDetail() + askAdminUrl, + isApproval, + setIsApproval, + } = useProductDetail(); useEffect(() => { - setActive(product.variants[0]) + setActive(product.variants[0]); }, [product, setActive]); + + return ( -
+
{!!activePrice && activePrice.price > 0 && ( <>
@@ -46,8 +54,8 @@ const PriceAction = ({ product }: Props) => {
- Termasuk PPN: {' '} - Rp {formatCurrency(Math.round(activePrice.price_discount * 1.11))} + Termasuk PPN: Rp{' '} + {formatCurrency(Math.round(activePrice.price_discount * 1.11))}
)} @@ -55,7 +63,11 @@ const PriceAction = ({ product }: Props) => { {!!activePrice && activePrice.price === 0 && ( Hubungi kami untuk dapatkan harga terbaik,{' '} - + klik disini @@ -64,13 +76,30 @@ const PriceAction = ({ product }: Props) => {
- - setQuantityInput(e.target.value)} className={style['quantity-input']} /> - - + + setQuantityInput(e.target.value)} + className={style['quantity-input']} + /> + + {!isApproval && ( + + )}
- ) -} + ); +}; -export default PriceAction \ No newline at end of file +export default PriceAction; diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index 3b1bdbea..6cd72353 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -22,6 +22,7 @@ import PriceAction from './PriceAction' import SimilarBottom from './SimilarBottom' import SimilarSide from './SimilarSide' import VariantList from './VariantList' +import { getAuth } from '~/libs/auth' type Props = { product: IProductDetail @@ -32,7 +33,8 @@ const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST const ProductDetail = ({ product }: Props) => { const { isDesktop, isMobile } = useDevice() const router = useRouter() - const { setAskAdminUrl, askAdminUrl, activeVariantId } = useProductDetail() + const auth = getAuth() + const { setAskAdminUrl, askAdminUrl, activeVariantId, setIsApproval, isApproval } = useProductDetail() useEffect(() => { const createdAskUrl = whatsappUrl({ @@ -48,6 +50,12 @@ const ProductDetail = ({ product }: Props) => { setAskAdminUrl(createdAskUrl) }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) + useEffect(() => { + if (typeof auth === 'object') { + setIsApproval(auth?.feature?.soApproval); + } + }, []); + return ( <>
@@ -115,7 +123,7 @@ const ProductDetail = ({ product }: Props) => { )}
- {!!activeVariantId && } + {!!activeVariantId && !isApproval && }

diff --git a/src-migrate/modules/product-detail/stores/useProductDetail.ts b/src-migrate/modules/product-detail/stores/useProductDetail.ts index 794f0346..2da8835d 100644 --- a/src-migrate/modules/product-detail/stores/useProductDetail.ts +++ b/src-migrate/modules/product-detail/stores/useProductDetail.ts @@ -6,12 +6,14 @@ type State = { activePrice: IProductVariantDetail['price'] | null; quantityInput: string; askAdminUrl: string; + isApproval : boolean; }; type Action = { setActive: (variant: IProductVariantDetail) => void; setQuantityInput: (value: string) => void; setAskAdminUrl: (url: string) => void; + setIsApproval : (value : boolean) => void; }; export const useProductDetail = create((set, get) => ({ @@ -19,6 +21,7 @@ export const useProductDetail = create((set, get) => ({ activePrice: null, quantityInput: '1', askAdminUrl: '', + isApproval : false, setActive: (variant) => { set({ activeVariantId: variant.id, activePrice: variant.price }); }, @@ -28,4 +31,7 @@ export const useProductDetail = create((set, get) => ({ setAskAdminUrl: (url: string) => { set({ askAdminUrl: url }); }, + setIsApproval : (value : boolean) => { + set({ isApproval : value }) + } })); diff --git a/src-migrate/pages/shop/cart/cart.module.css b/src-migrate/pages/shop/cart/cart.module.css index 98a6ac86..806104be 100644 --- a/src-migrate/pages/shop/cart/cart.module.css +++ b/src-migrate/pages/shop/cart/cart.module.css @@ -29,3 +29,7 @@ .summary-buttons { @apply grid grid-cols-2 gap-x-3 mt-6; } + +.summary-buttons-step-approval { + @apply grid grid-cols-1 gap-y-3 mt-6; +} diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index e101b5ad..d89707d2 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -110,7 +110,7 @@ const CartPage = () => { )} -
+
Date: Mon, 8 Jul 2024 14:31:45 +0700 Subject: update mobile view --- src-migrate/modules/promo/components/FlashSale.tsx | 2 +- src-migrate/modules/promo/components/PromoList.jsx | 6 +- .../modules/promo/components/PromotinProgram.jsx | 89 +--------------------- src-migrate/modules/promo/components/Voucher.tsx | 24 +++--- 4 files changed, 21 insertions(+), 100 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/FlashSale.tsx b/src-migrate/modules/promo/components/FlashSale.tsx index dac0365c..16cb7647 100644 --- a/src-migrate/modules/promo/components/FlashSale.tsx +++ b/src-migrate/modules/promo/components/FlashSale.tsx @@ -12,7 +12,7 @@ const FlashSale = dynamic( const FlashSalePromo = ()=> { return( <> -

Bayar Setengahnya!

+

Bayar Setengahnya!

) diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx index 529d54a1..a7356d71 100644 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -73,7 +73,7 @@ const PromoList = ({ selectedPromo }) => { }, [slug, setPromoItems, setPromoData, setIsLoading]); return ( -
+

{title}

@@ -87,10 +87,10 @@ const PromoList = ({ selectedPromo }) => {
) : ( - + {promoData?.map((promotion) => ( -
+
diff --git a/src-migrate/modules/promo/components/PromotinProgram.jsx b/src-migrate/modules/promo/components/PromotinProgram.jsx index 7770d372..33839944 100644 --- a/src-migrate/modules/promo/components/PromotinProgram.jsx +++ b/src-migrate/modules/promo/components/PromotinProgram.jsx @@ -5,14 +5,14 @@ import MobileView from '../../../../src/core/components/views/MobileView'; import DesktopView from '@/core/components/views/DesktopView'; import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; import 'swiper/css'; +import useDevice from '@/core/hooks/useDevice'; const PromotionProgram = ({ selectedPromo, onSelectPromo }) => { + const { isMobile } = useDevice(); return ( <>
Serba Serbi Promo
- -
{/*
onSelectPromo('Diskon')} @@ -39,88 +39,8 @@ const PromotionProgram = ({ selectedPromo, onSelectPromo }) => {
*/} -
-
onSelectPromo('Bundling')} - className={`border h-full p-2 flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Bundling' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- -
-
-
-

Paket Silat

- -
-

- Pilihan bundling barang kombinasi Silat. -

-
-
-
-
-
onSelectPromo('Loading')} - className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Loading' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- -
-
-
-

Paket Barong

- -
-

- Beli banyak barang/partai barang borong. -

-
-
-
-
-
onSelectPromo('Merchandise')} - className={`border p-2 h-full flex items-center gap-x-2 rounded-lg cursor-pointer ${selectedPromo === 'Merchandise' ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} - > -
- -
-
-
-

Paket Angklung

- -
-

- Gratis barang promosi/merchandise menang langsung. -

-
-
-
-
- - - + +
{
-
); diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 14d3c301..397134e8 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -5,25 +5,27 @@ import { getVoucher } from '~/services/voucher' import style from '../styles/voucher.module.css' import Image from 'next/image' import { useToast } from '@chakra-ui/react' +import useDevice from '@/core/hooks/useDevice'; -const swiperVoucher: SwiperProps = { - autoplay: { - delay: 6000, - disableOnInteraction: false - }, - loop: false, - className: 'h-[160px] w-full', - slidesPerView: 3, - spaceBetween: 16 -} const Voucher = () => { + const { isMobile } = useDevice(); const toast = useToast(); const voucherQuery = useQuery({ queryKey: ['voucher.all-voucher'], queryFn: getVoucher }) - + + const swiperVoucher: SwiperProps = { + autoplay: { + delay: 6000, + disableOnInteraction: false + }, + loop: false, + className: 'h-[160px] w-full', + slidesPerView: isMobile ? 1.2 : 3, + spaceBetween: 16 + } const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); const copyText = (text: string) => { -- cgit v1.2.3 From aedf523be9b0faf9cdd7a2231912a074fccdb262 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 15:00:29 +0700 Subject: update salin voucher --- src-migrate/modules/promo/components/Voucher.tsx | 54 ++++++++++++++++++------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 397134e8..c978dc7b 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -7,7 +7,6 @@ import Image from 'next/image' import { useToast } from '@chakra-ui/react' import useDevice from '@/core/hooks/useDevice'; - const Voucher = () => { const { isMobile } = useDevice(); const toast = useToast(); @@ -26,18 +25,50 @@ const Voucher = () => { slidesPerView: isMobile ? 1.2 : 3, spaceBetween: 16 } + const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); const copyText = (text: string) => { - navigator.clipboard.writeText(text) - toast({ - title: 'Salin ke papan klip', - description: 'Kode voucher berhasil disalin', - status: 'success', - duration: 3000, - isClosable: true, - position: 'bottom', - }) + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(text) + .then(() => { + toast({ + title: 'Salin ke papan klip', + description: 'Kode voucher berhasil disalin', + status: 'success', + duration: 3000, + isClosable: true, + position: 'bottom', + }) + }) + .catch(() => { + fallbackCopyTextToClipboard(text); + }); + } else { + fallbackCopyTextToClipboard(text); + } + } + + const fallbackCopyTextToClipboard = (text: string) => { + const textArea = document.createElement("textarea"); + textArea.value = text; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + try { + document.execCommand('copy'); + toast({ + title: 'Salin ke papan klip', + description: 'Kode voucher berhasil disalin', + status: 'success', + duration: 3000, + isClosable: true, + position: 'bottom', + }) + } catch (err) { + console.error('Fallback: Oops, unable to copy', err); + } + document.body.removeChild(textArea); } return ( @@ -78,9 +109,8 @@ const Voucher = () => {
)} - ) } -export default Voucher \ No newline at end of file +export default Voucher -- cgit v1.2.3 From 6a9e4aaaf73677b3b0650e93560c6738781f76c2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 15:13:01 +0700 Subject: update button salin voucher --- src-migrate/modules/promo/components/Voucher.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index c978dc7b..b5a25aa9 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -28,7 +28,8 @@ const Voucher = () => { const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); - const copyText = (text: string) => { + const copyText = (text: string, event: React.MouseEvent) => { + event.preventDefault(); if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text) .then(() => { @@ -100,7 +101,7 @@ const Voucher = () => {
Kode Promo
{voucher.code}
- +
-- cgit v1.2.3 From 120804d474b12743fb7e6fe9a5a3b024e52707d7 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 15:16:34 +0700 Subject: update button salin voucher --- src-migrate/modules/promo/components/Voucher.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index b5a25aa9..9e28a583 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -28,8 +28,7 @@ const Voucher = () => { const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); - const copyText = (text: string, event: React.MouseEvent) => { - event.preventDefault(); + const copyText = (text: string) => { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text) .then(() => { @@ -53,6 +52,17 @@ const Voucher = () => { const fallbackCopyTextToClipboard = (text: string) => { const textArea = document.createElement("textarea"); textArea.value = text; + // Tambahkan style untuk menyembunyikan textArea secara visual + textArea.style.position = 'fixed'; + textArea.style.top = '0'; + textArea.style.left = '0'; + textArea.style.width = '2em'; + textArea.style.height = '2em'; + textArea.style.padding = '0'; + textArea.style.border = 'none'; + textArea.style.outline = 'none'; + textArea.style.boxShadow = 'none'; + textArea.style.background = 'transparent'; document.body.appendChild(textArea); textArea.focus(); textArea.select(); @@ -101,7 +111,7 @@ const Voucher = () => {
Kode Promo
{voucher.code}
- +

-- cgit v1.2.3 From 2fbf5023e0d29765458b3385f354b416d08c42c4 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 15:32:34 +0700 Subject: update position toast --- src-migrate/modules/promo/components/Voucher.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 9e28a583..89b08a01 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -38,7 +38,7 @@ const Voucher = () => { status: 'success', duration: 3000, isClosable: true, - position: 'bottom', + position: 'top', }) }) .catch(() => { -- cgit v1.2.3 From 8ce480fedfa91e16d9adb997311a999aaabaafb2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 16:08:21 +0700 Subject: update testing swiper --- src-migrate/modules/promo/components/PromoList.jsx | 104 ------------------ src-migrate/modules/promo/components/PromoList.tsx | 122 +++++++++++++++++++++ 2 files changed, 122 insertions(+), 104 deletions(-) delete mode 100644 src-migrate/modules/promo/components/PromoList.jsx create mode 100644 src-migrate/modules/promo/components/PromoList.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx deleted file mode 100644 index a7356d71..00000000 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; -import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; -import { Swiper, SwiperSlide } from 'swiper/react'; -import useDevice from '@/core/hooks/useDevice'; -import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; -import usePromoStore from './promoStore'; -import { ChevronRightIcon } from '@heroicons/react/24/outline'; -import Link from '@/core/components/elements/Link/Link' - -const PromoList = ({ selectedPromo }) => { - const { - title, - slug, - promoItems, - promoData, - isLoading, - setTitle, - setSlug, - setPromoItems, - setPromoData, - setIsLoading, - } = usePromoStore(); - - const { isMobile } = useDevice(); - - useEffect(() => { - if (selectedPromo === 'Bundling') { - setTitle('Kombinasi Kilat Pilihan Kami!'); - setSlug('bundling'); - } else if (selectedPromo === 'Loading') { - setTitle('Belanja Borong Pilihan Kami!'); - setSlug('discount_loading'); - } else if (selectedPromo === 'Merchandise') { - setTitle('Gratis Merchandise Spesial Indoteknik'); - setSlug('merchandise'); - } - }, [selectedPromo, setTitle, setSlug]); - - useEffect(() => { - const fetchPromotions = async () => { - setIsLoading(true); - try { - const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); - setPromoItems(items); - - const promoDataPromises = items.map(async (item) => { - try { - const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); - return response; - } catch (fetchError) { - return []; - } - }); - - const promoDataArray = await Promise.all(promoDataPromises); - const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); - setPromoData(mergedPromoData); - - } catch (error) { - console.error('Error fetching promo items:', error); - } finally { - setIsLoading(false); - } - }; - - if (slug) { - setIsLoading(true); - setPromoItems([]); - setPromoData([]); - fetchPromotions(); - } - }, [slug, setPromoItems, setPromoData, setIsLoading]); - - return ( -
-
-

{title}

-
- - Lihat Semua - -
-
- {isLoading ? ( -
- -
- ) : ( - - {promoData?.map((promotion) => ( - -
- -
-
- ))} -
- )} -
- ); -}; - -export default PromoList; \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromoList.tsx b/src-migrate/modules/promo/components/PromoList.tsx new file mode 100644 index 00000000..1b359857 --- /dev/null +++ b/src-migrate/modules/promo/components/PromoList.tsx @@ -0,0 +1,122 @@ +import React, { useEffect, useState } from 'react'; +import ProductPromoCard from '../../product-promo/components/Card'; +import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import useDevice from '@/core/hooks/useDevice'; +import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; +import usePromoStore from './promoStore'; +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import Link from "next/link" +import SwiperCore, { Navigation, Pagination } from 'swiper'; +import { IPromotion } from '~/types/promotion'; + +SwiperCore.use([Navigation, Pagination]); + +interface PromoListProps { + selectedPromo: string; // Tipe selectedPromo ditetapkan sebagai string +} + +const PromoList: React.FC = ({ selectedPromo }) => { + const { isMobile } = useDevice(); + const { + title, + slug, + promoItems, + promoData, + isLoading, + setTitle, + setSlug, + setPromoItems, + setPromoData, + setIsLoading, + } = usePromoStore(); + + + useEffect(() => { + if (selectedPromo === 'Bundling') { + setTitle('Kombinasi Kilat Pilihan Kami!'); + setSlug('bundling'); + } else if (selectedPromo === 'Loading') { + setTitle('Belanja Borong Pilihan Kami!'); + setSlug('discount_loading'); + } else if (selectedPromo === 'Merchandise') { + setTitle('Gratis Merchandise Spesial Indoteknik'); + setSlug('merchandise'); + } + }, [selectedPromo, setTitle, setSlug]); + + useEffect(() => { + const fetchPromotions = async () => { + setIsLoading(true); + try { + const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); + setPromoItems(items); + + const promoDataPromises = items.map(async (item) => { + try { + const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); + return response; + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + + } catch (error) { + console.error('Error fetching promo items:', error); + } finally { + setIsLoading(false); + } + }; + + if (slug) { + setIsLoading(true); + setPromoItems([]); + setPromoData([]); + fetchPromotions(); + } + }, [slug, setPromoItems, setPromoData, setIsLoading]); + + const swiperBanner: SwiperProps = { + modules: [Navigation], + className: 'h-[400px] w-full', + slidesPerView: isMobile ? 1.1 : 3.25, + spaceBetween: 10, + navigation:isMobile? true : false, + allowTouchMove:isMobile? false : true, + }; + return ( + <> +
+
+

{title}

+
+ + Lihat Semua + +
+
+ {isLoading ? ( +
+ +
+ ) : ( + + {promoData?.map((promotion: IPromotion) => ( + +
+ +
+
+ ))} +
+ )} +
+ + ); +}; + +export default PromoList; -- cgit v1.2.3 From 678c5144cb7ac2a3c6bc8dc090e31313809d13a3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 16:53:36 +0700 Subject: update swiper --- src-migrate/modules/promo/components/PromoList.jsx | 110 +++++++++++++++++++ src-migrate/modules/promo/components/PromoList.tsx | 122 --------------------- 2 files changed, 110 insertions(+), 122 deletions(-) create mode 100644 src-migrate/modules/promo/components/PromoList.jsx delete mode 100644 src-migrate/modules/promo/components/PromoList.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx new file mode 100644 index 00000000..e6add893 --- /dev/null +++ b/src-migrate/modules/promo/components/PromoList.jsx @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react'; +import { Button, Skeleton } from '@chakra-ui/react' +import clsxm from "~/libs/clsxm" +import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; +import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import useDevice from '@/core/hooks/useDevice'; +import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; +import usePromoStore from './promoStore'; +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import Link from '@/core/components/elements/Link/Link' + +const PromoList = ({ selectedPromo }) => { + const { + title, + slug, + promoItems, + promoData, + isLoading, + setTitle, + setSlug, + setPromoItems, + setPromoData, + setIsLoading, + } = usePromoStore(); + + const { isMobile } = useDevice(); + + useEffect(() => { + if (selectedPromo === 'Bundling') { + setTitle('Kombinasi Kilat Pilihan Kami!'); + setSlug('bundling'); + } else if (selectedPromo === 'Loading') { + setTitle('Belanja Borong Pilihan Kami!'); + setSlug('discount_loading'); + } else if (selectedPromo === 'Merchandise') { + setTitle('Gratis Merchandise Spesial Indoteknik'); + setSlug('merchandise'); + } + }, [selectedPromo, setTitle, setSlug]); + + useEffect(() => { + const fetchPromotions = async () => { + setIsLoading(true); + try { + const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); + setPromoItems(items); + + const promoDataPromises = items.map(async (item) => { + try { + const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); + return response; + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + + } catch (error) { + console.error('Error fetching promo items:', error); + } finally { + setIsLoading(false); + } + }; + + if (slug) { + setIsLoading(true); + setPromoItems([]); + setPromoData([]); + fetchPromotions(); + } + }, [slug, setPromoItems, setPromoData, setIsLoading]); + + return ( +
+
+

{title}

+
+ + Lihat Semua + +
+
+ {isLoading ? ( +
+ +
+ ) : ( + 0 + })} + > + {promoData?.map((promotion) => ( +
+ +
+ ))} +
+ )} +
+ ); +}; + +export default PromoList; \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromoList.tsx b/src-migrate/modules/promo/components/PromoList.tsx deleted file mode 100644 index 1b359857..00000000 --- a/src-migrate/modules/promo/components/PromoList.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import ProductPromoCard from '../../product-promo/components/Card'; -import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; -import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; -import useDevice from '@/core/hooks/useDevice'; -import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; -import usePromoStore from './promoStore'; -import { ChevronRightIcon } from '@heroicons/react/24/outline'; -import Link from "next/link" -import SwiperCore, { Navigation, Pagination } from 'swiper'; -import { IPromotion } from '~/types/promotion'; - -SwiperCore.use([Navigation, Pagination]); - -interface PromoListProps { - selectedPromo: string; // Tipe selectedPromo ditetapkan sebagai string -} - -const PromoList: React.FC = ({ selectedPromo }) => { - const { isMobile } = useDevice(); - const { - title, - slug, - promoItems, - promoData, - isLoading, - setTitle, - setSlug, - setPromoItems, - setPromoData, - setIsLoading, - } = usePromoStore(); - - - useEffect(() => { - if (selectedPromo === 'Bundling') { - setTitle('Kombinasi Kilat Pilihan Kami!'); - setSlug('bundling'); - } else if (selectedPromo === 'Loading') { - setTitle('Belanja Borong Pilihan Kami!'); - setSlug('discount_loading'); - } else if (selectedPromo === 'Merchandise') { - setTitle('Gratis Merchandise Spesial Indoteknik'); - setSlug('merchandise'); - } - }, [selectedPromo, setTitle, setSlug]); - - useEffect(() => { - const fetchPromotions = async () => { - setIsLoading(true); - try { - const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); - setPromoItems(items); - - const promoDataPromises = items.map(async (item) => { - try { - const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); - return response; - } catch (fetchError) { - return []; - } - }); - - const promoDataArray = await Promise.all(promoDataPromises); - const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); - setPromoData(mergedPromoData); - - } catch (error) { - console.error('Error fetching promo items:', error); - } finally { - setIsLoading(false); - } - }; - - if (slug) { - setIsLoading(true); - setPromoItems([]); - setPromoData([]); - fetchPromotions(); - } - }, [slug, setPromoItems, setPromoData, setIsLoading]); - - const swiperBanner: SwiperProps = { - modules: [Navigation], - className: 'h-[400px] w-full', - slidesPerView: isMobile ? 1.1 : 3.25, - spaceBetween: 10, - navigation:isMobile? true : false, - allowTouchMove:isMobile? false : true, - }; - return ( - <> -
-
-

{title}

-
- - Lihat Semua - -
-
- {isLoading ? ( -
- -
- ) : ( - - {promoData?.map((promotion: IPromotion) => ( - -
- -
-
- ))} -
- )} -
- - ); -}; - -export default PromoList; -- cgit v1.2.3 From ffaf9994e8c47c5a32a2091b7d0949302528ee2e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 17:06:55 +0700 Subject: update button voucher --- src-migrate/modules/promo/components/Voucher.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 89b08a01..64b6b935 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -74,7 +74,7 @@ const Voucher = () => { status: 'success', duration: 3000, isClosable: true, - position: 'bottom', + position: 'top', }) } catch (err) { console.error('Fallback: Oops, unable to copy', err); -- cgit v1.2.3 From 6894d50e6dc50513c0760c2b36e00af8a943c3a2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 11 Jul 2024 11:11:06 +0700 Subject: update tooltip --- src-migrate/modules/product-promo/components/Card.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/components/Card.tsx b/src-migrate/modules/product-promo/components/Card.tsx index 56e29e38..728d23ca 100644 --- a/src-migrate/modules/product-promo/components/Card.tsx +++ b/src-migrate/modules/product-promo/components/Card.tsx @@ -90,10 +90,10 @@ const ProductPromoCard = ({ promotion}: Props) => {
{promotion.name}
- {/*
*/} - {/* Paket {PROMO_CATEGORY[promotion.type.value].alias} */} +
+ Paket {PROMO_CATEGORY[promotion.type.value].alias} - {/*
*/} +
-- cgit v1.2.3 From 8e0eb734a98bc9af7cfa10b2946b78d9019f2c71 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 11 Jul 2024 11:42:10 +0700 Subject: update center tooltip --- src-migrate/modules/product-promo/styles/card.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-promo/styles/card.module.css b/src-migrate/modules/product-promo/styles/card.module.css index faa3b370..4e294f1c 100644 --- a/src-migrate/modules/product-promo/styles/card.module.css +++ b/src-migrate/modules/product-promo/styles/card.module.css @@ -10,7 +10,7 @@ } .badgeType { - @apply p-2 flex gap-x-1.5 rounded-md border border-danger-500 text-danger-500; + @apply p-2 flex gap-x-1.5 rounded-md border border-danger-500 text-danger-500 items-center; } .productSection { -- cgit v1.2.3 From 061400a92ef10ac5f9eb1ac05a7b97bd4b3a0cd5 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 11 Jul 2024 14:09:29 +0700 Subject: update voucher default & coucher by id --- src-migrate/modules/promo/components/Voucher.tsx | 67 ++++++++++++++++++------ src-migrate/services/voucher.ts | 2 +- 2 files changed, 51 insertions(+), 18 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 64b6b935..729d957e 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -1,32 +1,65 @@ -import { useMemo } from 'react' -import { useQuery } from 'react-query' -import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react' -import { getVoucher } from '~/services/voucher' -import style from '../styles/voucher.module.css' -import Image from 'next/image' -import { useToast } from '@chakra-ui/react' +import { useMemo, useState, useEffect } from 'react'; +import { useQuery } from 'react-query'; +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { getVoucherAll } from '~/services/voucher'; +import style from '../styles/voucher.module.css'; +import Image from 'next/image'; +import { useToast } from '@chakra-ui/react'; import useDevice from '@/core/hooks/useDevice'; +import useAuth from '@/core/hooks/useAuth'; +import { getVoucher } from '../../../../src/lib/checkout/api/getVoucher'; -const Voucher = () => { +interface Auth { + id: string; +} +interface Voucher { + id: string; + image: string; + name: string; + description: string; + code: string; +} + +const VoucherComponent = () => { + const [listVouchers, setListVouchers] = useState(null); + const [loadingVoucher, setLoadingVoucher] = useState(true); const { isMobile } = useDevice(); + const auth = useAuth() as unknown as Auth; const toast = useToast(); + + useEffect(() => { + if (!listVouchers && auth?.id) { + (async () => { + try { + const dataVoucher = await getVoucher(auth.id); + setListVouchers(dataVoucher); + } finally { + setLoadingVoucher(false); + } + })(); + } + }, [auth?.id, listVouchers]); + const voucherQuery = useQuery({ queryKey: ['voucher.all-voucher'], - queryFn: getVoucher - }) - + queryFn: getVoucherAll, + }); + const swiperVoucher: SwiperProps = { autoplay: { delay: 6000, - disableOnInteraction: false + disableOnInteraction: false, }, loop: false, className: 'h-[160px] w-full', slidesPerView: isMobile ? 1.2 : 3, - spaceBetween: 16 - } + spaceBetween: 16, + }; - const vouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); + const dataVouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); + + const vouchers = auth?.id? listVouchers : dataVouchers; + const copyText = (text: string) => { if (navigator.clipboard && navigator.clipboard.writeText) { @@ -98,7 +131,7 @@ const Voucher = () => { {!voucherQuery.isLoading && (
- {vouchers.map((voucher) => ( + {vouchers?.map((voucher) => (
{voucher.name} @@ -124,4 +157,4 @@ const Voucher = () => { ) } -export default Voucher +export default VoucherComponent diff --git a/src-migrate/services/voucher.ts b/src-migrate/services/voucher.ts index 447b448e..13d9e2c0 100644 --- a/src-migrate/services/voucher.ts +++ b/src-migrate/services/voucher.ts @@ -1,7 +1,7 @@ import odooApi from '~/libs/odooApi'; import { IVoucher } from '~/types/voucher'; -export const getVoucher = async (): Promise => { +export const getVoucherAll = async (): Promise => { const url = `/api/v1/voucher`; return await odooApi('GET', url); -- cgit v1.2.3 From d584d4620ff633e68fa37f98089d9056012e7b21 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 11 Jul 2024 14:10:18 +0700 Subject: add image promotion on keranjang --- src-migrate/modules/cart/components/Item.tsx | 8 +++++--- src-migrate/types/cart.ts | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index 6ded6373..a757ba37 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -100,13 +100,15 @@ const CartItem = ({ item, editable = true }: Props) => { CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { const image = item?.image || item?.parent?.image + const imageProgram = item?.image_program[0] || item?.parent?.image + - return ( + return ( <> {item.cart_type === 'promotion' && (
- {image && {item.name}} - {!image &&
No Image
} + {imageProgram && {item.name}} + {!imageProgram &&
No Image
}
)} diff --git a/src-migrate/types/cart.ts b/src-migrate/types/cart.ts index 5a2cf4a9..4e3c8b99 100644 --- a/src-migrate/types/cart.ts +++ b/src-migrate/types/cart.ts @@ -23,6 +23,7 @@ export type CartProduct = { }; export type CartItem = { + image_program: string; cart_id: number; quantity: number; selected: boolean; -- cgit v1.2.3 From 46769b859bb56807d47053c3b99810455db12803 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 11 Jul 2024 15:37:19 +0700 Subject: update error code image program --- src-migrate/modules/cart/components/Item.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index a757ba37..a382279f 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -100,8 +100,7 @@ const CartItem = ({ item, editable = true }: Props) => { CartItem.Image = function CartItemImage({ item }: { item: CartItemProps }) { const image = item?.image || item?.parent?.image - const imageProgram = item?.image_program[0] || item?.parent?.image - + const imageProgram = item?.image_program ? item.image_program[0] : item?.parent?.image; return ( <> -- cgit v1.2.3 From 7bec0ceaa7de91f1ba1c9ef18fca3c53d9a7155a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 12 Jul 2024 16:52:14 +0700 Subject: update bug button quotation on cart --- src-migrate/pages/shop/cart/index.tsx | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index d89707d2..7de96425 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -2,8 +2,9 @@ import style from './cart.module.css'; import React, { useEffect, useMemo } from 'react'; import Link from 'next/link'; -import { Button, Tooltip } from '@chakra-ui/react'; - +import { Button, Toast, 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'; @@ -15,6 +16,7 @@ import CartSummaryMobile from '~/modules/cart/components/CartSummaryMobile'; import Image from '~/components/ui/image'; const CartPage = () => { + const router = useRouter(); const auth = getAuth(); const [isStepApproval, setIsStepApproval] = React.useState(false); @@ -52,6 +54,18 @@ const CartPage = () => { } return false; }, [cart]); + + const handleCheckout = (()=>{ + router.push('/shop/checkout'); + }) + + const handleQuotation = (()=>{ + if(hasSelectedPromo || !hasSelected){ + toast.error('Maaf, Barang promo tidak dapat dibuat quotation'); + }else{ + router.push('/shop/quotation'); + } + }) return ( <> @@ -121,8 +135,7 @@ const CartPage = () => { colorScheme='yellow' w='full' isDisabled={hasSelectedPromo || !hasSelected} - as={Link} - href='/shop/quotation' + onClick={handleQuotation} > Quotation @@ -138,8 +151,7 @@ const CartPage = () => { colorScheme='red' w='full' isDisabled={!hasSelected || hasSelectNoPrice} - as={Link} - href='/shop/checkout' + onClick={handleCheckout} > Checkout -- cgit v1.2.3 From 3fe75f5dcaf75e71d29d50f3fb0aa1b5fb443224 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 13 Jul 2024 10:37:34 +0700 Subject: update revisi banner all promotion --- src-migrate/modules/promo/components/Hero.tsx | 33 +++++++++++++-------------- src-migrate/services/promotionProgram.ts | 9 ++++++++ src-migrate/types/promotionProgram.ts | 2 ++ 3 files changed, 27 insertions(+), 17 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index 2701250d..b6e27270 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -4,14 +4,18 @@ import Image from 'next/image'; import { useEffect, useMemo } from 'react'; import { useQuery } from 'react-query'; import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; - -import { getBanner } from '~/services/banner'; import style from '../styles/hero.module.css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import { Navigation, Pagination, Autoplay } from 'swiper'; import MobileView from '../../../../src/core/components/views/MobileView'; import DesktopView from '@/core/components/views/DesktopView'; +import { getPromotionProgramSolr } from '~/services/promotionProgram'; + +interface IPromotionProgram { + banner_s: string; + name_s: string; +} const swiperBanner: SwiperProps = { modules:[Navigation, Pagination, Autoplay], @@ -39,18 +43,13 @@ const swiperBannerMob = { const Hero = () => { const bannerQuery = useQuery({ queryKey: ['banner.all-promo'], - queryFn: () => getBanner({ type: 'banner-promotion' }) - }) - - const banners = useMemo(() => bannerQuery.data || [], [bannerQuery.data]); + queryFn: getPromotionProgramSolr, + }); - useEffect(() => { - if (banners.length > 1) { - swiperBanner.slidesPerView = 1.1; - swiperBanner.loop = true; - swiperBannerMobile.loop = true; - } - }, [banners]); + const banners: IPromotionProgram[] = useMemo( + () => bannerQuery.data?.response?.docs || [], + [bannerQuery.data] + ); const swiperBannerMobile = { ...swiperBannerMob, @@ -72,8 +71,8 @@ const Hero = () => { {banners.map((banner, index) => ( {banner.name} { width={439} height={150} quality={100} - src={banner.image} - alt={banner.name} + src={banner.banner_s} + alt={banner.name_s} className='w-full h-full object-cover object-center rounded-2xl' /> diff --git a/src-migrate/services/promotionProgram.ts b/src-migrate/services/promotionProgram.ts index c8c46c65..92c60943 100644 --- a/src-migrate/services/promotionProgram.ts +++ b/src-migrate/services/promotionProgram.ts @@ -6,3 +6,12 @@ export const getPromotionProgram = async ( const url = `/api/promotion-program/${programId}`; return await fetch(url).then((res) => res.json()); }; + +export const getPromotionProgramSolr = async () => { + console.log(`/solr/promotion-program/select?q=*:*`) + const response = await fetch(`/solr/promotion_programs/select?indent=true&q.op=OR&q=*:*&fq=banner_s:[* TO *]`); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); +}; diff --git a/src-migrate/types/promotionProgram.ts b/src-migrate/types/promotionProgram.ts index 205884b6..c02cbfd0 100644 --- a/src-migrate/types/promotionProgram.ts +++ b/src-migrate/types/promotionProgram.ts @@ -5,4 +5,6 @@ export type IPromotionProgram = { end_time: string; applies_to: string; time_left: number; + image:string; + banner:string; }; -- cgit v1.2.3 From 4ee24671bc23979d7ac18a5390082c0007928540 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 16 Jul 2024 15:17:17 +0700 Subject: add select all cart --- src-migrate/modules/cart/components/Item.tsx | 13 +++++---- src-migrate/modules/cart/components/ItemSelect.tsx | 33 +++++++++++++++------- src-migrate/pages/shop/cart/index.tsx | 33 ++++++++++++++++++---- 3 files changed, 58 insertions(+), 21 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index 6ded6373..a337a47c 100644 --- a/src-migrate/modules/cart/components/Item.tsx +++ b/src-migrate/modules/cart/components/Item.tsx @@ -17,12 +17,14 @@ import CartItemSelect from './ItemSelect' type Props = { item: CartItemProps editable?: boolean + pilihSemuaCart?: boolean } -const CartItem = ({ item, editable = true }: Props) => { +const CartItem = ({ item, editable = true, pilihSemuaCart }: Props) => { + return (
- {item.cart_type === 'promotion' && ( + {item.cart_type === 'promotion' && (
{item.promotion_type?.value && ( @@ -43,7 +45,9 @@ const CartItem = ({ item, editable = true }: Props) => { )}
- {editable && } + {editable && ( + + )}
@@ -87,7 +91,6 @@ const CartItem = ({ item, editable = true }: Props) => { {!editable &&
{item.quantity}
}
-
@@ -153,4 +156,4 @@ CartItem.Skeleton = function CartItemSkeleton(props: SkeletonProps & { count: nu )) } -export default CartItem \ No newline at end of file +export default CartItem diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx index b904a1de..6b6b8f2b 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 } from 'react' +import React, { useState, useEffect } from 'react' import { getAuth } from '~/libs/auth' import { CartItem } from '~/types/cart' @@ -9,15 +9,17 @@ import { useCartStore } from '../stores/useCartStore' type Props = { item: CartItem + itemSelected?: boolean } -const CartItemSelect = ({ item }: Props) => { +const CartItemSelect = ({ item, itemSelected }: Props) => { const auth = getAuth() const { loadCart } = useCartStore() const [isLoad, setIsLoad] = useState(false) + const [isChecked, setIsChecked] = useState(itemSelected ?? true) - const handleChange = async (e: React.ChangeEvent) => { + const handleChange = async (isChecked: boolean) => { if (typeof auth !== 'object') return setIsLoad(true) @@ -26,29 +28,40 @@ const CartItemSelect = ({ item }: Props) => { type: item.cart_type, id: item.id, qty: item.quantity, - selected: e.target.checked + selected: isChecked, }) await loadCart(auth.id) setIsLoad(false) } + useEffect(() => { + if (typeof itemSelected === 'boolean') { + setIsChecked(itemSelected) + handleChange(itemSelected) + } + }, [itemSelected]) + + const handleCheckboxChange = (e: React.ChangeEvent) => { + const { checked } = e.target + setIsChecked(checked) + handleChange(checked) + } + return (
- {isLoad && ( - - )} + {isLoad && } {!isLoad && ( )}
) } -export default CartItemSelect \ No newline at end of file +export default CartItemSelect diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 7de96425..1f89c7a3 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -1,8 +1,8 @@ import style from './cart.module.css'; -import React, { useEffect, useMemo } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import Link from 'next/link'; -import { Button, Toast, Tooltip } from '@chakra-ui/react'; +import { Button, Checkbox, Toast, Tooltip } from '@chakra-ui/react'; import { toast } from 'react-hot-toast'; import { useRouter } from 'next/router'; import { getAuth } from '~/libs/auth'; @@ -19,6 +19,9 @@ const CartPage = () => { const router = useRouter(); const auth = getAuth(); const [isStepApproval, setIsStepApproval] = React.useState(false); + const [isSelectedAll, setIsSelectedAll] = useState(false); + const [isButtonChek, setIsButtonChek] = useState(false); + const [buttonSelectNow, setButtonSelectNow] = useState(true); const { loadCart, cart, summary } = useCartStore(); @@ -29,8 +32,9 @@ const CartPage = () => { loadCart(auth.id); setIsStepApproval(auth?.feature?.soApproval); } - }, [auth, loadCart, cart]); - + }, [auth, loadCart, cart, isButtonChek, ]); + + const hasSelectedPromo = useMemo(() => { if (!cart) return false; for (const item of cart.products) { @@ -67,10 +71,26 @@ const CartPage = () => { } }) + const handleChange = (()=>{ + setButtonSelectNow(!buttonSelectNow) + setIsSelectedAll(!isSelectedAll) + setIsButtonChek(!isButtonChek) + }) + return ( <>
Keranjang Belanja
- +
+

+ {buttonSelectNow? "Select all" : "Unchek all" } +

+
@@ -81,8 +101,9 @@ const CartPage = () => {
{cart?.products.map((item) => ( - + ))} + {cart?.products?.length === 0 && (
-- cgit v1.2.3 From 9525ae860e320358a7897cf5fb9c4e4fb7c203e1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 16 Jul 2024 15:35:08 +0700 Subject: update delete console log --- src-migrate/services/promotionProgram.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/services/promotionProgram.ts b/src-migrate/services/promotionProgram.ts index 92c60943..8bf2a0bd 100644 --- a/src-migrate/services/promotionProgram.ts +++ b/src-migrate/services/promotionProgram.ts @@ -8,7 +8,6 @@ export const getPromotionProgram = async ( }; export const getPromotionProgramSolr = async () => { - console.log(`/solr/promotion-program/select?q=*:*`) const response = await fetch(`/solr/promotion_programs/select?indent=true&q.op=OR&q=*:*&fq=banner_s:[* TO *]`); if (!response.ok) { throw new Error('Network response was not ok'); -- cgit v1.2.3 From 0f62655a7fa63a27f3af418108f44e3bc4bab980 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 16 Jul 2024 16:56:58 +0700 Subject: update location select all --- src-migrate/pages/shop/cart/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 1f89c7a3..2ecf1c03 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -80,6 +80,7 @@ const CartPage = () => { return ( <>
Keranjang Belanja
+
{ {buttonSelectNow? "Select all" : "Unchek all" }

-
-- cgit v1.2.3 From 60060b517651e1122a638a3f592017879a0e9e63 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 11:07:00 +0700 Subject: update all promotion --- src-migrate/modules/promo/components/FlashSale.tsx | 2 +- src-migrate/modules/promo/components/PromoList.jsx | 110 ----------------- src-migrate/modules/promo/components/PromoList.tsx | 135 +++++++++++++++++++++ 3 files changed, 136 insertions(+), 111 deletions(-) delete mode 100644 src-migrate/modules/promo/components/PromoList.jsx create mode 100644 src-migrate/modules/promo/components/PromoList.tsx (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/FlashSale.tsx b/src-migrate/modules/promo/components/FlashSale.tsx index 16cb7647..05bf1e11 100644 --- a/src-migrate/modules/promo/components/FlashSale.tsx +++ b/src-migrate/modules/promo/components/FlashSale.tsx @@ -12,7 +12,7 @@ const FlashSale = dynamic( const FlashSalePromo = ()=> { return( <> -

Bayar Setengahnya!

+

) diff --git a/src-migrate/modules/promo/components/PromoList.jsx b/src-migrate/modules/promo/components/PromoList.jsx deleted file mode 100644 index e6add893..00000000 --- a/src-migrate/modules/promo/components/PromoList.jsx +++ /dev/null @@ -1,110 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Button, Skeleton } from '@chakra-ui/react' -import clsxm from "~/libs/clsxm" -import ProductPromoCard from '../../../../src-migrate/modules/product-promo/components/Card'; -import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; -import { Swiper, SwiperSlide } from 'swiper/react'; -import useDevice from '@/core/hooks/useDevice'; -import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; -import usePromoStore from './promoStore'; -import { ChevronRightIcon } from '@heroicons/react/24/outline'; -import Link from '@/core/components/elements/Link/Link' - -const PromoList = ({ selectedPromo }) => { - const { - title, - slug, - promoItems, - promoData, - isLoading, - setTitle, - setSlug, - setPromoItems, - setPromoData, - setIsLoading, - } = usePromoStore(); - - const { isMobile } = useDevice(); - - useEffect(() => { - if (selectedPromo === 'Bundling') { - setTitle('Kombinasi Kilat Pilihan Kami!'); - setSlug('bundling'); - } else if (selectedPromo === 'Loading') { - setTitle('Belanja Borong Pilihan Kami!'); - setSlug('discount_loading'); - } else if (selectedPromo === 'Merchandise') { - setTitle('Gratis Merchandise Spesial Indoteknik'); - setSlug('merchandise'); - } - }, [selectedPromo, setTitle, setSlug]); - - useEffect(() => { - const fetchPromotions = async () => { - setIsLoading(true); - try { - const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); - setPromoItems(items); - - const promoDataPromises = items.map(async (item) => { - try { - const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); - return response; - } catch (fetchError) { - return []; - } - }); - - const promoDataArray = await Promise.all(promoDataPromises); - const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); - setPromoData(mergedPromoData); - - } catch (error) { - console.error('Error fetching promo items:', error); - } finally { - setIsLoading(false); - } - }; - - if (slug) { - setIsLoading(true); - setPromoItems([]); - setPromoData([]); - fetchPromotions(); - } - }, [slug, setPromoItems, setPromoData, setIsLoading]); - - return ( -
-
-

{title}

-
- - Lihat Semua - -
-
- {isLoading ? ( -
- -
- ) : ( - 0 - })} - > - {promoData?.map((promotion) => ( -
- -
- ))} -
- )} -
- ); -}; - -export default PromoList; \ No newline at end of file diff --git a/src-migrate/modules/promo/components/PromoList.tsx b/src-migrate/modules/promo/components/PromoList.tsx new file mode 100644 index 00000000..42725034 --- /dev/null +++ b/src-migrate/modules/promo/components/PromoList.tsx @@ -0,0 +1,135 @@ +import React, { useEffect, useState } from 'react'; +import { Button, Skeleton } from '@chakra-ui/react' +import clsxm from "~/libs/clsxm" +import ProductPromoCard from '../../product-promo/components/Card'; +import { fetchPromoItemsSolr } from '../../../../src/api/promoApi'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import SwiperCore, { Navigation, Pagination } from 'swiper'; +import useDevice from '@/core/hooks/useDevice'; +import LogoSpinner from '../../../../src/core/components/elements/Spinner/LogoSpinner'; +import usePromoStore from './promoStore'; +import Link from "next/link" +import { IPromotion } from '~/types/promotion'; +interface PromoListProps { + selectedPromo: string; // Tipe selectedPromo ditetapkan sebagai string +} + +const PromoList: React.FC = ({ selectedPromo }) => { + const { + title, + slug, + promoItems, + promoData, + isLoading, + setTitle, + setSlug, + setPromoItems, + setPromoData, + setIsLoading, + } = usePromoStore(); + + const { isMobile, isDesktop } = useDevice(); + + const swiperBanner = { + modules: [Navigation], + className: 'h-[400px] w-full', + slidesPerView: isMobile ? 1.1 : 3.25, + spaceBetween: 10, + navigation:isMobile? true : false, + allowTouchMove:isMobile? false : true, + }; + + useEffect(() => { + if (selectedPromo === 'Bundling') { + setTitle('Kombinasi Kilat Pilihan Kami!'); + setSlug('bundling'); + } else if (selectedPromo === 'Loading') { + setTitle('Belanja Borong Pilihan Kami!'); + setSlug('discount_loading'); + } else if (selectedPromo === 'Merchandise') { + setTitle('Gratis Merchandise Spesial Indoteknik'); + setSlug('merchandise'); + } + }, [selectedPromo, setTitle, setSlug]); + + useEffect(() => { + const fetchPromotions = async () => { + setIsLoading(true); + try { + const items = await fetchPromoItemsSolr(`type_value_s:${slug}`, 0, 10); + setPromoItems(items); + + const promoDataPromises = items.map(async (item) => { + try { + const response = await fetchPromoItemsSolr(`id:${item.id}`, 0, 10); + return response; + } catch (fetchError) { + return []; + } + }); + + const promoDataArray = await Promise.all(promoDataPromises); + const mergedPromoData = promoDataArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []); + setPromoData(mergedPromoData); + + } catch (error) { + console.error('Error fetching promo items:', error); + } finally { + setIsLoading(false); + } + }; + + if (slug) { + setIsLoading(true); + setPromoItems([]); + setPromoData([]); + fetchPromotions(); + } + }, [slug, setPromoItems, setPromoData, setIsLoading]); + + return ( +
+
+

{title}

+
+ + Lihat Semua + +
+
+ {isLoading ? ( +
+ +
+ ) : ( + 0 + })} + > + {isDesktop && ( + + {promoData?.map((promotion: IPromotion) => ( + +
+ +
+
+ ))} +
+ )} + {isMobile && (promoData?.map((promotion: IPromotion) => ( +
+ +
+ )))} + +
+ )} +
+ ); +}; + +export default PromoList; \ No newline at end of file -- cgit v1.2.3 From a42272ae50a5e8661db5ae534f08f475efb05665 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 14:09:51 +0700 Subject: update all promotion --- src-migrate/modules/promo/components/FlashSale.tsx | 1 - src-migrate/modules/promo/components/Hero.tsx | 24 ++++++++++------------ 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/FlashSale.tsx b/src-migrate/modules/promo/components/FlashSale.tsx index 05bf1e11..c0259396 100644 --- a/src-migrate/modules/promo/components/FlashSale.tsx +++ b/src-migrate/modules/promo/components/FlashSale.tsx @@ -12,7 +12,6 @@ const FlashSale = dynamic( const FlashSalePromo = ()=> { return( <> -

) diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index b6e27270..7eb84270 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -10,11 +10,11 @@ import 'swiper/css/pagination'; import { Navigation, Pagination, Autoplay } from 'swiper'; import MobileView from '../../../../src/core/components/views/MobileView'; import DesktopView from '@/core/components/views/DesktopView'; -import { getPromotionProgramSolr } from '~/services/promotionProgram'; +import {bannerApi} from '../../../../src/api/bannerApi' interface IPromotionProgram { - banner_s: string; - name_s: string; + image: string ; + name: string; } const swiperBanner: SwiperProps = { @@ -41,20 +41,18 @@ const swiperBannerMob = { }; const Hero = () => { - const bannerQuery = useQuery({ - queryKey: ['banner.all-promo'], - queryFn: getPromotionProgramSolr, - }); + const heroBanner = useQuery('heroBannerSecondary', bannerApi({ type: 'banner-promotion' })) const banners: IPromotionProgram[] = useMemo( - () => bannerQuery.data?.response?.docs || [], - [bannerQuery.data] + () => heroBanner?.data || [], + [heroBanner.data] ); const swiperBannerMobile = { ...swiperBannerMob, pagination: { dynamicBullets: false, clickable: true }, }; + return ( <> @@ -71,8 +69,8 @@ const Hero = () => { {banners.map((banner, index) => ( {banner.name_s} { width={439} height={150} quality={100} - src={banner.banner_s} - alt={banner.name_s} + src={banner.image} + alt={banner.name} className='w-full h-full object-cover object-center rounded-2xl' /> -- cgit v1.2.3 From 30142ab6c6f37fb381264efd0dc94aa997b1a278 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 15:14:43 +0700 Subject: update dynamic description --- src-migrate/modules/promo/components/Hero.tsx | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index 7eb84270..b91288dd 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -13,6 +13,8 @@ import DesktopView from '@/core/components/views/DesktopView'; import {bannerApi} from '../../../../src/api/bannerApi' interface IPromotionProgram { + headline_banner: string; + description_banner: string; image: string ; name: string; } @@ -58,27 +60,26 @@ const Hero = () => { <>
-
-
Pasti Hemat & Untung Selama Belanja di Indoteknik.com!
-
-
Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!
-
- -
{banners.map((banner, index) => ( - - {banner.name} + +
+
{banner.headline_banner? banner.headline_banner : "Pasti Hemat & Untung Selama Belanja di Indoteknik.com!"}
+
+
{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!"}
+
+
+ {banner.name} +
))} -
-- cgit v1.2.3 From e32af31e19d38bf5f94dc229bae012c5c5aea720 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 16:25:58 +0700 Subject: update slug banner and card voucher --- src-migrate/modules/promo/components/Hero.tsx | 2 +- src-migrate/modules/promo/styles/voucher.module.css | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index b91288dd..801136e9 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -43,7 +43,7 @@ const swiperBannerMob = { }; const Hero = () => { - const heroBanner = useQuery('heroBannerSecondary', bannerApi({ type: 'banner-promotion' })) + const heroBanner = useQuery('heroBannerSecondary', bannerApi({ type: 'banner-semua-promo' })) const banners: IPromotionProgram[] = useMemo( () => heroBanner?.data || [], diff --git a/src-migrate/modules/promo/styles/voucher.module.css b/src-migrate/modules/promo/styles/voucher.module.css index 24d3aac2..bcb8169f 100644 --- a/src-migrate/modules/promo/styles/voucher.module.css +++ b/src-migrate/modules/promo/styles/voucher.module.css @@ -7,11 +7,11 @@ } .voucher-card { - @apply w-full h-full rounded-xl border border-gray-200 shadow-md p-4 flex gap-x-4; + @apply w-11/12 h-3/4 rounded-xl border items-center border-gray-200 shadow-md p-4 flex gap-x-4 ; } .voucher-image { - @apply bg-gray-100 rounded-lg w-4/12 h-full object-contain object-center; + @apply bg-gray-100 rounded-lg w-4/12 h-fit object-contain object-center; } .voucher-content { @@ -27,7 +27,7 @@ } .voucher-bottom { - @apply flex justify-between mt-auto; + @apply flex justify-between mt-2; } .voucher-code-desc { -- cgit v1.2.3 From ec726a8d106992b4e4a9fd79863b64ea2112a218 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 16:49:26 +0700 Subject: update voucher --- src-migrate/modules/promo/components/Voucher.tsx | 4 ++-- src-migrate/modules/promo/styles/voucher.module.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Voucher.tsx b/src-migrate/modules/promo/components/Voucher.tsx index 729d957e..e5877e51 100644 --- a/src-migrate/modules/promo/components/Voucher.tsx +++ b/src-migrate/modules/promo/components/Voucher.tsx @@ -52,8 +52,8 @@ const VoucherComponent = () => { }, loop: false, className: 'h-[160px] w-full', - slidesPerView: isMobile ? 1.2 : 3, - spaceBetween: 16, + slidesPerView: isMobile ? 1.2 : 3.2, + spaceBetween: 2, }; const dataVouchers = useMemo(() => voucherQuery.data || [], [voucherQuery.data]); diff --git a/src-migrate/modules/promo/styles/voucher.module.css b/src-migrate/modules/promo/styles/voucher.module.css index bcb8169f..22d07f91 100644 --- a/src-migrate/modules/promo/styles/voucher.module.css +++ b/src-migrate/modules/promo/styles/voucher.module.css @@ -7,7 +7,7 @@ } .voucher-card { - @apply w-11/12 h-3/4 rounded-xl border items-center border-gray-200 shadow-md p-4 flex gap-x-4 ; + @apply w-full md:w-11/12 h-3/4 rounded-xl border items-center border-gray-200 shadow-md p-4 flex gap-x-4 ; } .voucher-image { -- cgit v1.2.3 From 795e774bfcf19e474ec4f4158856da0d1629bc3d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 24 Jul 2024 10:14:46 +0700 Subject: update all promotion --- src-migrate/pages/shop/promo/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/promo/index.tsx b/src-migrate/pages/shop/promo/index.tsx index 7c4df2c1..febe31a4 100644 --- a/src-migrate/pages/shop/promo/index.tsx +++ b/src-migrate/pages/shop/promo/index.tsx @@ -16,8 +16,6 @@ const PromoPage = () => { - - { -

+

-- cgit v1.2.3 From 8c848cf35811ee95e88ce03745ee25315172d758 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 1 Aug 2024 15:29:17 +0700 Subject: update unchek all cart --- src-migrate/modules/cart/components/Item.tsx | 4 +- src-migrate/modules/cart/components/ItemSelect.tsx | 33 ++----- src-migrate/pages/shop/cart/index.tsx | 108 +++++++++++---------- 3 files changed, 70 insertions(+), 75 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/Item.tsx b/src-migrate/modules/cart/components/Item.tsx index a337a47c..88a6a975 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 (
@@ -46,7 +46,7 @@ const CartItem = ({ item, editable = true, pilihSemuaCart }: Props) => {
{editable && ( - + )}
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(false) - const [isChecked, setIsChecked] = useState(itemSelected ?? true) - const handleChange = async (isChecked: boolean) => { + const handleChange = async (e: React.ChangeEvent) => { 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) => { - const { checked } = e.target - setIsChecked(checked) - handleChange(checked) - } - return (
- {isLoad && } + {isLoad && ( + + )} {!isLoad && ( )}
) } -export default CartItemSelect +export default CartItemSelect \ No newline at end of file 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(false); - const [isButtonChek, setIsButtonChek] = useState(false); - const [buttonSelectNow, setButtonSelectNow] = useState(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) => { + 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 ( <>
Keranjang Belanja
-
-

- {buttonSelectNow? "Select all" : "Unchek all" } -

-
+
+ +

+ {hasSelectedAll ? "Unchek all" : "Select all"} +

+
- {!cart && } + {!cart && }
{cart?.products.map((item) => ( - + ))} - {cart?.products?.length === 0 && (
@@ -145,7 +153,7 @@ const CartPage = () => { )} -
+
Date: Thu, 1 Aug 2024 16:19:45 +0700 Subject: update all promo --- src-migrate/modules/promo/components/Hero.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src-migrate') 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 ( <> @@ -64,9 +65,9 @@ const Hero = () => { {banners.map((banner, index) => (
-
{banner.headline_banner? banner.headline_banner : "Pasti Hemat & Untung Selama Belanja di Indoteknik.com!"}
+
{banner.headlineBanner? banner.headlineBanner : "Pasti Hemat & Untung Selama Belanja di Indoteknik.com!"}
-
{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!"}
+
{banner.descriptionBanner? banner.descriptionBanner : "Cari paket yang kami sediakan dengan penawaran harga & Nikmati kemudahan dalam setiap transaksi dengan fitur lengkap Pembayaran hingga barang sampai!"}
{ alt={banner.name} width={666} height={450} - quality={100} + quality={90} className='w-full h-full object-fit object-center rounded-2xl' />
-- cgit v1.2.3 From 516db9ccbaf00bfc5b668ea425aa74b9ffe820c6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 1 Aug 2024 16:46:29 +0700 Subject: delete console log --- src-migrate/modules/promo/components/Hero.tsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/promo/components/Hero.tsx b/src-migrate/modules/promo/components/Hero.tsx index 110052ba..c5f0afad 100644 --- a/src-migrate/modules/promo/components/Hero.tsx +++ b/src-migrate/modules/promo/components/Hero.tsx @@ -55,8 +55,6 @@ const Hero = () => { pagination: { dynamicBullets: false, clickable: true }, }; - console.log("banner",banners) - // console.log("headlineBanner",banners[0].headlineBanner) return ( <> -- cgit v1.2.3 From 622b27a302ba0736984d95beb761bf6a5f48614b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 08:58:03 +0700 Subject: delete console log --- src-migrate/hooks/useUtmSource.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/hooks/useUtmSource.ts b/src-migrate/hooks/useUtmSource.ts index a72fae36..43fbdcae 100644 --- a/src-migrate/hooks/useUtmSource.ts +++ b/src-migrate/hooks/useUtmSource.ts @@ -7,7 +7,7 @@ const useUtmSource = () => { const [source, setSource] = useState(); useEffect(() => { - console.log(router.pathname); + // console.log(router.pathname); if (router.pathname) { setSource(UTM_SOURCE[router.pathname as keyof typeof UTM_SOURCE]); -- cgit v1.2.3 From 35204954ac02efd1497715dec3d2695fdd7976f8 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 10:00:34 +0700 Subject: update form --- src-migrate/modules/register/components/Form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/register/components/Form.tsx b/src-migrate/modules/register/components/Form.tsx index 4baaf380..b834f97a 100644 --- a/src-migrate/modules/register/components/Form.tsx +++ b/src-migrate/modules/register/components/Form.tsx @@ -168,7 +168,7 @@ const Form = () => { -- cgit v1.2.3 From e4bbb9cf1b1918ce33e6c2ee22acf17b49d0fcd1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 11:19:10 +0700 Subject: add delete all cart button --- src-migrate/pages/shop/cart/index.tsx | 58 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 0eb9c554..cb0156f1 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -2,7 +2,7 @@ import style from './cart.module.css'; import React, { useEffect, useMemo, useState } from 'react'; import Link from 'next/link'; -import { Button, Checkbox, Tooltip } from '@chakra-ui/react'; +import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react'; import { toast } from 'react-hot-toast'; import { useRouter } from 'next/router'; import { getAuth } from '~/libs/auth'; @@ -24,6 +24,7 @@ const CartPage = () => { const [isSelectedAll, setIsSelectedAll] = useState(false); const [isButtonChek, setIsButtonChek] = useState(false); const [buttonSelectNow, setButtonSelectNow] = useState(true); + const [isLoad, setIsLoad] = useState(false) const { loadCart, cart, summary } = useCartStore(); const useDivvice = useDevice(); @@ -69,7 +70,7 @@ const CartPage = () => { const handleChange = async (e: React.ChangeEvent) => { if (typeof auth !== 'object' || !cart) return; - + setIsLoad(true) const newSelected = e.target.checked; setIsSelectedAll(newSelected); @@ -83,23 +84,54 @@ const CartPage = () => { }); } await loadCart(auth.id); + setIsLoad(false) + } + + const handleDelete = () => { + console.log("delete data"); } return ( <>
Keranjang Belanja
-
- -

- {hasSelectedAll ? "Unchek all" : "Select all"} -

+
+
+ {isLoad && ( + + )} + {!isLoad && ( + + )} +

+ {hasSelectedAll ? "Unchek all" : "Select all"} +

+
+
+ + + +
-- cgit v1.2.3 From 30a686e4140a503d88142e71c25bc517092b4bd5 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 13:23:30 +0700 Subject: update delete button --- src-migrate/pages/shop/cart/index.tsx | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index cb0156f1..4586c65c 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -15,7 +15,8 @@ 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' +import { deleteUserCart ,upsertUserCart } from '~/services/cart' +import { Trash2Icon } from 'lucide-react'; const CartPage = () => { const router = useRouter(); @@ -25,7 +26,7 @@ const CartPage = () => { const [isButtonChek, setIsButtonChek] = useState(false); const [buttonSelectNow, setButtonSelectNow] = useState(true); const [isLoad, setIsLoad] = useState(false) - + const [isLoadDelete, setIsLoadDelete] = useState(false) const { loadCart, cart, summary } = useCartStore(); const useDivvice = useDevice(); @@ -87,8 +88,17 @@ const CartPage = () => { setIsLoad(false) } - const handleDelete = () => { - console.log("delete data"); + const handleDelete = async () => { + if (typeof auth !== 'object' || !cart) return; + + setIsLoadDelete(true) + for (const item of cart.products) { + if(item.selected === true){ + await deleteUserCart(auth.id, [item.cart_id]) + await loadCart(auth.id) + } + } + setIsLoadDelete(false) } return ( @@ -128,7 +138,11 @@ const CartPage = () => { isDisabled={!hasSelected || hasSelectNoPrice} onClick={handleDelete} > - Hapus Barang + {isLoadDelete && } + {!isLoadDelete && } +

+ Hapus Barang +

-- cgit v1.2.3 From 1f5adcf66c175dde3ce3694eedb1acddb05613e5 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 13:30:56 +0700 Subject: add refresh cart after delete chart --- src-migrate/pages/shop/cart/index.tsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 4586c65c..d28e8c4b 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -17,6 +17,7 @@ import Image from '~/components/ui/image'; import { CartItem } from '~/types/cart' import { deleteUserCart ,upsertUserCart } from '~/services/cart' import { Trash2Icon } from 'lucide-react'; +import { useProductCartContext } from '@/contexts/ProductCartContext' const CartPage = () => { const router = useRouter(); @@ -29,6 +30,7 @@ const CartPage = () => { const [isLoadDelete, setIsLoadDelete] = useState(false) const { loadCart, cart, summary } = useCartStore(); const useDivvice = useDevice(); + const { setRefreshCart } = useProductCartContext() useEffect(() => { if (typeof auth === 'object' && !cart) { @@ -99,6 +101,7 @@ const CartPage = () => { } } setIsLoadDelete(false) + setRefreshCart(true) } return ( -- cgit v1.2.3 From 455e7b8daddec77f95929a7cb0eb31e8fa934e6d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 14:14:53 +0700 Subject: update unchek cart --- src-migrate/pages/shop/cart/index.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index d28e8c4b..2204857a 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -31,6 +31,20 @@ const CartPage = () => { const { loadCart, cart, summary } = useCartStore(); const useDivvice = useDevice(); const { setRefreshCart } = useProductCartContext() + const [isTop, setIsTop] = useState(true); + + + useEffect(() => { + const handleScroll = () => { + console.log("lokasi",window.scrollY) + setIsTop(window.scrollY < 200); + }; + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); useEffect(() => { if (typeof auth === 'object' && !cart) { @@ -108,7 +122,7 @@ const CartPage = () => { <>
Keranjang Belanja
-
+
{isLoad && ( @@ -130,7 +144,6 @@ const CartPage = () => { - +
+
Keranjang Belanja
+
+
+
+ {isLoad && ( + + )} + {!isLoad && ( + + )} +

+ {hasSelectedAll ? "Unchek all" : "Select all"} +

+
+ + + +
+
+
-- cgit v1.2.3 From 4e25a60e9c3cf93cc1faf77a5bf1ad7e6f0555ec Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 3 Aug 2024 08:58:01 +0700 Subject: update view & add refresh cart --- src-migrate/modules/cart/components/ItemAction.tsx | 4 +++- src-migrate/pages/shop/cart/index.tsx | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/ItemAction.tsx b/src-migrate/modules/cart/components/ItemAction.tsx index e73d507b..e5e7f314 100644 --- a/src-migrate/modules/cart/components/ItemAction.tsx +++ b/src-migrate/modules/cart/components/ItemAction.tsx @@ -11,6 +11,7 @@ import { deleteUserCart, upsertUserCart } from '~/services/cart' import { useDebounce } from 'usehooks-ts' import { useCartStore } from '../stores/useCartStore' +import { useProductCartContext } from '@/contexts/ProductCartContext' type Props = { @@ -19,7 +20,7 @@ type Props = { const CartItemAction = ({ item }: Props) => { const auth = getAuth() - + const { setRefreshCart } = useProductCartContext() const [isLoadDelete, setIsLoadDelete] = useState(false) const [isLoadQuantity, setIsLoadQuantity] = useState(false) @@ -36,6 +37,7 @@ const CartItemAction = ({ item }: Props) => { await deleteUserCart(auth.id, [item.cart_id]) await loadCart(auth.id) setIsLoadDelete(false) + setRefreshCart(true) } const decreaseQty = () => { setQuantity((quantity) => quantity -= 1) } diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 8d9ea91c..73b002b6 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -118,7 +118,7 @@ const CartPage = () => { return ( <> -
+
Keranjang Belanja
@@ -150,7 +150,7 @@ const CartPage = () => { variant='outline' colorScheme='red' w='full' - isDisabled={!hasSelected || hasSelectNoPrice} + isDisabled={!hasSelected} onClick={handleDelete} > {isLoadDelete && } -- cgit v1.2.3 From 865f509a8b45c6db195661f35417623572d33cea Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 3 Aug 2024 13:33:59 +0700 Subject: update unchek cart --- src-migrate/modules/cart/components/ItemSelect.tsx | 28 ++++--- src-migrate/modules/cart/stores/useCartStore.ts | 12 ++- src-migrate/pages/shop/cart/index.tsx | 97 +++++++++++++++++----- 3 files changed, 104 insertions(+), 33 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/cart/components/ItemSelect.tsx b/src-migrate/modules/cart/components/ItemSelect.tsx index b904a1de..d4a1b537 100644 --- a/src-migrate/modules/cart/components/ItemSelect.tsx +++ b/src-migrate/modules/cart/components/ItemSelect.tsx @@ -13,23 +13,25 @@ type Props = { const CartItemSelect = ({ item }: Props) => { const auth = getAuth() - const { loadCart } = useCartStore() + const { updateCartItem, cart } = useCartStore() const [isLoad, setIsLoad] = useState(false) const handleChange = async (e: React.ChangeEvent) => { - if (typeof auth !== 'object') return - - setIsLoad(true) - await upsertUserCart({ - userId: auth.id, - type: item.cart_type, - id: item.id, - qty: item.quantity, - selected: e.target.checked - }) - await loadCart(auth.id) - setIsLoad(false) + if (typeof auth !== 'object' || !cart) return + + setIsLoad(true); + const updatedCartItems = cart.products.map(cartItem => + cartItem.id === item.id + ? { ...cartItem, selected: e.target.checked } + : cartItem + ); + + // Update the entire cart + const updatedCart = { ...cart, products: updatedCartItems }; + updateCartItem(updatedCart); + + setIsLoad(false); } return ( diff --git a/src-migrate/modules/cart/stores/useCartStore.ts b/src-migrate/modules/cart/stores/useCartStore.ts index 3d9a0aed..3b50ec32 100644 --- a/src-migrate/modules/cart/stores/useCartStore.ts +++ b/src-migrate/modules/cart/stores/useCartStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { CartProps } from '~/types/cart'; +import { CartItem, CartProps } from '~/types/cart'; import { getUserCart } from '~/services/cart'; type State = { @@ -16,6 +16,7 @@ type State = { type Action = { loadCart: (userId: number) => Promise; + updateCartItem: (updateCart: CartProps) => void; }; export const useCartStore = create((set, get) => ({ @@ -39,6 +40,15 @@ export const useCartStore = create((set, get) => ({ const summary = computeSummary(cart); set({ summary }); }, + updateCartItem: (updatedCart) => { + const cart = get().cart; + if (!cart) return; + + set({ cart: updatedCart }); + const summary = computeSummary(updatedCart); + set({ summary }); + }, + })); const computeSummary = (cart: CartProps) => { diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index 73b002b6..cfb20284 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -1,6 +1,6 @@ import style from './cart.module.css'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import Link from 'next/link'; import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react'; import { toast } from 'react-hot-toast'; @@ -28,10 +28,12 @@ const CartPage = () => { const [buttonSelectNow, setButtonSelectNow] = useState(true); const [isLoad, setIsLoad] = useState(false) const [isLoadDelete, setIsLoadDelete] = useState(false) - const { loadCart, cart, summary } = useCartStore(); + const { loadCart, cart, summary, updateCartItem } = useCartStore(); const useDivvice = useDevice(); const { setRefreshCart } = useProductCartContext() const [isTop, setIsTop] = useState(true); + const [hasChanged, setHasChanged] = useState(false); + const prevCartRef = useRef(null); useEffect(() => { const handleScroll = () => { @@ -51,6 +53,35 @@ const CartPage = () => { } }, [auth, loadCart, cart, isButtonChek]); + useEffect(() => { + if (typeof auth === 'object' && !cart) { + loadCart(auth.id); + setIsStepApproval(auth?.feature?.soApproval); + } + }, [auth, loadCart, cart, isButtonChek]); + + useEffect(() => { + const hasSelectedChanged = () => { + if (prevCartRef.current && cart) { + const prevCart = prevCartRef.current; + return cart.products.some((item, index) => + prevCart[index] && prevCart[index].selected !== item.selected + ); + } + return false; + }; + + if (hasSelectedChanged()) { + setHasChanged(true) + // Perform necessary actions here if selection has changed + }else{ + setHasChanged(false) + } + + // Update the ref to the current cart state + prevCartRef.current = cart ? [...cart.products] : null; + }, [cart]); + const hasSelectedPromo = useMemo(() => { if (!cart) return false; return cart.products.some(item => item.cart_type === 'promotion' && item.selected); @@ -71,6 +102,31 @@ const CartPage = () => { return cart.products.every(item => item.selected); }, [cart]); + + useEffect(() => { + const updateCartItems = async () => { + if (typeof auth === 'object' && cart) { + const upsertPromises = cart.products.map(item => + upsertUserCart({ + userId: auth.id, + type: item.cart_type, + id: item.id, + qty: item.quantity, + selected: item.selected + }) + ); + try { + await Promise.all(upsertPromises); + await loadCart(auth.id); + } catch (error) { + console.error('Failed to update cart items:', error); + } + } + }; + + updateCartItems(); + }, [hasChanged]); + const handleCheckout = () => { router.push('/shop/checkout'); } @@ -84,23 +140,26 @@ const CartPage = () => { } const handleChange = async (e: React.ChangeEvent) => { - if (typeof auth !== 'object' || !cart) return; - setIsLoad(true) - const newSelected = e.target.checked; - setIsSelectedAll(newSelected); - - for (const item of cart.products) { - await upsertUserCart({ - userId: auth.id, - type: item.cart_type, - id: item.id, - qty: item.quantity, - selected: newSelected - }); + + // Ensure that cart is not null before attempting to update + if (cart) { + const updatedCart = { + ...cart, + products: cart.products.map(item => ({ + ...item, + selected: !hasSelectedAll + })) + }; + + updateCartItem(updatedCart); // Pass only valid CartProps to updateCartItem + if(hasSelectedAll){ + setIsSelectedAll(false); + }else{ + setIsSelectedAll(true); + } } - await loadCart(auth.id); - setIsLoad(false) - } + }; + const handleDelete = async () => { if (typeof auth !== 'object' || !cart) return; @@ -136,7 +195,7 @@ const CartPage = () => { /> )}

- {hasSelectedAll ? "Unchek all" : "Select all"} + {hasSelectedAll ? "Uncheck all" : "Select all"}

-- cgit v1.2.3 From 213b4444c48896f24dd6803a9db2ae58af5b0391 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 10:01:18 +0700 Subject: update unchek cart --- src-migrate/pages/shop/cart/index.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/pages/shop/cart/index.tsx b/src-migrate/pages/shop/cart/index.tsx index cfb20284..5e3e042a 100644 --- a/src-migrate/pages/shop/cart/index.tsx +++ b/src-migrate/pages/shop/cart/index.tsx @@ -78,7 +78,6 @@ const CartPage = () => { setHasChanged(false) } - // Update the ref to the current cart state prevCartRef.current = cart ? [...cart.products] : null; }, [cart]); @@ -141,7 +140,7 @@ const CartPage = () => { const handleChange = async (e: React.ChangeEvent) => { - // Ensure that cart is not null before attempting to update + if (cart) { const updatedCart = { ...cart, @@ -151,7 +150,7 @@ const CartPage = () => { })) }; - updateCartItem(updatedCart); // Pass only valid CartProps to updateCartItem + updateCartItem(updatedCart); if(hasSelectedAll){ setIsSelectedAll(false); }else{ -- cgit v1.2.3 From f19bed80a5711d2904745b1dff283d7936337b06 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 16 Aug 2024 12:00:12 +0700 Subject: update error code --- src-migrate/modules/product-detail/components/Information.tsx | 2 +- src-migrate/modules/product-detail/stores/useProductDetail.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src-migrate') diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx index 52eb6b88..75ae3c41 100644 --- a/src-migrate/modules/product-detail/components/Information.tsx +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -19,7 +19,7 @@ type Props = { const Information = ({ product }: Props) => { const querySLA = useQuery({ - queryKey: ['variant-sla', product.variants[0].id], + queryKey: ['variant-sla', product.variants[0]?.id], queryFn: () => getVariantSLA(product.variants[0].id), enabled: product.variant_total === 1 }) diff --git a/src-migrate/modules/product-detail/stores/useProductDetail.ts b/src-migrate/modules/product-detail/stores/useProductDetail.ts index 2da8835d..eb409930 100644 --- a/src-migrate/modules/product-detail/stores/useProductDetail.ts +++ b/src-migrate/modules/product-detail/stores/useProductDetail.ts @@ -23,7 +23,7 @@ export const useProductDetail = create((set, get) => ({ askAdminUrl: '', isApproval : false, setActive: (variant) => { - set({ activeVariantId: variant.id, activePrice: variant.price }); + set({ activeVariantId: variant?.id, activePrice: variant?.price }); }, setQuantityInput: (value: string) => { set({ quantityInput: value }); -- cgit v1.2.3