Merge branch 'develop' into 'devops-staging'

Develop

See merge request empatnusabangsa/ppob/ppob-frontend!17
This commit is contained in:
Catur Bagaskara 2021-12-23 16:17:04 +00:00
commit fe81a3d81b
29 changed files with 1334 additions and 934 deletions

View File

@ -34,32 +34,6 @@ export const CategoryComponent = observer((props) => {
dataIndex: "name", dataIndex: "name",
key: "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", title: "Action",
key: "action", key: "action",
@ -95,10 +69,12 @@ export const CategoryComponent = observer((props) => {
if (idData !== "") { if (idData !== "") {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.category.update(idData, data); const response =await store.category.update(idData, data);
message.success("Success Update Data Category"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Ubah Kategori")
: message.error("Gagal Ubah Kategori");
} catch (e) { } catch (e) {
message.error("Failed Update Data Category"); message.error("Gagal Ubah Data Kategori");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.category.visibleModalCategory = false; store.category.visibleModalCategory = false;
@ -107,11 +83,13 @@ export const CategoryComponent = observer((props) => {
} else { } else {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.category.create(data); const response=await store.category.create(data);
message.success("Success Add New Category"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Tambah Kategori")
: message.error("Gagal Tambah Kategori");
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Category"); message.error("Gagal Tambah Kategori");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.category.visibleModalCategory = false; store.category.visibleModalCategory = false;

View File

@ -52,10 +52,12 @@ export const CommissionComponent = observer((props) => {
const handleSubmit = async (data) => { const handleSubmit = async (data) => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.commission.update(idData, data); const response=await store.commission.update(idData, data);
message.success("Success Update Data Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Ubah Komisi")
: message.error("Gagal Ubah Komisi");
} catch (e) { } catch (e) {
message.error("Failed Update Data Member"); message.error("Gagal Ubah Komisi");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.commission.visibleModalCommission = false; store.commission.visibleModalCommission = false;

View File

@ -1,11 +1,22 @@
import React, {useContext, useState} from "react"; import React, { useContext, useState } from "react";
import {Button, Divider, Form, Input, List, message, Modal, Space, Table, Tag,} from "antd"; import {
import {observer} from "mobx-react-lite"; Button,
import {ExclamationCircleOutlined} from "@ant-design/icons"; Divider,
import {useHistory} from "react-router-dom"; Form,
import {useStore} from "../utils/useStore"; Input,
import {LINKS} from "../routes/app"; List,
import {ModalLoaderContext} from "../utils/modal"; message,
Modal,
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";
export const PartnerComponent = observer((props) => { export const PartnerComponent = observer((props) => {
const store = useStore(); const store = useStore();
@ -151,6 +162,7 @@ export const PartnerComponent = observer((props) => {
? "Failed Change Partner Password" ? "Failed Change Partner Password"
: "Success Update Data Partner" : "Success Update Data Partner"
); );
//await store.partner.getData() //await store.partner.getData()
} catch (e) { } catch (e) {
modalLoader.setLoading(true); modalLoader.setLoading(true);
@ -166,12 +178,14 @@ export const PartnerComponent = observer((props) => {
} else { } else {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.partner.create(data); const response = await store.partner.create(data);
message.success("Success Add New Partner");
modalLoader.setLoading(false); modalLoader.setLoading(false);
response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Tambah Partner")
: message.error("Gagal Tambah Partner");
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Partner"); message.error("Gagal Tambah Partner");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.partner.visibleModalPartner = false; store.partner.visibleModalPartner = false;
@ -219,7 +233,7 @@ export const PartnerComponent = observer((props) => {
pageSize: store.partner.pageSize, pageSize: store.partner.pageSize,
total: store.partner.total_data, total: store.partner.total_data,
current: store.partner.page + 1, current: store.partner.page + 1,
style: {marginBottom: "1rem", marginRight: "1rem"}, style: { marginBottom: "1rem", marginRight: "1rem" },
}} }}
dataSource={store.partner.data} dataSource={store.partner.data}
style={{ padding: 0 }} style={{ padding: 0 }}

View File

@ -79,19 +79,17 @@ export const ProductComponent = observer((props) => {
currency: "IDR", currency: "IDR",
}).format(text), }).format(text),
}, },
// { {
// title: "Gangguan", title: "Supplier",
// dataIndex: "status", dataIndex: "supplier_name",
// key: "status", key: "supplier_name",
// render: (text, record) => (
// <Tag },
// color={record?.status === "ACTIVE" ? "blue" : "#E3E8EE"} {
// style={{color: "#4F566B"}} title: "Sub Category",
// > dataIndex: "sub_categories_name",
// {capitalize(record?.status)} key: "sub_categories_name",
// </Tag> },
// ),
// },
{ {
title: "Tersedia", title: "Tersedia",
dataIndex: "tersedia", dataIndex: "tersedia",
@ -110,17 +108,17 @@ export const ProductComponent = observer((props) => {
key: "action", key: "action",
render: (text, record) => ( render: (text, record) => (
<Button <Button
onClick={async () => { onClick={async () => {
history.push(LINKS.PRODUCT_DETAIL.replace(":id", record.id)); history.push(LINKS.PRODUCT_DETAIL.replace(":id", record.product_id));
//console.log(record.id) }}
}} >
> Detail
Detail </Button>
</Button>
), ),
}, },
]; ];
if (store.authentication.userData.role !== "Admin") columns.pop();
if (store.authentication.userData.role !== "Admin") delete columns[4];
const deleteData = async (id) => { const deleteData = async (id) => {
try { try {
console.log(id); console.log(id);
@ -159,10 +157,12 @@ export const ProductComponent = observer((props) => {
if (idData !== "") { if (idData !== "") {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.product.update(idData, data); const response=await store.product.update(idData, data);
message.success("Success Update Data Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Ubah Data Produk")
: message.error("Gagal Ubah Data Produk");
} catch (e) { } catch (e) {
message.error("Failed Update Data Member"); message.error("Gagal Ubah Data Produk");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.product.visibleModalProduct = false; store.product.visibleModalProduct = false;
@ -171,11 +171,13 @@ export const ProductComponent = observer((props) => {
} else { } else {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.product.create(data); const response=await store.product.create(data);
message.success("Success Add New Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Tambah Produk")
: message.error("Gagal Tambah Produk");
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Member"); message.error("Gagal Tambah Produk");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.product.visibleModalProduct = false; store.product.visibleModalProduct = false;
@ -289,7 +291,7 @@ export const ProductComponent = observer((props) => {
pageSize: store.product.pageSize, pageSize: store.product.pageSize,
total: store.product.total_data, total: store.product.total_data,
current: store.product.page + 1, current: store.product.page + 1,
style: {marginBottom: "1rem", marginRight: "1rem"}, style: { marginBottom: "1rem", marginRight: "1rem" },
}} }}
dataSource={store.product.data} dataSource={store.product.data}
style={{ padding: 0 }} style={{ padding: 0 }}

View File

@ -67,11 +67,13 @@ export const SubcategoryComponent = observer((props) => {
if (idData !== "") { if (idData !== "") {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.subcategory.update(idData, data); const response=await store.subcategory.update(idData, data);
response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Ubah Data Sub Kategori")
: message.error("Gagal Ubah Data Sub Kategori");
//await getData(); //await getData();
message.success("Success Update Data Category");
} catch (e) { } catch (e) {
message.error("Failed Update Data Category"); message.error("Gagal Ubah Data Sub Kategori");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.subcategory.visibleModalSubcategory = false; store.subcategory.visibleModalSubcategory = false;
@ -80,11 +82,13 @@ export const SubcategoryComponent = observer((props) => {
} else { } else {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.subcategory.create(data); const response =await store.subcategory.create(data);
message.success("Success Add New Category"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Tambah Sub Kategori")
: message.error("Gagal Tambah Sub Kategori");
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Category"); message.error("Gagal Tambah Sub Kategori");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
store.subcategory.visibleModalSubcategory = false; store.subcategory.visibleModalSubcategory = false;

View File

@ -160,11 +160,13 @@ export const SupplierComponent = observer((props) => {
if (idData !== "") { if (idData !== "") {
try { try {
modalLoader.setLoading(true); modalLoader.setLoading(true);
await store.supplier.update(idData, data); const response=await store.supplier.update(idData, data);
message.success("Success Update Data Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Ubah Data Supplier")
: message.error("Gagal Ubah Data Supplier");
} catch (e) { } catch (e) {
modalLoader.setLoading(false); modalLoader.setLoading(false);
message.error("Failed Update Data Member"); message.error("Gagal Ubah Data Supplie");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
@ -174,11 +176,13 @@ export const SupplierComponent = observer((props) => {
} else { } else {
try { try {
modalLoader.setLoading(true); modalLoader.setLoading(true);
await store.supplier.create(data); const response=await store.supplier.create(data);
message.success("Success Add New Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success("Berhasil Tambah Supplier Baru")
: message.error("Gagal Tambah Supplier Baru");
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Member"); message.error("Gagal Tambah Supplier Baru");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);

View File

@ -120,15 +120,15 @@ export const DesktopLayout = observer(() => {
<Menu> <Menu>
<Menu.Item key="home"> <Menu.Item key="home">
<Link to={LINKS.HOME}> <Link to={LINKS.HOME}>
<HomeOutlined /> <HomeOutlined/>
<span>Home</span> <span>Beranda</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
{store.authentication.userData.role !== "Retail" && ( {store.authentication.userData.role !== "Retail" && (
<Menu.Item key="membership"> <Menu.Item key="membership">
<Link to={LINKS.MEMBERSHIP}> <Link to={LINKS.MEMBERSHIP}>
<FileProtectOutlined /> <FileProtectOutlined/>
<span>Membership</span> <span>Keanggotaan</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -141,14 +141,14 @@ export const DesktopLayout = observer(() => {
> >
<Menu.Item key="partner"> <Menu.Item key="partner">
<Link to={LINKS.PARTNER}> <Link to={LINKS.PARTNER}>
<HomeOutlined /> <HomeOutlined/>
<span>Partner</span> <span>Rekanan</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="commision"> <Menu.Item key="commision">
<Link to={LINKS.COMMISSION}> <Link to={LINKS.COMMISSION}>
<HomeOutlined /> <HomeOutlined/>
<span>Commision</span> <span>Komisi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="supplier"> <Menu.Item key="supplier">
@ -167,23 +167,23 @@ export const DesktopLayout = observer(() => {
> >
<Menu.Item key="product"> <Menu.Item key="product">
<Link to={LINKS.PRODUCT}> <Link to={LINKS.PRODUCT}>
<DatabaseOutlined /> <DatabaseOutlined/>
<span>Product</span> <span>Produk</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
{store.authentication.userData.role === "Admin" && ( {store.authentication.userData.role === "Admin" && (
<Menu.Item key="category"> <Menu.Item key="category">
<Link to={LINKS.CATEGORY}> <Link to={LINKS.CATEGORY}>
<FileAddOutlined /> <FileAddOutlined/>
<span>Category</span> <span>Kategori</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
{store.authentication.userData.role === "Admin" && ( {store.authentication.userData.role === "Admin" && (
<Menu.Item key="sub-category"> <Menu.Item key="sub-category">
<Link to={LINKS.SUBCATEGORY}> <Link to={LINKS.SUBCATEGORY}>
<FileSyncOutlined /> <FileSyncOutlined/>
<span>Sub Category</span> <span>Sub Kategori</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -192,29 +192,29 @@ export const DesktopLayout = observer(() => {
{store.authentication.userData.role !== "Admin" && ( {store.authentication.userData.role !== "Admin" && (
<Menu.Item key="product"> <Menu.Item key="product">
<Link to={LINKS.PRODUCT}> <Link to={LINKS.PRODUCT}>
<DatabaseOutlined /> <DatabaseOutlined/>
<span>Product</span> <span>Produk</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
{store.authentication.userData.role === "Retail" && ( {store.authentication.userData.role === "Retail" && (
<Menu.Item key="transaction"> <Menu.Item key="transaction">
<Link to={LINKS.TRANSACTION}> <Link to={LINKS.TRANSACTION}>
<ShoppingCartOutlined /> <ShoppingCartOutlined/>
<span>Transaction</span> <span>Transaksi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
<SubMenu <SubMenu
key="payback-main" key="payback-main"
icon={<ProfileOutlined/>} icon={<ProfileOutlined/>}
title="Created" title="Pembayaran"
> >
{store.authentication.userData.role !== "Retail" && ( {store.authentication.userData.role !== "Retail" && (
<Menu.Item key="payback-to-user"> <Menu.Item key="payback-to-user">
<Link to={LINKS.PAYBACK}> <Link to={LINKS.PAYBACK}>
<PayCircleOutlined/> <PayCircleOutlined/>
<span>Confirmation</span> <span>Konfirmasi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -222,7 +222,7 @@ export const DesktopLayout = observer(() => {
<Menu.Item key="payback-from-user"> <Menu.Item key="payback-from-user">
<Link to={LINKS.PAYBACK_CREATED}> <Link to={LINKS.PAYBACK_CREATED}>
<AlipayOutlined/> <AlipayOutlined/>
<span>Created</span> <span>Dibuat oleh Saya</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -230,8 +230,8 @@ export const DesktopLayout = observer(() => {
{store.authentication.userData.role !== "Admin" && ( {store.authentication.userData.role !== "Admin" && (
<Menu.Item key="profile"> <Menu.Item key="profile">
<Link to={LINKS.PROFILE}> <Link to={LINKS.PROFILE}>
<UserOutlined /> <UserOutlined/>
<span>Profile</span> <span>Profil</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}

View File

@ -2,7 +2,6 @@ import React, {useEffect, useState} from "react";
import {Menu} from "antd"; import {Menu} from "antd";
import {Link} from "react-router-dom"; import {Link} from "react-router-dom";
import { import {
AlipayOutlined,
AppstoreOutlined, AppstoreOutlined,
DatabaseOutlined, DatabaseOutlined,
FileAddOutlined, FileAddOutlined,
@ -11,7 +10,6 @@ import {
HomeOutlined, HomeOutlined,
MenuUnfoldOutlined, MenuUnfoldOutlined,
MoneyCollectOutlined, MoneyCollectOutlined,
PayCircleOutlined,
ProfileOutlined, ProfileOutlined,
ProjectOutlined, ProjectOutlined,
ShoppingCartOutlined, ShoppingCartOutlined,
@ -52,14 +50,14 @@ export const MenuList = observer((props) => {
<Menu.Item key="home"> <Menu.Item key="home">
<Link to={LINKS.HOME}> <Link to={LINKS.HOME}>
<HomeOutlined /> <HomeOutlined />
<span>Home</span> <span>Beranda</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
{store.authentication.userData.role !== "Retail" && ( {store.authentication.userData.role !== "Retail" && (
<Menu.Item key="membership"> <Menu.Item key="membership">
<Link to={LINKS.MEMBERSHIP}> <Link to={LINKS.MEMBERSHIP}>
<FileProtectOutlined /> <FileProtectOutlined />
<span>Membership</span> <span>Keanggotaan</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -68,13 +66,13 @@ export const MenuList = observer((props) => {
<Menu.Item key="partner"> <Menu.Item key="partner">
<Link to={LINKS.PARTNER}> <Link to={LINKS.PARTNER}>
<ProjectOutlined /> <ProjectOutlined />
<span>Partner</span> <span>Rekanan</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="commision"> <Menu.Item key="commision">
<Link to={LINKS.COMMISSION}> <Link to={LINKS.COMMISSION}>
<MoneyCollectOutlined /> <MoneyCollectOutlined />
<span>Commission</span> <span>Komisi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
<Menu.Item key="supplier"> <Menu.Item key="supplier">
@ -90,14 +88,14 @@ export const MenuList = observer((props) => {
<Menu.Item key="product"> <Menu.Item key="product">
<Link to={LINKS.PRODUCT}> <Link to={LINKS.PRODUCT}>
<DatabaseOutlined /> <DatabaseOutlined />
<span>Product</span> <span>Produk</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
{store.authentication.userData.role === "Admin" && ( {store.authentication.userData.role === "Admin" && (
<Menu.Item key="category"> <Menu.Item key="category">
<Link to={LINKS.CATEGORY}> <Link to={LINKS.CATEGORY}>
<FileAddOutlined /> <FileAddOutlined />
<span>Category</span> <span>Kategori</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -105,7 +103,7 @@ export const MenuList = observer((props) => {
<Menu.Item key="sub-category"> <Menu.Item key="sub-category">
<Link to={LINKS.SUBCATEGORY}> <Link to={LINKS.SUBCATEGORY}>
<FileSyncOutlined /> <FileSyncOutlined />
<span>Sub Category</span> <span>Sub Kategori</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -115,7 +113,7 @@ export const MenuList = observer((props) => {
<Menu.Item key="retail"> <Menu.Item key="retail">
<Link to={LINKS.PRODUCT}> <Link to={LINKS.PRODUCT}>
<DatabaseOutlined /> <DatabaseOutlined />
<span>Product</span> <span>Produk</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -123,24 +121,24 @@ export const MenuList = observer((props) => {
<Menu.Item key="transaction"> <Menu.Item key="transaction">
<Link to={LINKS.TRANSACTION}> <Link to={LINKS.TRANSACTION}>
<ShoppingCartOutlined /> <ShoppingCartOutlined />
<span>Transaction</span> <span>Transaksi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
<SubMenu key="payback-main" icon={<ProfileOutlined />} title="Payback"> <SubMenu key="payback-main" icon={<ProfileOutlined />} title="Pembayaran">
{store.authentication.userData.role !== "Retail" && ( {store.authentication.userData.role !== "Retail" && (
<Menu.Item key="payback-to-user"> <Menu.Item key="payback-to-user">
<Link to={LINKS.PAYBACK}> <Link to={LINKS.PAYBACK}>
<PayCircleOutlined/> <FileProtectOutlined/>
<span>Confirmation</span> <span>Konfirmasi</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
{store.authentication.userData.role !== "Admin" && ( {store.authentication.userData.role !== "Admin" && (
<Menu.Item key="payback-from-user"> <Menu.Item key="payback-from-user">
<Link to={LINKS.PAYBACK_CREATED}> <Link to={LINKS.PAYBACK_CREATED}>
<AlipayOutlined/> <FileProtectOutlined/>
<span>Created</span> <span>Dibuat oleh Saya</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
@ -148,17 +146,11 @@ export const MenuList = observer((props) => {
{store.authentication.userData.role !== "Admin" && ( {store.authentication.userData.role !== "Admin" && (
<Menu.Item key="profile"> <Menu.Item key="profile">
<Link to={LINKS.PROFILE}> <Link to={LINKS.PROFILE}>
<UserOutlined /> <UserOutlined/>
<span>Profile</span> <span>Profil</span>
</Link> </Link>
</Menu.Item> </Menu.Item>
)} )}
{/*<Menu.Item key="about">*/}
{/* <Link to={'/app/about'}>*/}
{/* <CalendarOutlined/>*/}
{/* <span>About</span>*/}
{/* </Link>*/}
{/*</Menu.Item>*/}
<Menu.Divider style={{ background: "transparent", paddingTop: 15 }} /> <Menu.Divider style={{ background: "transparent", paddingTop: 15 }} />
</Menu> </Menu>
); );

View File

@ -40,7 +40,7 @@ export const Partner = observer(() => {
}, },
{ {
route: LINKS.PARTNER, route: LINKS.PARTNER,
name: <span style={{fontWeight: 'bold'}}>Partner</span>, name: <span style={{fontWeight: 'bold'}}>Rekanan</span>,
}, },
]; ];
@ -49,21 +49,21 @@ export const Partner = observer(() => {
<BreadcumbComponent data={routeData}/> <BreadcumbComponent data={routeData}/>
<Card> <Card>
<Row style={{marginBottom: 20}}> <Row style={{marginBottom: 20}}>
<Col span={12}> {/* <Col span={12}>
{/* <Button> <Button>
<FilterOutlined/> <FilterOutlined/>
Filter Filter
</Button> */} </Button>
</Col> </Col> */}
<Col span={12} style={{textAlign: "right"}}> <Col span={24} style={{textAlign: "right"}}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
<Button onClick={() => store.partner.visibleModalPartner = true}> <Button onClick={() => store.partner.visibleModalPartner = true}>
<PlusSquareOutlined/> New <PlusSquareOutlined/> New
</Button> </Button>

View File

@ -71,7 +71,7 @@ export const Supplier = observer(() => {
</Button> </Button>
</Col> */} </Col> */}
<Col span={24} style={{ textAlign: "right" }}> <Col span={24} style={{ textAlign: "right" }}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
@ -79,7 +79,7 @@ export const Supplier = observer(() => {
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
onSearch={(value) => console.log(value)} onSearch={(value) => console.log(value)}
/> /> */}
<Button <Button
onClick={() => (store.supplier.visibleModalSupplier = true)} onClick={() => (store.supplier.visibleModalSupplier = true)}
> >

View File

@ -1,151 +1,279 @@
import React, {useContext, useEffect} from "react"; import React, {useContext, useEffect, useState} from "react";
import {Button, Card, Col, Row, Table, Typography} from "antd"; import {Button, Card, Col, message, Row, Space, Table, Tag, Typography,} from "antd";
import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import {BreadcumbComponent} from "../../component/BreadcumbComponent";
import {LINKS} from "../../routes/app"; import {LINKS} from "../../routes/app";
import {useStore} from "../../utils/useStore"; import {useStore} from "../../utils/useStore";
import {observer} from "mobx-react-lite"; import {observer} from "mobx-react-lite";
import {FilterOutlined} from "@ant-design/icons";
import {format, parseISO} from "date-fns"; import {format, parseISO} from "date-fns";
import {ModalLoaderContext} from "../../utils/modal"; import {ModalLoaderContext} from "../../utils/modal";
import {useParams} from "react-router-dom"; import {useParams} from "react-router-dom";
import {MembershipModal} from "./MembershipModal";
const {Title, Text} = Typography; const {Title, Text} = Typography;
export const DetailUser = observer(() => { export const DetailUser = observer(() => {
const store = useStore(); const store = useStore();
const modalLoader = useContext(ModalLoaderContext); const modalLoader = useContext(ModalLoaderContext);
const { id } = useParams(); const {id} = useParams();
const [visibleModal, setVisibleModal] = useState(false);
const [isVisibleTopUpModal, setIsVisibleTopUpModal] = useState(false);
const [destination, setDestination] = useState(null);
const [initialData, setInitialData] = useState({});
const [confirmLoading, setConfirmLoading] = useState(false);
useEffect(() => {
(async () => {
modalLoader.setLoading(true);
await getData();
modalLoader.setLoading(false);
})();
return () => {
store.membership.dataDetail = {};
store.transaction.dataHistoryTopUp = [];
};
}, []);
const getData = async () => {
const isAdmin = store.authentication.userData.role === "Admin";
await Promise.allSettled([
store.transaction.getDataHistoryTopUp(id),
store.membership.getDetail(id),
store.role.getData(isAdmin)
]);
};
const changeStatus = async (id, isActive) => {
const status = isActive ? "inactive" : "active";
const status2 = isActive ? "Inactivating" : "Activating";
try {
modalLoader.setLoading(true);
const response = await store.membership.changeStatus(id, status);
modalLoader.setLoading(false);
response?.body?.statusCode === 201 || response?.body?.statusCode === 200
? message.success(`Success ${status2} Membership`)
: message.error(`Failed ${status2} Membership`);
await getData();
} catch (err) {
modalLoader.setLoading(false);
message.error(`Failed ${status2} Membership`);
}
};
const onSubmit = async (data) => {
data.superior = true;
setConfirmLoading(true);
modalLoader.setLoading(true);
try {
let response;
if (initialData.isChangePassword) {
response = await store.membership.changePassword(initialData.id, data);
} else {
response = await store.membership.update(initialData.id, data);
}
setVisibleModal(false);
if (response?.body?.statusCode === 200) {
message.success(
initialData.isChangePassword
? "Success Change Member Password"
: "Success Update Data Member");
} else {
message.error(
initialData.isChangePassword
? "Failed Change Member Password"
: "Failed Update Data Member");
}
await getData();
} catch (e) {
modalLoader.setLoading(false);
message.error(
initialData.isChangePassword
? "Failed Update Member Password"
: "Failed Update Data Member"
);
}
modalLoader.setLoading(false);
setConfirmLoading(false);
};
const columns = [
{
title: "Amount",
dataIndex: "amount",
key: "amount",
},
{
title: "Transaction Date",
dataIndex: "transaction_date",
key: "transaction_date",
render: (text, record) => {
return (
<Text>
{format(parseISO(record.transaction_date), "dd MMMM yyyy ")}
</Text>
);
},
},
{
title: "Status",
dataIndex: "isActive",
key: "isActive",
render: (text, record) => (
<Tag
color={store.membership.dataDetail.isActive === true ? "processing" : "#E3E8EE"}
style={{color: "#4F566B"}}
>
{store.membership.dataDetail.isActive === true ? " ACTIVE" : "INACTIVE"}
</Tag>
),
},
];
const routeData = [ const routeData = [
{ {
route: LINKS.HOME, route: LINKS.HOME,
name: "Home", name: "Home",
}, },
{
route: LINKS.MEMBERSHIP,
name: <span style={{ fontWeight: "bold" }}>Keanggotaan</span>,
},
{ {
route: LINKS.USER_DETAIL, route: LINKS.USER_DETAIL,
name: <span style={{fontWeight: 'bold'}}>Detail User</span>, name: <span style={{ fontWeight: "bold" }}>Detail Anggota</span>,
}, },
]; ];
console.log(id)
useEffect(() => {
(async () => {
modalLoader.setLoading(true);
await Promise.allSettled([
store.authentication.getProfile(),
store.transaction.getDataHistoryTopUp(id),
store.transaction.getDataHistoryTransaction(),
]);
modalLoader.setLoading(false);
})()
}, []);
const columns = [
{
title: 'Markup Price',
dataIndex: 'mark_up_price',
key: 'mark_up_price',
width: '20%',
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: '50%',
},
{
title: 'Transaction Date',
dataIndex: 'created_at',
key: 'created_at',
render: (text, record) => {
return (
<Text>{format(parseISO(record.created_at), 'dd MMMM yyyy HH:mm')}</Text>
)
},
},
]
const styleSaldoTitle = store.ui.mediaQuery.isDesktop ? {
display: "flex",
justifyContent: "center"
} : {fontSize: "0.75rem"};
const styleSaldoContent = store.ui.mediaQuery.isDesktop ? {
fontSize: '1.25rem',
display: "flex",
justifyContent: "center"
} : null;
return ( return (
<div className={["ppob-container"].join(" ")}> <div className={["ppob-container"].join(" ")}>
<BreadcumbComponent data={routeData}/> <BreadcumbComponent data={routeData} />
<Card> <Card>
<Title strong>Detail User</Title> <Title strong>Detail User</Title>
<Row style={{marginBottom: 20}}> <Row style={{ marginBottom: 20 }}>
<Col lg={12} xs={24}> <Col lg={12} xs={24}>
<Row> <Row>
<Col span={12}> <Col span={12}>
<Text strong>Name</Text> <Text strong>Name</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.transaction.data.name}</Text> <Text>{store.membership.dataDetail.userDetail?.name}</Text>
</Col>
<Col span={12}>
<Text strong>Username</Text>
</Col>
<Col span={12}>
<Text>{store.membership.dataDetail.username}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Role</Text> <Text strong>Role</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData?.userDetail?.phone_number}</Text> <Text>{store.membership.dataDetail.roles?.name}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Saldo Supplier</Text> <Text strong>Phone Number</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData?.username}</Text> <Text>
</Col> {store.membership.dataDetail.userDetail?.phone_number}
<Col span={12}> </Text>
<Text strong>Saldo System</Text>
</Col>
<Col span={12}>
<Text>{store.authentication.profileData.roles?.name}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Status</Text> <Text strong>Status</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData.superior?.username}</Text> <Text>
{store.membership.dataDetail.isActive === true
? "Aktif"
: "Inaktif"}
</Text>
</Col> </Col>
</Row> </Row>
</Col> </Col>
<Col lg={12} xs={24}> <Col lg={12} xs={24}>
<Row justify={"center"}> <Title strong level={3}>Action User Detail</Title>
<Col lg={24} xs={12}> <Space
<Title strong level={3} style={styleSaldoTitle}>Saldo</Title> size="middle"
</Col> align={"center"}
<Col lg={24} xs={12}> wrap={true}
<Text style={styleSaldoContent}>{store.authentication.profileData?.wallet}</Text> style={{textAlign: 'center'}}
</Col> >
</Row> {store.authentication.userData.role === "Admin" &&
<Button
type={store.membership.dataDetail.isActive === true ? "danger" : "primary"}
onClick={() => changeStatus(store.membership.dataDetail.id, store.membership.dataDetail.isActive)}
>
{store.membership.dataDetail.isActive === true ? "Inactive" : "Active"}
</Button>
}
{store.authentication.userData.role === "Admin" &&
<Button
onClick={() => {
setInitialData({
id: store.membership.dataDetail.id,
name: store.membership.dataDetail.userDetail.name,
username: store.membership.dataDetail.username,
phone_number: store.membership.dataDetail.userDetail.phone_number,
roleId: store.membership.dataDetail.roles.id,
isChangePassword: false,
});
setVisibleModal(true);
}}
>
Edit
</Button>
}
{store.authentication.userData.role === "Admin" &&
<Button
onClick={() => {
setInitialData({
id: store.membership.dataDetail.id,
name: store.membership.dataDetail.userDetail.name,
username: store.membership.dataDetail.username,
phone_number: store.membership.dataDetail.userDetail.phone_number,
roleId: store.membership.dataDetail.roles.id,
isChangePassword: true,
});
setVisibleModal(true);
}}
>
Ganti Password
</Button>
}
</Space>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col span={24}> <Col span={24}>
<div> <div>
<Title strong level={3}>History Top Up</Title> <Title strong level={3}>
History Top Up
<Button style={{marginBottom: '1rem'}} onClick={() => { </Title>
console.log('clicked filter')
}}>
<FilterOutlined/>
Filter
</Button>
<Table <Table
columns={columns} columns={columns}
dataSource={store.transaction.dataHistoryTransaction} dataSource={store.transaction.dataHistoryTopUp}
bordered bordered
/> />
</div> </div>
</Col> </Col>
</Row> </Row>
<div/> <div />
</Card> </Card>
<MembershipModal
visible={visibleModal}
confirmLoading={confirmLoading}
initialData={initialData}
onCreate={async (data) => {
onSubmit(data);
}}
onCancel={() => {
setInitialData({});
setVisibleModal(false);
}}
/>
</div> </div>
) );
}); });

View File

@ -1,32 +1,28 @@
import React, {useContext, useEffect, useState} from "react"; import React, { useContext, useEffect, useState } from "react";
import { import {
Button, Button,
Card, Card,
Col, Col,
Divider, Divider,
Form, Form,
Input, InputNumber,
InputNumber, List,
List, message,
message, Modal,
Modal, Row,
Row, Space,
Select, Table,
Space, Tag,
Table,
Tag,
} from "antd"; } from "antd";
import {useStore} from "../../utils/useStore"; import { useStore } from "../../utils/useStore";
import {observer} from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import {DownloadOutlined, PlusSquareOutlined} from "@ant-design/icons"; import { DownloadOutlined, PlusSquareOutlined } from "@ant-design/icons";
import {MembershipModal} from "./MembershipModal"; import { MembershipModal } from "./MembershipModal";
import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import { BreadcumbComponent } from "../../component/BreadcumbComponent";
import {LINKS} from "../../routes/app"; import { LINKS } from "../../routes/app";
import {useHistory} from "react-router-dom"; import { useHistory } from "react-router-dom";
import {ModalLoaderContext} from "../../utils/modal"; import { ModalLoaderContext } from "../../utils/modal";
const {Search} = Input;
const {Option} = Select;
export const Membership = observer(() => { export const Membership = observer(() => {
const history = useHistory(); const history = useHistory();
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -71,14 +67,14 @@ export const Membership = observer(() => {
const status = isActive ? "inactive" : "active"; const status = isActive ? "inactive" : "active";
const status2 = isActive ? "Inactivating" : "Activating"; const status2 = isActive ? "Inactivating" : "Activating";
try { try {
modalLoader.setLoading(true); modalLoader.setLoading(true);
const response = await store.membership.changeStatus(id, status); const response = await store.membership.changeStatus(id, status);
modalLoader.setLoading(false); modalLoader.setLoading(false);
response?.body?.statusCode === 201 response?.body?.statusCode === 201
? message.success(`Success ${status2} Membership`) ? message.success(`Success ${status2} Membership`)
: message.error(`Failed ${status2} Membership`); : message.error(`Failed ${status2} Membership`);
await getData(); await getData();
} catch (err) { } catch (err) {
modalLoader.setLoading(false); modalLoader.setLoading(false);
message.error(`Failed ${status2} Membership`); message.error(`Failed ${status2} Membership`);
@ -93,26 +89,26 @@ export const Membership = observer(() => {
const handleSubmitTransaction = async (data) => { const handleSubmitTransaction = async (data) => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
data.destination = destination; data.destination = destination;
if (data.amount) { if (data.amount) {
data = { data = {
...data, ...data,
amount: Number(data.amount), amount: Number(data.amount),
}; };
} }
let response = null; let response = null;
(await store.authentication.userData.role) === "Admin" (await store.authentication.userData.role) === "Admin"
? (response = await store.transaction.distributeAdmin(data)) ? (response = await store.transaction.distributeAdmin(data))
: (response = await store.transaction.distribute(data)); : (response = await store.transaction.distribute(data));
response?.body?.statusCode === 201 response?.body?.statusCode === 201
? message.success("Success Top Up") ? message.success("Success Top Up")
: message.error("Failed Top Up"); : message.error("Failed Top Up");
modalLoader.setLoading(false); modalLoader.setLoading(false);
await getData(); await getData();
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
modalLoader.setLoading(false); modalLoader.setLoading(false);
@ -142,79 +138,30 @@ export const Membership = observer(() => {
key: ["coa", "amount"], key: ["coa", "amount"],
width: "20%", width: "20%",
render: (text) => render: (text) =>
new Intl.NumberFormat("id-ID", { new Intl.NumberFormat("id-ID", {
style: "currency", style: "currency",
currency: "IDR", currency: "IDR",
}).format(text), }).format(text),
},
{
title: "Status",
dataIndex: "isActive",
key: "isActive",
render: (text, record) => (
<Tag
color={record?.isActive === true ? "processing" : "#E3E8EE"}
style={{ color: "#4F566B" }}
>
{record?.isActive === true ? " ACTIVE" : "INACTIVE"}
</Tag>
),
}, },
{ {
title: "Action", title: "Action",
key: "action", key: "action",
render: (text, record) => ( render: (text, record) => (
<Space size="middle"> <Space size="middle">
{store.authentication.userData.role === "Admin" && <Button <Button
type={record?.isActive === true ? "danger" : "primary"} onClick={() => {
onClick={() => changeStatus(record?.id, record?.isActive)} setDestination(record?.id);
> console.log(record?.id);
{record?.isActive === true ? "Inactive" : "Active"} setIsVisibleTopUpModal(true);
</Button>} }}
<Button >
onClick={() => { <DownloadOutlined /> Top Up Saldo
setDestination(record?.id); </Button>
console.log(record?.id);
setIsVisibleTopUpModal(true);
}}
>
<DownloadOutlined/> Top Up Saldo
</Button>
{store.authentication.userData.role === "Admin" && <Button
onClick={() => {
let record2 = record;
delete record2.password;
record2.isChangePassword = false;
setInitialData({
...record2,
// roleId: record.roles.id,
});
setVisibleModal(true);
}}
>
Edit
</Button>}
{store.authentication.userData.role === "Admin" && <Button
onClick={() => {
let record2 = record;
delete record2.password;
record2.isChangePassword = true;
setInitialData({
...record2,
// roleId: record.roles.id,
});
setVisibleModal(true);
}}
>
Ganti Password
</Button>}
<Button <Button
onClick={async () => { onClick={async () => {
await store.transaction.getDataHistoryTopUp(record.id) await store.transaction.getDataHistoryTopUp(record.id);
history.push(LINKS.USER_DETAIL.replace(":id", record.id)); history.push(LINKS.USER_DETAIL.replace(":id", record.id));
console.log(record.id); console.log(record.id);
}} }}
> >
Detail Detail
@ -230,8 +177,8 @@ export const Membership = observer(() => {
name: "Home", name: "Home",
}, },
{ {
route: "/app/membership", route: LINKS.MEMBERSHIP,
name: <span style={{ fontWeight: "bold" }}>Membership</span>, name: <span style={{ fontWeight: "bold" }}>Keanggotaan</span>,
}, },
]; ];
@ -264,12 +211,14 @@ export const Membership = observer(() => {
setConfirmLoading(true); setConfirmLoading(true);
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
await store.membership.create(data); const response = await store.membership.create(data);
message.success("Success Add New Member"); response?.body?.statusCode === 201 || response?.body?.statusCode === 200
await getData(); ? message.success("Berhasil Tambah Member Baru")
: message.error("Gagal Tambah Member Baru");
await getData();
} catch (e) { } catch (e) {
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Add Member"); message.error("Gagal Tambah Member Baru");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
setConfirmLoading(false); setConfirmLoading(false);
@ -291,14 +240,14 @@ export const Membership = observer(() => {
</Button> */} </Button> */}
</Col> </Col>
<Col span={12} style={{ textAlign: "right" }}> <Col span={12} style={{ textAlign: "right" }}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
<Button <Button
onClick={() => { onClick={() => {
setInitialData({}); setInitialData({});
@ -318,7 +267,7 @@ export const Membership = observer(() => {
bordered bordered
pagination={{ pagination={{
pageSize: store.membership.pageSize, pageSize: store.membership.pageSize,
total: store.membership.total_data, total: store.membership.totalData,
current: store.membership.page + 1, current: store.membership.page + 1,
showSizeChanger: true, showSizeChanger: true,
simple: false, simple: false,
@ -339,17 +288,17 @@ export const Membership = observer(() => {
itemLayout="horizontal" itemLayout="horizontal"
position={"top"} position={"top"}
pagination={{ pagination={{
onChange: async (page) => { onChange: async (page) => {
store.membership.pageSize = page.pageSize; store.membership.pageSize = page.pageSize;
store.membership.page = page.current - 1; store.membership.page = page.current - 1;
modalLoader.setLoading(true); modalLoader.setLoading(true);
await getData(); await getData();
modalLoader.setLoading(false); modalLoader.setLoading(false);
}, },
pageSize: store.membership.pageSize, pageSize: store.membership.pageSize,
total: store.membership.total_data, total: store.membership.totalData,
current: store.membership.page + 1, current: store.membership.page + 1,
style: {marginBottom: "1rem", marginRight: "1rem"}, style: { marginBottom: "1rem", marginRight: "1rem" },
}} }}
dataSource={store.membership.data} dataSource={store.membership.data}
style={{ padding: 0 }} style={{ padding: 0 }}
@ -383,6 +332,29 @@ export const Membership = observer(() => {
Saldo System : {item.coa.amount} Saldo System : {item.coa.amount}
</small>{" "} </small>{" "}
<br /> <br />
<Button
style={{marginRight:10}}
onClick={() => {
setDestination(item?.id);
console.log(item?.id);
setIsVisibleTopUpModal(true);
}}
>
<DownloadOutlined /> Top Up Saldo
</Button>
<Button
onClick={async () => {
await store.transaction.getDataHistoryTopUp(
item.id
);
history.push(
LINKS.USER_DETAIL.replace(":id", item.id)
);
console.log(item.id);
}}
>
Detail
</Button>
</p> </p>
</div> </div>
} }
@ -394,7 +366,7 @@ export const Membership = observer(() => {
margin: 0, margin: 0,
}} }}
> >
<Button {/* <Button
type={ type={
item?.isActive === true ? "danger" : "primary" item?.isActive === true ? "danger" : "primary"
} }
@ -403,7 +375,7 @@ export const Membership = observer(() => {
} }
> >
{item?.isActive === true ? "Inactive" : "Active"} {item?.isActive === true ? "Inactive" : "Active"}
</Button> </Button> */}
</p> </p>
</div> </div>
</List.Item> </List.Item>

View File

@ -12,100 +12,96 @@ export const MembershipModal = ({
const {Option} = Select; const {Option} = Select;
const store = useStore(); const store = useStore();
return ( return (
<Modal <Modal
visible={visible} visible={visible}
title={ title={
initialData.isChangePassword initialData.isChangePassword
? "Change Member Password" ? "Change Member Password"
: initialData.id : initialData.id
? "Edit Member" ? "Edit Member"
: "Create a new Membership" : "Create a new Membership"
} }
okText={initialData.id ? "Edit" : "Create"} okText={initialData.id ? "Edit" : "Create"}
cancelText="Cancel" cancelText="Cancel"
onCancel={() => { onCancel={() => {
form.resetFields(); form.resetFields();
onCancel(); onCancel();
}} }}
onOk={() => { onOk={() => {
form form
.validateFields() .validateFields()
.then((values) => { .then((values) => {
let input = values; onCreate(values);
if (initialData.id) form.resetFields();
input.username = initialData.username; })
.catch((info) => {
onCreate(input); console.log("Validate Failed:", info);
form.resetFields(); });
}) }}
.catch((info) => { >
console.log("Validate Failed:", info); <Form
}); form={form}
}} layout="vertical"
> name="form_in_modal"
<Form initialValues={initialData}
form={form} >
layout="vertical" {((initialData.id && !initialData.isChangePassword) ||
name="form_in_modal" !initialData.id) && (
initialValues={initialData} <Form.Item
> name="name"
{((initialData.id && !initialData.isChangePassword) || label="Name"
!initialData.id) && ( rules={[{required: true, message: "Please input Name!"}]}
<Form.Item >
name="name" <Input/>
label="Name" </Form.Item>
rules={[{ required: true, message: "Please input Name!" }]} )}
> {!initialData.id && (
<Input /> <Form.Item
</Form.Item> name="username"
)} label="Username"
{!initialData.id && ( rules={[{required: true, message: "Please input Username!"}]}
<Form.Item >
name="username" <Input/>
label="Username" </Form.Item>
rules={[{ required: true, message: "Please input Username!" }]} )}
> {((initialData.id && initialData.isChangePassword) ||
<Input /> !initialData.id) && (
</Form.Item> <Form.Item
)} name="password"
{((initialData.id && initialData.isChangePassword) || label="Password"
!initialData.id) && ( rules={[{required: false, message: "Please input password!"}]}
<Form.Item >
name="password" <Input.Password/>
label="Password" </Form.Item>
rules={[{ required: false, message: "Please input password!" }]} )}
> {((initialData.id && !initialData.isChangePassword) ||
<Input.Password/> !initialData.id) && (
</Form.Item> <Form.Item
)} name="phone_number"
{((initialData.id && !initialData.isChangePassword) || label="Phone Number"
!initialData.id) && ( rules={[{required: true, message: "Please input Phone Number!"}]}
<Form.Item >
name="phone_number" <Input/>
label="Phone Number" </Form.Item>
rules={[{ required: true, message: "Please input Phone Number!" }]} )}
> {((initialData.id && !initialData.isChangePassword) ||
<Input /> !initialData.id) && (
</Form.Item> <Form.Item
)} name="roleId"
{((initialData.id && !initialData.isChangePassword) || label="Role"
!initialData.id) && ( rules={[{required: true, message: "Please input role id!"}]}
<Form.Item >
name="roleId" <Select>
label="Role" {store.role.data.map((item) => (
rules={[{ required: true, message: "Please input role id!" }]} <Option key={item.id} value={item.id}>
> {item.name}
<Select> </Option>
{store.role.data.map((item) => ( ))}
<Option key={item.id} value={item.id}> </Select>
{item.name} </Form.Item>
</Option> )}
))} </Form>
</Select> </Modal>
</Form.Item> );
)}
</Form>
</Modal>
);
}; };

View File

@ -1,271 +1,295 @@
import React, {useContext, useEffect} from "react"; import React, { useContext, useEffect } from "react";
import {Button, Card, Col, Divider, Image, Input, List, message, Modal, Row, Space, Table, Tag,} from "antd"; import {
import {useStore} from "../../utils/useStore"; Button,
import {observer} from "mobx-react-lite"; Card,
import {CheckCircleOutlined, CheckOutlined, CloseOutlined, FilterOutlined, StopOutlined,} from "@ant-design/icons"; Col,
import {BreadcumbComponent} from "../../component/BreadcumbComponent"; Divider,
import {LINKS} from "../../routes/app"; Image,
import {ModalLoaderContext} from "../../utils/modal"; Input,
import {appConfig} from "../../config/app"; List,
import {capitalize} from "lodash"; message,
import {PAYBACK_STATUS} from "../../constants/payback"; Modal,
Row,
Space,
Table,
Tag,
} from "antd";
import { useStore } from "../../utils/useStore";
import { observer } from "mobx-react-lite";
import {
CheckCircleOutlined,
CheckOutlined,
CloseOutlined,
FilterOutlined,
StopOutlined,
} from "@ant-design/icons";
import { BreadcumbComponent } from "../../component/BreadcumbComponent";
import { LINKS } from "../../routes/app";
import { ModalLoaderContext } from "../../utils/modal";
import { appConfig } from "../../config/app";
import { capitalize } from "lodash";
import { PAYBACK_STATUS } from "../../constants/payback";
const {Search} = Input; const { Search } = Input;
export const Payback = observer(() => { export const Payback = observer(() => {
const store = useStore(); const store = useStore();
const modalLoader = useContext(ModalLoaderContext); const modalLoader = useContext(ModalLoaderContext);
useEffect(() => { useEffect(() => {
const init = async () => { const init = async () => {
try { try {
modalLoader.setLoading(true); modalLoader.setLoading(true);
await store.payback.getDataConfirmation(); await store.payback.getDataConfirmation();
modalLoader.setLoading(false); modalLoader.setLoading(false);
} catch (e) { } catch (e) {
modalLoader.setLoading(false); modalLoader.setLoading(false);
if (e.response?.body?.message) { if (e.response?.body?.message) {
message.error(e.response.body.message); message.error(e.response.body.message);
return; return;
} }
message.error(e.message); message.error(e.message);
}
};
init();
}, []);
const columns = [
{
title: "Name",
dataIndex: "userData_name",
key: "userData_name",
},
{
title: "Picture",
dataIndex: "image_prove",
key: "image_prove",
render: (text, record) => (
<Image
src={`${appConfig.apiUrl}/config/image/${text}`}
style={{ width: "5vw" }}
alt={record.id}
/>
),
},
{
title: "Amount",
dataIndex: "amount",
key: "amount",
width: "20%",
render: (text) =>
new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
}).format(text),
},
{
title: "Action",
dataIndex: "amount",
key: "action",
width: "10%",
render: (text, record) =>
PAYBACK_STATUS[record.status] === PAYBACK_STATUS[0] ? (
<Space size="middle">
<Button
onClick={async () => {
Modal.confirm({
title: `Are you sure Accept this submission?`,
icon: <CheckOutlined />,
okText: "Accept",
cancelText: "Cancel",
okType: "primary",
onOk() {
handleAction(record.id, "accept");
},
onCancel() {
console.log("Cancel");
},
});
}}
icon={<CheckCircleOutlined />}
style={{
backgroundColor: "#1bb91d",
color: "#fff",
borderColor: "#1bb91d",
}}
>
Accept
</Button>
<Button
onClick={async () => {
Modal.confirm({
title: `Are you sure Reject this submission?`,
icon: <StopOutlined />,
okText: "Reject",
cancelText: "Cancel",
okType: "primary",
onOk() {
handleAction(record.id, "reject");
},
onCancel() {
console.log("Cancel");
},
});
}}
icon={<CloseOutlined />}
style={{
backgroundColor: "#ff1c1c",
color: "#fff",
borderColor: "#ff1c1c",
}}
>
Reject
</Button>
</Space>
) : (
<Tag
color={
PAYBACK_STATUS[record.status] === PAYBACK_STATUS[3]
? "cyan"
: "red"
} }
}; style={{ color: "#4F566B" }}
>
init(); {PAYBACK_STATUS[record.status]}
}, []); </Tag>
),
const columns = [ },
{
title: "Name",
dataIndex: "userData_name",
key: "userData_name",
},
{
title: "Picture",
dataIndex: "image_prove",
key: "image_prove",
render: (text, record) => (
<Image
src={`${appConfig.apiUrl}/config/image/${text}`}
style={{width: '5vw'}}
alt={record.id}
/>
),
},
{
title: "Amount",
dataIndex: "amount",
key: "amount",
width: '20%',
render: (text) =>
new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
}).format(text),
},
{
title: "Action",
dataIndex: "amount",
key: "action",
width: '10%',
render: (text, record) => (
PAYBACK_STATUS[record.status] === PAYBACK_STATUS[0] ?
<Space size="middle">
<Button
onClick={async () => {
Modal.confirm({
title: `Are you sure Accept this submission?`,
icon: <CheckOutlined/>,
okText: "Accept",
cancelText: "Cancel",
okType: "primary",
onOk() {
handleAction(record.id, "accept");
},
onCancel() {
console.log("Cancel");
},
})
}}
icon={<CheckCircleOutlined/>}
style={{
backgroundColor: "#1bb91d",
color: "#fff",
borderColor: "#1bb91d",
}}
>
Accept
</Button>
<Button
onClick={async () => {
Modal.confirm({
title: `Are you sure Reject this submission?`,
icon: <StopOutlined/>,
okText: "Reject",
cancelText: "Cancel",
okType: "primary",
onOk() {
handleAction(record.id, "reject");
},
onCancel() {
console.log("Cancel");
},
})
}}
icon={<CloseOutlined/>}
style={{
backgroundColor: "#ff1c1c",
color: "#fff",
borderColor: "#ff1c1c",
}}
>
Reject
</Button>
</Space> :
<Tag
color={PAYBACK_STATUS[record.status] === PAYBACK_STATUS[3] ? "cyan" : "red"}
style={{color: "#4F566B"}}
>
{PAYBACK_STATUS[record.status]}
</Tag>
),
},
]; ];
if (store.authentication.userData.role === "Retail") columns.pop(); if (store.authentication.userData.role === "Retail") columns.pop();
const routeData = [ const routeData = [
{ {
route: LINKS.HOME, route: LINKS.HOME,
name: "Home", name: "Home",
}, },
{ {
route: LINKS.PAYBACK, route: LINKS.PAYBACK,
name: <span style={{fontWeight: "bold"}}>Payback Confirmation</span>, name: <span style={{ fontWeight: "bold" }}>Konfirmasi Pembayaran</span>,
}, },
]; ];
const handleAction = async (id, type) => { const handleAction = async (id, type) => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
const response = await store.payback.confirmPayback(id, type); const response = await store.payback.confirmPayback(id, type);
if (response.body.status !== 201) { if (response.body.status !== 201) {
message.error(`Failed ${capitalize(type)} Payback`); message.error(`Failed ${capitalize(type)} Payback`);
} else { } else {
message.success(`Success ${capitalize(type)} Payback`); message.success(`Success ${capitalize(type)} Payback`);
} }
} catch (e) { } catch (e) {
console.error(e, "apa errornya"); console.error(e, "apa errornya");
message.error("Failed Handler Action Payback"); message.error("Failed Handler Action Payback");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
}; };
return ( return (
<div className={["ppob-container"].join(" ")}> <div className={["ppob-container"].join(" ")}>
<BreadcumbComponent data={routeData}/> <BreadcumbComponent data={routeData} />
<Card> <Card>
<div> <div>
<Row style={{marginBottom: 20}}> <Row style={{ marginBottom: 20 }}>
<Col span={12}> <Col span={12}>
<Button> <Button>
<FilterOutlined/> <FilterOutlined />
Filter Filter
</Button> </Button>
</Col> </Col>
<Col span={12} style={{textAlign: "right"}}> <Col span={12} style={{ textAlign: "right" }}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
</Col> </Col>
</Row> </Row>
{store.ui.mediaQuery.isDesktop && ( {store.ui.mediaQuery.isDesktop && (
<Table <Table
key="1" key="1"
hasEmpty hasEmpty
columns={columns} columns={columns}
dataSource={store.payback.dataConfirmation} dataSource={store.payback.dataConfirmation}
bordered bordered
pagination={{ pagination={{
pageSize: store.payback.pageSizeConfirmation, pageSize: store.payback.pageSizeConfirmation,
total: store.payback.totalDataConfirmation, total: store.payback.totalDataConfirmation,
current: store.payback.pageSizeConfirmation + 1, current: store.payback.pageSizeConfirmation + 1,
showSizeChanger: true, showSizeChanger: true,
simple: false simple: false,
}} }}
onChange={async (page) => { onChange={async (page) => {
let pageNumber = page.current; let pageNumber = page.current;
store.payback.pageSizeConfirmation = page.pageSize; store.payback.pageSizeConfirmation = page.pageSize;
store.payback.pageConfirmation = pageNumber - 1; store.payback.pageConfirmation = pageNumber - 1;
modalLoader.setLoading(true); modalLoader.setLoading(true);
await store.payback.getDataConfirmation(); await store.payback.getDataConfirmation();
modalLoader.setLoading(false); modalLoader.setLoading(false);
}} }}
/> />
)} )}
{store.ui.mediaQuery.isMobile && ( {store.ui.mediaQuery.isMobile && (
<List <List
itemLayout="horizontal" itemLayout="horizontal"
position={"top"} position={"top"}
pagination={{ pagination={{
onChange: async (page) => { onChange: async (page) => {
store.payback.pageSizeConfirmation = page.pageSize; store.payback.pageSizeConfirmation = page.pageSize;
store.payback.pageConfirmation = page.current - 1; store.payback.pageConfirmation = page.current - 1;
modalLoader.setLoading(true); modalLoader.setLoading(true);
await store.payback.getDataConfirmation(); await store.payback.getDataConfirmation();
modalLoader.setLoading(false); modalLoader.setLoading(false);
}, },
pageSize: store.payback.pageSizeConfirmation, pageSize: store.payback.pageSizeConfirmation,
total: store.payback.totalDataConfirmation, total: store.payback.totalDataConfirmation,
current: store.payback.pageConfirmation + 1, current: store.payback.pageConfirmation + 1,
style: {marginBottom: "1rem", marginRight: "1rem"}, style: { marginBottom: "1rem", marginRight: "1rem" },
}} }}
dataSource={store.payback.dataConfirmation} dataSource={store.payback.dataConfirmation}
style={{padding: 0}} style={{ padding: 0 }}
renderItem={(item) => { renderItem={(item) => {
return ( return (
<div> <div>
<List.Item <List.Item
key={item.id} key={item.id}
style={{ style={{
backgroundColor: "#ffffff", backgroundColor: "#ffffff",
paddingTop: 0, paddingTop: 0,
paddingBottom: 0, paddingBottom: 0,
display: "flex", display: "flex",
flexDirection: "row", flexDirection: "row",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}} }}
> >
<List.Item.Meta <List.Item.Meta
className={["cariparkir-container"].join(" ")} className={["cariparkir-container"].join(" ")}
title={item.name} title={item.name}
description={ description={
<div style={{}}> <div style={{}}>
<Image src={item.picture} preview={false}/> <Image src={item.picture} preview={false} />
</div> </div>
} }
/> />
<div style={{marginRight: 16}}> <div style={{ marginRight: 16 }}>
<p <p
style={{ style={{
fontSize: 9, fontSize: 9,
margin: 0, margin: 0,
}} }}
> >
{item.amount} {item.amount}
</p> </p>
</div> </div>
</List.Item> </List.Item>
<Divider plain style={{margin: 0}}/> <Divider plain style={{ margin: 0 }} />
</div> </div>
); );
}} }}

View File

@ -84,7 +84,7 @@ export const PaybackCreated = observer(() => {
}, },
{ {
route: LINKS.PAYBACK_CREATED, route: LINKS.PAYBACK_CREATED,
name: <span style={{fontWeight: "bold"}}>Payback Created</span>, name: <span style={{fontWeight: "bold"}}>Buat Pembayaran</span>,
}, },
]; ];
@ -101,14 +101,14 @@ export const PaybackCreated = observer(() => {
</Button> </Button>
</Col> </Col>
<Col span={12} style={{textAlign: "right"}}> <Col span={12} style={{textAlign: "right"}}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
{store.authentication.userData.role !== "Admin" && ( {store.authentication.userData.role !== "Admin" && (
<Button <Button
onClick={() => { onClick={() => {

View File

@ -3,7 +3,6 @@ import {Form, InputNumber, message, Modal, Upload,} from "antd";
import {useStore} from "../../utils/useStore"; import {useStore} from "../../utils/useStore";
import {LoadingOutlined, PlusOutlined} from "@ant-design/icons"; import {LoadingOutlined, PlusOutlined} from "@ant-design/icons";
import {ModalLoaderContext} from "../../utils/modal"; import {ModalLoaderContext} from "../../utils/modal";
import {http} from "../../utils/http";
import {appConfig} from "../../config/app"; import {appConfig} from "../../config/app";
export const PaybackModal = ({initialData}) => { export const PaybackModal = ({initialData}) => {
@ -32,7 +31,7 @@ export const PaybackModal = ({initialData}) => {
const uploadHandler = async (args) => { const uploadHandler = async (args) => {
const file = args.file; const file = args.file;
const res = await http.upload(file); const res = await store.payback.uploadImages(file);
setImage(`${appConfig.apiUrl}/config/image/${res.body.filename}`); setImage(`${appConfig.apiUrl}/config/image/${res.body.filename}`);
setResponseFilename(res.body.filename); setResponseFilename(res.body.filename);
setFileList([{ setFileList([{

View File

@ -41,7 +41,7 @@ export const Category = observer(() => {
}, },
{ {
route: LINKS.CATEGORY, route: LINKS.CATEGORY,
name: <span style={{ fontWeight: "bold" }}>Category</span>, name: <span style={{ fontWeight: "bold" }}>Kategori</span>,
}, },
]; ];
@ -50,21 +50,21 @@ export const Category = observer(() => {
<BreadcumbComponent data={routeData} /> <BreadcumbComponent data={routeData} />
<Card> <Card>
<Row style={{ marginBottom: 20 }}> <Row style={{ marginBottom: 20 }}>
<Col span={12}> {/* <Col span={12}>
<Button> <Button>
<FilterOutlined /> <FilterOutlined />
Filter Filter
</Button> </Button>
</Col> </Col> */}
<Col span={12} style={{ textAlign: "right" }}> <Col span={24} style={{ textAlign: "right" }}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
<Button <Button
onClick={() => (store.category.visibleModalCategory = true)} onClick={() => (store.category.visibleModalCategory = true)}
> >

View File

@ -1,26 +1,30 @@
import React, { useContext, useEffect } from "react"; import React, {useContext, useEffect, useState} from "react";
import { Button, Card, Col, Input, message, Row, Upload } from "antd"; import {Button, Card, Col, Form, Input, message, Modal, Row, Select, Upload} from "antd";
import { import {FilterOutlined, PlusOutlined, UploadOutlined,} from "@ant-design/icons";
FilterOutlined, import {BreadcumbComponent} from "../../component/BreadcumbComponent";
PlusSquareOutlined, import {useStore} from "../../utils/useStore";
UploadOutlined, import {observer} from "mobx-react-lite";
} from "@ant-design/icons"; import {ProductComponent} from "../../component/ProductComponent";
import { BreadcumbComponent } from "../../component/BreadcumbComponent"; import {LINKS} from "../../routes/app";
import { useStore } from "../../utils/useStore"; import {ModalLoaderContext} from "../../utils/modal";
import { observer } from "mobx-react-lite";
import { ProductComponent } from "../../component/ProductComponent";
import { LINKS } from "../../routes/app";
import { ModalLoaderContext } from "../../utils/modal";
const { Search } = Input; const {Search} = Input;
const {Option} = Select;
export const Product = observer(() => { export const Product = observer(() => {
const store = useStore(); const store = useStore();
const modalLoader = useContext(ModalLoaderContext); const modalLoader = useContext(ModalLoaderContext);
const [loading, setLoading] = useState(false);
const [visibleModalUpload, setVisibleModalUpload] = useState(false);
const [excel, setExcel] = useState("");
const [fileList, setFileList] = useState([]);
const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
const init = async () => { const init = async () => {
try { try {
store.supplier.page = 0;
store.supplier.pageSize = 1000;
modalLoader.setLoading(true); modalLoader.setLoading(true);
await Promise.allSettled([ await Promise.allSettled([
store.supplier.getData(), store.supplier.getData(),
@ -40,6 +44,10 @@ export const Product = observer(() => {
}; };
init(); init();
return () => {
store.supplier.pageSize = 10;
};
}, []); }, []);
const routeData = [ const routeData = [
@ -49,73 +57,231 @@ export const Product = observer(() => {
}, },
{ {
route: LINKS.PRODUCT, route: LINKS.PRODUCT,
name: <span style={{ fontWeight: "bold" }}>Product</span>, name: <span style={{fontWeight: "bold"}}>Produk</span>,
}, },
]; ];
const beforeUpload = (file) => {
let isLt2M;
let allowedFile = [
"text/csv", "application/csv",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"application/vnd.ms-excel",
"application/vnd.ms-excel.sheet.macroEnabled.12"
];
let isValid = allowedFile.includes(file.type);
if (!isValid) {
message.error("You can only upload Excel file!");
}
isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) {
message.error("File must smaller than 10MB!");
}
return isValid && isLt2M ? true : Upload.LIST_IGNORE;
};
const uploadHandler = async (args) => {
const file = args.file;
try {
const response = await store.product.uploadExcel(file);
if (response.status === 201) {
message.success("Success upload excel!");
} else {
message.error("Failed upload excel!");
}
setFileList([{
uid: '-1',
name: response.body.filename,
status: 'done',
url: '',
}]);
setExcel(response.body.filename);
} catch (e) {
setLoading(false);
message.error("Failed upload excel!");
}
};
const handleChange = (info) => {
if (info.file.status === 'uploading') {
setLoading(true);
} else {
setLoading(false)
}
};
const handleUploadProduct = async (data) => {
try {
const response = await store.product.uploadProduct(data);
if (response.status === 201) {
message.success("Success Create Product by Excel!");
} else {
message.error("Failed Create Product by Excel!");
}
return response;
} catch (e) {
setLoading(false);
message.error("Failed Create Product by Excel!");
}
};
const handleCancel = () => {
form.resetFields();
setFileList([]);
setExcel("");
setVisibleModalUpload(false);
};
const handleSubmit = async (data) => {
const request = {
fileName: excel,
supplierCode: data.supplierCode
};
const responseUploadProduct = await handleUploadProduct(request);
await store.product.getData();
setLoading(false);
setFileList([]);
setExcel("");
setVisibleModalUpload(false);
};
return ( return (
<div className={["ppob-container"].join(" ")}> <div className={["ppob-container"].join(" ")}>
<BreadcumbComponent data={routeData} /> <BreadcumbComponent data={routeData}/>
<Card> <Card>
<Row style={{ marginBottom: 20 }}> <div>
<Col span={12}> <Row style={{marginBottom: 20}}>
<Button <Col span={12}>
onClick={() => {
store.product.visibleModalFilterProduct = true;
}}
>
<FilterOutlined />
Filter
</Button>
</Col>
<Col span={12}>
<div
style={{
display: store.ui.mediaQuery.isMobile ? "" : "flex",
justifyContent: "flex-end",
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,
}}
/>
{store.authentication.userData.role === "Admin" && (
<div
style={{
display: store.ui.mediaQuery.isMobile ? "" : "flex",
justifyContent: "flex-end",
textAlign: "right",
}}
>
<Upload>
<Button <Button
disabled={store.product.uploadBtnProduct} onClick={() => {
store.product.visibleModalFilterProduct = true;
}}
>
<FilterOutlined/>
Filter
</Button>
</Col>
<Col span={12}>
<div
style={{
display: store.ui.mediaQuery.isMobile ? "" : "flex",
justifyContent: "flex-end",
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,
}}
/> */}
{store.authentication.userData.role == "Admin" && <div
style={{
display: store.ui.mediaQuery.isMobile ? "" : "flex",
justifyContent: "flex-end",
textAlign: "right",
}}
>
<Button
disabled={visibleModalUpload}
style={{
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 10,
}}
icon={<PlusOutlined/>}
onClick={() => setVisibleModalUpload(true)}
>
Tambah Produk
</Button>
</div>}
</div>
</Col>
</Row>
</div>
<ProductComponent/>
</Card>
<Modal
visible={visibleModalUpload}
title={"Upload Excel Product"}
okText={"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="fileName"
label="Upload Excel Product"
rules={[{required: true, message: "Please Upload Excel Product!"}]}
>
<Upload
fileList={fileList}
onChange={handleChange}
beforeUpload={(file) => beforeUpload(file)}
customRequest={(args) => uploadHandler(args)}
onRemove={(file) => {
setLoading(false);
setFileList([]);
setExcel("");
}}
>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
}}
>
<Button
disabled={loading}
style={{ style={{
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 10,
}} }}
icon={<UploadOutlined />} icon={<UploadOutlined/>}
>
Upload Product
</Button>
</Upload>
<Button
onClick={() => (store.product.visibleModalProduct = true)}
> >
<PlusSquareOutlined /> New Upload Product
</Button> </Button>
</div> </div>
)} </Upload>
</div> </Form.Item>
</Col> <Form.Item
</Row> name="supplierCode"
<ProductComponent /> label="Supplier Code"
</Card> rules={[{required: true, message: "Please input Supplier Code!"}]}
</div> >
<Select>
{store.supplier.data.map(data => (
<Option key={data.id} value={data.code}>
{data.name}
</Option>
))}
</Select>
</Form.Item>
</Form>
</Modal>
</div>
); );
}); });

View File

@ -1,17 +1,18 @@
import React, {useContext, useEffect} from "react"; import React, {useContext, useEffect} from "react";
import {Button, Card, Col, Row, Table, Typography} from "antd"; import {Card, Col, Row, Table, Typography} from "antd";
import {BreadcumbComponent} from "../../component/BreadcumbComponent"; import {BreadcumbComponent} from "../../component/BreadcumbComponent";
import {LINKS} from "../../routes/app"; import {LINKS} from "../../routes/app";
import {useStore} from "../../utils/useStore"; import {useStore} from "../../utils/useStore";
import {observer} from "mobx-react-lite"; import {observer} from "mobx-react-lite";
import {FilterOutlined} from "@ant-design/icons";
import {format, parseISO} from "date-fns"; import {format, parseISO} from "date-fns";
import {ModalLoaderContext} from "../../utils/modal"; import {ModalLoaderContext} from "../../utils/modal";
import {useParams} from "react-router-dom";
const {Title, Text} = Typography; const {Title, Text} = Typography;
export const ProductDetail = observer(() => { export const ProductDetail = observer(() => {
const store = useStore(); const store = useStore();
const {id} = useParams();
const modalLoader = useContext(ModalLoaderContext); const modalLoader = useContext(ModalLoaderContext);
const routeData = [ const routeData = [
@ -21,11 +22,11 @@ export const ProductDetail = observer(() => {
}, },
{ {
route: LINKS.PRODUCT, route: LINKS.PRODUCT,
name: <span style={{fontWeight: "bold"}}>Product</span>, name: <span style={{ fontWeight: "bold" }}>Produk</span>,
}, },
{ {
route: LINKS.PRODUCT_DETAIL, route: LINKS.PRODUCT_DETAIL,
name: <span style={{fontWeight: 'bold'}}>Product Detail</span>, name: <span style={{ fontWeight: "bold" }}>Detail Produk</span>,
}, },
]; ];
@ -33,89 +34,105 @@ export const ProductDetail = observer(() => {
(async () => { (async () => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
await Promise.allSettled([ await Promise.allSettled([
store.authentication.getProfile(), store.product.getPriceHistoryByProduct(id),
store.transaction.getDataHistoryTransaction(), store.product.getDetailProduct(id),
]); ]);
modalLoader.setLoading(false); modalLoader.setLoading(false);
})() })();
}, []); }, []);
const columns = [ const columns = [
{ {
title: 'Markup Price', title: "Markup Price",
dataIndex: 'mark_up_price', dataIndex: "mark_up_price",
key: 'mark_up_price', key: "mark_up_price",
width: '20%', render: (text) =>
new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
}).format(text),
}, },
{ {
title: 'Name', title: "Price",
dataIndex: 'name', dataIndex: "price",
key: 'name', key: "price",
width: '50%', render: (text) =>
new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
}).format(text),
}, },
{ {
title: 'Transaction Date', title: "Tanggal Berlaku",
dataIndex: 'created_at', dataIndex: "startDate",
key: 'created_at', key: "startDate",
render: (text, record) => { render: (text) => {
return ( return (
<Text>{format(parseISO(record.created_at), 'dd MMMM yyyy HH:mm')}</Text> <Text>{text ? format(parseISO(text), "dd MMMM yyyy") : "-"}</Text>
) );
}, },
}, },
] {
title: "Tanggal Berakhir",
dataIndex: "endDate",
key: "endDate",
render: (text) => {
return (
<Text>{text ? format(parseISO(text), "dd MMMM yyyy") : "Sampai Sekarang"}</Text>
);
},
},
];
const styleSaldoTitle = store.ui.mediaQuery.isDesktop ? { const styleSaldoTitle = store.ui.mediaQuery.isDesktop
display: "flex", ? {
justifyContent: "center" display: "flex",
} : {fontSize: "0.75rem"}; justifyContent: "center",
const styleSaldoContent = store.ui.mediaQuery.isDesktop ? { }
fontSize: '1.25rem', : { fontSize: "0.75rem" };
display: "flex", const styleSaldoContent = store.ui.mediaQuery.isDesktop
justifyContent: "center" ? {
} : null; fontSize: "1.25rem",
display: "flex",
justifyContent: "center",
}
: null;
return ( return (
<div className={["ppob-container"].join(" ")}> <div className={["ppob-container"].join(" ")}>
<BreadcumbComponent data={routeData}/> <BreadcumbComponent data={routeData} />
<Card> <Card>
<Title strong>Product Detail</Title> <Title strong>Product Detail</Title>
<Row style={{marginBottom: 20}}> <Row style={{ marginBottom: 20 }}>
<Col lg={12} xs={24}> <Col lg={12} xs={24}>
<Row> <Row>
<Col span={12}> <Col span={12}>
<Text strong>Kode</Text> <Text strong>Kode</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData?.userDetail?.name}</Text> <Text>{store.product?.dataDetailProduct?.code}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Produk</Text> <Text strong>Nama Produk</Text>
</Col>
<Col span={10}>
<Text>{store.product?.dataDetailProduct?.name}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData?.userDetail?.phone_number}</Text> <Text strong>Supplier</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Harga Beli</Text> <Text>{store.product?.dataDetailProduct?.supplier?.name}</Text>
</Col>
<Col span={12}>
<Text>{store.authentication.profileData?.username}</Text>
</Col>
<Col span={12}>
<Text strong>Harga Jual</Text>
</Col>
<Col span={12}>
<Text>{store.authentication.profileData.roles?.name}</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text strong>Status</Text> <Text strong>Status</Text>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Text>{store.authentication.profileData.superior?.username}</Text> <Text>{store.product?.dataDetailProduct?.status}</Text>
</Col> </Col>
</Row> </Row>
</Col> </Col>
<Col lg={12} xs={24}> {/* <Col lg={12} xs={24}>
<Row justify={"center"}> <Row justify={"center"}>
<Col lg={24} xs={12}> <Col lg={24} xs={12}>
<Title strong level={3} style={styleSaldoTitle}>Saldo</Title> <Title strong level={3} style={styleSaldoTitle}>Saldo</Title>
@ -124,29 +141,46 @@ export const ProductDetail = observer(() => {
<Text style={styleSaldoContent}>{store.authentication.profileData?.wallet}</Text> <Text style={styleSaldoContent}>{store.authentication.profileData?.wallet}</Text>
</Col> </Col>
</Row> </Row>
</Col> </Col> */}
</Row> </Row>
<Row> <Row>
<Col span={24}> <Col span={24}>
<div> <div>
<Title strong level={3}>History User Transaction</Title> <Title strong level={3}>
Product Price History
</Title>
<Button style={{marginBottom: '1rem'}} onClick={() => { {/* <Button style={{marginBottom: '1rem'}} onClick={() => {
console.log('clicked filter') console.log('clicked filter')
}}> }}>
<FilterOutlined/> <FilterOutlined/>
Filter Filter
</Button> </Button> */}
<Table <Table
columns={columns} columns={columns}
dataSource={store.transaction.dataHistoryTransaction} dataSource={store.product.dataPriceHistory}
bordered bordered
pagination={{
pageSize: store.product.pageSizePriceHistory,
total: store.product.totalDataPriceHistory,
current: store.product.pagePriceHistory + 1,
showSizeChanger: true,
simple: false,
}}
onChange={async (page) => {
let pageNumber = page.current;
store.product.pageSizePriceHistory = page.pageSize;
store.product.pagePriceHistory = pageNumber - 1;
modalLoader.setLoading(true);
await store.product.getPriceHistoryByProduct(id);
modalLoader.setLoading(false);
}}
/> />
</div> </div>
</Col> </Col>
</Row> </Row>
<div/> <div />
</Card> </Card>
</div> </div>
) );
}); });

View File

@ -45,7 +45,7 @@ export const Subcategory = observer(() => {
}, },
{ {
route: LINKS.SUBCATEGORY, route: LINKS.SUBCATEGORY,
name: <span style={{fontWeight: "bold"}}>Sub Category</span>, name: <span style={{fontWeight: "bold"}}>Sub Kategori</span>,
}, },
]; ];
@ -54,21 +54,21 @@ export const Subcategory = observer(() => {
<BreadcumbComponent data={routeData}/> <BreadcumbComponent data={routeData}/>
<Card> <Card>
<Row style={{marginBottom: 20}}> <Row style={{marginBottom: 20}}>
<Col span={12}> {/* <Col span={12}>
{/* <Button> <Button>
<FilterOutlined /> <FilterOutlined />
Filter Filter
</Button> */} </Button>
</Col> </Col> */}
<Col span={12} style={{textAlign: "right"}}> <Col span={24} style={{textAlign: "right"}}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{ style={{
width: store.ui.mediaQuery.isMobile ? 160 : 200, width: store.ui.mediaQuery.isMobile ? 160 : 200,
marginRight: store.ui.mediaQuery.isMobile ? 0 : 10, marginRight: store.ui.mediaQuery.isMobile ? 0 : 10,
marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0, marginBottom: store.ui.mediaQuery.isMobile ? 10 : 0,
}} }}
/> /> */}
<Button <Button
onClick={() => (store.subcategory.visibleModalSubcategory = true)} onClick={() => (store.subcategory.visibleModalSubcategory = true)}
> >

View File

@ -21,7 +21,7 @@ export const Profile = observer(() => {
}, },
{ {
route: LINKS.PROFILE, route: LINKS.PROFILE,
name: <span style={{fontWeight: 'bold'}}>Profile</span>, name: <span style={{fontWeight: 'bold'}}>Profil</span>,
}, },
]; ];
@ -60,7 +60,7 @@ export const Profile = observer(() => {
key: 'created_at', key: 'created_at',
render: (text, record) => { render: (text, record) => {
return ( return (
<Text>{format(parseISO(record.created_at), 'dd MMMM yyyy HH:mm')}</Text> <Text>{format(parseISO(record.created_at), 'mm:HH dd MM YYYY')}</Text>
) )
}, },
}, },

View File

@ -1,12 +1,12 @@
import React, {useContext, useEffect} from "react"; import React, { useContext, useEffect } from "react";
import {useStore} from "../../utils/useStore"; import { useStore } from "../../utils/useStore";
import {Button, Card, Col, Input, message, Modal, Row, Select} from "antd"; import { Button, Card, Col, Input, message, Modal, Row, Select } from "antd";
import {observer} from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import {MoneyCollectOutlined} from "@ant-design/icons"; import { MoneyCollectOutlined } from "@ant-design/icons";
import {ModalLoaderContext} from "../../utils/modal"; import { ModalLoaderContext } from "../../utils/modal";
const {Search} = Input; const { Search } = Input;
const {Option} = Select; const { Option } = Select;
export const Product = observer(() => { export const Product = observer(() => {
const store = useStore(); const store = useStore();
@ -18,8 +18,8 @@ export const Product = observer(() => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
await Promise.allSettled([ await Promise.allSettled([
store.transaction.getDataSubCategories(), store.transaction.getDataSubCategories(),
store.transaction.getDataCategories() store.transaction.getDataCategories(),
]) ]);
modalLoader.setLoading(false); modalLoader.setLoading(false);
} catch (e) { } catch (e) {
modalLoader.setLoading(false); modalLoader.setLoading(false);
@ -44,11 +44,13 @@ export const Product = observer(() => {
const handleBuyProduct = async (data) => { const handleBuyProduct = async (data) => {
modalLoader.setLoading(true); modalLoader.setLoading(true);
try { try {
const response = await store.transaction.buyProduct({productCode: data}); const response = await store.transaction.buyProduct({
productCode: data,
});
if (response.status === 201) { if (response.status === 201) {
message.success("Success Buy Product"); message.success("Berhasil Beli Produk");
} else { } else {
message.error("Failed Buy Product", 3); message.error("Gagal Beli Produk", 3);
} }
} catch (e) { } catch (e) {
if (e.response?.body?.message) { if (e.response?.body?.message) {
@ -56,7 +58,7 @@ export const Product = observer(() => {
return; return;
} }
console.log(e, "apa errornya"); console.log(e, "apa errornya");
message.error("Failed Buy Product"); message.error("Gagal Beli Product");
} }
modalLoader.setLoading(false); modalLoader.setLoading(false);
}; };
@ -64,16 +66,18 @@ export const Product = observer(() => {
return ( return (
<div> <div>
<Row> <Row>
<span style={{fontWeight: "bold", marginBottom: "10px"}}>Sub Category</span> <span style={{ fontWeight: "bold", marginBottom: "10px" }}>
Sub Category
</span>
</Row> </Row>
<Row> <Row>
<Col span={24}> <Col span={24}>
<Select <Select
placeholder={"Select Sub Category"} placeholder={"Select Sub Category"}
allowClear={true} allowClear={true}
onChange={(val) => handleChangeSubcategory(val)} onChange={(val) => handleChangeSubcategory(val)}
style={{marginBottom: "10px", width: "100%"}} style={{ marginBottom: "10px", width: "100%" }}
value={store.transaction.filterSubCategory} value={store.transaction.filterSubCategory}
> >
{store.transaction.dataSubCategories.map((item, index) => ( {store.transaction.dataSubCategories.map((item, index) => (
<Option key={item.id} value={item.id}> <Option key={item.id} value={item.id}>
@ -83,62 +87,69 @@ export const Product = observer(() => {
</Select> </Select>
</Col> </Col>
</Row> </Row>
<Row justify={"center"} align={"center"} style={{marginBottom: "1rem"}}> <Row justify={"center"} align={"center"} style={{ marginBottom: "1rem" }}>
<Col <Col
span={12} span={12}
style={{fontWeight: "bold", display: "flex", alignItems: "center"}} style={{ fontWeight: "bold", display: "flex", alignItems: "center" }}
> >
Produk & Nominal Produk & Nominal
</Col> </Col>
<Col span={12} style={{textAlign: "right"}}> <Col span={12} style={{ textAlign: "right" }}>
<Search {/* <Search
placeholder="input search text" placeholder="input search text"
style={{width: 200, marginRight: 10}} style={{ width: 200, marginRight: 10 }}
/> /> */}
</Col> </Col>
</Row> </Row>
{store.transaction.data.length != 0 && ( {store.transaction.data.length != 0 && (
<Row> <Row>
{store.transaction.data.map((item, index) => ( {store.transaction.data.map((item, index) => (
<Col key={index} xs={24} md={16} lg={8}> <Col key={index} xs={24} md={16} lg={8}>
<Card <Card
onClick={() => { onClick={() => {
Modal.confirm({ Modal.confirm({
title: `Are you sure buy ${item.product_name}?`, title: `Are you sure buy ${item.product_name}?`,
icon: <MoneyCollectOutlined/>, icon: <MoneyCollectOutlined />,
okText: "Confirm", okText: "Confirm",
cancelText: "Cancel", cancelText: "Cancel",
okType: "primary", okType: "primary",
onOk() { onOk() {
handleBuyProduct(item.product_code) handleBuyProduct(item.product_code);
}, },
onCancel() { onCancel() {
console.log("Cancel"); console.log("Cancel");
}, },
}); });
}} }}
style={{cursor: "pointer"}} hoverable
> style={{
<span style={{color: "black"}}>{item.product_name}</span> cursor: "pointer",
<br/> marginLeft: 10,
<span style={{color: "grey", fontSize: 10}}> borderColor: "salmon",
height: 100,
marginBottom: 10,
}}
>
<span style={{ color: "black" }}>{item.product_name}</span>
<br />
<span style={{ color: "grey", fontSize: 10 }}>
{new Intl.NumberFormat("id-ID", { {new Intl.NumberFormat("id-ID", {
style: "currency", style: "currency",
currency: "IDR", currency: "IDR",
}).format(item?.price)} }).format(item?.price)}
</span> </span>
</Card> </Card>
</Col> </Col>
))} ))}
</Row> </Row>
)} )}
{store.transaction.data.length !== 0 && ( {/* {store.transaction.data.length !== 0 && (
<Col style={{textAlign: "right", marginTop: "1em"}}> <Col style={{textAlign: "right", marginTop: "1em"}}>
<Button style={{backgroundColor: "#2D9CDB", color: "white"}}> <Button style={{backgroundColor: "#2D9CDB", color: "white"}}>
Beli Sekarang Beli Sekarang
</Button> </Button>
</Col> </Col>
)} )} */}
</div> </div>
); );
}); });

View File

@ -50,7 +50,7 @@ export const Transaction = observer(() => {
}, },
{ {
route: LINKS.TRANSACTION, route: LINKS.TRANSACTION,
name: <span style={{fontWeight: 'bold'}}>Transaction</span>, name: <span style={{fontWeight: 'bold'}}>Transaksi</span>,
}, },
]; ];

View File

@ -29,8 +29,8 @@ export const LINKS = {
PAYBACK: "/app/payback", PAYBACK: "/app/payback",
PAYBACK_CREATED: "/app/payback-created", PAYBACK_CREATED: "/app/payback-created",
SUBCATEGORY: "/app/subcategory", SUBCATEGORY: "/app/subcategory",
USER_DETAIL: "/app/user-detail", USER_DETAIL: "/app/user-detail/:id",
PRODUCT_DETAIL: "/app/product-detail", PRODUCT_DETAIL: "/app/product-detail/:id",
}; };
export const AppRoute = () => { export const AppRoute = () => {

View File

@ -63,5 +63,6 @@ export class Authentication {
TokenUtil.clearAccessToken(); TokenUtil.clearAccessToken();
TokenUtil.persistToken(); TokenUtil.persistToken();
this.isLoggedIn = false; this.isLoggedIn = false;
window.location.reload();
} }
} }

View File

@ -5,7 +5,9 @@ export class Membership {
page = 0; page = 0;
pageSize = 10 pageSize = 10
data = []; data = [];
total_data = 0 totalData = 0;
dataDetail = {};
constructor(ctx) { constructor(ctx) {
this.ctx = ctx; this.ctx = ctx;
@ -18,12 +20,23 @@ export class Membership {
this.data = response.body.data.map((item, idx) => { this.data = response.body.data.map((item, idx) => {
item.key = idx; item.key = idx;
item.name = item?.user_detail?.name; item.name = item?.user_detail?.name;
item.phone_number = item?.user_detail?.phone_number;item.roleId = item?.roles.id; item.phone_number = item?.user_detail?.phone_number;
item.roleId = item?.roles.id;
item.roleName = item?.roles.name; item.roleName = item?.roles.name;
return item return item
}) ?? [] }) ?? []
this.total_data = response?.body?.count ?? 0 this.totalData = response?.body?.count ?? 0
} catch (e) {
console.error(e);
}
}
async getDetail(id) {
try {
const response = await http.get(`/users/`+id);
console.log(response,'Data Detail')
this.dataDetail = response.body.data
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
@ -35,12 +48,13 @@ export class Membership {
this.data = response.body.data.map((item, idx) => { this.data = response.body.data.map((item, idx) => {
item.key = idx; item.key = idx;
item.name = item?.user_detail?.name; item.name = item?.user_detail?.name;
item.phone_number = item?.user_detail?.phone_number;item.roleId = item?.roles.id; item.phone_number = item?.user_detail?.phone_number;
item.roleId = item?.roles.id;
item.roleName = item?.roles?.name; item.roleName = item?.roles?.name;
return item return item
}) ?? [] }) ?? []
this.total_data = response?.body?.count ?? 0 this.totalData = response?.body?.count ?? 0
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
@ -64,6 +78,15 @@ export class Membership {
} }
} }
async changePassword(id, data) {
try {
const response = await http.put('/users/change-password/' + id).send(data);
return response;
} catch (e) {
console.error(e);
}
}
async delete(id) { async delete(id) {
try { try {
const response = await http.del('/users/' + id); const response = await http.del('/users/' + id);

View File

@ -93,4 +93,13 @@ export class Payback {
console.error(e); console.error(e);
} }
} }
async uploadImages(data) {
try {
const response = await http.upload(data);
return response;
} catch (e) {
console.error(e);
}
}
} }

View File

@ -13,7 +13,7 @@ export class Product {
uploadBtnProduct = false; uploadBtnProduct = false;
pageCategories = 0; pageCategories = 0;
pageSizeCategories = 10 pageSizeCategories = 100;
dataCategories = []; dataCategories = [];
total_dataCategories = 0; total_dataCategories = 0;
@ -23,6 +23,13 @@ export class Product {
total_dataSubCategories = 0; total_dataSubCategories = 0;
filterCategory = null; filterCategory = null;
dataPriceHistory = [];
totalDataPriceHistory = 0;
pagePriceHistory = 0;
pageSizePriceHistory = 10
dataDetailProduct = {};
constructor(ctx) { constructor(ctx) {
this.ctx = ctx; this.ctx = ctx;
makeAutoObservable(this); makeAutoObservable(this);
@ -31,7 +38,7 @@ export class Product {
async getData() { async getData() {
try { try {
const response = await http.get(`/product/all?supplier=${this.filterSupplier}&sub-category=${this.filterSubCategory}&page=${this.page}&pageSize=${this.pageSize}`); const response = await http.get(`/product/all?supplier=${this.filterSupplier}&sub-category=${this.filterSubCategory}&page=${this.page}&pageSize=${this.pageSize}`);
//console.log(response) console.log(response)
this.data = response.body.data.map((item, idx) => { this.data = response.body.data.map((item, idx) => {
item.key = idx; item.key = idx;
return item return item
@ -68,6 +75,25 @@ export class Product {
} }
} }
async getPriceHistoryByProduct(id) {
try {
const response = await http.get(`/product/price-history/${id}?page=${this.pagePriceHistory}&pageSize${this.pageSizePriceHistory}`);
this.dataPriceHistory = response.body.data
this.totalDataPriceHistory = response?.body?.count ?? 0
} catch (e) {
console.error(e);
}
}
async getDetailProduct(id) {
try {
const response = await http.get(`/product/${id}`);
this.dataDetailProduct = response.body.data
} catch (e) {
console.error(e);
}
}
async create(data) { async create(data) {
try { try {
const response = await http.post('/product').send(data); const response = await http.post('/product').send(data);
@ -107,6 +133,24 @@ export class Product {
console.error(e); console.error(e);
} }
} }
async uploadExcel(data) {
try {
const response = await http.upload(data);
return response;
} catch (e) {
console.error(e);
}
}
async uploadProduct(data) {
try {
const response = await http.post('/product/upload-product').send(data);
return response;
} catch (e) {
console.error(e);
}
}
} }

View File

@ -22,14 +22,15 @@ export class Transaction {
filterSubCategory = null; filterSubCategory = null;
pageHistoryTransaction = 0; pageHistoryTransaction = 0;
pageHistoryTopUp = 0;
pageSizeHistoryTransaction = 10 pageSizeHistoryTransaction = 10
dataHistoryTransaction = []; dataHistoryTransaction = [];
total_dataHistoryTransaction = 0; total_dataHistoryTransaction = 0;
dataHistoryTopUp=[]; pageHistoryTopUp = 0;
pageSizeHistoryTopUp = 10;
dataHistoryTopUp = [];
total_dataHistoryTopUp = 0; total_dataHistoryTopUp = 0;
constructor(ctx) { constructor(ctx) {
this.ctx = ctx; this.ctx = ctx;
makeAutoObservable(this); makeAutoObservable(this);
@ -58,7 +59,6 @@ export class Transaction {
async getDataCategories() { async getDataCategories() {
try { try {
const response = await http.get(`/product/categories?page=${this.pageCategories}&pageSize=${this.pageSizeCategories}`); const response = await http.get(`/product/categories?page=${this.pageCategories}&pageSize=${this.pageSizeCategories}`);
this.dataCategories = response.body.data ?? [] this.dataCategories = response.body.data ?? []
this.total_dataCategories = response?.body?.count ?? 0 this.total_dataCategories = response?.body?.count ?? 0
if (this.dataCategories.length > 0) { if (this.dataCategories.length > 0) {
@ -72,7 +72,6 @@ export class Transaction {
async getDataHistoryTransaction() { async getDataHistoryTransaction() {
try { try {
const response = await http.get(`/transaction/history?page=${this.pageHistoryTransaction}&pageSize=${this.pageSizeHistoryTransaction}`); const response = await http.get(`/transaction/history?page=${this.pageHistoryTransaction}&pageSize=${this.pageSizeHistoryTransaction}`);
this.dataHistoryTransaction = response.body.data ?? [] this.dataHistoryTransaction = response.body.data ?? []
this.total_dataHistoryTransaction = response?.body?.count ?? 0 this.total_dataHistoryTransaction = response?.body?.count ?? 0
} catch (e) { } catch (e) {
@ -82,9 +81,7 @@ export class Transaction {
async getDataHistoryTopUp(id) { async getDataHistoryTopUp(id) {
try { try {
console.log("Top up") const response = await http.get(`/transaction/history-deposit?page=${this.pageHistoryTopUp}&pageSize=${this.pageSizeHistoryTopUp}&user-destination=${id}`);
const response = await http.get(`/transaction/history-deposit?page=${this.pageHistoryTopUp}&user-destination=${id}`);
this.dataHistoryTopUp = response.body.data ?? [] this.dataHistoryTopUp = response.body.data ?? []
this.total_dataHistoryTopUp = response?.body?.count ?? 0 this.total_dataHistoryTopUp = response?.body?.count ?? 0
} catch (e) { } catch (e) {