summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <rafizadanly@gmail.com>2022-12-15 16:37:45 +0700
committerRafi Zadanly <rafizadanly@gmail.com>2022-12-15 16:37:45 +0700
commit4a615aae5f29ed8c0ad3631a8510df57b80cae94 (patch)
treea3dced877ba73e4cd5907076cbcfa2fe369bc33d
parent2c58745807110ba234e1a9ec939457e641fff469 (diff)
feature checbox add to process in cart
-rw-r--r--src/pages/shop/cart.js138
-rw-r--r--src/pages/shop/product/[slug].js8
-rw-r--r--src/styles/globals.css53
3 files changed, 158 insertions, 41 deletions
diff --git a/src/pages/shop/cart.js b/src/pages/shop/cart.js
index 5e7ff822..653f1ac4 100644
--- a/src/pages/shop/cart.js
+++ b/src/pages/shop/cart.js
@@ -2,18 +2,23 @@ import { useEffect, useState } from "react";
import Header from "../../components/Header";
import Layout from "../../components/Layout";
import Link from "../../components/Link";
-import { createOrUpdateItemCart, deleteItemCart, getCart, getItemCart } from "../../helpers/cart";
+import { createOrUpdateItemCart, deleteItemCart, getCart } from "../../helpers/cart";
import ChevronLeftIcon from "../../icons/chevron-left.svg";
import MinusIcon from "../../icons/minus.svg";
import PlusIcon from "../../icons/plus.svg";
+import TrashIcon from "../../icons/trash.svg";
import { LazyLoadImage } from "react-lazy-load-image-component";
-
-import 'react-lazy-load-image-component/src/effects/blur.css';
import apiOdoo from "../../helpers/apiOdoo";
import currencyFormat from "../../helpers/currencyFormat";
+import 'react-lazy-load-image-component/src/effects/blur.css';
+import { createSlug } from "../../helpers/slug";
+
export default function Cart() {
const [products, setProducts] = useState([]);
+ const [totalPriceBeforeTax, setTotalPriceBeforeTax] = useState(0);
+ const [totalTaxAmount, setTotalTaxAmount] = useState(0);
+ const [totalDiscountAmount, setTotalDiscountAmount] = useState(0);
const getProducts = async () => {
let cart = getCart();
@@ -23,7 +28,8 @@ export default function Cart() {
let dataProducts = await apiOdoo('GET', `/api/v1/product_variant/${productIds}`);
dataProducts = dataProducts.map((product) => ({
...product,
- quantity: cart[product.id].quantity
+ quantity: cart[product.id].quantity,
+ to_process: false
}));
setProducts(dataProducts);
}
@@ -33,13 +39,31 @@ export default function Cart() {
getProducts();
}, []);
+ useEffect(() => {
+ const productsToProcess = products.filter((product) => product.to_process == true);
+ if (products.length > 0) {
+
+ let calculateTotalPriceBeforeTax = 0;
+ let calculateTotalTaxAmount = 0;
+ let calculateTotalDiscountAmount = 0;
+ productsToProcess.forEach(product => {
+ let priceBeforeTax = product.price.price / 1.11;
+ calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity;
+ calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity;
+ calculateTotalDiscountAmount += (product.price.price - product.price.price_discount) * product.quantity;
+ });
+ setTotalPriceBeforeTax(calculateTotalPriceBeforeTax);
+ setTotalTaxAmount(calculateTotalTaxAmount);
+ setTotalDiscountAmount(calculateTotalDiscountAmount);
+ }
+ }, [products]);
+
const updateCart = (productId, quantity) => {
let productIndexToUpdate = products.findIndex((product) => product.id == productId);
if (quantity != '') createOrUpdateItemCart(productId, quantity);
- setProducts((products) => {
- products[productIndexToUpdate].quantity = quantity;
- return [...products];
- });
+ let productsToUpdate = products;
+ productsToUpdate[productIndexToUpdate].quantity = quantity;
+ setProducts([...productsToUpdate]);
};
const blurQuantity = (productId, quantity) => {
@@ -49,7 +73,9 @@ export default function Cart() {
const updateQuantity = (productId, quantity) => {
quantity = quantity == '' ? '' : parseInt(quantity);
- updateCart(productId, quantity);
+ if (quantity > 0) {
+ updateCart(productId, quantity);
+ }
};
const plusQuantity = (productId) => {
@@ -61,15 +87,22 @@ export default function Cart() {
const minusQuantity = (productId) => {
let productIndexToUpdate = products.findIndex((product) => product.id == productId);
let quantity = products[productIndexToUpdate].quantity - 1;
- if (quantity <= 0) {
- deleteItemCart(productId);
- setProducts((products) => {
- products.splice(productIndexToUpdate, 1);
- return [...products];
- });
- } else {
- updateCart(productId, quantity);
- }
+ updateCart(productId, quantity);
+ }
+
+ const deleteItem = (productId) => {
+ let productIndexToUpdate = products.findIndex((product) => product.id == productId);
+ let productsToUpdate = products;
+ productsToUpdate.splice(productIndexToUpdate, 1);
+ setProducts([...productsToUpdate]);
+ deleteItemCart(productId);
+ }
+
+ const toggleProductToProcess = (productId) => {
+ let productIndexToUpdate = products.findIndex((product) => product.id == productId);
+ let productsToUpdate = products;
+ productsToUpdate[productIndexToUpdate].to_process = !productsToUpdate[productIndexToUpdate].to_process;
+ setProducts([...productsToUpdate]);
}
return (
@@ -86,14 +119,14 @@ export default function Cart() {
<div className="h-0.5 w-full bg-gray_r-7"></div>
</div>
<div className="flex gap-x-2 items-center">
- <div className="bg-gray_r-3 leading-none p-2 rounded-full w-7 text-center text-gray_r-11 text-caption-2">2</div>
+ <div className="bg-gray_r-4 leading-none p-2 rounded-full w-7 text-center text-gray_r-11 text-caption-2">2</div>
<p className="font-medium text-gray_r-11 text-caption-2">Pembayaran</p>
</div>
<div className="flex-1 flex items-center">
<div className="h-0.5 w-full bg-gray_r-7"></div>
</div>
<div className="flex gap-x-2 items-center">
- <div className="bg-gray_r-3 leading-none p-2 rounded-full w-7 text-center text-gray_r-11 text-caption-2">3</div>
+ <div className="bg-gray_r-4 leading-none p-2 rounded-full w-7 text-center text-gray_r-11 text-caption-2">3</div>
<p className="font-medium text-gray_r-11 text-caption-2">Selesai</p>
</div>
</div>
@@ -110,14 +143,18 @@ export default function Cart() {
{/* [End] Title */}
{/* [Start] Product List */}
- <div className="flex flex-col gap-y-6">
+ <div className="flex flex-col gap-y-6 mb-8">
{products.map((product, index) => (
<div className="flex gap-x-3" key={index}>
- <div className="w-4/12">
+ <div className="w-4/12 flex items-center gap-x-2">
+ <button
+ className={'p-2 rounded border ' + (product.to_process ? 'border-yellow_r-9 bg-yellow_r-9' : 'border-gray_r-6')}
+ onClick={() => toggleProductToProcess(product.id)}
+ ></button>
<LazyLoadImage effect="blur" src={product.parent.image ? product.parent.image : '/images/noimage.jpeg'} alt={product.parent.name} className="object-contain object-center border border-gray_r-6 h-32 w-full rounded-md" />
</div>
<div className="w-8/12 flex flex-col">
- <Link href="/" className="product-card__title wrap-line-ellipsis-2">
+ <Link href={'/shop/product/' + createSlug(product.parent.name, product.parent.id)} className="product-card__title wrap-line-ellipsis-2">
{product.parent.name}
</Link>
<p className="text-caption-1 text-gray_r-11 mt-1">{product.code ? product.code : '-'}</p>
@@ -134,17 +171,27 @@ export default function Cart() {
<div className="flex items-center">
<p className="mr-auto text-caption-1 text-gray_r-12 font-bold">{currencyFormat(product.quantity * product.price.price_discount)}</p>
<div className="flex gap-x-2">
- <button className="btn-light p-1 rounded-full" onClick={() => minusQuantity(product.id)}>
- <MinusIcon className="stroke-gray_r-12 w-3"/>
+ <button
+ className="btn-red p-1 rounded"
+ onClick={() => deleteItem(product.id)}
+ >
+ <TrashIcon className="stroke-red_r-12 w-3"/>
+ </button>
+ <button
+ className="btn-light p-1 rounded"
+ disabled={product.quantity == 1}
+ onClick={() => minusQuantity(product.id)}
+ >
+ <MinusIcon className={'stroke-gray_r-12 w-3' + (product.quantity == 1 ? ' stroke-gray_r-11' : '')}/>
</button>
<input
type="number"
- className="bg-transparent border-none w-4 text-center outline-none"
+ className="bg-transparent border-none w-6 text-center outline-none"
onBlur={(e) => blurQuantity(product.id, e.target.value)}
onChange={(e) => updateQuantity(product.id, e.target.value)}
value={product.quantity}
/>
- <button className="btn-light p-1 rounded-full" onClick={() => plusQuantity(product.id)}>
+ <button className="btn-light p-1 rounded" onClick={() => plusQuantity(product.id)}>
<PlusIcon className="stroke-gray_r-12 w-3"/>
</button>
</div>
@@ -155,6 +202,43 @@ export default function Cart() {
</div>
{/* [End] Product List */}
+ {/* [Start] Review Order */}
+ <div className="p-4 border border-gray_r-6 rounded-md mb-4">
+ <h2>Ringkasan Pesanan</h2>
+ <hr className="my-4 border-gray_r-6"/>
+ <div className="flex flex-col gap-y-4">
+ <div className="flex gap-x-2 justify-between">
+ <p>Harga Sebelum PPN</p>
+ <p className="font-medium">{currencyFormat(totalPriceBeforeTax)}</p>
+ </div>
+ <div className="flex gap-x-2 justify-between">
+ <p>PPN 11%</p>
+ <p className="font-medium">{currencyFormat(totalTaxAmount)}</p>
+ </div>
+ <div className="flex gap-x-2 justify-between">
+ <p>Total Diskon</p>
+ <p className="font-medium text-red_r-11">- {currencyFormat(totalDiscountAmount)}</p>
+ </div>
+ </div>
+ <hr className="my-4 border-gray_r-6"/>
+ <div className="flex gap-x-2 justify-between mb-4">
+ <p>Total Harga</p>
+ <p className="font-medium text-yellow_r-11">{currencyFormat(totalPriceBeforeTax + totalTaxAmount - totalDiscountAmount)}</p>
+ </div>
+ <p className="text-caption-2 text-gray_r-10 mb-2">*) Belum termasuk biaya pengiriman</p>
+ <p className="text-caption-2 text-gray_r-10 leading-5">
+ Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui <Link href="/">Syarat & Ketentuan</Link> yang berlaku
+ </p>
+ </div>
+ {/* [End] Review Order */}
+
+ {/* [Start] Submit Button */}
+ <div className="flex gap-x-3">
+ <button className="flex-1 btn-light">Quotation (1)</button>
+ <button className="flex-1 btn-yellow">Bayar (1)</button>
+ </div>
+ {/* [End] Submit Button */}
+
</div>
</Layout>
</>
diff --git a/src/pages/shop/product/[slug].js b/src/pages/shop/product/[slug].js
index cabda175..9bb76fb6 100644
--- a/src/pages/shop/product/[slug].js
+++ b/src/pages/shop/product/[slug].js
@@ -140,7 +140,13 @@ export default function ProductDetail({ product }) {
<div className="flex gap-x-2 mt-2">
<button className="btn-light w-full">+ Quotation</button>
- <button className="btn-yellow w-full" onClick={addItemToCart} disabled={(product.lowest_price.price == 0 ? true : false)}>+ Keranjang</button>
+ <button
+ className="btn-yellow w-full"
+ onClick={addItemToCart}
+ disabled={(product.lowest_price.price == 0 ? true : false)}
+ >
+ + Keranjang
+ </button>
</div>
<div className="mt-10">
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 3ecf04b8..1224d661 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -14,6 +14,16 @@ html, body {
}
@layer base {
+ input[type="number"]::-webkit-inner-spin-button,
+ input[type="number"]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+ }
+
+ input[type=number] {
+ -moz-appearance:textfield;
+ }
+
h1, .h1 {
@apply
text-h-md
@@ -104,34 +114,48 @@ html, body {
;
}
- .btn-yellow {
- @apply
+ .btn-yellow,
+ .btn-light,
+ .btn-red {
+ @apply
block
w-fit
p-3
- bg-yellow_r-9
- border-yellow_r-9
rounded
border
text-center
+ font-medium
+ ease-linear
+ duration-150
+ ;
+ }
+
+ .btn-yellow {
+ @apply
+ bg-yellow_r-9
+ border-yellow_r-9
disabled:text-gray_r-10
disabled:bg-yellow_r-7
disabled:border-yellow_r-7
- ease-linear
- duration-150
+ ;
+ }
+
+ .btn-red {
+ @apply
+ bg-red_r-3
+ border-red_r-6
+ text-red_r-12
+ disabled:text-red_r-10
+ disabled:bg-red_r-6
;
}
.btn-light {
@apply
- block
- w-fit
- p-3
bg-gray_r-3
border-gray_r-6
- rounded
- border
- text-center
+ disabled:text-gray_r-10
+ disabled:bg-gray_r-6
;
}
@@ -299,7 +323,10 @@ html, body {
}
.lazy-load-image-background {
- @apply !block;
+ @apply
+ !block
+ w-full
+ ;
}
.swiper-pagination-bullet-active {