feat: add modal loader for each API request
This commit is contained in:
		@@ -1,8 +1,9 @@
 | 
			
		||||
import React, {useEffect, useState} from "react";
 | 
			
		||||
import React, {useContext, useEffect, useState} from "react";
 | 
			
		||||
import {useStore} from "../../utils/useStore";
 | 
			
		||||
import {Button, Card, Col, Input, message, Modal, Row, Select} from "antd";
 | 
			
		||||
import {observer} from "mobx-react-lite";
 | 
			
		||||
import {MoneyCollectOutlined} from "@ant-design/icons";
 | 
			
		||||
import {ModalLoaderContext} from "../../utils/modal";
 | 
			
		||||
 | 
			
		||||
const {Search} = Input;
 | 
			
		||||
const {Option} = Select;
 | 
			
		||||
@@ -10,133 +11,139 @@ const {Option} = Select;
 | 
			
		||||
export const Product = observer(() => {
 | 
			
		||||
  const store = useStore();
 | 
			
		||||
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(false);
 | 
			
		||||
  const [productData, setProductData] = useState([]);
 | 
			
		||||
  const modalLoader = useContext(ModalLoaderContext);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const init = async () => {
 | 
			
		||||
      try {
 | 
			
		||||
          setIsLoading(true);
 | 
			
		||||
          await store.transaction.getDataSubCategories();
 | 
			
		||||
          await store.transaction.getDataCategories();
 | 
			
		||||
          setIsLoading(false);
 | 
			
		||||
        modalLoader.setLoading(true);
 | 
			
		||||
        await Promise.allSettled([
 | 
			
		||||
          store.transaction.getDataSubCategories(),
 | 
			
		||||
          store.transaction.getDataCategories()
 | 
			
		||||
        ])
 | 
			
		||||
        modalLoader.setLoading(false);
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
          setIsLoading(false);
 | 
			
		||||
        modalLoader.setLoading(false);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
      init();
 | 
			
		||||
    init();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
    // data
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        console.log("⚡ transaction data store", store.transaction.data);
 | 
			
		||||
        setProductData(store.transaction.data);
 | 
			
		||||
    }, [store.transaction.data]);
 | 
			
		||||
  // data
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    console.log("⚡ transaction data store", store.transaction.data);
 | 
			
		||||
    setProductData(store.transaction.data);
 | 
			
		||||
  }, [store.transaction.data]);
 | 
			
		||||
 | 
			
		||||
    // Subcategory
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        console.log(
 | 
			
		||||
            "⚡ transaction subcategory store",
 | 
			
		||||
            store.transaction.dataSubCategories
 | 
			
		||||
        );
 | 
			
		||||
    }, [store.transaction.dataSubCategories]);
 | 
			
		||||
  // Subcategory
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    console.log(
 | 
			
		||||
      "⚡ transaction subcategory store",
 | 
			
		||||
      store.transaction.dataSubCategories
 | 
			
		||||
    );
 | 
			
		||||
  }, [store.transaction.dataSubCategories]);
 | 
			
		||||
 | 
			
		||||
    const handleChangeSubcategory = async (item) => {
 | 
			
		||||
        store.transaction.filterSubCategory = item;
 | 
			
		||||
        await store.transaction.getData();
 | 
			
		||||
    };
 | 
			
		||||
  const handleChangeSubcategory = async (item) => {
 | 
			
		||||
    store.transaction.filterSubCategory = item;
 | 
			
		||||
    modalLoader.setLoading(true);
 | 
			
		||||
    await store.transaction.getData();
 | 
			
		||||
    modalLoader.setLoading(false);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    const handleBuyProduct = async (data) => {
 | 
			
		||||
        try {
 | 
			
		||||
            const response = await store.transaction.buyProduct({productCode: data});
 | 
			
		||||
            // if (response.status === 200) {
 | 
			
		||||
                message.success("Success Buy Product");
 | 
			
		||||
            // } else {
 | 
			
		||||
                //message.error("Failed Buy Product");
 | 
			
		||||
            //}
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            console.log(e, "apa errornya");
 | 
			
		||||
            message.error("Failed Buy Product");
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
  const handleBuyProduct = async (data) => {
 | 
			
		||||
    modalLoader.setLoading(true);
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await store.transaction.buyProduct({productCode: data});
 | 
			
		||||
      // if (response.status === 200) {
 | 
			
		||||
      message.success("Success Buy Product");
 | 
			
		||||
      // } else {
 | 
			
		||||
      //message.error("Failed Buy Product");
 | 
			
		||||
      //}
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.log(e, "apa errornya");
 | 
			
		||||
      message.error("Failed Buy Product");
 | 
			
		||||
    }
 | 
			
		||||
    modalLoader.setLoading(false);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div>
 | 
			
		||||
            <Row>
 | 
			
		||||
                <span style={{fontWeight: "bold", marginBottom: "10px"}}>Sub Category</span>
 | 
			
		||||
            </Row>
 | 
			
		||||
            <Row>
 | 
			
		||||
                <Col span={24}>
 | 
			
		||||
                    <Select
 | 
			
		||||
                        placeholder={"Select Sub Category"}
 | 
			
		||||
                        allowClear={true}
 | 
			
		||||
                        onChange={(val) => {
 | 
			
		||||
                            if (val) {
 | 
			
		||||
                                handleChangeSubcategory(val);
 | 
			
		||||
                            }
 | 
			
		||||
                        }}
 | 
			
		||||
                        style={{marginBottom: "10px", width: "100%"}}
 | 
			
		||||
                    >
 | 
			
		||||
                        {store.transaction.dataSubCategories.map((item, index) => (
 | 
			
		||||
                            <Option key={item.id} value={item.id}>
 | 
			
		||||
                                {item.name}
 | 
			
		||||
                            </Option>
 | 
			
		||||
                        ))}
 | 
			
		||||
                    </Select>
 | 
			
		||||
                </Col>
 | 
			
		||||
            </Row>
 | 
			
		||||
            <Row justify={"center"} align={"center"} style={{marginBottom: "1rem"}}>
 | 
			
		||||
                <Col
 | 
			
		||||
                    span={12}
 | 
			
		||||
                    style={{fontWeight: "bold", display: "flex", alignItems: "center"}}
 | 
			
		||||
                >
 | 
			
		||||
                    Produk & Nominal
 | 
			
		||||
                </Col>
 | 
			
		||||
                <Col span={12} style={{textAlign: "right"}}>
 | 
			
		||||
                    <Search
 | 
			
		||||
                        placeholder="input search text"
 | 
			
		||||
                        style={{width: 200, marginRight: 10}}
 | 
			
		||||
                    />
 | 
			
		||||
                </Col>
 | 
			
		||||
            </Row>
 | 
			
		||||
            {productData.length != 0 && (
 | 
			
		||||
                <Row>
 | 
			
		||||
                    {productData.map((item, index) => (
 | 
			
		||||
                        <Col key={index} xs={24} md={16} lg={8}>
 | 
			
		||||
                            <Card
 | 
			
		||||
                                onClick={() => {
 | 
			
		||||
                                    Modal.confirm({
 | 
			
		||||
                                        title: `Are you sure buy ${item.name}?`,
 | 
			
		||||
                                        icon: <MoneyCollectOutlined/>,
 | 
			
		||||
                                        okText: "Confirm",
 | 
			
		||||
                                        cancelText: "Cancel",
 | 
			
		||||
                                        okType: "primary",
 | 
			
		||||
                                        onOk() {
 | 
			
		||||
                                            handleBuyProduct(item.code)
 | 
			
		||||
                                        },
 | 
			
		||||
                                        onCancel() {
 | 
			
		||||
                                            console.log("Cancel");
 | 
			
		||||
                                        },
 | 
			
		||||
                                    });
 | 
			
		||||
                                }}
 | 
			
		||||
                                style={{cursor: "pointer"}}
 | 
			
		||||
                            >
 | 
			
		||||
                                <span style={{color: "black"}}>{item.name}</span>
 | 
			
		||||
                                <br/>
 | 
			
		||||
                                <span style={{color: "grey", fontSize: 10}}>
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
      <Row>
 | 
			
		||||
        <span style={{fontWeight: "bold", marginBottom: "10px"}}>Sub Category</span>
 | 
			
		||||
      </Row>
 | 
			
		||||
      <Row>
 | 
			
		||||
        <Col span={24}>
 | 
			
		||||
          <Select
 | 
			
		||||
            placeholder={"Select Sub Category"}
 | 
			
		||||
            allowClear={true}
 | 
			
		||||
            onChange={(val) => {
 | 
			
		||||
              if (val) {
 | 
			
		||||
                handleChangeSubcategory(val);
 | 
			
		||||
              }
 | 
			
		||||
            }}
 | 
			
		||||
            style={{marginBottom: "10px", width: "100%"}}
 | 
			
		||||
          >
 | 
			
		||||
            {store.transaction.dataSubCategories.map((item, index) => (
 | 
			
		||||
              <Option key={item.id} value={item.id}>
 | 
			
		||||
                {item.name}
 | 
			
		||||
              </Option>
 | 
			
		||||
            ))}
 | 
			
		||||
          </Select>
 | 
			
		||||
        </Col>
 | 
			
		||||
      </Row>
 | 
			
		||||
      <Row justify={"center"} align={"center"} style={{marginBottom: "1rem"}}>
 | 
			
		||||
        <Col
 | 
			
		||||
          span={12}
 | 
			
		||||
          style={{fontWeight: "bold", display: "flex", alignItems: "center"}}
 | 
			
		||||
        >
 | 
			
		||||
          Produk & Nominal
 | 
			
		||||
        </Col>
 | 
			
		||||
        <Col span={12} style={{textAlign: "right"}}>
 | 
			
		||||
          <Search
 | 
			
		||||
            placeholder="input search text"
 | 
			
		||||
            style={{width: 200, marginRight: 10}}
 | 
			
		||||
          />
 | 
			
		||||
        </Col>
 | 
			
		||||
      </Row>
 | 
			
		||||
      {productData.length != 0 && (
 | 
			
		||||
        <Row>
 | 
			
		||||
          {productData.map((item, index) => (
 | 
			
		||||
            <Col key={index} xs={24} md={16} lg={8}>
 | 
			
		||||
              <Card
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                  Modal.confirm({
 | 
			
		||||
                    title: `Are you sure buy ${item.name}?`,
 | 
			
		||||
                    icon: <MoneyCollectOutlined/>,
 | 
			
		||||
                    okText: "Confirm",
 | 
			
		||||
                    cancelText: "Cancel",
 | 
			
		||||
                    okType: "primary",
 | 
			
		||||
                    onOk() {
 | 
			
		||||
                      handleBuyProduct(item.code)
 | 
			
		||||
                    },
 | 
			
		||||
                    onCancel() {
 | 
			
		||||
                      console.log("Cancel");
 | 
			
		||||
                    },
 | 
			
		||||
                  });
 | 
			
		||||
                }}
 | 
			
		||||
                style={{cursor: "pointer"}}
 | 
			
		||||
              >
 | 
			
		||||
                <span style={{color: "black"}}>{item.name}</span>
 | 
			
		||||
                <br/>
 | 
			
		||||
                <span style={{color: "grey", fontSize: 10}}>
 | 
			
		||||
                  {new Intl.NumberFormat("id-ID", {
 | 
			
		||||
                      style: "currency",
 | 
			
		||||
                      currency: "IDR",
 | 
			
		||||
                    style: "currency",
 | 
			
		||||
                    currency: "IDR",
 | 
			
		||||
                  }).format(item?.currentPrice?.mark_up_price)}
 | 
			
		||||
                </span>
 | 
			
		||||
                            </Card>
 | 
			
		||||
                        </Col>
 | 
			
		||||
                    ))}
 | 
			
		||||
              </Card>
 | 
			
		||||
            </Col>
 | 
			
		||||
          ))}
 | 
			
		||||
        </Row>
 | 
			
		||||
      )}
 | 
			
		||||
      {productData.length !== 0 && (
 | 
			
		||||
        <Col style={{ textAlign: "right" }}>
 | 
			
		||||
        <Col style={{textAlign: "right"}}>
 | 
			
		||||
          <Button style={{backgroundColor: "#2D9CDB", color: "white"}}>
 | 
			
		||||
            Beli Sekarang
 | 
			
		||||
          </Button>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,28 @@
 | 
			
		||||
import React, {useEffect, useState} from "react";
 | 
			
		||||
import React, {useContext, useEffect, useState} from "react";
 | 
			
		||||
import {useStore} from "../../utils/useStore";
 | 
			
		||||
import {Card, Tabs} from "antd";
 | 
			
		||||
import {BreadcumbComponent} from "../../component/BreadcumbComponent";
 | 
			
		||||
import {Product} from "./Product";
 | 
			
		||||
import {LINKS} from "../../routes/app";
 | 
			
		||||
import {observer} from "mobx-react-lite";
 | 
			
		||||
import {ModalLoaderContext} from "../../utils/modal";
 | 
			
		||||
 | 
			
		||||
const {TabPane} = Tabs;
 | 
			
		||||
 | 
			
		||||
export const Transaction = observer(() => {
 | 
			
		||||
  const store = useStore();
 | 
			
		||||
 | 
			
		||||
  const [isLoading, setIsLoading] = useState(false);
 | 
			
		||||
  const modalLoader = useContext(ModalLoaderContext);
 | 
			
		||||
 | 
			
		||||
  // Init
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const init = async () => {
 | 
			
		||||
      try {
 | 
			
		||||
        setIsLoading(true);
 | 
			
		||||
        modalLoader.setLoading(true);
 | 
			
		||||
        await store.transaction.getDataCategories();
 | 
			
		||||
        setIsLoading(false);
 | 
			
		||||
        modalLoader.setLoading(false);
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        setIsLoading(false);
 | 
			
		||||
        modalLoader.setLoading(false);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +36,9 @@ export const Transaction = observer(() => {
 | 
			
		||||
 | 
			
		||||
  const handleChangeTabs = async (key) => {
 | 
			
		||||
    store.transaction.filterCategory = key;
 | 
			
		||||
    modalLoader.setLoading(true);
 | 
			
		||||
    await store.transaction.getDataSubCategories();
 | 
			
		||||
    modalLoader.setLoading(false);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const routeData = [
 | 
			
		||||
@@ -50,22 +53,22 @@ export const Transaction = observer(() => {
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
      <div className={["ppob-container"].join(" ")}>
 | 
			
		||||
        <BreadcumbComponent data={routeData} text=""/>
 | 
			
		||||
        <Card>
 | 
			
		||||
          <Tabs
 | 
			
		||||
              onChange={handleChangeTabs}
 | 
			
		||||
              size="default"
 | 
			
		||||
              tabBarGutter="50"
 | 
			
		||||
          >
 | 
			
		||||
            {store.transaction.dataCategories.map((item, index) => (
 | 
			
		||||
                <TabPane tab={item.name} key={item.id}>
 | 
			
		||||
                  <Product/>
 | 
			
		||||
                </TabPane>
 | 
			
		||||
            ))}
 | 
			
		||||
    <div className={["ppob-container"].join(" ")}>
 | 
			
		||||
      <BreadcumbComponent data={routeData} text=""/>
 | 
			
		||||
      <Card>
 | 
			
		||||
        <Tabs
 | 
			
		||||
          onChange={handleChangeTabs}
 | 
			
		||||
          size="default"
 | 
			
		||||
          tabBarGutter="50"
 | 
			
		||||
        >
 | 
			
		||||
          {store.transaction.dataCategories.map((item, index) => (
 | 
			
		||||
            <TabPane tab={item.name} key={item.id}>
 | 
			
		||||
              <Product/>
 | 
			
		||||
            </TabPane>
 | 
			
		||||
          ))}
 | 
			
		||||
 | 
			
		||||
          </Tabs>
 | 
			
		||||
        </Card>
 | 
			
		||||
      </div>
 | 
			
		||||
        </Tabs>
 | 
			
		||||
      </Card>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user