From f99e0aba70efad0deb907d8e27f09fc9f527c8a4 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 17 Feb 2023 17:07:50 +0700 Subject: Refactor --- src/core/components/elements/Appbar/Appbar.jsx | 33 ++++++++ src/core/components/elements/Badge/Badge.jsx | 33 ++++++++ src/core/components/elements/Divider/Divider.jsx | 11 +++ src/core/components/elements/Image/Image.jsx | 15 ++++ src/core/components/elements/Link/Link.jsx | 17 +++++ src/core/components/elements/NavBar/NavBar.jsx | 31 ++++++++ src/core/components/elements/NavBar/Search.jsx | 89 ++++++++++++++++++++++ .../components/elements/Pagination/Pagination.js | 64 ++++++++++++++++ src/core/components/elements/Popup/BottomPopup.jsx | 21 +++++ .../components/elements/Skeleton/BrandSkeleton.jsx | 8 ++ .../components/elements/Skeleton/ImageSkeleton.jsx | 10 +++ .../elements/Skeleton/ProductCardSkeleton.jsx | 15 ++++ 12 files changed, 347 insertions(+) create mode 100644 src/core/components/elements/Appbar/Appbar.jsx create mode 100644 src/core/components/elements/Badge/Badge.jsx create mode 100644 src/core/components/elements/Divider/Divider.jsx create mode 100644 src/core/components/elements/Image/Image.jsx create mode 100644 src/core/components/elements/Link/Link.jsx create mode 100644 src/core/components/elements/NavBar/NavBar.jsx create mode 100644 src/core/components/elements/NavBar/Search.jsx create mode 100644 src/core/components/elements/Pagination/Pagination.js create mode 100644 src/core/components/elements/Popup/BottomPopup.jsx create mode 100644 src/core/components/elements/Skeleton/BrandSkeleton.jsx create mode 100644 src/core/components/elements/Skeleton/ImageSkeleton.jsx create mode 100644 src/core/components/elements/Skeleton/ProductCardSkeleton.jsx (limited to 'src/core/components/elements') diff --git a/src/core/components/elements/Appbar/Appbar.jsx b/src/core/components/elements/Appbar/Appbar.jsx new file mode 100644 index 00000000..0fe087d3 --- /dev/null +++ b/src/core/components/elements/Appbar/Appbar.jsx @@ -0,0 +1,33 @@ +import { useRouter } from "next/router" +import Link from "../Link/Link" +import { HomeIcon, Bars3Icon, ShoppingCartIcon, ChevronLeftIcon } from "@heroicons/react/24/outline" + +const AppBar = ({ title }) => { + const router = useRouter() + + return ( + + ) +} + +export default AppBar \ No newline at end of file diff --git a/src/core/components/elements/Badge/Badge.jsx b/src/core/components/elements/Badge/Badge.jsx new file mode 100644 index 00000000..5d8ebd1c --- /dev/null +++ b/src/core/components/elements/Badge/Badge.jsx @@ -0,0 +1,33 @@ +const Badge = ({ + children, + type, + ...props +}) => { + return ( +
+ { children } +
+ ) +} + +Badge.defaultProps = { + className: '' +} + +const badgeStyle = (type) => { + let className = ['rounded px-1 text-[11px]'] + switch (type) { + case 'solid-red': + className.push('bg-red_r-11 text-white') + break + case 'light': + className.push('bg-gray_r-4 text-gray_r-11') + break + } + return className.join(' ') +} + +export default Badge \ No newline at end of file diff --git a/src/core/components/elements/Divider/Divider.jsx b/src/core/components/elements/Divider/Divider.jsx new file mode 100644 index 00000000..355cd509 --- /dev/null +++ b/src/core/components/elements/Divider/Divider.jsx @@ -0,0 +1,11 @@ +const Divider = (props) => { + return ( +
+ ) +} + +Divider.defaultProps = { + className: '' +} + +export default Divider \ No newline at end of file diff --git a/src/core/components/elements/Image/Image.jsx b/src/core/components/elements/Image/Image.jsx new file mode 100644 index 00000000..be2866e7 --- /dev/null +++ b/src/core/components/elements/Image/Image.jsx @@ -0,0 +1,15 @@ +import { LazyLoadImage } from "react-lazy-load-image-component" +import "react-lazy-load-image-component/src/effects/opacity.css" + +const Image = ({ ...props }) => ( + +) + +Image.defaultProps = LazyLoadImage.defaultProps + +export default Image \ No newline at end of file diff --git a/src/core/components/elements/Link/Link.jsx b/src/core/components/elements/Link/Link.jsx new file mode 100644 index 00000000..a619164d --- /dev/null +++ b/src/core/components/elements/Link/Link.jsx @@ -0,0 +1,17 @@ +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/src/core/components/elements/NavBar/NavBar.jsx b/src/core/components/elements/NavBar/NavBar.jsx new file mode 100644 index 00000000..212fd341 --- /dev/null +++ b/src/core/components/elements/NavBar/NavBar.jsx @@ -0,0 +1,31 @@ +import Image from "next/image" +import IndoteknikLogo from "@/images/logo.png" +import { Bars3Icon, HeartIcon, ShoppingCartIcon } from "@heroicons/react/24/outline" +import Link from "../Link/Link" +import Search from "./Search" + +const NavBar = () => { + return ( + + ) +} + +export default NavBar \ No newline at end of file diff --git a/src/core/components/elements/NavBar/Search.jsx b/src/core/components/elements/NavBar/Search.jsx new file mode 100644 index 00000000..cca1a97c --- /dev/null +++ b/src/core/components/elements/NavBar/Search.jsx @@ -0,0 +1,89 @@ +import searchSuggestApi from "@/core/api/searchSuggestApi" +import { MagnifyingGlassIcon } from "@heroicons/react/24/outline" +import { useCallback, useEffect, useRef, useState } from "react" +import Link from "../Link/Link" +import { useRouter } from "next/router" + +const Search = () => { + const router = useRouter() + const queryRef = useRef() + const [ query, setQuery ] = useState('') + const [ suggestions, setSuggestions ] = useState([]) + + useEffect(() => { + setQuery(router.query.q) + }, [router.query]) + + const loadSuggestion = useCallback(() => { + if (query && document.activeElement == queryRef.current) { + (async () => { + const dataSuggestion = await searchSuggestApi({ query }) + setSuggestions(dataSuggestion.data.suggestions) + })() + return + } else { + setSuggestions([]) + } + }, [ query ]) + + useEffect(() => { + if (query && document.activeElement == queryRef.current) { + loadSuggestion() + } else { + setSuggestions([]) + } + }, [ loadSuggestion, query ]) + + const handleSubmit = (e) => { + e.preventDefault() + if (query) { + router.push(`/shop/search?q=${query}`) + } else { + queryRef.current.focus() + } + } + + const onInputBlur = () => { + setTimeout(() => { + setSuggestions([]) + }, 100) + } + + return ( +
+ setQuery(e.target.value)} + onBlur={onInputBlur} + onFocus={loadSuggestion} + /> + + + { suggestions.length > 1 && ( + <> +
+ {suggestions.map((suggestion, index) => ( + + {suggestion.term} + + ))} +
+ + ) } +
+ ) +} + +export default Search \ No newline at end of file diff --git a/src/core/components/elements/Pagination/Pagination.js b/src/core/components/elements/Pagination/Pagination.js new file mode 100644 index 00000000..485295fe --- /dev/null +++ b/src/core/components/elements/Pagination/Pagination.js @@ -0,0 +1,64 @@ +import Link from "../Link/Link" + +const Pagination = ({ pageCount, currentPage, url, className }) => { + 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 + } + }) } +
+ ) +} + +Pagination.defaultProps = { + className: '' +} + +export default Pagination \ No newline at end of file diff --git a/src/core/components/elements/Popup/BottomPopup.jsx b/src/core/components/elements/Popup/BottomPopup.jsx new file mode 100644 index 00000000..e687cf20 --- /dev/null +++ b/src/core/components/elements/Popup/BottomPopup.jsx @@ -0,0 +1,21 @@ +import { XMarkIcon } from "@heroicons/react/24/outline" + +const BottomPopup = ({ children, active, title, close }) => ( + <> +
+
+
+
{ title }
+ +
+ { children } +
+ +) + +export default BottomPopup \ No newline at end of file diff --git a/src/core/components/elements/Skeleton/BrandSkeleton.jsx b/src/core/components/elements/Skeleton/BrandSkeleton.jsx new file mode 100644 index 00000000..ce5a994d --- /dev/null +++ b/src/core/components/elements/Skeleton/BrandSkeleton.jsx @@ -0,0 +1,8 @@ +const BrandSkeleton = () => ( +
+
+ Loading... +
+) + +export default BrandSkeleton \ No newline at end of file diff --git a/src/core/components/elements/Skeleton/ImageSkeleton.jsx b/src/core/components/elements/Skeleton/ImageSkeleton.jsx new file mode 100644 index 00000000..2cda9536 --- /dev/null +++ b/src/core/components/elements/Skeleton/ImageSkeleton.jsx @@ -0,0 +1,10 @@ +const ImageSkeleton = () => ( +
+
+ +
+ Loading... +
+) + +export default ImageSkeleton \ No newline at end of file diff --git a/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx b/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx new file mode 100644 index 00000000..66b48f79 --- /dev/null +++ b/src/core/components/elements/Skeleton/ProductCardSkeleton.jsx @@ -0,0 +1,15 @@ +const ProductCardSkeleton = () => ( +
+
+ +
+
+
+
+
+
+ Loading... +
+) + +export default ProductCardSkeleton \ No newline at end of file -- cgit v1.2.3