From d336735a91133cc3f1cf6f67ba2ac29f0985fd2e Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 2 Mar 2023 16:51:05 +0700 Subject: delete src2 --- src2/components/auth/WithAuth.js | 20 - src2/components/elements/Alert.js | 19 - src2/components/elements/BottomPopup.js | 25 -- src2/components/elements/ConfirmAlert.js | 27 -- src2/components/elements/DescriptionRow.js | 10 - src2/components/elements/Disclosure.js | 14 - src2/components/elements/Fields.js | 21 - src2/components/elements/Filter.js | 176 -------- src2/components/elements/Image.js | 17 - src2/components/elements/LineDivider.js | 7 - src2/components/elements/Link.js | 13 - src2/components/elements/Pagination.js | 58 --- src2/components/elements/ProgressBar.js | 25 -- src2/components/elements/Skeleton.js | 48 --- src2/components/elements/Spinner.js | 13 - src2/components/layouts/AppBar.js | 47 --- src2/components/layouts/Footer.js | 91 ---- src2/components/layouts/Header.js | 253 ----------- src2/components/layouts/Layout.js | 20 - src2/components/manufactures/ManufactureCard.js | 18 - src2/components/products/ProductCard.js | 69 --- src2/components/products/ProductCategories.js | 62 --- src2/components/products/ProductSimilar.js | 25 -- src2/components/products/ProductSlider.js | 39 -- src2/components/transactions/TransactionDetail.js | 67 --- .../transactions/TransactionStatusBadge.js | 45 -- src2/components/variants/VariantCard.js | 92 ---- src2/components/variants/VariantGroupCard.js | 31 -- src2/core/utils/address.js | 27 -- src2/core/utils/apiOdoo.js | 44 -- src2/core/utils/auth.js | 38 -- src2/core/utils/cart.js | 36 -- src2/core/utils/convertToOption.js | 11 - src2/core/utils/currencyFormat.js | 8 - src2/core/utils/formValidation.js | 107 ----- src2/core/utils/getFileBase64.js | 11 - src2/core/utils/greeting.js | 9 - src2/core/utils/mailer.js | 12 - src2/core/utils/slug.js | 25 -- src2/core/utils/toTitleCase.js | 8 - src2/icons/chevron-left.svg | 3 - src2/icons/chevron-right.svg | 3 - src2/icons/close.svg | 1 - src2/icons/filter.svg | 1 - src2/icons/image-placeholder.svg | 1 - src2/icons/instagram.svg | 5 - src2/icons/linkedin.svg | 5 - src2/icons/menu.svg | 1 - src2/icons/minus.svg | 3 - src2/icons/plus.svg | 4 - src2/icons/search.svg | 4 - src2/icons/shopping-cart.svg | 1 - src2/icons/trash.svg | 4 - src2/images/logo.png | Bin 49879 -> 0 bytes src2/images/page-not-found.png | Bin 42280 -> 0 bytes src2/lib/elements/hooks/useBottomPopup.js | 40 -- src2/lib/elements/hooks/useConfirmAlert.js | 49 --- src2/pages/404.js | 27 -- src2/pages/_app.js | 31 -- src2/pages/_error.js | 11 - src2/pages/activate.js | 111 ----- src2/pages/api/activation-request.js | 31 -- src2/pages/api/activation.js | 16 - src2/pages/api/login.js | 15 - src2/pages/api/register.js | 15 - src2/pages/api/shop/search.js | 96 ----- src2/pages/api/shop/suggest.js | 12 - src2/pages/api/token.js | 10 - src2/pages/faqs.js | 91 ---- src2/pages/index.js | 106 ----- src2/pages/login.js | 97 ----- src2/pages/logout.js | 14 - src2/pages/my/address/[id]/edit.js | 249 ----------- src2/pages/my/address/create.js | 234 ----------- src2/pages/my/address/index.js | 84 ---- src2/pages/my/invoice/[id].js | 149 ------- src2/pages/my/invoices.js | 180 -------- src2/pages/my/menu.js | 82 ---- src2/pages/my/profile.js | 134 ------ src2/pages/my/transaction/[id].js | 265 ------------ src2/pages/my/transactions.js | 198 --------- src2/pages/my/wishlist.js | 60 --- src2/pages/register.js | 100 ----- src2/pages/shop/brands/[slug].js | 178 -------- src2/pages/shop/brands/index.js | 79 ---- src2/pages/shop/cart.js | 282 ------------- src2/pages/shop/checkout/finish.js | 47 --- src2/pages/shop/checkout/index.js | 325 -------------- src2/pages/shop/product/[slug].js | 305 -------------- src2/pages/shop/quotation/finish.js | 39 -- src2/pages/shop/quotation/index.js | 140 ------ src2/pages/shop/search.js | 125 ------ src2/styles/globals.css | 468 --------------------- 93 files changed, 6219 deletions(-) delete mode 100644 src2/components/auth/WithAuth.js delete mode 100644 src2/components/elements/Alert.js delete mode 100644 src2/components/elements/BottomPopup.js delete mode 100644 src2/components/elements/ConfirmAlert.js delete mode 100644 src2/components/elements/DescriptionRow.js delete mode 100644 src2/components/elements/Disclosure.js delete mode 100644 src2/components/elements/Fields.js delete mode 100644 src2/components/elements/Filter.js delete mode 100644 src2/components/elements/Image.js delete mode 100644 src2/components/elements/LineDivider.js delete mode 100644 src2/components/elements/Link.js delete mode 100644 src2/components/elements/Pagination.js delete mode 100644 src2/components/elements/ProgressBar.js delete mode 100644 src2/components/elements/Skeleton.js delete mode 100644 src2/components/elements/Spinner.js delete mode 100644 src2/components/layouts/AppBar.js delete mode 100644 src2/components/layouts/Footer.js delete mode 100644 src2/components/layouts/Header.js delete mode 100644 src2/components/layouts/Layout.js delete mode 100644 src2/components/manufactures/ManufactureCard.js delete mode 100644 src2/components/products/ProductCard.js delete mode 100644 src2/components/products/ProductCategories.js delete mode 100644 src2/components/products/ProductSimilar.js delete mode 100644 src2/components/products/ProductSlider.js delete mode 100644 src2/components/transactions/TransactionDetail.js delete mode 100644 src2/components/transactions/TransactionStatusBadge.js delete mode 100644 src2/components/variants/VariantCard.js delete mode 100644 src2/components/variants/VariantGroupCard.js delete mode 100644 src2/core/utils/address.js delete mode 100644 src2/core/utils/apiOdoo.js delete mode 100644 src2/core/utils/auth.js delete mode 100644 src2/core/utils/cart.js delete mode 100644 src2/core/utils/convertToOption.js delete mode 100644 src2/core/utils/currencyFormat.js delete mode 100644 src2/core/utils/formValidation.js delete mode 100644 src2/core/utils/getFileBase64.js delete mode 100644 src2/core/utils/greeting.js delete mode 100644 src2/core/utils/mailer.js delete mode 100644 src2/core/utils/slug.js delete mode 100644 src2/core/utils/toTitleCase.js delete mode 100644 src2/icons/chevron-left.svg delete mode 100644 src2/icons/chevron-right.svg delete mode 100644 src2/icons/close.svg delete mode 100644 src2/icons/filter.svg delete mode 100644 src2/icons/image-placeholder.svg delete mode 100644 src2/icons/instagram.svg delete mode 100644 src2/icons/linkedin.svg delete mode 100644 src2/icons/menu.svg delete mode 100644 src2/icons/minus.svg delete mode 100644 src2/icons/plus.svg delete mode 100644 src2/icons/search.svg delete mode 100644 src2/icons/shopping-cart.svg delete mode 100644 src2/icons/trash.svg delete mode 100644 src2/images/logo.png delete mode 100644 src2/images/page-not-found.png delete mode 100644 src2/lib/elements/hooks/useBottomPopup.js delete mode 100644 src2/lib/elements/hooks/useConfirmAlert.js delete mode 100644 src2/pages/404.js delete mode 100644 src2/pages/_app.js delete mode 100644 src2/pages/_error.js delete mode 100644 src2/pages/activate.js delete mode 100644 src2/pages/api/activation-request.js delete mode 100644 src2/pages/api/activation.js delete mode 100644 src2/pages/api/login.js delete mode 100644 src2/pages/api/register.js delete mode 100644 src2/pages/api/shop/search.js delete mode 100644 src2/pages/api/shop/suggest.js delete mode 100644 src2/pages/api/token.js delete mode 100644 src2/pages/faqs.js delete mode 100644 src2/pages/index.js delete mode 100644 src2/pages/login.js delete mode 100644 src2/pages/logout.js delete mode 100644 src2/pages/my/address/[id]/edit.js delete mode 100644 src2/pages/my/address/create.js delete mode 100644 src2/pages/my/address/index.js delete mode 100644 src2/pages/my/invoice/[id].js delete mode 100644 src2/pages/my/invoices.js delete mode 100644 src2/pages/my/menu.js delete mode 100644 src2/pages/my/profile.js delete mode 100644 src2/pages/my/transaction/[id].js delete mode 100644 src2/pages/my/transactions.js delete mode 100644 src2/pages/my/wishlist.js delete mode 100644 src2/pages/register.js delete mode 100644 src2/pages/shop/brands/[slug].js delete mode 100644 src2/pages/shop/brands/index.js delete mode 100644 src2/pages/shop/cart.js delete mode 100644 src2/pages/shop/checkout/finish.js delete mode 100644 src2/pages/shop/checkout/index.js delete mode 100644 src2/pages/shop/product/[slug].js delete mode 100644 src2/pages/shop/quotation/finish.js delete mode 100644 src2/pages/shop/quotation/index.js delete mode 100644 src2/pages/shop/search.js delete mode 100644 src2/styles/globals.css (limited to 'src2') diff --git a/src2/components/auth/WithAuth.js b/src2/components/auth/WithAuth.js deleted file mode 100644 index ef975873..00000000 --- a/src2/components/auth/WithAuth.js +++ /dev/null @@ -1,20 +0,0 @@ -import { getAuth } from "@/core/utils/auth"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const WithAuth = ({ children }) => { - const router = useRouter(); - const [response, setResponse] = useState(<>); - - useEffect(() => { - if (!getAuth()) { - router.replace('/login'); - } else { - setResponse(children); - } - }, [children, router]); - - return response; -} - -export default WithAuth; \ No newline at end of file diff --git a/src2/components/elements/Alert.js b/src2/components/elements/Alert.js deleted file mode 100644 index 914d1590..00000000 --- a/src2/components/elements/Alert.js +++ /dev/null @@ -1,19 +0,0 @@ -const Alert = ({ children, className, type }) => { - let typeClass = ''; - switch (type) { - case 'info': - typeClass = ' bg-blue-100 text-blue-900 border-blue-400 ' - break; - case 'success': - typeClass = ' bg-green-100 text-green-900 border-green-400 ' - break; - case 'warning': - typeClass = ' bg-yellow-100 text-yellow-900 border-yellow-400 ' - break; - } - return ( -
{children}
- ); -} - -export default Alert; \ No newline at end of file diff --git a/src2/components/elements/BottomPopup.js b/src2/components/elements/BottomPopup.js deleted file mode 100644 index c1a56e10..00000000 --- a/src2/components/elements/BottomPopup.js +++ /dev/null @@ -1,25 +0,0 @@ -import CloseIcon from "@/icons/close.svg"; - -const BottomPopup = ({ - active = false, - title, - children, - closePopup = () => {} -}) => { - return ( - <> -
-
-
-

{ title }

- -
- { children } -
- - ); -}; - -export default BottomPopup; \ No newline at end of file diff --git a/src2/components/elements/ConfirmAlert.js b/src2/components/elements/ConfirmAlert.js deleted file mode 100644 index d33abb89..00000000 --- a/src2/components/elements/ConfirmAlert.js +++ /dev/null @@ -1,27 +0,0 @@ -const ConfirmAlert = ({ - title, - caption, - show, - onClose, - onSubmit, - closeText, - submitText -}) => { - return ( - <> - {show && ( -
- )} -
-

{title}

-

{caption}

-
- - -
-
- - ); -}; - -export default ConfirmAlert; \ No newline at end of file diff --git a/src2/components/elements/DescriptionRow.js b/src2/components/elements/DescriptionRow.js deleted file mode 100644 index 7fe9e3a1..00000000 --- a/src2/components/elements/DescriptionRow.js +++ /dev/null @@ -1,10 +0,0 @@ -const DescriptionRow = ({ label, children }) => ( -
-

{ label }

-
- { children } -
-
-); - -export default DescriptionRow; \ No newline at end of file diff --git a/src2/components/elements/Disclosure.js b/src2/components/elements/Disclosure.js deleted file mode 100644 index 1f334be3..00000000 --- a/src2/components/elements/Disclosure.js +++ /dev/null @@ -1,14 +0,0 @@ -const { ChevronUpIcon, ChevronDownIcon } = require("@heroicons/react/24/outline"); - -const Disclosure = ({ label, active, onClick }) => ( -
-

{ label }

- { onClick && ( active ? ( - - ) : ( - - ) ) } -
-); - -export default Disclosure; \ No newline at end of file diff --git a/src2/components/elements/Fields.js b/src2/components/elements/Fields.js deleted file mode 100644 index 586a6a22..00000000 --- a/src2/components/elements/Fields.js +++ /dev/null @@ -1,21 +0,0 @@ -import ReactSelect from "react-select"; - -const Select = ({ - field, - ...props -}) => ( - <> - field.onChange(option.value)} - value={field.value ? props.options.find(option => option.value === field.value) : ''} - isDisabled={props.disabled} - {...props} - /> - -); - -export { - Select -}; \ No newline at end of file diff --git a/src2/components/elements/Filter.js b/src2/components/elements/Filter.js deleted file mode 100644 index f2051ba8..00000000 --- a/src2/components/elements/Filter.js +++ /dev/null @@ -1,176 +0,0 @@ -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import BottomPopup from "./BottomPopup"; - -const Filter = ({ - isActive, - closeFilter, - defaultRoute, - defaultPriceFrom, - defaultPriceTo, - defaultCategory, - defaultBrand, - defaultOrderBy, - searchResults, - disableFilter = [] -}) => { - const router = useRouter(); - - const [priceFrom, setPriceFrom] = useState(defaultPriceFrom); - const [priceTo, setPriceTo] = useState(defaultPriceTo); - const [orderBy, setOrderBy] = useState(defaultOrderBy); - const [selectedCategory, setSelectedCategory] = useState(defaultCategory); - const [selectedBrand, setSelectedBrand] = useState(defaultBrand); - const [categories, setCategories] = useState([]); - const [brands, setBrands] = useState([]); - - const filterRoute = () => { - let filterRoute = []; - let filterRoutePrefix = '?'; - if (selectedBrand) filterRoute.push(`brand=${selectedBrand}`); - if (selectedCategory) filterRoute.push(`category=${selectedCategory}`); - if (priceFrom) filterRoute.push(`price_from=${priceFrom}`); - if (priceTo) filterRoute.push(`price_to=${priceTo}`); - if (orderBy) filterRoute.push(`order_by=${orderBy}`); - - if (defaultRoute.includes('?')) filterRoutePrefix = '&'; - if (filterRoute.length > 0) { - filterRoute = filterRoutePrefix + filterRoute.join('&'); - } else { - filterRoute = ''; - } - - return defaultRoute + filterRoute; - } - - useEffect(() => { - const filterCategory = searchResults.facet_counts.facet_fields.category_name_str.filter((category, index) => { - if (index % 2 == 0) { - const productCountInCategory = searchResults.facet_counts.facet_fields.category_name_str[index + 1]; - if (productCountInCategory > 0) return category; - } - }); - setCategories(filterCategory); - - const filterBrand = searchResults.facet_counts.facet_fields.brand_str.filter((brand, index) => { - if (index % 2 == 0) { - const productCountInBrand = searchResults.facet_counts.facet_fields.brand_str[index + 1]; - if (productCountInBrand > 0) return brand; - } - }); - setBrands(filterBrand); - }, [searchResults]); - - const submit = (e) => { - e.preventDefault(); - closeFilter(); - router.push(filterRoute(), undefined, { scroll: false }); - } - - const reset = () => { - setSelectedBrand(''); - setSelectedCategory(''); - setPriceFrom(''); - setPriceTo(''); - setOrderBy(''); - } - - const changeOrderBy = (value) => { - if (orderBy == value) { - setOrderBy(''); - } else { - setOrderBy(value); - } - } - - const sortOptions = [ - { - name: 'Harga Terendah', - value: 'price-asc', - }, - { - name: 'Harga Tertinggi', - value: 'price-desc', - }, - { - name: 'Populer', - value: 'popular', - }, - { - name: 'Ready Stock', - value: 'stock', - }, - ]; - - return ( - <> - -
- {(selectedBrand || selectedCategory || priceFrom || priceTo || orderBy) && ( - - )} - - {!disableFilter.includes('orderBy') && ( -
- -
- {sortOptions.map((sortOption, index) => ( - - ))} -
-
- )} - - {!disableFilter.includes('category') && ( -
- - -
- )} - - {!disableFilter.includes('brand') && ( -
- - -
- )} - - {!disableFilter.includes('price') && ( -
- -
- setPriceFrom(e.target.value)}/> - - setPriceTo(e.target.value)}/> -
-
- )} - -
-
- - ) -}; - -export default Filter; \ No newline at end of file diff --git a/src2/components/elements/Image.js b/src2/components/elements/Image.js deleted file mode 100644 index 60e249b9..00000000 --- a/src2/components/elements/Image.js +++ /dev/null @@ -1,17 +0,0 @@ -import { LazyLoadImage } from "react-lazy-load-image-component" -import "react-lazy-load-image-component/src/effects/opacity.css" - -const Image = ({ ...props }) => { - return ( - - ) -} - -Image.defaultProps = LazyLoadImage.defaultProps - -export default Image \ No newline at end of file diff --git a/src2/components/elements/LineDivider.js b/src2/components/elements/LineDivider.js deleted file mode 100644 index 4e8c7b52..00000000 --- a/src2/components/elements/LineDivider.js +++ /dev/null @@ -1,7 +0,0 @@ -const LineDivider = () => { - return ( -
- ); -}; - -export default LineDivider; \ No newline at end of file diff --git a/src2/components/elements/Link.js b/src2/components/elements/Link.js deleted file mode 100644 index 065b5c9e..00000000 --- a/src2/components/elements/Link.js +++ /dev/null @@ -1,13 +0,0 @@ -import NextLink from "next/link"; - -const Link = ({ children, ...props }) => { - return ( - - {children} - - ) -} - -Link.defaultProps = NextLink.defaultProps - -export default Link \ No newline at end of file diff --git a/src2/components/elements/Pagination.js b/src2/components/elements/Pagination.js deleted file mode 100644 index ff2a8462..00000000 --- a/src2/components/elements/Pagination.js +++ /dev/null @@ -1,58 +0,0 @@ -import Link from "./Link"; - -export default function Pagination({ pageCount, currentPage, url }) { - let firstPage = false; - let lastPage = false; - let dotsPrevPage = false; - let dotsNextPage = false; - let urlParameterPrefix = url.includes('?') ? '&' : '?'; - - return pageCount > 1 && ( -
- {Array.from(Array(pageCount)).map((v, i) => { - let page = i + 1; - let rangePrevPage = currentPage - 2; - let rangeNextPage = currentPage + 2; - let PageComponent = {page}; - let DotsComponent =
...
; - - if (pageCount == 7) { - return PageComponent; - } - - if (currentPage == 1) rangeNextPage += 3; - if (currentPage == 2) rangeNextPage += 2; - if (currentPage == 3) rangeNextPage += 1; - if (currentPage == 4) rangePrevPage -= 1; - if (currentPage == pageCount) rangePrevPage -= 3; - if (currentPage == pageCount - 1) rangePrevPage -= 2; - if (currentPage == pageCount - 2) rangePrevPage -= 1; - if (currentPage == pageCount - 3) rangeNextPage += 1; - - if (page > rangePrevPage && page < rangeNextPage) { - return PageComponent; - } - - if (page == 1 && rangePrevPage >= 1 && !firstPage) { - firstPage = true; - return PageComponent; - } - - if (page == pageCount && rangeNextPage <= pageCount && !lastPage) { - lastPage = true; - return PageComponent; - } - - if (page > currentPage && (pageCount - currentPage) > 1 && !dotsNextPage) { - dotsNextPage = true; - return DotsComponent; - } - - if (page < currentPage && (currentPage - 1) > 1 && !dotsPrevPage) { - dotsPrevPage = true; - return DotsComponent; - } - })} -
- ) -} \ No newline at end of file diff --git a/src2/components/elements/ProgressBar.js b/src2/components/elements/ProgressBar.js deleted file mode 100644 index 0adedcdf..00000000 --- a/src2/components/elements/ProgressBar.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Fragment } from "react"; - -const ProgressBar = ({ current, labels }) => { - return ( -
- {labels.map((label, index) => ( - -
-
- { index + 1 } -
-

{ label }

-
- { index < (labels.length - 1) && ( -
-
-
- ) } -
- ))} -
- ) -} - -export default ProgressBar; \ No newline at end of file diff --git a/src2/components/elements/Skeleton.js b/src2/components/elements/Skeleton.js deleted file mode 100644 index fbdbc245..00000000 --- a/src2/components/elements/Skeleton.js +++ /dev/null @@ -1,48 +0,0 @@ -import ImagePlaceholderIcon from "../../icons/image-placeholder.svg"; - -const SkeletonList = ({ number }) => ( -
- { Array.from(Array(number), (e, i) => ( -
-
-
-
-
-
-
- )) } - Loading... -
-); - -const SkeletonProduct = () => ( -
-
-
- -
-
-
-
-
-
- Loading... -
-
-
- -
-
-
-
-
-
- Loading... -
-
-); - -export { - SkeletonList, - SkeletonProduct -}; \ No newline at end of file diff --git a/src2/components/elements/Spinner.js b/src2/components/elements/Spinner.js deleted file mode 100644 index 21006ecd..00000000 --- a/src2/components/elements/Spinner.js +++ /dev/null @@ -1,13 +0,0 @@ -const Spinner = ({ className }) => { - return ( -
- - Loading... -
- ) -} - -export default Spinner; \ No newline at end of file diff --git a/src2/components/layouts/AppBar.js b/src2/components/layouts/AppBar.js deleted file mode 100644 index fe74c940..00000000 --- a/src2/components/layouts/AppBar.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Bars3Icon, ChevronLeftIcon, HomeIcon, ShoppingCartIcon } from "@heroicons/react/24/outline"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import Link from "../elements/Link"; - -const AppBar = ({ title }) => { - const router = useRouter(); - - const handleBackButtonClick = (event) => { - event.currentTarget.disabled = true; - router.back(); - } - - return ( - <> - - { title } - Indoteknik - -
- {/* --- Start Title */} -
- -

{ title }

-
- {/* --- End Title */} - - {/* --- Start Icons */} -
- - - - - - - - - -
- {/* --- End Icons */} -
- - ); -}; - -export default AppBar; \ No newline at end of file diff --git a/src2/components/layouts/Footer.js b/src2/components/layouts/Footer.js deleted file mode 100644 index d173a525..00000000 --- a/src2/components/layouts/Footer.js +++ /dev/null @@ -1,91 +0,0 @@ -import { - PhoneIcon, - DevicePhoneMobileIcon, - EnvelopeIcon -} from "@heroicons/react/24/outline"; -import Image from "next/image"; -import InstagramIcon from "@/icons/instagram.svg"; -import LinkedinIcon from "@/icons/linkedin.svg"; -import Link from "../elements/Link"; - -export default function Footer() { - return ( -
-
-
-

Kantor Pusat

-

- Jl. Bandengan Utara 85A No. 8-9 RT.3/RW.16, Penjaringan, Kec. Penjaringan -

- -

Layanan Informasi

- - - - -

Panduan Pelanggan

-
- FAQ - Kebijakan Privasi - Pengajuan Tempo - Garansi Produk - Online Quotation - Pengiriman - Pembayaran - Syarat & Ketentuan - -
-
-
-

Jam Operasional

-

- Senin - Jumat: 08:30 - 17:00 -

-

- Sabtu: 08:30 - 14:00 -

- -

Temukan Kami

-
- - -
- -

Pembayaran

-
- BCA Payment - BCA Payment - BCA Payment - BCA Payment - BCA Payment - BCA Payment - BCA Payment - BCA Payment -
- - {/*

Pengiriman

*/} -
-
-
PT. Indoteknik Dotcom Gemilang
-
- ); -} \ No newline at end of file diff --git a/src2/components/layouts/Header.js b/src2/components/layouts/Header.js deleted file mode 100644 index 23fda642..00000000 --- a/src2/components/layouts/Header.js +++ /dev/null @@ -1,253 +0,0 @@ -import Image from "next/image"; -import { Fragment, useCallback, useEffect, useRef, useState } from "react"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import axios from "axios"; -import { - MagnifyingGlassIcon, - Bars3Icon, - ShoppingCartIcon, - ChevronRightIcon, - Cog6ToothIcon, - HeartIcon, - ChevronDownIcon, - ChevronUpIcon -} from "@heroicons/react/24/outline"; - -// Helpers -import { useAuth } from "@/core/utils/auth"; -// Components -import Link from "../elements/Link"; -// Images -import Logo from "@/images/logo.png"; -import greeting from "@/core/utils/greeting"; -import apiOdoo from "@/core/utils/apiOdoo"; - -const menus = [ - { name: 'Semua Brand', href: '/shop/brands' }, - { name: 'Blog Indoteknik', href: '/' }, - { name: 'Tentang Indoteknik', href: '/' }, - { name: 'Pusat Bantuan', href: '/' }, -]; - -export default function Header({ title }) { - const router = useRouter(); - const { q = '' } = router.query; - const [searchQuery, setSearchQuery] = useState(q != '*' ? q : ''); - const [suggestions, setSuggestions] = useState([]); - const searchQueryRef = useRef(); - const [isMenuActive, setIsMenuActive] = useState(false); - const [auth] = useAuth(); - - useEffect(() => { - if (q) { - searchQueryRef.current.blur(); - setSuggestions([]); - }; - }, [q]); - - const clickSuggestion = (value) => { - router.push(`/shop/search?q=${value}`, undefined, { scroll: false }); - }; - - const getSuggestion = useCallback(async () => { - if (searchQuery.trim().length > 0) { - let result = await axios(`${process.env.SELF_HOST}/api/shop/suggest?q=${searchQuery.trim()}`); - setSuggestions(result.data.suggest.mySuggester[searchQuery.trim()].suggestions); - } else { - setSuggestions([]); - } - }, [searchQuery]); - - useEffect(() => { - if (document.activeElement == searchQueryRef.current) getSuggestion(); - }, [getSuggestion]); - - const openMenu = () => setIsMenuActive(true); - const closeMenu = () => setIsMenuActive(false); - - const searchSubmit = (e) => { - e.preventDefault(); - if (searchQuery.length > 0) { - router.push(`/shop/search?q=${searchQuery}`, undefined, { scroll: false }); - } else { - searchQueryRef.current.focus(); - } - } - - const [ isOpenCategory, setOpenCategory ] = useState(false); - const [ categories, setCategories ] = useState([]); - - useEffect(() => { - const loadCategories = async () => { - if (isOpenCategory && categories.length == 0) { - let dataCategories = await apiOdoo('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(); - }, [ isOpenCategory, categories ]); - - const toggleCategories = (id = 0) => { - let newCategories = categories.map((category) => { - category.childs = category.childs.map((child1Category) => { - return { - ...child1Category, - isOpen: id == child1Category.id ? !child1Category.isOpen : child1Category.isOpen - } - }) - return { - ...category, - isOpen: id == category.id ? !category.isOpen : category.isOpen - } - }); - setCategories(newCategories); - } - - return ( - <> - - - {title} - - -
-
- { auth && ( - -
-

{ greeting() },

-

{auth.name}

-
-
- -
- - ) } - - { !auth && ( - <> - Masuk - Daftar - - ) } -
-
- { menus.map((menu, index) => ( - - { menu.name } -
- -
- - )) } -
setOpenCategory(!isOpenCategory)}> - Kategori -
- { !isOpenCategory && } - { isOpenCategory && } -
-
- { isOpenCategory && categories.map((category) => ( - -
- - { category.name } - -
toggleCategories(category.id)}> - { !category.isOpen && } - { category.isOpen && } -
-
- { category.isOpen && category.childs.map((child1Category) => ( - -
- - { child1Category.name } - - { child1Category.childs.length > 0 && ( -
toggleCategories(child1Category.id)}> - { !child1Category.isOpen && } - { child1Category.isOpen && } -
- ) } -
- { child1Category.isOpen && child1Category.childs.map((child2Category) => ( - - { child2Category.name } - - )) } -
- )) } -
- )) } -
-
- - -
-
- - Logo Indoteknik - -
- - - - - - - -
-
-
- setSearchQuery(e.target.value)} - onFocus={getSuggestion} - value={searchQuery} - className="form-input rounded-r-none border-r-0 focus:border-gray_r-7" - placeholder="Ketikan nama, merek, part number" - autoComplete="off" - /> - - - - {suggestions.length > 1 && ( -
- {suggestions.map((suggestion, index) => ( -

clickSuggestion(suggestion.term)} className="w-full p-2" key={index}>{suggestion.term}

- ))} -
- )} -
-
- - {suggestions.length > 1 && ( -
setSuggestions([])}>
- )} - - ) -} \ No newline at end of file diff --git a/src2/components/layouts/Layout.js b/src2/components/layouts/Layout.js deleted file mode 100644 index fd507963..00000000 --- a/src2/components/layouts/Layout.js +++ /dev/null @@ -1,20 +0,0 @@ -import { motion } from 'framer-motion'; - -export default function Layout({ children, ...pageProps }) { - const transition = { - ease: 'easeOut', - duration: 0.3 - }; - - return children && ( - - {children} - - ); -} \ No newline at end of file diff --git a/src2/components/manufactures/ManufactureCard.js b/src2/components/manufactures/ManufactureCard.js deleted file mode 100644 index 73a96902..00000000 --- a/src2/components/manufactures/ManufactureCard.js +++ /dev/null @@ -1,18 +0,0 @@ -import { createSlug } from "@/core/utils/slug"; -import Image from "../elements/Image"; -import Link from "../elements/Link"; - -export default function ManufactureCard({ data }) { - const manufacture = data; - return ( - - {manufacture.logo ? ( - {manufacture.name} - ) : manufacture.name} - - ); -} \ No newline at end of file diff --git a/src2/components/products/ProductCard.js b/src2/components/products/ProductCard.js deleted file mode 100644 index c79a4900..00000000 --- a/src2/components/products/ProductCard.js +++ /dev/null @@ -1,69 +0,0 @@ -import Link from "../elements/Link"; -import currencyFormat from "@/core/utils/currencyFormat"; -import { createSlug } from "@/core/utils/slug"; -import { ChevronRightIcon } from "@heroicons/react/20/solid"; -import Image from "../elements/Image"; - - -export default function ProductCard({ - data, - simpleProductTitleLine = false -}) { - let product = data; - return ( -
- - {product.name} - {product.variant_total > 1 ? ( -
{product.variant_total} Varian
- ) : ''} - -
-
- {typeof product.manufacture.name !== "undefined" ? ( - {product.manufacture.name} - ) : ( - - - )} - - {product.name} - -
-
- {product.lowest_price.discount_percentage > 0 ? ( -
-

{currencyFormat(product.lowest_price.price)}

- {product.lowest_price.discount_percentage}% -
- ) : ''} - - {product.lowest_price.price_discount > 0 ? ( -

- {currencyFormat(product.lowest_price.price_discount)} -

- ) : ( - - Tanya Harga - - )} - - {product.stock_total > 0 ? ( -
-
Ready Stock
-
{product.stock_total > 5 ? '> 5' : '< 5'}
-
- ) : ''} -
-
-
- ) -} \ No newline at end of file diff --git a/src2/components/products/ProductCategories.js b/src2/components/products/ProductCategories.js deleted file mode 100644 index 3b671f29..00000000 --- a/src2/components/products/ProductCategories.js +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect, useState } from "react"; -import ProductSlider from "./ProductSlider"; -import apiOdoo from "@/core/utils/apiOdoo"; -import { LazyLoadComponent } from "react-lazy-load-image-component"; -import { SkeletonProduct } from "../elements/Skeleton"; - -const ProductCategory = ({ id }) => { - const [ content, setContent ] = useState(null); - - useEffect(() => { - const loadContent = async () => { - if (!content) { - const dataContent = await apiOdoo('GET', `/api/v1/categories_homepage?id=${id}`); - setContent(dataContent[0]); - } - } - loadContent(); - }, [id, content]); - - return ( -
- { content ? ( - - ) : } -
- ); -} - -export default function ProductCategories() { - const [ contentIds, setContentIds ] = useState([]); - - useEffect(() => { - const getContentIds = async () => { - if (contentIds.length == 0) { - const dataContentIds = await apiOdoo('GET', '/api/v1/categories_homepage/ids'); - setContentIds(dataContentIds); - } - } - getContentIds(); - }, [ contentIds ]); - - return ( -
- { contentIds.map((contentId) => ( - } key={contentId}> - - - )) } -
- ) -} \ No newline at end of file diff --git a/src2/components/products/ProductSimilar.js b/src2/components/products/ProductSimilar.js deleted file mode 100644 index 9e2292cb..00000000 --- a/src2/components/products/ProductSimilar.js +++ /dev/null @@ -1,25 +0,0 @@ -import apiOdoo from '@/core/utils/apiOdoo'; -import { useEffect, useState } from 'react'; -import ProductSlider from './ProductSlider'; - -export default function ProductSimilar({ productId }) { - const [similarProducts, setSimilarProducts] = useState(null); - - useEffect(() => { - const getSimilarProducts = async () => { - if (productId && !similarProducts) { - const dataSimilarProducts = await apiOdoo('GET', `/api/v1/product/${productId}/similar?limit=20`); - setSimilarProducts(dataSimilarProducts); - } - } - getSimilarProducts(); - }, [productId, similarProducts]); - - - return ( -
-

Kamu Mungkin Juga Suka

- -
- ) -} \ No newline at end of file diff --git a/src2/components/products/ProductSlider.js b/src2/components/products/ProductSlider.js deleted file mode 100644 index 662a6511..00000000 --- a/src2/components/products/ProductSlider.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Swiper, SwiperSlide } from "swiper/react"; -import ProductCard from "./ProductCard"; -import "swiper/css"; -import Image from "../elements/Image"; -import Link from "../elements/Link"; -import { SkeletonProduct } from "../elements/Skeleton"; -import { useState } from "react"; - -export default function ProductSlider({ - products, - simpleProductTitleLine = false, - bannerMode = false -}) { - const [ activeIndex, setActiveIndex ] = useState(0); - const swiperSliderFirstMove = (swiper) => { - setActiveIndex(swiper.activeIndex); - }; - - return ( - <> - { bannerMode && ( - {products.banner.name} 0 ? 'opacity-0' : 'opacity-100')} /> - ) } - - { bannerMode && ( - - - - ) } - {products?.products?.map((product, index) => ( - - - - ))} - - { !products ? : ''} - - ) -} \ No newline at end of file diff --git a/src2/components/transactions/TransactionDetail.js b/src2/components/transactions/TransactionDetail.js deleted file mode 100644 index 295a4f9f..00000000 --- a/src2/components/transactions/TransactionDetail.js +++ /dev/null @@ -1,67 +0,0 @@ -import { useState } from "react"; -import DescriptionRow from "../elements/DescriptionRow"; -import Disclosure from "../elements/Disclosure"; - -const DetailAddress = ({ address }) => { - const fullAddress = []; - if (address?.street) fullAddress.push(address.street); - if (address?.sub_district?.name) fullAddress.push(address.sub_district.name); - if (address?.district?.name) fullAddress.push(address.district.name); - if (address?.city?.name) fullAddress.push(address.city.name); - return ( -
- { address?.name } - { address?.email || '-' } - { address?.mobile || '-' } - { fullAddress.join(', ') } -
- ); -}; - -const TransactionDetailAddress = ({ transaction }) => { - const [ activeSection, setActiveSection ] = useState({ - purchase: false, - shipping: false, - invoice: false, - }); - - const toggleSection = ( name ) => { - setActiveSection({ - ...activeSection, - [name]: !activeSection[name] - }); - }; - - return ( -
- toggleSection('purchase')} - /> - { activeSection.purchase && ( - - ) } - - toggleSection('shipping')} - /> - { activeSection.shipping && ( - - ) } - - toggleSection('invoice')} - /> - { activeSection.invoice && ( - - ) } -
- ); -}; - -export { TransactionDetailAddress }; \ No newline at end of file diff --git a/src2/components/transactions/TransactionStatusBadge.js b/src2/components/transactions/TransactionStatusBadge.js deleted file mode 100644 index f94fd3fd..00000000 --- a/src2/components/transactions/TransactionStatusBadge.js +++ /dev/null @@ -1,45 +0,0 @@ -const TransactionStatusBadge = ({ status }) => { - let badgeProps = { - className: ['h-fit'], - text: '' - }; - switch (status) { - case 'cancel': - badgeProps.className.push('badge-solid-red'); - badgeProps.text = 'Pesanan Batal' - break; - case 'draft': - badgeProps.className.push('badge-red'); - badgeProps.text = 'Pending Quotation' - break; - case 'waiting': - badgeProps.className.push('badge-yellow'); - badgeProps.text = 'Pesanan diterima' - break; - case 'sale': - badgeProps.className.push('badge-yellow'); - badgeProps.text = 'Pesanan diproses' - break; - case 'shipping': - badgeProps.className.push('badge-green'); - badgeProps.text = 'Pesanan dikirim' - break; - case 'partial_shipping': - badgeProps.className.push('badge-green'); - badgeProps.text = 'Dikirim sebagian' - break; - case 'done': - badgeProps.className.push('badge-solid-green'); - badgeProps.text = 'Pesanan Selesai' - break; - } - badgeProps.className = badgeProps.className.join(' '); - - return ( -
- { badgeProps.text } -
- ) -}; - -export default TransactionStatusBadge; \ No newline at end of file diff --git a/src2/components/variants/VariantCard.js b/src2/components/variants/VariantCard.js deleted file mode 100644 index a821480c..00000000 --- a/src2/components/variants/VariantCard.js +++ /dev/null @@ -1,92 +0,0 @@ -import { createSlug } from "@/core/utils/slug"; -import Image from "../elements/Image"; -import Link from "../elements/Link"; -import currencyFormat from "@/core/utils/currencyFormat"; -import { useRouter } from "next/router"; -import { toast } from "react-hot-toast"; -import { createOrUpdateItemCart } from "@/core/utils/cart"; - -export default function VariantCard({ - data, - openOnClick = true, - buyMore = false -}) { - let product = data; - const router = useRouter(); - - const addItemToCart = () => { - toast.success('Berhasil menambahkan ke keranjang', { duration: 1500 }); - createOrUpdateItemCart(product.id, 1); - return; - }; - - const checkoutItem = () => { - router.push(`/shop/checkout?product_id=${product.id}&qty=${product.quantity}`); - } - - const Card = () => ( -
-
- {product.parent.name} -
-
-

- {product.parent.name} -

-

- {product.code || '-'} - {product.attributes.length > 0 ? ` ・ ${product.attributes.join(', ')}` : ''} -

-
- {product.price.discount_percentage > 0 && ( - <> -

{currencyFormat(product.price.price)}

- {product.price.discount_percentage}% - - )} -

{currencyFormat(product.price.price_discount)}

-
-

- {currencyFormat(product.price.price_discount)} × {product.quantity} Barang -

-

- {currencyFormat(product.quantity * product.price.price_discount)} -

-
-
- ); - - if (openOnClick) { - return ( - <> - - - - { buyMore && ( -
- - -
- ) } - - ); - } - - return ; -} \ No newline at end of file diff --git a/src2/components/variants/VariantGroupCard.js b/src2/components/variants/VariantGroupCard.js deleted file mode 100644 index 462c63cf..00000000 --- a/src2/components/variants/VariantGroupCard.js +++ /dev/null @@ -1,31 +0,0 @@ -import { useState } from "react" -import VariantCard from "./VariantCard" - -export default function VariantGroupCard({ - variants, - ...props -}) { - const [ showAll, setShowAll ] = useState(false) - const variantsToShow = showAll ? variants : variants.slice(0, 2) - - return ( - <> - { variantsToShow?.map((variant, index) => ( - - )) } - { variants.length > 2 && ( - - ) } - - ) -} \ No newline at end of file diff --git a/src2/core/utils/address.js b/src2/core/utils/address.js deleted file mode 100644 index c4a19af5..00000000 --- a/src2/core/utils/address.js +++ /dev/null @@ -1,27 +0,0 @@ -const getAddress = () => { - const address = localStorage.getItem('address'); - if (address) return JSON.parse(address); - return {}; -} - -const setAddress = (address) => { - localStorage.setItem('address', JSON.stringify(address)); - return true; -} - -const getItemAddress = (key) => { - let address = getAddress(); - return address[key]; -} - -const createOrUpdateItemAddress = (key, value) => { - let address = getAddress(); - address[key] = value; - setAddress(address); - return true; -} - -export { - getItemAddress, - createOrUpdateItemAddress -}; \ No newline at end of file diff --git a/src2/core/utils/apiOdoo.js b/src2/core/utils/apiOdoo.js deleted file mode 100644 index 4d0adae3..00000000 --- a/src2/core/utils/apiOdoo.js +++ /dev/null @@ -1,44 +0,0 @@ -import { getCookie, setCookie } from 'cookies-next'; -import axios from 'axios'; -import { getAuth } from './auth'; - -const renewToken = async () => { - let token = await axios.get(process.env.SELF_HOST + '/api/token'); - setCookie('token', token.data); - return token.data; -}; - -const getToken = async () => { - let token = getCookie('token'); - if (token == undefined) token = await renewToken(); - return token; -}; - -let connectionTry = 0; -const apiOdoo = async (method, url, data = {}, headers = {}) => { - try { - connectionTry++; - let token = await getToken(); - let axiosParameter = { - method, - url: process.env.ODOO_HOST + url, - headers: {'Authorization': token, ...headers} - } - const auth = getAuth(); - - if (auth) axiosParameter.headers['Token'] = auth.token; - if (method.toUpperCase() == 'POST') axiosParameter.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - if (Object.keys(data).length > 0) axiosParameter.data = new URLSearchParams(Object.entries(data)).toString(); - - let res = await axios(axiosParameter); - if (res.data.status.code == 401 && connectionTry < 15) { - await renewToken(); - return apiOdoo(method, url, data, headers); - } - return res.data.result || []; - } catch (error) { - console.log(error) - } -} - -export default apiOdoo; \ No newline at end of file diff --git a/src2/core/utils/auth.js b/src2/core/utils/auth.js deleted file mode 100644 index 62eba2c0..00000000 --- a/src2/core/utils/auth.js +++ /dev/null @@ -1,38 +0,0 @@ -import { deleteCookie, getCookie, setCookie } from 'cookies-next'; -import { useEffect, useState } from 'react'; - -const getAuth = () => { - let auth = getCookie('auth'); - if (auth) { - return JSON.parse(auth); - } - return false; -} - -const setAuth = (user) => { - setCookie('auth', JSON.stringify(user)); - return true; -} - -const deleteAuth = () => { - deleteCookie('auth'); - return true; -} - -const useAuth = () => { - const [auth, setAuth] = useState(null); - - useEffect(() => { - const handleIsAuthenticated = () => setAuth(getAuth()); - handleIsAuthenticated(); - }, []); - - return [auth, setAuth]; -} - -export { - getAuth, - setAuth, - deleteAuth, - useAuth -}; \ No newline at end of file diff --git a/src2/core/utils/cart.js b/src2/core/utils/cart.js deleted file mode 100644 index 66efcbf2..00000000 --- a/src2/core/utils/cart.js +++ /dev/null @@ -1,36 +0,0 @@ -const getCart = () => { - const cart = localStorage.getItem('cart'); - if (cart) return JSON.parse(cart); - return {}; -} - -const setCart = (cart) => { - localStorage.setItem('cart', JSON.stringify(cart)); - return true; -} - -const getItemCart = (product_id) => { - let cart = getCart(); - return cart[product_id]; -} - -const createOrUpdateItemCart = (product_id, quantity, selected = false) => { - let cart = getCart(); - cart[product_id] = { product_id, quantity, selected }; - setCart(cart); - return true; -} - -const deleteItemCart = (product_id) => { - let cart = getCart(); - delete cart[product_id]; - setCart(cart); - return true; -} - -export { - getCart, - getItemCart, - createOrUpdateItemCart, - deleteItemCart -} \ No newline at end of file diff --git a/src2/core/utils/convertToOption.js b/src2/core/utils/convertToOption.js deleted file mode 100644 index 08fec08f..00000000 --- a/src2/core/utils/convertToOption.js +++ /dev/null @@ -1,11 +0,0 @@ -const convertToOption = (data) => { - if (data) { - return { - value: data.id, - label: data.name, - } - } - return null; -}; - -export default convertToOption; \ No newline at end of file diff --git a/src2/core/utils/currencyFormat.js b/src2/core/utils/currencyFormat.js deleted file mode 100644 index dadeaec6..00000000 --- a/src2/core/utils/currencyFormat.js +++ /dev/null @@ -1,8 +0,0 @@ -export default function currencyFormat(value) { - const currency = new Intl.NumberFormat('id-ID', { - style: 'currency', - currency: 'IDR', - maximumFractionDigits: 0 - }); - return currency.format(value); -} \ No newline at end of file diff --git a/src2/core/utils/formValidation.js b/src2/core/utils/formValidation.js deleted file mode 100644 index 0e83f4cc..00000000 --- a/src2/core/utils/formValidation.js +++ /dev/null @@ -1,107 +0,0 @@ -import { useCallback, useEffect, useState } from "react"; - -const validateForm = (data, queries, hasChangedInputs = null) => { - let result = { valid: true, errors: {} }; - - for (const query in queries) { - if (!hasChangedInputs || (hasChangedInputs && hasChangedInputs[query])) { - const value = data[query]; - const rules = queries[query]; - let errors = []; - let label = null; - for (const rule of rules) { - let emailValidationRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - if (rule.startsWith('label:')) { - label = rule.replace('label:', ''); - } else if (rule === 'required' && !value) { - errors.push('tidak boleh kosong'); - } else if (rule === 'email' && !value.match(emailValidationRegex)) { - errors.push('harus format johndoe@example.com'); - } else if (rule.startsWith('maxLength:')) { - let maxLength = parseInt(rule.replace('maxLength:', '')); - if (value && value.length > maxLength) errors.push(`maksimal ${maxLength} karakter`); - } - } - if (errors.length > 0) { - result.errors[query] = (label || query) + ' ' + errors.join(', '); - } - } - } - - if (Object.keys(result.errors).length > 0) { - result.valid = false; - } - - return result; -} - -const useFormValidation = ({ initialFormValue = {}, validationScheme = {} }) => { - const [ formInputs, setFormInputs ] = useState(initialFormValue); - const [ formErrors, setFormErrors ] = useState({}); - const [ formValidation ] = useState(validationScheme); - const [ hasChangedInputs, setHasChangedInputs ] = useState({}); - - const handleFormSubmit = (event, func) => { - if (event) { - event.preventDefault(); - - // Make all input to be has changed mode to revalidate - const changedInputs = {}; - for (const key in formInputs) changedInputs[key] = true; - setHasChangedInputs(changedInputs); - - const { valid, errors } = validateForm(formInputs, formValidation, changedInputs); - setFormErrors(errors); - - if (valid) func(); - } - }; - - const setChangedInput = (name, value = true) => { - setHasChangedInputs((hasChangedInputs) => ({ - ...hasChangedInputs, - [name]: value - })); - }; - - const handleInputChange = (event) => { - setFormInputs((formInputs) => ({ - ...formInputs, - [event.target.name]: event.target.value - })); - setChangedInput(event.target.name); - }; - - const handleSelectChange = useCallback((name, value) => { - setFormInputs((formInputs) => ({ - ...formInputs, - [name]: value - })); - setChangedInput(name); - }, []); - - const handleFormReset = () => { - setFormInputs(initialFormValue); - setFormErrors({}); - setHasChangedInputs({}); - } - - useEffect(() => { - if (formInputs) { - const { errors } = validateForm(formInputs, formValidation, hasChangedInputs); - setFormErrors(errors); - } - }, [ formInputs, formValidation, hasChangedInputs ]) - - return { - handleFormReset, - handleFormSubmit, - handleInputChange, - handleSelectChange, - hasChangedInputs, - formInputs, - formErrors - }; - }; - -export default useFormValidation; \ No newline at end of file diff --git a/src2/core/utils/getFileBase64.js b/src2/core/utils/getFileBase64.js deleted file mode 100644 index 78013e43..00000000 --- a/src2/core/utils/getFileBase64.js +++ /dev/null @@ -1,11 +0,0 @@ -const getFileBase64 = file => new Promise((resolve, reject) => { - let reader = new FileReader(); - reader.readAsBinaryString(file); - reader.onload = () => { - let result = reader.result; - resolve(btoa(result)); - }; - reader.onerror = error => reject(error); -}); - -export default getFileBase64; \ No newline at end of file diff --git a/src2/core/utils/greeting.js b/src2/core/utils/greeting.js deleted file mode 100644 index 7dc19f8f..00000000 --- a/src2/core/utils/greeting.js +++ /dev/null @@ -1,9 +0,0 @@ -const greeting = () => { - let hours = new Date().getHours(); - if (hours < 11) return 'Selamat Pagi'; - if (hours < 15) return 'Selamat Siang'; - if (hours < 18) return 'Selamat Sore'; - return 'Selamat Malam'; -} - -export default greeting; \ No newline at end of file diff --git a/src2/core/utils/mailer.js b/src2/core/utils/mailer.js deleted file mode 100644 index 4e7ff7cc..00000000 --- a/src2/core/utils/mailer.js +++ /dev/null @@ -1,12 +0,0 @@ -const nodemailer = require('nodemailer'); -const mailer = nodemailer.createTransport({ - port: process.env.MAIL_PORT, - host: process.env.MAIL_HOST, - auth: { - user: process.env.MAIL_USER, - pass: process.env.MAIL_PASS - }, - secure: true -}); - -export default mailer; \ No newline at end of file diff --git a/src2/core/utils/slug.js b/src2/core/utils/slug.js deleted file mode 100644 index 0a7d30fc..00000000 --- a/src2/core/utils/slug.js +++ /dev/null @@ -1,25 +0,0 @@ -import toTitleCase from './toTitleCase'; - -const createSlug = (name, id) => { - let slug = name?.trim().replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-').toLowerCase() + '-' + id; - let splitSlug = slug.split('-'); - let filterSlugFromEmptyChar = splitSlug.filter(x => x != ''); - return filterSlugFromEmptyChar.join('-'); -} - -const getIdFromSlug = (slug) => { - let id = slug.split('-'); - return id[id.length-1]; -} - -const getNameFromSlug = (slug) => { - let name = slug.split('-'); - name.pop(); - return toTitleCase(name.join(' ')); -} - -export { - createSlug, - getIdFromSlug, - getNameFromSlug -}; \ No newline at end of file diff --git a/src2/core/utils/toTitleCase.js b/src2/core/utils/toTitleCase.js deleted file mode 100644 index 5cfd70d0..00000000 --- a/src2/core/utils/toTitleCase.js +++ /dev/null @@ -1,8 +0,0 @@ -export default function toTitleCase(str) { - return str.replace( - /\w\S*/g, - function(txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - } - ); -} \ No newline at end of file diff --git a/src2/icons/chevron-left.svg b/src2/icons/chevron-left.svg deleted file mode 100644 index a22ce386..00000000 --- a/src2/icons/chevron-left.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src2/icons/chevron-right.svg b/src2/icons/chevron-right.svg deleted file mode 100644 index eb58f2f2..00000000 --- a/src2/icons/chevron-right.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src2/icons/close.svg b/src2/icons/close.svg deleted file mode 100644 index 50e0589d..00000000 --- a/src2/icons/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src2/icons/filter.svg b/src2/icons/filter.svg deleted file mode 100644 index c15ce7b9..00000000 --- a/src2/icons/filter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src2/icons/image-placeholder.svg b/src2/icons/image-placeholder.svg deleted file mode 100644 index 935e1097..00000000 --- a/src2/icons/image-placeholder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src2/icons/instagram.svg b/src2/icons/instagram.svg deleted file mode 100644 index d90842c6..00000000 --- a/src2/icons/instagram.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src2/icons/linkedin.svg b/src2/icons/linkedin.svg deleted file mode 100644 index a68aec96..00000000 --- a/src2/icons/linkedin.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src2/icons/menu.svg b/src2/icons/menu.svg deleted file mode 100644 index 5d067e8e..00000000 --- a/src2/icons/menu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src2/icons/minus.svg b/src2/icons/minus.svg deleted file mode 100644 index 12a10199..00000000 --- a/src2/icons/minus.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src2/icons/plus.svg b/src2/icons/plus.svg deleted file mode 100644 index 2923c684..00000000 --- a/src2/icons/plus.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src2/icons/search.svg b/src2/icons/search.svg deleted file mode 100644 index 6de1cdfa..00000000 --- a/src2/icons/search.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src2/icons/shopping-cart.svg b/src2/icons/shopping-cart.svg deleted file mode 100644 index 09f14ca6..00000000 --- a/src2/icons/shopping-cart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src2/icons/trash.svg b/src2/icons/trash.svg deleted file mode 100644 index e23673ee..00000000 --- a/src2/icons/trash.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src2/images/logo.png b/src2/images/logo.png deleted file mode 100644 index 87c696aa..00000000 Binary files a/src2/images/logo.png and /dev/null differ diff --git a/src2/images/page-not-found.png b/src2/images/page-not-found.png deleted file mode 100644 index 296c0443..00000000 Binary files a/src2/images/page-not-found.png and /dev/null differ diff --git a/src2/lib/elements/hooks/useBottomPopup.js b/src2/lib/elements/hooks/useBottomPopup.js deleted file mode 100644 index 88b72316..00000000 --- a/src2/lib/elements/hooks/useBottomPopup.js +++ /dev/null @@ -1,40 +0,0 @@ -import { useState } from "react"; -import dynamic from "next/dynamic"; - -const DynamicBottomPopup = dynamic(() => import('@/components/elements/BottomPopup')); - -const useBottomPopup = ({ - title, - children -}) => { - const [ isOpen, setIsOpen ] = useState(false); - const [ dataPopup, setDataPopup ] = useState(null); - - const closePopup = () => { - setIsOpen(false); - setDataPopup(null); - }; - const openPopup = ( data = null ) => { - setIsOpen(true); - setDataPopup(data); - }; - - const BottomPopup = ( - - { children(dataPopup) } - - ); - - return { - dataPopup, - BottomPopup, - closePopup, - openPopup - } -} - -export default useBottomPopup; \ No newline at end of file diff --git a/src2/lib/elements/hooks/useConfirmAlert.js b/src2/lib/elements/hooks/useConfirmAlert.js deleted file mode 100644 index 4975c57d..00000000 --- a/src2/lib/elements/hooks/useConfirmAlert.js +++ /dev/null @@ -1,49 +0,0 @@ -import { useState } from "react"; -import dynamic from "next/dynamic"; - -const DynamicConfirmAlert = dynamic(() => import('@/components/elements/ConfirmAlert')); - -const useConfirmAlert = ({ - title, - caption, - closeText, - submitText, - onSubmit, -}) => { - const [ isOpen, setIsOpen ] = useState(false); - const [ data, setData ] = useState(null); - - const closeConfirmAlert = () => { - setIsOpen(false); - setData(null); - }; - const openConfirmAlert = ( data = null ) => { - setIsOpen(true); - setData(data); - }; - const handleSubmit = async () => { - await onSubmit(data); - closeConfirmAlert(); - }; - - const ConfirmAlert = ( - - ); - - return { - isOpen, - closeConfirmAlert, - openConfirmAlert, - ConfirmAlert - }; -} - -export default useConfirmAlert; \ No newline at end of file diff --git a/src2/pages/404.js b/src2/pages/404.js deleted file mode 100644 index 1e1850f2..00000000 --- a/src2/pages/404.js +++ /dev/null @@ -1,27 +0,0 @@ -import Image from "next/image"; -import Link from "@/components/elements/Link"; -import Header from "@/components/layouts/Header"; -import Layout from "@/components/layouts/Layout"; -import PageNotFoundImage from "../images/page-not-found.png"; - -export default function PageNotFound() { - return ( - <> -
- -
- Halaman Tidak Ditemukan - Indoteknik -

Halaman tidak ditemukan

-
- - Kembali ke beranda - - - Tanya admin - -
-
-
- - ); -} \ No newline at end of file diff --git a/src2/pages/_app.js b/src2/pages/_app.js deleted file mode 100644 index 6a40f4e6..00000000 --- a/src2/pages/_app.js +++ /dev/null @@ -1,31 +0,0 @@ -import '../styles/globals.css'; -import NextProgress from 'next-progress'; -import { useRouter } from 'next/router'; -import { AnimatePresence } from 'framer-motion'; -import { Toaster } from "react-hot-toast"; - -function MyApp({ Component, pageProps }) { - const router = useRouter(); - - return ( - <> - - - window.scrollTo(0, 0)} - > - - - - ) -} - -export default MyApp diff --git a/src2/pages/_error.js b/src2/pages/_error.js deleted file mode 100644 index 107ddf46..00000000 --- a/src2/pages/_error.js +++ /dev/null @@ -1,11 +0,0 @@ -import Header from "@/components/layouts/Header"; -import Layout from "@/components/layouts/Layout"; - -export default function Error() { - return ( - -
- - - ); -} \ No newline at end of file diff --git a/src2/pages/activate.js b/src2/pages/activate.js deleted file mode 100644 index d9b41bf4..00000000 --- a/src2/pages/activate.js +++ /dev/null @@ -1,111 +0,0 @@ -import axios from "axios"; -import Head from "next/head"; -import Image from "next/image"; -import Link from "@/components/elements/Link"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import Alert from "@/components/elements/Alert"; -import Layout from "@/components/layouts/Layout"; -import Spinner from "@/components/elements/Spinner"; -import { setAuth } from "@/core/utils/auth"; -import Logo from "@/images/logo.png"; - -export default function Activate() { - const [email, setEmail] = useState(''); - const [isInputFulfilled, setIsInputFulfilled] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [alert, setAlert] = useState(); - const router = useRouter(); - const { token } = router.query; - - useEffect(() => { - if (router.query.email) setEmail(router.query.email); - }, [router]) - - useEffect(() => { - const activateIfTokenExist = async () => { - if (token) { - let activation = await axios.post(`${process.env.SELF_HOST}/api/activation`, {token}); - if (activation.data.activation) { - setAuth(activation.data.user); - setAlert({ - component: <>Selamat, akun anda berhasil diaktifkan, kembali ke beranda., - type: 'success' - }); - } else { - setAlert({ - component: <>Mohon maaf token sudah tidak aktif, lakukan permintaan aktivasi akun kembali atau masuk jika sudah memiliki akun., - type: 'info' - }); - } - } - } - activateIfTokenExist(); - }, [token]); - - useEffect(() => { - setIsInputFulfilled(email != ''); - }, [email]); - - const activationRequest = async (e) => { - e.preventDefault(); - setIsLoading(true); - let activationRequest = await axios.post(`${process.env.SELF_HOST}/api/activation-request`, {email}); - if (activationRequest.data.activation_request) { - setAlert({ - component: <>Mohon cek email anda untuk aktivasi akun Indoteknik, - type: 'success' - }); - } else { - switch (activationRequest.data.reason) { - case 'NOT_FOUND': - setAlert({ - component: <>Email tersebut belum terdaftar, daftar sekarang., - type: 'info' - }); - break; - case 'ACTIVE': - setAlert({ - component: <>Email tersebut sudah terdaftar dan sudah aktif, masuk sekarang., - type: 'info' - }); - break; - } - } - setIsLoading(false); - } - return ( - <> - - Aktivasi Akun Indoteknik - - - - Logo Indoteknik - -

Aktivasi Akun Indoteknik Anda

-

Link aktivasi akan dikirimkan melalui email

- {alert ? ( - {alert.component} - ) : ''} -
- setEmail(e.target.value)} - autoFocus - /> - -
-
- - ) -} \ No newline at end of file diff --git a/src2/pages/api/activation-request.js b/src2/pages/api/activation-request.js deleted file mode 100644 index 3f33875c..00000000 --- a/src2/pages/api/activation-request.js +++ /dev/null @@ -1,31 +0,0 @@ -import apiOdoo from "@/core/utils/apiOdoo"; -import mailer from "@/core/utils/mailer"; - -export default async function handler(req, res) { - try { - const { email } = req.body; - let result = await apiOdoo( - 'POST', - '/api/v1/user/activation-request', - {email} - ); - if (result.activation_request) { - mailer.sendMail({ - from: 'sales@indoteknik.com', - to: result.user.email, - subject: 'Permintaan Aktivasi Akun Indoteknik', - html: ` -

Permintaan Aktivasi Akun Indoteknik

-
-

Aktivasi akun anda melalui link berikut: Aktivasi Akun

- ` - }); - } - delete result.user; - delete result.token; - res.status(200).json(result); - } catch (error) { - console.log(error); - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/activation.js b/src2/pages/api/activation.js deleted file mode 100644 index 8b22af8d..00000000 --- a/src2/pages/api/activation.js +++ /dev/null @@ -1,16 +0,0 @@ -import apiOdoo from "@/core/utils/apiOdoo"; - -export default async function handler(req, res) { - try { - const { token } = req.body; - let result = await apiOdoo( - 'POST', - '/api/v1/user/activation', - {token} - ); - res.status(200).json(result); - } catch (error) { - console.log(error); - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/login.js b/src2/pages/api/login.js deleted file mode 100644 index e02a73cb..00000000 --- a/src2/pages/api/login.js +++ /dev/null @@ -1,15 +0,0 @@ -import apiOdoo from "@/core/utils/apiOdoo"; - -export default async function handler(req, res) { - try { - const { email, password } = req.body; - let result = await apiOdoo( - 'POST', - '/api/v1/user/login', - {email, password} - ); - res.status(200).json(result); - } catch (error) { - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/register.js b/src2/pages/api/register.js deleted file mode 100644 index 7c8d8b39..00000000 --- a/src2/pages/api/register.js +++ /dev/null @@ -1,15 +0,0 @@ -import apiOdoo from "@/core/utils/apiOdoo"; - -export default async function handler(req, res) { - try { - const { email, name, password } = req.body; - let result = await apiOdoo( - 'POST', - '/api/v1/user/register', - {email, name, password} - ); - res.status(200).json(result); - } catch (error) { - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/shop/search.js b/src2/pages/api/shop/search.js deleted file mode 100644 index ad986c86..00000000 --- a/src2/pages/api/shop/search.js +++ /dev/null @@ -1,96 +0,0 @@ -import axios from "axios"; - -const productResponseMap = (products) => { - return products.map((product) => { - let productMapped = { - id: product.product_id ? product.product_id[0] : '', - image: product.image ? product.image[0] : '', - code: product.default_code ? product.default_code[0] : '', - name: product.product_name ? product.product_name[0] : '', - lowest_price: { - price: product.price ? product.price[0] : 0, - price_discount: product.price_discount ? product.price_discount[0] : 0, - discount_percentage: product.discount ? product.discount[0] : 0, - }, - variant_total: product.variant_total ? product.variant_total[0] : 0, - stock_total: product.stock_total ? product.stock_total[0] : 0, - weight: product.weight ? product.weight[0] : 0, - manufacture: {}, - categories: [], - }; - - if (product.manufacture_id && product.brand) { - productMapped.manufacture = { - id: product.manufacture_id ? product.manufacture_id[0] : '', - name: product.brand ? product.brand[0] : '', - }; - } - - productMapped.categories = [ - { - id: product.category_id ? product.category_id[0] : '', - name: product.category_name ? product.category_name[0] : '', - } - ]; - - return productMapped; - }); -} - -export default async function handler(req, res) { - const { - q, - page = 1, - brand = '', - category = '', - price_from = 0, - price_to = 0, - order_by = '' - } = req.query; - - let paramOrderBy = ''; - switch (order_by) { - case 'price-asc': - paramOrderBy = ', price_discount ASC'; - break; - case 'price-desc': - paramOrderBy = ', price_discount DESC'; - break; - case 'popular': - paramOrderBy = ', search_rank DESC'; - break; - case 'stock': - paramOrderBy = ', stock_total DESC'; - break; - } - - let limit = 30; - let offset = (page - 1) * limit; - let parameter = [ - `facet.query=${q}`, - 'facet=true', - 'indent=true', - 'q.op=AND', - `q=${q}`, - 'facet.field=brand_str', - 'facet.field=category_name_str', - `start=${offset}`, - `rows=${limit}`, - `sort=product_rating DESC ${paramOrderBy}`, - `fq=price_discount:[${price_from == '' ? '*' : price_from} TO ${price_to == '' ? '*' : price_to}]` - ]; - - if (brand) parameter.push(`fq=brand:${brand}`); - if (category) parameter.push(`fq=category_name:${category}`); - - let result = await axios(process.env.SOLR_HOST + '/solr/products/select?' + parameter.join('&')); - try { - result.data.response.products = productResponseMap(result.data.response.docs); - result.data.responseHeader.params.start = parseInt(result.data.responseHeader.params.start); - result.data.responseHeader.params.rows = parseInt(result.data.responseHeader.params.rows); - delete result.data.response.docs; - res.status(200).json(result.data); - } catch (error) { - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/shop/suggest.js b/src2/pages/api/shop/suggest.js deleted file mode 100644 index 6db1a851..00000000 --- a/src2/pages/api/shop/suggest.js +++ /dev/null @@ -1,12 +0,0 @@ -import axios from "axios"; - -export default async function handler(req, res) { - const { q } = req.query; - - let result = await axios(process.env.SOLR_HOST + `/solr/products/suggest?suggest=true&suggest.dictionary=mySuggester&suggest.q=${q}`); - try { - res.status(200).json(result.data); - } catch (error) { - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/api/token.js b/src2/pages/api/token.js deleted file mode 100644 index ec048158..00000000 --- a/src2/pages/api/token.js +++ /dev/null @@ -1,10 +0,0 @@ -import axios from "axios"; - -export default async function handler(req, res) { - try { - let result = await axios.get(process.env.ODOO_HOST + '/api/token'); - res.status(200).json(result.data.result); - } catch (error) { - res.status(400).json({ error: error.message }); - } -} \ No newline at end of file diff --git a/src2/pages/faqs.js b/src2/pages/faqs.js deleted file mode 100644 index cdb8ef52..00000000 --- a/src2/pages/faqs.js +++ /dev/null @@ -1,91 +0,0 @@ -import AppBar from "@/components/layouts/AppBar"; -import Layout from "@/components/layouts/Layout"; -import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline"; -import { useEffect, useState } from "react"; - -const dataFaqs = [ - { - id: 1, - name: 'Akun', - description: 'Bantuan tentang pengelolaan fitur dan akun' - }, - { - id: 2, - name: 'Pembelian', - description: 'Bantuan seputar status stock, layanan pengiriman & asuransi hingga seluruh indonesia' - }, - { - id: 3, - name: 'Metode Pembayaran', - description: 'Bantuan terkait layanan metode pembayaran' - }, - { - id: 4, - name: 'Quotation', - description: 'Bantuan fitur RFQ & quotation Express' - }, - { - id: 5, - name: 'Faktur Pajak & Invoice', - description: 'Bantuan seputar layanan terbit faktur pajak & invoice' - }, - { - id: 6, - name: 'Pengembalian & Garansi', - description: 'Bantuan cara pengembalian produk & garansi produk' - } -]; - -export default function Faqs() { - const [ faqs, setFaqs ] = useState([]); - - useEffect(() => { - if (faqs.length == 0) { - setFaqs(dataFaqs.map((dataFaq) => ({ - ...dataFaq, - isOpen: false - }))); - } - }, [ faqs ]); - - const toggleFaq = (id) => { - const faqsToUpdate = faqs.map(faq => { - if (faq.id == id) faq.isOpen = !faq.isOpen; - return faq; - }); - setFaqs(faqsToUpdate); - }; - - return ( - - - -
- { faqs.map((faq, index) => ( -
-
-
-

{ faq.name }

-

- { faq.description } -

-
- -
- { faq.isOpen && ( -

- { faq?.content || 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.' } -

- ) } -
- )) } -
-
- ) -} \ No newline at end of file diff --git a/src2/pages/index.js b/src2/pages/index.js deleted file mode 100644 index 65999ff6..00000000 --- a/src2/pages/index.js +++ /dev/null @@ -1,106 +0,0 @@ -import { useEffect, useState } from "react"; -import { Pagination, Autoplay } from "swiper"; -import axios from "axios"; -import { Swiper, SwiperSlide } from "swiper/react"; -import "swiper/css"; -import "swiper/css/pagination"; -import "swiper/css/autoplay"; - -// Helpers -import apiOdoo from "@/core/utils/apiOdoo"; - -// Components -import Header from "@/components/layouts/Header"; -import ProductSlider from "@/components/products/ProductSlider"; -import Layout from "@/components/layouts/Layout"; -import ManufactureCard from "@/components/manufactures/ManufactureCard"; -import Footer from "@/components/layouts/Footer"; -import Image from "@/components/elements/Image"; -import ProductCategories from "@/components/products/ProductCategories"; - -const swiperBanner = { - pagination: { dynamicBullets: true }, - autoplay: { - delay: 6000, - disableOnInteraction: false - }, - modules: [Pagination, Autoplay] -} - -export async function getServerSideProps() { - const heroBanners = await apiOdoo('GET', `/api/v1/banner?type=index-a-1`); - - return { props: { heroBanners } }; -} - -export default function Home({ heroBanners }) { - const [manufactures, setManufactures] = useState(null); - const [popularProducts, setPopularProducts] = useState(null); - - useEffect(() => { - const getManufactures = async () => { - const dataManufactures = await apiOdoo('GET', `/api/v1/manufacture?level=prioritas`); - setManufactures(dataManufactures); - } - getManufactures(); - - const getPopularProducts = async () => { - const dataPopularProducts = await axios(`${process.env.SELF_HOST}/api/shop/search?q=*&page=1&order_by=popular`); - setPopularProducts(dataPopularProducts.data.response); - } - getPopularProducts(); - }, []); - - return ( - <> -
- - - { - heroBanners?.map((banner, index) => ( - - {banner.name} - - )) - } - -
-

Brand Pilihan

- - { - manufactures?.manufactures?.map((manufacture, index) => ( - - - - )) - } - -
-
-

Produk Populer

- -
- - - -
-
Platform Belanja B2B Alat Teknik & Industri di Indonesia
-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est -

-
- -