diff options
| author | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2023-05-08 16:44:09 +0700 |
|---|---|---|
| committer | HATEC\SPVDEV001 <tri.susilo@altama.co.id> | 2023-05-08 16:44:09 +0700 |
| commit | 486f85a45fc7e0669576f59824a31be472ed25bb (patch) | |
| tree | 0268afa8efe48746e040611ba41ad2cafda7ad08 /src/pages | |
| parent | cff198277e14450f8d20d9e18548325e6f277682 (diff) | |
| parent | 30fc50600009ca54f085d594d838803c107e87f2 (diff) | |
Merge branch 'master' into development_tri/implementasi_raja_ongkir
# Conflicts:
# src/lib/checkout/components/Checkout.jsx
Diffstat (limited to 'src/pages')
48 files changed, 681 insertions, 135 deletions
diff --git a/src/pages/404.jsx b/src/pages/404.jsx new file mode 100644 index 00000000..f73e6383 --- /dev/null +++ b/src/pages/404.jsx @@ -0,0 +1,22 @@ +import Seo from '@/core/components/Seo' +import Link from '@/core/components/elements/Link/Link' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import Image from 'next/image' + +export default function PageNotFound() { + return ( + <BasicLayout> + <Seo title='Halaman tidak ditemukan - Indoteknik.com' /> + <div className='container mx-auto'> + <Image + src='/images/page-not-found.svg' + alt='Page not found - Indoteknik' + className='w-full' + width={1024} + height={512} + /> + <Link href='/' className='btn-yellow text-black mx-auto mt-4'>Kembali ke halaman utama</Link> + </div> + </BasicLayout> + ) +} diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index 3c93d27f..2d74d8b7 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,7 +1,7 @@ import '../styles/globals.css' import NextProgress from 'next-progress' import { useRouter, Router } from 'next/router' -import { AnimatePresence } from 'framer-motion' +import { AnimatePresence, motion } from 'framer-motion' import { Toaster } from 'react-hot-toast' import { QueryClient, QueryClientProvider } from 'react-query' import useDevice from '@/core/hooks/useDevice' @@ -17,12 +17,17 @@ function MyApp({ Component, pageProps }) { const [animateLoader, setAnimateLoader] = useState(false) useEffect(() => { - Router.events.on('routeChangeStart', () => setAnimateLoader(true)) - Router.events.on('routeChangeComplete', () => 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) return () => { - Router.events.off('routeChangeStart', () => setAnimateLoader(true)) - Router.events.off('routeChangeComplete', () => setAnimateLoader(false)) + Router.events.off('routeChangeStart', handleRouteChangeStart) + Router.events.off('routeChangeComplete', handleRouteChangeComplete) + Router.events.off('routeChangeError', handleRouteChangeComplete) } }, []) @@ -43,11 +48,21 @@ function MyApp({ Component, pageProps }) { return ( <> - {animateLoader && ( - <div className='w-screen h-screen z-[500] flex justify-center items-center backdrop-blur'> - <LogoSpinner /> - </div> - )} + <AnimatePresence> + {animateLoader && ( + <motion.div + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + exit={{ opacity: 0 }} + transition={{ + duration: 0.1 + }} + className='fixed w-screen h-screen z-[500] bg-white flex justify-center items-center' + > + <LogoSpinner /> + </motion.div> + )} + </AnimatePresence> <Toaster position='top-center' containerStyle={toasterStyle} diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index ff205a38..dbe210aa 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -2,9 +2,13 @@ import { Html, Head, Main, NextScript } from 'next/document' import Script from 'next/script' export default function MyDocument() { + const env = process.env.NODE_ENV + return ( <Html> <Head> + <link rel='icon' href='/favicon.ico' /> + <meta name='facebook-domain-verification' content='328wmjs7hcnz74rwsqzxvq50rmbtm2' /> <Script async @@ -57,6 +61,24 @@ export default function MyDocument() { }} /> + {/* <Script + id='tawk-script-tag' + strategy='afterInteractive' + dangerouslySetInnerHTML={{ + __html: ` + var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date(); + (function(){ + var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0]; + s1.async=true; + s1.src='https://embed.tawk.to/643e00614247f20fefec36c5/1gu932vhh'; + s1.charset='UTF-8'; + s1.setAttribute('crossorigin','*'); + s0.parentNode.insertBefore(s1,s0); + })(); + ` + }} + /> */} + <meta name='google-site-verification' content='uHuW_mZhjv_fUg3do-lV8Mo7R2vVjF4MPQhTXFP3jH4' diff --git a/src/pages/activate.jsx b/src/pages/activate.jsx index 48d9c4d3..8e9d8fbb 100644 --- a/src/pages/activate.jsx +++ b/src/pages/activate.jsx @@ -1,9 +1,11 @@ import Seo from '@/core/components/Seo' -import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter' -import BasicLayout from '@/core/components/layouts/BasicLayout' import DesktopView from '@/core/components/views/DesktopView' import MobileView from '@/core/components/views/MobileView' -import ActivateComponent from '@/lib/auth/components/Activate' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const ActivateComponent = dynamic(() => import('@/lib/auth/components/Activate')) +const SimpleFooter = dynamic(() => import('@/core/components/elements/Footer/SimpleFooter')) export default function Activate() { return ( diff --git a/src/pages/api/shop/finish-checkout.js b/src/pages/api/shop/finish-checkout.js index 04e82118..9eaa36db 100644 --- a/src/pages/api/shop/finish-checkout.js +++ b/src/pages/api/shop/finish-checkout.js @@ -46,7 +46,7 @@ export default async function handler(req, res) { } } - const query = `name=${orderName.replaceAll('-', '/')}&limit=1` + const query = `name=${orderName.replaceAll('-', '/')}&limit=1&context=quotation` const searchTransaction = await odooApi( 'GET', `/api/v1/partner/${auth.partnerId}/sale_order?${query}`, diff --git a/src/pages/api/shop/midtrans-payment.js b/src/pages/api/shop/midtrans-payment.js index 1772e9e0..12aaa51f 100644 --- a/src/pages/api/shop/midtrans-payment.js +++ b/src/pages/api/shop/midtrans-payment.js @@ -22,6 +22,7 @@ export default async function handler(req, res) { {}, { Token: auth.token } ) + if (!transaction?.id) { return res.status(400).json({ error: 'No Data' }) } @@ -48,7 +49,7 @@ export default async function handler(req, res) { const parameter = { transaction_details: { order_id: transaction.name?.replaceAll('/', '-'), - gross_amount: transaction.amountTotal + gross_amount: Math.floor(transaction.amountTotal) }, credit_card: { secure: true @@ -56,17 +57,7 @@ export default async function handler(req, res) { customer_details: { first_name: transaction.address.customer.name, email: transaction.address.customer.email || '', - phone: transaction.address.customer.phone || '', - billing_address: { - first_name: transaction.address.invoice.name, - email: transaction.address.invoice.email || '', - phone: transaction.address.invoice.phone || '' - }, - shipping_address: { - first_name: transaction.address.shipping.name, - email: transaction.address.shipping.email || '', - phone: transaction.address.shipping.phone || '' - } + phone: transaction.address.customer.phone || '' } } diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 19b9655a..2e6764fd 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -29,6 +29,9 @@ export default async function handler(req, res) { case 'stock': paramOrderBy += 'stock_total_f DESC' break + default: + paramOrderBy += 'product_rating_f DESC, price_discount_f DESC' + break } let offset = (page - 1) * limit @@ -43,10 +46,17 @@ export default async function handler(req, res) { 'qf=name_s', `start=${offset}`, `rows=${limit}`, - `sort=${paramOrderBy}`, - `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${priceTo == '' ? '*' : priceTo}]` + `sort=${paramOrderBy}` ] + if (priceFrom > 0 || priceTo > 0) { + parameter.push( + `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ + priceTo == '' ? '*' : priceTo + }]` + ) + } + if (brand) parameter.push(`fq=manufacture_name:${brand}`) if (category) parameter.push(`fq=category_name:${category}`) @@ -57,7 +67,12 @@ export default async function handler(req, res) { let result = await axios(process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&')) try { - result.data.response.products = productResponseMap(result.data.response.docs) + let { auth } = req.cookies + if (auth) auth = JSON.parse(auth) + result.data.response.products = productResponseMap( + result.data.response.docs, + auth?.pricelist || false + ) 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 @@ -83,23 +98,42 @@ const escapeSolrQuery = (query) => { return escapedWords.join(' ') } -const productResponseMap = (products) => { +const productResponseMap = (products, pricelist) => { return products.map((product) => { + let price = product.price_f || 0 + let priceDiscount = product.price_discount_f || 0 + let discountPercentage = product.discount_f || 0 + + if (pricelist) { + const pricelistDiscount = product?.[`price_${pricelist}_f`] || false + const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false + + if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount + if (pricelistDiscountPerc && pricelistDiscountPerc > 0) + discountPercentage = pricelistDiscountPerc + } + + if (product?.flashsale_id_i > 0) { + price = product?.flashsale_base_price_f || 0 + priceDiscount = product?.flashsale_price_f || 0 + discountPercentage = product?.flashsale_discount_f || 0 + } + let productMapped = { id: product.product_id_i || '', image: product.image_s || '', code: product.default_code_s || '', name: product.name_s || '', - lowestPrice: { - price: product.price_f || 0, - priceDiscount: product.price_discount_f || 0, - discountPercentage: product.discount_f || 0 - }, + lowestPrice: { price, priceDiscount, discountPercentage }, variantTotal: product.variant_total_i || 0, stockTotal: product.stock_total_f || 0, weight: product.weight_f || 0, manufacture: {}, - categories: [] + categories: [], + flashSale: { + id: product?.flashsale_id_i, + name: product?.product?.flashsale_name_s + } } if (product.manufacture_id_i && product.manufacture_name_s) { diff --git a/src/pages/api/shop/spell.js b/src/pages/api/shop/spell.js new file mode 100644 index 00000000..4c01765c --- /dev/null +++ b/src/pages/api/shop/spell.js @@ -0,0 +1,18 @@ +import axios from 'axios' + +export default async function handler(req, res) { + const { q = '' } = req.query + + let result = await axios( + process.env.SOLR_HOST + `/solr/product/spell?indent=true&q.op=AND&q=${q}` + ) + + try { + res.status(200).json(result.data) + } catch (error) { + res.status(400).json({ + numFound: 0, + suggestions: [] + }) + } +} diff --git a/src/pages/blog/[slug].jsx b/src/pages/blog/[slug].jsx index 9305411d..39c0bb50 100644 --- a/src/pages/blog/[slug].jsx +++ b/src/pages/blog/[slug].jsx @@ -1,10 +1,11 @@ import Seo from '@/core/components/Seo' -import Link from '@/core/components/elements/Link/Link' import Spinner from '@/core/components/elements/Spinner/Spinner' -import BasicLayout from '@/core/components/layouts/BasicLayout' -import { createSlug, getIdFromSlug } from '@/core/utils/slug' +import { getIdFromSlug } from '@/core/utils/slug' import useBlog from '@/lib/blog/hooks/useBlog' import { useRouter } from 'next/router' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) export default function BlogDetail() { const router = useRouter() diff --git a/src/pages/blog/index.jsx b/src/pages/blog/index.jsx index c65fe07d..17446935 100644 --- a/src/pages/blog/index.jsx +++ b/src/pages/blog/index.jsx @@ -1,12 +1,14 @@ -import BasicLayout from '@/core/components/layouts/BasicLayout' import Link from 'next/link' +import { useRouter } from 'next/router' import { createSlug } from '@/core/utils/slug' -import Image from '@/core/components/elements/Image/Image' import useBlogs from '@/lib/blog/hooks/useBlogs' -import { useRouter } from 'next/router' -import Pagination from '@/core/components/elements/Pagination/Pagination' -import Spinner from '@/core/components/elements/Spinner/Spinner' import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const Pagination = dynamic(() => import('@/core/components/elements/Pagination/Pagination')) +const Spinner = dynamic(() => import('@/core/components/elements/Spinner/Spinner')) +const Image = dynamic(() => import('@/core/components/elements/Image/Image')) export default function Blogs() { const router = useRouter() diff --git a/src/pages/contact-us.jsx b/src/pages/contact-us.jsx deleted file mode 100644 index adbf9439..00000000 --- a/src/pages/contact-us.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import Seo from '@/core/components/Seo' -import BasicLayout from '@/core/components/layouts/BasicLayout' -import PageContent from '@/lib/content/components/PageContent' - -export default function ContactUs() { - return ( - <BasicLayout> - <Seo title='Hubungi Indoteknik.com' /> - <PageContent path='/contact-us' /> - </BasicLayout> - ) -} diff --git a/src/pages/faqs.jsx b/src/pages/faqs.jsx deleted file mode 100644 index e8ffb4e3..00000000 --- a/src/pages/faqs.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import Seo from '@/core/components/Seo' -import BasicLayout from '@/core/components/layouts/BasicLayout' -import PageContent from '@/lib/content/components/PageContent' - -export default function ContactUs() { - return ( - <BasicLayout> - <Seo title='FAQS Indoteknik.com' /> - <PageContent path='/faqs' /> - </BasicLayout> - ) -} diff --git a/src/pages/hubungi-kami.jsx b/src/pages/hubungi-kami.jsx new file mode 100644 index 00000000..a246b515 --- /dev/null +++ b/src/pages/hubungi-kami.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function HubungiKami() { + return ( + <BasicLayout> + <Seo title='Hubungi Kami - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/hubungi-kami' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 2a996b5d..5ca7b939 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -3,33 +3,29 @@ import ImageSkeleton from '@/core/components/elements/Skeleton/ImageSkeleton' import PopularProductSkeleton from '@/lib/home/components/Skeleton/PopularProductSkeleton' import MobileView from '@/core/components/views/MobileView' import DesktopView from '@/core/components/views/DesktopView' -import { useEffect, useRef, useState } from 'react' -import { NextSeo } from 'next-seo' +import { useRef } from 'react' import Seo from '@/core/components/Seo' import { useQuery } from 'react-query' import odooApi from '@/core/api/odooApi' -import Image from '@/core/components/elements/Image/Image' +import Image from 'next/image' const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) - +const FlashSale = dynamic(() => import('@/lib/flashSale/components/FlashSale')) const HeroBanner = dynamic(() => import('@/lib/home/components/HeroBanner'), { loading: () => <ImageSkeleton /> }) - const PreferredBrand = dynamic(() => import('@/lib/home/components/PreferredBrand'), { loading: () => <PopularProductSkeleton /> }) - const PopularProduct = dynamic(() => import('@/lib/home/components/PopularProduct'), { loading: () => <PopularProductSkeleton /> }) - const CategoryHomeId = dynamic(() => import('@/lib/home/components/CategoryHomeId'), { loading: () => <PopularProductSkeleton /> }) export default function Home() { - const fetchSecondHeroBanner = async () => await odooApi('GET', '/api/v1/banner?type=index-b-2') + const fetchSecondHeroBanner = async () => await odooApi('GET', '/api/v1/banner?type=index-a-2') const secondHeroBanner = useQuery('secondHeroBanner', fetchSecondHeroBanner) const bannerRef = useRef(null) @@ -57,12 +53,18 @@ export default function Home() { <DesktopView> <div className='container mx-auto'> <div className='flex h-[360px]' ref={wrapperRef} onLoad={handleOnLoad}> - <div className='w-3/12'> + <div className='w-2/12'> {secondHeroBanner.isFetched && ( - <Image src={secondHeroBanner.data[0].image} alt={secondHeroBanner.data[0].name} /> + <Image + src={secondHeroBanner.data[0].image} + width={512} + height={1024} + alt={secondHeroBanner.data[0].name} + className='object-cover object-center h-full' + /> )} </div> - <div className='w-6/12 px-1' ref={bannerRef}> + <div className='w-7/12 px-1' ref={bannerRef}> <HeroBanner /> </div> <div className='w-3/12'> @@ -72,6 +74,7 @@ export default function Home() { <div className='my-16 flex flex-col gap-y-10'> <PreferredBrand /> + <FlashSale /> <CategoryHomeId /> </div> </div> @@ -81,6 +84,7 @@ export default function Home() { <HeroBanner /> <div className='flex flex-col gap-y-6 my-6'> <PreferredBrand /> + <FlashSale /> <PopularProduct /> <CategoryHomeId /> </div> diff --git a/src/pages/informasi-garansi.jsx b/src/pages/informasi-garansi.jsx new file mode 100644 index 00000000..c4511d30 --- /dev/null +++ b/src/pages/informasi-garansi.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function InformasiGaransi() { + return ( + <BasicLayout> + <Seo title='Informasi Garansi - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/informasi-garansi' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/karir.jsx b/src/pages/karir.jsx new file mode 100644 index 00000000..406397d9 --- /dev/null +++ b/src/pages/karir.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function KebijakanPrivasi() { + return ( + <BasicLayout> + <Seo title='Karir - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/karir' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/kebijakan-privasi.jsx b/src/pages/kebijakan-privasi.jsx new file mode 100644 index 00000000..8662d56d --- /dev/null +++ b/src/pages/kebijakan-privasi.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function KebijakanPrivasi() { + return ( + <BasicLayout> + <Seo title='Kebijakan Privasi - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/kebijakan-privasi' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/metode-pembayaran.jsx b/src/pages/metode-pembayaran.jsx new file mode 100644 index 00000000..8e5d6467 --- /dev/null +++ b/src/pages/metode-pembayaran.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function MetodePembayaran() { + return ( + <BasicLayout> + <Seo title='Metode Pembayaran - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/metode-pembayaran' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/metode-pengiriman.jsx b/src/pages/metode-pengiriman.jsx new file mode 100644 index 00000000..2b0b65fa --- /dev/null +++ b/src/pages/metode-pengiriman.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function MetodePengiriman() { + return ( + <BasicLayout> + <Seo title='Metode Pengiriman - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/metode-pengiriman' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/my/daftar-merchant.jsx b/src/pages/my/daftar-merchant.jsx new file mode 100644 index 00000000..e1fa9bcb --- /dev/null +++ b/src/pages/my/daftar-merchant.jsx @@ -0,0 +1,15 @@ +import Seo from '@/core/components/Seo' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import CreateMerchant from '@/lib/form/components/Merchant' + +export default function DaftarMerchant() { + return ( + <> + <Seo title='Daftar Merchant - Indoteknik.com' /> + + <BasicLayout> + <CreateMerchant></CreateMerchant> + </BasicLayout> + </> + ) +} diff --git a/src/pages/my/invoice/[id].jsx b/src/pages/my/invoices/[id].jsx index 740819cc..5972b382 100644 --- a/src/pages/my/invoice/[id].jsx +++ b/src/pages/my/invoices/[id].jsx @@ -6,7 +6,7 @@ import IsAuth from '@/lib/auth/components/IsAuth' import InvoiceComponent from '@/lib/invoice/components/Invoice' import { useRouter } from 'next/router' -export default function Invoice() { +export default function MyInvoice() { const router = useRouter() return ( diff --git a/src/pages/my/invoices.jsx b/src/pages/my/invoices/index.jsx index 59059b2e..73c7b9fe 100644 --- a/src/pages/my/invoices.jsx +++ b/src/pages/my/invoices/index.jsx @@ -5,7 +5,7 @@ import MobileView from '@/core/components/views/MobileView' import IsAuth from '@/lib/auth/components/IsAuth' import InvoicesComponent from '@/lib/invoice/components/Invoices' -export default function Invoices() { +export default function MyInvoices() { return ( <IsAuth> <MobileView> diff --git a/src/pages/my/kunjungan-sales.jsx b/src/pages/my/kunjungan-sales.jsx index 63e95837..052991d9 100644 --- a/src/pages/my/kunjungan-sales.jsx +++ b/src/pages/my/kunjungan-sales.jsx @@ -2,7 +2,7 @@ import Seo from '@/core/components/Seo' import BasicLayout from '@/core/components/layouts/BasicLayout' import KunjunganSales from '@/lib/form/components/KunjunganSales' -export default function pembayaran_tempo() { +export default function kunjungan_sales() { return ( <> <Seo title='Kunjungan Sales - Indoteknik.com' /> diff --git a/src/pages/my/kunjungan-service.jsx b/src/pages/my/kunjungan-service.jsx index 80d1ecbc..37de5a0b 100644 --- a/src/pages/my/kunjungan-service.jsx +++ b/src/pages/my/kunjungan-service.jsx @@ -2,8 +2,7 @@ import Seo from '@/core/components/Seo' import BasicLayout from '@/core/components/layouts/BasicLayout' import CreateKunjunganService from '@/lib/form/components/KunjunganService' -export default function pembayaran_tempo() { - +export default function kunjungan_service() { return ( <> <Seo title='Kunjungan Service - Indoteknik.com' /> diff --git a/src/pages/my/media-relations.jsx b/src/pages/my/media-relations.jsx new file mode 100644 index 00000000..a965f39a --- /dev/null +++ b/src/pages/my/media-relations.jsx @@ -0,0 +1,15 @@ +import Seo from '@/core/components/Seo' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import CreateMediaRelations from '@/lib/form/components/MediaRelations' + +export default function media_relations() { + return ( + <> + <Seo title='Media Relations - Indoteknik.com' /> + + <BasicLayout> + <CreateMediaRelations></CreateMediaRelations> + </BasicLayout> + </> + ) +} diff --git a/src/pages/my/menu.jsx b/src/pages/my/menu.jsx index e7ae27fd..c8e1e7e9 100644 --- a/src/pages/my/menu.jsx +++ b/src/pages/my/menu.jsx @@ -40,6 +40,7 @@ export default function Menu() { <MenuHeader>Aktivitas Pembelian</MenuHeader> <div className='divide-y divide-gray_r-6 border-y border-gray_r-6 mt-4'> + <LinkItem href='/my/quotations'>Daftar Quotation</LinkItem> <LinkItem href='/my/transactions'>Daftar Transaksi</LinkItem> <LinkItem href='/my/invoices'>Invoice & Faktur Pajak</LinkItem> <LinkItem href='/my/wishlist'>Wishlist</LinkItem> diff --git a/src/pages/my/pembayaran-tempo.jsx b/src/pages/my/pembayaran-tempo.jsx index 1e4fc80d..8947bdd9 100644 --- a/src/pages/my/pembayaran-tempo.jsx +++ b/src/pages/my/pembayaran-tempo.jsx @@ -2,7 +2,7 @@ import Seo from '@/core/components/Seo' import BasicLayout from '@/core/components/layouts/BasicLayout' import PembayaranTempo from '@/lib/form/components/PembayaranTempo' -export default function pembayaran_tempo() { +export default function pembayaranTempo() { return ( <> <Seo title='Pembayaran Tempo - Indoteknik.com' /> diff --git a/src/pages/my/transaction/[id].jsx b/src/pages/my/quotations/[id].jsx index c3283783..1fbbf34a 100644 --- a/src/pages/my/transaction/[id].jsx +++ b/src/pages/my/quotations/[id].jsx @@ -6,7 +6,7 @@ import IsAuth from '@/lib/auth/components/IsAuth' import TransactionComponent from '@/lib/transaction/components/Transaction' import { useRouter } from 'next/router' -export default function Transaction() { +export default function MyQuotation() { const router = useRouter() return ( diff --git a/src/pages/my/quotations/index.jsx b/src/pages/my/quotations/index.jsx new file mode 100644 index 00000000..bd91d9d0 --- /dev/null +++ b/src/pages/my/quotations/index.jsx @@ -0,0 +1,26 @@ +import AppLayout from '@/core/components/layouts/AppLayout' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' +import IsAuth from '@/lib/auth/components/IsAuth' +import dynamic from 'next/dynamic' + +const TransactionsComponent = dynamic(() => import('@/lib/transaction/components/Transactions')) + +export default function MyQuotations() { + return ( + <IsAuth> + <MobileView> + <AppLayout title='Quotation'> + <TransactionsComponent context='quotation' /> + </AppLayout> + </MobileView> + + <DesktopView> + <BasicLayout> + <TransactionsComponent context='quotation' /> + </BasicLayout> + </DesktopView> + </IsAuth> + ) +} diff --git a/src/pages/my/surat-dukungan.jsx b/src/pages/my/surat-dukungan.jsx index 8c469d02..8058f34d 100644 --- a/src/pages/my/surat-dukungan.jsx +++ b/src/pages/my/surat-dukungan.jsx @@ -3,8 +3,7 @@ import BasicLayout from '@/core/components/layouts/BasicLayout' import CreateKunjunganService from '@/lib/form/components/KunjunganService' import CreateSuratDukungan from '@/lib/form/components/SuratDukungan' -export default function pembayaran_tempo() { - +export default function surat_dukungan() { return ( <> <Seo title='Surat Dukungan - Indoteknik.com' /> diff --git a/src/pages/my/transactions/[id].jsx b/src/pages/my/transactions/[id].jsx new file mode 100644 index 00000000..e36c1ca4 --- /dev/null +++ b/src/pages/my/transactions/[id].jsx @@ -0,0 +1,27 @@ +import AppLayout from '@/core/components/layouts/AppLayout' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import DesktopView from '@/core/components/views/DesktopView' +import MobileView from '@/core/components/views/MobileView' +import IsAuth from '@/lib/auth/components/IsAuth' +import TransactionComponent from '@/lib/transaction/components/Transaction' +import { useRouter } from 'next/router' + +export default function MyTransaction() { + const router = useRouter() + + return ( + <IsAuth> + <MobileView> + <AppLayout title='Transaksi'> + <TransactionComponent id={router.query.id} /> + </AppLayout> + </MobileView> + + <DesktopView> + <BasicLayout> + <TransactionComponent id={router.query.id} /> + </BasicLayout> + </DesktopView> + </IsAuth> + ) +} diff --git a/src/pages/my/transactions.jsx b/src/pages/my/transactions/index.jsx index a8ca78b8..91482a39 100644 --- a/src/pages/my/transactions.jsx +++ b/src/pages/my/transactions/index.jsx @@ -7,7 +7,7 @@ import dynamic from 'next/dynamic' const TransactionsComponent = dynamic(() => import('@/lib/transaction/components/Transactions')) -export default function Transactions() { +export default function MyTransactions() { return ( <IsAuth> <MobileView> diff --git a/src/pages/panduan-belanja.jsx b/src/pages/panduan-belanja.jsx new file mode 100644 index 00000000..27be13da --- /dev/null +++ b/src/pages/panduan-belanja.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function PanduanBelanja() { + return ( + <BasicLayout> + <Seo title='Panduan Belanja - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/panduan-belanja' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/panduan-pick-up-service.jsx b/src/pages/panduan-pick-up-service.jsx new file mode 100644 index 00000000..57f78a4c --- /dev/null +++ b/src/pages/panduan-pick-up-service.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function PanduanPickUpService() { + return ( + <BasicLayout> + <Seo title='Panduan Pick Up Service - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/panduan-pick-up-service' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/panduan-quotation.jsx b/src/pages/panduan-quotation.jsx new file mode 100644 index 00000000..e4ecdd95 --- /dev/null +++ b/src/pages/panduan-quotation.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function PanduanQuotation() { + return ( + <BasicLayout> + <Seo title='Panduan Quotation - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/panduan-quotation' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/pelanggan-kami.jsx b/src/pages/pelanggan-kami.jsx new file mode 100644 index 00000000..48b92339 --- /dev/null +++ b/src/pages/pelanggan-kami.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function PelangganKami() { + return ( + <BasicLayout> + <Seo title='Pelanggan Kami - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/pelanggan-kami' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/pengembalian-barang-dana.jsx b/src/pages/pengembalian-barang-dana.jsx new file mode 100644 index 00000000..57b5c9c5 --- /dev/null +++ b/src/pages/pengembalian-barang-dana.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function PengembalianBarangDana() { + return ( + <BasicLayout> + <Seo title='Pengembalian Barang & Dana - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/pengembalian-barang-dana' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/shop/category/[slug].jsx b/src/pages/shop/category/[slug].jsx new file mode 100644 index 00000000..dbc17c06 --- /dev/null +++ b/src/pages/shop/category/[slug].jsx @@ -0,0 +1,37 @@ +import dynamic from 'next/dynamic' +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug' +import { useRouter } from 'next/router' +import _ from 'lodash' +import Seo from '@/core/components/Seo' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const ProductSearch = dynamic(() => import('@/lib/product/components/ProductSearch')) + +export default function CategoryDetail() { + const router = useRouter() + const { slug = '' } = router.query + + const categoryName = getNameFromSlug(slug) + const categoryId = getIdFromSlug(slug) + const query = { + fq: `manufacture_id_i:${categoryId}` + } + return ( + <BasicLayout> + <Seo + title={`Beli ${categoryName} di Indoteknik`} + description={`Jual ${categoryName} Kirim Jakarta Surabaya Semarang Makassar Manado Denpasar Balikpapan Medan Palembang Lampung Bali Bandung Makassar Manado.`} + additionalMetaTags={[ + { + property: 'keywords', + content: `Jual ${categoryName}, harga ${categoryName}, ${categoryName} murah, toko ${categoryName}, ${categoryName} jakarta, ${categoryName} surabaya` + } + ]} + /> + + {!_.isEmpty(router.query) && ( + <ProductSearch query={query} prefixUrl={`/shop/category/${slug}`} /> + )} + </BasicLayout> + ) +} diff --git a/src/pages/shop/product/[slug].jsx b/src/pages/shop/product/[slug].jsx index 84b848f0..5d706dec 100644 --- a/src/pages/shop/product/[slug].jsx +++ b/src/pages/shop/product/[slug].jsx @@ -1,48 +1,75 @@ 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' 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 - let product = await productApi({ id: getIdFromSlug(slug) }) + const cookies = context.req.headers.cookie + const cookieObj = cookies ? cookie.parse(cookies) : {} + const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {} + const authToken = auth?.token || '' + + let product = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } }) if (product?.length == 1) { product = product[0] const regexHtmlTags = /(<([^>]+)>)/gi const regexHtmlTagsExceptP = /<\/?(?!p\b)[^>]*>/g - if (product.description.replace(regexHtmlTags, ' ').trim() == '') { - product.description = '' - } - product.description = product.description.replace(regexHtmlTagsExceptP, ' ') - product.description = product.description.trim() + product.description = product.description + .replace(regexHtmlTagsExceptP, ' ') + .replace(regexHtmlTags, ' ') + .trim() + } else { + product = null + } + + return { + props: { product } } - return { props: { product } } } export default function ProductDetail({ product }) { const router = useRouter() + + if (!product) return <PageNotFound /> + return ( <BasicLayout> <Seo - title={product?.name + ' - Indoteknik.com' || ''} + title={product?.name || '' + ' - Indoteknik.com' || ''} description='Temukan pilihan produk B2B Industri & Alat Teknik untuk Perusahaan, UMKM & Pemerintah dengan lengkap, mudah dan transparan.' openGraph={{ url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath, - image: product.image, + 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}` + content: `${product?.name}, Harga ${product?.name}, Beli ${product?.name}, Spesifikasi ${product?.name}` } ]} /> - <Product product={product} /> + {!product && ( + <div className='container mx-auto flex justify-center pt-10'> + <LogoSpinner width={36} height={36} /> + </div> + )} + {product && <Product product={product} />} </BasicLayout> ) } diff --git a/src/pages/shop/quotation/finish.jsx b/src/pages/shop/quotation/finish.jsx index 0e9c5672..3850fef8 100644 --- a/src/pages/shop/quotation/finish.jsx +++ b/src/pages/shop/quotation/finish.jsx @@ -30,7 +30,7 @@ export default function FinishQuotation() { </p> {id && ( <Link - href={`/my/transaction/${id}`} + href={`/my/quotations/${id}`} className='btn-yellow !text-gray_r-12 mt-6 w-full md:w-1/3 md:mx-auto' > Lihat Penawaran diff --git a/src/pages/sitemap/blogs.xml.js b/src/pages/sitemap/blogs.xml.js new file mode 100644 index 00000000..7f41ad0f --- /dev/null +++ b/src/pages/sitemap/blogs.xml.js @@ -0,0 +1,31 @@ +import { createSlug } from '@/core/utils/slug' +import blogsApi from '@/lib/blog/api/blogsApi' +import { create } from 'xmlbuilder' + +export async function getServerSideProps({ res }) { + const baseUrl = process.env.SELF_HOST + '/blog/' + const blogs = await blogsApi({ limit: 0, offset: 0 }) + const sitemap = create('urlset', { encoding: 'utf-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + const date = new Date() + blogs.blogs.forEach((blog) => { + const url = sitemap.ele('url') + url.ele('loc', createSlug(baseUrl, blog.title, blog.id)) + url.ele('lastmod', date.toISOString().slice(0, 10)) + url.ele('changefreq', 'weekly') + url.ele('priority', '0.6') + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap.end()) + res.end() + + return { props: {} } +} + +export default function SitemapProducts() { + return null +} diff --git a/src/pages/sitemap/brands.xml.js b/src/pages/sitemap/brands.xml.js new file mode 100644 index 00000000..c85c40e9 --- /dev/null +++ b/src/pages/sitemap/brands.xml.js @@ -0,0 +1,31 @@ +import { create } from 'xmlbuilder' +import { createSlug } from '@/core/utils/slug' +import odooApi from '@/core/api/odooApi' + +export async function getServerSideProps({ res }) { + const baseUrl = process.env.SELF_HOST + '/shop/brands/' + const brands = await odooApi('GET', `/api/v1/manufacture?limit=0`) + const sitemap = create('urlset', { encoding: 'utf-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + const date = new Date() + brands.manufactures.forEach((brand) => { + const url = sitemap.ele('url') + url.ele('loc', createSlug(baseUrl, brand.name, brand.id)) + url.ele('lastmod', date.toISOString().slice(0, 10)) + url.ele('changefreq', 'weekly') + url.ele('priority', '0.6') + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap.end()) + res.end() + + return { props: {} } +} + +export default function SitemapProducts() { + return null +} diff --git a/src/pages/sitemap/categories.xml.js b/src/pages/sitemap/categories.xml.js new file mode 100644 index 00000000..1c684576 --- /dev/null +++ b/src/pages/sitemap/categories.xml.js @@ -0,0 +1,41 @@ +import { create } from 'xmlbuilder' +import { createSlug } from '@/core/utils/slug' +import odooApi from '@/core/api/odooApi' + +export async function getServerSideProps({ res }) { + const categories = await odooApi('GET', '/api/v1/category/tree') + const sitemap = create('urlset', { encoding: 'utf-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + categories.forEach((category) => { + addUrlToSitemap(sitemap, category.name, category.id) + category.childs.forEach((child1Category) => { + addUrlToSitemap(sitemap, child1Category.name, child1Category.id) + child1Category.childs.forEach((child2Category) => { + addUrlToSitemap(sitemap, child2Category.name, child2Category.id) + }) + }) + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap.end()) + res.end() + + return { props: {} } +} + +function addUrlToSitemap(sitemap, name, id) { + const baseUrl = process.env.SELF_HOST + '/shop/category/' + const date = new Date() + const url = sitemap.ele('url') + url.ele('loc', createSlug(baseUrl, name, id)) + url.ele('lastmod', date.toISOString().slice(0, 10)) + url.ele('changefreq', 'weekly') + url.ele('priority', '0.6') +} + +export default function SitemapProducts() { + return null +} diff --git a/src/pages/sitemap/products.xml.js b/src/pages/sitemap/products.xml.js index e5fc8029..a2067308 100644 --- a/src/pages/sitemap/products.xml.js +++ b/src/pages/sitemap/products.xml.js @@ -9,7 +9,10 @@ export async function getServerSideProps({ res }) { const products = await productSearchApi({ query: _.toQuery(query) }) const pageCount = Math.ceil(products.response.numFound / limit) const pages = Array.from({ length: pageCount }, (_, i) => i + 1) - const sitemapIndex = create('sitemapindex', { encoding: 'UTF-8' }) + const sitemapIndex = create('sitemapindex', { encoding: 'UTF-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) const date = new Date() pages.forEach((page) => { diff --git a/src/pages/sitemap/products/[id].xml.js b/src/pages/sitemap/products/[id].xml.js deleted file mode 100644 index 98c2bf40..00000000 --- a/src/pages/sitemap/products/[id].xml.js +++ /dev/null @@ -1,32 +0,0 @@ -import productSearchApi from '@/lib/product/api/productSearchApi' -import { create } from 'xmlbuilder' -import _ from 'lodash-contrib' -import { createSlug } from '@/core/utils/slug' - -export async function getServerSideProps({ res }) { - const baseUrl = process.env.SELF_HOST + '/shop/product' - const limit = 2500 - const query = { limit } - const products = await productSearchApi({ query: _.toQuery(query) }) - console.log(products) - // const sitemap = create('urlset', { encoding: 'UTF-8' }) - - // const date = new Date() - // pages.forEach((page) => { - // const url = sitemap.ele('url') - // url.ele('loc', createSlug(baseUrl, '', '')) - // url.ele('lastmod', date.toISOString().slice(0, 10)) - // url.ele('changefreq', 'weekly') - // url.ele('priority', '0.8') - // }) - - // res.setHeader('Content-Type', 'text/xml') - // res.write(sitemap.end()) - // res.end() - - return { props: {} } -} - -export default function SitemapProducts() { - return <></> -} diff --git a/src/pages/sitemap/products/[page].js b/src/pages/sitemap/products/[page].js new file mode 100644 index 00000000..2f9c3198 --- /dev/null +++ b/src/pages/sitemap/products/[page].js @@ -0,0 +1,35 @@ +import productSearchApi from '@/lib/product/api/productSearchApi' +import { create } from 'xmlbuilder' +import _ from 'lodash-contrib' +import { createSlug } from '@/core/utils/slug' + +export async function getServerSideProps({ query, res }) { + const baseUrl = process.env.SELF_HOST + '/shop/product/' + const { page } = query + const limit = 2500 + const queries = { limit, page: page.replace('.xml', '') } + const products = await productSearchApi({ query: _.toQuery(queries) }) + const sitemap = create('urlset', { encoding: 'utf-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + const date = new Date() + products.response.products.forEach((product) => { + const url = sitemap.ele('url') + url.ele('loc', createSlug(baseUrl, product.name, product.id)) + url.ele('lastmod', date.toISOString().slice(0, 10)) + url.ele('changefreq', 'weekly') + url.ele('priority', '0.8') + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap.end()) + res.end() + + return { props: {} } +} + +export default function SitemapProducts() { + return null +} diff --git a/src/pages/syarat-ketentuan.jsx b/src/pages/syarat-ketentuan.jsx new file mode 100644 index 00000000..20a3aa63 --- /dev/null +++ b/src/pages/syarat-ketentuan.jsx @@ -0,0 +1,17 @@ +import Seo from '@/core/components/Seo' +import dynamic from 'next/dynamic' + +const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout')) +const PageContent = dynamic(() => import('@/lib/content/components/PageContent')) + +export default function SyaratKetentuan() { + return ( + <BasicLayout> + <Seo title='Syarat & Ketentuan - Indoteknik.com' /> + + <article className='container mx-auto py-6 px-4 sm:px-0'> + <PageContent path='/syarat-ketentuan' /> + </article> + </BasicLayout> + ) +} diff --git a/src/pages/about-us.jsx b/src/pages/tentang-kami.jsx index c7e546df..d7029a50 100644 --- a/src/pages/about-us.jsx +++ b/src/pages/tentang-kami.jsx @@ -2,7 +2,7 @@ import Seo from '@/core/components/Seo' import BasicLayout from '@/core/components/layouts/BasicLayout' import IframeContent from '@/lib/iframe/components/IframeContent' -export default function AboutUs() { +export default function TentangKami() { return ( <BasicLayout> <Seo title='Tentang Indoteknik.com' /> |
