From 7852e12d42a004952e23c56beb22e4c3db4ac30c Mon Sep 17 00:00:00 2001 From: ajat91 Date: Thu, 9 Dec 2021 20:04:37 +0700 Subject: [PATCH 01/24] Pages Product --- src/config/app.js | 2 +- src/pages/Product/Product.js | 60 ++++++++- src/pages/Product/Pulsa.js | 227 ++++++++++++++++++-------------- src/pages/Product/PulsaModal.js | 213 ++++++++++++++++++++++++++++++ src/store/categories.js | 40 ++++++ src/store/index.js | 4 + src/store/product.js | 40 ++++++ src/store/user.js | 2 +- 8 files changed, 482 insertions(+), 106 deletions(-) create mode 100644 src/pages/Product/PulsaModal.js create mode 100644 src/store/categories.js create mode 100644 src/store/product.js diff --git a/src/config/app.js b/src/config/app.js index 92eae9f..36a03ee 100644 --- a/src/config/app.js +++ b/src/config/app.js @@ -1,5 +1,5 @@ export const appConfig = { - apiUrl: 'https://api-reconcile.movic.id' + apiUrl: 'http://localhost:3222/v1' }; //export default appConfig; diff --git a/src/pages/Product/Product.js b/src/pages/Product/Product.js index edbefb0..72e5203 100644 --- a/src/pages/Product/Product.js +++ b/src/pages/Product/Product.js @@ -1,16 +1,30 @@ -import React from "react"; -import {Button, Card, Col, Input, Row, Tabs} from "antd"; +import React,{useState,useEffect} from "react"; +import {Button, Card, Col, Input, Row, Tabs,message} from "antd"; import {FilterOutlined, PlusSquareOutlined,} from "@ant-design/icons"; import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import {Pulsa} from "./Pulsa"; +import {PulsaModal} from "./PulsaModal"; +import {useStore} from "../../utils/useStore"; +import {observer} from "mobx-react-lite"; + + + const {TabPane} = Tabs; const {Search} = Input; -export const Product = () => { +export const Product =observer(() => { + const [visibleModal, setVisibleModal] = useState(false) + const [initialData, setInitialData] = useState({}) + const [confirmLoading, setConfirmLoading] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const store = useStore(); + + const callback = (key) => { console.log(key); }; + const routeData = [ { route: "/app/home", @@ -21,6 +35,32 @@ export const Product = () => { name: Product, }, ]; + const onSubmit = async (data) => { + if (initialData.id) { + setInitialData({}) + setConfirmLoading(true); + try { + await store.product.update(initialData.id, data) + message.success("Success Update Data Member") + } catch (e) { + message.error("Failed Update Data Member") + } + setConfirmLoading(false); + setVisibleModal(false); + } else { + setInitialData({}) + setConfirmLoading(true); + try { + await store.product.create(data) + message.success("Success Add New Member") + } catch (e) { + console.log(e, "apa errornya") + message.error("Failed Add Member") + } + setConfirmLoading(false); + setVisibleModal(false); + } + } return (
@@ -37,7 +77,7 @@ export const Product = () => { placeholder="input search text" style={{width: 200, marginRight: 10}} /> - @@ -65,6 +105,16 @@ export const Product = () => { + { + onSubmit(data) + }} + onCancel={() => { + setInitialData({}) + setVisibleModal(false); + }}/>
); -}; +}); diff --git a/src/pages/Product/Pulsa.js b/src/pages/Product/Pulsa.js index b633fd1..6525fdc 100644 --- a/src/pages/Product/Pulsa.js +++ b/src/pages/Product/Pulsa.js @@ -1,100 +1,129 @@ -import React from "react"; -import {Button, Space, Table, Tag} from "antd"; +import React, { useEffect, useState, useParams } from "react"; +import { Button, Space, Table, Tag, Modal, message } from "antd"; +import { useStore } from "../../utils/useStore"; +import { observer } from "mobx-react-lite"; +import { ExclamationCircleOutlined } from "@ant-design/icons"; +import { useHistory } from "react-router-dom"; -export const Pulsa = () => { - const columns = [ - { - title: "Kode", - dataIndex: "kode", - key: "kode", - }, - { - title: "Produk", - dataIndex: "produk", - key: "produk", - }, - { - title: "Harga Beli", - dataIndex: "harga_beli", - key: "harga_beli", - }, - , - { - title: "Harga Jual", - dataIndex: "harga_jual", - key: "harga_beli", - }, - { - title: "Gangguan", - dataIndex: "gangguan", - key: "gangguan", - }, - { - title: "Tersedia", - dataIndex: "tersedia", - key: "tersedia", - }, - { - title: "Action", - key: "action", - render: (text, record) => ( - - - - - ), - }, - ]; - const dataSource = [ - { - key: "1", - kode: "BROP2", - produk: "DATA AXIS 2GB-60HR", - harga_beli: "Rp.10.000", - harga_beli: "Rp.10.000", - harga_jual: "Rp.40.000", - gangguan: Active, - tersedia: Ya, - }, - { - key: "2", - kode: "-", - produk: "-", - harga_beli: "-", - harga_beli: "-", - harga_jual: "-", - gangguan: Gangguan, - tersedia: Tidak, - }, - { - key: "3", - kode: "-", - produk: "-", - harga_beli: "-", - harga_beli: "-", - harga_jual: "-", - gangguan: Active, - tersedia: Ya, - }, - { - key: "4", - kode: "-", - produk: "-", - harga_beli: "-", - harga_beli: "-", - harga_jual: "-", - gangguan: Active, - tersedia: Ya, - } - ]; - return ( -
- - - ); -}; +export const Pulsa = observer(() => { + const store = useStore(); + const history = useHistory(); + const [visibleModal, setVisibleModal] = useState(false); + const [initialData, setInitialData] = useState({}); + const [confirmLoading, setConfirmLoading] = useState(false); + const [isLoading, setIsLoading] = useState(false); + useEffect(() => { + const init = async () => { + try { + setIsLoading(true); + await store.product.getData(); + setIsLoading(false); + } catch (e) { + setIsLoading(false); + } + }; + + init(); + }, []); + const columns = [ + { + title: "Kode", + dataIndex: "code", + key: "code", + }, + { + title: "Produk", + dataIndex: "name", + key: "name", + }, + { + title: "Harga Beli", + dataIndex: "price", + key: "price", + }, + , + { + title: "Harga Jual", + dataIndex: "mark_up_price", + key: "mark_up_price", + }, + { + title: "Gangguan", + dataIndex: "status", + key: "status", + render: (text, record) => ( + + {record?.status} + + ), + }, + { + title: "Tersedia", + dataIndex: "tersedia", + key: "tersedia", + render: (text, record) => ( + + {record?.status === "AKTIF" ? " Ya" : "Tidak"} + + ), + }, + { + title: "Action", + key: "action", + render: (text, record) => ( + + + + + ), + }, + ]; + const deleteData = async (id) => { + try { + console.log(id); + await store.product.delete(id); + message.success("Data Berhasil Dihapus"); + history.push("/app/product"); + } catch (err) { + console.log("error", err); + message.error("Gagal menghapus"); + } + }; + const handleDelete = (id) => { + Modal.confirm({ + title: "Are you sure delete this record?", + icon: , + okText: "Yes", + okType: "primary", + cancelText: "Cancel", + onOk() { + return deleteData(id); + }, + onCancel() { + console.log("Cancel"); + }, + }); + }; + return ( +
+
+ + ); +}); diff --git a/src/pages/Product/PulsaModal.js b/src/pages/Product/PulsaModal.js new file mode 100644 index 0000000..822e394 --- /dev/null +++ b/src/pages/Product/PulsaModal.js @@ -0,0 +1,213 @@ +// import React,{useEffect,useState} from "react"; +// import { Form, Input, Modal, Select } from "antd"; + +// export const PulsaModal = ({ visible, onCreate, onCancel, initialData }) => { +// const [form] = Form.useForm(); +// const { Option } = Select; +// const [visibleModal, setVisibleModal] = useState(false) +// const [initialData, setInitialData] = useState({}) +// const [confirmLoading, setConfirmLoading] = useState(false); +// const [isLoading, setIsLoading] = useState(false); +// useEffect(() => { +// const init = async () => { +// try { +// setIsLoading(true); +// await store.categories.getData(); +// setIsLoading(false); +// } catch (e) { +// setIsLoading(false); +// } +// }; + +// init(); +// }, []); + +// return ( +// { +// onSubmit(data) +// }} +// onCancel={() => { +// setInitialData({}) +// setVisibleModal(false); +// }} +// visible={visible} +// title={initialData.id ? "Edit Member" : "Create a new Member"} +// okText={initialData.id ? "Edit" : "Create"} +// cancelText="Cancel" +// onCancel={() => { +// form.resetFields(); +// onCancel(); +// }} +// onOk={() => { +// form +// .validateFields() +// .then((values) => { +// onCreate(values); +// form.resetFields(); +// }) +// .catch((info) => { +// console.log("Validate Failed:", info); +// }); +// }} +// > +//
+// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +//
+// ); +// }; +import React, { useState, useEffect } from "react"; +import { Form, Input, Modal, Select } from "antd"; +import { useStore } from "../../utils/useStore"; + +export const PulsaModal = ({ visible, onCreate, onCancel }) => { + const [form] = Form.useForm(); + const { Option } = Select; + const dataStatus = ["Active", "Inactive"]; + const store = useStore(); + const [visibleModal, setVisibleModal] = useState(false); + const [initialData, setInitialData] = useState({}); + const [confirmLoading, setConfirmLoading] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const init = async () => { + try { + setIsLoading(true); + await store.categories.getData(); + setIsLoading(false); + } catch (e) { + setIsLoading(false); + } + }; + + useEffect(() => { + init(); + }, []); + + return ( + { + form.resetFields(); + onCancel(); + }} + onOk={() => { + form + .validateFields() + .then((values) => { + onCreate(values); + form.resetFields(); + }) + .catch((info) => { + console.log("Validate Failed:", info); + }); + }} + > +
+ + + + + + + + + + + + + + + + + + + +
+ ); +}; diff --git a/src/store/categories.js b/src/store/categories.js new file mode 100644 index 0000000..603aa3a --- /dev/null +++ b/src/store/categories.js @@ -0,0 +1,40 @@ +import {action, makeAutoObservable} from "mobx"; +import {http} from "../utils/http"; + +export class Categories { + page = 0; + pageSize = 10 + data = []; + total_data = 0 + + constructor(ctx) { + this.ctx = ctx; + makeAutoObservable(this); + } + + @action + async getData() { + const response = await http.get(`/product/sub-categories?page=${this.page}&pageSize=${this.pageSize}`); + console.log(response,'Data cate') + console.log(JSON.stringify(response.body.data),'Data') + + this.data = response.body.data ?? [] + this.total_data = response.body.total_data ?? 0 + } + + @action + async create(data) { + return await http.post('/user').send(data) + } + + @action + async update(id, data) { + return await http.put('/user/' + id).send(data); + } + + async delete(id) { + return await http.del('/product/' + id); + } +} + + diff --git a/src/store/index.js b/src/store/index.js index e3e59fb..e6250f3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2,12 +2,16 @@ import {UI} from "./ui"; import {Authentication} from "./authentication"; import {User} from "./user"; import {Membership} from "./membership"; +import {Product} from "./product"; +import {Categories} from "./categories"; export class Store { ui = new UI(this); authentication = new Authentication(this); user = new User(this); membership = new Membership(this); + product = new Product(this); + categories = new Categories(this); constructor() { } diff --git a/src/store/product.js b/src/store/product.js new file mode 100644 index 0000000..691a434 --- /dev/null +++ b/src/store/product.js @@ -0,0 +1,40 @@ +import {action, makeAutoObservable} from "mobx"; +import {http} from "../utils/http"; + +export class Product { + page = 0; + pageSize = 10 + data = []; + total_data = 0 + + constructor(ctx) { + this.ctx = ctx; + makeAutoObservable(this); + } + + @action + async getData() { + const response = await http.get(`/product?page=${this.page}&pageSize=${this.pageSize}`); + console.log(response,'Data') + console.log(JSON.stringify(response.body.data),'Data') + + this.data = response.body.data ?? [] + this.total_data = response.body.total_data ?? 0 + } + + @action + async create(data) { + return await http.post('/product').send(data) + } + + @action + async update(id, data) { + return await http.put('/user/' + id).send(data); + } + + async delete(id) { + return await http.del('/product/' + id); + } +} + + diff --git a/src/store/user.js b/src/store/user.js index 741da5b..00722be 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -6,7 +6,7 @@ export class User { @action async getData() { - this.data = (await http.get('/user')).body.data; + this.data = (await http.get('/product')).body.data; } } From c452e8ed77622033ffe095175b91b105467546c9 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 11:31:02 +0700 Subject: [PATCH 02/24] feat: init responsive mode --- src/component/BreadcumbComponent.js | 4 +- src/index.css | 7 + src/pages/About/About.js | 2 +- src/pages/App/App.js | 1 + src/pages/App/DesktopLayout.js | 416 +++++++++++++++++++++++----- src/pages/Home/Home.js | 2 +- src/pages/Membership/Membership.js | 3 +- src/store/ui.js | 18 +- 8 files changed, 379 insertions(+), 74 deletions(-) diff --git a/src/component/BreadcumbComponent.js b/src/component/BreadcumbComponent.js index e5690ad..75b4494 100644 --- a/src/component/BreadcumbComponent.js +++ b/src/component/BreadcumbComponent.js @@ -6,8 +6,8 @@ export const BreadcumbComponent = (props) => { return (
- {props.data.map((e) => ( - + {props.data.map((e, index) => ( + {e.name} diff --git a/src/index.css b/src/index.css index b244ccd..e81bbc3 100644 --- a/src/index.css +++ b/src/index.css @@ -46,3 +46,10 @@ code { background: #2D9CDB !important; } +.transparent { + background: transparent +} + +.ppob-container { + padding: 14px 14px 14px 14px; +} diff --git a/src/pages/About/About.js b/src/pages/About/About.js index 72330e5..242c868 100644 --- a/src/pages/About/About.js +++ b/src/pages/About/About.js @@ -2,7 +2,7 @@ import React from "react"; import {PageHeader} from "antd"; export const About = () => { - return
+ return
{ diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index a0156f5..d41f7d7 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -1,14 +1,17 @@ import React, {useState} from "react"; -import {Button, Layout, Menu, Popover, Typography,} from "antd"; +import {Button, Drawer, Layout, Menu, Popover, Typography,} from "antd"; import {MenuList} from "./MenuList"; import {Link} from "react-router-dom"; -import {PlusSquareOutlined, UserOutlined,} from "@ant-design/icons"; +import {CalendarOutlined, HomeOutlined, MenuOutlined, UserOutlined,} from "@ant-design/icons"; import {AppRoute} from "../../routes/app"; +import {useStore} from "../../utils/useStore"; +import {observer} from "mobx-react-lite"; const {Text, Paragraph} = Typography; const {Header, Content, Sider} = Layout; -export const DesktopLayout = () => { +export const DesktopLayout = observer(() => { + const store = useStore(); const [clicked, setClicked] = useState(false); return ( @@ -23,7 +26,7 @@ export const DesktopLayout = () => { height: "100vh", }} > - {
{ }}/> - + } + + {store.ui.mediaQuery.isMobile && ( + { + store.ui.toggleLeftDrawerIsShown() + console.log("clicked"); + }} + visible={store.ui.leftDrawerIsShown} + key={"dashboard-drawer"} + bodyStyle={{ + padding: 0, + paddingTop: 20, + }} + > +
+ + + + + Home + + + + + + Membership + + + + + + Product + + + + + + Transaction + + + + + + About + + + + +
+
+ )}
- - +
- - - Profile - - - + } onClick={() => { - // store.authentication.logout(); - // return history.push("/login"); + store.ui.toggleLeftDrawerIsShown(); + console.log("apa") + }} + /> +
- Sign out - - - } - title={ - - info@bangun-kreatif.com - {/*{store.userData.email}{" "}*/} - - Administrator - {/*{store.userData.role}*/} - - - } - trigger="click" - visible={clicked} - onVisibleChange={() => setClicked(!clicked)} - > -
+ + + + Profile + + + { + // store.authentication.logout(); + // return history.push("/login"); + }} + > + Sign out + + + } + title={ + + {/*{store.user.data.email}{" "}*/} + {/**/} + {/* {store.authentication.userData.full_name}*/} + {/**/} + + } + trigger="click" + visible={clicked} + onVisibleChange={() => setClicked(!clicked)} + > +
+
+ {/**/} +
+ )} + + {store.ui.mediaQuery.isDesktop && ( +
+
+
+ + + + Profile + + + { + // store.authentication.logout(); + // return history.push("/login"); + }} + > + Sign out + + + } + title={ + + {store.user.data.email}{" "} + + {/*{store.authentication.userData.full_name}*/} + + + } + trigger="click" + visible={clicked} + onVisibleChange={() => setClicked(!clicked)} + > +
+ )}
- + + + + + +
); -}; +}); diff --git a/src/pages/Home/Home.js b/src/pages/Home/Home.js index 198586b..5a96c09 100644 --- a/src/pages/Home/Home.js +++ b/src/pages/Home/Home.js @@ -4,7 +4,7 @@ import {store} from "../../utils/useStore"; import {observer} from "mobx-react-lite"; export const Home = observer(() => { - return
+ return
{ } return ( -
+
{store.ui.mediaQuery.isDesktop && ( @@ -201,7 +201,6 @@ export const Membership = observer(() => { dataSource={store.membership.data} style={{padding: 0}} renderItem={(item) => { - console.log(item, "item ->"); return (
Date: Thu, 9 Dec 2021 12:53:55 +0700 Subject: [PATCH 03/24] fix: responsive each pages --- src/index.css | 4 + src/pages/App/DesktopLayout.js | 8 +- src/pages/Membership/Membership.js | 161 ++++++--------------------- src/pages/Transaction/Transaction.js | 2 +- 4 files changed, 44 insertions(+), 131 deletions(-) diff --git a/src/index.css b/src/index.css index e81bbc3..39746de 100644 --- a/src/index.css +++ b/src/index.css @@ -53,3 +53,7 @@ code { .ppob-container { padding: 14px 14px 14px 14px; } + +.shadow { + box-shadow: 0 7px 14px 0 rgba(60, 66, 87, 0.05), 0 3px 6px 0 rgba(0, 0, 0, 0.05); +} \ No newline at end of file diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index d41f7d7..7d1edf9 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -18,7 +18,7 @@ export const DesktopLayout = observer(() => { { theme={"light"} className={store.ui.mediaQuery.isMobile ? "shadow" : null} style={{ - height: store.ui.mediaQuery.isDesktop ? 54 : 35, + height: store.ui.mediaQuery.isDesktop ? 24 : 35, // width: 'calc(100vw - 200px)', width: "100%", position: store.ui.mediaQuery.isDesktop ? "fixed" : "fixed", @@ -158,7 +158,7 @@ export const DesktopLayout = observer(() => { backgroundColor: store.ui.mediaQuery.isMobile ? "#fff" : "transparent", - maxWidth: store.ui.mediaQuery.isDesktop ? 1920 : 768, + maxWidth: store.ui.mediaQuery.isDesktop ? 1024 : 768, // minWidth: store.ui.mediaQuery.isDesktop ? 768 : 0, top: store.ui.mediaQuery.isMobile ? 0 : 12, /**/ @@ -426,7 +426,7 @@ export const DesktopLayout = observer(() => { zIndex: 22, // height: `calc(100vh - ${store.ui.mediaQuery.isDesktop ? 78 : 71}px)`, height: `calc(100vh - ${ - store.ui.mediaQuery.isDesktop ? 78 : 71 + store.ui.mediaQuery.isDesktop ? 43 : 37 }px)`, // paddingLeft: 8, // paddingRight: 8 diff --git a/src/pages/Membership/Membership.js b/src/pages/Membership/Membership.js index 7add9f3..72276fa 100644 --- a/src/pages/Membership/Membership.js +++ b/src/pages/Membership/Membership.js @@ -1,5 +1,5 @@ import React, {useEffect, useState} from "react"; -import {Button, Card, Col, Input, List, message, Modal, PageHeader, Row, Space, Table, Tag} from "antd"; +import {Button, Card, Col, Input, message, Modal, Row, Space, Table, Tag} from "antd"; import {useStore} from "../../utils/useStore"; import {observer} from "mobx-react-lite"; import {ExclamationCircleOutlined, FilterOutlined, PlusSquareOutlined,} from "@ant-design/icons"; @@ -137,132 +137,41 @@ export const Membership = observer(() => {
- {store.ui.mediaQuery.isDesktop && ( -
- -
- - - - - - - -
{ - store.membership.pageSize = page.pageSize; - store.membership.page = page.current; - store.membership.getData(); - }} current={store.membership.page} - loading={store.membership.pageSize}/> - - )} - {store.ui.mediaQuery.isMobile && ( -
- - } - size={"small"} - style={{margin: 3}} - > - Filter - - } - subTitle="" - /> - - - { - return ( -
- - {item.name}} - description={ -
-

- Username : {item.username}
-

-

- {item.status} -

-
- } - /> - {/*
- - {item.updated_at ? moment(item.updated_at).format("DD MMM YY, H:mm:ss") : "There is not top up yet"} -

- } - prefix={"Rp"} - precision={0} - style={{ fontSize: 12, fontWeight: 300 }} - valueStyle={{ - color: "#5469d4", - fontSize: 12, - fontWeight: 600, - textAlign: "right", - }} - value={item.balances} - /> - -
*/} -
- {/* */} -
- ); - }} +
+ +
+ + + + - - )} + + + +
{ + store.membership.pageSize = page.pageSize; + store.membership.page = page.current; + store.membership.getData(); + }} current={store.membership.page} + loading={store.membership.pageSize}/> + { }, ]; return ( -
+
From b2ca591fee4b12f33b64ac246c205d51e11de93e Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 14:35:14 +0700 Subject: [PATCH 04/24] fix: responsive layout --- package.json | 3 +- src/index.css | 10 +-- src/pages/App/DesktopLayout.js | 10 ++- src/pages/Membership/Membership.js | 107 ++++++++++++++++++++++++----- yarn.lock | 19 +++-- 5 files changed, 114 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index bd09d63..78c12c6 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "camelcase": "^6.2.0", "case-sensitive-paths-webpack-plugin": "2.4.0", "css-loader": "4.3.0", + "date-fns": "^2.27.0", "dotenv": "8.2.0", "dotenv-expand": "5.1.0", "eslint": "^7.28.0", @@ -61,7 +62,7 @@ "react-dev-utils": "^11.0.4", "react-dom": "^17.0.2", "react-refresh": "^0.8.3", - "react-responsive": "^8.2.0", + "react-responsive": "^9.0.0-beta.5", "react-router-dom": "^5.2.0", "react-router-transition": "^2.1.0", "resolve": "1.20.0", diff --git a/src/index.css b/src/index.css index 39746de..1e43dce 100644 --- a/src/index.css +++ b/src/index.css @@ -24,11 +24,11 @@ code { border-color: #2D9CDB !important; } -.ant-card { - margin-bottom: 30px !important; - width: 1000px; - height: auto; -} +/*.ant-card {*/ +/* margin-bottom: 30px !important;*/ +/* width: 1000px;*/ +/* height: auto;*/ +/*}*/ .ant-table-cell { text-align: center !important; diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index 7d1edf9..2a1da7a 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -6,11 +6,13 @@ import {CalendarOutlined, HomeOutlined, MenuOutlined, UserOutlined,} from "@ant- import {AppRoute} from "../../routes/app"; import {useStore} from "../../utils/useStore"; import {observer} from "mobx-react-lite"; +import {useMediaQuery} from "react-responsive"; const {Text, Paragraph} = Typography; const {Header, Content, Sider} = Layout; export const DesktopLayout = observer(() => { + const xl = useMediaQuery({minWidth: 1024}); const store = useStore(); const [clicked, setClicked] = useState(false); @@ -20,10 +22,12 @@ export const DesktopLayout = observer(() => { className={"transparent"} hasSider={store.ui.mediaQuery.isDesktop} style={{ - paddingLeft: 0, + paddingLeft: xl ? "calc(70vw - 1024px)" : "0", display: "flex", - width: "100vw", - height: "100vh", + // minWidth: 1024, + width: "100%", + height: "100%", + position: "relative", }} > {store.ui.mediaQuery.isDesktop && { }, { title: "Username", - dataIndex: "username", - key: "username", + dataIndex: "name", + key: "name", }, { title: "Status", @@ -155,22 +156,90 @@ export const Membership = observer(() => { -
{ - store.membership.pageSize = page.pageSize; - store.membership.page = page.current; - store.membership.getData(); - }} current={store.membership.page} - loading={store.membership.pageSize}/> + + {store.ui.mediaQuery.isDesktop && ( +
{ + store.membership.pageSize = page.pageSize; + store.membership.page = page.current; + store.membership.getData(); + }} + current={store.membership.page} + loading={store.membership.pageSize} + />)} + + {store.ui.mediaQuery.isMobile && ( + { + store.membership.pageSize = page.pageSize; + store.membership.page = page.current; + store.membership.getData(); + }, + pageSize: store.membership.pageSize, + total: store.membership.total_data, + current: store.membership.page, + style: {marginBottom: '1rem', marginRight: '1rem'} + }} + dataSource={store.membership.data} + style={{padding: 0}} + renderItem={(item) => { + return ( +
+ + +

+ Email : {item.email}
+

+
+ } + /> +
+

+ {format(new Date(item.created_at), "dd-MM-yyyy")} +

+
+ + + + ); + }} + /> + )} Date: Thu, 9 Dec 2021 19:02:02 +0700 Subject: [PATCH 05/24] fix: change key --- src/pages/App/MenuList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/App/MenuList.js b/src/pages/App/MenuList.js index 8f061a8..1e81b44 100644 --- a/src/pages/App/MenuList.js +++ b/src/pages/App/MenuList.js @@ -51,7 +51,7 @@ export const MenuList = observer((props) => { Product - + Transaction From b20835257e2fb67c74f15c67e0552c6b4ed94638 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 19:55:53 +0700 Subject: [PATCH 06/24] fix: card product responsive --- src/pages/Transaction/Pulsa.js | 214 +++++++++++++-------------- src/pages/Transaction/Transaction.js | 4 +- 2 files changed, 106 insertions(+), 112 deletions(-) diff --git a/src/pages/Transaction/Pulsa.js b/src/pages/Transaction/Pulsa.js index 6392849..ded433a 100644 --- a/src/pages/Transaction/Pulsa.js +++ b/src/pages/Transaction/Pulsa.js @@ -2,126 +2,120 @@ import React from "react"; import {Button, Card, Col, Dropdown, Menu, message, Modal, Row, Space,} from "antd"; import {DownOutlined, TabletOutlined, UserOutlined} from "@ant-design/icons"; -//const style = { background: "#0092ff", padding: "8px 0" }; -const gridStyle = { - width: "18%", - textAlign: "center", - marginRight: "8px", - marginBottom: "20px", -}; - export const Pulsa = () => { - function handleMenuClick(e) { - message.info("Click on menu item."); - console.log("click", e); - } + function handleMenuClick(e) { + message.info("Click on menu item."); + console.log("click", e); + } - const menu = ( - - }> - 1st menu item - - }> - 2nd menu item - - }> - 3rd menu item - - - ); + const menu = ( + + }> + 1st menu item + + }> + 2nd menu item + + }> + 3rd menu item + + + ); - function success() { - Modal.success({ - content: 'some messages...some messages...', - }); - } + function success() { + Modal.success({ + content: 'some messages...some messages...', + }); + } - return ( -
- + const dataCard = [ + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + { + title: "DATA AXIS BRONET 2GB-60HR", + price: "Harga : Rp.6.000", + }, + ] + + return ( +
+ Sub-Category - - - - - - - - - + + + + + + + + + Produk & Nominal - - - - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
- - DATA AXIS BRONET 2GB-60HR -
- Harga : Rp.6.000 -
-
-
- - - + + + {dataCard.map((item, index) => ( + + + {item.title} +
+ {item.price} +
+ + ))} + + + + + ); }; diff --git a/src/pages/Transaction/Transaction.js b/src/pages/Transaction/Transaction.js index c255002..9d42dfe 100644 --- a/src/pages/Transaction/Transaction.js +++ b/src/pages/Transaction/Transaction.js @@ -55,10 +55,10 @@ export const Transaction = () => { Product - Prduct + Product - Prdct + Product From 62dfdbe40a40260d96863d43e7256469b82f0bf0 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 23:00:56 +0700 Subject: [PATCH 07/24] feat: implement login --- src/config/app.js | 2 +- src/pages/App/DesktopLayout.js | 19 ++-- src/pages/Login/Login.js | 172 +++++++++++---------------------- src/routes/index.js | 5 +- src/store/authentication.js | 54 +++++++++-- src/store/index.js | 5 + src/store/user.js | 2 +- src/utils/token.js | 17 ---- 8 files changed, 124 insertions(+), 152 deletions(-) diff --git a/src/config/app.js b/src/config/app.js index 36a03ee..e4b7ca0 100644 --- a/src/config/app.js +++ b/src/config/app.js @@ -1,5 +1,5 @@ export const appConfig = { - apiUrl: 'http://localhost:3222/v1' + apiUrl: 'https://ppob-backend.k3s.bangun-kreatif.com/v1' }; //export default appConfig; diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index 2a1da7a..abf523d 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -1,7 +1,7 @@ import React, {useState} from "react"; import {Button, Drawer, Layout, Menu, Popover, Typography,} from "antd"; import {MenuList} from "./MenuList"; -import {Link} from "react-router-dom"; +import {Link, useHistory} from "react-router-dom"; import {CalendarOutlined, HomeOutlined, MenuOutlined, UserOutlined,} from "@ant-design/icons"; import {AppRoute} from "../../routes/app"; import {useStore} from "../../utils/useStore"; @@ -12,6 +12,7 @@ const {Text, Paragraph} = Typography; const {Header, Content, Sider} = Layout; export const DesktopLayout = observer(() => { + let history = useHistory(); const xl = useMediaQuery({minWidth: 1024}); const store = useStore(); const [clicked, setClicked] = useState(false); @@ -268,8 +269,8 @@ export const DesktopLayout = observer(() => { { - // store.authentication.logout(); - // return history.push("/login"); + store.authentication.logout(); + history.push("/login"); }} > Sign out @@ -278,10 +279,10 @@ export const DesktopLayout = observer(() => { } title={ - {/*{store.user.data.email}{" "}*/} - {/**/} - {/* {store.authentication.userData.full_name}*/} - {/**/} + {store.user.data.email}{" "} + + {store.authentication.userData.email} + } trigger="click" @@ -359,8 +360,8 @@ export const DesktopLayout = observer(() => { { - // store.authentication.logout(); - // return history.push("/login"); + store.authentication.logout(); + history.push("/login"); }} > Sign out diff --git a/src/pages/Login/Login.js b/src/pages/Login/Login.js index 9c5090a..14f1e6f 100644 --- a/src/pages/Login/Login.js +++ b/src/pages/Login/Login.js @@ -1,51 +1,52 @@ -import React, {useState} from "react"; +import React from "react"; import {observer} from 'mobx-react-lite'; import {useStore} from "../../utils/useStore"; -import {Button, Card, Checkbox, Col, Form, Input, Row, Typography} from 'antd'; -import {LockOutlined, UserOutlined} from '@ant-design/icons'; +import {Button, Card, Col, Form, Input, message, Row, Typography} from 'antd'; import {useHistory} from "react-router-dom"; export const Login = observer(() => { const store = useStore(); - const [loading, setLoading] = useState(false); - let history = useHistory(); + const [form] = Form.useForm(); - const onFinish = values => { - console.log('Received values of form: ', values); - enterLoading(values).then(res => { - console.log(res, "awasaa"); - }).catch((error) => { - console.log({error}, "awasaa error"); - }); - }; + const handleLogin = async (params) => { + try { + await store.authentication.login({ + username: params.username, + password: params.password, + }); + history.push('/app/home'); + } catch (e) { + if (e.response?.body?.message) { + message.error(e.response.body.message); + return; + } + message.error(e.message); + } + } - const enterLoading = async (props) => { - // store.setInitialToken("ayayay", "clap"); - return history.push("/app/page_example_1"); - }; - - return
- -
-
-
- + return ( +
+ +
+
+
+ Boilerplate
@@ -57,83 +58,28 @@ export const Login = observer(() => { title={'Sign in to your account'} >
- - } - type="text" - placeholder="Email"/> + + - - - } - type="password" - placeholder="Password" - /> - - - - Forgot password - - - - - - Remember me - - - - - + + +
+ +
-
- - - - ; + + + + + ); }); diff --git a/src/routes/index.js b/src/routes/index.js index dd37c94..e35d030 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -2,15 +2,16 @@ import {Redirect, Route, Switch} from "react-router-dom"; import {Login} from "../pages/Login/Login"; import {PublicRoute} from "../component/PublicRoute"; import {App} from "../pages/App/App"; +import {PrivateRoute} from "../component/PrivateRoute"; export const MainRoutes = (props) => { return ( - + - + ); }; diff --git a/src/store/authentication.js b/src/store/authentication.js index 49a92ae..ef39c7a 100644 --- a/src/store/authentication.js +++ b/src/store/authentication.js @@ -1,27 +1,63 @@ -import {makeAutoObservable} from "mobx"; +import {makeAutoObservable, runInAction} from "mobx"; +import {TokenUtil} from "../utils/token"; +import {http} from "../utils/http"; export class Authentication { + isLoggedIn = false; + isLoginLoading = false; ctx; accessToken = ''; - refreshToken = ''; - constructor(ctx) { this.ctx = ctx; makeAutoObservable(this); } get isLoggedIn() { - return !!this.refreshToken; + return !!this.accessToken; } - setInitialToken(accessToken, refreshToken) { - this.setToken(accessToken, refreshToken); + get userData() { + const defaultValue = { + role: '', + user_id: '', + username: '', + }; + + try { + return JSON.parse(atob(this.accessToken.split('.')[1])); + } catch (err) { + return defaultValue; + } } - setToken(accessToken, refreshToken) { - this.accessToken = accessToken; - this.refreshToken = refreshToken; + async login({username, password}) { + runInAction(() => { + this.isLoginLoading = true; + }); + + try { + const result = await http.post('/auth/login').send({username, password}); + + TokenUtil.setAccessToken(result.body.access_token); + TokenUtil.persistToken(); + runInAction(() => { + this.isLoginLoading = false; + this.isLoggedIn = true; + }); + } catch (e) { + runInAction(() => { + this.isLoginLoading = false; + }); + console.error(e); + throw e; + } + } + + logout() { + TokenUtil.clearAccessToken(); + TokenUtil.persistToken(); + this.isLoggedIn = false; } } diff --git a/src/store/index.js b/src/store/index.js index e6250f3..cb89030 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,6 +4,7 @@ import {User} from "./user"; import {Membership} from "./membership"; import {Product} from "./product"; import {Categories} from "./categories"; +import {TokenUtil} from "../utils/token"; export class Store { ui = new UI(this); @@ -14,5 +15,9 @@ export class Store { categories = new Categories(this); constructor() { + TokenUtil.loadToken(); + if (TokenUtil.accessToken) { + this.authentication.isLoggedIn = true; + } } } diff --git a/src/store/user.js b/src/store/user.js index 00722be..741da5b 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -6,7 +6,7 @@ export class User { @action async getData() { - this.data = (await http.get('/product')).body.data; + this.data = (await http.get('/user')).body.data; } } diff --git a/src/utils/token.js b/src/utils/token.js index a66e156..8b28c65 100644 --- a/src/utils/token.js +++ b/src/utils/token.js @@ -4,15 +4,10 @@ export class TokenUtil { static loadToken() { const accessToken = localStorage.getItem('access_token'); - const refreshToken = localStorage.getItem('refresh_token'); if (accessToken) { TokenUtil.setAccessToken(accessToken); } - - if (refreshToken) { - TokenUtil.setRefreshToken(refreshToken); - } } static persistToken() { @@ -22,25 +17,13 @@ export class TokenUtil { localStorage.removeItem('access_token'); } - if (TokenUtil.refreshToken != null) { - localStorage.setItem('refresh_token', TokenUtil.refreshToken); - } else { - localStorage.removeItem('refresh_token'); - } } static setAccessToken(accessToken) { TokenUtil.accessToken = accessToken; } - static setRefreshToken(refreshToken) { - TokenUtil.refreshToken = refreshToken; - } - static clearAccessToken() { TokenUtil.accessToken = null; } - static clearRefreshToken() { - TokenUtil.accessToken = null; - } } From 9e6ce2dbd8ee5e1fb98df574f5f38533bbff21cf Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 23:06:16 +0700 Subject: [PATCH 08/24] feat: implement token in fetch api --- src/store/authentication.js | 1 + src/utils/http.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/store/authentication.js b/src/store/authentication.js index ef39c7a..24f2b35 100644 --- a/src/store/authentication.js +++ b/src/store/authentication.js @@ -26,6 +26,7 @@ export class Authentication { }; try { + console.log(JSON.parse(atob(this.accessToken.split('.')[1])), "isi jwt") return JSON.parse(atob(this.accessToken.split('.')[1])); } catch (err) { return defaultValue; diff --git a/src/utils/http.js b/src/utils/http.js index d794204..a63234c 100644 --- a/src/utils/http.js +++ b/src/utils/http.js @@ -1,33 +1,33 @@ import superagent from "superagent"; import {appConfig} from "../config/app"; -import {store} from "./useStore"; +import {TokenUtil} from "./token"; export const http = { get: (url, opts = {}) => { let req = superagent.get(appConfig.apiUrl + url); - if (store.token) { - req = req.set('Authorization', 'Bearer ' + store.token); + if (TokenUtil.accessToken) { + req = req.set('Authorization', 'Bearer ' + TokenUtil.accessToken); } return req; }, post: (url, opts) => { let req = superagent.post(appConfig.apiUrl + url); - if (store.token) { - req = req.set('Authorization', 'Bearer ' + store.token); + if (TokenUtil.accessToken) { + req = req.set('Authorization', 'Bearer ' + TokenUtil.accessToken); } return req; }, put: (url, opts) => { let req = superagent.put(appConfig.apiUrl + url); - if (store.token) { - req = req.set('Authorization', 'Bearer ' + store.token); + if (TokenUtil.accessToken) { + req = req.set('Authorization', 'Bearer ' + TokenUtil.accessToken); } return req; }, del: (url, opts) => { let req = superagent.del(appConfig.apiUrl + url); - if (store.token) { - req = req.set('Authorization', 'Bearer ' + store.token); + if (TokenUtil.accessToken) { + req = req.set('Authorization', 'Bearer ' + TokenUtil.accessToken); } return req; }, From c46599bdeff13745aa54c9a1b8e0a06402bb122e Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 23:18:54 +0700 Subject: [PATCH 09/24] feat: get data from jwt --- src/pages/App/DesktopLayout.js | 9 +++++---- src/store/authentication.js | 2 ++ src/store/index.js | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index abf523d..6a474fc 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -279,9 +279,9 @@ export const DesktopLayout = observer(() => { } title={ - {store.user.data.email}{" "} + {store.user.data.username} - {store.authentication.userData.email} + {store.authentication.userData.username} } @@ -353,12 +353,13 @@ export const DesktopLayout = observer(() => { }} mode="inline" > - + Profile { store.authentication.logout(); history.push("/login"); @@ -372,7 +373,7 @@ export const DesktopLayout = observer(() => { {store.user.data.email}{" "} - {/*{store.authentication.userData.full_name}*/} + {store.authentication.userData.username} } diff --git a/src/store/authentication.js b/src/store/authentication.js index 24f2b35..2b46fe9 100644 --- a/src/store/authentication.js +++ b/src/store/authentication.js @@ -41,6 +41,7 @@ export class Authentication { try { const result = await http.post('/auth/login').send({username, password}); + this.accessToken = result.body.access_token; TokenUtil.setAccessToken(result.body.access_token); TokenUtil.persistToken(); runInAction(() => { @@ -60,5 +61,6 @@ export class Authentication { TokenUtil.clearAccessToken(); TokenUtil.persistToken(); this.isLoggedIn = false; + this.accessToken = ''; } } diff --git a/src/store/index.js b/src/store/index.js index cb89030..3d345dd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -18,6 +18,7 @@ export class Store { TokenUtil.loadToken(); if (TokenUtil.accessToken) { this.authentication.isLoggedIn = true; + this.authentication.accessToken = TokenUtil.accessToken; } } } From 9c87efc3d206b4fecc23573db472a63d3f9ccc3f Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 23:20:22 +0700 Subject: [PATCH 10/24] feat: remove unused code --- src/utils/token.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/token.js b/src/utils/token.js index 8b28c65..00d6b67 100644 --- a/src/utils/token.js +++ b/src/utils/token.js @@ -1,6 +1,5 @@ export class TokenUtil { static accessToken = null; - static refreshToken = null; static loadToken() { const accessToken = localStorage.getItem('access_token'); From 56252bbd531d2ed10e2f8633ffa99d4061cc77c5 Mon Sep 17 00:00:00 2001 From: caturbgs Date: Thu, 9 Dec 2021 23:29:40 +0700 Subject: [PATCH 11/24] feat: remove unused code --- src/pages/App/DesktopLayout.js | 2 -- src/store/authentication.js | 11 +---------- src/store/index.js | 1 - 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/pages/App/DesktopLayout.js b/src/pages/App/DesktopLayout.js index 6a474fc..1c46dc5 100644 --- a/src/pages/App/DesktopLayout.js +++ b/src/pages/App/DesktopLayout.js @@ -88,7 +88,6 @@ export const DesktopLayout = observer(() => { width={"50%"} onClose={() => { store.ui.toggleLeftDrawerIsShown() - console.log("clicked"); }} visible={store.ui.leftDrawerIsShown} key={"dashboard-drawer"} @@ -211,7 +210,6 @@ export const DesktopLayout = observer(() => { } onClick={() => { store.ui.toggleLeftDrawerIsShown(); - console.log("apa") }} />
{ @@ -61,6 +53,5 @@ export class Authentication { TokenUtil.clearAccessToken(); TokenUtil.persistToken(); this.isLoggedIn = false; - this.accessToken = ''; } } diff --git a/src/store/index.js b/src/store/index.js index 3d345dd..cb89030 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -18,7 +18,6 @@ export class Store { TokenUtil.loadToken(); if (TokenUtil.accessToken) { this.authentication.isLoggedIn = true; - this.authentication.accessToken = TokenUtil.accessToken; } } } From ac948f3dd5fb63591c34a68cb557dbc7bf7ddd63 Mon Sep 17 00:00:00 2001 From: ajat91 Date: Fri, 10 Dec 2021 10:53:02 +0700 Subject: [PATCH 12/24] Data Membership --- src/pages/Membership/Membership.js | 69 +++++++++++++++--------------- src/store/membership.js | 6 ++- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/pages/Membership/Membership.js b/src/pages/Membership/Membership.js index 653b1c3..9e43b81 100644 --- a/src/pages/Membership/Membership.js +++ b/src/pages/Membership/Membership.js @@ -16,16 +16,17 @@ export const Membership = observer(() => { const [confirmLoading, setConfirmLoading] = useState(false); const [isLoading, setIsLoading] = useState(false); - useEffect(() => { - const init = async () => { - try { - setIsLoading(true) - await store.membership.getData(); - setIsLoading(false) - } catch (e) { - setIsLoading(false) - } + const init = async () => { + try { + setIsLoading(true) + await store.membership.getData(); + setIsLoading(false) + } catch (e) { + setIsLoading(false) } + } + useEffect(() => { + init() @@ -34,26 +35,26 @@ export const Membership = observer(() => { const columns = [ { title: "Name", - dataIndex: "name", - key: "name", + dataIndex: "username", + key: "username", }, { title: "Username", - dataIndex: "name", - key: "name", + dataIndex: "username", + key: "username", }, { title: "Status", dataIndex: "status", key: "status", render: (text, record) => ( - <> - - Inactive - - Active - - ) + + {record?.status} + + ) }, { title: "Action", @@ -163,21 +164,21 @@ export const Membership = observer(() => { hasEmpty size={"small"} columns={columns} - dataSource={store.membership.data} + dataSource={store.membership.data[0]} bordered - pagination={{ - total: store.membership.total_data, - current: store.membership.page, - pageSize: store.membership.pageSize, - simple: true - }} - onChange={(page) => { - store.membership.pageSize = page.pageSize; - store.membership.page = page.current; - store.membership.getData(); - }} - current={store.membership.page} - loading={store.membership.pageSize} + // pagination={{ + // total: store.membership.total_data, + // current: store.membership.page, + // pageSize: store.membership.pageSize, + // simple: true + // }} + // onChange={(page) => { + // store.membership.pageSize = page.pageSize; + // store.membership.page = page.current; + // store.membership.getData(); + // }} + // current={store.membership.page} + // loading={store.membership.pageSize} />)} {store.ui.mediaQuery.isMobile && ( diff --git a/src/store/membership.js b/src/store/membership.js index 558dee2..50280bd 100644 --- a/src/store/membership.js +++ b/src/store/membership.js @@ -2,7 +2,7 @@ import {action, makeAutoObservable} from "mobx"; import {http} from "../utils/http"; export class Membership { - page = 1; + page = 0; pageSize = 10 data = []; total_data = 0 @@ -14,7 +14,9 @@ export class Membership { @action async getData() { - const response = await http.get(`/user?page=${this.page}&pageSize=${this.pageSize}`); + const response = await http.get(`/users/find-by-supperior?page=${this.page}&pageSize=${this.pageSize}`); + // console.log(response, 'Data user') + // console.log(JSON.stringify(response.body.data), 'Data') this.data = response.body.data ?? [] this.total_data = response.body.total_data ?? 0 } From 48905225bb34b4d235fde4e11d632c81b4c6461f Mon Sep 17 00:00:00 2001 From: caturbgs Date: Fri, 10 Dec 2021 10:50:39 +0700 Subject: [PATCH 13/24] feat: create component product --- package.json | 1 + src/{pages/Product/Pulsa.js => component/ProductComponent.js} | 0 src/store/index.js | 2 -- yarn.lock | 2 +- 4 files changed, 2 insertions(+), 3 deletions(-) rename src/{pages/Product/Pulsa.js => component/ProductComponent.js} (100%) diff --git a/package.json b/package.json index 78c12c6..31c20a8 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "jest-watch-typeahead": "0.6.1", "less": "^3.11.1", "less-loader": "6.1.0", + "lodash": "^4.17.21", "mini-css-extract-plugin": "0.11.3", "mobx": "^6.3.2", "mobx-react-lite": "^3.2.0", diff --git a/src/pages/Product/Pulsa.js b/src/component/ProductComponent.js similarity index 100% rename from src/pages/Product/Pulsa.js rename to src/component/ProductComponent.js diff --git a/src/store/index.js b/src/store/index.js index cb89030..a5a0d80 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3,7 +3,6 @@ import {Authentication} from "./authentication"; import {User} from "./user"; import {Membership} from "./membership"; import {Product} from "./product"; -import {Categories} from "./categories"; import {TokenUtil} from "../utils/token"; export class Store { @@ -12,7 +11,6 @@ export class Store { user = new User(this); membership = new Membership(this); product = new Product(this); - categories = new Categories(this); constructor() { TokenUtil.loadToken(); diff --git a/yarn.lock b/yarn.lock index 172036b..9a5a60e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7784,7 +7784,7 @@ lodash.uniq@^4.5.0: lodash@^4.17.21: version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loglevel@^1.6.8: From 0da2118bec08ef575eef3907a44cd0657ab8ff5a Mon Sep 17 00:00:00 2001 From: ajat91 Date: Fri, 10 Dec 2021 13:18:42 +0700 Subject: [PATCH 14/24] Crud Membership --- src/pages/Membership/Membership.js | 363 +++++++++++++----------- src/pages/Membership/MembershipModal.js | 33 ++- src/store/membership.js | 6 +- 3 files changed, 216 insertions(+), 186 deletions(-) diff --git a/src/pages/Membership/Membership.js b/src/pages/Membership/Membership.js index 9e43b81..0f599a5 100644 --- a/src/pages/Membership/Membership.js +++ b/src/pages/Membership/Membership.js @@ -1,35 +1,49 @@ -import React, {useEffect, useState} from "react"; -import {Button, Card, Col, Divider, Input, List, message, Modal, Row, Space, Table, Tag} from "antd"; -import {useStore} from "../../utils/useStore"; -import {observer} from "mobx-react-lite"; -import {ExclamationCircleOutlined, FilterOutlined, PlusSquareOutlined,} from "@ant-design/icons"; -import {MembershipModal} from "./MembershipModal"; -import {BreadcumbComponent} from "../../component/BreadcumbComponent"; -import {format} from "date-fns"; +import React, { useEffect, useState } from "react"; +import { + Button, + Card, + Col, + Divider, + Input, + List, + message, + Modal, + Row, + Space, + Table, + Tag, +} from "antd"; +import { useStore } from "../../utils/useStore"; +import { observer } from "mobx-react-lite"; +import { + ExclamationCircleOutlined, + FilterOutlined, + PlusSquareOutlined, +} from "@ant-design/icons"; +import { MembershipModal } from "./MembershipModal"; +import { BreadcumbComponent } from "../../component/BreadcumbComponent"; +import { format } from "date-fns"; -const {Search} = Input; +const { Search } = Input; export const Membership = observer(() => { const store = useStore(); - const [visibleModal, setVisibleModal] = useState(false) - const [initialData, setInitialData] = useState({}) + const [visibleModal, setVisibleModal] = useState(false); + const [initialData, setInitialData] = useState({}); const [confirmLoading, setConfirmLoading] = useState(false); const [isLoading, setIsLoading] = useState(false); const init = async () => { try { - setIsLoading(true) + setIsLoading(true); await store.membership.getData(); - setIsLoading(false) + setIsLoading(false); } catch (e) { - setIsLoading(false) + setIsLoading(false); } - } + }; useEffect(() => { - - - init() - + init(); }, []); const columns = [ @@ -49,28 +63,34 @@ export const Membership = observer(() => { key: "status", render: (text, record) => ( - {record?.status} + {record?.isActive === true ? " ACTIVE" : "INACTIVE"} - ) + ), }, { title: "Action", key: "action", render: (text, record) => ( - - - - + > + Edit + + + ), }, ]; @@ -82,177 +102,180 @@ export const Membership = observer(() => { }, { route: "/app/membership", - name: Membership, + name: Membership, }, ]; const onSubmit = async (data) => { if (initialData.id) { - setInitialData({}) + setInitialData({}); setConfirmLoading(true); try { - await store.membership.update(initialData.id, data) - message.success("Success Update Data Member") + await store.membership.update(initialData.id, data); + message.success("Success Update Data Member"); + await store.membership.getData(); } catch (e) { - message.error("Failed Update Data Member") + message.error("Failed Update Data Member"); } setConfirmLoading(false); setVisibleModal(false); } else { - setInitialData({}) + setInitialData({}); setConfirmLoading(true); try { - await store.membership.create(data) - message.success("Success Add New Member") + await store.membership.create(data); + message.success("Success Add New Member"); + await store.membership.getData(); } catch (e) { - console.log(e, "apa errornya") - message.error("Failed Add Member") + console.log(e, "apa errornya"); + message.error("Failed Add Member"); } setConfirmLoading(false); setVisibleModal(false); } - } + }; const handleDelete = (record) => { Modal.confirm({ - title: 'Are you sure reject this record?', - icon: , - okText: 'Yes', - okType: 'primary', - cancelText: 'Cancel', + title: "Are you sure reject this record?", + icon: , + okText: "Yes", + okType: "primary", + cancelText: "Cancel", onOk() { try { //TODO: minta apinya ke ka ilham ya, jangan di uncomment kalo pake api reconcile, nanti beneran ke apus datanya // await store.membership.delete(record.id) - message.success('Success Delete Data') + message.success("Success Delete Data"); } catch (e) { - message.error("Failed Delete Data") + message.error("Failed Delete Data"); } }, onCancel() { - console.log('Cancel'); + console.log("Cancel"); }, }); - } - + }; return ( -
- - -
- -
- - - - - - - +
+ + +
+ +
+ + + + + + + + {store.ui.mediaQuery.isDesktop && ( +
{ + // store.membership.pageSize = page.pageSize; + // store.membership.page = page.current; + // store.membership.getData(); + // }} + // current={store.membership.page} + // loading={store.membership.pageSize} + /> + )} - {store.ui.mediaQuery.isDesktop && ( -
{ - // store.membership.pageSize = page.pageSize; - // store.membership.page = page.current; - // store.membership.getData(); - // }} - // current={store.membership.page} - // loading={store.membership.pageSize} - />)} - - {store.ui.mediaQuery.isMobile && ( - { - store.membership.pageSize = page.pageSize; - store.membership.page = page.current; - store.membership.getData(); - }, - pageSize: store.membership.pageSize, - total: store.membership.total_data, - current: store.membership.page, - style: {marginBottom: '1rem', marginRight: '1rem'} - }} - dataSource={store.membership.data} - style={{padding: 0}} - renderItem={(item) => { - return ( -
- - -

- Email : {item.email}
-

-
- } - /> -
-

- {format(new Date(item.created_at), "dd-MM-yyyy")} -

-
- - + {store.ui.mediaQuery.isMobile && ( + { + store.membership.pageSize = page.pageSize; + store.membership.page = page.current; + store.membership.getData(); + }, + pageSize: store.membership.pageSize, + total: store.membership.total_data, + current: store.membership.page, + style: { marginBottom: "1rem", marginRight: "1rem" }, + }} + dataSource={store.membership.data} + style={{ padding: 0 }} + renderItem={(item) => { + return ( +
+ + +

+ Username : {item.username}
+

- ); - }} - /> - )} - - - { - onSubmit(data) - }} - onCancel={() => { - setInitialData({}) - setVisibleModal(false); - }}/> - + } + /> +
+

+ {item.username} +

+
+ + + + ); + }} + /> + )} + + + { + onSubmit(data); + }} + onCancel={() => { + setInitialData({}); + setVisibleModal(false); + }} + /> + ); }); diff --git a/src/pages/Membership/MembershipModal.js b/src/pages/Membership/MembershipModal.js index bcbece4..b404639 100644 --- a/src/pages/Membership/MembershipModal.js +++ b/src/pages/Membership/MembershipModal.js @@ -9,13 +9,13 @@ export const MembershipModal = ({ }) => { const [form] = Form.useForm(); const {Option} = Select; - const dataStatus = ['Active', 'Inactive'] + const dataStatus = ["true", "false"] return ( { @@ -40,13 +40,7 @@ export const MembershipModal = ({ name="form_in_modal" initialValues={initialData} > - - - + + + + + + + + {dataStatus.map(it => { - return + return })} diff --git a/src/store/index.js b/src/store/index.js index a5a0d80..8a935c9 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,6 +4,7 @@ import {User} from "./user"; import {Membership} from "./membership"; import {Product} from "./product"; import {TokenUtil} from "../utils/token"; +import {Role} from "./role"; export class Store { ui = new UI(this); @@ -11,6 +12,7 @@ export class Store { user = new User(this); membership = new Membership(this); product = new Product(this); + role = new Role(this); constructor() { TokenUtil.loadToken(); diff --git a/src/store/membership.js b/src/store/membership.js index 786313f..9dad452 100644 --- a/src/store/membership.js +++ b/src/store/membership.js @@ -15,8 +15,6 @@ export class Membership { @action async getData() { const response = await http.get(`/users/find-by-supperior?page=${this.page}&pageSize=${this.pageSize}`); - // console.log(response, 'Data user') - // console.log(JSON.stringify(response.body.data), 'Data') this.data = response.body.data ?? [] this.total_data = response.body.total_data ?? 0 } diff --git a/src/store/role.js b/src/store/role.js new file mode 100644 index 0000000..4352187 --- /dev/null +++ b/src/store/role.js @@ -0,0 +1,34 @@ +import {makeAutoObservable} from "mobx"; +import {http} from "../utils/http"; + +export class Role { + page = null; + pageSize = null; + data = []; + total_data = 0 + + constructor(ctx) { + this.ctx = ctx; + makeAutoObservable(this); + } + + async getData() { + const response = await http.get(`/config/roles?page=${this.page}&pageSize=${this.pageSize}`); + this.data = response.body.data ?? [] + this.total_data = response.body.total_data ?? 0 + } + + async create(data) { + return await http.post('/users').send(data) + } + + async update(id, data) { + return await http.put('/users/' + id).send(data); + } + + async delete(id) { + return await http.del('/users/' + id); + } +} + + From c1f8a79ad7f5c1403b1c978cf462440174f2f7f3 Mon Sep 17 00:00:00 2001 From: ajat91 Date: Thu, 9 Dec 2021 20:04:37 +0700 Subject: [PATCH 16/24] Pages Product --- src/store/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/user.js b/src/store/user.js index 741da5b..00722be 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -6,7 +6,7 @@ export class User { @action async getData() { - this.data = (await http.get('/user')).body.data; + this.data = (await http.get('/product')).body.data; } } From d057864b3c6b91e99f10f3391a291fb1ea53db66 Mon Sep 17 00:00:00 2001 From: Rido Akbar Ibrahim Date: Wed, 26 Jan 2022 22:14:02 +0700 Subject: [PATCH 17/24] add deployment --- k8s/production/ingress.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/k8s/production/ingress.yaml b/k8s/production/ingress.yaml index 2fe0e8c..9a11926 100644 --- a/k8s/production/ingress.yaml +++ b/k8s/production/ingress.yaml @@ -6,9 +6,10 @@ metadata: annotations: kubernetes.io/ingress.class: "traefik" cert-manager.io/cluster-issuer: letsencrypt-prod + traefik.ingress.kubernetes.io/router.middlewares: empatnusabangsa-production-redirect-https@kubernetescrd spec: rules: - - host: "wndsolutions.id" + - host: "www.wndsolutions.id" http: paths: - pathType: Prefix @@ -20,5 +21,5 @@ spec: number: 80 tls: - hosts: - - "wndsolutions.id" - secretName: wndsolutions-id-tls + - "www.wndsolutions.id" + secretName: www-wndsolutions-id-tls From 6239cfd49149fea91e46868b8da93b9f550abdcc Mon Sep 17 00:00:00 2001 From: "ajat91.sudrajat" Date: Thu, 27 Jan 2022 09:40:42 +0700 Subject: [PATCH 18/24] Bug Fixing --- src/pages/Membership/Konfirmasi.js | 36 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/pages/Membership/Konfirmasi.js b/src/pages/Membership/Konfirmasi.js index ee76999..e55f3d9 100644 --- a/src/pages/Membership/Konfirmasi.js +++ b/src/pages/Membership/Konfirmasi.js @@ -91,7 +91,7 @@ export const Konfirmasi = observer(() => { { title: "Foto Toko", render: (text, record) => - record.user_detail?.image_store !== "\"\"" ? ( + record.user_detail?.image_store !== '""' ? ( - + {item.user_detail?.image_store !== "\"\"" ? ( + + ) : ( + "" + )}

} From 859bf200cac43fed4ed8cf50240bc148125e8d8e Mon Sep 17 00:00:00 2001 From: "ajat91.sudrajat" Date: Thu, 27 Jan 2022 12:12:27 +0700 Subject: [PATCH 19/24] Bug Fixing --- src/pages/Membership/DetailUser.js | 63 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/pages/Membership/DetailUser.js b/src/pages/Membership/DetailUser.js index ca191eb..5e411a9 100644 --- a/src/pages/Membership/DetailUser.js +++ b/src/pages/Membership/DetailUser.js @@ -469,9 +469,11 @@ export const DetailUser = observer(() => { Ganti Password {((store.authentication.userData.role === "Sales" && - store.membership.dataDetail.is_rejected === true) || + store.membership.dataDetail.is_rejected === true && + store.membership.dataDetail.is_active === false) || (store.authentication.userData.role === "Supervisor" && - store.membership.dataDetail.is_rejected === true)) && ( + store.membership.dataDetail.is_rejected === true && + store.membership.dataDetail.is_active === false)) && ( - {item.user_detail?.image_store !== "\"\"" ? ( + {item.user_detail?.image_store !== '""' ? (