From 620223f151700bbd91a33d32e2a4c29d4c287e9d Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 6 Feb 2023 12:04:30 +0700 Subject: no message --- src/components/elements/ConfirmAlert.js | 6 +- src/components/elements/Image.js | 21 ++--- src/components/products/ProductSlider.js | 2 +- src/lib/elements/hooks/useBottomPopup.js | 40 ++++++++++ src/lib/elements/hooks/useConfirmAlert.js | 49 ++++++++++++ src/pages/my/address/create.js | 2 +- src/pages/my/transaction/[id].js | 127 +++++++++++++++++++++++++++--- src/pages/my/transactions.js | 102 ++++++++++++++++-------- src/pages/shop/cart.js | 53 +++++-------- src/pages/shop/checkout.js | 2 +- 10 files changed, 308 insertions(+), 96 deletions(-) create mode 100644 src/lib/elements/hooks/useBottomPopup.js create mode 100644 src/lib/elements/hooks/useConfirmAlert.js (limited to 'src') diff --git a/src/components/elements/ConfirmAlert.js b/src/components/elements/ConfirmAlert.js index 27155011..96f4029d 100644 --- a/src/components/elements/ConfirmAlert.js +++ b/src/components/elements/ConfirmAlert.js @@ -4,6 +4,8 @@ const ConfirmAlert = ({ show, onClose, onSubmit, + closeText, + submitText }) => { return ( <> @@ -14,8 +16,8 @@ const ConfirmAlert = ({

{title}

{caption}

- - + +
diff --git a/src/components/elements/Image.js b/src/components/elements/Image.js index 1fedf61c..8981547a 100644 --- a/src/components/elements/Image.js +++ b/src/components/elements/Image.js @@ -1,18 +1,13 @@ -import NextImage from "next/image"; -import { LazyLoadComponent } from "react-lazy-load-image-component"; +import { LazyLoadImage } from "react-lazy-load-image-component"; +import "react-lazy-load-image-component/src/effects/opacity.css"; export default function Image({ src, alt, className = "" }) { return ( - -
- -
-
+ ); } \ No newline at end of file diff --git a/src/components/products/ProductSlider.js b/src/components/products/ProductSlider.js index 6ee31f9b..11fab069 100644 --- a/src/components/products/ProductSlider.js +++ b/src/components/products/ProductSlider.js @@ -19,7 +19,7 @@ export default function ProductSlider({ return ( <> { bannerMode && ( - {products.banner.name} 0 ? 'opacity-20' : 'opacity-100')} /> + {products.banner.name} 0 ? 'opacity-10' : 'opacity-100')} /> ) } { bannerMode && ( diff --git a/src/lib/elements/hooks/useBottomPopup.js b/src/lib/elements/hooks/useBottomPopup.js new file mode 100644 index 00000000..88b72316 --- /dev/null +++ b/src/lib/elements/hooks/useBottomPopup.js @@ -0,0 +1,40 @@ +import { useState } from "react"; +import dynamic from "next/dynamic"; + +const DynamicBottomPopup = dynamic(() => import('@/components/elements/BottomPopup')); + +const useBottomPopup = ({ + title, + children +}) => { + const [ isOpen, setIsOpen ] = useState(false); + const [ dataPopup, setDataPopup ] = useState(null); + + const closePopup = () => { + setIsOpen(false); + setDataPopup(null); + }; + const openPopup = ( data = null ) => { + setIsOpen(true); + setDataPopup(data); + }; + + const BottomPopup = ( + + { children(dataPopup) } + + ); + + return { + dataPopup, + BottomPopup, + closePopup, + openPopup + } +} + +export default useBottomPopup; \ No newline at end of file diff --git a/src/lib/elements/hooks/useConfirmAlert.js b/src/lib/elements/hooks/useConfirmAlert.js new file mode 100644 index 00000000..4975c57d --- /dev/null +++ b/src/lib/elements/hooks/useConfirmAlert.js @@ -0,0 +1,49 @@ +import { useState } from "react"; +import dynamic from "next/dynamic"; + +const DynamicConfirmAlert = dynamic(() => import('@/components/elements/ConfirmAlert')); + +const useConfirmAlert = ({ + title, + caption, + closeText, + submitText, + onSubmit, +}) => { + const [ isOpen, setIsOpen ] = useState(false); + const [ data, setData ] = useState(null); + + const closeConfirmAlert = () => { + setIsOpen(false); + setData(null); + }; + const openConfirmAlert = ( data = null ) => { + setIsOpen(true); + setData(data); + }; + const handleSubmit = async () => { + await onSubmit(data); + closeConfirmAlert(); + }; + + const ConfirmAlert = ( + + ); + + return { + isOpen, + closeConfirmAlert, + openConfirmAlert, + ConfirmAlert + }; +} + +export default useConfirmAlert; \ No newline at end of file diff --git a/src/pages/my/address/create.js b/src/pages/my/address/create.js index 4c7a8130..42cd117c 100644 --- a/src/pages/my/address/create.js +++ b/src/pages/my/address/create.js @@ -53,7 +53,7 @@ export default function CreateAddress() { } = useForm({ resolver: yupResolver(validationSchema), defaultValues - }); + }); const [ cities, setCities ] = useState([]); const [ districts, setDistricts ] = useState([]); diff --git a/src/pages/my/transaction/[id].js b/src/pages/my/transaction/[id].js index 428d71fb..d1ecbd7f 100644 --- a/src/pages/my/transaction/[id].js +++ b/src/pages/my/transaction/[id].js @@ -2,13 +2,12 @@ import AppBar from "@/components/layouts/AppBar"; import Layout from "@/components/layouts/Layout"; import LineDivider from "@/components/elements/LineDivider"; import WithAuth from "@/components/auth/WithAuth"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import apiOdoo from "@/core/utils/apiOdoo"; import { useRouter } from "next/router"; import { useAuth } from "@/core/utils/auth"; import VariantCard from "@/components/variants/VariantCard"; import currencyFormat from "@/core/utils/currencyFormat"; -import Disclosure from "@/components/elements/Disclosure"; import DescriptionRow from "@/components/elements/DescriptionRow"; import { TransactionDetailAddress } from "@/components/transactions/TransactionDetail"; import { SkeletonList } from "@/components/elements/Skeleton"; @@ -16,6 +15,10 @@ import Link from "@/components/elements/Link"; import { ChevronRightIcon } from "@heroicons/react/24/outline"; import Alert from "@/components/elements/Alert"; import TransactionStatusBadge from "@/components/transactions/TransactionStatusBadge"; +import useConfirmAlert from "@/lib/elements/hooks/useConfirmAlert"; +import { toast } from "react-hot-toast"; +import useBottomPopup from "@/lib/elements/hooks/useBottomPopup"; +import getFileBase64 from "@/core/utils/getFileBase64"; export default function DetailTransaction() { const router = useRouter(); @@ -23,16 +26,94 @@ export default function DetailTransaction() { const [ auth ] = useAuth(); const [ transaction, setTransaction ] = useState(null); - useEffect(() => { + const loadTransaction = useCallback(async () => { if (auth && id) { - const loadTransaction = async () => { - const dataTransaction = await apiOdoo('GET', `/api/v1/partner/${auth?.partner_id}/sale_order/${id}`); - setTransaction(dataTransaction); - } - loadTransaction(); + const dataTransaction = await apiOdoo('GET', `/api/v1/partner/${auth?.partner_id}/sale_order/${id}`); + setTransaction(dataTransaction); } }, [ auth, id ]); + useEffect(() => { + loadTransaction(); + }, [ loadTransaction ]); + + const submitCancelTransaction = async (data) => { + const isCancelled = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/${data.id}/cancel`); + if (isCancelled) { + toast.success('Berhasil batalkan transaksi'); + loadTransaction(); + } + } + + const { + openConfirmAlert, + ConfirmAlert + } = useConfirmAlert({ + title: 'Batalkan Transaksi', + caption: 'Apakah anda yakin untuk membatalkan transaksi?', + closeText: 'Tidak', + submitText: 'Iya, batalkan', + onSubmit: submitCancelTransaction + }); + + const UploadPurchaseOrder = () => { + const nameRef = useRef(''); + const fileRef = useRef(''); + + const submitUploadPurchaseOrder = async (e) => { + e.preventDefault(); + const file = fileRef.current.files[0]; + const name = nameRef.current.value; + if (file.size > 5000000) { + toast.error('Maksimal ukuran file adalah 5MB', { + position: 'bottom-center' + }); + return; + } + const parameter = { + name, + file: await getFileBase64(file) + }; + const isUploaded = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/${transaction.id}/upload_po`, parameter); + if (isUploaded) { + toast.success('Berhasil upload PO'); + loadTransaction(); + closePopup(); + } + }; + + return ( +
+
+ + +
+
+ + +
+ +
+ ); + } + + const { + closePopup, + BottomPopup, + openPopup + } = useBottomPopup({ + title: 'Upload PO', + children: UploadPurchaseOrder + }); + + const downloadPurchaseOrder = () => { + + }; + + const uploadPurchaseOrder = () => { + openPopup(); + }; + return ( @@ -49,9 +130,6 @@ export default function DetailTransaction() { { transaction?.name } - - { transaction?.purchase_order_name || '-' } - { transaction?.payment_term } @@ -65,6 +143,24 @@ export default function DetailTransaction() { +
+ + { transaction?.purchase_order_name || '-' } + +
+

Dokumen PO

+ +
+
+ + +

Detail Produk

@@ -115,6 +211,13 @@ export default function DetailTransaction() { Belum ada Invoice ) } +
@@ -123,6 +226,8 @@ export default function DetailTransaction() { ) } + { ConfirmAlert } + { BottomPopup }
); diff --git a/src/pages/my/transactions.js b/src/pages/my/transactions.js index a03ff007..6eb0fb4e 100644 --- a/src/pages/my/transactions.js +++ b/src/pages/my/transactions.js @@ -1,9 +1,8 @@ import { useRouter } from "next/router"; import AppBar from "@/components/layouts/AppBar"; -import BottomPopup from "@/components/elements/BottomPopup"; import Layout from "@/components/layouts/Layout"; import WithAuth from "@/components/auth/WithAuth"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useAuth } from "@/core/utils/auth"; import apiOdoo from "@/core/utils/apiOdoo"; import currencyFormat from "@/core/utils/currencyFormat"; @@ -12,6 +11,9 @@ import Link from "@/components/elements/Link"; import Pagination from "@/components/elements/Pagination"; import Alert from "@/components/elements/Alert"; import TransactionStatusBadge from "@/components/transactions/TransactionStatusBadge"; +import { toast } from "react-hot-toast"; +import useConfirmAlert from "@/lib/elements/hooks/useConfirmAlert"; +import useBottomPopup from "@/lib/elements/hooks/useBottomPopup"; export default function Transactions() { const [ auth ] = useAuth(); @@ -22,31 +24,30 @@ export default function Transactions() { } = router.query; const [ transactions, setTransactions ] = useState([]); - const [ activePopupId, setActivePopupId ] = useState(null); const [ pageCount, setPageCount ] = useState(0); const [ isLoading, setIsLoading ] = useState(true); const searchQueryRef = useRef(); + const loadTransactions = useCallback(async () => { + if (auth) { + const limit = 10; + let offset = (page - 1) * 10; + let queryParams = [`limit=${limit}`, `offset=${offset}`]; + if (q) queryParams.push(`name=${q}`); + queryParams = queryParams.join('&'); + queryParams = queryParams ? '?' + queryParams : ''; + + const dataTransactions = await apiOdoo('GET', `/api/v1/partner/${auth.partner_id}/sale_order${queryParams}`); + setTransactions(dataTransactions); + setPageCount(Math.ceil(dataTransactions?.sale_order_total / limit)); + setIsLoading(false); + }; + }, [ auth, q, page ]); useEffect(() => { - const loadTransactions = async () => { - if (auth) { - const limit = 10; - let offset = (page - 1) * 10; - let queryParams = [`limit=${limit}`, `offset=${offset}`]; - if (q) queryParams.push(`name=${q}`); - queryParams = queryParams.join('&'); - queryParams = queryParams ? '?' + queryParams : ''; - - const dataTransactions = await apiOdoo('GET', `/api/v1/partner/${auth.partner_id}/sale_order${queryParams}`); - setTransactions(dataTransactions); - setPageCount(Math.ceil(dataTransactions?.sale_order_total / limit)); - setIsLoading(false); - }; - } loadTransactions(); - }, [ auth, q, page ]); + }, [ loadTransactions ]); const actionSearch = (e) => { e.preventDefault(); @@ -57,6 +58,51 @@ export default function Transactions() { router.push(`/my/transactions${queryParams}`); }; + const childrenPopup = (data) => ( +
+ + +
+ ); + + const { + closePopup, + openPopup, + BottomPopup + } = useBottomPopup({ + title: 'Lainnya', + children: childrenPopup + }); + + const submitCancelTransaction = async (data) => { + const isCancelled = await apiOdoo('POST', `/api/v1/partner/${auth.partner_id}/sale_order/${data.id}/cancel`); + if (isCancelled) { + toast.success('Berhasil batalkan transaksi'); + loadTransactions(); + } + } + + const { + openConfirmAlert, + ConfirmAlert + } = useConfirmAlert({ + title: 'Batalkan Transaksi', + caption: 'Apakah anda yakin untuk membatalkan transaksi?', + closeText: 'Tidak', + submitText: 'Iya, batalkan', + onSubmit: submitCancelTransaction + }); + return ( @@ -90,7 +136,7 @@ export default function Transactions() {
- setActivePopupId(transaction.id)} /> + openPopup(transaction)} />
@@ -122,19 +168,9 @@ export default function Transactions() {
- - { transactions?.sale_orders?.length > 0 && ( - setActivePopupId(null)} - > -
-

Download Quotation

-

Batalkan Transaksi

-
-
- ) } + + { ConfirmAlert } + { BottomPopup }
); diff --git a/src/pages/shop/cart.js b/src/pages/shop/cart.js index aaf67e1f..d8327a10 100644 --- a/src/pages/shop/cart.js +++ b/src/pages/shop/cart.js @@ -20,7 +20,6 @@ import apiOdoo from "@/core/utils/apiOdoo"; import currencyFormat from "@/core/utils/currencyFormat"; // Components -import ConfirmAlert from "@/components/elements/ConfirmAlert"; import Image from "@/components/elements/Image"; import Layout from "@/components/layouts/Layout"; import Link from "@/components/elements/Link"; @@ -29,6 +28,7 @@ import Spinner from "@/components/elements/Spinner"; import AppBar from "@/components/layouts/AppBar"; import ProgressBar from "@/components/elements/ProgressBar"; import LineDivider from "@/components/elements/LineDivider"; +import useConfirmAlert from "@/lib/elements/hooks/useConfirmAlert"; export default function Cart() { const router = useRouter(); @@ -37,10 +37,6 @@ export default function Cart() { const [totalPriceBeforeTax, setTotalPriceBeforeTax] = useState(0); const [totalTaxAmount, setTotalTaxAmount] = useState(0); const [totalDiscountAmount, setTotalDiscountAmount] = useState(0); - const [deleteConfirmation, setDeleteConfirmation] = useState({ - productId: null, - show: false - }); useEffect(() => { const getProducts = async () => { @@ -117,47 +113,36 @@ export default function Cart() { updateCart(productId, quantity); } - const showDeleteConfirmation = (productId) => { - setDeleteConfirmation({ - productId: productId, - show: true - }); - } - - const hideDeleteConfirmation = () => { - setDeleteConfirmation({ - productId: null, - show: false - }); + const toggleProductSelected = (productId) => { + let productIndexToUpdate = products.findIndex((product) => product.id == productId); + let productsToUpdate = products; + productsToUpdate[productIndexToUpdate].selected = !productsToUpdate[productIndexToUpdate].selected; + setProducts([...productsToUpdate]); } - const deleteItem = () => { - const productId = deleteConfirmation.productId; + const deleteItem = (productId) => { let productIndexToUpdate = products.findIndex((product) => product.id == productId); let productsToUpdate = products; productsToUpdate.splice(productIndexToUpdate, 1); setProducts([...productsToUpdate]); deleteItemCart(productId); - hideDeleteConfirmation(); toast.success('Berhasil menghapus 1 barang dari keranjang', { duration: 1500 }); } - const toggleProductSelected = (productId) => { - let productIndexToUpdate = products.findIndex((product) => product.id == productId); - let productsToUpdate = products; - productsToUpdate[productIndexToUpdate].selected = !productsToUpdate[productIndexToUpdate].selected; - setProducts([...productsToUpdate]); - } + const { + openConfirmAlert, + ConfirmAlert + } = useConfirmAlert({ + title: 'Hapus barang dari keranjang', + caption:'Apakah anda yakin menghapus barang dari keranjang', + closeText: 'Batal', + submitText: 'Hapus', + onSubmit: deleteItem + }) return ( <> - + { ConfirmAlert } @@ -235,7 +220,7 @@ export default function Cart() {
diff --git a/src/pages/shop/checkout.js b/src/pages/shop/checkout.js index 8a540bcd..8a52486c 100644 --- a/src/pages/shop/checkout.js +++ b/src/pages/shop/checkout.js @@ -195,7 +195,7 @@ export default function Checkout() { { selectedAddress.shipping && (
-
{ selectedAddress.invoicing.type.charAt(0).toUpperCase() + selectedAddress.invoicing.type.slice(1) + ' Address' }
+
{ selectedAddress.shipping.type.charAt(0).toUpperCase() + selectedAddress.shipping.type.slice(1) + ' Address' }

{ selectedAddress.shipping.name }

{ selectedAddress.shipping.mobile }

{ selectedAddress.shipping.street }, { selectedAddress.shipping?.city?.name }

-- cgit v1.2.3