summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-02-14 15:52:29 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-02-14 15:52:29 +0700
commitcce0ab7c8bf657b8dbe804e30fd7851ff9c26414 (patch)
treee5b738169a6c87701f8b8d2763a5c0ebdd4734f8
parent8dc379e37d7ab3b86725b58d9636c4ad64dcfc2f (diff)
no message
-rw-r--r--src/components/layouts/Header.js8
-rw-r--r--src/components/variants/VariantGroupCard.js2
-rw-r--r--src/pages/my/invoice/[id].js12
-rw-r--r--src/pages/shop/brands/[slug].js27
-rw-r--r--src/pages/shop/checkout/index.js166
-rw-r--r--src/pages/shop/product/[slug].js235
6 files changed, 245 insertions, 205 deletions
diff --git a/src/components/layouts/Header.js b/src/components/layouts/Header.js
index 5df75c3c..23fda642 100644
--- a/src/components/layouts/Header.js
+++ b/src/components/layouts/Header.js
@@ -26,6 +26,8 @@ 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 }) {
@@ -164,19 +166,19 @@ export default function Header({ title }) {
<Link href={`/shop/search?category=${category.name}`} className="flex-1 font-normal text-gray_r-11 py-4">
{ category.name }
</Link>
- <div className="ml-3 h-full py-4" onClick={() => toggleCategories(category.id)}>
+ <div className="ml-4 h-full py-4" onClick={() => toggleCategories(category.id)}>
{ !category.isOpen && <ChevronDownIcon className="text-gray_r-12 w-5" /> }
{ category.isOpen && <ChevronUpIcon className="text-gray_r-12 w-5" /> }
</div>
</div>
{ category.isOpen && category.childs.map((child1Category) => (
<Fragment key={child1Category.id}>
- <div className="flex w-full text-gray_r-11 border-b border-gray_r-6 p-4 pl-12">
+ <div className={`flex w-full text-gray_r-11 border-b border-gray_r-6 p-4 pl-12 ${category.isOpen ? 'bg-gray_r-2' : ''}`}>
<Link href={`/shop/search?category=${child1Category.name}`} className="flex-1 font-normal text-gray_r-11">
{ child1Category.name }
</Link>
{ child1Category.childs.length > 0 && (
- <div className="ml-3 h-full" onClick={() => toggleCategories(child1Category.id)}>
+ <div className="ml-4 h-full" onClick={() => toggleCategories(child1Category.id)}>
{ !child1Category.isOpen && <ChevronDownIcon className="text-gray_r-12 w-5" /> }
{ child1Category.isOpen && <ChevronUpIcon className="text-gray_r-12 w-5" /> }
</div>
diff --git a/src/components/variants/VariantGroupCard.js b/src/components/variants/VariantGroupCard.js
index 98f2d739..462c63cf 100644
--- a/src/components/variants/VariantGroupCard.js
+++ b/src/components/variants/VariantGroupCard.js
@@ -23,7 +23,7 @@ export default function VariantGroupCard({
className="btn-light py-2 w-full"
onClick={() => setShowAll(!showAll)}
>
- { !showAll ? 'Lihat Semua' : 'Tutup' }
+ { !showAll ? `Lihat Semua +${variants.length - variantsToShow.length}` : 'Tutup' }
</button>
) }
</>
diff --git a/src/pages/my/invoice/[id].js b/src/pages/my/invoice/[id].js
index 7342b1bf..820c9af8 100644
--- a/src/pages/my/invoice/[id].js
+++ b/src/pages/my/invoice/[id].js
@@ -11,6 +11,7 @@ import currencyFormat from "@/core/utils/currencyFormat";
import Disclosure from "@/components/elements/Disclosure";
import DescriptionRow from "@/components/elements/DescriptionRow";
import { SkeletonList } from "@/components/elements/Skeleton";
+import VariantGroupCard from "@/components/variants/VariantGroupCard";
export default function DetailInvoice() {
const router = useRouter();
@@ -127,13 +128,10 @@ export default function DetailInvoice() {
/>
<div className="mt-2 p-4 pt-0 flex flex-col gap-y-3">
- { invoice?.products?.map((product, index) => (
- <VariantCard
- key={index}
- data={product}
- buyMore
- />
- )) }
+ <VariantGroupCard
+ variants={invoice?.products}
+ buyMore
+ />
<div className="flex justify-between mt-3 font-medium">
<p className="text-gray_r-11">Total Belanja</p>
<p>{ currencyFormat(invoice?.amount_total || 0) }</p>
diff --git a/src/pages/shop/brands/[slug].js b/src/pages/shop/brands/[slug].js
index 64ff7706..a387e55d 100644
--- a/src/pages/shop/brands/[slug].js
+++ b/src/pages/shop/brands/[slug].js
@@ -15,6 +15,7 @@ import "swiper/css/pagination";
import "swiper/css/autoplay";
import { Pagination as SwiperPagination } from "swiper";
import Image from "@/components/elements/Image";
+import LineDivider from "@/components/elements/LineDivider";
export async function getServerSideProps(context) {
const {
@@ -112,21 +113,33 @@ export default function BrandDetail({
<Image
src={banner}
alt={`Banner ${manufacture.name}`}
- className="w-full h-auto"
+ className="w-full h-auto border-b border-gray_r-6"
/>
</SwiperSlide>
))
}
</Swiper>
- <div className="p-4">
- <div className="flex">
+ <div className="p-4 grid grid-cols-2">
+ <div>
+ <p className="text-caption-2 text-gray_r-11 mb-2">Produk dari brand:</p>
{ manufacture.logo ? (
- <Image src={manufacture?.logo} alt={manufacture.name} className="w-4/12 border border-gray_r-6 rounded p-3" />
+ <div className="w-8/12">
+ <Image src={manufacture?.logo} alt={manufacture.name} className="border border-gray_r-6 rounded p-3" />
+ </div>
) : (
- <p className="badge-red text-caption-1">Brand { manufacture.name }</p>
- ) }
+ <p className="badge-solid-red text-caption-1">{ manufacture.name }</p>
+ ) }
+ </div>
+ <div className="text-right">
+ <p className="text-caption-2 text-gray_r-11 mb-2">Jumlah Produk:</p>
+ <p>{ searchResults.response.numFound }</p>
</div>
- <h1 className="mb-2 mt-4">Produk</h1>
+ </div>
+
+ <LineDivider />
+
+ <div className="p-4">
+ <h1 className="mb-2">Produk</h1>
<div className="text-caption-1 mb-4">
{productFound > 0 ? (
<>
diff --git a/src/pages/shop/checkout/index.js b/src/pages/shop/checkout/index.js
index 57fe5d3a..0a77ebed 100644
--- a/src/pages/shop/checkout/index.js
+++ b/src/pages/shop/checkout/index.js
@@ -1,142 +1,146 @@
-import { ExclamationCircleIcon } from "@heroicons/react/24/solid";
-import { useEffect, useState } from "react";
-import Alert from "@/components/elements/Alert";
-import AppBar from "@/components/layouts/AppBar";
-import Layout from "@/components/layouts/Layout";
-import LineDivider from "@/components/elements/LineDivider";
-import Link from "@/components/elements/Link";
-import ProgressBar from "@/components/elements/ProgressBar";
-import Spinner from "@/components/elements/Spinner";
-import apiOdoo from "@/core/utils/apiOdoo";
-import { useAuth } from "@/core/utils/auth";
-import { deleteItemCart, getCart } from "@/core/utils/cart";
-import currencyFormat from "@/core/utils/currencyFormat";
-import { getItemAddress } from "@/core/utils/address";
-import { useRouter } from "next/router";
-import WithAuth from "@/components/auth/WithAuth";
-import { toast } from "react-hot-toast";
-import getFileBase64 from "@/core/utils/getFileBase64";
-import VariantCard from "@/components/variants/VariantCard";
+import { ExclamationCircleIcon } from "@heroicons/react/24/solid"
+import { useEffect, useState } from "react"
+import Alert from "@/components/elements/Alert"
+import AppBar from "@/components/layouts/AppBar"
+import Layout from "@/components/layouts/Layout"
+import LineDivider from "@/components/elements/LineDivider"
+import Link from "@/components/elements/Link"
+import ProgressBar from "@/components/elements/ProgressBar"
+import Spinner from "@/components/elements/Spinner"
+import apiOdoo from "@/core/utils/apiOdoo"
+import { useAuth } from "@/core/utils/auth"
+import { deleteItemCart, getCart } from "@/core/utils/cart"
+import currencyFormat from "@/core/utils/currencyFormat"
+import { getItemAddress } from "@/core/utils/address"
+import { useRouter } from "next/router"
+import WithAuth from "@/components/auth/WithAuth"
+import { toast } from "react-hot-toast"
+import getFileBase64 from "@/core/utils/getFileBase64"
+import VariantCard from "@/components/variants/VariantCard"
export default function Checkout() {
- const router = useRouter();
- const { product_id, qty } = router.query;
- const [ auth ] = useAuth();
- const [ addresses, setAddresses ] = useState(null);
- const [ poNumber, setPoNumber ] = useState('');
- const [ poFile, setPoFile ] = useState('');
+ const router = useRouter()
+ const { product_id, qty } = router.query
+ const [ auth ] = useAuth()
+ const [ addresses, setAddresses ] = useState(null)
+ const [ poNumber, setPoNumber ] = useState('')
+ const [ poFile, setPoFile ] = useState('')
const [ selectedAddress, setSelectedAddress ] = useState({
shipping: null,
invoicing: null
- });
- const [ selectedPayment, setSelectedPayment ] = useState(null);
- const [ products, setProducts ] = useState(null);
- const [ totalAmount, setTotalAmount ] = useState(0);
- const [ totalDiscountAmount, setTotalDiscountAmount ] = useState(0);
+ })
+ const [ selectedPayment, setSelectedPayment ] = useState(null)
+ const [ products, setProducts ] = useState(null)
+ const [ totalAmount, setTotalAmount ] = useState(0)
+ const [ totalDiscountAmount, setTotalDiscountAmount ] = useState(0)
+
+ const [ isLoading, setIsLoading ] = useState(false)
const payments = [
{ name: 'BCA', number: '8870-4000-81' },
{ name: 'MANDIRI', number: '155-0067-6869-75' },
- ];
+ ]
useEffect(() => {
const getAddresses = async () => {
if (auth) {
- const dataAddresses = await apiOdoo('GET', `/api/v1/user/${auth.id}/address`);
- setAddresses(dataAddresses);
+ const dataAddresses = await apiOdoo('GET', `/api/v1/user/${auth.id}/address`)
+ setAddresses(dataAddresses)
}
- };
- getAddresses();
- }, [auth]);
+ }
+ getAddresses()
+ }, [auth])
useEffect(() => {
const getProducts = async () => {
- let cart = getCart();
- let productIds = [];
+ let cart = getCart()
+ let productIds = []
if (product_id) {
- productIds = [parseInt(product_id)];
+ productIds = [parseInt(product_id)]
} else {
productIds = Object
.values(cart)
.filter((itemCart) => itemCart.selected == true)
- .map((itemCart) => itemCart.product_id);
+ .map((itemCart) => itemCart.product_id)
}
if (productIds.length > 0) {
- productIds = productIds.join(',');
- let dataProducts = await apiOdoo('GET', `/api/v1/product_variant/${productIds}`);
+ productIds = productIds.join(',')
+ let dataProducts = await apiOdoo('GET', `/api/v1/product_variant/${productIds}`)
dataProducts = dataProducts.map((product) => {
if (product_id) {
- product.quantity = 1;
- if (qty) product.quantity = parseInt(qty);
+ product.quantity = 1
+ if (qty) product.quantity = parseInt(qty)
} else {
- product.quantity = cart[product.id].quantity;
+ product.quantity = cart[product.id].quantity
}
- return product;
- });
- setProducts(dataProducts);
+ return product
+ })
+ setProducts(dataProducts)
}
- };
- getProducts();
- }, [router, auth, product_id, qty]);
+ }
+ getProducts()
+ }, [router, auth, product_id, qty])
useEffect(() => {
if (addresses) {
const matchAddress = (key) => {
- const addressToMatch = getItemAddress(key);
- let foundAddress = addresses.filter((address) => address.id == addressToMatch);
+ const addressToMatch = getItemAddress(key)
+ let foundAddress = addresses.filter((address) => address.id == addressToMatch)
if (foundAddress.length > 0) {
- return foundAddress[0];
+ return foundAddress[0]
}
- return addresses[0];
+ return addresses[0]
}
setSelectedAddress({
shipping: matchAddress('shipping'),
invoicing: matchAddress('invoicing'),
- });
- };
- }, [addresses]);
+ })
+ }
+ }, [addresses])
useEffect(() => {
if (products) {
- let calculateTotalAmount = 0;
- let calculateTotalDiscountAmount = 0;
+ let calculateTotalAmount = 0
+ let calculateTotalDiscountAmount = 0
products.forEach(product => {
- calculateTotalAmount += product.price.price * product.quantity;
- calculateTotalDiscountAmount += (product.price.price - product.price.price_discount) * product.quantity;
- });
- setTotalAmount(calculateTotalAmount);
- setTotalDiscountAmount(calculateTotalDiscountAmount);
+ calculateTotalAmount += product.price.price * product.quantity
+ calculateTotalDiscountAmount += (product.price.price - product.price.price_discount) * product.quantity
+ })
+ setTotalAmount(calculateTotalAmount)
+ setTotalDiscountAmount(calculateTotalDiscountAmount)
}
- }, [products]);
+ }, [products])
- const submit = async () => {
+ const checkout = async () => {
if (!selectedPayment) {
toast.error('Mohon pilih metode pembayaran', {
position: 'bottom-center'
- });
- return;
+ })
+ return
}
if (poFile && poFile.size > 5000000) {
toast.error('Maksimal ukuran file adalah 5MB', {
position: 'bottom-center'
- });
- return;
+ })
+ return
}
- let productOrder = products.map((product) => ({ 'product_id': product.id, 'quantity': product.quantity }));
+ setIsLoading(true)
+ let productOrder = products.map((product) => ({ 'product_id': product.id, 'quantity': product.quantity }))
let data = {
'partner_shipping_id': selectedAddress.shipping.id,
'partner_invoice_id': selectedAddress.invoicing.id,
'order_line': JSON.stringify(productOrder),
'type': 'sale_order'
- };
- if (poNumber) data.po_number = poNumber;
- if (poFile) data.po_file = await getFileBase64(poFile);
+ }
+ if (poNumber) data.po_number = poNumber
+ if (poFile) data.po_file = await getFileBase64(poFile)
- const checkoutToOdoo = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/checkout`, data);
+ const checkoutToOdoo = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/checkout`, data)
for (const product of products) {
- deleteItemCart(product.id);
+ deleteItemCart(product.id)
}
- router.push(`/shop/checkout/finish?id=${checkoutToOdoo.id}`);
+ router.push(`/shop/checkout/finish?id=${checkoutToOdoo.id}`)
+ setIsLoading(false)
}
return (
@@ -306,9 +310,11 @@ export default function Checkout() {
<div className="flex gap-x-3 p-4">
<button
className="flex-1 btn-yellow"
- onClick={submit}
+ onClick={checkout}
+ disabled={isLoading}
>
- Bayar
+ { isLoading && 'Loading...' }
+ { !isLoading && 'Bayar' }
</button>
</div>
</>
diff --git a/src/pages/shop/product/[slug].js b/src/pages/shop/product/[slug].js
index 60849264..61692c1c 100644
--- a/src/pages/shop/product/[slug].js
+++ b/src/pages/shop/product/[slug].js
@@ -1,43 +1,43 @@
-import Link from "@/components/elements/Link";
-import { useRouter } from "next/router";
-import { useEffect, useState } from "react";
-import Header from "@/components/layouts/Header";
-import apiOdoo from "@/core/utils/apiOdoo";
-import { createSlug, getIdFromSlug } from "@/core/utils/slug";
-import currencyFormat from "@/core/utils/currencyFormat";
-import Layout from "@/components/layouts/Layout";
-import { createOrUpdateItemCart } from "@/core/utils/cart";
-import toast from "react-hot-toast";
-import Footer from "@/components/layouts/Footer";
-import Image from "@/components/elements/Image";
-import LineDivider from "@/components/elements/LineDivider";
-import { HeartIcon as HeartIconSolid } from "@heroicons/react/24/solid";
-import { useAuth } from "@/core/utils/auth";
-import { HeartIcon } from "@heroicons/react/24/outline";
-import LazyLoad from "react-lazy-load";
-import ProductSimilar from "@/components/products/ProductSimilar";
+import Link from "@/components/elements/Link"
+import { useRouter } from "next/router"
+import { useEffect, useState } from "react"
+import Header from "@/components/layouts/Header"
+import apiOdoo from "@/core/utils/apiOdoo"
+import { createSlug, getIdFromSlug } from "@/core/utils/slug"
+import currencyFormat from "@/core/utils/currencyFormat"
+import Layout from "@/components/layouts/Layout"
+import { createOrUpdateItemCart } from "@/core/utils/cart"
+import toast from "react-hot-toast"
+import Footer from "@/components/layouts/Footer"
+import Image from "@/components/elements/Image"
+import LineDivider from "@/components/elements/LineDivider"
+import { HeartIcon as HeartIconSolid } from "@heroicons/react/24/solid"
+import { useAuth } from "@/core/utils/auth"
+import { HeartIcon } from "@heroicons/react/24/outline"
+import LazyLoad from "react-lazy-load"
+import ProductSimilar from "@/components/products/ProductSimilar"
export async function getServerSideProps( context ) {
- const { slug } = context.query;
- let product = await apiOdoo('GET', '/api/v1/product/' + getIdFromSlug(slug));
+ const { slug } = context.query
+ let product = await apiOdoo('GET', '/api/v1/product/' + getIdFromSlug(slug))
if (product?.length == 1) {
- product = product[0];
- product.description = product.description.replaceAll('<p>', '||p||');
- product.description = product.description.replaceAll('</p>', '||/p||');
- product.description = product.description.replace(/(<([^>]+)>)/gi, ' ');
- product.description = product.description.replaceAll('||p||', '<p>');
- product.description = product.description.replaceAll('||/p||', '</p>');
- product.description = product.description.trim();
+ product = product[0]
+ product.description = product.description.replaceAll('<p>', '||p||')
+ product.description = product.description.replaceAll('</p>', '||/p||')
+ product.description = product.description.replace(/(<([^>]+)>)/gi, ' ')
+ product.description = product.description.replaceAll('||p||', '<p>')
+ product.description = product.description.replaceAll('||/p||', '</p>')
+ product.description = product.description.trim()
}
- return { props: { product } };
+ return { props: { product } }
}
export default function ProductDetail({ product }) {
- const [ auth ] = useAuth();
- const router = useRouter();
- const { slug } = router.query;
- const [selectedVariant, setSelectedVariant] = useState("");
- const [quantity, setQuantity] = useState("1");
+ const [ auth ] = useAuth()
+ const router = useRouter()
+ const { slug } = router.query
+ const [selectedVariant, setSelectedVariant] = useState("")
+ const [quantity, setQuantity] = useState("1")
const [activeVariant, setActiveVariant] = useState({
id: product.id,
code: product.code,
@@ -45,51 +45,52 @@ export default function ProductDetail({ product }) {
stock: product.stock_total,
weight: product.weight,
attributes: '',
- });
+ })
- const [ isAddedToWishlist, setAddedToWishlist ] = useState(false);
+ const [ isAddedToWishlist, setAddedToWishlist ] = useState(false)
+ const [ activeTab, setActiveTab ] = useState('specification')
const addOrDeleteWishlist = async () => {
if (auth) {
await apiOdoo('POST', `/api/v1/user/${auth.id}/wishlist/create-or-delete`, {
product_id: product.id
- });
+ })
if (isAddedToWishlist) {
- toast.success('Berhasil menghapus dari wishlist');
+ toast.success('Berhasil menghapus dari wishlist')
} else {
- toast.success('Berhasil menambahkan ke wishlist');
+ toast.success('Berhasil menambahkan ke wishlist')
}
- setAddedToWishlist(!isAddedToWishlist);
+ setAddedToWishlist(!isAddedToWishlist)
} else {
- toast.error('Login terlebih dahulu untuk melanjutkan');
- router.push('/login');
+ toast.error('Login terlebih dahulu untuk melanjutkan')
+ router.push('/login')
}
- };
+ }
useEffect(() => {
if (auth) {
const checkWishlist = async () => {
- const wishlist = await apiOdoo('GET', `/api/v1/user/${auth.id}/wishlist?product_id=${product.id}`);
- setAddedToWishlist(wishlist.product_total > 0 ? true : false);
+ const wishlist = await apiOdoo('GET', `/api/v1/user/${auth.id}/wishlist?product_id=${product.id}`)
+ setAddedToWishlist(wishlist.product_total > 0 ? true : false)
}
- checkWishlist();
+ checkWishlist()
}
- }, [ auth, product ]);
+ }, [ auth, product ])
useEffect(() => {
if (product.variants.length == 1) {
- setSelectedVariant(product.variants[0].id);
+ setSelectedVariant(product.variants[0].id)
}
- }, [ product ]);
+ }, [ product ])
useEffect(() => {
if (selectedVariant != '') {
let newActiveVariant = product.variants.filter((variant) => {
- return variant.id == selectedVariant;
- });
+ return variant.id == selectedVariant
+ })
if (newActiveVariant.length == 1) {
- newActiveVariant = newActiveVariant[0];
+ newActiveVariant = newActiveVariant[0]
setActiveVariant({
id: newActiveVariant.id,
code: newActiveVariant.code,
@@ -97,55 +98,65 @@ export default function ProductDetail({ product }) {
stock: newActiveVariant.stock,
weight: newActiveVariant.weight,
attributes: newActiveVariant.attributes.join(', '),
- });
+ })
}
}
- }, [selectedVariant, product]);
+ }, [selectedVariant, product])
const onchangeVariant = (e) => {
- setSelectedVariant(e.target.value);
+ setSelectedVariant(e.target.value)
}
const onChangeQuantity = (e) => {
- let inputValue = e.target.value;
- inputValue = parseInt(inputValue);
- inputValue = Math.floor(inputValue);
- setQuantity(inputValue);
+ let inputValue = e.target.value
+ inputValue = parseInt(inputValue)
+ inputValue = Math.floor(inputValue)
+ setQuantity(inputValue)
}
const addItemToCart = () => {
if (product.variant_total > 1 && !selectedVariant) {
- toast.error('Pilih varian terlebih dahulu untuk menambahkan ke keranjang', { duration: 2000 });
- return false;
+ toast.error('Pilih varian terlebih dahulu untuk menambahkan ke keranjang', { duration: 2000 })
+ return false
}
if (quantity > 0) {
- toast.success('Berhasil menambahkan ke keranjang', { duration: 1500 });
- createOrUpdateItemCart(activeVariant.id, parseInt(quantity));
+ toast.success('Berhasil menambahkan ke keranjang', { duration: 1500 })
+ createOrUpdateItemCart(activeVariant.id, parseInt(quantity))
} else {
- toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 });
+ toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 })
}
- return true;
+ return true
}
const checkoutProduct = () => {
if (!auth) {
- toast.error('Login terlebih dahulu untuk melanjutkan', { duration: 2000 });
- router.push('/login');
- return;
+ toast.error('Login terlebih dahulu untuk melanjutkan', { duration: 2000 })
+ router.push('/login')
+ return
}
if (product.variant_total > 1 && !selectedVariant) {
- toast.error('Pilih varian terlebih dahulu untuk melanjutkan pembelian', { duration: 2000 });
- return;
+ toast.error('Pilih varian terlebih dahulu untuk melanjutkan pembelian', { duration: 2000 })
+ return
}
if (quantity < 0) {
- toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 });
- return;
+ toast.error('Jumlah barang yang ditambahkan minimal 1 pcs', { duration: 2000 })
+ return
}
- router.push(`/shop/checkout?product_id=${activeVariant.id}&qty=${quantity}`);
+ router.push(`/shop/checkout?product_id=${activeVariant.id}&qty=${quantity}`)
}
+ const TabButton = ({ children, name }) => (
+ <button
+ type="button"
+ className={`font-medium pb-1 ${activeTab == name ? 'text-red_r-11 border-b border-red_r-10' : 'text-gray_r-11'}`}
+ onClick={() => setActiveTab(name)}
+ >
+ { children }
+ </button>
+ )
+
return (
<>
<Header title={`${product.name} - Indoteknik`}/>
@@ -203,7 +214,7 @@ export default function ProductDetail({ product }) {
product.variants.map((variant) => {
return (
<option key={variant.id} value={variant.id}>{variant.attributes.join(', ')}</option>
- );
+ )
})
) : (
<option key={product.variants[0].id} value={product.variants[0].id}>{product.variants[0].name}</option>
@@ -234,41 +245,42 @@ export default function ProductDetail({ product }) {
<LineDivider />
<div className="p-4">
- <h2 className="font-bold mb-2">Detail Produk</h2>
- <div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">Jumlah Varian</h3>
- <p className="text-gray-800">{product.variant_total} Varian</p>
+ <h2 className="font-bold mb-4">Informasi Produk</h2>
+ <div className="flex gap-x-3 mb-4">
+ <TabButton name="specification">Spesifikasi</TabButton>
+ <TabButton name="description">Deskripsi</TabButton>
+ <TabButton name="information">Info Penting</TabButton>
</div>
- <div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">No. SKU</h3>
- <p className="text-gray-800" id="sku_number">SKU-{activeVariant.id}</p>
+
+ <div className={`border border-gray_r-6 rounded divide-y ${activeTab == 'specification' ? 'block' : 'hidden'}`}>
+ <ProductSpecification label="Jumlah Varian">
+ <p className="text-gray-800">{product.variant_total} Varian</p>
+ </ProductSpecification>
+ <ProductSpecification label="Nomor SKU">
+ <p className="text-gray-800" id="sku_number">SKU-{activeVariant.id}</p>
+ </ProductSpecification>
+ <ProductSpecification label="Part Number">
+ <p className="text-gray-800" id="part_number">{activeVariant.code}</p>
+ </ProductSpecification>
+ <ProductSpecification label="Stok">
+ <div className="flex gap-x-2" id="stock">
+ {activeVariant.stock > 0 ? (activeVariant.stock > 5 && (
+ <>
+ <div className="badge-solid-red">Ready Stock</div>
+ <div className="badge-gray">{activeVariant.stock > 5 ? '> 5' : '< 5'}</div>
+ </>
+ )) : '0'}
+ </div>
+ </ProductSpecification>
+ <ProductSpecification label="Part Number">
+ <p className="text-gray-800" id="weight">{activeVariant.weight > 0 ? activeVariant.weight : '1'} KG</p>
+ </ProductSpecification>
</div>
- <div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">Part Number</h3>
- <p className="text-gray-800" id="part_number">{activeVariant.code}</p>
- </div>
- <div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">Stok</h3>
- <div className="flex gap-x-2" id="stock">
- {activeVariant.stock > 0 ? (activeVariant.stock > 5 && (
- <>
- <div className="badge-solid-red">Ready Stock</div>
- <div className="badge-gray">{activeVariant.stock > 5 ? '> 5' : '< 5'}</div>
- </>
- )) : '0'}
- </div>
- </div>
- <div className="flex py-2 justify-between items-center gap-x-1">
- <h3 className="text-gray-900">Berat Barang</h3>
- <p className="text-gray-800" id="weight">{activeVariant.weight > 0 ? activeVariant.weight : '1'} KG</p>
- </div>
- </div>
-
- <LineDivider />
-
- <div className="p-4">
- <h2 className="font-bold mb-4">Deskripsi Produk</h2>
- <div className="text-gray-800 leading-7" dangerouslySetInnerHTML={{__html: (product.description != '' ? product.description : 'Belum ada deskripsi produk.')}}></div>
+
+ <div
+ className={`text-gray-800 leading-7 ${activeTab == 'description' ? 'block' : 'hidden'}`}
+ dangerouslySetInnerHTML={{__html: (product.description != '' ? product.description : 'Belum ada deskripsi produk.')}}
+ ></div>
</div>
<LineDivider />
@@ -280,5 +292,14 @@ export default function ProductDetail({ product }) {
<Footer />
</Layout>
</>
- );
+ )
+}
+
+const ProductSpecification = ({ children, ...props }) => {
+ return (
+ <div className="flex p-3 justify-between items-center gap-x-1">
+ <h3 className="text-gray-900">{ props.label }</h3>
+ { children }
+ </div>
+ )
} \ No newline at end of file