|
- "use client";
- import { ProjectExpensesResult, ProjectExpensesResultFormatted } from "@/app/api/projectExpenses";
- import { useCallback, useEffect, useMemo, useState } from "react";
- import { useTranslation } from "react-i18next";
- import SearchBox, { Criterion } from "../SearchBox";
- import SearchResults, { Column } from "../SearchResults";
- import { useRouter } from "next/navigation";
- import {
- Button,
- ButtonGroup,
- Card,
- CardContent,
- Divider,
- Grid,
- Stack,
- Typography,
- } from "@mui/material";
- import { moneyFormatter } from "@/app/utils/formatUtil";
- import { EditNote } from "@mui/icons-material";
- import AddIcon from '@mui/icons-material/Add';
- import { uniq } from "lodash";
- import CreateExpenseModal from "./CreateExpenseModal";
- import { ProjectResult } from "@/app/api/projects";
-
- interface Props {
- expenses: ProjectExpensesResultFormatted[]
- projects: ProjectResult[];
- }
-
- type SearchQuery = Partial<Omit<ProjectExpensesResultFormatted, "id">>;
- type SearchParamNames = keyof SearchQuery;
-
- type Modals = {
- createInvoiceModal: boolean
- }
- const initState: Modals = {
- createInvoiceModal: false,
- }
-
- const ExpenseSearch: React.FC<Props> = ({ expenses, projects }) => {
- const router = useRouter();
- const { t } = useTranslation("expenses");
- const [filteredExpenses, setFilteredExpenses] = useState(expenses);
- const [modalsOpen, setModalsOpen] = useState(initState)
- const toggleModals = useCallback((key: keyof Modals) => {
- setModalsOpen((prev) => ({...prev, [key]: !prev[key]}))
- }, [modalsOpen]);
-
- const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
- () => [
- // { label: t("Expense No"), paramName: "ExpenseNo", type: "text" },
- { label: t("Project Code"), paramName: "projectCode", type: "text" },
- { label: t("Project Name"), paramName: "projectName", type: "text" },
- // {
- // label: t("Team"),
- // paramName: "team",
- // type: "select",
- // options: uniq(expenses.map((expenses) => expenses.teamCode)),
- // },
- ],
- []
- );
-
- const onExpenseClick = useCallback(
- (expenses?: ProjectExpensesResultFormatted) => {},
- [router]
- );
-
- const columns = useMemo<Column<ProjectExpensesResultFormatted>[]>(
- () => [
- {
- name: "id",
- label: t("Details"),
- onClick: onExpenseClick,
- buttonIcon: <EditNote />,
- // disabled: !abilities.includes(MAINTAIN_PROJECT),
- },
- { name: "projectCode", label: t("Project Code") },
- { name: "projectName", label: t("Project Name") },
- { name: "amount", label: t("Amount") },
- { name: "teamCode", label: t("Team") },
- { name: "issueDate", label: t("Issue Date") },
- ],
- [t, onExpenseClick]
- );
- const onReset = useCallback(() => {
- // setFilteredExpenses();
- }, []);
-
- return (
- <>
- <Stack
- spacing={2}
- >
- <Stack
- direction="row"
- justifyContent="right"
- flexWrap="wrap"
- spacing={2}
- >
- <Grid xs={12} justifyContent="right">
- <ButtonGroup variant="contained">
- <Button
- startIcon={<AddIcon />}
- variant="outlined"
- component="label"
- onClick={() => toggleModals("createInvoiceModal")}
- >
- {t("Create expense")}
- </Button>
- </ButtonGroup>
- </Grid>
- </Stack>
- <SearchBox
- criteria={searchCriteria}
- onSearch={(query) => {
- // setFilteredExpenses(
- // projects.filter(
- // (p) =>
- // p.code.toLowerCase().includes(query.code.toLowerCase()) &&
- // p.name.toLowerCase().includes(query.name.toLowerCase()) &&
- // (query.client === "All" || p.client === query.client) &&
- // (query.category === "All" || p.category === query.category) &&
- // // (query.team === "All" || p.team === query.team) &&
- // (query.team === "All" || query.team.toLowerCase().includes(p.team.toLowerCase())) &&
- // (query.status === "All" || p.status === query.status),
- // ),
- // );
- }}
- onReset={onReset}
- />
- <Divider sx={{ paddingBlockStart: 2 }} />
- <Card sx={{ display: "block" }}>
- <CardContent>
- <Stack direction="row" justifyContent="space-between">
- <Typography variant="h6">
- {t("Total Issued Amount (HKD)")}:
- </Typography>
- <Typography variant="h6">
- {/* {moneyFormatter.format(filteredExpenses.reduce((acc, curr) => (acc + curr.issuedAmount), 0))} */}
- </Typography>
- </Stack>
- <Stack direction="row" justifyContent="space-between">
- <Typography variant="h6">
- {t("Total Received Amount (HKD)")}:
- </Typography>
- <Typography variant="h6">
- {/* {moneyFormatter.format(filteredExpenses.reduce((acc, curr) => (acc + curr.receivedAmount), 0))} */}
- </Typography>
- </Stack>
- </CardContent>
- </Card>
- <Divider sx={{ paddingBlockEnd: 2 }} />
- <SearchResults<ProjectExpensesResultFormatted>
- items={filteredExpenses}
- columns={columns}
- />
- </Stack>
- <CreateExpenseModal
- isOpen={modalsOpen.createInvoiceModal}
- onClose={() => toggleModals("createInvoiceModal")}
- projects={projects}
- />
- </>
- );
- };
- export default ExpenseSearch;
|