Merge branch 'develop' of gitlab.com:empatnusabangsa/ppob/ppob-frontend into develop
This commit is contained in:
		| @@ -42,7 +42,7 @@ export const CategoryComponent = observer((props) => { | |||||||
|  |  | ||||||
|     const columns = [ |     const columns = [ | ||||||
|         { |         { | ||||||
|             title: "Product Name", |             title: "Category Name", | ||||||
|             dataIndex: "name", |             dataIndex: "name", | ||||||
|             key: "name", |             key: "name", | ||||||
|         }, |         }, | ||||||
|   | |||||||
							
								
								
									
										217
									
								
								src/component/Subcategory.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								src/component/Subcategory.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | |||||||
|  | import React, {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 {capitalize} from "lodash"; | ||||||
|  | import {useStore} from "../utils/useStore"; | ||||||
|  | import {LINKS} from "../routes/app"; | ||||||
|  |  | ||||||
|  | export const SubcategoryComponent = observer((props) => { | ||||||
|  |     const store = useStore(); | ||||||
|  |     const [form] = Form.useForm(); | ||||||
|  |     const {Option} = Select; | ||||||
|  |     const history = useHistory(); | ||||||
|  |     const [idData, setIdData] = useState(''); | ||||||
|  |     const [confirmLoading, setConfirmLoading] = useState(false); | ||||||
|  |     const [isLoading, setIsLoading] = useState(false); | ||||||
|  |  | ||||||
|  |     useEffect(() => { | ||||||
|  |         const init = async () => { | ||||||
|  |             try { | ||||||
|  |                 setIsLoading(true); | ||||||
|  |                 //store.product.pageCategories=StrToLower(props.category) | ||||||
|  |                 await store.subcategory.getData(); | ||||||
|  |                 setIsLoading(false); | ||||||
|  |             } catch (e) { | ||||||
|  |                 setIsLoading(false); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         init(); | ||||||
|  |     }, []); | ||||||
|  |  | ||||||
|  |     const handleEditButton = (data) => { | ||||||
|  |         console.log(data, "isi data") | ||||||
|  |         form.setFieldsValue({ | ||||||
|  |             name: data.name, | ||||||
|  |         }); | ||||||
|  |         store.category.visibleModalCategory = true; | ||||||
|  |         setIdData(data.id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const columns = [ | ||||||
|  |         { | ||||||
|  |             title: "Sub Category Name", | ||||||
|  |             dataIndex: "name", | ||||||
|  |             key: "name", | ||||||
|  |         }, | ||||||
|  |         // { | ||||||
|  |         //     title: "Gangguan", | ||||||
|  |         //     dataIndex: "status", | ||||||
|  |         //     key: "status", | ||||||
|  |         //     render: (text, record) => ( | ||||||
|  |         //         <Tag | ||||||
|  |         //             color={record?.status === "ACTIVE" ? "blue" : "#E3E8EE"} | ||||||
|  |         //             style={{color: "#4F566B"}} | ||||||
|  |         //         > | ||||||
|  |         //             {capitalize(record?.status)} | ||||||
|  |         //         </Tag> | ||||||
|  |         //     ), | ||||||
|  |         // }, | ||||||
|  |         // { | ||||||
|  |         //     title: "Tersedia", | ||||||
|  |         //     dataIndex: "tersedia", | ||||||
|  |         //     key: "tersedia", | ||||||
|  |         //     render: (text, record) => ( | ||||||
|  |         //         <Tag | ||||||
|  |         //             color={record?.status === "ACTIVE" ? "blue" : "#E3E8EE"} | ||||||
|  |         //             style={{color: "#4F566B"}} | ||||||
|  |         //         > | ||||||
|  |         //             {record?.status === "ACTIVE" ? " Ya" : "Tidak"} | ||||||
|  |         //         </Tag> | ||||||
|  |         //     ), | ||||||
|  |         // }, | ||||||
|  |         { | ||||||
|  |             title: "Action", | ||||||
|  |             key: "action", | ||||||
|  |             render: (text, record) => ( | ||||||
|  |                 <Space size="middle"> | ||||||
|  |                     <Button | ||||||
|  |                         onClick={() => handleEditButton(record)} | ||||||
|  |                     >Edit</Button> | ||||||
|  |                     <Button | ||||||
|  |                         onClick={() => handleDelete(record.id)} | ||||||
|  |                     > | ||||||
|  |                         Delete | ||||||
|  |                     </Button> | ||||||
|  |                 </Space> | ||||||
|  |             ), | ||||||
|  |         }, | ||||||
|  |     ]; | ||||||
|  |  | ||||||
|  |     const deleteData = async (id) => { | ||||||
|  |         try { | ||||||
|  |             console.log(id); | ||||||
|  |             await store.category.delete(id); | ||||||
|  |             message.success("Data Berhasil Dihapus"); | ||||||
|  |             history.push(LINKS.PRODUCT); | ||||||
|  |         } catch (err) { | ||||||
|  |             console.log("error", err); | ||||||
|  |             message.error("Gagal menghapus"); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const handleDelete = (id) => { | ||||||
|  |         Modal.confirm({ | ||||||
|  |             title: "Are you sure delete this record?", | ||||||
|  |             icon: <ExclamationCircleOutlined/>, | ||||||
|  |             okText: "Yes", | ||||||
|  |             okType: "primary", | ||||||
|  |             cancelText: "Cancel", | ||||||
|  |             onOk() { | ||||||
|  |                 return deleteData(id); | ||||||
|  |             }, | ||||||
|  |             onCancel() { | ||||||
|  |                 console.log("Cancel"); | ||||||
|  |             }, | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const handleCancel = () => { | ||||||
|  |         setIdData('') | ||||||
|  |         store.category.visibleModalCategory = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const handleSubmit = async (data) => { | ||||||
|  |         console.log(data, "isi data2") | ||||||
|  |         if (idData !== '') { | ||||||
|  |             setConfirmLoading(true); | ||||||
|  |             try { | ||||||
|  |                 await store.category.update(idData, data) | ||||||
|  |                 message.success("Success Update Data Category") | ||||||
|  |             } catch (e) { | ||||||
|  |                 message.error("Failed Update Data Category") | ||||||
|  |             } | ||||||
|  |             setConfirmLoading(false); | ||||||
|  |             store.category.visibleModalCategory = false; | ||||||
|  |             setIdData(''); | ||||||
|  |             form.resetFields(); | ||||||
|  |         } else { | ||||||
|  |             setConfirmLoading(true); | ||||||
|  |             try { | ||||||
|  |                 await store.category.create(data) | ||||||
|  |                 message.success("Success Add New Category") | ||||||
|  |             } catch (e) { | ||||||
|  |                 console.log(e, "apa errornya") | ||||||
|  |                 message.error("Failed Add Category") | ||||||
|  |             } | ||||||
|  |             setConfirmLoading(false); | ||||||
|  |             store.category.visibleModalCategory = false; | ||||||
|  |             setIdData(''); | ||||||
|  |             form.resetFields(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return ( | ||||||
|  |         <div> | ||||||
|  |             <Table | ||||||
|  |                 style={{textAlign: "center"}} | ||||||
|  |                 columns={columns} | ||||||
|  |                 dataSource={store.subcategory.data} | ||||||
|  |                 bordered | ||||||
|  |                 pagination={{ | ||||||
|  |                     pageSize: store.product.pageSize, | ||||||
|  |                     total: store.product.total_data, | ||||||
|  |                     current: store.product.page + 1, | ||||||
|  |                     showSizeChanger: true, | ||||||
|  |                     simple: false | ||||||
|  |                 }} | ||||||
|  |                 onChange={async (page) => { | ||||||
|  |                     let pageNumber = page.current; | ||||||
|  |                     store.product.pageSize = page.pageSize; | ||||||
|  |                     store.product.page = pageNumber - 1; | ||||||
|  |                     // store.membership.isLoading = true; | ||||||
|  |                     await store.product.getData(); | ||||||
|  |                     // store.membership.isLoading = false; | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |  | ||||||
|  |             <Modal | ||||||
|  |                 visible={store.category.visibleModalCategory} | ||||||
|  |                 title={idData ? "Edit Category" : "Create a new Category"} | ||||||
|  |                 okText={idData ? "Edit" : "Create"} | ||||||
|  |                 cancelText="Cancel" | ||||||
|  |                 onCancel={() => { | ||||||
|  |                     form.resetFields(); | ||||||
|  |                     handleCancel(); | ||||||
|  |                 }} | ||||||
|  |                 onOk={() => { | ||||||
|  |                     form | ||||||
|  |                         .validateFields() | ||||||
|  |                         .then((values) => { | ||||||
|  |                             console.log(values, "isi form") | ||||||
|  |                             handleSubmit(values); | ||||||
|  |                             form.resetFields(); | ||||||
|  |                         }) | ||||||
|  |                         .catch((info) => { | ||||||
|  |                             console.error("Validate Failed:", info); | ||||||
|  |                         }); | ||||||
|  |                 }} | ||||||
|  |             > | ||||||
|  |                 <Form | ||||||
|  |                     form={form} | ||||||
|  |                     layout="vertical" | ||||||
|  |                 > | ||||||
|  |                     <Form.Item | ||||||
|  |                         name="name" | ||||||
|  |                         label="Name" | ||||||
|  |                         rules={[{required: true, message: "Please input name category!"}]} | ||||||
|  |                     > | ||||||
|  |                         <Input/> | ||||||
|  |                     </Form.Item> | ||||||
|  |                 </Form> | ||||||
|  |             </Modal> | ||||||
|  |         </div> | ||||||
|  |     ); | ||||||
|  | }); | ||||||
| @@ -105,7 +105,7 @@ export const MenuList = observer((props) => { | |||||||
|           </Link> |           </Link> | ||||||
|         </Menu.Item> |         </Menu.Item> | ||||||
|         <Menu.Item key="sub-category"> |         <Menu.Item key="sub-category"> | ||||||
|           <Link to={LINKS.PRODUCT}> |           <Link to={LINKS.SUBCATEGORY}> | ||||||
|           <FileSyncOutlined /> |           <FileSyncOutlined /> | ||||||
|             <span>Sub Category</span> |             <span>Sub Category</span> | ||||||
|           </Link> |           </Link> | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ export const Category = observer(() => { | |||||||
|             <TabPane tab="Category" key="1"> |             <TabPane tab="Category" key="1"> | ||||||
|               <CategoryComponent/> |               <CategoryComponent/> | ||||||
|             </TabPane> |             </TabPane> | ||||||
|           ))} |           )) | ||||||
|         </Tabs> |         </Tabs> | ||||||
|       </Card> |       </Card> | ||||||
|     </div> |     </div> | ||||||
|   | |||||||
| @@ -0,0 +1,83 @@ | |||||||
|  | import React, { useEffect, useState } from "react"; | ||||||
|  | import { Button, Card, Col, Input, Row, Tabs } from "antd"; | ||||||
|  | import { FilterOutlined, PlusSquareOutlined } from "@ant-design/icons"; | ||||||
|  | import { BreadcumbComponent } from "../../component/BreadcumbComponent"; | ||||||
|  | import { useStore } from "../../utils/useStore"; | ||||||
|  | import { observer } from "mobx-react-lite"; | ||||||
|  | import { LINKS } from "../../routes/app"; | ||||||
|  | import { SubcategoryComponent } from "../../component/Subcategory"; | ||||||
|  |  | ||||||
|  | const { TabPane } = Tabs; | ||||||
|  | const { Search } = Input; | ||||||
|  |  | ||||||
|  | export const Subcategory = observer(() => { | ||||||
|  |   const [isLoading, setIsLoading] = useState(false); | ||||||
|  |   const store = useStore(); | ||||||
|  |  | ||||||
|  |   useEffect(() => { | ||||||
|  |     const init = async () => { | ||||||
|  |       try { | ||||||
|  |         setIsLoading(true); | ||||||
|  |         //await store.product.getDataCategories(); | ||||||
|  |         await store.subcategory.getDataSubCategories(); | ||||||
|  |         setIsLoading(false); | ||||||
|  |       } catch (e) { | ||||||
|  |         setIsLoading(false); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     init(); | ||||||
|  |   }, []); | ||||||
|  |  | ||||||
|  |   const handleChangeTabPane = async (key) => { | ||||||
|  |     store.product.filterCategory = key; | ||||||
|  |     console.log(key); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   const routeData = [ | ||||||
|  |     { | ||||||
|  |       route: LINKS.HOME, | ||||||
|  |       name: "Home", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       route: LINKS.SUBCATEGORY, | ||||||
|  |       name: <span style={{ fontWeight: "bold" }}>Sub Category</span>, | ||||||
|  |     }, | ||||||
|  |   ]; | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <div className={["ppob-container"].join(" ")}> | ||||||
|  |       <BreadcumbComponent data={routeData} /> | ||||||
|  |       <Card> | ||||||
|  |         <Row style={{ marginBottom: 20 }}> | ||||||
|  |           <Col span={12}> | ||||||
|  |             <Button> | ||||||
|  |               <FilterOutlined /> | ||||||
|  |               Filter | ||||||
|  |             </Button> | ||||||
|  |           </Col> | ||||||
|  |           <Col span={12} style={{ textAlign: "right" }}> | ||||||
|  |             <Search | ||||||
|  |               placeholder="input search text" | ||||||
|  |               style={{ | ||||||
|  |                 width: store.ui.mediaQuery.isMobile ? 160 : 200, | ||||||
|  |                 marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, | ||||||
|  |                 marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, | ||||||
|  |               }} | ||||||
|  |             /> | ||||||
|  |             <Button onClick={() => (store.category.visibleModalCategory = true)}> | ||||||
|  |               <PlusSquareOutlined /> New | ||||||
|  |             </Button> | ||||||
|  |           </Col> | ||||||
|  |         </Row> | ||||||
|  |  | ||||||
|  |         <Tabs onChange={handleChangeTabPane} size="default" tabBarGutter="50"> | ||||||
|  |             <TabPane tab="Sub-Category" key="1"> | ||||||
|  |               <SubcategoryComponent/> | ||||||
|  |             </TabPane> | ||||||
|  |           )) | ||||||
|  |         </Tabs> | ||||||
|  |       </Card> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }); | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import {Partner} from "../pages/Config/Partner"; | |||||||
| import {Supplier} from "../pages/Config/Supplier"; | import {Supplier} from "../pages/Config/Supplier"; | ||||||
| import {Category} from "../pages/Product/Category"; | import {Category} from "../pages/Product/Category"; | ||||||
| import {Payback} from "../pages/Payback/Payback"; | import {Payback} from "../pages/Payback/Payback"; | ||||||
|  | import {Subcategory} from "../pages/Product/Subcategory"; | ||||||
|  |  | ||||||
| export const LINKS = { | export const LINKS = { | ||||||
|     HOME: "/app/home", |     HOME: "/app/home", | ||||||
| @@ -24,6 +24,7 @@ export const LINKS = { | |||||||
|     SUPPLIER: "/app/supplier", |     SUPPLIER: "/app/supplier", | ||||||
|     CATEGORY: "/app/category", |     CATEGORY: "/app/category", | ||||||
|     PAYBACK: "/app/payback", |     PAYBACK: "/app/payback", | ||||||
|  |     SUBCATEGORY: "/app/subcategory", | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -38,6 +39,9 @@ export const AppRoute = () => { | |||||||
|         <Route path={LINKS.CATEGORY}> |         <Route path={LINKS.CATEGORY}> | ||||||
|             <Category/> |             <Category/> | ||||||
|         </Route> |         </Route> | ||||||
|  |         <Route path={LINKS.SUBCATEGORY}> | ||||||
|  |             <Subcategory/> | ||||||
|  |         </Route> | ||||||
|         <Route path={LINKS.SUPPLIER}> |         <Route path={LINKS.SUPPLIER}> | ||||||
|             <Supplier/> |             <Supplier/> | ||||||
|         </Route> |         </Route> | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import { Commission } from "./commission"; | |||||||
| import { Transaction } from "./transaction"; | import { Transaction } from "./transaction"; | ||||||
| import { TokenUtil } from "../utils/token"; | import { TokenUtil } from "../utils/token"; | ||||||
| import { Category } from "./category"; | import { Category } from "./category"; | ||||||
|  | import { Subcategory } from "./subcategory"; | ||||||
|  |  | ||||||
| import { Role } from "./role"; | import { Role } from "./role"; | ||||||
|  |  | ||||||
| @@ -23,6 +24,7 @@ export class Store { | |||||||
|     commission = new Commission(this); |     commission = new Commission(this); | ||||||
|     category = new Category(this); |     category = new Category(this); | ||||||
|     transaction = new Transaction(this); |     transaction = new Transaction(this); | ||||||
|  |     subcategory = new Subcategory(this); | ||||||
|     role = new Role(this); |     role = new Role(this); | ||||||
|  |  | ||||||
|     constructor() { |     constructor() { | ||||||
|   | |||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | import {makeAutoObservable} from "mobx"; | ||||||
|  | import {http} from "../utils/http"; | ||||||
|  |  | ||||||
|  | export class Subcategory { | ||||||
|  |     page = 0; | ||||||
|  |     pageSize = 10 | ||||||
|  |     data = []; | ||||||
|  |     total_data = 0; | ||||||
|  |     filterCategory = null; | ||||||
|  |     visibleModalCategory = false; | ||||||
|  |  | ||||||
|  |     pageCategories = 0; | ||||||
|  |     pageSizeCategories = 10 | ||||||
|  |     dataCategories = []; | ||||||
|  |     total_dataCategories = 0; | ||||||
|  |  | ||||||
|  |     pageSubCategories = 0; | ||||||
|  |     pageSizeSubCategories = 10 | ||||||
|  |     dataSubCategories = []; | ||||||
|  |     total_dataSubCategories = 0; | ||||||
|  |  | ||||||
|  |     constructor(ctx) { | ||||||
|  |         this.ctx = ctx; | ||||||
|  |         makeAutoObservable(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async getData() { | ||||||
|  |         const response = await http.get(`/product/sub-categories?page=${this.page}&pageSize=${this.pageSize}`); | ||||||
|  |         console.log(response) | ||||||
|  |         this.data = response.body.data ?? [] | ||||||
|  |         this.total_data = response.body.total_data ?? 0 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async getDataSubCategories() { | ||||||
|  |         const response = await http.get(`/product/sub-categories?page=${this.pageSubCategories}&pageSize=${this.pageSizeSubCategories}`); | ||||||
|  |         console.log(response) | ||||||
|  |         this.dataSubCategories = response.body.data ?? [] | ||||||
|  |         this.total_dataSubCategories = response.body.count ?? 0 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async getDataCategories() { | ||||||
|  |         const response = await http.get(`/product/categories?page=${this.pageCategories}&pageSize=${this.pageSizeCategories}`); | ||||||
|  |  | ||||||
|  |         this.dataCategories = response.body.data ?? [] | ||||||
|  |         this.total_dataCategories = response.body.total_data ?? 0 | ||||||
|  |         if (this.dataCategories.length > 0) { | ||||||
|  |             this.filterCategory = this.dataCategories[0].id | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async create(data) { | ||||||
|  |         const response = await http.post('/product/categories').send(data); | ||||||
|  |         await this.getData(); | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async update(id, data) { | ||||||
|  |         const response = await http.put(`/product/categories/${id}`).send(data); | ||||||
|  |         await this.getData(); | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async delete(id) { | ||||||
|  |         const response = await http.del(`/product/${id}`); | ||||||
|  |         await this.getData(); | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user