summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/components/layouts/AppLayout.jsx18
-rw-r--r--src/core/components/layouts/BasicLayout.jsx82
-rw-r--r--src/pages/_app.jsx99
-rw-r--r--src/pages/shop/product/[slug].jsx118
4 files changed, 118 insertions, 199 deletions
diff --git a/src/core/components/layouts/AppLayout.jsx b/src/core/components/layouts/AppLayout.jsx
index d74d61e3..ebbc1ad5 100644
--- a/src/core/components/layouts/AppLayout.jsx
+++ b/src/core/components/layouts/AppLayout.jsx
@@ -1,6 +1,12 @@
-import AppBar from '../elements/Appbar/Appbar'
-import BasicFooter from '../elements/Footer/BasicFooter'
-import AnimationLayout from './AnimationLayout'
+import dynamic from 'next/dynamic';
+import AnimationLayout from './AnimationLayout';
+
+const AppBar = dynamic(() => import('../elements/Appbar/Appbar'), {
+ ssr: false,
+});
+const BasicFooter = dynamic(() => import('../elements/Footer/BasicFooter'), {
+ ssr: false,
+});
const AppLayout = ({ children, title, withFooter = true }) => {
return (
@@ -11,7 +17,7 @@ const AppLayout = ({ children, title, withFooter = true }) => {
</AnimationLayout>
{withFooter && <BasicFooter />}
</>
- )
-}
+ );
+};
-export default AppLayout
+export default AppLayout;
diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx
index 9441dbd7..2962a08b 100644
--- a/src/core/components/layouts/BasicLayout.jsx
+++ b/src/core/components/layouts/BasicLayout.jsx
@@ -1,55 +1,61 @@
-import dynamic from 'next/dynamic'
-import BasicFooter from '../elements/Footer/BasicFooter'
-import Image from 'next/image'
-import whatsappUrl from '@/core/utils/whatsappUrl'
-import { useEffect, useState } from 'react'
-import axios from 'axios'
-import odooApi from '@/core/api/odooApi'
-import { useRouter } from 'next/router'
-import productApi from '@/lib/product/api/productApi'
-import { getAuth, setAuth } from '@/core/utils/auth'
-import { createSlug, getIdFromSlug } from '@/core/utils/slug'
-import { useSession } from 'next-auth/react'
-import { setCookie } from 'cookies-next'
-import { useProductContext } from '@/contexts/ProductContext'
+import dynamic from 'next/dynamic';
+import Image from 'next/image';
+import { useEffect, useState } from 'react';
+import axios from 'axios';
-const Navbar = dynamic(() => import('../elements/Navbar/Navbar'))
-const AnimationLayout = dynamic(() => import('./AnimationLayout'))
+import whatsappUrl from '@/core/utils/whatsappUrl';
+import odooApi from '@/core/api/odooApi';
+import { useRouter } from 'next/router';
+import { useProductContext } from '@/contexts/ProductContext';
+
+const Navbar = dynamic(() => import('../elements/Navbar/Navbar'), {
+ ssr: false,
+});
+const AnimationLayout = dynamic(() => import('./AnimationLayout'), {
+ ssr: false,
+});
+const BasicFooter = dynamic(() => import('../elements/Footer/BasicFooter'), {
+ ssr: false,
+});
const BasicLayout = ({ children }) => {
- const [templateWA, setTemplateWA] = useState(null)
- const [payloadWA, setPayloadWa] = useState(null)
- const [urlPath, setUrlPath] = useState(null)
+ const [templateWA, setTemplateWA] = useState(null);
+ const [payloadWA, setPayloadWa] = useState(null);
+ const [urlPath, setUrlPath] = useState(null);
- const router = useRouter()
+ const router = useRouter();
- const { product } = useProductContext()
+ const { product } = useProductContext();
useEffect(() => {
- if (router.pathname === '/shop/product/[slug]' || router.pathname === '/shop/product/variant/[slug]') {
+ if (
+ router.pathname === '/shop/product/[slug]' ||
+ router.pathname === '/shop/product/variant/[slug]'
+ ) {
setPayloadWa({
name: product?.name,
manufacture: product?.manufacture.name,
- url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath
- })
- setTemplateWA('product')
+ url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath,
+ });
+ setTemplateWA('product');
- setUrlPath(router.asPath)
+ setUrlPath(router.asPath);
}
- }, [product, router])
-
+ }, [product, router]);
useEffect(() => {
const getIP = async () => {
- const ip = await odooApi('GET', '/api/ip-address')
+ 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()
- }, [])
+ ip: ip,
+ };
+ axios.get(
+ `/api/user-activity?page_title=${data.page_title}&url=${data.url}&ip=${data.ip}`
+ );
+ };
+ getIP();
+ }, []);
return (
<>
<Navbar />
@@ -82,7 +88,7 @@ const BasicLayout = ({ children }) => {
</AnimationLayout>
<BasicFooter />
</>
- )
-}
+ );
+};
-export default BasicLayout
+export default BasicLayout;
diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx
index 3fe1d3cf..aa545863 100644
--- a/src/pages/_app.jsx
+++ b/src/pages/_app.jsx
@@ -1,58 +1,73 @@
-import '@/fonts/Inter/inter.css'
-import '@/styles/globals.css'
-import 'react-loading-skeleton/dist/skeleton.css'
+import '@/fonts/Inter/inter.css';
+import '@/styles/globals.css';
+import 'react-loading-skeleton/dist/skeleton.css';
-import NextProgress from 'next-progress'
-import { useRouter, Router } from 'next/router'
-import { AnimatePresence, motion } from 'framer-motion'
-import { Toaster } from 'react-hot-toast'
-import { QueryClient, QueryClientProvider } from 'react-query'
-import useDevice from '@/core/hooks/useDevice'
-import { useEffect, useState } from 'react'
-import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
-import { SessionProvider } from 'next-auth/react'
-import { ProductProvider } from '@/contexts/ProductContext'
-import { ProductCartProvider } from '@/contexts/ProductCartContext'
-import { ChakraProvider } from '@chakra-ui/react'
-import theme from '../../chakra.theme'
+import { useEffect, useState } from 'react';
+import dynamic from 'next/dynamic';
+import { useRouter, Router } from 'next/router';
+import { AnimatePresence, motion } from 'framer-motion';
+import { QueryClient, QueryClientProvider } from 'react-query';
-const queryClient = new QueryClient()
+import useDevice from '@/core/hooks/useDevice';
+import { ProductProvider } from '@/contexts/ProductContext';
+import { ProductCartProvider } from '@/contexts/ProductCartContext';
+import theme from '../../chakra.theme';
+
+const NextProgress = dynamic(() => import('next-progress'), { ssr: false });
+const ChakraProvider = dynamic(
+ () => import('@chakra-ui/react').then((mod) => mod.ChakraProvider),
+ { ssr: false }
+);
+const SessionProvider = dynamic(
+ () => import('next-auth/react').then((mod) => mod.SessionProvider),
+ { ssr: false }
+);
+const LogoSpinner = dynamic(
+ () => import('@/core/components/elements/Spinner/LogoSpinner'),
+ { ssr: false }
+);
+const Toaster = dynamic(
+ () => import('react-hot-toast').then((mod) => mod.Toaster),
+ { ssr: false }
+);
+
+const queryClient = new QueryClient();
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
- const router = useRouter()
- const { isMobile } = useDevice()
+ const router = useRouter();
+ const { isMobile } = useDevice();
- const [animateLoader, setAnimateLoader] = useState(false)
+ const [animateLoader, setAnimateLoader] = useState(false);
useEffect(() => {
- const handleRouteChangeStart = () => setAnimateLoader(true)
- const handleRouteChangeComplete = () => setAnimateLoader(false)
+ const handleRouteChangeStart = () => setAnimateLoader(true);
+ const handleRouteChangeComplete = () => setAnimateLoader(false);
- Router.events.on('routeChangeStart', handleRouteChangeStart)
- Router.events.on('routeChangeComplete', handleRouteChangeComplete)
- Router.events.on('routeChangeError', handleRouteChangeComplete)
+ Router.events.on('routeChangeStart', handleRouteChangeStart);
+ Router.events.on('routeChangeComplete', handleRouteChangeComplete);
+ Router.events.on('routeChangeError', handleRouteChangeComplete);
return () => {
- Router.events.off('routeChangeStart', handleRouteChangeStart)
- Router.events.off('routeChangeComplete', handleRouteChangeComplete)
- Router.events.off('routeChangeError', handleRouteChangeComplete)
- }
- }, [])
+ Router.events.off('routeChangeStart', handleRouteChangeStart);
+ Router.events.off('routeChangeComplete', handleRouteChangeComplete);
+ Router.events.off('routeChangeError', handleRouteChangeComplete);
+ };
+ }, []);
- const [toasterStyle, setToasterStyle] = useState({})
+ const [toasterStyle, setToasterStyle] = useState({});
useEffect(() => {
- let elems = document.querySelectorAll('nav')
- let totalNavHeight = 0
+ let elems = document.querySelectorAll('nav');
+ let totalNavHeight = 0;
elems.forEach(function (elem) {
- totalNavHeight += elem.offsetHeight
- })
+ totalNavHeight += elem.offsetHeight;
+ });
setToasterStyle({
- marginTop: isMobile ? totalNavHeight - 8 : totalNavHeight
- })
- }, [isMobile])
+ marginTop: isMobile ? totalNavHeight - 8 : totalNavHeight,
+ });
+ }, [isMobile]);
return (
<SessionProvider session={session}>
@@ -63,7 +78,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) {
animate={{ opacity: 1 }}
exit={{ opacity: 0.4 }}
transition={{
- duration: 0.1
+ duration: 0.1,
}}
className='fixed w-screen h-screen z-[500] bg-white flex justify-center items-center'
>
@@ -76,7 +91,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) {
containerStyle={toasterStyle}
toastOptions={{
duration: 3000,
- className: 'border border-gray_r-8'
+ className: 'border border-gray_r-8',
}}
/>
<NextProgress color='#F01C21' options={{ showSpinner: false }} />
@@ -90,7 +105,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }) {
</ProductProvider>
</QueryClientProvider>
</SessionProvider>
- )
+ );
}
-export default MyApp
+export default MyApp;
diff --git a/src/pages/shop/product/[slug].jsx b/src/pages/shop/product/[slug].jsx
index 667373b4..73e8987c 100644
--- a/src/pages/shop/product/[slug].jsx
+++ b/src/pages/shop/product/[slug].jsx
@@ -1,114 +1,6 @@
-import Seo from '@/core/components/Seo';
-import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner';
-import { getIdFromSlug } from '@/core/utils/slug';
-import productApi from '@/lib/product/api/productApi';
-import PageNotFound from '@/pages/404';
-import dynamic from 'next/dynamic';
-import { useRouter } from 'next/router';
-import cookie from 'cookie';
-import axios from 'axios';
-import { useProductContext } from '@/contexts/ProductContext';
-import { useEffect } from 'react';
-import { updateItemCart } from '@/core/utils/cart';
+import ProductDetailPage, {
+ getServerSideProps,
+} from '~/pages/shop/product/[slug]';
-const BasicLayout = dynamic(() =>
- import('@/core/components/layouts/BasicLayout')
-);
-const Product = dynamic(() =>
- import('@/lib/product/components/Product/Product')
-);
-
-export async function getServerSideProps(context) {
- const { slug } = context.query;
- const cookies = context.req.headers.cookie;
- const cookieObj = cookies ? cookie.parse(cookies) : {};
- const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {};
- const tier = auth.pricelist ? auth.pricelist : false;
-
- let response = await axios(
- `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=` +
- getIdFromSlug(slug) +
- '&auth=' +
- tier
- );
- let product = response.data;
- // let productSolr = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } })
- // let productSolr = null
- if (product?.length == 1) {
- product = product[0];
- } else {
- product = null;
- }
-
- return {
- props: { product },
- };
-}
-
-export default function ProductDetail({ product }) {
- const router = useRouter();
- const { setProduct } = useProductContext();
-
- useEffect(() => {
- if (product) {
- setProduct(product);
- }
- }, [product, setProduct]);
-
- useEffect(() => {
- const { action, variantId, qty } = router.query;
- const addToCart = async () => {
- const data = {
- productId: variantId,
- quantity: qty,
- selected: true,
- programLineId: null,
- source: action,
- };
-
- await updateItemCart(data);
- const redirectURL =
- action === 'buy' ? '/shop/checkout?source=buy' : '/shop/cart';
- router.push(redirectURL);
- };
-
- if (action && variantId && qty) {
- addToCart();
- }
- }, [router]);
-
- if (!product) return <PageNotFound />;
-
- return (
- <BasicLayout>
- <Seo
- title={product?.name || '' + ' - Indoteknik.com' || ''}
- description='Temukan pilihan produk B2B Industri &amp; Alat Teknik untuk Perusahaan, UMKM &amp; Pemerintah dengan lengkap, mudah dan transparan.'
- openGraph={{
- url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath,
- images: [
- {
- url: product?.image,
- width: 800,
- height: 800,
- alt: product?.name,
- },
- ],
- type: 'product',
- }}
- additionalMetaTags={[
- {
- name: 'keywords',
- content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}`,
- },
- ]}
- />
- {!product && (
- <div className='container mx-auto flex justify-center pt-10'>
- <LogoSpinner width={36} height={36} />
- </div>
- )}
- {product && <Product product={product} />}
- </BasicLayout>
- );
-}
+export { getServerSideProps };
+export default ProductDetailPage;