From a4ba756dbce32278ae2dc866909447956d69ca75 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Tue, 21 Dec 2021 14:42:53 +0700 Subject: [PATCH 1/3] feat: add upload image payback --- src/pages/Payback/PaybackFromUser.js | 6 +- src/pages/Payback/PaybackModal.js | 226 ++++++++++++--------------- src/utils/http.js | 9 +- 3 files changed, 106 insertions(+), 135 deletions(-) diff --git a/src/pages/Payback/PaybackFromUser.js b/src/pages/Payback/PaybackFromUser.js index 3df9981..cc258f2 100644 --- a/src/pages/Payback/PaybackFromUser.js +++ b/src/pages/Payback/PaybackFromUser.js @@ -20,8 +20,10 @@ export const PaybackFromUser = observer(() => { const init = async () => { try { modalLoader.setLoading(true); - await store.payback.getDataUser(); - await store.authentication.getProfile(); + await Promise.allSettled([ + store.payback.getDataUser(), + store.authentication.getProfile() + ]); modalLoader.setLoading(false); } catch (e) { modalLoader.setLoading(false); diff --git a/src/pages/Payback/PaybackModal.js b/src/pages/Payback/PaybackModal.js index a6bf6de..9079ad9 100644 --- a/src/pages/Payback/PaybackModal.js +++ b/src/pages/Payback/PaybackModal.js @@ -1,37 +1,28 @@ -import React, {useState, useEffect, useContext} from "react"; -import { - Button, - Form, - Image, - Input, - message, - Modal, - Upload, -} from "antd"; +import React, {useContext, useState} from "react"; +import {Form, Input, message, Modal, Upload,} from "antd"; import {useStore} from "../../utils/useStore"; -import {appConfig} from "../../config/app"; -import {LoadingOutlined, UploadOutlined} from "@ant-design/icons"; +import {LoadingOutlined, PlusOutlined} from "@ant-design/icons"; import {ModalLoaderContext} from "../../utils/modal"; +import {http} from "../../utils/http"; +import {appConfig} from "../../config/app"; export const PaybackModal = ({visible, onCreate, onCancel, initialData}) => { const [form] = Form.useForm(); const store = useStore(); + const [image, setImage] = useState(""); const [fileList, setFileList] = useState([]); - const [previewTitle, setPreviewTitle] = useState(""); const [previewImage, setPreviewImage] = useState(""); - const [fileUrl, setFileUrl] = useState(""); - const firstIndexFileList = fileList[0]; + const [previewVisible, setPreviewVisible] = useState(false); const [loading, setLoading] = useState(false); const modalLoader = useContext(ModalLoaderContext); const beforeUpload = (file) => { - let isPdf, isLt2M; - let allowedFile = ["image/jpeg", "image/png", "application/pdf"]; + let isLt2M; + let allowedFile = ["image/jpeg", "image/png"]; let isValid = allowedFile.includes(file.type); if (!isValid) { - message.error("You can only upload PDF or Image file!"); + message.error("You can only upload Image file!"); } - // return file.type === 'application/pdf' ? true : Upload.LIST_IGNORE; isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { message.error("File must smaller than 2MB!"); @@ -39,40 +30,31 @@ export const PaybackModal = ({visible, onCreate, onCancel, initialData}) => { return isValid && isLt2M ? true : Upload.LIST_IGNORE; }; - const handlePreview = async (file) => { - const fileUrl = appConfig.apiUrl + file.response.path; - setPreviewTitle(file.url?.substring(file.url?.lastIndexOf("/") + 1)); + const uploadHandler = async (args) => { + const file = args.file; + const res = await http.upload(file); + setImage(`${appConfig.apiUrl}/config/image/${res.body.filename}`); + setFileList([{ + uid: '-1', + name: 'image', + status: 'done', + url: `${appConfig.apiUrl}/config/image/${res.body.filename}`, + }]); }; - const handleChange = ({fileList}) => { - setFileList(fileList); - if (fileList.length && fileList[0].status === "done") { - form.setFieldsValue({ - file_url: fileList[0].response.path, - }); - console.log(fileList, "apaaaaaa"); - setFileUrl(fileList[0].response.path); - setPreviewImage(fileList[0].response.path); - setPreviewTitle(fileList[0].name); + const handleChange = (info) => { + if (info.file.status === 'uploading') { + setLoading(true); + return; } + setLoading(false) }; const uploadButton = ( -
- {loading ? ( - - ) : ( - - )} -
- ); - - const previewUpload = ( - +
+ {loading ? : } +
Click to Upload
+
); const handleSubmit = async (data) => { @@ -95,101 +77,85 @@ export const PaybackModal = ({visible, onCreate, onCancel, initialData}) => { }; return ( - { - form.resetFields(); - onCancel(); - }} - onOk={() => { - form - .validateFields() - .then((values) => { - handleSubmit(values); - console.log(values); + { form.resetFields(); - }) - .catch((info) => { - console.log("Validate Failed:", info); - }); - }} - > -
{ + form + .validateFields() + .then((values) => { + handleSubmit(values); + console.log(values); + form.resetFields(); + }) + .catch((info) => { + console.log("Validate Failed:", info); + }); + }} > - - - - -
+ + +
{ + setPreviewImage(file.url || file.filename); + setPreviewVisible(file.url || file.filename); + }} + showUploadList={true} + onChange={handleChange} + beforeUpload={(file) => beforeUpload(file)} + customRequest={(args) => uploadHandler(args)} + onRemove={(file) => { + setImage(''); + setLoading(false); + setFileList([]); + }} > - {!firstIndexFileList ? uploadButton : null} + + {image === "" ? uploadButton : null}
Max size of file 2 mb
-
-
Preview
-
- preview -
-
{previewTitle}
-
- {previewUpload} - {previewTitle && {`${previewTitle ?? ""}`}} -
-
-
-
- - - -
-
+ + + + + +
); }; diff --git a/src/utils/http.js b/src/utils/http.js index a752a36..4bb2fe8 100644 --- a/src/utils/http.js +++ b/src/utils/http.js @@ -50,13 +50,16 @@ export const http = { return req; }, upload: (file) => { - const request = superagent - .post(appConfig.apiUrl + '/files') + let req = superagent + .post(appConfig.apiUrl + '/config/upload-files') .attach('file', file) .use(authIntercept) .use(attachSuperagentLogger); + if (TokenUtil.accessToken) { + req = req.set('Authorization', 'Bearer ' + TokenUtil.accessToken); + } - return request; + return req; }, uploadAntd: (args) => { const file = args.file; From 2d87c65bbc1ca8d3d769c27670557d577ca7cb31 Mon Sep 17 00:00:00 2001 From: ilham Date: Tue, 21 Dec 2021 15:07:49 +0700 Subject: [PATCH 2/3] fix: get membership --- src/component/SupplierComponent.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/component/SupplierComponent.js b/src/component/SupplierComponent.js index 8071879..29b1298 100644 --- a/src/component/SupplierComponent.js +++ b/src/component/SupplierComponent.js @@ -65,15 +65,26 @@ export const SupplierComponent = observer((props) => { width: "5%", }, { - title: "Saldo", + title: "Saldo di Supplier", dataIndex: ["coa", "amount"], key: ["coa", "amount"], width: "20%", render: (text, record) => - new Intl.NumberFormat("id-ID", { - style: "currency", - currency: "IDR", - }).format(text) + new Intl.NumberFormat("id-ID", { + style: "currency", + currency: "IDR", + }).format(text) + }, + { + title: "Saldo di System", + dataIndex: ["coa_undistribute", "amount"], + key: ["coa_undistribute", "amount"], + width: "20%", + render: (text, record) => + new Intl.NumberFormat("id-ID", { + style: "currency", + currency: "IDR", + }).format(text) }, { title: "Status", From f91cbd02b2350d38151a820683e27bd44bcc1d34 Mon Sep 17 00:00:00 2001 From: "ajat91.sudrajat" Date: Tue, 21 Dec 2021 15:21:58 +0700 Subject: [PATCH 3/3] Mobile Responsive --- src/component/PartnerComponent.js | 217 +++++++++++++++++------ src/component/ProductComponent.js | 276 +++++++++++++++++++++--------- src/component/Subcategory.js | 148 ++++++++++++---- src/pages/App/DesktopLayout.js | 2 +- src/pages/Product/Product.js | 2 +- 5 files changed, 471 insertions(+), 174 deletions(-) diff --git a/src/component/PartnerComponent.js b/src/component/PartnerComponent.js index bd4c46a..7a3afd0 100644 --- a/src/component/PartnerComponent.js +++ b/src/component/PartnerComponent.js @@ -1,11 +1,23 @@ -import React, {useContext, useEffect, useState} from "react"; -import {Button, Form, Input, message, Modal, Select, Space, Table, Tag,} 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 React, { useContext, useEffect, useState } from "react"; +import { + Button, + Form, + Input, + message, + Modal, + Select, + Space, + Table, + Tag, + List, + Divider, +} 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"; export const PartnerComponent = observer((props) => { const store = useStore(); @@ -78,7 +90,7 @@ export const PartnerComponent = observer((props) => { render: (text, record) => ( {record?.status === true ? " ACTIVE" : "INACTIVE"} @@ -121,7 +133,7 @@ export const PartnerComponent = observer((props) => { const handleDelete = (id) => { Modal.confirm({ title: "Are you sure delete this record?", - icon: , + icon: , okText: "Yes", okType: "primary", cancelText: "Cancel", @@ -181,36 +193,126 @@ export const PartnerComponent = observer((props) => { }; return (
- { - let pageNumber = page.current; - store.partner.pageSize = page.pageSize; - store.partner.page = pageNumber - 1; - modalLoader.setLoading(true); - await store.partner.getData(); - modalLoader.setLoading(false); - }} - /> - + {store.ui.mediaQuery.isDesktop && ( +
{ + let pageNumber = page.current; + store.partner.pageSize = page.pageSize; + store.partner.page = pageNumber - 1; + modalLoader.setLoading(true); + await store.partner.getData(); + modalLoader.setLoading(false); + }} + /> + )} + {store.ui.mediaQuery.isMobile && ( + { + store.partner.pageSize = page.pageSize; + store.partner.page = page.current; + modalLoader.setLoading(true); + await store.partner.getData(); + modalLoader.setLoading(false); + }, + pageSize: store.partner.pageSize, + total: store.partner.total_data, + current: store.partner.page, + style: { marginBottom: "1rem", marginRight: "1rem" }, + }} + dataSource={store.partner.data} + style={{ padding: 0 }} + renderItem={(item) => { + return ( +
+ + +

+ Nama : {item.name}
+ Npwp : {item.npwp}
+ Address : {item.address} + + + + {/* */} + + +

+

+
+ } + /> +
+

+ + {item?.status === true ? " ACTIVE" : "INACTIVE"} + +

+
+ + + + ); + }} + /> + )} { label="Name" rules={[ idData - ? {required: false} - : {required: true, message: "Please input password name!"}, + ? { required: false } + : { required: true, message: "Please input password name!" }, ]} > - + )} {!idData && ( @@ -251,11 +353,11 @@ export const PartnerComponent = observer((props) => { label="Owner" rules={[ idData - ? {required: false} - : {required: true, message: "Please input password owner!"}, + ? { required: false } + : { required: true, message: "Please input password owner!" }, ]} > - + )} {((idData && isChangePassword) || !idData) && ( @@ -264,14 +366,14 @@ export const PartnerComponent = observer((props) => { label="Password Account" rules={[ idData - ? {required: false} + ? { required: false } : { - required: true, - message: "Please input password account!", - }, + required: true, + message: "Please input password account!", + }, ]} > - + )} {!idData && ( @@ -280,11 +382,14 @@ export const PartnerComponent = observer((props) => { label="Phone Number" rules={[ idData - ? {required: false} - : {required: true, message: "Please input password phone number!"}, + ? { required: false } + : { + required: true, + message: "Please input password phone number!", + }, ]} > - + )} {!isChangePassword && ( @@ -294,25 +399,25 @@ export const PartnerComponent = observer((props) => { label="Npwp" rules={[ idData - ? {required: false} - : {required: true, message: "Please input npwp!"}, + ? { required: false } + : { required: true, message: "Please input npwp!" }, ]} > - + - + )} diff --git a/src/component/ProductComponent.js b/src/component/ProductComponent.js index 9d62954..4b0b143 100644 --- a/src/component/ProductComponent.js +++ b/src/component/ProductComponent.js @@ -1,28 +1,42 @@ -import React, {useContext, useState} from "react"; -import {Button, Col, Form, Input, message, Modal, Row, Select, Table, Tag, Typography} from "antd"; -import {observer} from "mobx-react-lite"; -import {ExclamationCircleOutlined} from "@ant-design/icons"; -import {useHistory} from "react-router-dom"; -import {capitalize} from "lodash"; -import {useStore} from "../utils/useStore"; -import {LINKS} from "../routes/app"; -import {ModalLoaderContext} from "../utils/modal"; +import React, { useContext, useState } from "react"; +import { + Button, + Col, + Form, + Input, + message, + Modal, + Row, + Select, + Table, + Divider, + Tag, + Typography, + List, +} from "antd"; +import { observer } from "mobx-react-lite"; +import { ExclamationCircleOutlined } from "@ant-design/icons"; +import { useHistory } from "react-router-dom"; +import { capitalize } from "lodash"; +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 [idData, setIdData] = useState(""); const [filterSupplier, setFilterSupplier] = useState(null); const [filterCategories, setFilterCategories] = useState(null); const [filterSubCategories, setFilterSubCategories] = useState(null); const modalLoader = useContext(ModalLoaderContext); const handleEditButton = (data) => { - console.log(data, "isi data") + console.log(data, "isi data"); form.setFieldsValue({ name: data.name, price: data.price, @@ -33,7 +47,7 @@ export const ProductComponent = observer((props) => { }); store.product.visibleModalProduct = true; setIdData(data.id); - } + }; const columns = [ { @@ -76,12 +90,12 @@ export const ProductComponent = observer((props) => { render: (text, record) => ( {record?.status === "ACTIVE" ? " Tersedia" : "Tidak"} ), - } + }, ]; const deleteData = async (id) => { @@ -99,7 +113,7 @@ export const ProductComponent = observer((props) => { const handleDelete = (id) => { Modal.confirm({ title: "Are you sure delete this record?", - icon: , + icon: , okText: "Yes", okType: "primary", cancelText: "Cancel", @@ -113,39 +127,39 @@ export const ProductComponent = observer((props) => { }; const handleCancel = () => { - setIdData('') + setIdData(""); store.product.visibleModalProduct = false; - } + }; const handleSubmit = async (data) => { - console.log(data, "isi data2") - if (idData !== '') { + console.log(data, "isi data2"); + if (idData !== "") { modalLoader.setLoading(true); try { - await store.product.update(idData, data) - message.success("Success Update Data Member") + await store.product.update(idData, data); + message.success("Success Update Data Member"); } catch (e) { - message.error("Failed Update Data Member") + message.error("Failed Update Data Member"); } modalLoader.setLoading(false); store.product.visibleModalProduct = false; - setIdData(''); + setIdData(""); form.resetFields(); } else { modalLoader.setLoading(true); try { - await store.product.create(data) - message.success("Success Add New Member") + await store.product.create(data); + message.success("Success Add New Member"); } catch (e) { - console.log(e, "apa errornya") - message.error("Failed Add Member") + console.log(e, "apa errornya"); + message.error("Failed Add Member"); } modalLoader.setLoading(false); store.product.visibleModalProduct = false; - setIdData(''); + setIdData(""); form.resetFields(); } - } + }; const handleRemoveFilter = async () => { store.product.filterSupplier = null; @@ -174,39 +188,132 @@ export const ProductComponent = observer((props) => { }; const footerLayoutFilter = [ - , - , - - ] + , + , + , + ]; return (
-
{ - let pageNumber = page.current; - store.product.pageSize = page.pageSize; - store.product.page = pageNumber - 1; - modalLoader.setLoading(true); - await store.product.getData(); - modalLoader.setLoading(false); - }} - /> - + {store.ui.mediaQuery.isDesktop && ( +
{ + let pageNumber = page.current; + store.product.pageSize = page.pageSize; + store.product.page = pageNumber - 1; + modalLoader.setLoading(true); + await store.product.getData(); + modalLoader.setLoading(false); + }} + /> + )} + {store.ui.mediaQuery.isMobile && ( + { + store.product.pageSize = page.pageSize; + store.product.page = page.current; + modalLoader.setLoading(true); + await store.product.getData(); + modalLoader.setLoading(false); + }, + pageSize: store.product.pageSize, + total: store.product.total_data, + current: store.product.page, + style: { marginBottom: "1rem", marginRight: "1rem" }, + }} + dataSource={store.product.data} + style={{ padding: 0 }} + renderItem={(item) => { + return ( +
+ + +

+ Nama Produk : {item.name}
+ Harga Beli : {item.currentPrice.price} +
+ + Harga Jual : {item.currentPrice.mark_up_price} + +

+

+
+ } + /> +
+

+ + {item?.status === "ACTIVE" ? " Tersedia" : "Tidak"} + +

+
+ + + + ); + }} + /> + )} { form .validateFields() .then((values) => { - console.log(values, "isi form") + console.log(values, "isi form"); handleSubmit(values); form.resetFields(); }) @@ -229,42 +336,39 @@ export const ProductComponent = observer((props) => { }); }} > -
+ - + - + - + - + {store.product.dataSubCategories.map((item) => ( @@ -294,14 +400,16 @@ export const ProductComponent = observer((props) => { >
- Filter Supplier + + Filter Supplier + - Filter Categories + + Filter Categories + - Filter Sub-Categories + + Filter Sub-Categories +
{ - let pageNumber = page.current; - store.subcategory.pageSize = page.pageSize; - store.subcategory.page = pageNumber - 1; - modalLoader.setLoading(true); - await getData(); - modalLoader.setLoading(false); - }} - /> - + {store.ui.mediaQuery.isDesktop && ( +
{ + let pageNumber = page.current; + store.subcategory.pageSize = page.pageSize; + store.subcategory.page = pageNumber - 1; + modalLoader.setLoading(true); + await getData(); + modalLoader.setLoading(false); + }} + /> + )} + {store.ui.mediaQuery.isMobile && ( + { + store.subcategory.pageSize = page.pageSize; + store.subcategory.page = page.current; + modalLoader.setLoading(true); + await store.subcategory.getData(); + modalLoader.setLoading(false); + }, + pageSize: store.subcategory.pageSize, + total: store.subcategory.total_data, + current: store.subcategory.page, + style: { marginBottom: "1rem", marginRight: "1rem" }, + }} + dataSource={store.subcategory.data} + style={{ padding: 0 }} + renderItem={(item) => { + return ( +
+ + +

+ Sub Category : {item.name}
+ Category : {item.categoryName} +
+

+

+
+ } + /> +
+

+ +

+
+ + + + ); + }} + /> + )} { name="code" label="Code" rules={[ - {required: true, message: "Please input code category!"}, + { required: true, message: "Please input code category!" }, ]} > - + )} - + {!idData && (