Merge branch 'develop' into 'devops-staging'
Develop See merge request empatnusabangsa/ppob/ppob-frontend!4
This commit is contained in:
		| @@ -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) => ( | ||||
|         <Tag | ||||
|           color={record?.status === true ? "processing" : "#E3E8EE"} | ||||
|           style={{color: "#4F566B", cursor: "pointer"}} | ||||
|           style={{ color: "#4F566B", cursor: "pointer" }} | ||||
|         > | ||||
|           {record?.status === true ? " ACTIVE" : "INACTIVE"} | ||||
|         </Tag> | ||||
| @@ -121,7 +133,7 @@ export const PartnerComponent = observer((props) => { | ||||
|   const handleDelete = (id) => { | ||||
|     Modal.confirm({ | ||||
|       title: "Are you sure delete this record?", | ||||
|       icon: <ExclamationCircleOutlined/>, | ||||
|       icon: <ExclamationCircleOutlined />, | ||||
|       okText: "Yes", | ||||
|       okType: "primary", | ||||
|       cancelText: "Cancel", | ||||
| @@ -181,8 +193,9 @@ export const PartnerComponent = observer((props) => { | ||||
|   }; | ||||
|   return ( | ||||
|     <div> | ||||
|       {store.ui.mediaQuery.isDesktop && ( | ||||
|         <Table | ||||
|         style={{textAlign: "center"}} | ||||
|           style={{ textAlign: "center" }} | ||||
|           columns={columns} | ||||
|           dataSource={store.partner.data} | ||||
|           bordered | ||||
| @@ -202,7 +215,96 @@ export const PartnerComponent = observer((props) => { | ||||
|             modalLoader.setLoading(false); | ||||
|           }} | ||||
|         /> | ||||
|  | ||||
|       )} | ||||
|       {store.ui.mediaQuery.isMobile && ( | ||||
|         <List | ||||
|           itemLayout="horizontal" | ||||
|           position={"top"} | ||||
|           pagination={{ | ||||
|             onChange: async (page) => { | ||||
|               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 ( | ||||
|               <div> | ||||
|                 <List.Item | ||||
|                   key={item.id} | ||||
|                   style={{ | ||||
|                     backgroundColor: "#ffffff", | ||||
|                     paddingTop: 0, | ||||
|                     paddingBottom: 0, | ||||
|                     display: "flex", | ||||
|                     flexDirection: "row", | ||||
|                     alignItems: "center", | ||||
|                     justifyContent: "center", | ||||
|                   }} | ||||
|                 > | ||||
|                   <List.Item.Meta | ||||
|                     className={["cariparkir-container"].join(" ")} | ||||
|                     title={item.code} | ||||
|                     description={ | ||||
|                       <div style={{}}> | ||||
|                         <p> | ||||
|                           <small>Nama : {item.name}</small> <br /> | ||||
|                           <small>Npwp : {item.npwp}</small> <br /> | ||||
|                           <small>Address : {item.address}</small> | ||||
|                           <Space size="middle"> | ||||
|                             <Button | ||||
|                               type={ | ||||
|                                 item?.status === true ? "danger" : "primary" | ||||
|                               } | ||||
|                               onClick={() => | ||||
|                                 changeStatus(item?.id, item?.status) | ||||
|                               } | ||||
|                             > | ||||
|                               {item?.status === true ? "Inactive" : "Active"} | ||||
|                             </Button> | ||||
|                             <Button onClick={() => handleEditButton(item)}> | ||||
|                               Edit | ||||
|                             </Button> | ||||
|                             {/* <Button onClick={() => handleDelete(record.id)}>Delete</Button> */} | ||||
|                             <Button onClick={() => changePassword(item)}> | ||||
|                               Change Password | ||||
|                             </Button> | ||||
|                           </Space> | ||||
|                         </p> | ||||
|                         <p></p> | ||||
|                       </div> | ||||
|                     } | ||||
|                   /> | ||||
|                   <div style={{ marginRight: 16 }}> | ||||
|                     <p | ||||
|                       style={{ | ||||
|                         fontSize: 9, | ||||
|                         marginBottom: 40, | ||||
|                       }} | ||||
|                     > | ||||
|                       <Tag | ||||
|                         color={item?.status === true ? "processing" : "#E3E8EE"} | ||||
|                         style={{ color: "#4F566B", cursor: "pointer" }} | ||||
|                       > | ||||
|                         {item?.status === true ? " ACTIVE" : "INACTIVE"} | ||||
|                       </Tag> | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </List.Item> | ||||
|                 <Divider plain style={{ margin: 0 }} /> | ||||
|               </div> | ||||
|             ); | ||||
|           }} | ||||
|         /> | ||||
|       )} | ||||
|       <Modal | ||||
|         visible={store.partner.visibleModalPartner} | ||||
|         title={ | ||||
| @@ -238,11 +340,11 @@ export const PartnerComponent = observer((props) => { | ||||
|               label="Name" | ||||
|               rules={[ | ||||
|                 idData | ||||
|                   ? {required: false} | ||||
|                   : {required: true, message: "Please input password name!"}, | ||||
|                   ? { required: false } | ||||
|                   : { required: true, message: "Please input password name!" }, | ||||
|               ]} | ||||
|             > | ||||
|               <Input/> | ||||
|               <Input /> | ||||
|             </Form.Item> | ||||
|           )} | ||||
|           {!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!" }, | ||||
|               ]} | ||||
|             > | ||||
|               <Input/> | ||||
|               <Input /> | ||||
|             </Form.Item> | ||||
|           )} | ||||
|           {((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!", | ||||
|                     }, | ||||
|               ]} | ||||
|             > | ||||
|               <Input/> | ||||
|               <Input /> | ||||
|             </Form.Item> | ||||
|           )} | ||||
|           {!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!", | ||||
|                     }, | ||||
|               ]} | ||||
|             > | ||||
|               <Input/> | ||||
|               <Input /> | ||||
|             </Form.Item> | ||||
|           )} | ||||
|           {!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!" }, | ||||
|                 ]} | ||||
|               > | ||||
|                 <Input/> | ||||
|                 <Input /> | ||||
|               </Form.Item> | ||||
|               <Form.Item | ||||
|                 name="address" | ||||
|                 label="Address" | ||||
|                 rules={[ | ||||
|                   idData | ||||
|                     ? {required: false} | ||||
|                     ? { required: false } | ||||
|                     : { | ||||
|                         required: true, | ||||
|                         message: "Please input address!", | ||||
|                       }, | ||||
|                 ]} | ||||
|               > | ||||
|                 <Input/> | ||||
|                 <Input /> | ||||
|               </Form.Item> | ||||
|             </> | ||||
|           )} | ||||
|   | ||||
| @@ -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) => ( | ||||
|         <Tag | ||||
|           color={record?.status === "ACTIVE" ? "blue" : "#E3E8EE"} | ||||
|           style={{color: "#4F566B"}} | ||||
|           style={{ color: "#4F566B" }} | ||||
|         > | ||||
|           {record?.status === "ACTIVE" ? " Tersedia" : "Tidak"} | ||||
|         </Tag> | ||||
|       ), | ||||
|     } | ||||
|     }, | ||||
|   ]; | ||||
|  | ||||
|   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: <ExclamationCircleOutlined/>, | ||||
|       icon: <ExclamationCircleOutlined />, | ||||
|       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,19 +188,39 @@ export const ProductComponent = observer((props) => { | ||||
|   }; | ||||
|  | ||||
|   const footerLayoutFilter = [ | ||||
|     <Button key={'remove'} onClick={handleRemoveFilter} style={{ | ||||
|       backgroundColor: '#e74e5e', color: '#fff' | ||||
|     }}>Remove Filter</Button>, | ||||
|     <Button key={'cancel'} onClick={handleCancelFilter}>Cancel</Button>, | ||||
|     <Button key={'submit'} onClick={handleSubmitFilter} style={{ | ||||
|       backgroundColor: '#4e79e7', color: '#fff' | ||||
|     }}>Apply</Button> | ||||
|   ] | ||||
|     <Button | ||||
|       key={"remove"} | ||||
|       onClick={handleRemoveFilter} | ||||
|       style={{ | ||||
|         backgroundColor: "#e74e5e", | ||||
|         color: "#fff", | ||||
|       }} | ||||
|     > | ||||
|       Remove Filter | ||||
|     </Button>, | ||||
|     <Button key={"cancel"} onClick={handleCancelFilter}> | ||||
|       Cancel | ||||
|     </Button>, | ||||
|     <Button | ||||
|       key={"submit"} | ||||
|       onClick={handleSubmitFilter} | ||||
|       style={{ | ||||
|         backgroundColor: "#4e79e7", | ||||
|         color: "#fff", | ||||
|       }} | ||||
|     > | ||||
|       Apply | ||||
|     </Button>, | ||||
|   ]; | ||||
|  | ||||
|   return ( | ||||
|     <div> | ||||
|       {store.ui.mediaQuery.isDesktop && ( | ||||
|         <Table | ||||
|         style={{textAlign: "center"}} | ||||
|           style={{ | ||||
|             textAlign: "center", | ||||
|             width: store.ui.mediaQuery.isMobile ? 250 : "", | ||||
|           }} | ||||
|           columns={columns} | ||||
|           dataSource={store.product.data} | ||||
|           bordered | ||||
| @@ -195,7 +229,7 @@ export const ProductComponent = observer((props) => { | ||||
|             total: store.product.total_data, | ||||
|             current: store.product.page + 1, | ||||
|             showSizeChanger: true, | ||||
|           simple: false | ||||
|             simple: false, | ||||
|           }} | ||||
|           onChange={async (page) => { | ||||
|             let pageNumber = page.current; | ||||
| @@ -206,7 +240,80 @@ export const ProductComponent = observer((props) => { | ||||
|             modalLoader.setLoading(false); | ||||
|           }} | ||||
|         /> | ||||
|  | ||||
|       )} | ||||
|       {store.ui.mediaQuery.isMobile && ( | ||||
|         <List | ||||
|           itemLayout="horizontal" | ||||
|           position={"top"} | ||||
|           pagination={{ | ||||
|             onChange: async (page) => { | ||||
|               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 ( | ||||
|               <div> | ||||
|                 <List.Item | ||||
|                   key={item.id} | ||||
|                   style={{ | ||||
|                     backgroundColor: "#ffffff", | ||||
|                     paddingTop: 0, | ||||
|                     paddingBottom: 0, | ||||
|                     display: "flex", | ||||
|                     flexDirection: "row", | ||||
|                     alignItems: "center", | ||||
|                     justifyContent: "center", | ||||
|                   }} | ||||
|                 > | ||||
|                   <List.Item.Meta | ||||
|                     className={["cariparkir-container"].join(" ")} | ||||
|                     title={item.code} | ||||
|                     description={ | ||||
|                       <div style={{}}> | ||||
|                         <p> | ||||
|                           <small>Nama Produk : {item.name}</small> <br /> | ||||
|                           <small>Harga Beli : {item.currentPrice.price}</small> | ||||
|                           <br /> | ||||
|                           <small> | ||||
|                             Harga Jual : {item.currentPrice.mark_up_price} | ||||
|                           </small> | ||||
|                         </p> | ||||
|                         <p></p> | ||||
|                       </div> | ||||
|                     } | ||||
|                   /> | ||||
|                   <div style={{ marginRight: 16 }}> | ||||
|                     <p | ||||
|                       style={{ | ||||
|                         fontSize: 9, | ||||
|                         margin: 0, | ||||
|                       }} | ||||
|                     > | ||||
|                       <Tag | ||||
|                         color={item?.status === "ACTIVE" ? "blue" : "#E3E8EE"} | ||||
|                         style={{ color: "#4F566B" }} | ||||
|                       > | ||||
|                         {item?.status === "ACTIVE" ? " Tersedia" : "Tidak"} | ||||
|                       </Tag> | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </List.Item> | ||||
|                 <Divider plain style={{ margin: 0 }} /> | ||||
|               </div> | ||||
|             ); | ||||
|           }} | ||||
|         /> | ||||
|       )} | ||||
|       <Modal | ||||
|         visible={store.product.visibleModalProduct} | ||||
|         title={idData ? "Edit Product" : "Create a new Product"} | ||||
| @@ -220,7 +327,7 @@ export const ProductComponent = observer((props) => { | ||||
|           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) => { | ||||
|             }); | ||||
|         }} | ||||
|       > | ||||
|         <Form | ||||
|           form={form} | ||||
|           layout="vertical" | ||||
|         > | ||||
|         <Form form={form} layout="vertical"> | ||||
|           <Form.Item | ||||
|             name="name" | ||||
|             label="Name" | ||||
|             rules={[{required: true, message: "Please input name!"}]} | ||||
|             rules={[{ required: true, message: "Please input name!" }]} | ||||
|           > | ||||
|             <Input/> | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
|           <Form.Item | ||||
|             name="price" | ||||
|             label="Price" | ||||
|             rules={[{required: true, message: "Please input price!"}]} | ||||
|             rules={[{ required: true, message: "Please input price!" }]} | ||||
|           > | ||||
|             <Input/> | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
|           <Form.Item | ||||
|             name="markUpPrice" | ||||
|             label="Mark Up Price" | ||||
|             rules={[{required: true, message: "Please input mark up price!"}]} | ||||
|             rules={[{ required: true, message: "Please input mark up price!" }]} | ||||
|           > | ||||
|             <Input/> | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
|           <Form.Item | ||||
|             name="code" | ||||
|             label="Code" | ||||
|             rules={[{required: true, message: "Please input code!"}]} | ||||
|             rules={[{ required: true, message: "Please input code!" }]} | ||||
|           > | ||||
|             <Input/> | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
|           <Form.Item | ||||
|             name="status" | ||||
|             label="Status" | ||||
|             rules={[{required: true, message: "Please select Status!"}]} | ||||
|             rules={[{ required: true, message: "Please select Status!" }]} | ||||
|           > | ||||
|             <Select placeholder="Select Sub Category" allowClear> | ||||
|               <Option value="ACTIVE">ACTIVE</Option> | ||||
| @@ -274,7 +378,9 @@ export const ProductComponent = observer((props) => { | ||||
|           <Form.Item | ||||
|             name="subCategoriesId" | ||||
|             label="Sub categories" | ||||
|             rules={[{required: true, message: "Please select sub categories!"}]} | ||||
|             rules={[ | ||||
|               { required: true, message: "Please select sub categories!" }, | ||||
|             ]} | ||||
|           > | ||||
|             <Select placeholder="Select Sub Category" allowClear> | ||||
|               {store.product.dataSubCategories.map((item) => ( | ||||
| @@ -294,14 +400,16 @@ export const ProductComponent = observer((props) => { | ||||
|       > | ||||
|         <Row> | ||||
|           <Col span={24}> | ||||
|             <Title level={5} type={"secondary"} strong>Filter Supplier</Title> | ||||
|             <Title level={5} type={"secondary"} strong> | ||||
|               Filter Supplier | ||||
|             </Title> | ||||
|             <Select | ||||
|               mode={"multiple"} | ||||
|               placeholder="Choose Supplier" | ||||
|               onChange={(val) => { | ||||
|                 setFilterSupplier(val); | ||||
|               }} | ||||
|               style={{marginBottom: "20px", width: "100%"}} | ||||
|               style={{ marginBottom: "20px", width: "100%" }} | ||||
|             > | ||||
|               {store.supplier.data.map((item) => ( | ||||
|                 <Option value={item.id} key={item.id}> | ||||
| @@ -311,7 +419,9 @@ export const ProductComponent = observer((props) => { | ||||
|             </Select> | ||||
|           </Col> | ||||
|           <Col span={24}> | ||||
|             <Title level={5} type={"secondary"} strong>Filter Categories</Title> | ||||
|             <Title level={5} type={"secondary"} strong> | ||||
|               Filter Categories | ||||
|             </Title> | ||||
|             <Select | ||||
|               mode={"multiple"} | ||||
|               placeholder="Choose Category" | ||||
| @@ -320,7 +430,7 @@ export const ProductComponent = observer((props) => { | ||||
|                 store.product.filterByCategory = val; | ||||
|                 await store.product.getDataSubCategories(); | ||||
|               }} | ||||
|               style={{marginBottom: "20px", width: "100%"}} | ||||
|               style={{ marginBottom: "20px", width: "100%" }} | ||||
|             > | ||||
|               {store.category.data.map((item) => ( | ||||
|                 <Option value={item.id} key={item.id}> | ||||
| @@ -330,14 +440,16 @@ export const ProductComponent = observer((props) => { | ||||
|             </Select> | ||||
|           </Col> | ||||
|           <Col span={24}> | ||||
|             <Title level={5} type={"secondary"} strong>Filter Sub-Categories</Title> | ||||
|             <Title level={5} type={"secondary"} strong> | ||||
|               Filter Sub-Categories | ||||
|             </Title> | ||||
|             <Select | ||||
|               mode={"multiple"} | ||||
|               placeholder="Choose Sub-Category" | ||||
|               onChange={(val) => { | ||||
|                 setFilterSubCategories(val); | ||||
|               }} | ||||
|               style={{marginBottom: "20px", width: "100%"}} | ||||
|               style={{ marginBottom: "20px", width: "100%" }} | ||||
|             > | ||||
|               {store.product.dataSubCategories.map((item) => ( | ||||
|                 <Option value={item.id} key={item.id}> | ||||
|   | ||||
| @@ -1,14 +1,26 @@ | ||||
| import React, {useContext, useState} from "react"; | ||||
| import {Button, Form, Input, message, Modal, Select, Space, Table,} from "antd"; | ||||
| import {observer} from "mobx-react-lite"; | ||||
| import {useHistory} from "react-router-dom"; | ||||
| import {useStore} from "../utils/useStore"; | ||||
| import {ModalLoaderContext} from "../utils/modal"; | ||||
| import React, { useContext, useState } from "react"; | ||||
| import { | ||||
|   Button, | ||||
|   Form, | ||||
|   Input, | ||||
|   message, | ||||
|   Modal, | ||||
|   Select, | ||||
|   Space, | ||||
|   Table, | ||||
|   List, | ||||
|   Tag, | ||||
|   Divider, | ||||
| } from "antd"; | ||||
| import { observer } from "mobx-react-lite"; | ||||
| import { useHistory } from "react-router-dom"; | ||||
| import { useStore } from "../utils/useStore"; | ||||
| import { ModalLoaderContext } from "../utils/modal"; | ||||
|  | ||||
| export const SubcategoryComponent = observer((props) => { | ||||
|   const store = useStore(); | ||||
|   const [form] = Form.useForm(); | ||||
|   const {Option} = Select; | ||||
|   const { Option } = Select; | ||||
|   const [idData, setIdData] = useState(""); | ||||
|   const modalLoader = useContext(ModalLoaderContext); | ||||
|  | ||||
| @@ -94,8 +106,9 @@ export const SubcategoryComponent = observer((props) => { | ||||
|  | ||||
|   return ( | ||||
|     <div> | ||||
|       {store.ui.mediaQuery.isDesktop && ( | ||||
|         <Table | ||||
|         style={{textAlign: "center"}} | ||||
|           style={{ textAlign: "center" }} | ||||
|           columns={columns} | ||||
|           dataSource={store.subcategory.data} | ||||
|           bordered | ||||
| @@ -115,7 +128,74 @@ export const SubcategoryComponent = observer((props) => { | ||||
|             modalLoader.setLoading(false); | ||||
|           }} | ||||
|         /> | ||||
|  | ||||
|       )} | ||||
|       {store.ui.mediaQuery.isMobile && ( | ||||
|         <List | ||||
|           itemLayout="horizontal" | ||||
|           position={"top"} | ||||
|           pagination={{ | ||||
|             onChange: async (page) => { | ||||
|               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 ( | ||||
|               <div> | ||||
|                 <List.Item | ||||
|                   key={item.id} | ||||
|                   style={{ | ||||
|                     backgroundColor: "#ffffff", | ||||
|                     paddingTop: 0, | ||||
|                     paddingBottom: 0, | ||||
|                     display: "flex", | ||||
|                     flexDirection: "row", | ||||
|                     alignItems: "center", | ||||
|                     justifyContent: "center", | ||||
|                   }} | ||||
|                 > | ||||
|                   <List.Item.Meta | ||||
|                     className={["cariparkir-container"].join(" ")} | ||||
|                     title={item.code} | ||||
|                     description={ | ||||
|                       <div style={{}}> | ||||
|                         <p> | ||||
|                           <small>Sub Category : {item.name}</small> <br /> | ||||
|                           <small>Category : {item.categoryName}</small> | ||||
|                           <br /> | ||||
|                         </p> | ||||
|                         <p></p> | ||||
|                       </div> | ||||
|                     } | ||||
|                   /> | ||||
|                   <div style={{ marginRight: 16 }}> | ||||
|                     <p | ||||
|                       style={{ | ||||
|                         fontSize: 9, | ||||
|                         margin: 0, | ||||
|                       }} | ||||
|                     > | ||||
|                       <Button onClick={() => handleEditButton(item)}> | ||||
|                         Edit | ||||
|                       </Button> | ||||
|                     </p> | ||||
|                   </div> | ||||
|                 </List.Item> | ||||
|                 <Divider plain style={{ margin: 0 }} /> | ||||
|               </div> | ||||
|             ); | ||||
|           }} | ||||
|         /> | ||||
|       )} | ||||
|       <Modal | ||||
|         visible={store.subcategory.visibleModalSubcategory} | ||||
|         title={idData ? "Edit Sub Category" : "Create a new sub category"} | ||||
| @@ -144,24 +224,24 @@ export const SubcategoryComponent = observer((props) => { | ||||
|               name="code" | ||||
|               label="Code" | ||||
|               rules={[ | ||||
|                 {required: true, message: "Please input code category!"}, | ||||
|                 { required: true, message: "Please input code category!" }, | ||||
|               ]} | ||||
|             > | ||||
|               <Input/> | ||||
|               <Input /> | ||||
|             </Form.Item> | ||||
|           )} | ||||
|           <Form.Item | ||||
|             name="name" | ||||
|             label="Name" | ||||
|             rules={[{required: true, message: "Please input name category!"}]} | ||||
|             rules={[{ required: true, message: "Please input name category!" }]} | ||||
|           > | ||||
|             <Input/> | ||||
|             <Input /> | ||||
|           </Form.Item> | ||||
|           {!idData && ( | ||||
|             <Form.Item | ||||
|               name="categoryId" | ||||
|               label="Categories" | ||||
|               rules={[{required: true, message: "Please input category id!"}]} | ||||
|               rules={[{ required: true, message: "Please input category id!" }]} | ||||
|             > | ||||
|               <Select placeholder="Select Category" allowClear> | ||||
|                 {store.category.data.map((item) => ( | ||||
|   | ||||
| @@ -65,7 +65,7 @@ export const SupplierComponent = observer((props) => { | ||||
|       width: "5%", | ||||
|     }, | ||||
|     { | ||||
|       title: "Saldo", | ||||
|       title: "Saldo di Supplier", | ||||
|       dataIndex: ["coa", "amount"], | ||||
|       key: ["coa", "amount"], | ||||
|       width: "20%", | ||||
| @@ -75,6 +75,17 @@ export const SupplierComponent = observer((props) => { | ||||
|             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", | ||||
|       dataIndex: "status", | ||||
|   | ||||
| @@ -145,7 +145,7 @@ export const DesktopLayout = observer(() => { | ||||
|                     </Link> | ||||
|                   </Menu.Item> | ||||
|                   <Menu.Item key="commision"> | ||||
|                     <Link to={LINKS.COMMISION}> | ||||
|                     <Link to={LINKS.COMMISSION}> | ||||
|                       <HomeOutlined /> | ||||
|                       <span>Commision</span> | ||||
|                     </Link> | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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,42 +30,33 @@ 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 = ( | ||||
|       <div> | ||||
|       {loading ? ( | ||||
|         <LoadingOutlined/> | ||||
|       ) : ( | ||||
|         <Button icon={<UploadOutlined/>}>Click to Upload</Button> | ||||
|       )} | ||||
|         {loading ? <LoadingOutlined/> : <PlusOutlined/>} | ||||
|         <div style={{marginTop: 8}}>Click to Upload</div> | ||||
|       </div> | ||||
|   ); | ||||
|  | ||||
|   const previewUpload = ( | ||||
|     <Image | ||||
|       className="w-full h-full" | ||||
|       preview={false} | ||||
|       src={!fileUrl ? null : `${appConfig.apiUrl}${fileUrl ?? ""}`} | ||||
|     /> | ||||
|   ); | ||||
|  | ||||
|   const handleSubmit = async (data) => { | ||||
|     console.log(data, "isi data2"); | ||||
|     try { | ||||
| @@ -134,27 +116,27 @@ export const PaybackModal = ({visible, onCreate, onCancel, initialData}) => { | ||||
|           <Form.Item | ||||
|               label="Upload Picture" | ||||
|               name="image_prove" | ||||
|         > | ||||
|           <div | ||||
|             style={{ | ||||
|               display: "flex", | ||||
|               justifyContent: "space-between", | ||||
|               alignItems: "center", | ||||
|             }} | ||||
|           > | ||||
|             <div> | ||||
|               <Upload | ||||
|                 name="image_prove" | ||||
|                 maxCount={1} | ||||
|                 className="avatar-uploader" | ||||
|                 // listType="picture-card" | ||||
|                 action={appConfig.apiUrl + "/files"} | ||||
|                   listType="picture-card" | ||||
|                   fileList={fileList} | ||||
|                 beforeUpload={beforeUpload} | ||||
|                 onPreview={handlePreview} | ||||
|                   onPreview={(file) => { | ||||
|                     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} | ||||
|               </Upload> | ||||
|               <h5 | ||||
|                   style={{ | ||||
| @@ -165,22 +147,6 @@ export const PaybackModal = ({visible, onCreate, onCancel, initialData}) => { | ||||
|                 Max size of file 2 mb | ||||
|               </h5> | ||||
|             </div> | ||||
|             <div> | ||||
|               <h5>Preview</h5> | ||||
|               <div> | ||||
|                 <img | ||||
|                   src={previewImage} | ||||
|                   alt="preview" | ||||
|                   style={{width: "100%"}} | ||||
|                 /> | ||||
|               </div> | ||||
|               <h5>{previewTitle}</h5> | ||||
|               <h5> | ||||
|                 {previewUpload} | ||||
|                 {previewTitle && <span>{`${previewTitle ?? ""}`}</span>} | ||||
|               </h5> | ||||
|             </div> | ||||
|           </div> | ||||
|           </Form.Item> | ||||
|           <Form.Item | ||||
|               name="amount" | ||||
|   | ||||
| @@ -63,7 +63,7 @@ export const Product = observer(() => { | ||||
|             </Button> | ||||
|           </Col> | ||||
|           <Col span={12}> | ||||
|             <div style={{display: 'flex', justifyContent: 'flex-end'}}> | ||||
|             <div style={{display: store.ui.mediaQuery.isMobile? "" :'flex',justifyContent: 'flex-end',textAlign: "right"}}> | ||||
|               <Search | ||||
|                   placeholder="input search text" | ||||
|                   style={{ | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user