diff options
| author | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2024-02-09 10:19:48 +0700 |
|---|---|---|
| committer | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2024-02-09 10:19:48 +0700 |
| commit | 5ea7cbe7aa564d66a3660839d5a2c40d877647cc (patch) | |
| tree | 6666549859fe0e1e890263c8d1c24699be9f7ffc | |
| parent | 2e38ec15d42201c26c48f9bcf856750204db0582 (diff) | |
| parent | 41f5aa212c69b61c2b101b682e77c8106849076e (diff) | |
Merge branch 'release' of https://bitbucket.org/altafixco/next-indoteknik into release
| -rw-r--r-- | src-migrate/modules/product-detail/components/ProductDetail.tsx | 5 | ||||
| -rw-r--r-- | src-migrate/modules/product-detail/components/SimilarBottom.tsx | 12 | ||||
| -rw-r--r-- | src-migrate/modules/product-detail/components/SimilarSide.tsx | 12 | ||||
| -rw-r--r-- | src-migrate/modules/product-detail/styles/side-similar.module.css | 3 | ||||
| -rw-r--r-- | src/core/components/layouts/BasicLayout.jsx | 39 | ||||
| -rw-r--r-- | src/core/utils/slug.js | 34 | ||||
| -rw-r--r-- | src/lib/product/components/ProductSearch.jsx | 35 | ||||
| -rw-r--r-- | src/pages/shop/category/[slug].jsx | 44 |
8 files changed, 107 insertions, 77 deletions
diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index 80f43aea..2bd3c901 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -23,6 +23,7 @@ import SimilarBottom from './SimilarBottom' import PriceAction from './PriceAction' import ProductPromoSection from '~/modules/product-promo/components/Section' import Breadcrumb from './Breadcrumb' +import { LazyLoadComponent } from 'react-lazy-load-image-component' type Props = { product: IProductDetail @@ -166,7 +167,9 @@ const ProductDetail = ({ product }: Props) => { <div className='h-6' /> - <SimilarBottom product={product} /> + <LazyLoadComponent> + <SimilarBottom product={product} /> + </LazyLoadComponent> </div> <div className='h-6 md:h-0' /> diff --git a/src-migrate/modules/product-detail/components/SimilarBottom.tsx b/src-migrate/modules/product-detail/components/SimilarBottom.tsx index 9a12a6ef..40d4dd82 100644 --- a/src-migrate/modules/product-detail/components/SimilarBottom.tsx +++ b/src-migrate/modules/product-detail/components/SimilarBottom.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { Skeleton } from '@chakra-ui/react' import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' import ProductSlider from '~/modules/product-slider' import { IProductDetail } from '~/types/product' @@ -15,7 +15,15 @@ const SimilarBottom = ({ product }: Props) => { const products = productSimilar.data?.products || [] - return <ProductSlider products={products} productLayout='vertical' />; + return ( + <Skeleton + isLoaded={!productSimilar.isLoading} + rounded='lg' + className='h-[350px]' + > + <ProductSlider products={products} productLayout='vertical' /> + </Skeleton> + ); } export default SimilarBottom
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarSide.tsx b/src-migrate/modules/product-detail/components/SimilarSide.tsx index 646a1c51..d70a314d 100644 --- a/src-migrate/modules/product-detail/components/SimilarSide.tsx +++ b/src-migrate/modules/product-detail/components/SimilarSide.tsx @@ -1,6 +1,4 @@ -import style from '../styles/side-similar.module.css' - -import React from 'react' +import { Skeleton } from '@chakra-ui/react' import ProductCard from '~/modules/product-card' import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' @@ -19,7 +17,11 @@ const SimilarSide = ({ product }: Props) => { const products = productSimilar.data?.products || [] return ( - <div className={style['wrapper']}> + <Skeleton + isLoaded={!productSimilar.isLoading} + className="h-[500px] overflow-auto grid grid-cols-1 gap-y-4 divide-y divide-gray-300 border border-gray-300 rounded-lg" + rounded='lg' + > {products.map((product) => ( <ProductCard key={product.id} @@ -27,7 +29,7 @@ const SimilarSide = ({ product }: Props) => { layout='horizontal' /> ))} - </div> + </Skeleton> ) } diff --git a/src-migrate/modules/product-detail/styles/side-similar.module.css b/src-migrate/modules/product-detail/styles/side-similar.module.css deleted file mode 100644 index 08692efa..00000000 --- a/src-migrate/modules/product-detail/styles/side-similar.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.wrapper { - @apply max-h-[500px] overflow-auto grid grid-cols-1 gap-y-4 divide-y divide-gray-300 border border-gray-300 rounded-lg; -} diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index b6e2c59f..fa41a8ed 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -1,8 +1,9 @@ import dynamic from 'next/dynamic'; import Image from 'next/image'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useProductContext } from '@/contexts/ProductContext'; +import odooApi from '@/core/api/odooApi'; import whatsappUrl from '@/core/utils/whatsappUrl'; import { useRouter } from 'next/router'; @@ -41,20 +42,28 @@ const BasicLayout = ({ children }) => { } }, [product, router]); - // useEffect(() => { - // const getIP = async () => { - // const ip = await odooApi('GET', '/api/ip-address'); - // const data = { - // page_title: document.title, - // url: window.location.href, - // ip: ip, - // }; - // axios.get( - // `/api/user-activity?page_title=${data.page_title}&url=${data.url}&ip=${data.ip}` - // ); - // }; - // getIP(); - // }, []); + const recordActivity = useCallback(async () => { + const recordedPath = [ + '/shop/product/[slug]', + '/shop/product/variant/[slug]', + ]; + + if (!recordedPath.includes(router.pathname)) return; + + const ip = await odooApi('GET', '/api/ip-address'); + const data = new URLSearchParams({ + page_title: document.title, + url: window.location.href, + ip, + }); + + fetch(`/api/user-activity?${data.toString()}`); + }, [router.pathname]); + + useEffect(() => { + recordActivity(); + }, [recordActivity]); + return ( <> <Navbar /> diff --git a/src/core/utils/slug.js b/src/core/utils/slug.js index e91bcf83..19c7b115 100644 --- a/src/core/utils/slug.js +++ b/src/core/utils/slug.js @@ -1,4 +1,4 @@ -import toTitleCase from './toTitleCase' +import toTitleCase from './toTitleCase'; /** * Creates a slug from input parameters by converting the name and appending it with an ID. @@ -10,19 +10,20 @@ import toTitleCase from './toTitleCase' * @returns {string} - The generated slug with the prefix, name, and ID. */ const createSlug = (prefix, name, id, withHost = false) => { + name ||= ''; let slug = name ?.trim() .replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-') .toLowerCase() + '-' + - id - let splitSlug = slug.split('-') - let filterSlugFromEmptyChar = splitSlug.filter((x) => x != '') - slug = prefix + filterSlugFromEmptyChar.join('-') - if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug - return slug -} + id; + let splitSlug = slug.split('-'); + let filterSlugFromEmptyChar = splitSlug.filter((x) => x != ''); + slug = prefix + filterSlugFromEmptyChar.join('-'); + if (withHost) slug = process.env.NEXT_PUBLIC_SELF_HOST + slug; + return slug; +}; /** * Extracts the ID from a slug. @@ -32,9 +33,9 @@ const createSlug = (prefix, name, id, withHost = false) => { * @returns {string} - The extracted ID from the slug. */ const getIdFromSlug = (slug) => { - let id = slug.split('-') - return id[id.length - 1] -} + let id = slug.split('-'); + return id[id.length - 1]; +}; /** * Extracts the name from a slug. @@ -45,9 +46,10 @@ const getIdFromSlug = (slug) => { * @returns {string} - The extracted name from the slug in title case. */ const getNameFromSlug = (slug) => { - let name = slug.split('-') - name.pop() - return toTitleCase(name.join(' ')) -} + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +}; + +export { createSlug, getIdFromSlug, getNameFromSlug }; -export { createSlug, getIdFromSlug, getNameFromSlug } diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 90e93aa0..b3fdf888 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -1,25 +1,28 @@ -import { useEffect, useMemo, useState } from 'react'; -import useProductSearch from '../hooks/useProductSearch'; -import ProductCard from './ProductCard'; -import Pagination from '@/core/components/elements/Pagination/Pagination'; -import { toQuery } from 'lodash-contrib'; -import _ from 'lodash'; -import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; -import ProductFilter from './ProductFilter'; -import useActive from '@/core/hooks/useActive'; -import MobileView from '@/core/components/views/MobileView'; -import DesktopView from '@/core/components/views/DesktopView'; import NextImage from 'next/image'; -import ProductFilterDesktop from './ProductFilterDesktop'; import { useRouter } from 'next/router'; -import searchSpellApi from '@/core/api/searchSpellApi'; -import Link from '@/core/components/elements/Link/Link'; -import whatsappUrl from '@/core/utils/whatsappUrl'; +import { useEffect, useMemo, useState } from 'react'; + import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; +import axios from 'axios'; +import _ from 'lodash'; +import { toQuery } from 'lodash-contrib'; + import odooApi from '@/core/api/odooApi'; +import searchSpellApi from '@/core/api/searchSpellApi'; +import Link from '@/core/components/elements/Link/Link'; +import Pagination from '@/core/components/elements/Pagination/Pagination'; +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import useActive from '@/core/hooks/useActive'; import { formatCurrency } from '@/core/utils/formatValue'; -import axios from 'axios'; import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; + +import useProductSearch from '../hooks/useProductSearch'; +import ProductCard from './ProductCard'; +import ProductFilter from './ProductFilter'; +import ProductFilterDesktop from './ProductFilterDesktop'; +import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; const ProductSearch = ({ query, diff --git a/src/pages/shop/category/[slug].jsx b/src/pages/shop/category/[slug].jsx index 6d3985a8..1afe30bf 100644 --- a/src/pages/shop/category/[slug].jsx +++ b/src/pages/shop/category/[slug].jsx @@ -1,25 +1,31 @@ -import dynamic from 'next/dynamic' -import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug' -import { useRouter } from 'next/router' -import _ from 'lodash' -import Seo from '@/core/components/Seo' -import Breadcrumb from '@/lib/category/components/Breadcrumb' +import _ from 'lodash'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; -const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) -const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')) +import Seo from '@/core/components/Seo'; +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; +import Breadcrumb from '@/lib/category/components/Breadcrumb'; + +const BasicLayout = dynamic(() => + import('@/core/components/layouts/BasicLayout') +); +const ProductSearch = dynamic(() => + import('@/lib/product/components/ProductSearch') +); export default function CategoryDetail() { - const router = useRouter() - const { slug = '' } = router.query + const router = useRouter(); + const { slug = '', page = 1 } = router.query; - const categoryName = getNameFromSlug(slug) - const categoryId = getIdFromSlug(slug) - const q = router?.query.q || null + const categoryName = getNameFromSlug(slug); + const categoryId = getIdFromSlug(slug); + const q = router?.query.q || null; const query = { - fq: `category_id_i:${categoryId}` - } + fq: `category_id_i:${categoryId}`, + page, + }; if (q) { - query.q = q + query.q = q; } return ( @@ -30,8 +36,8 @@ export default function CategoryDetail() { additionalMetaTags={[ { property: 'keywords', - content: `Jual ${categoryName}, harga ${categoryName}, ${categoryName} murah, toko ${categoryName}, ${categoryName} jakarta, ${categoryName} surabaya` - } + content: `Jual ${categoryName}, harga ${categoryName}, ${categoryName} murah, toko ${categoryName}, ${categoryName} jakarta, ${categoryName} surabaya`, + }, ]} /> @@ -41,5 +47,5 @@ export default function CategoryDetail() { <ProductSearch query={query} prefixUrl={`/shop/category/${slug}`} /> )} </BasicLayout> - ) + ); } |
