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 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 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 f3aa76b1810b3bc8b25bd02c76b50384893fc453 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Tue, 6 Aug 2024 15:12:56 +0700 Subject: voucher --- src/lib/checkout/api/getVoucher.js | 1 + src/lib/checkout/components/Checkout.jsx | 118 ++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/checkout/api/getVoucher.js b/src/lib/checkout/api/getVoucher.js index 779cef43..ead4ffbe 100644 --- a/src/lib/checkout/api/getVoucher.js +++ b/src/lib/checkout/api/getVoucher.js @@ -3,6 +3,7 @@ import { getAuth } from '@/core/utils/auth' export const getVoucher = async (id, query) => { const queryParam = new URLSearchParams(query); + console.log('ini params string',queryParam.toString()) const url = `/api/v1/user/${id}/voucher?${queryParam.toString()}`; const dataVoucher = await odooApi('GET', url); return dataVoucher; diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 09a791ee..84f68dab 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -131,6 +131,7 @@ const Checkout = () => { setLoadingVoucher(true); let dataVoucher = await getVoucher(auth?.id, { source: query, + type: 'all,brand', }); SetListVoucher(dataVoucher); @@ -146,40 +147,71 @@ const Checkout = () => { }; const VoucherCode = async (code) => { - const source = 'code=' + code + '&source=' + query; // let dataVoucher = await findVoucher(code, auth.id, query); - let dataVoucher = await getVoucherNew(source); + let dataVoucher = await getVoucher(auth?.id, { + source: query, + code: code + }); if (dataVoucher.length <= 0) { SetFindVoucher(1); return; } let addNewLine = dataVoucher[0]; - let checkList = listVouchers?.findIndex( - (voucher) => voucher.code == addNewLine.code - ); - if (checkList >= 0) { - if (listVouchers[checkList].canApply) { - ToggleSwitch(code); - SetCodeVoucher(null); - } else { - SetSelisihHargaCode(listVouchers[checkList].differenceToApply); + console.log('addNewLine', addNewLine); + if (addNewLine.applyType != 'shipping') { + let checkList = listVouchers?.findIndex( + (voucher) => voucher.code == addNewLine.code + ); + if (checkList >= 0) { + if (listVouchers[checkList].canApply) { + ToggleSwitch(code); + SetCodeVoucher(null); + } else { + SetSelisihHargaCode(listVouchers[checkList].differenceToApply); + SetFindVoucher(2); + } + return; + } + if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) { + SetSelisihHargaCode( + currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal) + ); SetFindVoucher(2); + return; + } else { + SetFindVoucher(3); + SetButtonTerapkan(true); } - return; - } - if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) { - SetSelisihHargaCode( - currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal) - ); - SetFindVoucher(2); - return; + SetListVoucher((prevList) => [addNewLine, ...prevList]); + SetActiveVoucher(addNewLine.code); } else { - SetFindVoucher(3); - SetButtonTerapkan(true); + let checkList = listVoucherShippings?.findIndex( + (voucher) => voucher.code == addNewLine.code + ); + if (checkList >= 0) { + if (listVoucherShippings[checkList].canApply) { + ToggleSwitch(code); + SetCodeVoucher(null); + } else { + SetSelisihHargaCode(listVoucherShippings[checkList].differenceToApply); + SetFindVoucher(2); + } + return; + } + if (cartCheckout?.subtotal < addNewLine.minPurchaseAmount) { + SetSelisihHargaCode( + currencyFormat(addNewLine.minPurchaseAmount - cartCheckout?.subtotal) + ); + SetFindVoucher(2); + return; + } else { + SetFindVoucher(3); + SetButtonTerapkan(true); + } + SetListVoucherShipping((prevList) => [addNewLine, ...prevList]); + setActiveVoucherShipping(addNewLine.code); } - SetListVoucher((prevList) => [addNewLine, ...prevList]); - SetActiveVoucher(addNewLine.code); }; useEffect(() => { @@ -187,7 +219,7 @@ const Checkout = () => { }, [bottomPopup]); useEffect(() => { - voucher(); + // voucher(); const loadExpedisi = async () => { let dataExpedisi = await ExpedisiList(); dataExpedisi = dataExpedisi.map((expedisi) => ({ @@ -210,13 +242,24 @@ const Checkout = () => { }; }, []); - const hitungDiscountVoucher = (code) => { - let dataVoucherIndex = listVouchers.findIndex( - (voucher) => voucher.code == code - ); - let dataActiveVoucher = listVouchers[dataVoucherIndex]; - - let countDiscount = dataActiveVoucher.discountVoucher; + const hitungDiscountVoucher = (code, source) => { + let countDiscount = 0; + if(source === 'voucher'){ + let dataVoucherIndex = listVouchers.findIndex( + (voucher) => voucher.code == code + ); + let dataActiveVoucher = listVouchers[dataVoucherIndex]; + + countDiscount = dataActiveVoucher.discountVoucher; + }else{ + let dataVoucherIndex = listVoucherShippings.findIndex( + (voucher) => voucher.code == code + ); + let dataActiveVoucher = listVoucherShippings[dataVoucherIndex]; + + countDiscount = dataActiveVoucher.discountVoucher; + } + /*if (dataActiveVoucher.discountType === 'percentage') { countDiscount = cartCheckout?.subtotal * (dataActiveVoucher.discountAmount / 100) @@ -237,11 +280,22 @@ const Checkout = () => { if (!listVouchers) return; if (!activeVoucher) return; - const countDiscount = hitungDiscountVoucher(activeVoucher); + console.log('voucher') + const countDiscount = hitungDiscountVoucher(activeVoucher, 'voucher'); SetDiscountVoucher(countDiscount); }, [activeVoucher, listVouchers]); + useEffect(() => { + if (!listVoucherShippings) return; + if (!activeVoucherShipping) return; + + console.log('voucher shipping') + const countDiscount = hitungDiscountVoucher(activeVoucherShipping, 'voucher_shipping'); + + SetDiscountVoucher(countDiscount); + }, [activeVoucherShipping, listVoucherShippings]); + useEffect(() => { if (qVoucher === 'PASTIHEMAT' && listVouchers) { let code = qVoucher; -- 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 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 bad8abd263bd43c59dad8e61e2f5f35bfe5b7746 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 11:37:58 +0700 Subject: update quotation pop up --- src/lib/quotation/components/Quotation.jsx | 7 +++-- src/lib/quotation/components/Quotationheader.jsx | 38 +++++++++++++++++++++--- 2 files changed, 39 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index df234dc2..3fac6f29 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -9,6 +9,7 @@ import _ from 'lodash'; import { deleteItemCart, getCart, getItemCart } from '@/core/utils/cart'; import currencyFormat from '@/core/utils/currencyFormat'; import { toast } from 'react-hot-toast'; +import { useProductCartContext } from '@/contexts/ProductCartContext'; // import checkoutApi from '@/lib/checkout/api/checkoutApi' import { useRouter } from 'next/router'; import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'; @@ -38,11 +39,12 @@ const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi'); const Quotation = () => { const router = useRouter(); const auth = useAuth(); - + const { data: cartCheckout } = useQuery('cartCheckout', () => getProductsCheckout() - ); +); +const { setRefreshQuotation } = useProductCartContext(); const SELF_PICKUP_ID = 32; const [products, setProducts] = useState(null); @@ -293,6 +295,7 @@ const Quotation = () => { if (isSuccess?.id) { for (const product of products) deleteItemCart({ productId: product.id }); router.push(`/shop/quotation/finish?id=${isSuccess.id}`); + setRefreshQuotation(true); return; } diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 79011682..14743fd6 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -30,6 +30,7 @@ const Quotationheader = (quotationCount) => { const [isHovered, setIsHovered] = useState(false); const [isTop, setIsTop] = useState(true); + const qotation = useMemo(() => { return productQuotation || []; }, [productQuotation]); @@ -49,6 +50,7 @@ const Quotationheader = (quotationCount) => { } }; let { transactions } = useTransactions({ query }); + const refreshCartf = useCallback(async () => { setIsloading(true); let pendingTransactions = transactions?.data?.saleOrders.filter(transaction => transaction.status === 'draft'); @@ -57,6 +59,18 @@ const Quotationheader = (quotationCount) => { setIsloading(false); }, [setProductQuotation, setIsloading]); + useEffect(() => { + if (!qotation) return + + let calculateTotalDiscountAmount = 0 + for (const product of qotation) { + // if (qotation.quantity == '') continue + calculateTotalDiscountAmount += product.amountUntaxed + } + let subTotal = calculateTotalDiscountAmount + setSubTotal(subTotal) + }, [qotation]) + useEffect(() => { if (refreshQuotation) { refreshCartf(); @@ -84,8 +98,6 @@ const Quotationheader = (quotationCount) => { router.push('/shop/quotation'); }; - console.log("quotation",qotation) - return (
    @@ -211,8 +223,8 @@ const Quotationheader = (quotationCount) => {
    -

    Total

    -

    {currencyFormat(product.amountTotal)}

    +

    Total

    +

    {currencyFormat(product.amountUntaxed)}

    @@ -224,6 +236,24 @@ const Quotationheader = (quotationCount) => { )}
    + {auth && qotation.length > 0 && !isLoading && ( + <> +
    + Subtotal Sebelum PPN : + {currencyFormat(subTotal)} +
    +
    + +
    + + )} -- cgit v1.2.3 From 29662765048f561af5ab0dc586a37bd80068b633 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 11:45:59 +0700 Subject: update location quotationHeader --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index c0e9b383..85e77b2d 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -5,7 +5,7 @@ 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 Quotationheader from '../../../../../src/lib/quotation/components/QuotationHeader' import Category from '@/lib/category/components/Category'; import { useProductCartContext } from '@/contexts/ProductCartContext'; import { -- cgit v1.2.3 From 6e36b0e78c7ac56c8b7d2f27a19838e9aaa9da98 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 12:03:04 +0700 Subject: add import quotationHeader --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 85e77b2d..03335df6 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -5,7 +5,7 @@ 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 '../../../../../src/lib/quotation/components/QuotationHeader' +import Quotationheader from "../../../../../src/lib/quotation/components/Quotationheader.jsx" import Category from '@/lib/category/components/Category'; import { useProductCartContext } from '@/contexts/ProductCartContext'; import { -- cgit v1.2.3 From 079f8029445fdd243e267a4af7c7a4d5780afa24 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 14:11:32 +0700 Subject: update pop up quotation & cart --- src/contexts/ProductCartContext.js | 5 ++--- .../components/elements/Navbar/NavbarDesktop.jsx | 3 --- src/lib/cart/components/Cartheader.jsx | 1 + src/lib/quotation/components/Quotation.jsx | 4 ++-- src/lib/quotation/components/Quotationheader.jsx | 20 +++++++++----------- 5 files changed, 14 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/contexts/ProductCartContext.js b/src/contexts/ProductCartContext.js index 19889e07..3a21d2e0 100644 --- a/src/contexts/ProductCartContext.js +++ b/src/contexts/ProductCartContext.js @@ -4,14 +4,13 @@ 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) + const [productQuotation, setProductQuotation] = useState(null) return ( {children} diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 03335df6..2e8c982e 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -41,8 +41,6 @@ const NavbarDesktop = () => { const [cartCount, setCartCount] = useState(0); const [quotationCount, setQuotationCount] = useState(0); - 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); @@ -65,7 +63,6 @@ const NavbarDesktop = () => { ); useEffect(() => { - setProductQuotation(data); setPendingTransactions(data); }, [transactions.data]); diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index c7a8f0b8..6967d180 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -81,6 +81,7 @@ const Cardheader = (cartCount) => { useEffect(() => { setCountCart(cartCount.cartCount) + setRefreshCart(false) }, [cartCount]) useEffect(() => { diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index 3fac6f29..0ad042de 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -44,7 +44,7 @@ const Quotation = () => { getProductsCheckout() ); -const { setRefreshQuotation } = useProductCartContext(); +const { setRefreshCart } = useProductCartContext(); const SELF_PICKUP_ID = 32; const [products, setProducts] = useState(null); @@ -295,7 +295,7 @@ const { setRefreshQuotation } = useProductCartContext(); if (isSuccess?.id) { for (const product of products) deleteItemCart({ productId: product.id }); router.push(`/shop/quotation/finish?id=${isSuccess.id}`); - setRefreshQuotation(true); + setRefreshCart(true); return; } diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 14743fd6..10e3e147 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -25,7 +25,7 @@ const Quotationheader = (quotationCount) => { const [buttonLoading, SetButtonTerapkan] = useState(false); const itemLoading = [1, 2, 3]; const [countQuotation, setCountQuotation] = useState(null); - const { productCart, setProductCart, refreshCart, setRefreshCart, isLoading, setIsloading, productQuotation, setProductQuotation, refreshQuotation, setRefreshQuotation } = + const { productCart, setProductCart, refreshCart, setRefreshCart, isLoading, setIsloading, productQuotation, setProductQuotation } = useProductCartContext(); const [isHovered, setIsHovered] = useState(false); @@ -72,11 +72,11 @@ const Quotationheader = (quotationCount) => { }, [qotation]) useEffect(() => { - if (refreshQuotation) { + if (refreshCart) { refreshCartf(); } - setRefreshQuotation(false); - }, [refreshQuotation, refreshCartf, setRefreshQuotation]); + setRefreshCart(false); + }, [ refreshCartf, setRefreshCart]); useEffect(() => { setCountQuotation(quotationCount.quotationCount); @@ -150,9 +150,6 @@ const Quotationheader = (quotationCount) => { >
    Daftar Quotation
    - - Lihat Semua -

    @@ -221,7 +218,8 @@ const Quotationheader = (quotationCount) => {

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

    -
    + {/*
    */} +

    Total

    {currencyFormat(product.amountUntaxed)}

    @@ -238,18 +236,18 @@ const Quotationheader = (quotationCount) => {
    {auth && qotation.length > 0 && !isLoading && ( <> -
    +
    Subtotal Sebelum PPN : {currencyFormat(subTotal)}
    -- cgit v1.2.3 From 64489b794a80b381d86ea226f0fe36457d5836be Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 15:06:37 +0700 Subject: update quotation pop up bug --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 2 +- src/lib/quotation/components/Quotationheader.jsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 2e8c982e..1163aff3 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -175,7 +175,7 @@ const NavbarDesktop = () => {
    - + diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 10e3e147..0bb4dfe0 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -80,6 +80,7 @@ const Quotationheader = (quotationCount) => { useEffect(() => { setCountQuotation(quotationCount.quotationCount); + setProductQuotation(quotationCount.data); }, [quotationCount]); useEffect(() => { -- cgit v1.2.3 From 3de1a412bba31b19b8b443dd91df8aff8d6eda07 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 16:22:00 +0700 Subject: update link button --- src/lib/quotation/components/Quotationheader.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/quotation/components/Quotationheader.jsx b/src/lib/quotation/components/Quotationheader.jsx index 0bb4dfe0..4529c977 100644 --- a/src/lib/quotation/components/Quotationheader.jsx +++ b/src/lib/quotation/components/Quotationheader.jsx @@ -96,7 +96,7 @@ const Quotationheader = (quotationCount) => { const handleCheckout = async () => { SetButtonTerapkan(true); let checkoutAll = await odooApi('POST', `/api/v1/user/${auth.id}/cart/select-all`); - router.push('/shop/quotation'); + router.push('/my/quotations'); }; return ( -- cgit v1.2.3 From 8a4d7247dd4163050f95055f13391b709bb29e66 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 10 Aug 2024 13:22:42 +0700 Subject: add feature tracking order --- src/lib/tracking-order/component/TrackingOrder.jsx | 94 ++++++++++++++++++++++ src/pages/tracking-order.jsx | 26 ++++++ 2 files changed, 120 insertions(+) create mode 100644 src/lib/tracking-order/component/TrackingOrder.jsx create mode 100644 src/pages/tracking-order.jsx (limited to 'src') diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx new file mode 100644 index 00000000..476e6507 --- /dev/null +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -0,0 +1,94 @@ +import odooApi from '@/core/api/odooApi' +import HookFormSelect from '@/core/components/elements/Select/HookFormSelect' +import cityApi from '@/lib/address/api/cityApi' +import { yupResolver } from '@hookform/resolvers/yup' +import React, { useEffect, useRef, useState } from 'react' +import ReCAPTCHA from 'react-google-recaptcha' +import { Controller, useForm } from 'react-hook-form' +import { toast } from 'react-hot-toast' +import * as Yup from 'yup' +import { useRouter } from 'next/router' +import Manifest from '@/lib/treckingAwb/component/Manifest' +const TrackingOrder = () => { + const [idAWB, setIdAWB] = useState(null) + const closePopup = () => { + setIdAWB(null) + } + const { + register, + handleSubmit, + formState: { errors }, + control, + reset + } = useForm({ + resolver: yupResolver(validationSchema), + defaultValues + }) + + const onSubmitHandler = async (values) => { + console.log('values',values) + // setIdAWB(shipment.id) + // setIdAWB(20623) + setIdAWB(25085) + } + return ( +
    +

    Tracking Order

    +
    + Untuk melacak pesanan Anda, masukkan ID Pesanan Anda di kotak di bawah ini dan tekan tombol "Lacak". ID ini diberikan kepada Anda pada tanda terima dan dalam email konfirmasi yang seharusnya Anda terima. +
    +
    +
    +
    +
    + + + {console.log("errors",errors)} +
    {errors.id?.message}
    +
    +
    + + +
    {errors.email?.message}
    +
    +
    +
    + + +
    +
    + +
    +
    + ) +} + +const validationSchema = Yup.object().shape({ + email: Yup.string().email('Format harus seperti contoh@email.com'), + id: Yup.string().required('Harus di-isi'), + }) + + const defaultValues = { + email: '', + id: '' + } + + +export default TrackingOrder diff --git a/src/pages/tracking-order.jsx b/src/pages/tracking-order.jsx new file mode 100644 index 00000000..18e1a78a --- /dev/null +++ b/src/pages/tracking-order.jsx @@ -0,0 +1,26 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' +import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter'; +import BasicLayout from '@/core/components/layouts/BasicLayout'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +const PageTrackingOrder = dynamic(() => import('@/lib/tracking-order/component/TrackingOrder')) + +export default function TrackingOrder() { + return ( + <> + + + + + + + + + + + + + + ); +} -- cgit v1.2.3 From 9ee852f139aed0f1034798b6a22b76eb9bd03aa4 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 12 Aug 2024 16:35:23 +0700 Subject: update tracking order --- src/lib/tracking-order/api/trackingOrder.js | 8 + src/lib/tracking-order/component/TrackingOrder.jsx | 164 +++++++++++++-------- 2 files changed, 107 insertions(+), 65 deletions(-) create mode 100644 src/lib/tracking-order/api/trackingOrder.js (limited to 'src') diff --git a/src/lib/tracking-order/api/trackingOrder.js b/src/lib/tracking-order/api/trackingOrder.js new file mode 100644 index 00000000..cc48c40c --- /dev/null +++ b/src/lib/tracking-order/api/trackingOrder.js @@ -0,0 +1,8 @@ +import odooApi from "@/core/api/odooApi"; + +export const trackingOrder = async ({query}) => { + const params = new URLSearchParams(query).toString(); + const list = await odooApi('GET', `/api/v1/tracking_order?${params}`) + + return list; +} diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx index 476e6507..c9f739b3 100644 --- a/src/lib/tracking-order/component/TrackingOrder.jsx +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -1,94 +1,128 @@ -import odooApi from '@/core/api/odooApi' -import HookFormSelect from '@/core/components/elements/Select/HookFormSelect' -import cityApi from '@/lib/address/api/cityApi' import { yupResolver } from '@hookform/resolvers/yup' -import React, { useEffect, useRef, useState } from 'react' -import ReCAPTCHA from 'react-google-recaptcha' -import { Controller, useForm } from 'react-hook-form' -import { toast } from 'react-hot-toast' +import React, { useEffect, useState } from 'react' +import { useForm } from 'react-hook-form' import * as Yup from 'yup' -import { useRouter } from 'next/router' import Manifest from '@/lib/treckingAwb/component/Manifest' +import { trackingOrder } from '../api/trackingOrder' +import { useQuery } from 'react-query' +import { Spinner } from '@chakra-ui/react'; +import { Search } from 'lucide-react'; +import odooApi from '@/core/api/odooApi' + const TrackingOrder = () => { const [idAWB, setIdAWB] = useState(null) + const [inputQuery, setInputQuery] = useState(null) + const [buttonClick, setButtonClick] = useState(false) + const [apiError, setApiError] = useState(null) // State to store API error message + const closePopup = () => { setIdAWB(null) - } + setButtonClick(false) + setInputQuery(null) + setApiError(null) // Reset error message on close + } + const { register, handleSubmit, formState: { errors }, control, reset - } = useForm({ + } = useForm({ resolver: yupResolver(validationSchema), defaultValues - }) + }) + + const query = { + email: inputQuery?.email, + so: inputQuery?.id + } + + const { data: tracking, isLoading, isError, error } = useQuery( + ['tracking', query], + () => trackingOrder({ query: query }), + { + enabled: !!query.email && !!query.so, + onSuccess: (data) => { + if (buttonClick) { + if (data?.code === 403 || data?.code === 400 || data?.code === 404) { + setApiError(data?.description); + } else if (data?.pickings?.length > 0) { + setIdAWB(data.pickings[0]?.id); + } else { + setApiError('No pickings data available'); + } + setButtonClick(false); + setInputQuery(null); + } + }, + } + ); const onSubmitHandler = async (values) => { - console.log('values',values) - // setIdAWB(shipment.id) - // setIdAWB(20623) - setIdAWB(25085) - } - return ( -
    -

    Tracking Order

    -
    - Untuk melacak pesanan Anda, masukkan ID Pesanan Anda di kotak di bawah ini dan tekan tombol "Lacak". ID ini diberikan kepada Anda pada tanda terima dan dalam email konfirmasi yang seharusnya Anda terima. -
    -
    -
    -
    -
    - - +

    Tracking Order

    +
    + Untuk melacak pesanan Anda, masukkan ID Pesanan Anda di kotak di bawah ini dan tekan tombol "Lacak". ID ini diberikan kepada Anda pada tanda terima dan dalam email konfirmasi yang seharusnya Anda terima. +
    +
    + +
    +
    + + - {console.log("errors",errors)} -
    {errors.id?.message}
    +
    {errors.id?.message}
    +
    +
    + + +
    {errors.email?.message}
    +
    -
    - - -
    {errors.email?.message}
    +
    +
    -
    -
    - - -
    - - + + {/* Display the API error message */} + {apiError &&
    {apiError}
    } + +
    -
    - ) + ) } const validationSchema = Yup.object().shape({ - email: Yup.string().email('Format harus seperti contoh@email.com'), + email: Yup.string().email('Format harus seperti contoh@email.com').required('Harus di-isi'), id: Yup.string().required('Harus di-isi'), - }) - - const defaultValues = { +}) + +const defaultValues = { email: '', id: '' - } - +} export default TrackingOrder -- cgit v1.2.3 From 4dc62bbe5262be23b2622853973e803f63214a60 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 12 Aug 2024 17:09:13 +0700 Subject: update category management --- src/lib/category/components/Category.jsx | 32 ++++++++++++++++++++++++++-- src/lib/category/components/PopularBrand.jsx | 2 +- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index ff958378..b10cb661 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -6,11 +6,36 @@ import { ChevronRightIcon } from '@heroicons/react/24/outline' import Image from 'next/image' import { useEffect, useState } from 'react' import PopularBrand from './PopularBrand' +import { bannerApi } from '@/api/bannerApi'; +const { useQuery } = require('react-query') const Category = () => { const [categories, setCategories] = useState([]) const [openCategories, setOpenCategory] = useState([]); + const [banner, setBanner] = useState([]); + + const promotionProgram = useQuery('banner-promo-category-card', bannerApi({ type: 'banner-promo-category-card' })); + // const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' })); + useEffect(() => { + const loadCategories = async () => { + let dataCategories = await odooApi('GET', '/api/v1/category/tree') + dataCategories = dataCategories?.map((category) => { + category.childs = category.childs.map((child1Category) => { + return { + ...child1Category, + isOpen: false + } + }) + return { + ...category, + isOpen: false + } + }) + setCategories(dataCategories) + } + loadCategories() + }, []) useEffect(() => { const loadCategories = async () => { @@ -86,9 +111,12 @@ const Category = () => {
    -
    - + {promotionProgram?.data[0]?.map((banner, index)=>( +
    + {/* */} + {`${banner.name}`}
    + ))}
    diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index dca731e8..7c297d39 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -17,7 +17,7 @@ const PopularBrand = ({ category }) => { const fetchTopBrands = async () => { try { - const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); + const items = await fetchPromoItemsSolr(`category_id_ids:(${category?.categoryDataIds.join(' OR ')})`); // console.log("id",items) // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas const getTop12UniqueBrands = (prod) => { -- cgit v1.2.3 From 3e11fce63de4b0d99a1e48c9998d6fcfcec13d98 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 12 Aug 2024 17:11:07 +0700 Subject: update error code --- src/lib/category/components/PopularBrand.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index 7c297d39..09c0f8a1 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -17,7 +17,7 @@ const PopularBrand = ({ category }) => { const fetchTopBrands = async () => { try { - const items = await fetchPromoItemsSolr(`category_id_ids:(${category?.categoryDataIds.join(' OR ')})`); + const items = await fetchPromoItemsSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); // console.log("id",items) // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas const getTop12UniqueBrands = (prod) => { -- cgit v1.2.3 From 0a889a2acb147ffe3fe0ad1ca205683c7bf3fe82 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 13 Aug 2024 09:12:51 +0700 Subject: add tracking order to footer --- src/core/components/elements/Footer/BasicFooter.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Footer/BasicFooter.jsx b/src/core/components/elements/Footer/BasicFooter.jsx index 4beea604..8f024d86 100644 --- a/src/core/components/elements/Footer/BasicFooter.jsx +++ b/src/core/components/elements/Footer/BasicFooter.jsx @@ -175,7 +175,7 @@ const CustomerGuide = () => (
    Bantuan & Panduan
      -
    • +
    • Metode Pembayaran @@ -210,6 +210,11 @@ const CustomerGuide = () => ( Panduan Pick Up Service
    • +
    • + + Tracking Order + +
    ); -- cgit v1.2.3 From 004a9a644aed65d5c02263f19cce8b7c3000f354 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 13 Aug 2024 10:19:38 +0700 Subject: update category --- src/lib/category/api/popularProduct.js | 5 ++-- src/lib/category/components/Category.jsx | 38 ++++++++++++++-------------- src/lib/category/components/PopularBrand.jsx | 4 +-- 3 files changed, 24 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js index e17e0ae5..146c9449 100644 --- a/src/lib/category/api/popularProduct.js +++ b/src/lib/category/api/popularProduct.js @@ -1,9 +1,10 @@ -export const fetchPromoItemsSolr = async (category_id_ids) => { +export const fetchPopulerProductSolr = 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,manufacture_id_i,id,display_name_s&${sort}`); + const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s,manufacture_id_i,id,display_name_s,qty_sold_f&${sort}`); + console.log("response",response) 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 b10cb661..374cdf78 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -37,25 +37,25 @@ const Category = () => { loadCategories() }, []) - useEffect(() => { - const loadCategories = async () => { - let dataCategories = await odooApi('GET', '/api/v1/category/tree') - dataCategories = dataCategories?.map((category) => { - category.childs = category.childs.map((child1Category) => { - return { - ...child1Category, - isOpen: false - } - }) - return { - ...category, - isOpen: false - } - }) - setCategories(dataCategories) - } - loadCategories() - }, []) + // useEffect(() => { + // const loadCategories = async () => { + // let dataCategories = await odooApi('GET', '/api/v1/category/tree') + // dataCategories = dataCategories?.map((category) => { + // category.childs = category.childs.map((child1Category) => { + // return { + // ...child1Category, + // isOpen: false + // } + // }) + // return { + // ...category, + // isOpen: false + // } + // }) + // setCategories(dataCategories) + // } + // loadCategories() + // }, []) // console.log("categories",categories) return ( diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index 09c0f8a1..f0b12e2c 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -8,7 +8,7 @@ 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 { fetchPopulerProductSolr } from '../api/popularProduct' const SOLR_HOST = process.env.SOLR_HOST @@ -17,7 +17,7 @@ const PopularBrand = ({ category }) => { const fetchTopBrands = async () => { try { - const items = await fetchPromoItemsSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); + const items = await fetchPopulerProductSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); // console.log("id",items) // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas const getTop12UniqueBrands = (prod) => { -- cgit v1.2.3 From 4fa3d1026ebabeb75dafc3bb9c630ea300859959 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 13 Aug 2024 11:23:19 +0700 Subject: update tracking order --- src/lib/tracking-order/component/TrackingOrder.jsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx index c9f739b3..03b21b3e 100644 --- a/src/lib/tracking-order/component/TrackingOrder.jsx +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -7,7 +7,7 @@ import { trackingOrder } from '../api/trackingOrder' import { useQuery } from 'react-query' import { Spinner } from '@chakra-ui/react'; import { Search } from 'lucide-react'; -import odooApi from '@/core/api/odooApi' +import whatsappUrl from '@/core/utils/whatsappUrl'; const TrackingOrder = () => { const [idAWB, setIdAWB] = useState(null) @@ -68,7 +68,17 @@ const TrackingOrder = () => {

    Tracking Order

    - Untuk melacak pesanan Anda, masukkan ID Pesanan Anda di kotak di bawah ini dan tekan tombol "Lacak". ID ini diberikan kepada Anda pada tanda terima dan dalam email konfirmasi yang seharusnya Anda terima. + + {`Untuk melacak pesanan Anda, masukkan Nomor Transaksi di kotak bawah ini dan masukkan Email login anda lalu tekan tombol "Lacak". Nomor Transaksi ini dapat Anda lihat dalam menu `} + + Daftar Transaksi + + {`. Jika mengalami kesulitan `} + + hubungi kami + + {`.`} +
    -- cgit v1.2.3 From f97e2c348e3c4b3984eb598ac34de98e35fdde28 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 13 Aug 2024 12:00:17 +0700 Subject: update number wa --- src/lib/tracking-order/component/TrackingOrder.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx index 03b21b3e..cf790832 100644 --- a/src/lib/tracking-order/component/TrackingOrder.jsx +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -74,7 +74,7 @@ const TrackingOrder = () => { Daftar Transaksi {`. Jika mengalami kesulitan `} - + hubungi kami {`.`} -- cgit v1.2.3 From e8745f729cb48a2cab96f8f216617240326f2018 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 13 Aug 2024 14:39:08 +0700 Subject: add feature pickup service --- src/lib/checkout/components/Checkout.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 09a791ee..5f771f41 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -1295,7 +1295,7 @@ const Checkout = () => {
    {!!products && snakecaseKeys(products).map((item, index) => ( - + ))}
    -- cgit v1.2.3 From 62704c101d17afb7f71389ef23d6183b2cd16dfa Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 14 Aug 2024 15:11:33 +0700 Subject: update self picking di product card --- src/lib/product/components/ProductCard.jsx | 28 ++++++++++++++++++++++++---- src/utils/solrMapping.js | 1 + 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 35e2a665..4b3f693c 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -147,9 +147,20 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
    {product?.manufacture?.name ? ( - - {product.manufacture.name} - +
    + +
    + {product.manufacture.name} +
    + + {product?.is_in_bu && ( +
    + + Click & Pickup + +
    + )} +
    ) : (
    -
    )} @@ -292,9 +303,18 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
    )} {product?.manufacture?.name ? ( - +
    + {product.manufacture.name} + {/* {product?.is_in_bu && ( +
    + + Click & Pickup + +
    + )} */} +
    ) : (
    -
    )} diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js index d4694eb2..fee474be 100644 --- a/src/utils/solrMapping.js +++ b/src/utils/solrMapping.js @@ -38,6 +38,7 @@ export const productMappingSolr = (products, pricelist) => { qtySold: product?.qty_sold_f || 0, isTkdn:product?.tkdn_b || false, isSni:product?.sni_b || false, + is_in_bu:product?.is_in_bu_b || false, voucherPastiHemat:product?.voucher_pastihemat || [] }; -- cgit v1.2.3 From c324065cf2270c4e489749f0281eb45a5f120b08 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 14 Aug 2024 15:20:16 +0700 Subject: change to --- src/lib/tracking-order/component/TrackingOrder.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx index cf790832..394979c1 100644 --- a/src/lib/tracking-order/component/TrackingOrder.jsx +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -8,6 +8,7 @@ import { useQuery } from 'react-query' import { Spinner } from '@chakra-ui/react'; import { Search } from 'lucide-react'; import whatsappUrl from '@/core/utils/whatsappUrl'; +import Link from 'next/link' const TrackingOrder = () => { const [idAWB, setIdAWB] = useState(null) @@ -70,13 +71,13 @@ const TrackingOrder = () => { -- cgit v1.2.3 From ad82ceb618565eec7b1e955c8ba12243d26253f1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 15 Aug 2024 11:27:35 +0700 Subject: update view --- src/lib/checkout/components/Checkout.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 5f771f41..6deba693 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -1004,7 +1004,7 @@ const Checkout = () => {
    {!!products && snakecaseKeys(products).map((item, index) => ( - + ))}
    -- cgit v1.2.3 From 33363a1a8dc7f4641b7b054dc72339bf53495102 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 15 Aug 2024 16:55:28 +0700 Subject: update pickup image on product card --- src/lib/product/components/ProductCard.jsx | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 4b3f693c..a1491c7f 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -146,24 +146,20 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )}
    - {product?.manufacture?.name ? ( -
    - -
    - {product.manufacture.name} -
    - +
    + {product?.manufacture?.name ? ( + + {product.manufacture.name} + + ) : ( +
    -
    + )} {product?.is_in_bu && ( -
    - - Click & Pickup - +
    + pickup now
    )} -
    - ) : ( -
    -
    - )} +
    Date: Tue, 20 Aug 2024 16:29:22 +0700 Subject: delete border brand homepage --- src/lib/home/components/PreferredBrand.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index fdefb526..56268db7 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -71,7 +71,7 @@ const PreferredBrand = () => { )}
    -
    +
    {manufactures.isLoading && } {!manufactures.isLoading && ( -- cgit v1.2.3 From 16db179d5bb5ebd3ce946fb6e682539ffc8f728e Mon Sep 17 00:00:00 2001 From: Imanuel Marinao Date: Tue, 20 Aug 2024 20:40:32 +0700 Subject: update avoid error --- src/core/components/elements/Navbar/TopBanner.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 5ea8f635..f438ae67 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -6,7 +6,7 @@ import Link from '../Link/Link'; import { background } from '@chakra-ui/react'; import { useEffect } from 'react'; -const TopBanner = ({ onLoad }) => { +const TopBanner = ({ onLoad = () => {} }) => { const { isDesktop, isMobile } = useDevice() const topBanner = useQuery({ queryKey: 'topBanner', -- cgit v1.2.3 From 152eee248c4a793250526954e62a9e82258d615a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 21 Aug 2024 11:44:08 +0700 Subject: update image margin --- src/lib/home/components/CategoryDynamic.jsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 0cc43d91..b7798a24 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -82,6 +82,7 @@ const CategoryDynamic = () => { -- cgit v1.2.3 From 6dafc3c06566646bdf23ab1da271e337b131ccd9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 22 Aug 2024 10:27:47 +0700 Subject: update name field --- 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 a1491c7f..611fb002 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -154,7 +154,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { ) : (
    -
    )} - {product?.is_in_bu && ( + {product?.isInBu && (
    pickup now
    -- cgit v1.2.3 From 5e2a8d315fa0bc58a18d4df5a995e402388995c9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 22 Aug 2024 13:10:29 +0700 Subject: update category dropdown --- src/lib/category/api/popularProduct.js | 3 +- src/lib/category/components/Category.jsx | 30 ++----------------- src/lib/category/components/PopularBrand.jsx | 45 ++++++++++++++++++---------- src/styles/globals.css | 3 +- 4 files changed, 36 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js index 48f8a2a0..3fdfc41c 100644 --- a/src/lib/category/api/popularProduct.js +++ b/src/lib/category/api/popularProduct.js @@ -3,7 +3,7 @@ export const fetchPopulerProductSolr = 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,manufacture_id_i,id,display_name_s,qty_sold_f&${sort}`); + const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s,manufacture_id_i,id,display_name_s,qty_sold_f,qty_sold_f&${sort}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } @@ -24,6 +24,7 @@ export const fetchPopulerProductSolr = async (category_id_ids) => { name: promotion.display_name_s, manufacture_name: promotion.manufacture_name_s, manufacture_id: promotion.manufacture_id_i, + qty_sold: promotion.qty_sold_f, }; result.push(data); } diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index 374cdf78..f76e6e42 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -15,7 +15,6 @@ const Category = () => { const [banner, setBanner] = useState([]); const promotionProgram = useQuery('banner-promo-category-card', bannerApi({ type: 'banner-promo-category-card' })); - // const promotionProgram = useQuery('promotionProgram', bannerApi({ type: 'banner-promotion' })); useEffect(() => { const loadCategories = async () => { @@ -36,28 +35,6 @@ const Category = () => { } loadCategories() }, []) - - // useEffect(() => { - // const loadCategories = async () => { - // let dataCategories = await odooApi('GET', '/api/v1/category/tree') - // dataCategories = dataCategories?.map((category) => { - // category.childs = category.childs.map((child1Category) => { - // return { - // ...child1Category, - // isOpen: false - // } - // }) - // return { - // ...category, - // isOpen: false - // } - // }) - // setCategories(dataCategories) - // } - // loadCategories() - // }, []) - // console.log("categories",categories) - return (
    @@ -67,8 +44,8 @@ const Category = () => { href={createSlug('/shop/category/', category.name, category.id)} className='category-mega-box__parent flex items-center' > -
    - +
    +
    {category.name} @@ -111,9 +88,8 @@ const Category = () => {
    - {promotionProgram?.data[0]?.map((banner, index)=>( + {Array.isArray(promotionProgram?.data) && promotionProgram?.data.length > 0 && promotionProgram?.data[0]?.map((banner, index) => (
    - {/* */} {`${banner.name}`}
    ))} diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index f0b12e2c..4777fded 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -18,28 +18,41 @@ const PopularBrand = ({ category }) => { const fetchTopBrands = async () => { try { const items = await fetchPopulerProductSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); - // console.log("id",items) - // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas const getTop12UniqueBrands = (prod) => { - const brandSet = new Set(); - const topBrands = []; - + const brandMap = new Map(); + 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{ + const { manufacture_name, manufacture_id, qty_sold } = product; + + if (brandMap.has(manufacture_name)) { + // Update the existing brand's qty_sold + brandMap.set(manufacture_name, { + name: manufacture_name, + id: manufacture_id, + qty_sold: brandMap.get(manufacture_name).qty_sold + qty_sold + }); + } else { + // Add a new brand to the map + brandMap.set(manufacture_name, { + name: manufacture_name, + id: manufacture_id, + qty_sold + }); } - if (topBrands.length === 18) break; } - return topBrands; - } - - // Menggunakan hasil pencarian produk + + // Convert the map to an array and sort by qty_sold in descending order + const sortedBrands = Array.from(brandMap.values()).sort((a, b) => b.qty_sold - a.qty_sold); + + // Return the top 12 brands + return sortedBrands.slice(0, 18); + }; + + // Using the fetched products const products = items; const top12UniqueBrands = getTop12UniqueBrands(products); - - // console.log('top12UniqueBrands', top12UniqueBrands); + + // Set the top 12 brands to the state setTopBrands(top12UniqueBrands); } catch (error) { console.error("Error fetching data from Solr", error); diff --git a/src/styles/globals.css b/src/styles/globals.css index 505dcab4..b3ca85f4 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -563,7 +563,8 @@ button { } .category-mega-box > div:hover .category-mega-box__parent { - @apply bg-gray_r-5; + @apply bg-gray_r-5 + w-full; } .category-mega-box > div:hover .category-mega-box__child-wrapper { -- cgit v1.2.3 From 6623dba2f6cd4a4ca7b25f7086991afef092cd26 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 22 Aug 2024 15:48:00 +0700 Subject: update new register view --- src/pages/api/activation-request.js | 2 +- src/styles/globals.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pages/api/activation-request.js b/src/pages/api/activation-request.js index 61dbb597..64a67bbc 100644 --- a/src/pages/api/activation-request.js +++ b/src/pages/api/activation-request.js @@ -7,7 +7,7 @@ export default async function handler(req, res) { let result = await odooApi('POST', '/api/v1/user/activation-request', { email }) if (result.activationRequest) { mailer.sendMail({ - from: 'sales@indoteknik.com', + from: 'noreply@indoteknik.com', to: result.user.email, subject: 'Permintaan Aktivasi Akun Indoteknik', html: ` diff --git a/src/styles/globals.css b/src/styles/globals.css index f6561b00..ebd5e9a5 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -98,7 +98,7 @@ button { border text-gray_r-12 border-gray_r-7 - !bg-white + bg-white bg-transparent w-full leading-none -- cgit v1.2.3 From ae5891eba4ad89fd8281d26ce765b3b5d6662483 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 22 Aug 2024 17:22:28 +0700 Subject: update email --- src/pages/api/activation-request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/api/activation-request.js b/src/pages/api/activation-request.js index 61dbb597..64a67bbc 100644 --- a/src/pages/api/activation-request.js +++ b/src/pages/api/activation-request.js @@ -7,7 +7,7 @@ export default async function handler(req, res) { let result = await odooApi('POST', '/api/v1/user/activation-request', { email }) if (result.activationRequest) { mailer.sendMail({ - from: 'sales@indoteknik.com', + from: 'noreply@indoteknik.com', to: result.user.email, subject: 'Permintaan Aktivasi Akun Indoteknik', html: ` -- cgit v1.2.3 From 07dd60c2706d960ebb9cebe093b449f32c5f87a2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 23 Aug 2024 09:32:19 +0700 Subject: update activation request from mail --- src/pages/api/activation-request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/api/activation-request.js b/src/pages/api/activation-request.js index 64a67bbc..98d27f78 100644 --- a/src/pages/api/activation-request.js +++ b/src/pages/api/activation-request.js @@ -7,7 +7,7 @@ export default async function handler(req, res) { let result = await odooApi('POST', '/api/v1/user/activation-request', { email }) if (result.activationRequest) { mailer.sendMail({ - from: 'noreply@indoteknik.com', + from: 'Indoteknik.com ', to: result.user.email, subject: 'Permintaan Aktivasi Akun Indoteknik', html: ` -- cgit v1.2.3 From 6111e1115ffba4ef336dfb763b3fd23e52b6668b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 23 Aug 2024 10:50:47 +0700 Subject: update click image pickup now --- src/lib/product/components/ProductCard.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 611fb002..22ce0533 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -155,9 +155,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
    -
    )} {product?.isInBu && ( -
    - pickup now -
    + + pickup now + + + )}
    Date: Fri, 23 Aug 2024 11:13:54 +0700 Subject: update google tag to new tag --- src/pages/_document.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index cd60bd89..6af6294f 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -41,13 +41,13 @@ export default function MyDocument() { content='328wmjs7hcnz74rwsqzxvq50rmbtm2' /> -