From 0febf9b149fbd05bafb67aaed8fffe36e346dcab Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Tue, 18 Feb 2025 10:07:12 +0000 Subject: [PATCH] Feature/amiriis damage items --- .../dashboard/receipt/damages/page.js | 13 ++ .../Actions/Create/Form/CreateFormContent.jsx | 145 ++++++++++++++++++ .../damages/Actions/Create/Form/index.jsx | 11 ++ .../receipt/damages/Actions/Create/index.jsx | 36 +++++ .../dashboard/receipt/damages/DamagesList.jsx | 84 ++++++++++ .../damages/RowActions/Activity/index.jsx | 31 ++++ .../damages/RowActions/Edit/Form/index.jsx | 145 ++++++++++++++++++ .../receipt/damages/RowActions/Edit/index.jsx | 30 ++++ .../receipt/damages/RowActions/index.jsx | 13 ++ .../dashboard/receipt/damages/Toolbar.jsx | 10 ++ .../dashboard/receipt/damages/index.jsx | 13 ++ .../operator/Actions/Create/Forms/index.jsx | 2 +- .../RowActions/DeleteForm/index.jsx | 5 +- src/core/utils/pageMenu.js | 8 + src/core/utils/routes.js | 6 + 15 files changed, 548 insertions(+), 4 deletions(-) create mode 100644 src/app/(withAuth)/dashboard/receipt/damages/page.js create mode 100644 src/components/dashboard/receipt/damages/Actions/Create/Form/CreateFormContent.jsx create mode 100644 src/components/dashboard/receipt/damages/Actions/Create/Form/index.jsx create mode 100644 src/components/dashboard/receipt/damages/Actions/Create/index.jsx create mode 100644 src/components/dashboard/receipt/damages/DamagesList.jsx create mode 100644 src/components/dashboard/receipt/damages/RowActions/Activity/index.jsx create mode 100644 src/components/dashboard/receipt/damages/RowActions/Edit/Form/index.jsx create mode 100644 src/components/dashboard/receipt/damages/RowActions/Edit/index.jsx create mode 100644 src/components/dashboard/receipt/damages/RowActions/index.jsx create mode 100644 src/components/dashboard/receipt/damages/Toolbar.jsx create mode 100644 src/components/dashboard/receipt/damages/index.jsx diff --git a/src/app/(withAuth)/dashboard/receipt/damages/page.js b/src/app/(withAuth)/dashboard/receipt/damages/page.js new file mode 100644 index 0000000..7310363 --- /dev/null +++ b/src/app/(withAuth)/dashboard/receipt/damages/page.js @@ -0,0 +1,13 @@ +import DamagesPage from "@/components/dashboard/receipt/damages"; +import WithPermission from "@/core/middlewares/withPermission"; + +const Page = () => { + return ( + + + + ); +}; +export default Page; diff --git a/src/components/dashboard/receipt/damages/Actions/Create/Form/CreateFormContent.jsx b/src/components/dashboard/receipt/damages/Actions/Create/Form/CreateFormContent.jsx new file mode 100644 index 0000000..e3745f4 --- /dev/null +++ b/src/components/dashboard/receipt/damages/Actions/Create/Form/CreateFormContent.jsx @@ -0,0 +1,145 @@ +import NumberField from "@/core/components/NumberField"; +import StyledForm from "@/core/components/StyledForm"; +import { CREATE_RECEIPT_DAMAGE_ITEMS } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Beenhere, ExitToApp } from "@mui/icons-material"; +import { Button, DialogActions, DialogContent, DialogTitle, Stack, TextField } from "@mui/material"; +import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog"; +import { Controller, useForm } from "react-hook-form"; +import { object, string } from "yup"; + +const validationSchema = object({ + title: string().required("وارد کردن عنوان الزامیست!"), + unit: string().required("وارد کردن واحد الزامیست!"), + base_price: string().required("وارد کردن فی الزامیست!"), +}); + +const CreateFormContent = ({ setOpen, mutate }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const defaultValues = { + title: "", + unit: "", + base_price: null, + }; + + const { + control, + handleSubmit, + formState: { isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + + const onSubmit = async (data) => { + const formData = new FormData(); + formData.append("title", data.title); + formData.append("unit", data.unit); + formData.append("base_price", data.base_price); + + try { + await requestServer(CREATE_RECEIPT_DAMAGE_ITEMS, "post", { + data: formData, + }); + mutate(); + setOpen(false); + } catch (error) {} + }; + + return ( + <> + + ثبت آیتم جدید + + + + + ( + + )} + /> + ( + + )} + /> + ( + { + if (!isNaN(event.target.value)) { + onChange(event.target.value); + } else { + onChange(value); + } + }} + helperText={error ? error.message : null} + variant="outlined" + fullWidth + /> + )} + /> + + + + + + + + + ); +}; +export default CreateFormContent; diff --git a/src/components/dashboard/receipt/damages/Actions/Create/Form/index.jsx b/src/components/dashboard/receipt/damages/Actions/Create/Form/index.jsx new file mode 100644 index 0000000..91aa0fb --- /dev/null +++ b/src/components/dashboard/receipt/damages/Actions/Create/Form/index.jsx @@ -0,0 +1,11 @@ +import { Dialog } from "@mui/material"; +import CreateFormContent from "./CreateFormContent"; + +const CreateForm = ({ open, setOpen, mutate }) => { + return ( + + {open && } + + ); +}; +export default CreateForm; diff --git a/src/components/dashboard/receipt/damages/Actions/Create/index.jsx b/src/components/dashboard/receipt/damages/Actions/Create/index.jsx new file mode 100644 index 0000000..a720b22 --- /dev/null +++ b/src/components/dashboard/receipt/damages/Actions/Create/index.jsx @@ -0,0 +1,36 @@ +import { AddCircle } from "@mui/icons-material"; +import { Button, IconButton, useMediaQuery, useTheme } from "@mui/material"; +import CreateForm from "./Form"; +import { useState } from "react"; + +const CreateDamage = ({ mutate }) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + return ( + <> + {isMobile ? ( + + + + ) : ( + + )} + + + ); +}; +export default CreateDamage; diff --git a/src/components/dashboard/receipt/damages/DamagesList.jsx b/src/components/dashboard/receipt/damages/DamagesList.jsx new file mode 100644 index 0000000..e93d216 --- /dev/null +++ b/src/components/dashboard/receipt/damages/DamagesList.jsx @@ -0,0 +1,84 @@ +"use client"; +import DataTableWithAuth from "@/core/components/DataTableWithAuth"; +import { GET_RECEIPT_DAMAGE_ITEMS_LIST } from "@/core/utils/routes"; +import { Box } from "@mui/material"; +import { useMemo } from "react"; +import Toolbar from "./Toolbar"; +import RowActions from "./RowActions"; + +const DamagesList = () => { + const columns = useMemo( + () => [ + { + accessorKey: "id", + header: "کد یکتا", + id: "id", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + sortDescFirst: false, + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "title", + header: "عنوان", + id: "title", + enableColumnFilter: true, + datatype: "text", + filterMode: "equals", + columnFilterModeOptions: ["equals", "contains"], + grow: false, + size: 100, + }, + { + accessorKey: "unit", + header: "واحد", + id: "unit", + enableColumnFilter: false, + grow: false, + size: 100, + }, + { + accessorKey: "base_price", + header: "فی (ریال)", + id: "base_price", + enableColumnFilter: false, + grow: false, + size: 100, + Cell: ({ renderedCellValue }) => (renderedCellValue / 1).toLocaleString(), + }, + { + accessorKey: "status", + header: "وضعیت", + id: "status", + enableColumnFilter: false, + grow: false, + size: 100, + Cell: ({ renderedCellValue }) => (renderedCellValue == 1 ? "فعال" : "غیرفعال"), + }, + ], + [] + ); + + return ( + <> + + + + + ); +}; +export default DamagesList; diff --git a/src/components/dashboard/receipt/damages/RowActions/Activity/index.jsx b/src/components/dashboard/receipt/damages/RowActions/Activity/index.jsx new file mode 100644 index 0000000..4f64584 --- /dev/null +++ b/src/components/dashboard/receipt/damages/RowActions/Activity/index.jsx @@ -0,0 +1,31 @@ +import { ATIVITY_RECEIPT_DAMAGE_ITEMS } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { Switch } from "@mui/material"; +import { useState } from "react"; + +const Activity = ({ rowId, mutate, status }) => { + const [disabled, setDisabled] = useState(false) + const [checked, setChecked] = useState(status == 1); + const requestServer = useRequest(); + + const handleSwitch = (event) => { + const newChecked = event.target.checked; + setChecked(newChecked); + setDisabled(true) + + requestServer(`${ATIVITY_RECEIPT_DAMAGE_ITEMS}/${rowId}`, "post") + .then(() => { + mutate(); + }) + .catch(() => { + setChecked(!newChecked); + }) + .finally(() => { + setDisabled(false) + }) + }; + + return ; +}; + +export default Activity; diff --git a/src/components/dashboard/receipt/damages/RowActions/Edit/Form/index.jsx b/src/components/dashboard/receipt/damages/RowActions/Edit/Form/index.jsx new file mode 100644 index 0000000..30965fe --- /dev/null +++ b/src/components/dashboard/receipt/damages/RowActions/Edit/Form/index.jsx @@ -0,0 +1,145 @@ +import NumberField from "@/core/components/NumberField"; +import StyledForm from "@/core/components/StyledForm"; +import { UPDATE_RECEIPT_DAMAGE_ITEMS } from "@/core/utils/routes"; +import useRequest from "@/lib/hooks/useRequest"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Beenhere, ExitToApp } from "@mui/icons-material"; +import { Button, DialogActions, DialogContent, DialogTitle, Stack, TextField } from "@mui/material"; +import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog"; +import { Controller, useForm } from "react-hook-form"; +import { object, string } from "yup"; + +const validationSchema = object({ + title: string().required("وارد کردن عنوان الزامیست!"), + unit: string().required("وارد کردن واحد الزامیست!"), + base_price: string().required("وارد کردن فی الزامیست!"), +}); + +const EditFormContent = ({ row, rowId, mutate, setOpen }) => { + const requestServer = useRequest({ notificationSuccess: true }); + const defaultValues = { + title: row.original.title, + unit: row.original.unit, + base_price: row.original.base_price, + }; + + const { + control, + handleSubmit, + formState: { isSubmitting }, + } = useForm({ + defaultValues, + resolver: yupResolver(validationSchema), + mode: "onBlur", + }); + + const onSubmit = async (data) => { + const formData = new FormData(); + formData.append("title", data.title); + formData.append("unit", data.unit); + formData.append("base_price", data.base_price); + + try { + await requestServer(`${UPDATE_RECEIPT_DAMAGE_ITEMS}/${rowId}`, "post", { + data: formData, + }); + mutate(); + setOpen(false); + } catch (error) {} + }; + + return ( + <> + + ویرایش آیتم + + + + + ( + + )} + /> + ( + + )} + /> + ( + { + if (!isNaN(event.target.value)) { + onChange(event.target.value); + } else { + onChange(value); + } + }} + helperText={error ? error.message : null} + variant="outlined" + fullWidth + /> + )} + /> + + + + + + + + + ); +}; +export default EditFormContent; diff --git a/src/components/dashboard/receipt/damages/RowActions/Edit/index.jsx b/src/components/dashboard/receipt/damages/RowActions/Edit/index.jsx new file mode 100644 index 0000000..5fad290 --- /dev/null +++ b/src/components/dashboard/receipt/damages/RowActions/Edit/index.jsx @@ -0,0 +1,30 @@ +import BorderColorIcon from "@mui/icons-material/BorderColor"; +import { Dialog, IconButton, Tooltip } from "@mui/material"; +import EditFormContent from "./Form"; +import { useState } from "react"; + +const Edit = ({ row, mutate, rowId }) => { + const [openEditDialog, setOpenEditDialog] = useState(false); + + return ( + <> + + { + setOpenEditDialog(true); + }} + > + + + + + {openEditDialog && ( + + )} + + + ); +}; +export default Edit; diff --git a/src/components/dashboard/receipt/damages/RowActions/index.jsx b/src/components/dashboard/receipt/damages/RowActions/index.jsx new file mode 100644 index 0000000..18aa6ea --- /dev/null +++ b/src/components/dashboard/receipt/damages/RowActions/index.jsx @@ -0,0 +1,13 @@ +import { Box } from "@mui/material"; +import Activity from "./Activity"; +import Edit from "./Edit"; + +const RowActions = ({ row, mutate }) => { + return ( + + + + + ); +}; +export default RowActions; diff --git a/src/components/dashboard/receipt/damages/Toolbar.jsx b/src/components/dashboard/receipt/damages/Toolbar.jsx new file mode 100644 index 0000000..b639318 --- /dev/null +++ b/src/components/dashboard/receipt/damages/Toolbar.jsx @@ -0,0 +1,10 @@ +import CreateDamage from "./Actions/Create"; + +const Toolbar = ({ mutate }) => { + return ( + <> + + + ); +}; +export default Toolbar; diff --git a/src/components/dashboard/receipt/damages/index.jsx b/src/components/dashboard/receipt/damages/index.jsx new file mode 100644 index 0000000..ac37d7d --- /dev/null +++ b/src/components/dashboard/receipt/damages/index.jsx @@ -0,0 +1,13 @@ +import PageTitle from "@/core/components/PageTitle"; +import { Stack } from "@mui/material"; +import DamagesList from "./DamagesList"; + +const DamagesPage = () => { + return ( + + + + + ); +}; +export default DamagesPage; diff --git a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx index c9921bf..0a215b5 100644 --- a/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx +++ b/src/components/dashboard/roadItems/operator/Actions/Create/Forms/index.jsx @@ -4,7 +4,7 @@ import CreateFormContent from "@/components/dashboard/roadItems/operator/Actions import { CREATE_ROAD_ITEMS } from "@/core/utils/routes"; import useRequest from "@/lib/hooks/useRequest"; -const OperatorCreateForm = ({ open, setOpen, mutate, rowId }) => { +const OperatorCreateForm = ({ open, setOpen, mutate }) => { const requestServer = useRequest({ notificationSuccess: true }); const HandleSubmit = async ({ result }) => { const formData = new FormData(); diff --git a/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/index.jsx b/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/index.jsx index c8c8375..596cf9a 100644 --- a/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/index.jsx +++ b/src/components/dashboard/roadItems/supervisor/RowActions/DeleteForm/index.jsx @@ -1,8 +1,7 @@ -import React, { useState } from "react"; -import { Tooltip, IconButton, Dialog, DialogTitle } from "@mui/material"; import DeleteIcon from "@mui/icons-material/Delete"; +import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material"; +import { useState } from "react"; import DeleteContent from "./DeleteContent"; -import useRequest from "@/lib/hooks/useRequest"; const DeleteForm = ({ rowId, mutate }) => { const [openDeleteDialog, setOpenDeleteDialog] = useState(false); diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index fa593bb..6a778b3 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -473,6 +473,14 @@ export const pageMenu = [ }, ], }, + { + id: "damageItems", + label: "آیتم خسارات", + type: "page", + route: "/dashboard/receipt/damages", + icon: , + permissions: ["manage-damage"], + }, { id: "receiptManagmentReport", label: "گزارش ها", diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 94ce0d9..42e2f87 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -76,5 +76,11 @@ export const GET_CITY_ACTIVITY_PER_ITEM = api + "/api/v3/road_item_reports/provi export const GET_PROVINCE_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/country_activity_per_sub_item"; export const GET_CITY_ACTIVITY_PER_SUB_ITEM = api + "/api/v3/road_item_reports/province_activity_per_sub_item"; +// damage items +export const GET_RECEIPT_DAMAGE_ITEMS_LIST = api + "/api/v3/damages"; +export const CREATE_RECEIPT_DAMAGE_ITEMS = api + "/api/v3/damages"; +export const UPDATE_RECEIPT_DAMAGE_ITEMS = api + "/api/v3/damages"; +export const ATIVITY_RECEIPT_DAMAGE_ITEMS = api + "/api/v3/damages/activate"; + // activity code log export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity";