From 52a75ff081226c487b0e7f0bb977b936c2d68026 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 23 Dec 2021 21:31:37 +0700 Subject: [PATCH 1/8] feat: move upload into modal --- src/pages/Product/Product.js | 175 +++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 41 deletions(-) diff --git a/src/pages/Product/Product.js b/src/pages/Product/Product.js index 3f87bcd..6e77e97 100644 --- a/src/pages/Product/Product.js +++ b/src/pages/Product/Product.js @@ -1,6 +1,6 @@ import React, {useContext, useEffect, useState} from "react"; -import {Button, Card, Col, Input, message, Row, Upload} from "antd"; -import {FilterOutlined, LoadingOutlined, UploadOutlined,} from "@ant-design/icons"; +import {Button, Card, Col, Form, Input, message, Modal, Row, Select, Upload} from "antd"; +import {FilterOutlined, PlusOutlined, UploadOutlined,} from "@ant-design/icons"; import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import {useStore} from "../../utils/useStore"; import {observer} from "mobx-react-lite"; @@ -9,15 +9,22 @@ import {LINKS} from "../../routes/app"; import {ModalLoaderContext} from "../../utils/modal"; const {Search} = Input; +const {Option} = Select; export const Product = observer(() => { const store = useStore(); const modalLoader = useContext(ModalLoaderContext); const [loading, setLoading] = useState(false); + const [visibleModalUpload, setVisibleModalUpload] = useState(false); + const [excel, setExcel] = useState(""); + const [fileList, setFileList] = useState([]); + const [form] = Form.useForm(); useEffect(() => { const init = async () => { try { + store.supplier.page = 0; + store.supplier.pageSize = 1000; modalLoader.setLoading(true); await Promise.allSettled([ store.supplier.getData(), @@ -37,6 +44,10 @@ export const Product = observer(() => { }; init(); + + return () => { + store.supplier.pageSize = 10; + }; }, []); const routeData = [ @@ -73,16 +84,21 @@ export const Product = observer(() => { const uploadHandler = async (args) => { const file = args.file; try { - const responseUpload = await store.product.uploadExcel(file); + const response = await store.product.uploadExcel(file); - if (responseUpload.status === 201) { + if (response.status === 201) { message.success("Success upload excel!"); } else { message.error("Failed upload excel!"); } - setLoading(false); - const responseUploadProduct = await handleUploadProduct(responseUpload); + setFileList([{ + uid: '-1', + name: response.body.filename, + status: 'done', + url: '', + }]); + setExcel(response.body.filename); } catch (e) { setLoading(false); message.error("Failed upload excel!"); @@ -99,27 +115,40 @@ export const Product = observer(() => { const handleUploadProduct = async (data) => { try { - const response = await store.product.uploadProduct({fileName: data.body.filename}); + const response = await store.product.uploadProduct(data); if (response.status === 201) { message.success("Success Create Product by Excel!"); } else { message.error("Failed Create Product by Excel!"); } - setLoading(false); - await store.product.getData(); return response; } catch (e) { setLoading(false); message.error("Failed Create Product by Excel!"); } - } + }; - const loadingState = ( -
- {loading ? : null} -
- ); + const handleCancel = () => { + form.resetFields(); + setFileList([]); + setExcel(""); + setVisibleModalUpload(false); + }; + + const handleSubmit = async (data) => { + const request = { + fileName: excel, + supplierCode: data.supplierCode + }; + const responseUploadProduct = await handleUploadProduct(request); + + await store.product.getData(); + setLoading(false); + setFileList([]); + setExcel(""); + setVisibleModalUpload(false); + }; return (
@@ -162,35 +191,99 @@ export const Product = observer(() => { textAlign: "right", }} > - beforeUpload(file)} - customRequest={(args) => uploadHandler(args)} - onRemove={(file) => { - setLoading(false); + - - {loadingState} + Tambah Produk +
- - - - )} - - - + + + + )} + + + + { + form.resetFields(); + handleCancel(); + }} + onOk={() => { + form + .validateFields() + .then((values) => { + console.log(values, "isi form"); + handleSubmit(values); + form.resetFields(); + }) + .catch((info) => { + console.error("Validate Failed:", info); + }); + }} + > +
+ + beforeUpload(file)} + customRequest={(args) => uploadHandler(args)} + onRemove={(file) => { + setLoading(false); + setFileList([]); + setExcel(""); + }} + > +
+ +
+
+
+ + + +
+
+ ); }); From 097782d791d00401a7a8cd8a01c310975f38ea68 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 23 Dec 2021 21:51:37 +0700 Subject: [PATCH 2/8] fix: role button new product admin --- src/pages/Product/Product.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/Product/Product.js b/src/pages/Product/Product.js index 6e77e97..7cdd86e 100644 --- a/src/pages/Product/Product.js +++ b/src/pages/Product/Product.js @@ -154,7 +154,6 @@ export const Product = observer(() => {
- {store.authentication.userData.role !== "Admin" && (
@@ -184,7 +183,7 @@ export const Product = observer(() => { }} /> */} -
{ > Tambah Produk -
+
}
- )} From 98e7827247bf7d0e13cb4d017590e15c136f0c43 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 23 Dec 2021 23:16:47 +0700 Subject: [PATCH 3/8] feat: add separated column in date and add pagination on price history on product detail --- src/component/ProductComponent.js | 21 +++---- src/pages/Product/ProductDetail.js | 96 +++++++++++++++--------------- src/store/product.js | 25 ++++---- 3 files changed, 69 insertions(+), 73 deletions(-) diff --git a/src/component/ProductComponent.js b/src/component/ProductComponent.js index 0087f07..293fffa 100644 --- a/src/component/ProductComponent.js +++ b/src/component/ProductComponent.js @@ -1,4 +1,4 @@ -import React, { useContext, useState } from "react"; +import React, {useContext, useState} from "react"; import { Button, Col, @@ -15,19 +15,19 @@ import { Tag, Typography, } from "antd"; -import { observer } from "mobx-react-lite"; -import { ExclamationCircleOutlined } from "@ant-design/icons"; -import { useHistory } from "react-router-dom"; -import { useStore } from "../utils/useStore"; -import { LINKS } from "../routes/app"; -import { ModalLoaderContext } from "../utils/modal"; +import {observer} from "mobx-react-lite"; +import {ExclamationCircleOutlined} from "@ant-design/icons"; +import {useHistory} from "react-router-dom"; +import {useStore} from "../utils/useStore"; +import {LINKS} from "../routes/app"; +import {ModalLoaderContext} from "../utils/modal"; -const { Title, Text } = Typography; +const {Title, Text} = Typography; export const ProductComponent = observer((props) => { const store = useStore(); const [form] = Form.useForm(); - const { Option } = Select; + const {Option} = Select; const history = useHistory(); const [idData, setIdData] = useState(""); const [filterSupplier, setFilterSupplier] = useState([]); @@ -109,10 +109,7 @@ export const ProductComponent = observer((props) => { render: (text, record) => ( */} { + let pageNumber = page.current; + store.product.pageSizePriceHistory = page.pageSize; + store.product.pagePriceHistory = pageNumber - 1; + modalLoader.setLoading(true); + await store.product.getPriceHistoryByProduct(id); + modalLoader.setLoading(false); + }} /> diff --git a/src/store/product.js b/src/store/product.js index 1ccd96a..36a8295 100644 --- a/src/store/product.js +++ b/src/store/product.js @@ -13,7 +13,7 @@ export class Product { uploadBtnProduct = false; pageCategories = 0; - pageSizeCategories = 10 + pageSizeCategories = 100; dataCategories = []; total_dataCategories = 0; @@ -22,11 +22,13 @@ export class Product { dataSubCategories = []; total_dataSubCategories = 0; filterCategory = null; - dataDetail=[] - dataDetailProduct=[] - pageGetDetail=0 - supplier=null + dataPriceHistory = []; + totalDataPriceHistory = 0; + pagePriceHistory = 0; + pageSizePriceHistory = 10 + + dataDetailProduct = {}; constructor(ctx) { this.ctx = ctx; @@ -72,22 +74,21 @@ export class Product { console.error(e); } } - async getDetail(id) { + + async getPriceHistoryByProduct(id) { try { - const response = await http.get(`/product/price-history/${id}?page=${this.pageGetDetail}&supplier=${this.supplier}`); - //console.log(response,' Detail') - this.dataDetail = response.body.data - this.total_data = response?.body?.count ?? 0 + const response = await http.get(`/product/price-history/${id}?page=${this.pagePriceHistory}&pageSize${this.pageSizePriceHistory}`); + this.dataPriceHistory = response.body.data + this.totalDataPriceHistory = response?.body?.count ?? 0 } catch (e) { console.error(e); } } + async getDetailProduct(id) { try { const response = await http.get(`/product/${id}`); - //console.log(response,' Detail Product') this.dataDetailProduct = response.body.data - this.total_data = response?.body?.count ?? 0 } catch (e) { console.error(e); } From 258dd4af34e4679b7f885484f94a59f14cdaebc7 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 23 Dec 2021 23:21:12 +0700 Subject: [PATCH 4/8] feat: link detail url --- src/pages/Product/ProductDetail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Product/ProductDetail.js b/src/pages/Product/ProductDetail.js index a62d047..e30aa91 100644 --- a/src/pages/Product/ProductDetail.js +++ b/src/pages/Product/ProductDetail.js @@ -25,8 +25,8 @@ export const ProductDetail = observer(() => { name: Produk, }, { - route: LINKS.PRODUCT_DETAIL, - name: Detail Produk, + route: LINKS.PRODUCT_DETAIL.replace(':id', `${id}`), + name: Detail Produk, }, ]; From 7c38f65ba973772583fb86524d8766450191e0a6 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Fri, 24 Dec 2021 00:54:29 +0700 Subject: [PATCH 5/8] feat: ajust detail user --- src/pages/Membership/DetailUser.js | 108 +++++++++++++---------------- 1 file changed, 47 insertions(+), 61 deletions(-) diff --git a/src/pages/Membership/DetailUser.js b/src/pages/Membership/DetailUser.js index c0afcee..a7b5249 100644 --- a/src/pages/Membership/DetailUser.js +++ b/src/pages/Membership/DetailUser.js @@ -1,5 +1,5 @@ import React, {useContext, useEffect, useState} from "react"; -import {Button, Card, Col, message, Row, Space, Table, Tag, Typography,} from "antd"; +import {Button, Card, Col, message, Row, Space, Table, Typography,} from "antd"; import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import {LINKS} from "../../routes/app"; import {useStore} from "../../utils/useStore"; @@ -104,6 +104,11 @@ export const DetailUser = observer(() => { title: "Amount", dataIndex: "amount", key: "amount", + render: (text) => + new Intl.NumberFormat("id-ID", { + style: "currency", + currency: "IDR", + }).format(text), }, { title: "Transaction Date", @@ -117,19 +122,6 @@ export const DetailUser = observer(() => { ); }, }, - { - title: "Status", - dataIndex: "isActive", - key: "isActive", - render: (text, record) => ( - - {store.membership.dataDetail.isActive === true ? " ACTIVE" : "INACTIVE"} - - ), - }, ]; const routeData = [ @@ -142,8 +134,8 @@ export const DetailUser = observer(() => { name: Keanggotaan, }, { - route: LINKS.USER_DETAIL, - name: Detail Anggota, + route: LINKS.USER_DETAIL.replace(":id", id), + name: Detail User, }, ]; @@ -194,56 +186,50 @@ export const DetailUser = observer(() => { - Action User Detail - Action User Detail} + {store.authentication.userData.role === "Admin" && - {store.authentication.userData.role === "Admin" && - - } - {store.authentication.userData.role === "Admin" && - - } - {store.authentication.userData.role === "Admin" && - - } - + + + + } From c68d8105e32709725eff85bb66d250c164ce4fbf Mon Sep 17 00:00:00 2001 From: caturbgs Date: Fri, 24 Dec 2021 00:57:42 +0700 Subject: [PATCH 6/8] feat: remove extra whitespace --- src/pages/Membership/DetailUser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Membership/DetailUser.js b/src/pages/Membership/DetailUser.js index a7b5249..1301340 100644 --- a/src/pages/Membership/DetailUser.js +++ b/src/pages/Membership/DetailUser.js @@ -117,7 +117,7 @@ export const DetailUser = observer(() => { render: (text, record) => { return ( - {format(parseISO(record.transaction_date), "dd MMMM yyyy ")} + {format(parseISO(record.transaction_date), "dd MMMM yyyy")} ); }, From 5ac16feb6bac8d959e7cb7132af8de477d38fa86 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Fri, 24 Dec 2021 01:29:59 +0700 Subject: [PATCH 7/8] fix: format date on profile --- src/pages/Profile/Profile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Profile/Profile.js b/src/pages/Profile/Profile.js index def501f..c346341 100644 --- a/src/pages/Profile/Profile.js +++ b/src/pages/Profile/Profile.js @@ -60,7 +60,7 @@ export const Profile = observer(() => { key: 'created_at', render: (text, record) => { return ( - {format(parseISO(record.created_at), 'mm:HH dd MM YYYY')} + {format(parseISO(record.created_at), 'mm:HH dd-MM-yyyy')} ) }, }, From fbad2d68e870f8dbdee3077918099fe22a090de4 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Fri, 24 Dec 2021 01:44:55 +0700 Subject: [PATCH 8/8] feat: add phone number on buy product --- src/pages/Transaction/Product.js | 138 ++++++++++++++++++------------- 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/src/pages/Transaction/Product.js b/src/pages/Transaction/Product.js index dffb907..25e68a9 100644 --- a/src/pages/Transaction/Product.js +++ b/src/pages/Transaction/Product.js @@ -1,16 +1,17 @@ -import React, { useContext, useEffect } from "react"; -import { useStore } from "../../utils/useStore"; -import { Button, Card, Col, Input, message, Modal, Row, Select } from "antd"; -import { observer } from "mobx-react-lite"; -import { MoneyCollectOutlined } from "@ant-design/icons"; -import { ModalLoaderContext } from "../../utils/modal"; +import React, {useContext, useEffect, useState} from "react"; +import {useStore} from "../../utils/useStore"; +import {Card, Col, Form, Input, message, Modal, Row, Select} from "antd"; +import {observer} from "mobx-react-lite"; +import {ModalLoaderContext} from "../../utils/modal"; -const { Search } = Input; -const { Option } = Select; +const {Search} = Input; +const {Option} = Select; export const Product = observer(() => { const store = useStore(); const modalLoader = useContext(ModalLoaderContext); + const [form] = Form.useForm(); + const [visibleModalBuy, setVisibleModalBuy] = useState(false); useEffect(() => { const init = async () => { @@ -41,11 +42,12 @@ export const Product = observer(() => { modalLoader.setLoading(false); }; - const handleBuyProduct = async (data) => { + const handleBuyProduct = async (data, productCode) => { modalLoader.setLoading(true); try { const response = await store.transaction.buyProduct({ - productCode: data, + ...data, + productCode: productCode, }); if (response.status === 201) { message.success("Berhasil Beli Produk"); @@ -60,38 +62,44 @@ export const Product = observer(() => { console.log(e, "apa errornya"); message.error("Gagal Beli Product"); } + setVisibleModalBuy(false); modalLoader.setLoading(false); }; + const handleCancel = () => { + form.resetFields(); + setVisibleModalBuy(false); + }; + return ( -
- - +
+ + Sub Category - - -
- handleChangeSubcategory(val)} + style={{marginBottom: "10px", width: "100%"}} + value={store.transaction.filterSubCategory} + > + {store.transaction.dataSubCategories.map((item, index) => ( + + ))} + + + + + - {store.transaction.dataSubCategories.map((item, index) => ( - - ))} - - - - - Produk & Nominal @@ -107,19 +115,7 @@ export const Product = observer(() => { { - Modal.confirm({ - title: `Are you sure buy ${item.product_name}?`, - icon: , - okText: "Confirm", - cancelText: "Cancel", - okType: "primary", - onOk() { - handleBuyProduct(item.product_code); - }, - onCancel() { - console.log("Cancel"); - }, - }); + setVisibleModalBuy(true) }} hoverable style={{ @@ -130,26 +126,52 @@ export const Product = observer(() => { marginBottom: 10, }} > - {item.product_name} -
- + {item.product_name} +
+ {new Intl.NumberFormat("id-ID", { style: "currency", currency: "IDR", }).format(item?.price)}
+ + { + form.resetFields(); + handleCancel(); + }} + onOk={() => { + form + .validateFields() + .then((values) => { + console.log(values, "isi form"); + handleBuyProduct(values, item.product_code); + form.resetFields(); + }) + .catch((info) => { + console.error("Validate Failed:", info); + }); + }} + > +
+ + + + +
))} )} - {/* {store.transaction.data.length !== 0 && ( - - - - )} */} ); });