summaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/_app.js7
-rw-r--r--src/pages/index.js12
-rw-r--r--src/pages/shop/product/[slug].js172
3 files changed, 191 insertions, 0 deletions
diff --git a/src/pages/_app.js b/src/pages/_app.js
new file mode 100644
index 00000000..1e1cec92
--- /dev/null
+++ b/src/pages/_app.js
@@ -0,0 +1,7 @@
+import '../styles/globals.css'
+
+function MyApp({ Component, pageProps }) {
+ return <Component {...pageProps} />
+}
+
+export default MyApp
diff --git a/src/pages/index.js b/src/pages/index.js
new file mode 100644
index 00000000..57f96ec9
--- /dev/null
+++ b/src/pages/index.js
@@ -0,0 +1,12 @@
+import { useEffect, useState } from "react";
+import Header from "../components/header";
+
+export default function Home() {
+ const [product, setProduct] = useState({});
+
+ return (
+ <>
+ <Header />
+ </>
+ )
+}
diff --git a/src/pages/shop/product/[slug].js b/src/pages/shop/product/[slug].js
new file mode 100644
index 00000000..519f8160
--- /dev/null
+++ b/src/pages/shop/product/[slug].js
@@ -0,0 +1,172 @@
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import Header from "../../../components/header";
+import ProductCard from "../../../components/productCard";
+import { getOdoo } from "../../../helpers/apiOdoo";
+import { createSlug, getId } from "../../../helpers/slug";
+import currencyFormat from "../../../helpers/currencyFormat";
+import Head from "next/head";
+import { Swiper, SwiperSlide } from "swiper/react";
+
+import 'swiper/css';
+
+
+export async function getServerSideProps(context) {
+ const { slug } = context.query;
+ let product = await getOdoo('/api/v1/product/' + getId(slug));
+ product = product[0];
+
+ const similarProducts = await getOdoo(`/api/v1/product/${getId(slug)}/similar?limit=20`);
+
+ return {props: {product, similarProducts}};
+}
+
+export default function ProductDetail({product, similarProducts}) {
+ 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,
+ price: product.lowest_price,
+ stock: product.stock_total,
+ weight: product.weight,
+ attributes: '',
+ });
+
+ useEffect(() => {
+ if (product.variants.length == 1) {
+ setSelectedVariant(product.variants[0].id);
+ }
+ }, [product.variants]);
+
+ useEffect(() => {
+ if (selectedVariant != '') {
+ let newActiveVariant = product.variants.filter((variant) => {
+ return variant.id == selectedVariant;
+ });
+
+ if (newActiveVariant.length == 1) {
+ newActiveVariant = newActiveVariant[0];
+ setActiveVariant({
+ id: newActiveVariant.id,
+ code: newActiveVariant.code,
+ price: newActiveVariant.price,
+ stock: newActiveVariant.stock,
+ weight: newActiveVariant.weight,
+ attributes: newActiveVariant.attributes.join(', '),
+ });
+ }
+ }
+ }, [selectedVariant])
+
+ let onchangeVariant = (e) => {
+ setSelectedVariant(e.target.value);
+ setQuantity("1");
+ }
+
+ let addToCart = () => {
+ return true;
+ }
+
+ return (
+ <>
+ <Head>
+ <title>{product.name + '- Indoteknik'}</title>
+ </Head>
+ <Header />
+ <div className="px-4 pt-5 pb-10">
+ <img src={product.image} alt={product.name} className="border border-gray-300 rounded-md mb-4 w-full h-[300px] object-contain object-center" />
+ <Link href={'/shop/brands/' + createSlug(product.manufacture.name, product.manufacture.id)}>
+ {product.manufacture.name || '-'}
+ </Link>
+ <h1 className="mb-3">{product.name}{activeVariant.attributes != '' ? ' - ' + activeVariant.attributes : ''}</h1>
+
+ {product.variant_total > 1 && selectedVariant == "" ? (
+ <p className="text-xs text-gray-800 mb-1">Harga mulai dari:</p>
+ ) : ''}
+
+ {product.lowest_price.discount_percentage > 0 ? (
+ <div className="flex gap-x-1 items-center">
+ <span className="badge-yellow">{activeVariant.price.discount_percentage}%</span>
+ <p className="text-xs text-gray-800 line-through">{currencyFormat(activeVariant.price.price)}</p>
+ </div>
+ ) : ''}
+
+ {product.lowest_price.price > 0 ? (
+ <p className="text-lg text-gray-900 font-semibold">{currencyFormat(activeVariant.price.price_discount)}</p>
+ ) : (
+ <p className="text-gray-800">Dapatkan harga terbaik, <a href="">hubungi kami.</a></p>
+ )}
+
+ <div className="flex gap-x-2 mt-5">
+ <div className="w-9/12">
+ <label className="form-label">Pilih: <span className="text-gray-800">{product.variant_total} Varian</span></label>
+ <select name="variant" className="form-input" value={selectedVariant} onChange={onchangeVariant} >
+ <option value="" disabled={selectedVariant != "" ? true : false}>Pilih Varian...</option>
+ {product.variants.length > 1 ? (
+ 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>
+ )}
+ </select>
+ </div>
+ <div className="w-3/12">
+ <label htmlFor="quantity" className="form-label">Jumlah</label>
+ <input type="number" name="quantity" id="quantity" className="form-input text-center is-invalid" value={quantity} onChange={(e) => setQuantity(e.target.value)} />
+ </div>
+ </div>
+
+ <div className="flex gap-x-2 mt-2">
+ <button className="btn-light w-full" >+ Quotation</button>
+ <button className="btn-primary w-full" onClick={addToCart} disabled={(product.lowest_price.price == 0 ? true : false)}>+ Keranjang</button>
+ </div>
+
+ <div className="mt-10">
+ <h2 className="h1 mb-2">Detail Produk</h2>
+ <div className="flex py-2 justify-between items-center gap-x-1 border-b border-gray-300">
+ <h3 className="text-gray-900">Jumlah Varian</h3>
+ <p className="text-gray-800">{product.variant_total} Varian</p>
+ </div>
+ <div className="flex py-2 justify-between items-center gap-x-1 border-b border-gray-300">
+ <h3 className="text-gray-900">Nomor SKU</h3>
+ <p className="text-gray-800" id="sku_number">SKU-{activeVariant.id}</p>
+ </div>
+ <div className="flex py-2 justify-between items-center gap-x-1 border-b border-gray-300">
+ <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 border-b border-gray-300">
+ <h3 className="text-gray-900">Stok</h3>
+ <p className="text-gray-800" id="stock">
+ {activeVariant.stock > 0 ? (activeVariant.stock > 5 ? 'Lebih dari 5' : 'Kurang dari 5') : '0'}
+ </p>
+ </div>
+ <div className="flex py-2 justify-between items-center gap-x-1 border-b border-gray-300">
+ <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>
+
+ <div className="mt-10">
+ <h2 className="h1 mb-4">Deskripsi Produk</h2>
+ <div className="text-gray-800 leading-7" dangerouslySetInnerHTML={{__html: (product.description.trim() != '' ? product.description.replaceAll(/<*b>/g, '') : 'Belum ada deskripsi produk.')}}></div>
+ </div>
+
+ <div className="mt-10">
+ <h2 className="h1 mb-4">Produk Lainnya</h2>
+ <Swiper freeMode={true} slidesPerView={2.15} spaceBetween={8} loop={true}>
+ {similarProducts.products.map((product, index) => (<SwiperSlide key={index}><ProductCard data={product} /></SwiperSlide>))}
+ </Swiper>
+ </div>
+
+ </div>
+ </>
+ );
+} \ No newline at end of file