From 6b173eaf8a95432316822b1d41b084875adfbd83 Mon Sep 17 00:00:00 2001 From: "tri.susilo" Date: Wed, 8 May 2024 14:47:11 +0700 Subject: [agnes] - Feature category management --- src/lib/category/components/Category.jsx | 79 ++++++++++++++++++++------ src/lib/home/components/CategoryPilihan.jsx | 32 +++++++++++ src/lib/product/components/CategorySection.jsx | 22 +++++++ src/lib/product/components/ProductSearch.jsx | 20 +++++++ src/pages/index.jsx | 22 ++++++- src/pages/shop/category/[slug].jsx | 9 ++- src/styles/globals.css | 5 +- 7 files changed, 166 insertions(+), 23 deletions(-) create mode 100644 src/lib/home/components/CategoryPilihan.jsx create mode 100644 src/lib/product/components/CategorySection.jsx (limited to 'src') diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index e6ea5acf..c147a3b3 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -2,10 +2,14 @@ import odooApi from '@/core/api/odooApi' import Link from '@/core/components/elements/Link/Link' import DesktopView from '@/core/components/views/DesktopView' import { createSlug } from '@/core/utils/slug' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import Image from 'next/image' import { useEffect, useState } from 'react' const Category = () => { const [categories, setCategories] = useState([]) + const [openCategories, setOpenCategory] = useState([]); + useEffect(() => { const loadCategories = async () => { @@ -31,7 +35,7 @@ const Category = () => {
{categories?.map((category) => ( -
+
{ {category.name}
-
+
{category.childs.map((child1Category) => ( -
+
{child1Category.name} -
- {child1Category.childs.map((child2Category) => ( - - {child2Category.name} - +
+ {child1Category.childs.map((child2Category, index) => ( + (index < 4) && ( + + {child2Category.name} + + ) ))} + {child1Category.childs.length > 5 && ( +
+ +

Lihat Semua

+ + +
+ )}
))}
+
+
+
+ {category.childs.map((brand, index) => ( + (index < 8 ) && ( +
+ + + +
+ ) + ))} +
+ {category.childs.length > 8 && ( +
+ +

Lihat Semua Brand

+ + +
+ )} +
+
+ +
+
))} diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx new file mode 100644 index 00000000..c506ef29 --- /dev/null +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -0,0 +1,32 @@ +import Image from 'next/image' +import useCategoryHome from '../hooks/useCategoryHome' + +const CategoryPilihan = ({ id, categories }) => { + const { categoryHome } = useCategoryHome({ id }) + + return ( +
+
+

Kategori Pilihan

+

total produk

+
+
+ {categories.map((category) => ( +
+ +
+

{category?.name}

+
+
+ ))} +
+
+ ) +} + +export default CategoryPilihan diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx new file mode 100644 index 00000000..7c347fe8 --- /dev/null +++ b/src/lib/product/components/CategorySection.jsx @@ -0,0 +1,22 @@ +import Image from "next/image" + +const CategorySection = ({ categories }) => { + return ( +
+
+ {categories.map((category) => ( +
+
+ {category?.name} +
+
+

{category?.name}

+
+
+ ))} +
+
+ ) +} + +export default CategorySection \ No newline at end of file diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 08b64c13..253c3703 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -26,6 +26,8 @@ import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; +import CategorySection from './CategorySection'; +import { getIdFromSlug } from '@/core/utils/slug' const ProductSearch = ({ query, @@ -68,6 +70,10 @@ const ProductSearch = ({ const productStart = productSearch.data?.responseHeader.params.start; const productRows = limit; const productFound = productSearch.data?.response.numFound; + const [dataCategories, setDataCategories] = useState([]) + + const categoryId = getIdFromSlug(prefixUrl) + useEffect(() => { if (productFound == 0 && query.q && !spellings) { @@ -116,6 +122,18 @@ const ProductSearch = ({ } }, [q]); + useEffect(() => { + const loadCategories = async () => { + const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() + }, []) + + console.log('Data Category : ', dataCategories) + const brands = []; for ( let i = 0; @@ -409,7 +427,9 @@ const ProductSearch = ({
+
+ {bannerPromotionHeader && bannerPromotionHeader?.image && (
import('@/core/components/layouts/BasicLayout') @@ -52,7 +55,7 @@ const CustomerReviews = dynamic(() => ); const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); -export default function Home() { +export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); @@ -61,6 +64,18 @@ export default function Home() { bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; }; + const [dataCategories, setDataCategories] = useState([]) + + useEffect(() => { + const loadCategories = async () => { + const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() + }, []) + return ( - + + {/* */}
diff --git a/src/pages/shop/category/[slug].jsx b/src/pages/shop/category/[slug].jsx index 1afe30bf..11840d47 100644 --- a/src/pages/shop/category/[slug].jsx +++ b/src/pages/shop/category/[slug].jsx @@ -5,6 +5,8 @@ import { useRouter } from 'next/router'; import Seo from '@/core/components/Seo'; import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; import Breadcrumb from '@/lib/category/components/Breadcrumb'; +import { useEffect, useState } from 'react'; +import odooApi from '@/core/api/odooApi'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -12,10 +14,14 @@ const BasicLayout = dynamic(() => const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch') ); +const CategorySection = dynamic(() => + import('@/lib/product/components/CategorySection') +) export default function CategoryDetail() { const router = useRouter(); const { slug = '', page = 1 } = router.query; + const [dataCategories, setDataCategories] = useState([]) const categoryName = getNameFromSlug(slug); const categoryId = getIdFromSlug(slug); @@ -43,8 +49,9 @@ export default function CategoryDetail() { + {!_.isEmpty(router.query) && ( - + )} ); diff --git a/src/styles/globals.css b/src/styles/globals.css index f6561b00..505dcab4 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -583,12 +583,11 @@ button { @apply absolute left-[100%] top-12 - w-[40vw] bg-gray_r-1/90 backdrop-blur-md border border-gray_r-6 - p-6 + p-6 opacity-0 h-full transition-all @@ -604,6 +603,7 @@ button { transition-colors ease-linear duration-100 + w-fit font-semibold; } @@ -613,6 +613,7 @@ button { transition-colors ease-linear duration-100 + w-full font-normal; } -- cgit v1.2.3 From 6c79d14a11c8dba20778c0559230a406cd147cc7 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 3 Jul 2024 08:34:16 +0700 Subject: update category management --- src/lib/home/components/CategoryPilihan.jsx | 38 ++++++++++++++++---------- src/lib/product/components/CategorySection.jsx | 22 +++++++++------ src/lib/product/components/ProductSearch.jsx | 7 ++--- 3 files changed, 39 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index c506ef29..3f1066e2 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -1,30 +1,40 @@ import Image from 'next/image' import useCategoryHome from '../hooks/useCategoryHome' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' const CategoryPilihan = ({ id, categories }) => { const { categoryHome } = useCategoryHome({ id }) - + console.log("id",id) + console.log("categories",categories) return (
-
-

Kategori Pilihan

-

total produk

+
+
Kategori Pilihan
+

200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!

-
+
{categories.map((category) => ( -
-
- {category?.name} - +
+
+
+
+ {category?.name} +
+

{category?.name}

+
-
-

{category?.name}

+
+ + Lihat semua +
))} -
+
) } diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 7c347fe8..c250efeb 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -1,20 +1,24 @@ import Image from "next/image" +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' const CategorySection = ({ categories }) => { return ( -
-
+
+
{categories.map((category) => ( -
-
- {category?.name} -
-
-

{category?.name}

+
+
+
+
+ {category?.name} +
+

{category?.name}

+
))} -
+
) } diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 253c3703..29cf94da 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -74,7 +74,6 @@ const ProductSearch = ({ const categoryId = getIdFromSlug(prefixUrl) - useEffect(() => { if (productFound == 0 && query.q && !spellings) { searchSpellApi({ query: query.q }).then((response) => { @@ -121,18 +120,16 @@ const ProductSearch = ({ checkIfBrand(); } }, [q]); - + useEffect(() => { const loadCategories = async () => { - const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) + const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) if(getCategories){ setDataCategories(getCategories) } } loadCategories() }, []) - - console.log('Data Category : ', dataCategories) const brands = []; for ( -- cgit v1.2.3 From 1a70984f3497652b8d8b64d16053c1f2be452bd7 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 5 Jul 2024 10:06:49 +0700 Subject: update category management --- src/lib/home/components/CategoryPilihan.jsx | 34 ++++++++++++++++++++++---- src/lib/product/components/CategorySection.jsx | 22 ++++++++--------- 2 files changed, 40 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 3f1066e2..4a1106b0 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -2,17 +2,41 @@ import Image from 'next/image' import useCategoryHome from '../hooks/useCategoryHome' import Link from '@/core/components/elements/Link/Link' import { createSlug } from '@/core/utils/slug' +import { useEffect, useState } from 'react'; +import { bannerApi } from '../../../api/bannerApi'; +const { useQuery } = require('react-query') +import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton'; + const CategoryPilihan = ({ id, categories }) => { - const { categoryHome } = useCategoryHome({ id }) - console.log("id",id) - console.log("categories",categories) - return ( -
+ const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'index-a-1' })); + + return ( +
Kategori Pilihan

200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!

+
+ {heroBanner.data && + heroBanner.data?.length > 0 && ( +
+ {/* {heroBanner.data?.map((banner) => ( */} + + {heroBanner.data[0].name} + + {/* ))} */} +
+ + )} +
{categories.map((category) => (
diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index c250efeb..4c66e861 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -1,26 +1,26 @@ import Image from "next/image" -import Link from '@/core/components/elements/Link/Link' +import Link from 'next/link' import { createSlug } from '@/core/utils/slug' const CategorySection = ({ categories }) => { return (
-
+
{categories.map((category) => ( -
-
-
-
- {category?.name} + +
+
+
+ {category?.name} +

{category?.name}

-

{category?.name}

-
+ ))} -
+
) } -export default CategorySection \ No newline at end of file +export default CategorySection -- cgit v1.2.3 From 59cba752134fa41063956569a3f4e7ed2a6d2537 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 8 Jul 2024 08:48:29 +0700 Subject: add dynamic category --- src/lib/home/components/CategoryDynamic.jsx | 9 +++++++++ src/pages/index.jsx | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 src/lib/home/components/CategoryDynamic.jsx (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx new file mode 100644 index 00000000..59a1858b --- /dev/null +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -0,0 +1,9 @@ +const CategoryDynamic = ({}) =>{ + return( +
+ DISINI CATEGORY DYNAMIC +
+ ) +}; + +export default CategoryDynamic; \ No newline at end of file diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 9675c355..149352c2 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -12,6 +12,7 @@ import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBran import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; +import CategoryDynamic from '../lib/home/components/CategoryDynamic'; import odooApi from '@/core/api/odooApi'; import { getIdFromSlug } from '@/core/utils/slug' @@ -120,6 +121,7 @@ export default function Home({categoryId}) { + {/* */} -- cgit v1.2.3 From bc7c0d1891db37ad314bd5016e19917e0f1e63be Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 17 Jul 2024 15:38:45 +0700 Subject: update error code --- src/api/promoApi.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/api/promoApi.js b/src/api/promoApi.js index f262db8d..3f85db8e 100644 --- a/src/api/promoApi.js +++ b/src/api/promoApi.js @@ -13,11 +13,11 @@ export const fetchPromoItems = async (type) => { } }; -export const fetchPromoItemsSolr = async (type) => { +export const fetchPromoItemsSolr = async (type, start, rows) => { // let query = type ? `type_value_s:${type}` : '*:*'; let sort ='sort=if(exists(sequence_i),0,1) asc, sequence_i asc, if(exists(total_qty_sold_f), total_qty_sold_f, -1) desc'; - let start = 0 - let rows = 100 + // let start = 0 + // let rows = 100 // let start = 0 // let rows = 10 try { -- cgit v1.2.3 From 0840f5ccc7493dfa091508db84bad8a21e073268 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 18 Jul 2024 17:24:36 +0700 Subject: update category-management --- src/lib/home/components/CategoryDynamic.jsx | 95 ++++++++++++++++++++++++++--- src/lib/home/hooks/useCategoryManagement.js | 34 +++++++++++ src/pages/index.jsx | 9 ++- 3 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 src/lib/home/hooks/useCategoryManagement.js (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 59a1858b..e3052d11 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,9 +1,90 @@ -const CategoryDynamic = ({}) =>{ - return( -
- DISINI CATEGORY DYNAMIC -
- ) +import React, { useEffect, useState } from 'react'; +import {fetchProductManagementSolr} from '../hooks/useCategoryManagement'; +import NextImage from 'next/image'; +import Link from "next/link" +import router from 'next/router'; +import { createSlug } from '@/core/utils/slug' + +const CategoryDynamic = () => { + const [promoItems, setPromoItems] = useState([]); + useEffect(() => { + const loadPromo = async () => { + + try { + const items = await fetchProductManagementSolr(); + setPromoItems(items); + + } catch (loadError) { + // console.error("Error loading promo items:", loadError) + } + } + + + loadPromo() + + },[]); + + const image = 'https://erp.indoteknik.com/api/image/product.template/image_256/544371?ratio=square' + const handleLink = (name, id) => { + return `/shop/category/${name}/${id}`; }; -export default CategoryDynamic; \ No newline at end of file + console.log("promoItems",promoItems) + + return ( +
+
Kategori Pilihan
+ {/* Render category data */} + {promoItems && promoItems.map((category) => ( +
+
+
{category.name}
+

999 rb+ Produk tersedia

+ Lihat Semua +
+

+ Kategori level 1 : {category.name} - ID level 1 : {category.id} + +

+
+ {category.category_id2.map((index)=> ( +
+

+ id LEVEL 2: {index.id_level_2} - Name LEVEL 2: {index.name} + +

+ {index.child_frontend_id_i.map((x)=> ( +
+

+ id LEVEL 3: {x.id_level_3} - name LEVEL 3: {x.name} + +

+
+ ))} +
+

+
+ ))} +
+
+ ))} +
+ ); +} + +export default CategoryDynamic; diff --git a/src/lib/home/hooks/useCategoryManagement.js b/src/lib/home/hooks/useCategoryManagement.js new file mode 100644 index 00000000..7c01df6e --- /dev/null +++ b/src/lib/home/hooks/useCategoryManagement.js @@ -0,0 +1,34 @@ +export const fetchProductManagementSolr = async () => { + try { + const queryParams = new URLSearchParams({q: 'type_value_s:bundling'}) + const response = await fetch(`/solr/product_category_management/query?q=*:*&q.op=OR&indent=true`); + // console.log("response", response) + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + // console.log("data",data) + const dataManagement = await map(data.response.docs); + // console.log("dataManagement",dataManagement) + return dataManagement; + } catch (error) { + console.error("Error fetching promotion data:", error); + return []; + } +}; + +const map = async (promotions) => { + const result = []; + for (const promotion of promotions) { + const data = { + id: promotion.id, + category_id: promotion.category_id_i, + name: promotion.name_s, + sequence: promotion.sequence_i, + image: promotion.image_s, + category_id2: JSON.parse(promotion.category_id2_s), + }; + result.push(data); + } + return result; +}; diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 149352c2..b5d004ca 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -12,7 +12,7 @@ import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBran import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; -import CategoryDynamic from '../lib/home/components/CategoryDynamic'; +// import CategoryDynamic from '../lib/home/components/CategoryDynamic'; import odooApi from '@/core/api/odooApi'; import { getIdFromSlug } from '@/core/utils/slug' @@ -51,6 +51,11 @@ const BannerSection = dynamic(() => const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId') ); + +const CategoryDynamic = dynamic(() => + import('@/lib/home/components/CategoryDynamic') +); + const CustomerReviews = dynamic(() => import('@/lib/review/components/CustomerReviews') ); @@ -122,7 +127,7 @@ export default function Home({categoryId}) { - {/* */} +
-- cgit v1.2.3 From 8564ea1361d40560679df6823b28dfc7e02ab197 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 19 Jul 2024 16:45:46 +0700 Subject: update view category dynamic --- src/lib/home/components/CategoryDynamic.jsx | 81 +++++++++++++---------------- src/lib/home/hooks/useCategoryManagement.js | 2 +- 2 files changed, 38 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index e3052d11..4180438a 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -18,66 +18,59 @@ const CategoryDynamic = () => { // console.error("Error loading promo items:", loadError) } } - - loadPromo() },[]); - - const image = 'https://erp.indoteknik.com/api/image/product.template/image_256/544371?ratio=square' - const handleLink = (name, id) => { - return `/shop/category/${name}/${id}`; -}; console.log("promoItems",promoItems) return (
-
Kategori Pilihan
+ {/*
Kategori Pilihan
*/} {/* Render category data */} {promoItems && promoItems.map((category) => (
-
+
{category.name}

999 rb+ Produk tersedia

- Lihat Semua + Lihat Semua
-

- Kategori level 1 : {category.name} - ID level 1 : {category.id} - -

-
+
{category.category_id2.map((index)=> ( -
-

- id LEVEL 2: {index.id_level_2} - Name LEVEL 2: {index.name} - -

- {index.child_frontend_id_i.map((x)=> ( -
-

- id LEVEL 3: {x.id_level_3} - name LEVEL 3: {x.name} - -

-
- ))} +
+
+
+ +
+
{index.name}
+

999 rb+ Produk

+ Lihat Semua +
+
+
+ {index.child_frontend_id_i.map((x)=> ( +
+ + +
+
{x.name}
+
+ +
+ ))}
-

+
))}
diff --git a/src/lib/home/hooks/useCategoryManagement.js b/src/lib/home/hooks/useCategoryManagement.js index 7c01df6e..db4e79e1 100644 --- a/src/lib/home/hooks/useCategoryManagement.js +++ b/src/lib/home/hooks/useCategoryManagement.js @@ -1,7 +1,7 @@ export const fetchProductManagementSolr = async () => { try { const queryParams = new URLSearchParams({q: 'type_value_s:bundling'}) - const response = await fetch(`/solr/product_category_management/query?q=*:*&q.op=OR&indent=true`); + const response = await fetch(`/solr/product_category_management/query?q=*:*&q.op=OR&sort=sequence_i asc&indent=true`); // console.log("response", response) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); -- cgit v1.2.3 From 911e0fdc6beb2f97c7e390a6aec5773202189d68 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 19 Jul 2024 17:07:23 +0700 Subject: update mobile view --- src/lib/home/components/CategoryDynamicMobile.jsx | 69 +++++++++++++++++++++++ src/pages/index.jsx | 8 +++ 2 files changed, 77 insertions(+) create mode 100644 src/lib/home/components/CategoryDynamicMobile.jsx (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx new file mode 100644 index 00000000..a550bd62 --- /dev/null +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -0,0 +1,69 @@ +import React, { useEffect, useState } from 'react'; +import {fetchProductManagementSolr} from '../hooks/useCategoryManagement'; +import NextImage from 'next/image'; +import Link from "next/link" +import router from 'next/router'; +import { createSlug } from '@/core/utils/slug' +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; + +const CategoryDynamicMobile = () => { + const [promoItems, setPromoItems] = useState([]); + useEffect(() => { + const loadPromo = async () => { + + try { + const items = await fetchProductManagementSolr(); + setPromoItems(items); + + } catch (loadError) { + // console.error("Error loading promo items:", loadError) + } + } + loadPromo() + + },[]); + + console.log("promoItems",promoItems) + + return ( +
+ {/*
Kategori Pilihan
*/} + {/* Render category data */} + {promoItems && promoItems.map((category) => ( +
+
+
{category.name}
+ Lihat Semua +
+ + {category.category_id2.map((index)=> ( + +
+
+
+ +
+
{index.name}
+

999 rb+ Produk

+ Lihat Semua +
+
+
+
+
+ ))} +
+
+ ))} +
+ ); +} + +export default CategoryDynamicMobile; diff --git a/src/pages/index.jsx b/src/pages/index.jsx index b5d004ca..0255e239 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -56,6 +56,10 @@ const CategoryDynamic = dynamic(() => import('@/lib/home/components/CategoryDynamic') ); +const CategoryDynamicMobile = dynamic(() => + import('@/lib/home/components/CategoryDynamicMobile') +); + const CustomerReviews = dynamic(() => import('@/lib/review/components/CustomerReviews') ); @@ -153,6 +157,10 @@ export default function Home({categoryId}) { + + {/* */} + + -- cgit v1.2.3 From d6b459b3ea396775fae25b44d34c8dc724379224 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 20 Jul 2024 11:45:41 +0700 Subject: update mobile view --- src/lib/home/components/CategoryDynamic.jsx | 14 ++-- src/lib/home/components/CategoryDynamicMobile.jsx | 97 +++++++++++++++-------- src/lib/home/components/CategoryPilihan.jsx | 2 +- src/lib/product/components/CategorySection.jsx | 51 +++++++++--- src/lib/product/components/ProductSearch.jsx | 1 + 5 files changed, 111 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 4180438a..244543be 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -26,22 +26,20 @@ const CategoryDynamic = () => { return (
- {/*
Kategori Pilihan
*/} - {/* Render category data */} {promoItems && promoItems.map((category) => (
{category.name}

999 rb+ Produk tersedia

- Lihat Semua + Lihat Semua
{category.category_id2.map((index)=> ( -
+
-
+
{
{index.child_frontend_id_i.map((x)=> (
- + { +const CategoryDynamicMobile = () => { const [promoItems, setPromoItems] = useState([]); + const [selectedCategory, setSelectedCategory] = useState({}); + useEffect(() => { const loadPromo = async () => { - try { const items = await fetchProductManagementSolr(); setPromoItems(items); - + if (items.length > 0) { + const initialSelections = items.reduce((acc, category) => { + if (category.category_id2.length > 0) { + acc[category.id] = category.category_id2[0].id_level_2; + } + return acc; + }, {}); + setSelectedCategory(initialSelections); + } } catch (loadError) { // console.error("Error loading promo items:", loadError) } - } - loadPromo() + }; + loadPromo(); + }, []); - },[]); - - console.log("promoItems",promoItems) + const handleCategoryLevel2Click = (categoryLevel1Id, categoryLevel2Id) => { + setSelectedCategory(prev => ({ + ...prev, + [categoryLevel1Id]: categoryLevel2Id + })); + }; return (
- {/*
Kategori Pilihan
*/} - {/* Render category data */} {promoItems && promoItems.map((category) => (
-
{category.name}
- Lihat Semua +
{category.name}
+ Lihat Semua
- {category.category_id2.map((index)=> ( - -
-
-
+ {category.category_id2.map((index) => ( + +
handleCategoryLevel2Click(category.id, index?.id_level_2)} + className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.id_level_2 ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+
-
-
{index.name}
-

999 rb+ Produk

- Lihat Semua +
+
{index.name}
+

999 rb+ Produk

+
-
-
+ ))} +
+
+ {category.category_id2.map((index) => ( + selectedCategory[category.id] === index?.id_level_2 && index.child_frontend_id_i.map((x) => ( +
+ + +
+
{x.name}
+
+ +
+ )) + ))} +
+
))}
); -} +}; export default CategoryDynamicMobile; diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 4a1106b0..409a8918 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -43,7 +43,7 @@ const CategoryPilihan = ({ id, categories }) => {
- {category?.name} + {category?.name}

{category?.name}

diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 4c66e861..278bda94 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -1,24 +1,49 @@ import Image from "next/image" import Link from 'next/link' import { createSlug } from '@/core/utils/slug' - +import useDevice from '@/core/hooks/useDevice'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; const CategorySection = ({ categories }) => { + const { isDesktop, isMobile } = useDevice(); return (
-
- {categories.map((category) => ( - -
-
-
- {category?.name} -

{category?.name}

+ {isDesktop && +
+ {categories.map((category) => ( + +
+
+
+ {category?.name} +

{category?.name}

+
-
- - ))} -
+ + ))} +
+ } + {isMobile && +
+ + {categories.map((category) => ( + + +
+
+
+ {category?.name} +

{category?.name}

+
+
+
+ +
+ ))} +
+
+ }
) } diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 29cf94da..c4970b21 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -336,6 +336,7 @@ const ProductSearch = ({ SpellingComponent )}
+ {productFound > 0 && (
-- cgit v1.2.3 From a181665f20207db5617d794df8159483fef0c2a8 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Mon, 22 Jul 2024 11:16:47 +0700 Subject: no message --- src/lib/product/components/ProductCard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 818dbbcf..3b5fab28 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -18,7 +18,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { let voucherPastiHemat = 0; - if (product?.voucherPastiHemat.length > 0) { + if (product?.voucherPastiHemat?.length > 0) { const stringVoucher = product?.voucherPastiHemat[0]; const validJsonString = stringVoucher.replace(/'/g, '"'); voucherPastiHemat = JSON.parse(validJsonString); -- cgit v1.2.3 From 1a3bef5d01fb50ad731f269f0a76b5c5fd52813d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 22 Jul 2024 16:56:30 +0700 Subject: { return ( diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 571c4745..fc899665 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,4 +1,5 @@ -import { Swiper, SwiperSlide } from 'swiper/react' +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { Navigation, Pagination, Autoplay } from 'swiper'; import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' @@ -10,6 +11,22 @@ const PreferredBrand = () => { let params = 'prioritas' const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() + const swiperBanner = { + modules:[Navigation, Pagination, Autoplay], + autoplay: { + delay: 4000, + disableOnInteraction: false + }, + loop: true, + className: 'h-[70px] md:h-[100px] w-full', + slidesPerView: isMobile ? 4 : 8, + spaceBetween: isMobile ? 12 : 0, + pagination: { + dynamicBullets: true, + dynamicMainBullets: isMobile ? 6 : 8, + clickable: true, + } + } return (
@@ -21,16 +38,18 @@ const PreferredBrand = () => { )}
- {preferredBrands.isLoading && } - {!preferredBrands.isLoading && ( - - {preferredBrands.data?.data.map((brand) => ( - - - - ))} - - )} +
+ {preferredBrands.isLoading && } + {!preferredBrands.isLoading && ( + + {preferredBrands.data?.data.map((brand) => ( + + + + ))} + + )} +
) } -- cgit v1.2.3 From a78251dc5cdfdd5438aad3ce7b7e342fceb7275e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 22 Jul 2024 16:57:47 +0700 Subject: update category management --- src/lib/home/components/CategoryDynamic.jsx | 4 -- src/lib/product/components/CategorySection.jsx | 67 +++++++++++++++++++------- src/pages/index.jsx | 2 +- 3 files changed, 51 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 244543be..2edd5485 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -19,11 +19,7 @@ const CategoryDynamic = () => { } } loadPromo() - },[]); - - console.log("promoItems",promoItems) - return (
{promoItems && promoItems.map((category) => ( diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 278bda94..e80429f4 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -4,44 +4,77 @@ import { createSlug } from '@/core/utils/slug' import useDevice from '@/core/hooks/useDevice'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; +import { useQuery } from 'react-query' +import { useRouter } from 'next/router' + const CategorySection = ({ categories }) => { const { isDesktop, isMobile } = useDevice(); + const router = useRouter() + + let teks = router.query.slug; + let hasil = teks?.match(/(\d+)$/)[0]; + + const breadcrumbs = useQuery( + `category-breadcrumbs/${hasil}`, + async () => await odooApi('GET', `/api/v1/category/${hasil}/category-breadcrumb`) + ) + return (
- {isDesktop && + {isDesktop && (
- {categories.map((category) => ( + {categories.slice(0, 10).map((category) => (
- {category?.name} -

{category?.name}

+ {category?.name} +

{category?.name}

))}
- } + )} + {isDesktop && categories.length > 10 && ( +
+ Lihat Semua + +
+ )} + {isMobile &&
- {categories.map((category) => ( - - -
-
-
- {category?.name} -

{category?.name}

-
-
+ {categories.slice(0, 10).map((category) => ( + + +
+
+
+ {category?.name} +

+ {category?.name} +

- +
+
+
- ))} + ))} + {categories.length > 10 && ( +
+ Lihat Semua + +
+ )}
}
diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 0255e239..cdbe0dd0 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -158,7 +158,7 @@ export default function Home({categoryId}) { - {/* */} + -- cgit v1.2.3 From bf5c3b1d48da54e0e44689412ad9de9c10cf9edb Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 09:28:21 +0700 Subject: update category management --- src/lib/home/api/categoryManagementApi.js | 8 +++++ src/lib/home/components/CategoryDynamic.jsx | 32 ++++++----------- src/lib/home/components/CategoryDynamicMobile.jsx | 41 +++++++++++---------- src/lib/home/components/CategoryPilihan.jsx | 2 +- src/lib/home/hooks/useCategoryManagement.js | 43 ++++++----------------- src/lib/product/components/CategorySection.jsx | 10 +++--- 6 files changed, 55 insertions(+), 81 deletions(-) create mode 100644 src/lib/home/api/categoryManagementApi.js (limited to 'src') diff --git a/src/lib/home/api/categoryManagementApi.js b/src/lib/home/api/categoryManagementApi.js new file mode 100644 index 00000000..b70d60ce --- /dev/null +++ b/src/lib/home/api/categoryManagementApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi' + +const categoryManagementApi = async () => { + const dataCategoryManagement = await odooApi('GET', '/api/v1/categories_management') + return dataCategoryManagement +} + +export default categoryManagementApi diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 2edd5485..cac8a138 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,36 +1,24 @@ import React, { useEffect, useState } from 'react'; -import {fetchProductManagementSolr} from '../hooks/useCategoryManagement'; +import useCategoryManagement from '../hooks/useCategoryManagement'; import NextImage from 'next/image'; import Link from "next/link" import router from 'next/router'; import { createSlug } from '@/core/utils/slug' -const CategoryDynamic = () => { - const [promoItems, setPromoItems] = useState([]); - useEffect(() => { - const loadPromo = async () => { - - try { - const items = await fetchProductManagementSolr(); - setPromoItems(items); - - } catch (loadError) { - // console.error("Error loading promo items:", loadError) - } - } - loadPromo() - },[]); +const CategoryDynamic = () => { + const { categoryManagement } = useCategoryManagement() + return (
- {promoItems && promoItems.map((category) => ( + {categoryManagement && categoryManagement.data?.map((category) => (
{category.name}

999 rb+ Produk tersedia

- Lihat Semua + Lihat Semua
- {category.category_id2.map((index)=> ( + {category.categories.map((index)=> (
@@ -44,13 +32,13 @@ const CategoryDynamic = () => {
{index.name}

999 rb+ Produk

- Lihat Semua + Lihat Semua
- {index.child_frontend_id_i.map((x)=> ( + {index.childFrontendIdI.map((x)=> (
- + { - const [promoItems, setPromoItems] = useState([]); + const { categoryManagement } = useCategoryManagement() const [selectedCategory, setSelectedCategory] = useState({}); useEffect(() => { const loadPromo = async () => { try { - const items = await fetchProductManagementSolr(); - setPromoItems(items); - if (items.length > 0) { - const initialSelections = items.reduce((acc, category) => { - if (category.category_id2.length > 0) { - acc[category.id] = category.category_id2[0].id_level_2; + if (categoryManagement.data?.length > 0) { + const initialSelections = categoryManagement.data.reduce((acc, category) => { + if (category.categories.length > 0) { + acc[category.id] = category.categories[0].idLevel2; } return acc; }, {}); setSelectedCategory(initialSelections); } } catch (loadError) { - // console.error("Error loading promo items:", loadError) + // console.error("Error loading promo items:", loadError); } }; + loadPromo(); - }, []); + }, [categoryManagement.data]); - const handleCategoryLevel2Click = (categoryLevel1Id, categoryLevel2Id) => { + const handleCategoryLevel2Click = (categoryIdI, idLevel2) => { setSelectedCategory(prev => ({ ...prev, - [categoryLevel1Id]: categoryLevel2Id + [categoryIdI]: idLevel2 })); }; - + return (
- {promoItems && promoItems.map((category) => ( + {categoryManagement.data && categoryManagement.data.map((category) => (
{category.name}
- Lihat Semua + Lihat Semua
- {category.category_id2.map((index) => ( + {category.categories.map((index) => (
handleCategoryLevel2Click(category.id, index?.id_level_2)} - className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.id_level_2 ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + onClick={() => handleCategoryLevel2Click(category.id, index?.idLevel2)} + className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.idLevel2 ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} >
@@ -74,10 +73,10 @@ const CategoryDynamicMobile = () => {
- {category.category_id2.map((index) => ( - selectedCategory[category.id] === index?.id_level_2 && index.child_frontend_id_i.map((x) => ( + {category.categories.map((index) => ( + selectedCategory[category.id] === index?.idLevel2 && index.childFrontendIdI.map((x) => (
- + {
- {category?.name} + {category?.name}

{category?.name}

diff --git a/src/lib/home/hooks/useCategoryManagement.js b/src/lib/home/hooks/useCategoryManagement.js index db4e79e1..c1dda585 100644 --- a/src/lib/home/hooks/useCategoryManagement.js +++ b/src/lib/home/hooks/useCategoryManagement.js @@ -1,34 +1,13 @@ -export const fetchProductManagementSolr = async () => { - try { - const queryParams = new URLSearchParams({q: 'type_value_s:bundling'}) - const response = await fetch(`/solr/product_category_management/query?q=*:*&q.op=OR&sort=sequence_i asc&indent=true`); - // console.log("response", response) - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const data = await response.json(); - // console.log("data",data) - const dataManagement = await map(data.response.docs); - // console.log("dataManagement",dataManagement) - return dataManagement; - } catch (error) { - console.error("Error fetching promotion data:", error); - return []; - } -}; +import categoryManagementApi from '../api/categoryManagementApi' +import { useQuery } from 'react-query' + +const useCategoryManagement = () => { + const fetchCategoryManagement = async () => await categoryManagementApi() + const { isLoading, data } = useQuery('categoryManagementApi', fetchCategoryManagement) -const map = async (promotions) => { - const result = []; - for (const promotion of promotions) { - const data = { - id: promotion.id, - category_id: promotion.category_id_i, - name: promotion.name_s, - sequence: promotion.sequence_i, - image: promotion.image_s, - category_id2: JSON.parse(promotion.category_id2_s), - }; - result.push(data); + return { + categoryManagement: { data, isLoading } } - return result; -}; +} + +export default useCategoryManagement \ No newline at end of file diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index e80429f4..749a56eb 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -25,10 +25,10 @@ const CategorySection = ({ categories }) => {
{categories.slice(0, 10).map((category) => ( -
-
-
- {category?.name} +
+
+
+ {category?.name}

{category?.name}

@@ -54,7 +54,7 @@ const CategorySection = ({ categories }) => {
{category?.name} Date: Tue, 23 Jul 2024 09:42:57 +0700 Subject: marged develompent & category management --- src/lib/brand/components/BrandCard.jsx | 2 +- src/lib/category/components/Category.jsx | 79 +++++++++++++---- src/lib/home/api/categoryManagementApi.js | 8 ++ src/lib/home/components/CategoryDynamic.jsx | 65 ++++++++++++++ src/lib/home/components/CategoryDynamicMobile.jsx | 101 ++++++++++++++++++++++ src/lib/home/components/CategoryPilihan.jsx | 66 ++++++++++++++ src/lib/home/components/PreferredBrand.jsx | 42 ++++++--- src/lib/home/hooks/useCategoryManagement.js | 13 +++ src/lib/product/components/CategorySection.jsx | 84 ++++++++++++++++++ src/lib/product/components/ProductSearch.jsx | 18 ++++ src/pages/index.jsx | 35 +++++++- src/pages/shop/category/[slug].jsx | 9 +- src/styles/globals.css | 5 +- 13 files changed, 492 insertions(+), 35 deletions(-) create mode 100644 src/lib/home/api/categoryManagementApi.js create mode 100644 src/lib/home/components/CategoryDynamic.jsx create mode 100644 src/lib/home/components/CategoryDynamicMobile.jsx create mode 100644 src/lib/home/components/CategoryPilihan.jsx create mode 100644 src/lib/home/hooks/useCategoryManagement.js create mode 100644 src/lib/product/components/CategorySection.jsx (limited to 'src') diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx index 731214ff..39b1aec1 100644 --- a/src/lib/brand/components/BrandCard.jsx +++ b/src/lib/brand/components/BrandCard.jsx @@ -8,7 +8,7 @@ const BrandCard = ({ brand }) => { return ( diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index e6ea5acf..c147a3b3 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -2,10 +2,14 @@ import odooApi from '@/core/api/odooApi' import Link from '@/core/components/elements/Link/Link' import DesktopView from '@/core/components/views/DesktopView' import { createSlug } from '@/core/utils/slug' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import Image from 'next/image' import { useEffect, useState } from 'react' const Category = () => { const [categories, setCategories] = useState([]) + const [openCategories, setOpenCategory] = useState([]); + useEffect(() => { const loadCategories = async () => { @@ -31,7 +35,7 @@ const Category = () => {
{categories?.map((category) => ( -
+
{ {category.name}
-
+
{category.childs.map((child1Category) => ( -
+
{child1Category.name} -
- {child1Category.childs.map((child2Category) => ( - - {child2Category.name} - +
+ {child1Category.childs.map((child2Category, index) => ( + (index < 4) && ( + + {child2Category.name} + + ) ))} + {child1Category.childs.length > 5 && ( +
+ +

Lihat Semua

+ + +
+ )}
))}
+
+
+
+ {category.childs.map((brand, index) => ( + (index < 8 ) && ( +
+ + + +
+ ) + ))} +
+ {category.childs.length > 8 && ( +
+ +

Lihat Semua Brand

+ + +
+ )} +
+
+ +
+
))} diff --git a/src/lib/home/api/categoryManagementApi.js b/src/lib/home/api/categoryManagementApi.js new file mode 100644 index 00000000..b70d60ce --- /dev/null +++ b/src/lib/home/api/categoryManagementApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi' + +const categoryManagementApi = async () => { + const dataCategoryManagement = await odooApi('GET', '/api/v1/categories_management') + return dataCategoryManagement +} + +export default categoryManagementApi diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx new file mode 100644 index 00000000..cac8a138 --- /dev/null +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from 'react'; +import useCategoryManagement from '../hooks/useCategoryManagement'; +import NextImage from 'next/image'; +import Link from "next/link" +import router from 'next/router'; +import { createSlug } from '@/core/utils/slug' + +const CategoryDynamic = () => { + const { categoryManagement } = useCategoryManagement() + + return ( +
+ {categoryManagement && categoryManagement.data?.map((category) => ( +
+
+
{category.name}
+

999 rb+ Produk tersedia

+ Lihat Semua +
+
+ {category.categories.map((index)=> ( +
+
+
+ +
+
{index.name}
+

999 rb+ Produk

+ Lihat Semua +
+
+
+ {index.childFrontendIdI.map((x)=> ( +
+ + +
+
{x.name}
+
+ +
+ ))} +
+
+
+ ))} +
+
+ ))} +
+ ); +} + +export default CategoryDynamic; diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx new file mode 100644 index 00000000..c1433a2d --- /dev/null +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -0,0 +1,101 @@ +import React, { useEffect, useState } from 'react'; +import useCategoryManagement from '../hooks/useCategoryManagement'; +import NextImage from 'next/image'; +import Link from "next/link"; +import { createSlug } from '@/core/utils/slug'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; + +const CategoryDynamicMobile = () => { + const { categoryManagement } = useCategoryManagement() + const [selectedCategory, setSelectedCategory] = useState({}); + + useEffect(() => { + const loadPromo = async () => { + try { + if (categoryManagement.data?.length > 0) { + const initialSelections = categoryManagement.data.reduce((acc, category) => { + if (category.categories.length > 0) { + acc[category.id] = category.categories[0].idLevel2; + } + return acc; + }, {}); + setSelectedCategory(initialSelections); + } + } catch (loadError) { + // console.error("Error loading promo items:", loadError); + } + }; + + loadPromo(); + }, [categoryManagement.data]); + + const handleCategoryLevel2Click = (categoryIdI, idLevel2) => { + setSelectedCategory(prev => ({ + ...prev, + [categoryIdI]: idLevel2 + })); + }; + + return ( +
+ {categoryManagement.data && categoryManagement.data.map((category) => ( +
+
+
{category.name}
+ Lihat Semua +
+ + {category.categories.map((index) => ( + +
handleCategoryLevel2Click(category.id, index?.idLevel2)} + className={`border flex justify-start items-center max-w-48 max-h-16 rounded ${selectedCategory[category.id] === index?.idLevel2 ? 'bg-red-50 border-red-500 text-red-500' : 'border-gray-200 text-gray-900'}`} + > +
+
+ +
+
{index.name}
+

999 rb+ Produk

+
+
+
+
+
+ ))} +
+
+
+ {category.categories.map((index) => ( + selectedCategory[category.id] === index?.idLevel2 && index.childFrontendIdI.map((x) => ( +
+ + +
+
{x.name}
+
+ +
+ )) + ))} +
+
+
+ ))} +
+ ); +}; + +export default CategoryDynamicMobile; diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx new file mode 100644 index 00000000..7b9f0094 --- /dev/null +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -0,0 +1,66 @@ +import Image from 'next/image' +import useCategoryHome from '../hooks/useCategoryHome' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' +import { useEffect, useState } from 'react'; +import { bannerApi } from '../../../api/bannerApi'; +const { useQuery } = require('react-query') +import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton'; + + +const CategoryPilihan = ({ id, categories }) => { + const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'index-a-1' })); + + return ( +
+
+
Kategori Pilihan
+

200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!

+
+
+ {heroBanner.data && + heroBanner.data?.length > 0 && ( +
+ {/* {heroBanner.data?.map((banner) => ( */} + + {heroBanner.data[0].name} + + {/* ))} */} +
+ + )} +
+
+ {categories.map((category) => ( +
+
+
+
+ {category?.name} +
+

{category?.name}

+
+
+
+ + Lihat semua + +
+
+ ))} +
+
+ ) +} + +export default CategoryPilihan diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 6b64a444..1aa9746b 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,5 +1,5 @@ -import { Swiper, SwiperSlide } from 'swiper/react' -import { useCallback, useEffect, useState } from 'react' +import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { Navigation, Pagination, Autoplay } from 'swiper'; import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' @@ -38,6 +38,22 @@ const PreferredBrand = () => { const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() + const swiperBanner = { + modules:[Navigation, Pagination, Autoplay], + autoplay: { + delay: 4000, + disableOnInteraction: false + }, + loop: true, + className: 'h-[70px] md:h-[100px] w-full', + slidesPerView: isMobile ? 4 : 8, + spaceBetween: isMobile ? 12 : 0, + pagination: { + dynamicBullets: true, + dynamicMainBullets: isMobile ? 6 : 8, + clickable: true, + } + } return (
@@ -54,16 +70,18 @@ const PreferredBrand = () => { )}
- {manufactures.isLoading && } - {!manufactures.isLoading && ( - - {manufactures.map((manufacture) => ( - - - - ))} - - )} +
+ {preferredBrands.isLoading && } + {!preferredBrands.isLoading && ( + + {preferredBrands.data?.data.map((brand) => ( + + + + ))} + + )} +
) } diff --git a/src/lib/home/hooks/useCategoryManagement.js b/src/lib/home/hooks/useCategoryManagement.js new file mode 100644 index 00000000..c1dda585 --- /dev/null +++ b/src/lib/home/hooks/useCategoryManagement.js @@ -0,0 +1,13 @@ +import categoryManagementApi from '../api/categoryManagementApi' +import { useQuery } from 'react-query' + +const useCategoryManagement = () => { + const fetchCategoryManagement = async () => await categoryManagementApi() + const { isLoading, data } = useQuery('categoryManagementApi', fetchCategoryManagement) + + return { + categoryManagement: { data, isLoading } + } +} + +export default useCategoryManagement \ No newline at end of file diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx new file mode 100644 index 00000000..749a56eb --- /dev/null +++ b/src/lib/product/components/CategorySection.jsx @@ -0,0 +1,84 @@ +import Image from "next/image" +import Link from 'next/link' +import { createSlug } from '@/core/utils/slug' +import useDevice from '@/core/hooks/useDevice'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; +import { useQuery } from 'react-query' +import { useRouter } from 'next/router' + +const CategorySection = ({ categories }) => { + const { isDesktop, isMobile } = useDevice(); + const router = useRouter() + + let teks = router.query.slug; + let hasil = teks?.match(/(\d+)$/)[0]; + + const breadcrumbs = useQuery( + `category-breadcrumbs/${hasil}`, + async () => await odooApi('GET', `/api/v1/category/${hasil}/category-breadcrumb`) + ) + + return ( +
+ {isDesktop && ( +
+ {categories.slice(0, 10).map((category) => ( + +
+
+
+ {category?.name} +

{category?.name}

+
+
+
+ + ))} +
+ )} + {isDesktop && categories.length > 10 && ( +
+ Lihat Semua + +
+ )} + + {isMobile && +
+ + {categories.slice(0, 10).map((category) => ( + + +
+
+
+ {category?.name} +

+ {category?.name} +

+
+
+
+ +
+ ))} +
+ {categories.length > 10 && ( +
+ Lihat Semua + +
+ )} +
+ } +
+ ) +} + +export default CategorySection diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index b1a5d409..34018ffe 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -26,6 +26,8 @@ import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; +import CategorySection from './CategorySection'; +import { getIdFromSlug } from '@/core/utils/slug' const ProductSearch = ({ query, @@ -68,6 +70,9 @@ const ProductSearch = ({ const productStart = productSearch.data?.responseHeader.params.start; const productRows = limit; const productFound = productSearch.data?.response.numFound; + const [dataCategories, setDataCategories] = useState([]) + + const categoryId = getIdFromSlug(prefixUrl) useEffect(() => { if (productFound == 0 && query.q && !spellings) { @@ -115,6 +120,16 @@ const ProductSearch = ({ checkIfBrand(); } }, [q]); + + useEffect(() => { + const loadCategories = async () => { + const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() + }, []) const brands = []; for ( @@ -323,6 +338,7 @@ const ProductSearch = ({ SpellingComponent )}
+ {productFound > 0 && (
@@ -411,7 +427,9 @@ const ProductSearch = ({
+
+ {bannerPromotionHeader && bannerPromotionHeader?.image && (
const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId') ); + +const CategoryDynamic = dynamic(() => + import('@/lib/home/components/CategoryDynamic') +); + +const CategoryDynamicMobile = dynamic(() => + import('@/lib/home/components/CategoryDynamicMobile') +); + const CustomerReviews = dynamic(() => import('@/lib/review/components/CustomerReviews') ); const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); -export default function Home() { +export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); @@ -70,6 +83,18 @@ export default function Home() { bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; }; + const [dataCategories, setDataCategories] = useState([]) + + useEffect(() => { + const loadCategories = async () => { + const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() + }, []) + return ( )} + + @@ -150,6 +177,10 @@ export default function Home() { + + + + diff --git a/src/pages/shop/category/[slug].jsx b/src/pages/shop/category/[slug].jsx index 1afe30bf..11840d47 100644 --- a/src/pages/shop/category/[slug].jsx +++ b/src/pages/shop/category/[slug].jsx @@ -5,6 +5,8 @@ import { useRouter } from 'next/router'; import Seo from '@/core/components/Seo'; import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; import Breadcrumb from '@/lib/category/components/Breadcrumb'; +import { useEffect, useState } from 'react'; +import odooApi from '@/core/api/odooApi'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -12,10 +14,14 @@ const BasicLayout = dynamic(() => const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch') ); +const CategorySection = dynamic(() => + import('@/lib/product/components/CategorySection') +) export default function CategoryDetail() { const router = useRouter(); const { slug = '', page = 1 } = router.query; + const [dataCategories, setDataCategories] = useState([]) const categoryName = getNameFromSlug(slug); const categoryId = getIdFromSlug(slug); @@ -43,8 +49,9 @@ export default function CategoryDetail() { + {!_.isEmpty(router.query) && ( - + )} ); diff --git a/src/styles/globals.css b/src/styles/globals.css index f6561b00..505dcab4 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -583,12 +583,11 @@ button { @apply absolute left-[100%] top-12 - w-[40vw] bg-gray_r-1/90 backdrop-blur-md border border-gray_r-6 - p-6 + p-6 opacity-0 h-full transition-all @@ -604,6 +603,7 @@ button { transition-colors ease-linear duration-100 + w-fit font-semibold; } @@ -613,6 +613,7 @@ button { transition-colors ease-linear duration-100 + w-full font-normal; } -- cgit v1.2.3 From cf48c684d2f8da4dd70e2ed0f57623169bc5106f Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 10:01:58 +0700 Subject: update error code --- src/lib/home/components/PreferredBrand.jsx | 34 +----------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 1aa9746b..f822b9a0 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -5,37 +5,10 @@ import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' import useDevice from '@/core/hooks/useDevice' import Link from '@/core/components/elements/Link/Link' -import axios from 'axios' const PreferredBrand = () => { let query = 'level_s' let params = 'prioritas' - const [isLoading, setIsLoading] = useState(true) - const [startWith, setStartWith] = useState(null) - const [manufactures, setManufactures] = useState([]) - - const loadBrand = useCallback(async () => { - setIsLoading(true) - const name = startWith ? `${startWith}*` : '' - const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`) - - setIsLoading(false) - setManufactures((manufactures) => [...result.data]) - }, [startWith]) - - const toggleStartWith = (alphabet) => { - setManufactures([]) - if (alphabet == startWith) { - setStartWith(null) - return - } - setStartWith(alphabet) - } - - useEffect(() => { - loadBrand() - }, [loadBrand]) - const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() const swiperBanner = { @@ -64,11 +37,6 @@ const PreferredBrand = () => { Lihat Semua )} - {isMobile && ( - - Lihat Semua - - )}
{preferredBrands.isLoading && } @@ -86,4 +54,4 @@ const PreferredBrand = () => { ) } -export default PreferredBrand +export default PreferredBrand \ No newline at end of file -- cgit v1.2.3 From 1d770053ce0b75eab1d3755085d03c9d32fe3a83 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 10:07:46 +0700 Subject: update error log --- src/lib/home/components/CategoryPilihan.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 7b9f0094..73e42626 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -20,7 +20,7 @@ const CategoryPilihan = ({ id, categories }) => {
{heroBanner.data && heroBanner.data?.length > 0 && ( -
+
{/* {heroBanner.data?.map((banner) => ( */} {
{categories.map((category) => ( -
+
-- cgit v1.2.3 From b1341b76e94da9e64549768646bb54d2836976d0 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 14:29:08 +0700 Subject: update categories management --- src/lib/brand/components/BrandCard.jsx | 6 +- src/lib/home/components/CategoryDynamic.jsx | 119 ++++++++++++++----------- src/lib/home/components/PreferredBrand.jsx | 44 +++++++-- src/lib/product/components/CategorySection.jsx | 109 +++++++++++++--------- 4 files changed, 176 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/lib/brand/components/BrandCard.jsx b/src/lib/brand/components/BrandCard.jsx index 39b1aec1..2d78d956 100644 --- a/src/lib/brand/components/BrandCard.jsx +++ b/src/lib/brand/components/BrandCard.jsx @@ -16,9 +16,9 @@ const BrandCard = ({ brand }) => { {brand.name} )} {!brand.logo && ( diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index cac8a138..fa1df286 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,65 +1,84 @@ import React, { useEffect, useState } from 'react'; -import useCategoryManagement from '../hooks/useCategoryManagement'; +import useCategoryManagement from '../hooks/useCategoryManagement'; import NextImage from 'next/image'; -import Link from "next/link" +import Link from "next/link"; import router from 'next/router'; -import { createSlug } from '@/core/utils/slug' +import { createSlug } from '@/core/utils/slug'; + +const CategoryDynamic = () => { + const { categoryManagement } = useCategoryManagement(); + + const calculateLevel3Products = (category) => { + return category.childFrontendIdI.reduce((total, child) => total + (child.numFound || 0), 0); + }; + + const calculateLevel2Products = (category) => { + return category.categories.reduce((total, subCategory) => { + const level3Products = calculateLevel3Products(subCategory); + return total + (subCategory.numFound || 0) + level3Products; + }, 0); + }; -const CategoryDynamic = () => { - const { categoryManagement } = useCategoryManagement() - return (
- {categoryManagement && categoryManagement.data?.map((category) => ( -
-
+ {categoryManagement && categoryManagement.data?.map((category) => { + const countLevel2 = calculateLevel2Products(category); + + return ( +
+
{category.name}
-

999 rb+ Produk tersedia

+

{countLevel2} Produk tersedia

Lihat Semua -
-
- {category.categories.map((index)=> ( -
-
-
- -
-
{index.name}
-

999 rb+ Produk

- Lihat Semua +
+
+ {category.categories.map((subCategory) => { + const countLevel3 = calculateLevel3Products(subCategory); + + return ( +
+
+
+ +
+
{subCategory.name}
+

{(subCategory.numFound || 0) + countLevel3} Produk

+ Lihat Semua +
+
+
+ {subCategory.childFrontendIdI.map((childCategory) => ( +
+ + +
+
{childCategory.name}
+
+ +
+ ))}
-
- {index.childFrontendIdI.map((x)=> ( -
- - -
-
{x.name}
-
- -
- ))} -
-
-
- ))} +
+ ); + })} +
-
- ))} + ); + })}
); -} +}; export default CategoryDynamic; diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index fc899665..ae12505d 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,14 +1,42 @@ -import { Swiper, SwiperProps, SwiperSlide } from 'swiper/react'; +import { Swiper, SwiperSlide } from 'swiper/react' import { Navigation, Pagination, Autoplay } from 'swiper'; +import { useCallback, useEffect, useState } from 'react' import usePreferredBrand from '../hooks/usePreferredBrand' import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' import BrandCard from '@/lib/brand/components/BrandCard' import useDevice from '@/core/hooks/useDevice' import Link from '@/core/components/elements/Link/Link' +import axios from 'axios' const PreferredBrand = () => { let query = 'level_s' let params = 'prioritas' + const [isLoading, setIsLoading] = useState(true) + const [startWith, setStartWith] = useState(null) + const [manufactures, setManufactures] = useState([]) + + const loadBrand = useCallback(async () => { + setIsLoading(true) + const name = startWith ? `${startWith}*` : '' + const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`) + + setIsLoading(false) + setManufactures((manufactures) => [...result.data]) + }, [startWith]) + + const toggleStartWith = (alphabet) => { + setManufactures([]) + if (alphabet == startWith) { + setStartWith(null) + return + } + setStartWith(alphabet) + } + + useEffect(() => { + loadBrand() + }, [loadBrand]) + const { preferredBrands } = usePreferredBrand(query) const { isMobile, isDesktop } = useDevice() const swiperBanner = { @@ -27,7 +55,7 @@ const PreferredBrand = () => { clickable: true, } } - + const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : [] return (
@@ -39,12 +67,12 @@ const PreferredBrand = () => { )}
- {preferredBrands.isLoading && } - {!preferredBrands.isLoading && ( + {manufactures.isLoading && } + {!manufactures.isLoading && ( - {preferredBrands.data?.data.map((brand) => ( - - + {preferredBrandsData.map((manufacture) => ( + + ))} @@ -54,4 +82,4 @@ const PreferredBrand = () => { ) } -export default PreferredBrand +export default PreferredBrand \ No newline at end of file diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 749a56eb..14a39e7e 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -1,15 +1,23 @@ -import Image from "next/image" -import Link from 'next/link' -import { createSlug } from '@/core/utils/slug' +import Image from "next/image"; +import Link from 'next/link'; +import { createSlug } from '@/core/utils/slug'; import useDevice from '@/core/hooks/useDevice'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; -import { useQuery } from 'react-query' -import { useRouter } from 'next/router' +import { useQuery } from 'react-query'; +import { useRouter } from 'next/router'; +import { + ChevronDownIcon, + ChevronUpIcon, // Import ChevronUpIcon for toggling + DocumentCheckIcon, + HeartIcon, +} from '@heroicons/react/24/outline'; +import { useState } from 'react'; // Import useState const CategorySection = ({ categories }) => { const { isDesktop, isMobile } = useDevice(); - const router = useRouter() + const router = useRouter(); + const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility let teks = router.query.slug; let hasil = teks?.match(/(\d+)$/)[0]; @@ -17,18 +25,24 @@ const CategorySection = ({ categories }) => { const breadcrumbs = useQuery( `category-breadcrumbs/${hasil}`, async () => await odooApi('GET', `/api/v1/category/${hasil}/category-breadcrumb`) - ) - + ); + + const handleToggleCategories = () => { + setIsOpenCategory(!isOpenCategory); + }; + + const displayedCategories = isOpenCategory ? categories : categories.slice(0, 10); + return (
{isDesktop && (
- {categories.slice(0, 10).map((category) => ( + {displayedCategories.map((category) => (
-
- {category?.name} +
+ {category?.name}

{category?.name}

@@ -38,45 +52,58 @@ const CategorySection = ({ categories }) => {
)} {isDesktop && categories.length > 10 && ( -
- Lihat Semua - -
+
+ +
)} - {isMobile && + {isMobile && (
- {categories.slice(0, 10).map((category) => ( - - -
-
-
- {category?.name} -

- {category?.name} -

-
-
-
- -
- ))} + {displayedCategories.map((category) => ( + + +
+
+
+ {category?.name} +

+ {category?.name} +

+
+
+
+ +
+ ))}
- {categories.length > 10 && ( + {categories.length > 10 && (
- Lihat Semua - +
)}
- } + )}
) } -- cgit v1.2.3 From 2fbfdb7a3d090b0ad8dae5527464b25e5df65c25 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 14:40:23 +0700 Subject: Merge branch 'Feature/category-management' into development # Conflicts: # src/lib/home/components/CategoryDynamic.jsx # src/lib/home/components/CategoryPilihan.jsx # src/lib/home/components/PreferredBrand.jsx # src/lib/product/components/CategorySection.jsx # src/pages/index.jsx --- src/pages/index.jsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index db868470..0f2add9a 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -64,13 +64,13 @@ const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId') ); -const CategoryDynamic = dynamic(() => - import('@/lib/home/components/CategoryDynamic') -); +// const CategoryDynamic = dynamic(() => +// import('@/lib/home/components/CategoryDynamic') +// ); -const CategoryDynamicMobile = dynamic(() => - import('@/lib/home/components/CategoryDynamicMobile') -); +// const CategoryDynamicMobile = dynamic(() => +// import('@/lib/home/components/CategoryDynamicMobile') +// ); const CategoryDynamic = dynamic(() => @@ -86,7 +86,7 @@ const CustomerReviews = dynamic(() => ); const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); -export default function Home({categoryId}) { + export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); @@ -98,7 +98,7 @@ export default function Home({categoryId}) { bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; }; - const [dataCategories, setDataCategories] = useState([]) + // const [dataCategories, setDataCategories] = useState([]) useEffect(() => { const loadCategories = async () => { -- cgit v1.2.3 From ca30fe957369a16f6833d6a3bd37df74182b2911 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 14:45:17 +0700 Subject: update error code --- src/pages/index.jsx | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 0f2add9a..c720547e 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -1,7 +1,5 @@ import dynamic from 'next/dynamic'; import { useEffect, useRef, useState } from 'react'; -import { useEffect, useRef, useState } from 'react'; - import { HeroBannerSkeleton } from '@/components/skeleton/BannerSkeleton'; import { PopularProductSkeleton } from '@/components/skeleton/PopularProductSkeleton'; import Seo from '@/core/components/Seo'; @@ -13,15 +11,8 @@ import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBran import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; -// import CategoryDynamic from '../lib/home/components/CategoryDynamic'; import odooApi from '@/core/api/odooApi'; -import { getIdFromSlug } from '@/core/utils/slug' -import useProductDetail from '~/modules/product-detail/stores/useProductDetail'; import { getAuth } from '~/libs/auth'; -import CategoryPilihan from '../lib/home/components/CategoryPilihan'; -// import CategoryDynamic from '../lib/home/components/CategoryDynamic'; -import odooApi from '@/core/api/odooApi'; -import { getIdFromSlug } from '@/core/utils/slug' const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -64,15 +55,6 @@ const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId') ); -// const CategoryDynamic = dynamic(() => -// import('@/lib/home/components/CategoryDynamic') -// ); - -// const CategoryDynamicMobile = dynamic(() => -// import('@/lib/home/components/CategoryDynamicMobile') -// ); - - const CategoryDynamic = dynamic(() => import('@/lib/home/components/CategoryDynamic') ); -- cgit v1.2.3 From f6e0632292b1600341fccfd9d14c1ffe1be0f309 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 14:46:42 +0700 Subject: update error code --- src/pages/index.jsx | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index cdbe0dd0..578c4e2d 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -1,6 +1,5 @@ import dynamic from 'next/dynamic'; import { useEffect, useRef, useState } from 'react'; - import { HeroBannerSkeleton } from '@/components/skeleton/BannerSkeleton'; import { PopularProductSkeleton } from '@/components/skeleton/PopularProductSkeleton'; import Seo from '@/core/components/Seo'; @@ -12,9 +11,8 @@ import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBran import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; -// import CategoryDynamic from '../lib/home/components/CategoryDynamic'; import odooApi from '@/core/api/odooApi'; -import { getIdFromSlug } from '@/core/utils/slug' +import { getAuth } from '~/libs/auth'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -45,6 +43,11 @@ const FlashSale = dynamic( loading: () => , } ); + +const ProgramPromotion = dynamic(() => + import('@/lib/home/components/PromotionProgram') +); + const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection') ); @@ -65,17 +68,18 @@ const CustomerReviews = dynamic(() => ); const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); + export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); + const auth = getAuth(); + const handleOnLoad = () => { wrapperRef.current.style.height = bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; }; - const [dataCategories, setDataCategories] = useState([]) - useEffect(() => { const loadCategories = async () => { const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) @@ -86,6 +90,8 @@ export default function Home({categoryId}) { loadCategories() }, []) + const [dataCategories, setDataCategories] = useState([]) + return (
-
+
- + {!auth?.feature?.soApproval && ( + <> + + + )} + + @@ -151,11 +163,22 @@ export default function Home({categoryId}) {
+ {!auth?.feature?.soApproval && ( + <> + + + + + + + + )} - + - + + @@ -175,4 +198,4 @@ export default function Home({categoryId}) { ); -} +} \ No newline at end of file -- cgit v1.2.3 From c36d43c9b41eeb6f0c996476eaa8a2d13fbf42d1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 14:47:17 +0700 Subject: update error code --- src/pages/index.jsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index c720547e..578c4e2d 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -80,8 +80,6 @@ export default function Home({categoryId}) { bannerRef.current?.querySelector(':first-child')?.clientHeight + 'px'; }; - // const [dataCategories, setDataCategories] = useState([]) - useEffect(() => { const loadCategories = async () => { const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) @@ -94,16 +92,6 @@ export default function Home({categoryId}) { const [dataCategories, setDataCategories] = useState([]) - useEffect(() => { - const loadCategories = async () => { - const getCategories = await odooApi('GET', '/api/v1/category/child?partner_id='+{categoryId}) - if(getCategories){ - setDataCategories(getCategories) - } - } - loadCategories() - }, []) - return ( ); -} +} \ No newline at end of file -- cgit v1.2.3 From 70ac7c6ee5d13f1aca58904d4cc3db3998e7dee0 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 15:00:28 +0700 Subject: update error code --- src/pages/index.jsx | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 578c4e2d..6558f605 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -141,8 +141,6 @@ export default function Home({categoryId}) { - - @@ -180,10 +178,6 @@ export default function Home({categoryId}) { - - - - -- cgit v1.2.3 From e244185f6a83ad396be4d1f84bf22c2d6be0997e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 15:11:48 +0700 Subject: update error code --- src/pages/index.jsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 6558f605..60dcb9e0 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -44,10 +44,6 @@ const FlashSale = dynamic( } ); -const ProgramPromotion = dynamic(() => - import('@/lib/home/components/PromotionProgram') -); - const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection') ); @@ -135,7 +131,7 @@ export default function Home({categoryId}) {
{!auth?.feature?.soApproval && ( <> - + )} @@ -163,9 +159,6 @@ export default function Home({categoryId}) { {!auth?.feature?.soApproval && ( <> - - - -- cgit v1.2.3 From 44e1ed755b6714fbf76216ef914a8dfc73bef367 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 15:21:12 +0700 Subject: merge --- src/pages/index.jsx | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 578c4e2d..ad654922 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -13,6 +13,7 @@ import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; import odooApi from '@/core/api/odooApi'; import { getAuth } from '~/libs/auth'; +import { getAuth } from '~/libs/auth'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -92,6 +93,8 @@ export default function Home({categoryId}) { const [dataCategories, setDataCategories] = useState([]) + const [dataCategories, setDataCategories] = useState([]) + return (
+
-- cgit v1.2.3 From 233f2501a7ad23bedb8d02b7a3e7762632108098 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 15:23:28 +0700 Subject: update code --- src/pages/index.jsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index ad654922..0b2b6046 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -93,8 +93,6 @@ export default function Home({categoryId}) { const [dataCategories, setDataCategories] = useState([]) - const [dataCategories, setDataCategories] = useState([]) - return ( - -
+
@@ -184,10 +181,6 @@ export default function Home({categoryId}) { - - - - -- cgit v1.2.3 From d42a1c2bb522a3b29c60bbe75d0d250fa3fca6d8 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 23 Jul 2024 17:01:10 +0700 Subject: update category management --- src/lib/home/components/CategoryPilihan.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 7b9f0094..54807686 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -9,7 +9,7 @@ import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton' const CategoryPilihan = ({ id, categories }) => { - const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'index-a-1' })); + const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); return (
@@ -29,7 +29,7 @@ const CategoryPilihan = ({ id, categories }) => { quality={100} src={heroBanner.data[0].image} alt={heroBanner.data[0].name} - className='h-48 object-fill w-full rounded hover:scale-105 transition duration-500 ease-in-out' + className='h-48 object-fill w-full' /> {/* ))} */} @@ -41,9 +41,9 @@ const CategoryPilihan = ({ id, categories }) => { {categories.map((category) => (
-
-
- {category?.name} +
+
+ {category?.name}

{category?.name}

-- cgit v1.2.3 From 5214c9578aac1db612cd154cf04ee6d75750918d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 24 Jul 2024 08:49:05 +0700 Subject: update error code --- src/pages/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 0b2b6046..110d8b17 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -13,7 +13,7 @@ import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; import odooApi from '@/core/api/odooApi'; import { getAuth } from '~/libs/auth'; -import { getAuth } from '~/libs/auth'; +// import { getAuth } from '~/libs/auth'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') -- cgit v1.2.3 From 0768abc2828369a0c41a8042e0d005d32b5315ba Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 24 Jul 2024 08:59:29 +0700 Subject: update error code --- src/pages/index.jsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 60dcb9e0..0e4ee5e6 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -124,6 +124,7 @@ export default function Home({categoryId}) {
+
@@ -141,6 +142,7 @@ export default function Home({categoryId}) {
+
-- cgit v1.2.3 From a264e12c5af60e82f6e496209b6ac81d4a994a10 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 24 Jul 2024 09:06:05 +0700 Subject: merge category management to development --- src/lib/home/components/CategoryPilihan.jsx | 10 +++++----- src/pages/index.jsx | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 73e42626..5aa1fbcc 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -9,7 +9,7 @@ import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton' const CategoryPilihan = ({ id, categories }) => { - const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'index-a-1' })); + const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); return (
@@ -29,7 +29,7 @@ const CategoryPilihan = ({ id, categories }) => { quality={100} src={heroBanner.data[0].image} alt={heroBanner.data[0].name} - className='h-48 object-fill w-full rounded hover:scale-105 transition duration-500 ease-in-out' + className='h-48 object-fill w-full' /> {/* ))} */} @@ -41,9 +41,9 @@ const CategoryPilihan = ({ id, categories }) => { {categories.map((category) => (
-
-
- {category?.name} +
+
+ {category?.name}

{category?.name}

diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 110d8b17..30a7ac1f 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -70,6 +70,7 @@ const CustomerReviews = dynamic(() => const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); + export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); -- cgit v1.2.3 From 2e71abba4ca5b83cc1fec229d4d85961c4b56d71 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 25 Jul 2024 08:27:05 +0700 Subject: update category management --- src/lib/home/components/CategoryDynamic.jsx | 50 ++++++++++++++++++-------- src/lib/home/components/CategoryPilihan.jsx | 3 +- src/lib/product/components/CategorySection.jsx | 11 ++---- src/lib/product/components/ProductSearch.jsx | 35 ++++++++++++++++-- 4 files changed, 70 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index fa1df286..bbba2ceb 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -2,38 +2,58 @@ import React, { useEffect, useState } from 'react'; import useCategoryManagement from '../hooks/useCategoryManagement'; import NextImage from 'next/image'; import Link from "next/link"; -import router from 'next/router'; import { createSlug } from '@/core/utils/slug'; +import odooApi from '@/core/api/odooApi'; const CategoryDynamic = () => { const { categoryManagement } = useCategoryManagement(); + const [categoryData, setCategoryData] = useState({}); + const [subCategoryData, setSubCategoryData] = useState({}); + + useEffect(() => { + const fetchCategoryData = async () => { + if (categoryManagement && categoryManagement.data) { + const updatedCategoryData = {}; + const updatedSubCategoryData = {}; + + for (const category of categoryManagement.data) { + // Calculate level 1 products + const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); + // console.log("countLevel1.child",countLevel1) + + updatedCategoryData[category.categoryIdI] = countLevel1.numFound; + + + // Calculate level 2 products for each sub-category + for (const subCategory of countLevel1.children) { + updatedSubCategoryData[subCategory.id] = subCategory.numFound; + } + } - const calculateLevel3Products = (category) => { - return category.childFrontendIdI.reduce((total, child) => total + (child.numFound || 0), 0); - }; + setCategoryData(updatedCategoryData); + setSubCategoryData(updatedSubCategoryData); + } + }; - const calculateLevel2Products = (category) => { - return category.categories.reduce((total, subCategory) => { - const level3Products = calculateLevel3Products(subCategory); - return total + (subCategory.numFound || 0) + level3Products; - }, 0); - }; + fetchCategoryData(); + }, [categoryManagement, categoryData]); + return (
{categoryManagement && categoryManagement.data?.map((category) => { - const countLevel2 = calculateLevel2Products(category); - + const countLevel1 = categoryData[category.categoryIdI] || 0; + return (
{category.name}
-

{countLevel2} Produk tersedia

+

{countLevel1} Produk tersedia

Lihat Semua
{category.categories.map((subCategory) => { - const countLevel3 = calculateLevel3Products(subCategory); + const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; return (
@@ -48,7 +68,7 @@ const CategoryDynamic = () => { />
{subCategory.name}
-

{(subCategory.numFound || 0) + countLevel3} Produk

+

{countLevel2} Produk tersedia

Lihat Semua
diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 54807686..ea78b349 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -10,7 +10,6 @@ import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton' const CategoryPilihan = ({ id, categories }) => { const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); - return (
@@ -38,7 +37,7 @@ const CategoryPilihan = ({ id, categories }) => { )}
- {categories.map((category) => ( + {categories?.map((category) => (
diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 14a39e7e..2af3db10 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -13,23 +13,16 @@ import { HeartIcon, } from '@heroicons/react/24/outline'; import { useState } from 'react'; // Import useState +import { getIdFromSlug } from '@/core/utils/slug' const CategorySection = ({ categories }) => { const { isDesktop, isMobile } = useDevice(); - const router = useRouter(); const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility - let teks = router.query.slug; - let hasil = teks?.match(/(\d+)$/)[0]; - - const breadcrumbs = useQuery( - `category-breadcrumbs/${hasil}`, - async () => await odooApi('GET', `/api/v1/category/${hasil}/category-breadcrumb`) - ); - const handleToggleCategories = () => { setIsOpenCategory(!isOpenCategory); }; + const displayedCategories = isOpenCategory ? categories : categories.slice(0, 10); diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index c4970b21..b5c1e87d 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -28,6 +28,7 @@ import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; import CategorySection from './CategorySection'; import { getIdFromSlug } from '@/core/utils/slug' +import { data } from 'autoprefixer'; const ProductSearch = ({ query, @@ -63,6 +64,7 @@ const ProductSearch = ({ const [categoryValues, setCategory] = useState( query?.category?.split(',') || [] ); + const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null); const [priceTo, setPriceTo] = useState(query?.priceTo || null); @@ -71,6 +73,9 @@ const ProductSearch = ({ const productRows = limit; const productFound = productSearch.data?.response.numFound; const [dataCategories, setDataCategories] = useState([]) + const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const dataId = [] + // console.log("dataCategories",dataCategories) const categoryId = getIdFromSlug(prefixUrl) @@ -103,7 +108,7 @@ const ProductSearch = ({ }); } }, [productFound, query, spellings]); - + let id = [] useEffect(() => { const checkIfBrand = async () => { const brand = await axios( @@ -123,13 +128,37 @@ const ProductSearch = ({ useEffect(() => { const loadCategories = async () => { - const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) + const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) if(getCategories){ setDataCategories(getCategories) } } loadCategories() + + const loadProduct = async () => { + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`) + console.log("getCategoriesId",getCategoriesId) + if(getCategoriesId){ + setDataCategoriesProduct(getCategoriesId) + } + } + loadProduct() }, []) + collectIds(dataCategoriesProduct); + +// Fungsi rekursif untuk menambahkan ID dari kategori dan subkategori ke array dataId +function collectIds(category) { + if (category && category.id) { + dataId.push(category.id); + } + if (Array.isArray(category.children)) { + for (const child of category.children) { + collectIds(child); + } + } +} + +console.log("dataID",dataId) const brands = []; for ( @@ -275,7 +304,7 @@ const ProductSearch = ({ }; const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; - + console.log("query?.category?.split(',')",query.fq) return ( <> -- cgit v1.2.3 From 2c2885f57e9eb15e8c7d00c3a543a71c1d6ba83e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 25 Jul 2024 14:04:43 +0700 Subject: update search handle for category --- src/lib/product/components/ProductSearch.jsx | 83 ++++++++++++++++++---------- 1 file changed, 53 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index b5c1e87d..413f4fb2 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -42,9 +42,56 @@ const ProductSearch = ({ const [search, setSearch] = useState(query?.q || '*'); const [limit, setLimit] = useState(query?.limit || 30); const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); + const [finalQuery, setFinalQuery] = useState({}); + const [queryFinal, setQueryFinal] = useState({}); + const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const categoryId = getIdFromSlug(prefixUrl) if (defaultBrand) query.brand = defaultBrand.toLowerCase(); + useEffect(() => { + const loadProduct = async () => { + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`); + if (getCategoriesId) { + setDataCategoriesProduct(getCategoriesId); + } + }; + loadProduct(); + }, [categoryId]); + + const collectIds = (category) => { + const ids = []; + function recurse(cat) { + if (cat && cat.id) { + ids.push(cat.id); + } + if (Array.isArray(cat.children)) { + cat.children.forEach(recurse); + } + } + recurse(category); + return ids; + }; + + useEffect(() => { + const ids = collectIds(dataCategoriesProduct); + const newQuery = { + fq: `category_id_i:(${ids.join(' OR ')})`, + page: 1, + brand : router.query.brand? router.query.brand : '', + }; + setFinalQuery(newQuery); + }, [dataCategoriesProduct]); + + useEffect(() => { + if (prefixUrl.includes('category')) { + setQueryFinal({ ...finalQuery, q, limit, orderBy }); + // setQueryFinal({ ...query, q, limit, orderBy }); + } else { + setQueryFinal({ ...query, q, limit, orderBy }); + } + }, [prefixUrl, finalQuery, q, limit, orderBy]); + const { productSearch } = useProductSearch({ - query: { ...query, q, limit, orderBy }, + query: queryFinal, operation: 'AND', }); const [products, setProducts] = useState(null); @@ -73,12 +120,7 @@ const ProductSearch = ({ const productRows = limit; const productFound = productSearch.data?.response.numFound; const [dataCategories, setDataCategories] = useState([]) - const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) - const dataId = [] - // console.log("dataCategories",dataCategories) - - const categoryId = getIdFromSlug(prefixUrl) - + useEffect(() => { if (productFound == 0 && query.q && !spellings) { searchSpellApi({ query: query.q }).then((response) => { @@ -134,31 +176,10 @@ const ProductSearch = ({ } } loadCategories() - - const loadProduct = async () => { - const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`) - console.log("getCategoriesId",getCategoriesId) - if(getCategoriesId){ - setDataCategoriesProduct(getCategoriesId) - } - } - loadProduct() }, []) - collectIds(dataCategoriesProduct); -// Fungsi rekursif untuk menambahkan ID dari kategori dan subkategori ke array dataId -function collectIds(category) { - if (category && category.id) { - dataId.push(category.id); - } - if (Array.isArray(category.children)) { - for (const child of category.children) { - collectIds(child); - } - } -} + -console.log("dataID",dataId) const brands = []; for ( @@ -304,7 +325,9 @@ console.log("dataID",dataId) }; const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; - console.log("query?.category?.split(',')",query.fq) + + + return ( <> -- cgit v1.2.3 From 4758a0989f2ec0d79e1c5e3a3d42c249f28a9e72 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 26 Jul 2024 14:13:20 +0700 Subject: update code category management --- src/lib/product/components/ProductSearch.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 413f4fb2..cd7cda9f 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -74,7 +74,7 @@ const ProductSearch = ({ useEffect(() => { const ids = collectIds(dataCategoriesProduct); const newQuery = { - fq: `category_id_i:(${ids.join(' OR ')})`, + fq: `category_id_ids:(${ids.join(' OR ')})`, page: 1, brand : router.query.brand? router.query.brand : '', }; -- cgit v1.2.3 From e5a01976cb665b824b2ad6426a2c52a5bd0964e6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 27 Jul 2024 08:27:54 +0700 Subject: add feature category lob --- src/lib/home/api/CategoryPilihanApi.js | 8 +++ src/lib/home/components/CategoryDynamic.jsx | 2 +- src/lib/home/components/CategoryPilihan.jsx | 12 +++-- src/lib/home/hooks/useCategoryPilihan.js | 13 +++++ src/lib/product/components/ProductSearch.jsx | 5 +- src/pages/api/shop/product-homepage.js | 3 +- src/pages/api/shop/search.js | 2 +- src/pages/shop/lob/[slug].jsx | 73 ++++++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/lib/home/api/CategoryPilihanApi.js create mode 100644 src/lib/home/hooks/useCategoryPilihan.js create mode 100644 src/pages/shop/lob/[slug].jsx (limited to 'src') diff --git a/src/lib/home/api/CategoryPilihanApi.js b/src/lib/home/api/CategoryPilihanApi.js new file mode 100644 index 00000000..8a0b38d3 --- /dev/null +++ b/src/lib/home/api/CategoryPilihanApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi' + +const categoryPilihanApi = async () => { + const dataCategoryPilihan = await odooApi('GET', '/api/v1/lob_homepage') + return dataCategoryPilihan +} + +export default categoryPilihanApi diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index bbba2ceb..6ab03ec3 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -21,7 +21,7 @@ const CategoryDynamic = () => { const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); // console.log("countLevel1.child",countLevel1) - updatedCategoryData[category.categoryIdI] = countLevel1.numFound; + updatedCategoryData[category.categoryIdI] = countLevel1?.numFound; // Calculate level 2 products for each sub-category diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index ea78b349..9f184709 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -6,9 +6,11 @@ import { useEffect, useState } from 'react'; import { bannerApi } from '../../../api/bannerApi'; const { useQuery } = require('react-query') import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton'; - +import useCategoryPilihan from '../hooks/useCategoryPilihan'; const CategoryPilihan = ({ id, categories }) => { + const { categoryPilihan } = useCategoryPilihan(); + console.log("categoryPilihan",categoryPilihan) const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); return (
@@ -37,19 +39,19 @@ const CategoryPilihan = ({ id, categories }) => { )}
- {categories?.map((category) => ( + {categoryPilihan?.data?.map((category) => (
- {category?.name} + {category?.name}
-

{category?.name}

+

{category?.industries}

Lihat semua diff --git a/src/lib/home/hooks/useCategoryPilihan.js b/src/lib/home/hooks/useCategoryPilihan.js new file mode 100644 index 00000000..12a86f7e --- /dev/null +++ b/src/lib/home/hooks/useCategoryPilihan.js @@ -0,0 +1,13 @@ +import categoryPilihanApi from '../api/CategoryPilihanApi' +import { useQuery } from 'react-query' + +const useCategoryPilihan = () => { + const fetchCategoryPilihan = async () => await categoryPilihanApi() + const { isLoading, data } = useQuery('categoryPilihanApi', fetchCategoryPilihan) + + return { + categoryPilihan: { data, isLoading } + } +} + +export default useCategoryPilihan \ No newline at end of file diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index cd7cda9f..735ef58e 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -78,8 +78,9 @@ const ProductSearch = ({ page: 1, brand : router.query.brand? router.query.brand : '', }; + console.log("newQuery",newQuery) setFinalQuery(newQuery); - }, [dataCategoriesProduct]); + }, [dataCategoriesProduct, prefixUrl, prefixUrl, finalQuery, q, limit, orderBy]); useEffect(() => { if (prefixUrl.includes('category')) { @@ -178,7 +179,7 @@ const ProductSearch = ({ loadCategories() }, []) - + console.log("queryFinal", queryFinal) const brands = []; diff --git a/src/pages/api/shop/product-homepage.js b/src/pages/api/shop/product-homepage.js index 02c01ee0..61732c77 100644 --- a/src/pages/api/shop/product-homepage.js +++ b/src/pages/api/shop/product-homepage.js @@ -36,7 +36,8 @@ const respoonseMap = (productHomepage, products) => { name: productHomepage.name_s, image: productHomepage.image_s, url: productHomepage.url_s, - products: products + products: products, + categoryIds: productHomepage.category_id_ids, } return productMapped diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index b6b8c795..66f517ae 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -56,7 +56,7 @@ export default async function handler(req, res) { `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, - `fq=-publish_b:false`, + // `fq=-publish_b:false`, ]; if (priceFrom > 0 || priceTo > 0) { diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx new file mode 100644 index 00000000..be8db639 --- /dev/null +++ b/src/pages/shop/lob/[slug].jsx @@ -0,0 +1,73 @@ +import _ from 'lodash'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; +import Seo from '@/core/components/Seo'; +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; +import Breadcrumb from '@/lib/category/components/Breadcrumb'; +import { useEffect, useState } from 'react'; +import odooApi from '@/core/api/odooApi'; + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')); +const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')); +const CategorySection = dynamic(() => import('@/lib/product/components/CategorySection')); + +export default function CategoryDetail() { + const router = useRouter(); + const { slug = '', page = 1 } = router.query; + const [dataLob, setDataLob] = useState([]); + const [finalQuery, setFinalQuery] = useState({}); + + const categoryName = getNameFromSlug(slug); + const lobId = getIdFromSlug(slug); + + useEffect(() => { + const fetchCategoryData = async () => { + try { + const lobData = await odooApi('GET', `/api/v1/lob_homepage?lob_id=${lobId}`); + setDataLob(lobData); + } catch (error) { + console.error("Error fetching category data:", error); + } + }; + + fetchCategoryData(); + }, [lobId]); + + console.log("dataLob",dataLob) + + useEffect(() => { + const collectIds = (categories) => { + return categories?.categoryIds?.map(data => data.id) || []; + }; + + const ids = collectIds(dataLob[0]); + const newQuery = { + fq: `category_id_ids:(${ids.join(' OR ')})`, + page: 1, + brand: router.query.brand || '', + }; + setFinalQuery(newQuery); + console.log("finalQuery",finalQuery) + }, [dataLob, router.query.brand]); + + return ( + + + + + + {!_.isEmpty(router.query) && ( + + )} + + ); +} -- cgit v1.2.3 From f1910544cf6df50bcb175b66b604f5903f6ae3fa Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 27 Jul 2024 13:34:00 +0700 Subject: update category management for lob --- src/lib/home/components/CategoryPilihan.jsx | 1 - src/lib/lob/components/Breadcrumb.jsx | 55 ++++++++++++++++ src/lib/product/components/ProductSearch.jsx | 98 +++++++++++++++++++++------- src/pages/api/shop/search.js | 2 +- src/pages/shop/lob/[slug].jsx | 71 +++++++++++++++----- 5 files changed, 186 insertions(+), 41 deletions(-) create mode 100644 src/lib/lob/components/Breadcrumb.jsx (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 9f184709..5548fc1b 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -10,7 +10,6 @@ import useCategoryPilihan from '../hooks/useCategoryPilihan'; const CategoryPilihan = ({ id, categories }) => { const { categoryPilihan } = useCategoryPilihan(); - console.log("categoryPilihan",categoryPilihan) const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); return (
diff --git a/src/lib/lob/components/Breadcrumb.jsx b/src/lib/lob/components/Breadcrumb.jsx new file mode 100644 index 00000000..04d9a691 --- /dev/null +++ b/src/lib/lob/components/Breadcrumb.jsx @@ -0,0 +1,55 @@ +import odooApi from '@/core/api/odooApi' +import { createSlug } from '@/core/utils/slug' +import { + Breadcrumb as ChakraBreadcrumb, + BreadcrumbItem, + BreadcrumbLink, + Skeleton +} from '@chakra-ui/react' +import Link from 'next/link' +import React from 'react' +import { useQuery } from 'react-query' + +/** + * Render a breadcrumb component. + * + * @param {object} categoryId - The ID of the category. + * @return {JSX.Element} The breadcrumb component. + */ +const Breadcrumb = ({ categoryId }) => { + const breadcrumbs = useQuery( + `lob-breadcrumbs/${categoryId}`, + async () => await odooApi('GET', `/api/v1/lob_homepage?lob_id=${categoryId}`) + ) + return ( +
+ + + + + Home + + + + {breadcrumbs.data?.map((category, index) => ( + + {index === breadcrumbs.data.length - 1 ? ( + {category.industries} + ) : ( + + {category.industries} + + )} + + ))} + + +
+ ) +} + +export default Breadcrumb diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 735ef58e..2da84d63 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -37,6 +37,7 @@ const ProductSearch = ({ brand = null, }) => { const router = useRouter(); + const { page = 1 } = query; const [q, setQ] = useState(query?.q || '*'); const [search, setSearch] = useState(query?.q || '*'); @@ -45,18 +46,35 @@ const ProductSearch = ({ const [finalQuery, setFinalQuery] = useState({}); const [queryFinal, setQueryFinal] = useState({}); const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const [dataCategoriesLob, setDataCategoriesLob] = useState([]) const categoryId = getIdFromSlug(prefixUrl) + console.log("categoryId",categoryId ) + const [data, setData] = useState([]) + const [dataLob, setDataLob] = useState([]); if (defaultBrand) query.brand = defaultBrand.toLowerCase(); + const dataIdCategories = [] useEffect(() => { - const loadProduct = async () => { - const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`); - if (getCategoriesId) { - setDataCategoriesProduct(getCategoriesId); - } - }; - loadProduct(); + if(prefixUrl.includes('category')){ + const loadProduct = async () => { + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`); + if (getCategoriesId) { + setDataCategoriesProduct(getCategoriesId); + } + }; + loadProduct(); + }else if(prefixUrl.includes('lob')){ + const loadProduct = async () => { + const lobData = await odooApi('GET', `/api/v1/lob_homepage?lob_id=${categoryId}`); + console.log("lobData",lobData ) + if (lobData) { + setDataLob(lobData); + } + }; + loadProduct(); + console.log("dataLob",dataLob ) + } }, [categoryId]); - + const collectIds = (category) => { const ids = []; function recurse(cat) { @@ -70,26 +88,61 @@ const ProductSearch = ({ recurse(category); return ids; }; - + useEffect(() => { - const ids = collectIds(dataCategoriesProduct); - const newQuery = { - fq: `category_id_ids:(${ids.join(' OR ')})`, - page: 1, - brand : router.query.brand? router.query.brand : '', - }; - console.log("newQuery",newQuery) - setFinalQuery(newQuery); - }, [dataCategoriesProduct, prefixUrl, prefixUrl, finalQuery, q, limit, orderBy]); + if(prefixUrl.includes('category')){ + const ids = collectIds(dataCategoriesProduct); + const newQuery = { + fq: `category_id_ids:(${ids.join(' OR ')})`, + page, + brand : router.query.brand? router.query.brand : '', + category : router.query.category? router.query.category : '', + }; + setFinalQuery(newQuery); + } else if (prefixUrl.includes('lob')){ + console.log("prefixUrl",prefixUrl) + const fetchCategoryData = async () => { + if (dataLob[0]?.categoryIds) { + console.log("dataLob[0]?.categoryIds",dataLob[0]?.categoryIds) + for (const cate of dataLob[0].categoryIds) { + console.log("cate",cate) + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${cate.id}`); + console.log("getCategoriesId",getCategoriesId) + if (getCategoriesId) { + const ids = collectIds(getCategoriesId); + console.log("ids",ids) + dataIdCategories.push(ids) + console.log("dataIdCategories",dataIdCategories) + } + } + + console.log("dataIdCategories2",dataIdCategories) + // setData(dataIdCategories) + // console.log("data",data) + const mergedArray = dataIdCategories.flat(); + console.log("mergedArray",mergedArray) + const newQuery = { + fq: `category_id_ids:(${mergedArray.join(' OR ')})`, + page, + brand : router.query.brand? router.query.brand : '', + category : router.query.category? router.query.category : '', + }; + console.log("newQuery",newQuery) + setFinalQuery(newQuery); + console.log("final query",finalQuery) + } + }; + fetchCategoryData(); + } + }, [dataCategoriesProduct, dataLob]); useEffect(() => { - if (prefixUrl.includes('category')) { + if (prefixUrl.includes('category') || prefixUrl.includes('lob')) { setQueryFinal({ ...finalQuery, q, limit, orderBy }); - // setQueryFinal({ ...query, q, limit, orderBy }); } else { setQueryFinal({ ...query, q, limit, orderBy }); } - }, [prefixUrl, finalQuery, q, limit, orderBy]); + }, [prefixUrl,dataCategoriesProduct, query, finalQuery]); const { productSearch } = useProductSearch({ query: queryFinal, @@ -179,7 +232,8 @@ const ProductSearch = ({ loadCategories() }, []) - console.log("queryFinal", queryFinal) + // console.log("query asal ", query) + // console.log("queryFinal", queryFinal) const brands = []; diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 66f517ae..b6b8c795 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -56,7 +56,7 @@ export default async function handler(req, res) { `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, - // `fq=-publish_b:false`, + `fq=-publish_b:false`, ]; if (priceFrom > 0 || priceTo > 0) { diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx index be8db639..d02ec8ac 100644 --- a/src/pages/shop/lob/[slug].jsx +++ b/src/pages/shop/lob/[slug].jsx @@ -3,9 +3,10 @@ import dynamic from 'next/dynamic'; import { useRouter } from 'next/router'; import Seo from '@/core/components/Seo'; import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; -import Breadcrumb from '@/lib/category/components/Breadcrumb'; +import Breadcrumb from '../../../lib/lob/components/Breadcrumb'; import { useEffect, useState } from 'react'; import odooApi from '@/core/api/odooApi'; +import { div } from 'lodash-contrib'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')); const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')); @@ -16,9 +17,20 @@ export default function CategoryDetail() { const { slug = '', page = 1 } = router.query; const [dataLob, setDataLob] = useState([]); const [finalQuery, setFinalQuery] = useState({}); + const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const [data, setData] = useState([]) + const dataIdCategories = [] const categoryName = getNameFromSlug(slug); const lobId = getIdFromSlug(slug); + const q = router?.query.q || null; + const query = { + fq: `id:${lobId}`, + page, + }; + if (q) { + query.q = q; + } useEffect(() => { const fetchCategoryData = async () => { @@ -33,22 +45,40 @@ export default function CategoryDetail() { fetchCategoryData(); }, [lobId]); - console.log("dataLob",dataLob) - + const collectIdsCategory = (category) => { + const ids = []; + function recurse(cat) { + if (cat && cat.id) { + ids.push(cat.id); + } + if (Array.isArray(cat.children)) { + cat.children.forEach(recurse); + } + } + recurse(category); + return ids; + }; useEffect(() => { - const collectIds = (categories) => { - return categories?.categoryIds?.map(data => data.id) || []; - }; - - const ids = collectIds(dataLob[0]); - const newQuery = { - fq: `category_id_ids:(${ids.join(' OR ')})`, - page: 1, - brand: router.query.brand || '', - }; - setFinalQuery(newQuery); - console.log("finalQuery",finalQuery) - }, [dataLob, router.query.brand]); + const fetchCategoryData = async () => { + if (dataLob[0]?.categoryIds) { + for (const category of dataLob[0].categoryIds) { + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.id}`); + if (getCategoriesId) { + setDataCategoriesProduct(getCategoriesId); + const ids = collectIdsCategory(getCategoriesId); + dataIdCategories.push(ids) + } + } + setData(dataIdCategories) + } + }; + fetchCategoryData(); + const mergedArray = data.flat(); + const newQuery = { + fq: `category_id_ids:(${mergedArray.join(' OR ')})`, + }; + setFinalQuery(newQuery); + }, [dataLob, ]); return ( @@ -64,9 +94,16 @@ export default function CategoryDetail() { /> +
+ {dataLob[0]?.categoryIds && ( +
+ +
+ )} +
{!_.isEmpty(router.query) && ( - + )}
); -- cgit v1.2.3 From 556e7e226a2043d43bc55bf0ff2118294bb9f330 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 13:32:39 +0700 Subject: update lob category --- src/lib/lob/components/Breadcrumb.jsx | 4 +- src/lib/product/components/LobSectionCategory.jsx | 89 +++++++++++++++++++++++ src/lib/product/components/ProductSearch.jsx | 54 ++++++-------- src/pages/shop/lob/[slug].jsx | 48 ------------ 4 files changed, 115 insertions(+), 80 deletions(-) create mode 100644 src/lib/product/components/LobSectionCategory.jsx (limited to 'src') diff --git a/src/lib/lob/components/Breadcrumb.jsx b/src/lib/lob/components/Breadcrumb.jsx index 04d9a691..5722fd39 100644 --- a/src/lib/lob/components/Breadcrumb.jsx +++ b/src/lib/lob/components/Breadcrumb.jsx @@ -19,7 +19,7 @@ import { useQuery } from 'react-query' const Breadcrumb = ({ categoryId }) => { const breadcrumbs = useQuery( `lob-breadcrumbs/${categoryId}`, - async () => await odooApi('GET', `/api/v1/lob_homepage?lob_id=${categoryId}`) + async () => await odooApi('GET', `/api/v1/lob_homepage/${categoryId}/category_id`) ) return (
@@ -31,7 +31,7 @@ const Breadcrumb = ({ categoryId }) => { - {breadcrumbs.data?.map((category, index) => ( + {breadcrumbs?.data?.map((category, index) => ( {index === breadcrumbs.data.length - 1 ? ( {category.industries} diff --git a/src/lib/product/components/LobSectionCategory.jsx b/src/lib/product/components/LobSectionCategory.jsx new file mode 100644 index 00000000..5e9934c3 --- /dev/null +++ b/src/lib/product/components/LobSectionCategory.jsx @@ -0,0 +1,89 @@ +import Image from "next/image"; +import Link from 'next/link'; +import { createSlug } from '@/core/utils/slug'; +import useDevice from '@/core/hooks/useDevice'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; +import { useQuery } from 'react-query'; +import { useRouter } from 'next/router'; +import { + ChevronDownIcon, + ChevronUpIcon, // Import ChevronUpIcon for toggling + DocumentCheckIcon, + HeartIcon, +} from '@heroicons/react/24/outline'; +import { useState } from 'react'; // Import useState +import { getIdFromSlug } from '@/core/utils/slug' + +const LobSectionCategory = ({ categories }) => { + const { isDesktop, isMobile } = useDevice(); + const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility + + const handleToggleCategories = () => { + setIsOpenCategory(!isOpenCategory); + }; + console.log("categories",categories[0]?.categoryIds) + + const displayedCategories = categories[0]?.categoryIds; + + return ( +
+ {isDesktop && ( +
+ {displayedCategories?.map((category) => ( + +
+
+
+ {category?.name} + {/*

{category?.name}

*/} +
+
+
+ + ))} +
+ )} + + {isMobile && ( +
+ + {displayedCategories.map((category) => ( + + +
+
+
+ {category?.name} +

+ {category?.name} +

+
+
+
+ +
+ ))} +
+ {categories.length > 10 && ( +
+ +
+ )} +
+ )} +
+ ) +} + +export default LobSectionCategory diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 2da84d63..12e3b358 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -27,6 +27,7 @@ import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; import CategorySection from './CategorySection'; +import LobSectionCategory from './LobSectionCategory'; import { getIdFromSlug } from '@/core/utils/slug' import { data } from 'autoprefixer'; @@ -48,7 +49,6 @@ const ProductSearch = ({ const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) const [dataCategoriesLob, setDataCategoriesLob] = useState([]) const categoryId = getIdFromSlug(prefixUrl) - console.log("categoryId",categoryId ) const [data, setData] = useState([]) const [dataLob, setDataLob] = useState([]); if (defaultBrand) query.brand = defaultBrand.toLowerCase(); @@ -64,14 +64,14 @@ const ProductSearch = ({ loadProduct(); }else if(prefixUrl.includes('lob')){ const loadProduct = async () => { - const lobData = await odooApi('GET', `/api/v1/lob_homepage?lob_id=${categoryId}`); - console.log("lobData",lobData ) + const lobData = await odooApi('GET', `/api/v1/lob_homepage/${categoryId}/category_id`); + if (lobData) { setDataLob(lobData); } }; loadProduct(); - console.log("dataLob",dataLob ) + } }, [categoryId]); @@ -100,36 +100,27 @@ const ProductSearch = ({ }; setFinalQuery(newQuery); } else if (prefixUrl.includes('lob')){ - console.log("prefixUrl",prefixUrl) + const fetchCategoryData = async () => { if (dataLob[0]?.categoryIds) { - console.log("dataLob[0]?.categoryIds",dataLob[0]?.categoryIds) + for (const cate of dataLob[0].categoryIds) { - console.log("cate",cate) - const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${cate.id}`); - console.log("getCategoriesId",getCategoriesId) - if (getCategoriesId) { - const ids = collectIds(getCategoriesId); - console.log("ids",ids) - dataIdCategories.push(ids) - console.log("dataIdCategories",dataIdCategories) - } + + dataIdCategories.push(cate.childId) } - console.log("dataIdCategories2",dataIdCategories) - // setData(dataIdCategories) - // console.log("data",data) + const mergedArray = dataIdCategories.flat(); - console.log("mergedArray",mergedArray) + const newQuery = { fq: `category_id_ids:(${mergedArray.join(' OR ')})`, page, brand : router.query.brand? router.query.brand : '', category : router.query.category? router.query.category : '', }; - console.log("newQuery",newQuery) + setFinalQuery(newQuery); - console.log("final query",finalQuery) + } }; fetchCategoryData(); @@ -223,17 +214,18 @@ const ProductSearch = ({ }, [q]); useEffect(() => { - const loadCategories = async () => { - const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) - if(getCategories){ - setDataCategories(getCategories) - } + if(prefixUrl.includes('category')){ + const loadCategories = async () => { + const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() } - loadCategories() }, []) - // console.log("query asal ", query) - // console.log("queryFinal", queryFinal) + const brands = []; @@ -381,7 +373,7 @@ const ProductSearch = ({ const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; - + console.log("finalQuery",finalQuery) return ( <> @@ -443,6 +435,7 @@ const ProductSearch = ({ SpellingComponent )}
+ {productFound > 0 && ( @@ -534,6 +527,7 @@ const ProductSearch = ({
+ {bannerPromotionHeader && bannerPromotionHeader?.image && (
diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx index d02ec8ac..2153b565 100644 --- a/src/pages/shop/lob/[slug].jsx +++ b/src/pages/shop/lob/[slug].jsx @@ -32,54 +32,6 @@ export default function CategoryDetail() { query.q = q; } - useEffect(() => { - const fetchCategoryData = async () => { - try { - const lobData = await odooApi('GET', `/api/v1/lob_homepage?lob_id=${lobId}`); - setDataLob(lobData); - } catch (error) { - console.error("Error fetching category data:", error); - } - }; - - fetchCategoryData(); - }, [lobId]); - - const collectIdsCategory = (category) => { - const ids = []; - function recurse(cat) { - if (cat && cat.id) { - ids.push(cat.id); - } - if (Array.isArray(cat.children)) { - cat.children.forEach(recurse); - } - } - recurse(category); - return ids; - }; - useEffect(() => { - const fetchCategoryData = async () => { - if (dataLob[0]?.categoryIds) { - for (const category of dataLob[0].categoryIds) { - const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.id}`); - if (getCategoriesId) { - setDataCategoriesProduct(getCategoriesId); - const ids = collectIdsCategory(getCategoriesId); - dataIdCategories.push(ids) - } - } - setData(dataIdCategories) - } - }; - fetchCategoryData(); - const mergedArray = data.flat(); - const newQuery = { - fq: `category_id_ids:(${mergedArray.join(' OR ')})`, - }; - setFinalQuery(newQuery); - }, [dataLob, ]); - return ( Date: Mon, 29 Jul 2024 14:15:41 +0700 Subject: update top banner --- src/core/components/elements/Navbar/TopBanner.jsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 722a7501..83ef8c7a 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -4,6 +4,7 @@ import { useQuery } from 'react-query'; import odooApi from '@/core/api/odooApi'; import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; +import { background } from '@chakra-ui/react'; const TopBanner = () => { const topBanner = useQuery({ @@ -12,7 +13,7 @@ const TopBanner = () => { refetchOnWindowFocus: false, }); - const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; + // const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; const hasData = topBanner.data?.length > 0; const data = topBanner.data?.[0] || null; @@ -22,16 +23,17 @@ const TopBanner = () => { height='36px' duration='700ms' delay='300ms' - style={{ backgroundColor }} > - - {data?.name} + ); -- cgit v1.2.3 From 1a58c55e6415d78f5d155055071a649d1f56492a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 14:52:57 +0700 Subject: update mobile view --- src/lib/product/components/LobSectionCategory.jsx | 51 ++++++++++------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/LobSectionCategory.jsx b/src/lib/product/components/LobSectionCategory.jsx index 5e9934c3..34a09e46 100644 --- a/src/lib/product/components/LobSectionCategory.jsx +++ b/src/lib/product/components/LobSectionCategory.jsx @@ -29,43 +29,36 @@ const LobSectionCategory = ({ categories }) => { return (
{isDesktop && ( -
+
{displayedCategories?.map((category) => ( - -
-
-
- {category?.name} - {/*

{category?.name}

*/} -
-
-
- + + ))}
)} {isMobile && (
- - {displayedCategories.map((category) => ( + + {displayedCategories?.map((category) => ( - -
-
-
- {category?.name} -

- {category?.name} -

-
-
-
+
))} -- cgit v1.2.3 From 1f07818ba6718755684de5863e01636805b80867 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 15:16:00 +0700 Subject: update to avoid conflict --- src/pages/index.jsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 0e4ee5e6..30a7ac1f 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -13,6 +13,7 @@ import PagePopupIformation from '~/modules/popup-information'; import CategoryPilihan from '../lib/home/components/CategoryPilihan'; import odooApi from '@/core/api/odooApi'; import { getAuth } from '~/libs/auth'; +// import { getAuth } from '~/libs/auth'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -44,6 +45,10 @@ const FlashSale = dynamic( } ); +const ProgramPromotion = dynamic(() => + import('@/lib/home/components/PromotionProgram') +); + const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection') ); @@ -65,6 +70,7 @@ const CustomerReviews = dynamic(() => const ServiceList = dynamic(() => import('@/lib/home/components/ServiceList')); + export default function Home({categoryId}) { const bannerRef = useRef(null); const wrapperRef = useRef(null); @@ -132,7 +138,7 @@ export default function Home({categoryId}) {
{!auth?.feature?.soApproval && ( <> - + )} @@ -161,6 +167,9 @@ export default function Home({categoryId}) { {!auth?.feature?.soApproval && ( <> + + + -- cgit v1.2.3 From a59ed6e73a599a82d6ef248c57ad29f2ab9cb15d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 15:23:01 +0700 Subject: Merge branch 'Feature/category-management' into development --- src/core/components/elements/Navbar/TopBanner.jsx | 22 ++-- src/lib/home/api/CategoryPilihanApi.js | 8 ++ src/lib/home/components/CategoryDynamic.jsx | 50 ++++++--- src/lib/home/components/CategoryPilihan.jsx | 14 +-- src/lib/home/hooks/useCategoryPilihan.js | 13 +++ src/lib/lob/components/Breadcrumb.jsx | 55 ++++++++++ src/lib/product/components/CategorySection.jsx | 11 +- src/lib/product/components/LobSectionCategory.jsx | 82 +++++++++++++++ src/lib/product/components/ProductSearch.jsx | 123 ++++++++++++++++++++-- src/pages/api/shop/product-homepage.js | 3 +- src/pages/shop/lob/[slug].jsx | 62 +++++++++++ 11 files changed, 390 insertions(+), 53 deletions(-) create mode 100644 src/lib/home/api/CategoryPilihanApi.js create mode 100644 src/lib/home/hooks/useCategoryPilihan.js create mode 100644 src/lib/lob/components/Breadcrumb.jsx create mode 100644 src/lib/product/components/LobSectionCategory.jsx create mode 100644 src/pages/shop/lob/[slug].jsx (limited to 'src') diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 722a7501..83ef8c7a 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -4,6 +4,7 @@ import { useQuery } from 'react-query'; import odooApi from '@/core/api/odooApi'; import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; +import { background } from '@chakra-ui/react'; const TopBanner = () => { const topBanner = useQuery({ @@ -12,7 +13,7 @@ const TopBanner = () => { refetchOnWindowFocus: false, }); - const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; + // const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; const hasData = topBanner.data?.length > 0; const data = topBanner.data?.[0] || null; @@ -22,16 +23,17 @@ const TopBanner = () => { height='36px' duration='700ms' delay='300ms' - style={{ backgroundColor }} > - - {data?.name} + ); diff --git a/src/lib/home/api/CategoryPilihanApi.js b/src/lib/home/api/CategoryPilihanApi.js new file mode 100644 index 00000000..8a0b38d3 --- /dev/null +++ b/src/lib/home/api/CategoryPilihanApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi' + +const categoryPilihanApi = async () => { + const dataCategoryPilihan = await odooApi('GET', '/api/v1/lob_homepage') + return dataCategoryPilihan +} + +export default categoryPilihanApi diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index fa1df286..6ab03ec3 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -2,38 +2,58 @@ import React, { useEffect, useState } from 'react'; import useCategoryManagement from '../hooks/useCategoryManagement'; import NextImage from 'next/image'; import Link from "next/link"; -import router from 'next/router'; import { createSlug } from '@/core/utils/slug'; +import odooApi from '@/core/api/odooApi'; const CategoryDynamic = () => { const { categoryManagement } = useCategoryManagement(); + const [categoryData, setCategoryData] = useState({}); + const [subCategoryData, setSubCategoryData] = useState({}); + + useEffect(() => { + const fetchCategoryData = async () => { + if (categoryManagement && categoryManagement.data) { + const updatedCategoryData = {}; + const updatedSubCategoryData = {}; + + for (const category of categoryManagement.data) { + // Calculate level 1 products + const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); + // console.log("countLevel1.child",countLevel1) + + updatedCategoryData[category.categoryIdI] = countLevel1?.numFound; + + + // Calculate level 2 products for each sub-category + for (const subCategory of countLevel1.children) { + updatedSubCategoryData[subCategory.id] = subCategory.numFound; + } + } - const calculateLevel3Products = (category) => { - return category.childFrontendIdI.reduce((total, child) => total + (child.numFound || 0), 0); - }; + setCategoryData(updatedCategoryData); + setSubCategoryData(updatedSubCategoryData); + } + }; - const calculateLevel2Products = (category) => { - return category.categories.reduce((total, subCategory) => { - const level3Products = calculateLevel3Products(subCategory); - return total + (subCategory.numFound || 0) + level3Products; - }, 0); - }; + fetchCategoryData(); + }, [categoryManagement, categoryData]); + return (
{categoryManagement && categoryManagement.data?.map((category) => { - const countLevel2 = calculateLevel2Products(category); - + const countLevel1 = categoryData[category.categoryIdI] || 0; + return (
{category.name}
-

{countLevel2} Produk tersedia

+

{countLevel1} Produk tersedia

Lihat Semua
{category.categories.map((subCategory) => { - const countLevel3 = calculateLevel3Products(subCategory); + const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; return (
@@ -48,7 +68,7 @@ const CategoryDynamic = () => { />
{subCategory.name}
-

{(subCategory.numFound || 0) + countLevel3} Produk

+

{countLevel2} Produk tersedia

Lihat Semua
diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 5aa1fbcc..6efc1070 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -6,11 +6,11 @@ import { useEffect, useState } from 'react'; import { bannerApi } from '../../../api/bannerApi'; const { useQuery } = require('react-query') import { HeroBannerSkeleton } from '../../../components/skeleton/BannerSkeleton'; - +import useCategoryPilihan from '../hooks/useCategoryPilihan'; const CategoryPilihan = ({ id, categories }) => { + const { categoryPilihan } = useCategoryPilihan(); const heroBanner = useQuery('categoryPilihan', bannerApi({ type: 'banner-category-list' })); - return (
@@ -38,19 +38,19 @@ const CategoryPilihan = ({ id, categories }) => { )}
- {categories.map((category) => ( -
+ {categoryPilihan?.data?.map((category) => ( +
- {category?.name} + {category?.name}
-

{category?.name}

+

{category?.industries}

Lihat semua diff --git a/src/lib/home/hooks/useCategoryPilihan.js b/src/lib/home/hooks/useCategoryPilihan.js new file mode 100644 index 00000000..12a86f7e --- /dev/null +++ b/src/lib/home/hooks/useCategoryPilihan.js @@ -0,0 +1,13 @@ +import categoryPilihanApi from '../api/CategoryPilihanApi' +import { useQuery } from 'react-query' + +const useCategoryPilihan = () => { + const fetchCategoryPilihan = async () => await categoryPilihanApi() + const { isLoading, data } = useQuery('categoryPilihanApi', fetchCategoryPilihan) + + return { + categoryPilihan: { data, isLoading } + } +} + +export default useCategoryPilihan \ No newline at end of file diff --git a/src/lib/lob/components/Breadcrumb.jsx b/src/lib/lob/components/Breadcrumb.jsx new file mode 100644 index 00000000..5722fd39 --- /dev/null +++ b/src/lib/lob/components/Breadcrumb.jsx @@ -0,0 +1,55 @@ +import odooApi from '@/core/api/odooApi' +import { createSlug } from '@/core/utils/slug' +import { + Breadcrumb as ChakraBreadcrumb, + BreadcrumbItem, + BreadcrumbLink, + Skeleton +} from '@chakra-ui/react' +import Link from 'next/link' +import React from 'react' +import { useQuery } from 'react-query' + +/** + * Render a breadcrumb component. + * + * @param {object} categoryId - The ID of the category. + * @return {JSX.Element} The breadcrumb component. + */ +const Breadcrumb = ({ categoryId }) => { + const breadcrumbs = useQuery( + `lob-breadcrumbs/${categoryId}`, + async () => await odooApi('GET', `/api/v1/lob_homepage/${categoryId}/category_id`) + ) + return ( +
+ + + + + Home + + + + {breadcrumbs?.data?.map((category, index) => ( + + {index === breadcrumbs.data.length - 1 ? ( + {category.industries} + ) : ( + + {category.industries} + + )} + + ))} + + +
+ ) +} + +export default Breadcrumb diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx index 14a39e7e..2af3db10 100644 --- a/src/lib/product/components/CategorySection.jsx +++ b/src/lib/product/components/CategorySection.jsx @@ -13,23 +13,16 @@ import { HeartIcon, } from '@heroicons/react/24/outline'; import { useState } from 'react'; // Import useState +import { getIdFromSlug } from '@/core/utils/slug' const CategorySection = ({ categories }) => { const { isDesktop, isMobile } = useDevice(); - const router = useRouter(); const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility - let teks = router.query.slug; - let hasil = teks?.match(/(\d+)$/)[0]; - - const breadcrumbs = useQuery( - `category-breadcrumbs/${hasil}`, - async () => await odooApi('GET', `/api/v1/category/${hasil}/category-breadcrumb`) - ); - const handleToggleCategories = () => { setIsOpenCategory(!isOpenCategory); }; + const displayedCategories = isOpenCategory ? categories : categories.slice(0, 10); diff --git a/src/lib/product/components/LobSectionCategory.jsx b/src/lib/product/components/LobSectionCategory.jsx new file mode 100644 index 00000000..34a09e46 --- /dev/null +++ b/src/lib/product/components/LobSectionCategory.jsx @@ -0,0 +1,82 @@ +import Image from "next/image"; +import Link from 'next/link'; +import { createSlug } from '@/core/utils/slug'; +import useDevice from '@/core/hooks/useDevice'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import 'swiper/css'; +import { useQuery } from 'react-query'; +import { useRouter } from 'next/router'; +import { + ChevronDownIcon, + ChevronUpIcon, // Import ChevronUpIcon for toggling + DocumentCheckIcon, + HeartIcon, +} from '@heroicons/react/24/outline'; +import { useState } from 'react'; // Import useState +import { getIdFromSlug } from '@/core/utils/slug' + +const LobSectionCategory = ({ categories }) => { + const { isDesktop, isMobile } = useDevice(); + const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility + + const handleToggleCategories = () => { + setIsOpenCategory(!isOpenCategory); + }; + console.log("categories",categories[0]?.categoryIds) + + const displayedCategories = categories[0]?.categoryIds; + + return ( +
+ {isDesktop && ( +
+ {displayedCategories?.map((category) => ( + + + ))} +
+ )} + + {isMobile && ( +
+ + {displayedCategories?.map((category) => ( + + + + + ))} + + {categories.length > 10 && ( +
+ +
+ )} +
+ )} +
+ ) +} + +export default LobSectionCategory diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 34018ffe..4d510c5b 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -27,7 +27,9 @@ import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; import CategorySection from './CategorySection'; +import LobSectionCategory from './LobSectionCategory'; import { getIdFromSlug } from '@/core/utils/slug' +import { data } from 'autoprefixer'; const ProductSearch = ({ query, @@ -36,14 +38,105 @@ const ProductSearch = ({ brand = null, }) => { const router = useRouter(); + const { page = 1 } = query; const [q, setQ] = useState(query?.q || '*'); const [search, setSearch] = useState(query?.q || '*'); const [limit, setLimit] = useState(query?.limit || 30); const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); + const [finalQuery, setFinalQuery] = useState({}); + const [queryFinal, setQueryFinal] = useState({}); + const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const [dataCategoriesLob, setDataCategoriesLob] = useState([]) + const categoryId = getIdFromSlug(prefixUrl) + const [data, setData] = useState([]) + const [dataLob, setDataLob] = useState([]); if (defaultBrand) query.brand = defaultBrand.toLowerCase(); + const dataIdCategories = [] + useEffect(() => { + if(prefixUrl.includes('category')){ + const loadProduct = async () => { + const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`); + if (getCategoriesId) { + setDataCategoriesProduct(getCategoriesId); + } + }; + loadProduct(); + }else if(prefixUrl.includes('lob')){ + const loadProduct = async () => { + const lobData = await odooApi('GET', `/api/v1/lob_homepage/${categoryId}/category_id`); + + if (lobData) { + setDataLob(lobData); + } + }; + loadProduct(); + + } + }, [categoryId]); + + const collectIds = (category) => { + const ids = []; + function recurse(cat) { + if (cat && cat.id) { + ids.push(cat.id); + } + if (Array.isArray(cat.children)) { + cat.children.forEach(recurse); + } + } + recurse(category); + return ids; + }; + + useEffect(() => { + if(prefixUrl.includes('category')){ + const ids = collectIds(dataCategoriesProduct); + const newQuery = { + fq: `category_id_ids:(${ids.join(' OR ')})`, + page, + brand : router.query.brand? router.query.brand : '', + category : router.query.category? router.query.category : '', + }; + setFinalQuery(newQuery); + } else if (prefixUrl.includes('lob')){ + + const fetchCategoryData = async () => { + if (dataLob[0]?.categoryIds) { + + for (const cate of dataLob[0].categoryIds) { + + dataIdCategories.push(cate.childId) + } + + + const mergedArray = dataIdCategories.flat(); + + const newQuery = { + fq: `category_id_ids:(${mergedArray.join(' OR ')})`, + page, + brand : router.query.brand? router.query.brand : '', + category : router.query.category? router.query.category : '', + }; + + setFinalQuery(newQuery); + + } + }; + fetchCategoryData(); + } + }, [dataCategoriesProduct, dataLob]); + + useEffect(() => { + if (prefixUrl.includes('category') || prefixUrl.includes('lob')) { + setQueryFinal({ ...finalQuery, q, limit, orderBy }); + } else { + setQueryFinal({ ...query, q, limit, orderBy }); + } + }, [prefixUrl,dataCategoriesProduct, query, finalQuery]); + const { productSearch } = useProductSearch({ - query: { ...query, q, limit, orderBy }, + query: queryFinal, operation: 'AND', }); const [products, setProducts] = useState(null); @@ -63,6 +156,7 @@ const ProductSearch = ({ const [categoryValues, setCategory] = useState( query?.category?.split(',') || [] ); + const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null); const [priceTo, setPriceTo] = useState(query?.priceTo || null); @@ -71,9 +165,7 @@ const ProductSearch = ({ const productRows = limit; const productFound = productSearch.data?.response.numFound; const [dataCategories, setDataCategories] = useState([]) - - const categoryId = getIdFromSlug(prefixUrl) - + useEffect(() => { if (productFound == 0 && query.q && !spellings) { searchSpellApi({ query: query.q }).then((response) => { @@ -103,7 +195,7 @@ const ProductSearch = ({ }); } }, [productFound, query, spellings]); - + let id = [] useEffect(() => { const checkIfBrand = async () => { const brand = await axios( @@ -122,15 +214,20 @@ const ProductSearch = ({ }, [q]); useEffect(() => { - const loadCategories = async () => { - const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) - if(getCategories){ - setDataCategories(getCategories) - } + if(prefixUrl.includes('category')){ + const loadCategories = async () => { + const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) + if(getCategories){ + setDataCategories(getCategories) + } + } + loadCategories() } - loadCategories() }, []) + + + const brands = []; for ( let i = 0; @@ -277,6 +374,8 @@ const ProductSearch = ({ }; const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; + + console.log("finalQuery",finalQuery) return ( <> @@ -338,6 +437,7 @@ const ProductSearch = ({ SpellingComponent )}
+ {productFound > 0 && ( @@ -429,6 +529,7 @@ const ProductSearch = ({
+ {bannerPromotionHeader && bannerPromotionHeader?.image && (
diff --git a/src/pages/api/shop/product-homepage.js b/src/pages/api/shop/product-homepage.js index 02c01ee0..61732c77 100644 --- a/src/pages/api/shop/product-homepage.js +++ b/src/pages/api/shop/product-homepage.js @@ -36,7 +36,8 @@ const respoonseMap = (productHomepage, products) => { name: productHomepage.name_s, image: productHomepage.image_s, url: productHomepage.url_s, - products: products + products: products, + categoryIds: productHomepage.category_id_ids, } return productMapped diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx new file mode 100644 index 00000000..2153b565 --- /dev/null +++ b/src/pages/shop/lob/[slug].jsx @@ -0,0 +1,62 @@ +import _ from 'lodash'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; +import Seo from '@/core/components/Seo'; +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; +import Breadcrumb from '../../../lib/lob/components/Breadcrumb'; +import { useEffect, useState } from 'react'; +import odooApi from '@/core/api/odooApi'; +import { div } from 'lodash-contrib'; + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')); +const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')); +const CategorySection = dynamic(() => import('@/lib/product/components/CategorySection')); + +export default function CategoryDetail() { + const router = useRouter(); + const { slug = '', page = 1 } = router.query; + const [dataLob, setDataLob] = useState([]); + const [finalQuery, setFinalQuery] = useState({}); + const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) + const [data, setData] = useState([]) + const dataIdCategories = [] + + const categoryName = getNameFromSlug(slug); + const lobId = getIdFromSlug(slug); + const q = router?.query.q || null; + const query = { + fq: `id:${lobId}`, + page, + }; + if (q) { + query.q = q; + } + + return ( + + + + +
+ {dataLob[0]?.categoryIds && ( +
+ +
+ )} +
+ + {!_.isEmpty(router.query) && ( + + )} +
+ ); +} -- cgit v1.2.3 From e79b956cd190419100e52a5468f91eefb7933387 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 15:25:59 +0700 Subject: update category management --- src/pages/index.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 30a7ac1f..64c880c7 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -45,9 +45,9 @@ const FlashSale = dynamic( } ); -const ProgramPromotion = dynamic(() => - import('@/lib/home/components/PromotionProgram') -); +// const ProgramPromotion = dynamic(() => +// import('@/lib/home/components/PromotionProgram') +// ); const BannerSection = dynamic(() => import('@/lib/home/components/BannerSection') @@ -138,7 +138,7 @@ export default function Home({categoryId}) {
{!auth?.feature?.soApproval && ( <> - + {/* */} )} @@ -168,7 +168,7 @@ export default function Home({categoryId}) { {!auth?.feature?.soApproval && ( <> - + {/* */} -- cgit v1.2.3 From 7c2a69c9b48c1930dc3f7cbef20d6479b3047ca2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 17:13:30 +0700 Subject: update category lob --- src/lib/product/components/ProductSearch.jsx | 35 ++++++++++++-------- src/pages/shop/lob/[slug].jsx | 49 +++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 12e3b358..7ab6b8af 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -38,11 +38,10 @@ const ProductSearch = ({ brand = null, }) => { const router = useRouter(); - const { page = 1 } = query; const [q, setQ] = useState(query?.q || '*'); const [search, setSearch] = useState(query?.q || '*'); - const [limit, setLimit] = useState(query?.limit || 30); + const [limit, setLimit] = useState(router.query?.limit || 30); const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); const [finalQuery, setFinalQuery] = useState({}); const [queryFinal, setQueryFinal] = useState({}); @@ -94,9 +93,13 @@ const ProductSearch = ({ const ids = collectIds(dataCategoriesProduct); const newQuery = { fq: `category_id_ids:(${ids.join(' OR ')})`, - page, + page : router.query.page? router.query.page : 1, brand : router.query.brand? router.query.brand : '', category : router.query.category? router.query.category : '', + priceFrom : router.query.priceFrom? router.query.priceFrom : '', + priceTo : router.query.priceTo? router.query.priceTo : '', + limit : router.query.limit? router.query.limit : '', + orderBy : router.query.orderBy? router.query.orderBy : '' }; setFinalQuery(newQuery); } else if (prefixUrl.includes('lob')){ @@ -114,9 +117,13 @@ const ProductSearch = ({ const newQuery = { fq: `category_id_ids:(${mergedArray.join(' OR ')})`, - page, - brand : router.query.brand? router.query.brand : '', category : router.query.category? router.query.category : '', + page : router.query.page? router.query.page : 1, + brand : router.query.brand? router.query.brand : '', + priceFrom : router.query.priceFrom? router.query.priceFrom : '', + priceTo : router.query.priceTo? router.query.priceTo : '', + limit : router.query.limit? router.query.limit : '', + orderBy : router.query.orderBy? router.query.orderBy : '' }; setFinalQuery(newQuery); @@ -148,17 +155,17 @@ const ProductSearch = ({ const numRows = [30, 50, 80, 100]; const [brandValues, setBrand] = useState( !router.pathname.includes('brands') - ? query.brand - ? query.brand.split(',') + ? router.query.brand + ? router.query.brand.split(',') : [] : [] ); const [categoryValues, setCategory] = useState( - query?.category?.split(',') || [] + router.query?.category?.split(',') || router.query?.category?.split(',') ); - const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null); - const [priceTo, setPriceTo] = useState(query?.priceTo || null); + const [priceFrom, setPriceFrom] = useState(router.query?.priceFrom || null); + const [priceTo, setPriceTo] = useState(router.query?.priceTo || null); const pageCount = Math.ceil(productSearch.data?.response.numFound / limit); const productStart = productSearch.data?.responseHeader.params.start; @@ -373,8 +380,6 @@ const ProductSearch = ({ const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; - console.log("finalQuery",finalQuery) - return ( <> @@ -476,7 +481,8 @@ const ProductSearch = ({ @@ -665,7 +671,8 @@ const ProductSearch = ({
diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx index 2153b565..cdaf3c91 100644 --- a/src/pages/shop/lob/[slug].jsx +++ b/src/pages/shop/lob/[slug].jsx @@ -24,8 +24,55 @@ export default function CategoryDetail() { const categoryName = getNameFromSlug(slug); const lobId = getIdFromSlug(slug); const q = router?.query.q || null; + + useEffect(() => { + if(router.pathname.includes('lob')){ + const loadProduct = async () => { + const lobData = await odooApi('GET', `/api/v1/lob_homepage/${lobId}/category_id`); + + if (lobData) { + setDataLob(lobData); + } + }; + loadProduct(); + + } + }, [lobId]); + + useEffect(() => { + if (router.pathname.includes('lob')){ + + const fetchCategoryData = async () => { + if (dataLob[0]?.categoryIds) { + + for (const cate of dataLob[0].categoryIds) { + + dataIdCategories.push(cate.childId) + } + + + setData(dataIdCategories.flat()) + + // const newQuery = { + // fq: `category_id_ids:(${mergedArray.join(' OR ')})`, + // category : router.query.category? router.query.category : '', + // page : router.query.page? router.query.page : 1, + // brand : router.query.brand? router.query.brand : '', + // priceFrom, + // priceTo, + // limit, + // orderBy + // }; + + // setFinalQuery(newQuery); + + } + }; + fetchCategoryData(); + } + }, [dataCategoriesProduct, dataLob]); const query = { - fq: `id:${lobId}`, + fq: `category_id_ids:(${data.join(' OR ')})`, page, }; if (q) { -- cgit v1.2.3 From 7f060ad3f3d938a462292721b9c54d1cb9140ad3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 29 Jul 2024 17:17:17 +0700 Subject: update category managemrnt --- src/lib/home/components/CategoryPilihan.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 5548fc1b..183c123a 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -39,7 +39,7 @@ const CategoryPilihan = ({ id, categories }) => {
{categoryPilihan?.data?.map((category) => ( -
+
-- cgit v1.2.3 From 593c508bb87451a985a5aec7e9d7bde45b18074b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 09:53:35 +0700 Subject: update category lob --- src/lib/product/components/LobSectionCategory.jsx | 1 - src/lib/product/components/ProductSearch.jsx | 9 ++-- src/pages/shop/lob/[slug].jsx | 63 +---------------------- 3 files changed, 5 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/LobSectionCategory.jsx b/src/lib/product/components/LobSectionCategory.jsx index 34a09e46..03d6e8c0 100644 --- a/src/lib/product/components/LobSectionCategory.jsx +++ b/src/lib/product/components/LobSectionCategory.jsx @@ -22,7 +22,6 @@ const LobSectionCategory = ({ categories }) => { const handleToggleCategories = () => { setIsOpenCategory(!isOpenCategory); }; - console.log("categories",categories[0]?.categoryIds) const displayedCategories = categories[0]?.categoryIds; diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 7ab6b8af..d4c5a308 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -379,7 +379,6 @@ const ProductSearch = ({ }; const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; - return ( <> @@ -481,8 +480,8 @@ const ProductSearch = ({ @@ -671,8 +670,8 @@ const ProductSearch = ({
diff --git a/src/pages/shop/lob/[slug].jsx b/src/pages/shop/lob/[slug].jsx index cdaf3c91..d939c25c 100644 --- a/src/pages/shop/lob/[slug].jsx +++ b/src/pages/shop/lob/[slug].jsx @@ -25,60 +25,6 @@ export default function CategoryDetail() { const lobId = getIdFromSlug(slug); const q = router?.query.q || null; - useEffect(() => { - if(router.pathname.includes('lob')){ - const loadProduct = async () => { - const lobData = await odooApi('GET', `/api/v1/lob_homepage/${lobId}/category_id`); - - if (lobData) { - setDataLob(lobData); - } - }; - loadProduct(); - - } - }, [lobId]); - - useEffect(() => { - if (router.pathname.includes('lob')){ - - const fetchCategoryData = async () => { - if (dataLob[0]?.categoryIds) { - - for (const cate of dataLob[0].categoryIds) { - - dataIdCategories.push(cate.childId) - } - - - setData(dataIdCategories.flat()) - - // const newQuery = { - // fq: `category_id_ids:(${mergedArray.join(' OR ')})`, - // category : router.query.category? router.query.category : '', - // page : router.query.page? router.query.page : 1, - // brand : router.query.brand? router.query.brand : '', - // priceFrom, - // priceTo, - // limit, - // orderBy - // }; - - // setFinalQuery(newQuery); - - } - }; - fetchCategoryData(); - } - }, [dataCategoriesProduct, dataLob]); - const query = { - fq: `category_id_ids:(${data.join(' OR ')})`, - page, - }; - if (q) { - query.q = q; - } - return ( -
- {dataLob[0]?.categoryIds && ( -
- -
- )} -
{!_.isEmpty(router.query) && ( - + )}
); -- cgit v1.2.3 From de27df05af1f23d70099d36d11e07f35faff26c6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 13:25:14 +0700 Subject: update mobile view --- .../components/elements/Navbar/NavbarMobile.jsx | 4 +- src/core/components/elements/Navbar/TopBanner.jsx | 29 ++-- src/lib/home/components/CategoryPilihan.jsx | 147 +++++++++++++++------ 3 files changed, 119 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarMobile.jsx b/src/core/components/elements/Navbar/NavbarMobile.jsx index bcf45e0a..90314671 100644 --- a/src/core/components/elements/Navbar/NavbarMobile.jsx +++ b/src/core/components/elements/Navbar/NavbarMobile.jsx @@ -11,7 +11,7 @@ import Image from 'next/image'; import { useEffect, useState } from 'react'; import MobileView from '../../views/MobileView'; import Link from '../Link/Link'; -// import TopBanner from './TopBanner'; +import TopBanner from './TopBanner'; const Search = dynamic(() => import('./Search')); @@ -39,7 +39,7 @@ const NavbarMobile = () => { return ( - {/* */} +
) } -- cgit v1.2.3 From a3875b3e803d7075fa8788286fb478bb0c825d26 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 14:06:55 +0700 Subject: update category management banner --- src/lib/home/components/CategoryPilihan.jsx | 17 ++++++----------- src/pages/index.jsx | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index e47524aa..72e6f6a8 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -23,25 +23,21 @@ const CategoryPilihan = ({ id, categories }) => {
LOB Kategori Pilihan

200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!

-
{heroBanner.data && heroBanner.data?.length > 0 && ( -
- +
+ {heroBanner.data[0].name} -
- +
)} -
{categoryPilihan?.data?.map((category) => (
@@ -72,7 +68,7 @@ const CategoryPilihan = ({ id, categories }) => {
LOB Kategori Pilihan
{/*

200 Rb+ Produk Unggulan & 800+ Brand Rekomendasi tersedia!

*/}
-
+
{heroBanner.data && heroBanner.data?.length > 0 && (
@@ -87,7 +83,6 @@ const CategoryPilihan = ({ id, categories }) => { />
- )}
diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 64c880c7..9d9d5dc0 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -156,7 +156,7 @@ export default function Home({categoryId}) { -
+
-- cgit v1.2.3 From d14f51d91cfb8851ae2c335628737d2f516dbf6a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 14:25:53 +0700 Subject: update category management --- src/lib/home/components/CategoryPilihan.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryPilihan.jsx b/src/lib/home/components/CategoryPilihan.jsx index 72e6f6a8..6568621c 100644 --- a/src/lib/home/components/CategoryPilihan.jsx +++ b/src/lib/home/components/CategoryPilihan.jsx @@ -88,7 +88,7 @@ const CategoryPilihan = ({ id, categories }) => { {categoryPilihan?.data?.map((category) => ( -
+
-- cgit v1.2.3 From 53d214ef3222bcc4169b188bff3dadf6c43f6b7e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 14:27:23 +0700 Subject: git aMerge branch 'Feature/category-management' into development --- .../components/elements/Navbar/NavbarMobile.jsx | 4 +- src/core/components/elements/Navbar/TopBanner.jsx | 29 ++--- src/lib/home/components/CategoryPilihan.jsx | 142 ++++++++++++++------- src/pages/index.jsx | 4 +- 4 files changed, 116 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarMobile.jsx b/src/core/components/elements/Navbar/NavbarMobile.jsx index bcf45e0a..90314671 100644 --- a/src/core/components/elements/Navbar/NavbarMobile.jsx +++ b/src/core/components/elements/Navbar/NavbarMobile.jsx @@ -11,7 +11,7 @@ import Image from 'next/image'; import { useEffect, useState } from 'react'; import MobileView from '../../views/MobileView'; import Link from '../Link/Link'; -// import TopBanner from './TopBanner'; +import TopBanner from './TopBanner'; const Search = dynamic(() => import('./Search')); @@ -39,7 +39,7 @@ const NavbarMobile = () => { return ( - {/* */} +
) } diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 64c880c7..d649ee17 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -61,7 +61,7 @@ const CategoryDynamic = dynamic(() => ); const CategoryDynamicMobile = dynamic(() => - import('@/lib/home/components/CategoryDynamicMobile') +import('@/lib/home/components/CategoryDynamicMobile') ); const CustomerReviews = dynamic(() => @@ -156,7 +156,7 @@ export default function Home({categoryId}) { -
+
-- cgit v1.2.3 From c92b47f81b4ea90f799810555395af7afcfa5a4d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 14:47:28 +0700 Subject: update category management --- src/lib/product/components/ProductSearch.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index d4c5a308..09534a5d 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -249,6 +249,7 @@ const ProductSearch = ({ brands.push({ brand, qty }); } } + const categories = []; for ( @@ -263,6 +264,7 @@ const ProductSearch = ({ categories.push({ name, qty }); } } + const orderOptions = [ { value: 'price-asc', label: 'Harga Terendah' }, @@ -340,7 +342,7 @@ const ProductSearch = ({ q: router.query.q, orderBy: orderBy, brand: brandValues.join(','), - category: categoryValues.join(','), + category: categoryValues?.join(','), priceFrom, priceTo, }; -- cgit v1.2.3 From 5296ce7dba6cf674b4942113a7716a89f05b64e0 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 15:06:02 +0700 Subject: update category management search product --- src/lib/product/components/ProductFilterDesktop.jsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index e4a62abb..384f2daa 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -102,7 +102,19 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu } params = _.pickBy(params, _.identity) params = toQuery(params) - router.push(`${prefixUrl}?${params}`) + + const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug; + + if (slug) { + if(prefixUrl.includes('category') || prefixUrl.includes('lob')){ + router.push(`${prefixUrl}?${params}`) + }else{ + router.push(`${prefixUrl}/${slug}?${params}`) + } + } else { + router.push(`${prefixUrl}?${params}`) + } + } -- cgit v1.2.3 From 09e2fd0ec1e2a1d8438ec1c630a08bc349400ecb Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 15:08:00 +0700 Subject: update error code --- src/lib/product/components/ProductFilterDesktop.jsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index 384f2daa..a8073036 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -21,6 +21,7 @@ import Image from '@/core/components/elements/Image/Image' import { formatCurrency } from '@/core/utils/formatValue' const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => { + const router = useRouter() const { query } = router const [order, setOrder] = useState(query?.orderBy) @@ -102,19 +103,14 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu } params = _.pickBy(params, _.identity) params = toQuery(params) - + const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug; if (slug) { - if(prefixUrl.includes('category') || prefixUrl.includes('lob')){ - router.push(`${prefixUrl}?${params}`) - }else{ - router.push(`${prefixUrl}/${slug}?${params}`) - } + router.push(`${prefixUrl}/${slug}?${params}`) } else { router.push(`${prefixUrl}?${params}`) } - } -- cgit v1.2.3 From 7dc18df04a6cf75e696f53ca578e4c36cfce9748 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 15:12:00 +0700 Subject: update category management filter search --- src/lib/product/components/ProductFilterDesktop.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index a8073036..1933c5f0 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -107,7 +107,11 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug; if (slug) { - router.push(`${prefixUrl}/${slug}?${params}`) + if(prefixUrl.includes('category') || prefixUrl.includes('lob')){ + router.push(`${prefixUrl}?${params}`) + }else{ + router.push(`${prefixUrl}/${slug}?${params}`) + } } else { router.push(`${prefixUrl}?${params}`) } -- cgit v1.2.3 From 067b536d7ea507575bd5bc3c12815927bd40d103 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 16:06:13 +0700 Subject: add skeleton --- src/lib/home/components/CategoryDynamic.jsx | 114 +++++++++++++++------------- 1 file changed, 63 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 6ab03ec3..dda7cdc4 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -4,6 +4,7 @@ import NextImage from 'next/image'; import Link from "next/link"; import { createSlug } from '@/core/utils/slug'; import odooApi from '@/core/api/odooApi'; +import { Skeleton} from '@chakra-ui/react' const CategoryDynamic = () => { const { categoryManagement } = useCategoryManagement(); @@ -41,62 +42,73 @@ const CategoryDynamic = () => { return (
- {categoryManagement && categoryManagement.data?.map((category) => { - const countLevel1 = categoryData[category.categoryIdI] || 0; - - return ( -
-
-
{category.name}
-

{countLevel1} Produk tersedia

- Lihat Semua -
-
- {category.categories.map((subCategory) => { - const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; + {categoryManagement && categoryManagement.data?.map((category) => { + const countLevel1 = categoryData[category.categoryIdI] || 0; + + return ( + +
+
+
{category.name}
+

+ {countLevel1 === 0 ? 'Menghitung jumlah produk...' : `${countLevel1} Produk tersedia`} +

+ Lihat Semua +
+
+ {category.categories.map((subCategory) => { + const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; - return ( -
-
-
- -
-
{subCategory.name}
-

{countLevel2} Produk tersedia

- Lihat Semua -
-
-
- {subCategory.childFrontendIdI.map((childCategory) => ( -
- - -
-
{childCategory.name}
-
- + return ( +
+
+
+ +
+
{subCategory.name}
+ {/*

+ {countLevel2 === 0 ? 'Menghitung jumlah produk...' : `${countLevel2} Produk tersedia`} +

*/} + +

+ {countLevel2} Produk tersedia +

+
+ Lihat Semua
- ))} +
+
+ {subCategory.childFrontendIdI.map((childCategory) => ( +
+ + +
+
{childCategory.name}
+
+ +
+ ))} +
-
- ); - })} + ); + })} +
-
- ); - })} + + ); + })}
); }; -- cgit v1.2.3 From c62a5dd32e961f06a01d0a535d2fbf37118ff2e7 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 30 Jul 2024 16:09:07 +0700 Subject: add key missing --- src/lib/home/components/CategoryDynamic.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index dda7cdc4..60e01df0 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -46,7 +46,7 @@ const CategoryDynamic = () => { const countLevel1 = categoryData[category.categoryIdI] || 0; return ( - +
{category.name}
-- cgit v1.2.3 From 8fe0cdf1f457148eb39d5438b13bbec7bc912976 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 31 Jul 2024 08:59:17 +0700 Subject: update category management --- src/lib/home/components/CategoryDynamic.jsx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 60e01df0..f2d1a16f 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -18,14 +18,10 @@ const CategoryDynamic = () => { const updatedSubCategoryData = {}; for (const category of categoryManagement.data) { - // Calculate level 1 products const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); - // console.log("countLevel1.child",countLevel1) updatedCategoryData[category.categoryIdI] = countLevel1?.numFound; - - // Calculate level 2 products for each sub-category for (const subCategory of countLevel1.children) { updatedSubCategoryData[subCategory.id] = subCategory.numFound; } @@ -50,9 +46,9 @@ const CategoryDynamic = () => {
{category.name}
-

- {countLevel1 === 0 ? 'Menghitung jumlah produk...' : `${countLevel1} Produk tersedia`} -

+ +

{countLevel1} Produk tersedia

+
Lihat Semua
@@ -72,9 +68,6 @@ const CategoryDynamic = () => { />
{subCategory.name}
- {/*

- {countLevel2 === 0 ? 'Menghitung jumlah produk...' : `${countLevel2} Produk tersedia`} -

*/}

{countLevel2} Produk tersedia -- cgit v1.2.3 From 7cac694f5a78f01e7e8185f7d37b758e9b7dab34 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 31 Jul 2024 14:01:48 +0700 Subject: add pop up cart --- src/lib/cart/components/Cartheader.jsx | 250 +++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 19f79bc9..a7dd621d 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -1,14 +1,21 @@ import { useCallback, useEffect, useMemo, useState } from 'react' import { getCartApi } from '../api/CartApi' +import currencyFormat from '@/core/utils/currencyFormat' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' +import whatsappUrl from '@/core/utils/whatsappUrl' +import { AnimatePresence, motion } from 'framer-motion' +import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' const { ShoppingCartIcon, PhotoIcon } = require('@heroicons/react/24/outline') const { default: Link } = require('next/link') const Cardheader = (cartCount) => { + const router = useRouter() const [subTotal, setSubTotal] = useState(null) const [buttonLoading, SetButtonTerapkan] = useState(false) @@ -109,6 +116,249 @@ const Cardheader = (cartCount) => {

+ + {isHovered && ( + <> + + + + +
+
Keranjang Belanja
+ + Lihat Semua + +
+
+
+ {!auth && ( +
+

+ Silahkan{' '} + + Login + {' '} + Untuk Melihat Daftar Keranjang Belanja Anda +

+
+ )} + {isLoading && + itemLoading.map((item) => ( +
+
+
+ +
+
+
+
+
+
+
+
+ ))} + {auth && products.length === 0 && !isLoading && ( +
+

+ Tidak Ada Produk di Keranjang Belanja Anda +

+
+ )} + {auth && products.length > 0 && !isLoading && ( + <> +
    + {products && + products?.map((product, index) => ( + <> +
  • +
    +
    + {product.cartType === 'promotion' && ( + {product.name} + )} + {product.cartType === 'product' && ( + + {product?.name} + + )} +
    +
    + {product.cartType === 'promotion' && ( +

    + {product.name} +

    + )} + {product.cartType === 'product' && ( + + {' '} +

    + {product.parent.name} +

    + + )} + + {product?.hasFlashsale && ( +
    +
    + {product?.price?.discountPercentage}% +
    +
    + {currencyFormat(product?.price?.price)} +
    +
    + )} + +
    +
    + {product?.price?.priceDiscount > 0 ? ( + currencyFormat(product?.price?.priceDiscount) + ) : ( + + + Call For Price + + + )} +
    +
    +
    +
    +
    + {product.products?.map((product) => +
    + + {product?.image && {product.name}} + + +
    + + {product.displayName} + + +
    +
    + {/*
    {product.code}
    */} +
    + Berat Barang: + {product.packageWeight} Kg +
    +
    +
    +
    + +
    + )} + {product.freeProducts?.map((product) => +
    + + {product?.image && {product.name}} + + +
    + + {product.displayName} + + +
    +
    + {/*
    {product.code}
    */} +
    + Berat Barang: + {product.packageWeight} Kg +
    +
    +
    +
    + +
    + )} +
    +
  • + + ))} +
+
+ + )} +
+ {auth && products.length > 0 && !isLoading && ( + <> +
+ Subtotal Sebelum PPN : + {currencyFormat(subTotal)} +
+
+ +
+ + )} +
+
+ + )} +
+
) } -- cgit v1.2.3 From 12f581a4c0c4a3316385015622823c9e5935bb05 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 31 Jul 2024 14:13:10 +0700 Subject: update pop up cart --- src/lib/cart/components/Cartheader.jsx | 19 ++++++++++++++++--- src/lib/home/components/CategoryDynamic.jsx | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index a7dd621d..c8aa7cc3 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -26,6 +26,7 @@ const Cardheader = (cartCount) => { useProductCartContext() const [isHovered, setIsHovered] = useState(false) + const [isTop, setIsTop] = useState(true) const products = useMemo(() => { return productCart?.products || [] @@ -84,12 +85,24 @@ const Cardheader = (cartCount) => { setCountCart(cartCount.cartCount) }, [cartCount]) + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY === 0) + } + + window.addEventListener('scroll', handleScroll) + return () => { + window.removeEventListener('scroll', handleScroll) + } + }, []) + const handleCheckout = async () => { SetButtonTerapkan(true) let checkoutAll = await odooApi('POST', `/api/v1/user/${auth.id}/cart/select-all`) router.push('/shop/checkout') } + return (
@@ -121,10 +134,10 @@ const Cardheader = (cartCount) => { <> { // Calculate level 2 products for each sub-category - for (const subCategory of countLevel1.children) { + for (const subCategory of countLevel1?.children) { updatedSubCategoryData[subCategory.id] = subCategory.numFound; } } -- cgit v1.2.3 From 6e5766739b0684919c8630580403ed279cc3a71e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 31 Jul 2024 14:14:27 +0700 Subject: back log --- src/lib/home/components/CategoryDynamic.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index dae17c94..6ab03ec3 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -25,7 +25,7 @@ const CategoryDynamic = () => { // Calculate level 2 products for each sub-category - for (const subCategory of countLevel1?.children) { + for (const subCategory of countLevel1.children) { updatedSubCategoryData[subCategory.id] = subCategory.numFound; } } -- cgit v1.2.3 From 8a03b5a325692fd39c193f2a12b1a9aa4af1553e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 31 Jul 2024 14:31:34 +0700 Subject: update cart pop up --- src/lib/cart/components/Cartheader.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index c8aa7cc3..7d43a4da 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -290,7 +290,7 @@ const Cardheader = (cartCount) => {
-
+
{product.products?.map((product) =>
-- cgit v1.2.3 From e07a57651649cb2493e5b00a361797cf1392a186 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 1 Aug 2024 11:59:26 +0700 Subject: update template switch --- .../components/Product/ProductDesktopVariant.jsx | 66 ++++++++++++++++++-- .../components/Product/ProductMobileVariant.jsx | 71 +++++++++++++++++++--- 2 files changed, 123 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 09b30a44..882673f4 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -6,6 +6,11 @@ import { useRouter } from 'next/router'; import { useCallback, useEffect, useRef, useState } from 'react'; import { toast } from 'react-hot-toast'; import LazyLoad from 'react-lazy-load'; +import { Button } from '@chakra-ui/react' +import { MessageCircleIcon, Share2Icon } from 'lucide-react' +import AddToWishlist from '../../../../../src-migrate/modules/product-detail/components/AddToWishlist' +import { RWebShare } from 'react-web-share' +// import Link from 'next/link' import { useProductCartContext } from '@/contexts/ProductCartContext'; import odooApi from '@/core/api/odooApi'; @@ -18,11 +23,14 @@ import { updateItemCart } from '@/core/utils/cart'; import currencyFormat from '@/core/utils/currencyFormat'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; +import Breadcrumb from '../../../../../src-migrate/modules/product-detail/components/Breadcrumb'; import productSimilarApi from '../../api/productSimilarApi'; import ProductCard from '../ProductCard'; import ProductSimilar from '../ProductSimilar'; +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST + const ProductDesktopVariant = ({ product, wishlist, @@ -32,7 +40,7 @@ const ProductDesktopVariant = ({ const router = useRouter(); const auth = useAuth(); const { slug } = router.query; - + const [ askAdminUrl, setAskAdminUrl ] = useState() const [lowestPrice, setLowestPrice] = useState(null); const [addCartAlert, setAddCartAlert] = useState(false); @@ -53,6 +61,20 @@ const ProductDesktopVariant = ({ setLowestPrice(lowest); }, [getLowestPrice]); + useEffect(() => { + const createdAskUrl = whatsappUrl({ + template: 'product', + payload: { + manufacture: product.manufacture.name, + productName: product.name, + url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath + }, + fallbackUrl: router.asPath + }) + + setAskAdminUrl(createdAskUrl) + }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) + const [informationTab, setInformationTab] = useState( informationTabOptions[0].value ); @@ -154,6 +176,7 @@ const ProductDesktopVariant = ({ return (
+
@@ -263,9 +286,42 @@ const ProductDesktopVariant = ({
+
+
+ + + + + + + +
+ -
+ +

Informasi Produk

-
+
{product?.isFlashsale > 0 && product?.price?.discountPercentage > 0 ? ( <> @@ -359,7 +415,7 @@ const ProductDesktopVariant = ({ Beli
-
+ {/*
+
*/}
Produk Serupa diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index af9e52bb..ce836d5b 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -16,9 +16,15 @@ import currencyFormat from '@/core/utils/currencyFormat'; import { gtagAddToCart } from '@/core/utils/googleTag'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; - +import Breadcrumb from '../../../../../src-migrate/modules/product-detail/components/Breadcrumb'; +import { Button } from '@chakra-ui/react' +import { MessageCircleIcon, Share2Icon } from 'lucide-react' +import AddToWishlist from '../../../../../src-migrate/modules/product-detail/components/AddToWishlist' +import { RWebShare } from 'react-web-share' import ProductSimilar from '../ProductSimilar'; +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST + const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { const router = useRouter(); @@ -28,7 +34,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { informationTabOptions[0].value ); const [addCartAlert, setAddCartAlert] = useState(false); - + const [ askAdminUrl, setAskAdminUrl ] = useState() const [isLoadingSLA, setIsLoadingSLA] = useState(true); const getLowestPrice = () => { @@ -60,6 +66,20 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { } }, [selectedVariant, product]); + useEffect(() => { + const createdAskUrl = whatsappUrl({ + template: 'product', + payload: { + manufacture: product.manufacture.name, + productName: product.name, + url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath + }, + fallbackUrl: router.asPath + }) + + setAskAdminUrl(createdAskUrl) + }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) + const validAction = () => { let isValid = true; if (!selectedVariant) { @@ -120,14 +140,17 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { return ( +
+ +
{product.name}
-
+
{product.manufacture?.name ? ( { ) : (
-
)} - + + + + + + +
+ {/* + */}
-

{activeVariant?.name}

+

{activeVariant?.name}

{activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? ( @@ -173,11 +226,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
) : ( -

+

{activeVariant?.price?.price > 0 ? ( <> {currencyFormat(activeVariant?.price?.price)} -
+
Termasuk PPN:{' '} {currencyFormat( activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN -- cgit v1.2.3 From d57ca7be5e2de9c48f4229b20a49a94bf05e88d1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 2 Aug 2024 14:55:16 +0700 Subject: update cart pop up --- src/lib/cart/components/Cartheader.jsx | 259 ++++++++++++++++++++++++++++++++- 1 file changed, 257 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 19f79bc9..e3a5cc1f 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -4,7 +4,12 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' - +import currencyFormat from '@/core/utils/currencyFormat' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' +import whatsappUrl from '@/core/utils/whatsappUrl' +import { AnimatePresence, motion } from 'framer-motion' +import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' const { ShoppingCartIcon, PhotoIcon } = require('@heroicons/react/24/outline') const { default: Link } = require('next/link') @@ -19,7 +24,7 @@ const Cardheader = (cartCount) => { useProductCartContext() const [isHovered, setIsHovered] = useState(false) - + const [isTop, setIsTop] = useState(true) const products = useMemo(() => { return productCart?.products || [] }, [productCart]) @@ -77,6 +82,16 @@ const Cardheader = (cartCount) => { setCountCart(cartCount.cartCount) }, [cartCount]) + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY === 0) + } + window.addEventListener('scroll', handleScroll) + return () => { + window.removeEventListener('scroll', handleScroll) + } + }, []) + const handleCheckout = async () => { SetButtonTerapkan(true) let checkoutAll = await odooApi('POST', `/api/v1/user/${auth.id}/cart/select-all`) @@ -109,6 +124,246 @@ const Cardheader = (cartCount) => {
+ + {isHovered && ( + <> + + + +
+
Keranjang Belanja
+ + Lihat Semua + +
+
+
+ {!auth && ( +
+

+ Silahkan{' '} + + Login + {' '} + Untuk Melihat Daftar Keranjang Belanja Anda +

+
+ )} + {isLoading && + itemLoading.map((item) => ( +
+
+
+ +
+
+
+
+
+
+
+
+ ))} + {auth && products.length === 0 && !isLoading && ( +
+

+ Tidak Ada Produk di Keranjang Belanja Anda +

+
+ )} + {auth && products.length > 0 && !isLoading && ( + <> +
    + {products && + products?.map((product, index) => ( + <> +
  • +
    +
    + {product.cartType === 'promotion' && ( + {product.name} + )} + {product.cartType === 'product' && ( + + {product?.name} + + )} +
    +
    + {product.cartType === 'promotion' && ( +

    + {product.name} +

    + )} + {product.cartType === 'product' && ( + + {' '} +

    + {product.parent.name} +

    + + )} + {product?.hasFlashsale && ( +
    +
    + {product?.price?.discountPercentage}% +
    +
    + {currencyFormat(product?.price?.price)} +
    +
    + )} + +
    +
    + {product?.price?.priceDiscount > 0 ? ( + currencyFormat(product?.price?.priceDiscount) + ) : ( + + + Call For Price + + + )} +
    +
    +
    +
    +
    + {product.products?.map((product) => +
    + + {product?.image && {product.name}} + + +
    + + {product.displayName} + + +
    +
    + {/*
    {product.code}
    */} +
    + Berat Barang: + {product.packageWeight} Kg +
    +
    +
    +
    + +
    + )} + {product.freeProducts?.map((product) => +
    + + {product?.image && {product.name}} + + +
    + + {product.displayName} + + +
    +
    + {/*
    {product.code}
    */} +
    + Berat Barang: + {product.packageWeight} Kg +
    +
    +
    +
    + +
    + )} +
    +
  • + + ))} +
+
+ + )} +
+ {auth && products.length > 0 && !isLoading && ( + <> +
+ Subtotal Sebelum PPN : + {currencyFormat(subTotal)} +
+
+ +
+ + )} +
+
+ + )} +
) } -- cgit v1.2.3 From cf8a2c77f5a76a3b1dc10db6de56a4958de7b068 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 3 Aug 2024 08:41:51 +0700 Subject: update error code --- src/lib/cart/components/Cartheader.jsx | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index f76634ce..c7a8f0b8 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -1,15 +1,12 @@ import { useCallback, useEffect, useMemo, useState } from 'react' import { getCartApi } from '../api/CartApi' import currencyFormat from '@/core/utils/currencyFormat' -import Image from '@/core/components/elements/Image/Image' import { createSlug } from '@/core/utils/slug' import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' -import currencyFormat from '@/core/utils/currencyFormat' import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' -- cgit v1.2.3 From 04c73b4da52658b0060a20bbd100a8fdacd68ef9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:47:26 +0700 Subject: Revert " update error code" This reverts commit 70ec90799154dab2da475e840d8277d85648483b. --- src/lib/cart/components/Cartheader.jsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index c7a8f0b8..30e89317 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -6,6 +6,9 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' +import currencyFormat from '@/core/utils/currencyFormat' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' import Image from '@/core/components/elements/Image/Image' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' -- cgit v1.2.3 From 53d4cc076bbf52b1c4220df912755513e4bb5864 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:53:48 +0700 Subject: Revert " update error code" This reverts commit 70ec90799154dab2da475e840d8277d85648483b. --- src/lib/cart/components/Cartheader.jsx | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 30e89317..c7a8f0b8 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -6,9 +6,6 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' -import currencyFormat from '@/core/utils/currencyFormat' -import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' import Image from '@/core/components/elements/Image/Image' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' -- cgit v1.2.3 From aaac6b72dddf8ef8460941797a1f6d88f289f726 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 15:59:30 +0700 Subject: update category management --- src/lib/category/api/popularProduct.js | 36 +++++++++++ src/lib/category/components/Category.jsx | 35 ++-------- src/lib/category/components/PopularBrand.jsx | 96 ++++++++++++++++++++++++++++ src/lib/home/components/CategoryDynamic.jsx | 3 +- 4 files changed, 140 insertions(+), 30 deletions(-) create mode 100644 src/lib/category/api/popularProduct.js create mode 100644 src/lib/category/components/PopularBrand.jsx (limited to 'src') diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js new file mode 100644 index 00000000..2298f6fa --- /dev/null +++ b/src/lib/category/api/popularProduct.js @@ -0,0 +1,36 @@ + +export const fetchPromoItemsSolr = async (category_id_ids) => { + let sort ='sort=qty_sold_f desc'; + try { + const queryParams = new URLSearchParams({ q: category_id_ids }); + // const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s&${sort}`); + console.log("queryParams",queryParams) + + // const response = await fetch(`/solr/product/select?${queryParams.toString()}`); + const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=10&start=0&${sort}`); + console.log("response",response) + 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 map = async (promotions) => { + const result = []; + for (const promotion of promotions) { + const data = { + id: promotion.id, + name: promotion.display_name_s, + manufacture_name: promotion.manufacture_name_s, + manufacture_id: promotion.manufacture_id_i, + }; + result.push(data); + } + return result; + }; \ No newline at end of file diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index c147a3b3..1f3d7a51 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -5,6 +5,7 @@ import { createSlug } from '@/core/utils/slug' import { ChevronRightIcon } from '@heroicons/react/24/outline' import Image from 'next/image' import { useEffect, useState } from 'react' +import PopularBrand from './PopularBrand' const Category = () => { const [categories, setCategories] = useState([]) @@ -30,6 +31,7 @@ const Category = () => { } loadCategories() }, []) + console.log("categories",categories) return ( @@ -38,8 +40,11 @@ const Category = () => {
+
+ +
{category.name}
@@ -80,33 +85,7 @@ const Category = () => { ))}
-
-
- {category.childs.map((brand, index) => ( - (index < 8 ) && ( -
- - - -
- ) - ))} -
- {category.childs.length > 8 && ( -
- -

Lihat Semua Brand

- - -
- )} -
+
diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx new file mode 100644 index 00000000..32623f91 --- /dev/null +++ b/src/lib/category/components/PopularBrand.jsx @@ -0,0 +1,96 @@ +import odooApi from '@/core/api/odooApi' +import {React } from 'react' +import axios from 'axios'; +import { useQuery } from 'react-query' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' +import Image from 'next/image' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import useProductSearch from '../../../lib/product/hooks/useProductSearch'; +import { SolrResponse } from "~/types/solr"; +import {fetchPromoItemsSolr} from '../api/popularProduct' +const SOLR_HOST = process.env.SOLR_HOST + +const PopularBrand = ({ category }) => { + + const queryFinal = { + fq: `category_id_ids:(${category.categoryDataIds.join(' OR ')})`, + fl: 'manufacture_name_s,qty_sold_f', + sort: 'qty_sold_f desc', + rows: '2000' + }; + + // Konversi objek queryFinal menjadi string query + // const queryString = new URLSearchParams(queryFinal).toString(); + + async function fetchTopBrands() { + try { + // const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); + const items = await fetchPromoItemsSolr(`type_value_s:discount_loading`); + + console.log("queryFinal", queryFinal); + console.log("items", items); + + // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas + function getTop12UniqueBrands(products) { + const brandSet = new Set(); + const topBrands = []; + + for (const product of products) { + if (!brandSet.has(product.manufacture_name_s)) { + brandSet.add(product.manufacture_name_s); + topBrands.push(product.manufacture_name_s); + } + if (topBrands.length === 12) break; + } + + return topBrands; + } + + // Menggunakan hasil pencarian produk + const products = items; + const top12UniqueBrands = getTop12UniqueBrands(products); + + console.log('top12UniqueBrands',top12UniqueBrands); + return top12UniqueBrands; + } catch (error) { + console.error("Error fetching data from Solr", error); + throw error; + } + } + + fetchTopBrands(); + + + return ( +
+
+ {category.childs.map((brand, index) => ( + (index < 8 ) && ( +
+ + + +
+ ) + ))} +
+ {category.childs.length > 8 && ( +
+ +

Lihat Semua Brand

+ + +
+ )} +
+ ) +} + +export default PopularBrand diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index f2d1a16f..0cc43d91 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -33,9 +33,8 @@ const CategoryDynamic = () => { }; fetchCategoryData(); - }, [categoryManagement, categoryData]); + }, [categoryManagement.isLoading]); - return (
{categoryManagement && categoryManagement.data?.map((category) => { -- cgit v1.2.3 From 54fca7062ee0963d6ea6a22a82fba7fa3fa516e5 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 17:07:35 +0700 Subject: update category management --- src/lib/category/api/popularProduct.js | 7 +- src/lib/category/components/Category.jsx | 2 +- src/lib/category/components/PopularBrand.jsx | 105 ++++++++++++--------------- 3 files changed, 48 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js index 2298f6fa..e17e0ae5 100644 --- a/src/lib/category/api/popularProduct.js +++ b/src/lib/category/api/popularProduct.js @@ -3,12 +3,7 @@ export const fetchPromoItemsSolr = async (category_id_ids) => { let sort ='sort=qty_sold_f desc'; try { const queryParams = new URLSearchParams({ q: category_id_ids }); - // const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s&${sort}`); - console.log("queryParams",queryParams) - - // const response = await fetch(`/solr/product/select?${queryParams.toString()}`); - const response = await fetch(`/solr/promotion_program_lines/select?${queryParams.toString()}&rows=10&start=0&${sort}`); - console.log("response",response) + const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s,manufacture_id_i,id,display_name_s&${sort}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index 1f3d7a51..ff958378 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -31,7 +31,7 @@ const Category = () => { } loadCategories() }, []) - console.log("categories",categories) + // console.log("categories",categories) return ( diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index 32623f91..dca731e8 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -1,5 +1,5 @@ import odooApi from '@/core/api/odooApi' -import {React } from 'react' +import React, { useEffect, useState } from 'react' import axios from 'axios'; import { useQuery } from 'react-query' import Link from '@/core/components/elements/Link/Link' @@ -8,89 +8,76 @@ import Image from 'next/image' import { ChevronRightIcon } from '@heroicons/react/24/outline' import useProductSearch from '../../../lib/product/hooks/useProductSearch'; import { SolrResponse } from "~/types/solr"; -import {fetchPromoItemsSolr} from '../api/popularProduct' +import { fetchPromoItemsSolr } from '../api/popularProduct' + const SOLR_HOST = process.env.SOLR_HOST const PopularBrand = ({ category }) => { + const [topBrands, setTopBrands] = useState([]); - const queryFinal = { - fq: `category_id_ids:(${category.categoryDataIds.join(' OR ')})`, - fl: 'manufacture_name_s,qty_sold_f', - sort: 'qty_sold_f desc', - rows: '2000' - }; - - // Konversi objek queryFinal menjadi string query - // const queryString = new URLSearchParams(queryFinal).toString(); - - async function fetchTopBrands() { + const fetchTopBrands = async () => { try { - // const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); - const items = await fetchPromoItemsSolr(`type_value_s:discount_loading`); - - console.log("queryFinal", queryFinal); - console.log("items", items); - + const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); + // console.log("id",items) // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas - function getTop12UniqueBrands(products) { + const getTop12UniqueBrands = (prod) => { const brandSet = new Set(); const topBrands = []; - - for (const product of products) { - if (!brandSet.has(product.manufacture_name_s)) { - brandSet.add(product.manufacture_name_s); - topBrands.push(product.manufacture_name_s); + + for (const product of prod) { + if (!brandSet.has(product.manufacture_name)) { + brandSet.add(product.manufacture_name); + topBrands.push({ name: product.manufacture_name, id: product.manufacture_id }); + }else{ } - if (topBrands.length === 12) break; + if (topBrands.length === 18) break; } - return topBrands; } - + // Menggunakan hasil pencarian produk const products = items; const top12UniqueBrands = getTop12UniqueBrands(products); - - console.log('top12UniqueBrands',top12UniqueBrands); - return top12UniqueBrands; + + // console.log('top12UniqueBrands', top12UniqueBrands); + setTopBrands(top12UniqueBrands); } catch (error) { console.error("Error fetching data from Solr", error); throw error; } } - - fetchTopBrands(); + useEffect(() => { + fetchTopBrands(); + }, [category]); - return ( -
-
- {category.childs.map((brand, index) => ( - (index < 8 ) && ( -
- - - -
- ) - ))} -
- {category.childs.length > 8 && ( -
- +
+ {topBrands.map((brand, index) => ( +
+ + {`${brand.name}`} + +
+ ))} +
+ {/* {topBrands.length > 8 && ( +
+ + >

Lihat Semua Brand

- -
- )} -
- ) + +
+ )} */} +
+ ) } -export default PopularBrand +export default PopularBrand; -- cgit v1.2.3 From 807931ee9bcb063157ceb8368e5ee0941450c6ca Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 6 Aug 2024 14:32:41 +0700 Subject: add quotation pop up --- src/contexts/ProductQuotationContext.js | 17 ++ .../components/elements/Navbar/NavbarDesktop.jsx | 58 +++++-- src/lib/quotation/components/Quotationheader.jsx | 189 +++++++++++++++++++++ 3 files changed, 249 insertions(+), 15 deletions(-) create mode 100644 src/contexts/ProductQuotationContext.js create mode 100644 src/lib/quotation/components/Quotationheader.jsx (limited to 'src') diff --git a/src/contexts/ProductQuotationContext.js b/src/contexts/ProductQuotationContext.js new file mode 100644 index 00000000..f9e17830 --- /dev/null +++ b/src/contexts/ProductQuotationContext.js @@ -0,0 +1,17 @@ +import React, { createContext, useContext, useState } from 'react'; + +const ProductQuotationContext = createContext(); + +export const useProductQuotationContext = () => useContext(ProductQuotationContext); + +export const ProductQuotationProvider = ({ children }) => { + const [productQuotation, setProductQuotation] = useState([]); + const [refreshQuotation, setRefreshQuotation] = useState(false); + const [isLoading, setIsloading] = useState(false); + + return ( + + {children} + + ); +}; diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 7d9e4264..49c4cd6e 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -5,7 +5,9 @@ import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; import IndoteknikLogo from '@/images/logo.png'; import Cardheader from '@/lib/cart/components/Cartheader'; +import Quotationheader from '@/lib/quotation/components/QuotationHeader' import Category from '@/lib/category/components/Category'; +import { useProductQuotationContext } from '@/contexts/ProductQuotationContext' import { ChevronDownIcon, DocumentCheckIcon, @@ -28,6 +30,7 @@ import { useDisclosure, } from '@chakra-ui/react'; import style from "./style/NavbarDesktop.module.css"; +import useTransactions from '@/lib/transaction/hooks/useTransactions'; const Search = dynamic(() => import('./Search'), { ssr: false }); const TopBanner = dynamic(() => import('./TopBanner'), { ssr: false }); @@ -37,6 +40,8 @@ const NavbarDesktop = () => { const auth = useAuth(); const [cartCount, setCartCount] = useState(0); + const [quotationCount, setQuotationCount] = useState(0); + // const { setProductQuotation, refreshQuotation, setRefreshQuotation, isLoading, setIsloading } = useProductQuotationContext() const [templateWA, setTemplateWA] = useState(null); const [payloadWA, setPayloadWa] = useState(null); @@ -47,6 +52,16 @@ const NavbarDesktop = () => { const { product } = useProductContext(); const { isOpen, onOpen, onClose } = useDisclosure(); + const query = { + context: 'quotation', + site: + (auth?.webRole === null && auth?.site ? auth.site : null), + }; + + const { transactions } = useTransactions({query}); + const pendingTransactions = transactions?.data?.saleOrders.filter(transaction => transaction.status === 'draft'); + + useEffect(() => { if (router.pathname === '/shop/product/[slug]') { setPayloadWa({ @@ -55,11 +70,11 @@ const NavbarDesktop = () => { url: createSlug('/shop/product/', product?.name, product?.id, true), }); setTemplateWA('product'); - + setUrlPath(router.asPath); } }, [product, router]); - + useEffect(() => { const handleCartChange = () => { const cart = async () => { @@ -69,14 +84,36 @@ const NavbarDesktop = () => { cart(); }; handleCartChange(); - + window.addEventListener('localStorageChange', handleCartChange); - + return () => { window.removeEventListener('localStorageChange', handleCartChange); }; }, []); + + // useEffect(() => { + // setProductQuotation(pendingTransactions) + // }, [transactions, ]) + // console.log("Pending Transactions", pendingTransactions); + // console.log("pendingTransactions.length", pendingTransactions.length); + + useEffect(() => { + const handleQuotationChange = () => { + const quotation = async () => { + setQuotationCount(pendingTransactions?.length); + }; + quotation(); + }; + handleQuotationChange(); + window.addEventListener('localStorageChange', handleQuotationChange); + + return () => { + window.removeEventListener('localStorageChange', handleQuotationChange); + }; + }, []); + console.log("quotationCount",quotationCount) return ( @@ -139,17 +176,8 @@ const NavbarDesktop = () => {
- - - Daftar -
- Quotation - + + diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx new file mode 100644 index 00000000..141b731e --- /dev/null +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -0,0 +1,189 @@ +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { getQuotationApi } from '../api/QuotationApi'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { createSlug } from '@/core/utils/slug'; +import useAuth from '@/core/hooks/useAuth'; +import { useRouter } from 'next/router'; +import odooApi from '@/core/api/odooApi'; +import { useProductQuotationContext } from '@/contexts/ProductQuotationContext'; +import Image from '@/core/components/elements/Image/Image'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import { AnimatePresence, motion } from 'framer-motion'; +import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css'; +import useTransactions from '../../transaction/hooks/useTransactions'; +const { DocumentCheckIcon, PhotoIcon } = require('@heroicons/react/24/outline'); +const { default: Link } = require('next/link'); + +const Quotationheader = (quotationCount) => { + const auth = useAuth(); + const query = { + context: 'quotation', + site: auth?.webRole === null && auth?.site ? auth.site : null, + }; + + const router = useRouter(); + const [subTotal, setSubTotal] = useState(null); + const [buttonLoading, SetButtonTerapkan] = useState(false); + const itemLoading = [1, 2, 3]; + const [countQuotation, setCountQuotation] = useState(null); + const { productQuotation, setProductQuotation, refreshQuotation, setRefreshQuotation, isLoading, setIsloading } = + useProductQuotationContext(); + + const [isHovered, setIsHovered] = useState(false); + const [isTop, setIsTop] = useState(true); + const qotation = useMemo(() => { + return productQuotation || []; + }, [productQuotation]); + + const handleMouseEnter = () => { + setIsHovered(true); + getCart(); + }; + + const handleMouseLeave = () => { + setIsHovered(false); + }; + + const getCart = () => { + if (!productQuotation && auth) { + refreshCartf(); + } + }; + const refreshCartf = useCallback(async () => { + setIsloading(true); + let { transactions } = await useTransactions({ query }); + let pendingTransactions = transactions?.data?.saleOrders.filter(transaction => transaction.status === 'draft'); + setProductQuotation(pendingTransactions); + setCountQuotation(pendingTransactions.length); + setIsloading(false); + }, [setProductQuotation, setIsloading]); + + useEffect(() => { + if (refreshQuotation) { + refreshCartf(); + } + setRefreshQuotation(false); + }, [refreshQuotation, refreshCartf, setRefreshQuotation]); + + useEffect(() => { + setCountQuotation(quotationCount.cartCount); + }, [quotationCount]); + + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY === 0); + }; + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const handleCheckout = async () => { + SetButtonTerapkan(true); + let checkoutAll = await odooApi('POST', `/api/v1/user/${auth.id}/cart/select-all`); + router.push('/shop/quotation'); + }; + + return ( +
+
+ +
0 && 'mr-2'}`}> + + {countQuotation > 0 && ( + + {countQuotation} + + )} +
+ + Daftar +
+ Quotation +
+ +
+ + {isHovered && ( + <> + + + +
+
Daftar Quotation
+ + Lihat Semua + +
+
+
+ {!auth && ( +
+

+ Silahkan{' '} + + Login + {' '} + Untuk Melihat Daftar Keranjang Belanja Anda +

+
+ )} + {isLoading && + itemLoading.map((item) => ( +
+
+
+ +
+
+
+
+
+
+
+
+ ))} + {auth && qotation.length === 0 && !isLoading && ( +
+

+ Tidak Ada Quotation +

+
+ )} +
+
+
+ + )} +
+
+ ); +}; + +export default Quotationheader; -- cgit v1.2.3 From a63b03fffdf46ecddecf356d1d00d6582add75cf Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 6 Aug 2024 17:05:01 +0700 Subject: update cart pop up --- src/contexts/ProductCartContext.js | 4 +- src/contexts/ProductQuotationContext.js | 17 ------ .../components/elements/Navbar/NavbarDesktop.jsx | 35 +++++------ src/lib/quotation/components/Quotationheader.jsx | 67 ++++++++++++++++++---- 4 files changed, 76 insertions(+), 47 deletions(-) delete mode 100644 src/contexts/ProductQuotationContext.js (limited to 'src') diff --git a/src/contexts/ProductCartContext.js b/src/contexts/ProductCartContext.js index 06e97563..19889e07 100644 --- a/src/contexts/ProductCartContext.js +++ b/src/contexts/ProductCartContext.js @@ -4,12 +4,14 @@ const ProductCartContext = createContext() export const ProductCartProvider = ({ children }) => { const [productCart, setProductCart] = useState(null) + const [productQuotation, setProductQuotation] = useState(null) + const [refreshQuotation, setRefreshQuotation] = useState(false) const [refreshCart, setRefreshCart] = useState(false) const [isLoading, setIsloading] = useState(false) return ( {children} diff --git a/src/contexts/ProductQuotationContext.js b/src/contexts/ProductQuotationContext.js deleted file mode 100644 index f9e17830..00000000 --- a/src/contexts/ProductQuotationContext.js +++ /dev/null @@ -1,17 +0,0 @@ -import React, { createContext, useContext, useState } from 'react'; - -const ProductQuotationContext = createContext(); - -export const useProductQuotationContext = () => useContext(ProductQuotationContext); - -export const ProductQuotationProvider = ({ children }) => { - const [productQuotation, setProductQuotation] = useState([]); - const [refreshQuotation, setRefreshQuotation] = useState(false); - const [isLoading, setIsloading] = useState(false); - - return ( - - {children} - - ); -}; diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 49c4cd6e..c0e9b383 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -7,7 +7,7 @@ import IndoteknikLogo from '@/images/logo.png'; import Cardheader from '@/lib/cart/components/Cartheader'; import Quotationheader from '@/lib/quotation/components/QuotationHeader' import Category from '@/lib/category/components/Category'; -import { useProductQuotationContext } from '@/contexts/ProductQuotationContext' +import { useProductCartContext } from '@/contexts/ProductCartContext'; import { ChevronDownIcon, DocumentCheckIcon, @@ -41,8 +41,9 @@ const NavbarDesktop = () => { const [cartCount, setCartCount] = useState(0); const [quotationCount, setQuotationCount] = useState(0); - // const { setProductQuotation, refreshQuotation, setRefreshQuotation, isLoading, setIsloading } = useProductQuotationContext() - + const { productCart, setProductCart, refreshCart, setRefreshCart, isLoading, setIsloading, productQuotation, setProductQuotation, refreshQuotation, setRefreshQuotation } = + useProductCartContext(); + const [pendingTransactions, setPendingTransactions] = useState([]) const [templateWA, setTemplateWA] = useState(null); const [payloadWA, setPayloadWa] = useState(null); const [urlPath, setUrlPath] = useState(null); @@ -51,15 +52,22 @@ const NavbarDesktop = () => { const { product } = useProductContext(); const { isOpen, onOpen, onClose } = useDisclosure(); - + const query = { context: 'quotation', site: - (auth?.webRole === null && auth?.site ? auth.site : null), + (auth?.webRole === null && auth?.site ? auth.site : null), }; - const { transactions } = useTransactions({query}); - const pendingTransactions = transactions?.data?.saleOrders.filter(transaction => transaction.status === 'draft'); + const { transactions } = useTransactions({ query }); + const data = transactions?.data?.saleOrders.filter( + (transaction) => transaction.status === 'draft' + ); + + useEffect(() => { + setProductQuotation(data); + setPendingTransactions(data); + }, [transactions.data]); useEffect(() => { @@ -83,7 +91,7 @@ const NavbarDesktop = () => { }; cart(); }; - handleCartChange(); + handleCartChange(); window.addEventListener('localStorageChange', handleCartChange); @@ -91,12 +99,6 @@ const NavbarDesktop = () => { window.removeEventListener('localStorageChange', handleCartChange); }; }, []); - - // useEffect(() => { - // setProductQuotation(pendingTransactions) - // }, [transactions, ]) - // console.log("Pending Transactions", pendingTransactions); - // console.log("pendingTransactions.length", pendingTransactions.length); useEffect(() => { const handleQuotationChange = () => { @@ -112,8 +114,8 @@ const NavbarDesktop = () => { return () => { window.removeEventListener('localStorageChange', handleQuotationChange); }; - }, []); - console.log("quotationCount",quotationCount) + }, [pendingTransactions]); + return ( @@ -176,7 +178,6 @@ const NavbarDesktop = () => {
- diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 141b731e..9f0f17a6 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -1,16 +1,15 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; -import { getQuotationApi } from '../api/QuotationApi'; -import currencyFormat from '@/core/utils/currencyFormat'; import { createSlug } from '@/core/utils/slug'; import useAuth from '@/core/hooks/useAuth'; import { useRouter } from 'next/router'; import odooApi from '@/core/api/odooApi'; -import { useProductQuotationContext } from '@/contexts/ProductQuotationContext'; +import { useProductCartContext } from '@/contexts/ProductCartContext'; import Image from '@/core/components/elements/Image/Image'; import whatsappUrl from '@/core/utils/whatsappUrl'; import { AnimatePresence, motion } from 'framer-motion'; import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css'; import useTransactions from '../../transaction/hooks/useTransactions'; +import currencyFormat from '@/core/utils/currencyFormat'; const { DocumentCheckIcon, PhotoIcon } = require('@heroicons/react/24/outline'); const { default: Link } = require('next/link'); @@ -20,14 +19,14 @@ const Quotationheader = (quotationCount) => { context: 'quotation', site: auth?.webRole === null && auth?.site ? auth.site : null, }; - + const router = useRouter(); const [subTotal, setSubTotal] = useState(null); const [buttonLoading, SetButtonTerapkan] = useState(false); const itemLoading = [1, 2, 3]; const [countQuotation, setCountQuotation] = useState(null); - const { productQuotation, setProductQuotation, refreshQuotation, setRefreshQuotation, isLoading, setIsloading } = - useProductQuotationContext(); + const { productCart, setProductCart, refreshCart, setRefreshCart, isLoading, setIsloading, productQuotation, setProductQuotation, refreshQuotation, setRefreshQuotation } = + useProductCartContext(); const [isHovered, setIsHovered] = useState(false); const [isTop, setIsTop] = useState(true); @@ -49,12 +48,12 @@ const Quotationheader = (quotationCount) => { refreshCartf(); } }; + let { transactions } = useTransactions({ query }); const refreshCartf = useCallback(async () => { setIsloading(true); - let { transactions } = await useTransactions({ query }); let pendingTransactions = transactions?.data?.saleOrders.filter(transaction => transaction.status === 'draft'); setProductQuotation(pendingTransactions); - setCountQuotation(pendingTransactions.length); + setCountQuotation(pendingTransactions?.length ? pendingTransactions?.length : pendingTransactions?.length); setIsloading(false); }, [setProductQuotation, setIsloading]); @@ -66,7 +65,7 @@ const Quotationheader = (quotationCount) => { }, [refreshQuotation, refreshCartf, setRefreshQuotation]); useEffect(() => { - setCountQuotation(quotationCount.cartCount); + setCountQuotation(quotationCount.quotationCount); }, [quotationCount]); useEffect(() => { @@ -85,6 +84,8 @@ const Quotationheader = (quotationCount) => { router.push('/shop/quotation'); }; + console.log("quotation",qotation) + return (
@@ -105,7 +106,7 @@ const Quotationheader = (quotationCount) => { )}
- Daftar + List
Quotation
@@ -137,7 +138,7 @@ const Quotationheader = (quotationCount) => { >
Daftar Quotation
- + Lihat Semua
@@ -150,7 +151,7 @@ const Quotationheader = (quotationCount) => { Login {' '} - Untuk Melihat Daftar Keranjang Belanja Anda + Untuk Melihat Daftar Quotation Anda

)} @@ -176,6 +177,48 @@ const Quotationheader = (quotationCount) => {

)} + {auth && qotation.length > 0 && !isLoading && ( + <> +
    + {qotation && + qotation?.map((product, index) => ( + <> +
  • +
    +
    +

    {product.dateOrder}

    +

    Pending Quotation

    +
    +
    +
    +

    + No. Transaksi +

    +

    + {product.name} +

    +
    +
    +

    + No. Purchase Order +

    +

    + {product.purchaseOrderFile} +

    +
    +
    +
    +

    Total

    +

    {currencyFormat(product.amountTotal)}

    +
    +
    +
  • + + ))} +
+
+ + )}
-- cgit v1.2.3 From 617f920b5d60e989c08f8afd0e969d0d285b5a36 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 09:36:36 +0700 Subject: add skeleton to banner promo homepage --- src/lib/home/components/PromotionProgram.jsx | 5 +++++ src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx | 16 ++++++++++++++++ src/pages/index.jsx | 13 +++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx (limited to 'src') diff --git a/src/lib/home/components/PromotionProgram.jsx b/src/lib/home/components/PromotionProgram.jsx index 99258d94..c2f76069 100644 --- a/src/lib/home/components/PromotionProgram.jsx +++ b/src/lib/home/components/PromotionProgram.jsx @@ -3,11 +3,16 @@ import Image from 'next/image' import { bannerApi } from '@/api/bannerApi'; import useDevice from '@/core/hooks/useDevice' import { Swiper, SwiperSlide } from 'swiper/react'; +import BannerPromoSkeleton from '../components/Skeleton/BannerPromoSkeleton'; const { useQuery } = require('react-query') const BannerSection = () => { const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' })); const { isMobile, isDesktop } = useDevice() + if (promotionProgram.isLoading) { + return ; + } + return (
diff --git a/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx b/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx new file mode 100644 index 00000000..c5f39f19 --- /dev/null +++ b/src/lib/home/components/Skeleton/BannerPromoSkeleton.jsx @@ -0,0 +1,16 @@ +import useDevice from '@/core/hooks/useDevice' +import Skeleton from 'react-loading-skeleton' + +const BannerPromoSkeleton = () => { + const { isDesktop } = useDevice() + + return ( +
+ {Array.from({ length: isDesktop ? 3 : 1.2 }, (_, index) => ( + + ))} +
+ ) +} + +export default BannerPromoSkeleton diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 8af963fb..cad5d33b 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -9,6 +9,7 @@ import DesktopView from '@/core/components/views/DesktopView'; import MobileView from '@/core/components/views/MobileView'; import { FlashSaleSkeleton } from '@/lib/flashSale/skeleton/FlashSaleSkeleton'; import PreferredBrandSkeleton from '@/lib/home/components/Skeleton/PreferredBrandSkeleton'; +import BannerPromoSkeleton from '@/lib/home/components/Skeleton/BannerPromoSkeleton'; import PromotinProgram from '@/lib/promotinProgram/components/HomePage'; import PagePopupIformation from '~/modules/popup-information'; import useProductDetail from '~/modules/product-detail/stores/useProductDetail'; @@ -45,7 +46,10 @@ const FlashSale = dynamic( ); const ProgramPromotion = dynamic(() => - import('@/lib/home/components/PromotionProgram') + import('@/lib/home/components/PromotionProgram'), +{ + loading: () => , +} ); const BannerSection = dynamic(() => @@ -113,7 +117,12 @@ export default function Home() {
{!auth?.feature?.soApproval && ( <> - + + + + + + )} -- cgit v1.2.3 From e26e9b44c88cf6cf76ba3ab1d8e8408bf45c61ca Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Wed, 7 Aug 2024 10:35:54 +0700 Subject: cr fq solr search --- src/pages/api/shop/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 29471f7b..5c2d4ffc 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -56,7 +56,7 @@ export default async function handler(req, res) { `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, - `fq=-publish_b:false, product_rating_f:[13 TO *], discount_tier1_v2_f:[1 TO *]`, + `fq=-publish_b:false, product_rating_f:[13 TO *], price_tier1_v2_f:[1 TO *]`, ]; if (priceFrom > 0 || priceTo > 0) { -- cgit v1.2.3 From a1ed8969b451acc7867622fc302b0fd2b3c970a2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 12:10:50 +0700 Subject: update quotation pop up --- src/lib/quotation/components/Quotationheader.jsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 9f0f17a6..c9686b5a 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -184,26 +184,26 @@ const Quotationheader = (quotationCount) => { qotation?.map((product, index) => ( <>
  • -
    +
    -

    {product.dateOrder}

    -

    Pending Quotation

    +

    {product.dateOrder}

    +

    Pending Quotation

    -

    +

    No. Transaksi

    -

    + {product.name} -

    +
    -

    +

    No. Purchase Order

    - {product.purchaseOrderFile} + {product.purchaseOrderFile ? product.purchaseOrderFile : '-'}

    -- cgit v1.2.3 From 86c880442fc0abbc4c356da4fa8a20bc5759aff3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 14:00:07 +0700 Subject: quotation update popup --- src/lib/quotation/components/Quotationheader.jsx | 54 +++++++++++++----------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index c9686b5a..79011682 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -184,33 +184,37 @@ const Quotationheader = (quotationCount) => { qotation?.map((product, index) => ( <>
  • -
    -
    -

    {product.dateOrder}

    -

    Pending Quotation

    -
    -
    -
    -

    - No. Transaksi -

    - - {product.name} - +
    + +
    +
    +

    Sales :

    +

    {product.sales}

    +
    +
    +

    Status :

    +

    Pending Quotation

    +
    -
    -

    - No. Purchase Order -

    -

    - {product.purchaseOrderFile ? product.purchaseOrderFile : '-'} -

    +
    +
    +

    No. Transaksi

    +

    {product.name}

    +
    +
    +

    No. Purchase Order

    +

    {product.purchaseOrderName ? product.purchaseOrderName : '-'}

    +
    -
    -
    -

    Total

    -

    {currencyFormat(product.amountTotal)}

    -
    +
    +
    +

    Total

    +

    {currencyFormat(product.amountTotal)}

    +
    +
  • -- cgit v1.2.3 From 564cdef1d0d310fd85a96447151172febe337ef9 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Wed, 7 Aug 2024 15:10:16 +0700 Subject: bugfix upload po --- src/lib/transaction/components/Transaction.jsx | 400 +++++++++++++------------ 1 file changed, 213 insertions(+), 187 deletions(-) (limited to 'src') diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 9bef895a..85f6163b 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -1,6 +1,6 @@ import Spinner from '@/core/components/elements/Spinner/Spinner'; import NextImage from 'next/image'; -import rejectImage from "../../../../public/images/reject.png" +import rejectImage from '../../../../public/images/reject.png'; import useTransaction from '../hooks/useTransaction'; import TransactionStatusBadge from './TransactionStatusBadge'; import Divider from '@/core/components/elements/Divider/Divider'; @@ -40,7 +40,7 @@ import rejectProductApi from '../api/rejectProductApi'; import { useRouter } from 'next/router'; const Transaction = ({ id }) => { - const router = useRouter() + const router = useRouter(); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedProduct, setSelectedProduct] = useState(null); const [reason, setReason] = useState(''); @@ -152,7 +152,10 @@ const Transaction = ({ id }) => { const memoizeVariantGroupCardReject = useMemo( () => (
    - +
    ), [transaction.data] @@ -182,26 +185,25 @@ const Transaction = ({ id }) => { }; const handleRejectProduct = async () => { - try{ + try { if (!reason.trim()) { toast.error('Masukkan alasan terlebih dahulu'); return; - }else{ - let idSo = transaction?.data.id - let idProduct = selectedProduct?.id - await rejectProductApi({ idSo, idProduct, reason}); + } else { + let idSo = transaction?.data.id; + let idProduct = selectedProduct?.id; + await rejectProductApi({ idSo, idProduct, reason }); closeModal(); - toast.success("Produk berhasil di reject") + toast.success('Produk berhasil di reject'); setTimeout(() => { window.location.reload(); - }, 1500); + }, 1500); } - }catch(error){ + } catch (error) { toast.error('Gagal reject produk. Silakan coba lagi.'); } }; - return ( transaction.data?.name && ( <> @@ -390,14 +392,20 @@ const Transaction = ({ id }) => {

    Dokumen PO

    @@ -406,13 +414,13 @@ const Transaction = ({ id }) => {
    Detail Produk
    - {transaction?.data?.products.length > 0? ( -
    - {memoizeVariantGroupCard} -
    + {transaction?.data?.products.length > 0 ? ( +
    {memoizeVariantGroupCard}
    ) : ( -
    Semua produk telah di reject
    - )} +
    + Semua produk telah di reject +
    + )} {transaction?.data?.productsRejectLine.length > 0 && (
    @@ -594,12 +602,16 @@ const Transaction = ({ id }) => { onClick={ transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) - : openUploadPo + : transaction?.data.invoices.length < 1 + ? openUploadPo + : '' } > {transaction?.data?.purchaseOrderFile ? 'Download' - : 'Upload'} + : transaction?.data.invoices.length < 1 + ? 'Upload' + : '-'}
    @@ -628,9 +640,11 @@ const Transaction = ({ id }) => {
    Pengiriman
    - {transaction?.data?.pickings.length == 0 && ( -
    Belum ada pengiriman
    - )} + {transaction?.data?.pickings.length == 0 && ( +
    + Belum ada pengiriman +
    + )}
    {transaction?.data?.pickings?.map((airway) => (
    - {airway?.delivered ? 'Pesanan Tiba' : 'Sedang Dikirim'} + {airway?.delivered + ? 'Pesanan Tiba' + : 'Sedang Dikirim'}
    @@ -655,51 +671,53 @@ const Transaction = ({ id }) => {
    -
    Invoice
    - {transaction.data?.invoices?.length === 0 && ( -
    Belum ada invoice
    - )} -
    - {transaction.data?.invoices?.map((invoice, index) => ( - -
    -
    -

    {invoice?.name}

    -
    - {invoice.amountResidual > 0 ? ( -
    Belum Lunas
    - ) : ( -
    Lunas
    - )} -

    - {currencyFormat(invoice.amountTotal)} -

    -
    +
    + Invoice +
    + {transaction.data?.invoices?.length === 0 && ( +
    Belum ada invoice
    + )} +
    + {transaction.data?.invoices?.map((invoice, index) => ( + +
    +
    +

    {invoice?.name}

    +
    + {invoice.amountResidual > 0 ? ( +
    Belum Lunas
    + ) : ( +
    Lunas
    + )} +

    + {currencyFormat(invoice.amountTotal)} +

    -
    - - ))} -
    + +
    + + ))} +
    Rincian Pembelian
    - {transaction?.data?.products?.length > 0? ( - - - - - {/* */} - - - - - - - + {transaction?.data?.products?.length > 0 ? ( +
    Nama ProdukDiskonJumlahHargaSubtotal
    + + + + {/* */} + + + + + + + {transaction?.data?.products?.map((product) => ( {/* {auth?.feature.soApproval && (auth.webRole == 2 || auth.webRole == 3) && (transaction.data.isReaject == false) && ( */} - {auth?.feature.soApproval && (auth.webRole == 2 || auth.webRole == 3) && (router.asPath.includes("/my/quotations/")) && transaction.data?.status == 'draft' && ( - - )} + {auth?.feature.soApproval && + (auth.webRole == 2 || auth.webRole == 3) && + router.asPath.includes('/my/quotations/') && + transaction.data?.status == 'draft' && ( + + )} ))}
    Nama ProdukDiskonJumlahHargaSubtotal
    @@ -711,37 +729,37 @@ const Transaction = ({ id }) => { )} className='w-[20%] flex-shrink-0' > -
    +
    {product?.name} -
    -
    - {product.isSni && ( - - )} -
    -
    - {product.isTkdn && ( - - )} +
    +
    + {product.isSni && ( + + )} +
    +
    + {product.isTkdn && ( + + )} +
    -
    { {currencyFormat(product.price.price)}
    )} */} -
    {currencyFormat(product.price.priceDiscount)}
    +
    + {currencyFormat(product.price.priceDiscount)} +
    {currencyFormat(product.price.subtotal)} - - + +
    ) : ( -
    Semua produk telah di reject
    +
    + Semua produk telah di reject +
    )} - + {isModalOpen && (
    -
    + transform transition-transform duration-300 scale-100' + >

    Berikan Alasan