Feature/amiriis missions

This commit is contained in:
AmirHossein Mahmoodi
2025-06-25 07:41:03 +00:00
parent 9ae5b8934c
commit 12d6d08bef
734 changed files with 48930 additions and 46048 deletions

View File

@@ -1,18 +1,18 @@
import AzmayeshPage from "@/components/dashboard/azmayesh";
import WithPermission from "@/core/middlewares/withPermission";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل آزمایشات",
};
const Page = () => {
return (
<WithPermission permission_name={["azmayesh-management"]}>
<AzmayeshPage />
<ActivityCodeLog activity_code={1157} />
</WithPermission>
);
};
export default Page;
import AzmayeshPage from "@/components/dashboard/azmayesh";
import WithPermission from "@/core/middlewares/withPermission";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل آزمایشات",
};
const Page = () => {
return (
<WithPermission permission_name={["azmayesh-management"]}>
<AzmayeshPage />
<ActivityCodeLog activity_code={1157} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
import AzmayeshTypePage from "@/components/dashboard/azmayeshType";
import WithPermission from "@/core/middlewares/withPermission";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل نوع آزمایشات",
};
const Page = () => {
return (
<WithPermission permission_name={["azmayesh-type-management"]}>
<AzmayeshTypePage />
<ActivityCodeLog activity_code={1161} />
</WithPermission>
);
};
export default Page;
import AzmayeshTypePage from "@/components/dashboard/azmayeshType";
import WithPermission from "@/core/middlewares/withPermission";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل نوع آزمایشات",
};
const Page = () => {
return (
<WithPermission permission_name={["azmayesh-type-management"]}>
<AzmayeshTypePage />
<ActivityCodeLog activity_code={1161} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,13 +1,13 @@
import DamagesPage from "@/components/dashboard/damageItems";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "آیتم خسارات",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-damage"]}>
<DamagesPage />
</WithPermission>
);
};
export default Page;
import DamagesPage from "@/components/dashboard/damageItems";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "آیتم خسارات",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-damage"]}>
<DamagesPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
import OperatorPage from "@/components/dashboard/damages/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل عملیات خسارات وارد بر ابنیه فنی",
};
const Page = () => {
return (
<WithPermission permission_name={["show-receipt", "show-receipt-province"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1122} />
</WithPermission>
);
};
export default Page;
import OperatorPage from "@/components/dashboard/damages/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل عملیات خسارات وارد بر ابنیه فنی",
};
const Page = () => {
return (
<WithPermission permission_name={["show-receipt", "show-receipt-province"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1122} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,13 +1,13 @@
import DamagesReportPage from "@/components/dashboard/damages/report";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل گزارش خسارات وارد بر ابنیه فنی",
};
const Page = () => {
return (
<WithPermission permission_name={["show-receipt", "show-receipt-province"]}>
<DamagesReportPage />
</WithPermission>
);
};
export default Page;
import DamagesReportPage from "@/components/dashboard/damages/report";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل گزارش خسارات وارد بر ابنیه فنی",
};
const Page = () => {
return (
<WithPermission permission_name={["show-receipt", "show-receipt-province"]}>
<DamagesReportPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,15 +1,15 @@
import OperatorPage from "@/components/dashboard/fastReact/operator";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل عملیات واکنش سریع",
};
const Page = () => {
return (
<WithPermission permission_name={["show-fast-react-edarate-shahri"]}>
<OperatorPage />
{/* <ActivityCodeLog activity_code={1137} /> */}
</WithPermission>
);
};
export default Page;
import OperatorPage from "@/components/dashboard/fastReact/operator";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل عملیات واکنش سریع",
};
const Page = () => {
return (
<WithPermission permission_name={["show-fast-react-edarate-shahri"]}>
<OperatorPage />
{/* <ActivityCodeLog activity_code={1137} /> */}
</WithPermission>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/fastReact/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی واکنش سریع",
};
const Page = () => {
return (
<WithPermission permission_name={["show-fast-react", "show-fast-react-province"]}>
<SupervisorPage />
<ActivityCodeLog activity_code={1137} />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/fastReact/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی واکنش سریع",
};
const Page = () => {
return (
<WithPermission permission_name={["show-fast-react", "show-fast-react-province"]}>
<SupervisorPage />
<ActivityCodeLog activity_code={1137} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,12 +1,12 @@
import AssistantZaminGovComponent from "@/components/dashboard/inquiryPrivacy/assistant/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<AssistantZaminGovComponent />
</WithPermission>
);
};
export default Page;
import AssistantZaminGovComponent from "@/components/dashboard/inquiryPrivacy/assistant/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<AssistantZaminGovComponent />
</WithPermission>
);
};
export default Page;

View File

@@ -1,12 +1,12 @@
import CityAdminZaminGovComponent from "@/components/dashboard/inquiryPrivacy/cityAdmin/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<CityAdminZaminGovComponent />
</WithPermission>
);
};
export default Page;
import CityAdminZaminGovComponent from "@/components/dashboard/inquiryPrivacy/cityAdmin/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<CityAdminZaminGovComponent />
</WithPermission>
);
};
export default Page;

View File

@@ -1,12 +1,12 @@
import GeneralManagerZaminGovComponent from "@/components/dashboard/inquiryPrivacy/generalManager/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<GeneralManagerZaminGovComponent />
</WithPermission>
);
};
export default Page;
import GeneralManagerZaminGovComponent from "@/components/dashboard/inquiryPrivacy/generalManager/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<GeneralManagerZaminGovComponent />
</WithPermission>
);
};
export default Page;

View File

@@ -1,12 +1,12 @@
import ProvinceAdminZaminGovComponent from "@/components/dashboard/inquiryPrivacy/provinceAdmin/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<ProvinceAdminZaminGovComponent />
</WithPermission>
);
};
export default Page;
import ProvinceAdminZaminGovComponent from "@/components/dashboard/inquiryPrivacy/provinceAdmin/zaminGov";
import WithPermission from "@/core/middlewares/withPermission";
const Page = () => {
return (
<WithPermission>
<ProvinceAdminZaminGovComponent />
</WithPermission>
);
};
export default Page;

View File

@@ -1,7 +1,7 @@
"use client";
import PageLoading from "@/core/components/PageLoading";
const Loading = () => {
return <PageLoading />;
};
export default Loading;
"use client";
import PageLoading from "@/core/components/PageLoading";
const Loading = () => {
return <PageLoading />;
};
export default Loading;

View File

@@ -1,9 +1,9 @@
export const metadata = {
title: "پیشخوان",
};
const Page = () => {
return <></>;
};
export default Page;
export const metadata = {
title: "پیشخوان",
};
const Page = () => {
return <></>;
};
export default Page;

View File

@@ -1,13 +1,13 @@
import WithPermission from "@/core/middlewares/withPermission";
import PermissionTablePage from "@/components/dashboard/permissionTable";
export const metadata = {
title: "سطح دسترسی ها",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-permissions"]}>
<PermissionTablePage />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import PermissionTablePage from "@/components/dashboard/permissionTable";
export const metadata = {
title: "سطح دسترسی ها",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-permissions"]}>
<PermissionTablePage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadItems/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات فعالیت روزانه",
};
const Page = () => {
return (
<WithPermission permission_name={["create-road-item"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1152} />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadItems/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات فعالیت روزانه",
};
const Page = () => {
return (
<WithPermission permission_name={["create-road-item"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1152} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,20 +1,20 @@
import WithPermission from "@/core/middlewares/withPermission";
import ReportPage from "@/components/dashboard/roadItems/reports/ItemsReports";
export const metadata = {
title: "کارتابل گزارش تعداد فعالیت ها به تفکیک آیتم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-road-item-supervise-cartable",
"show-road-item-supervise-cartable-province",
"create-road-item",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import ReportPage from "@/components/dashboard/roadItems/reports/ItemsReports";
export const metadata = {
title: "کارتابل گزارش تعداد فعالیت ها به تفکیک آیتم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-road-item-supervise-cartable",
"show-road-item-supervise-cartable-province",
"create-road-item",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,9 +1,9 @@
import RoadItemsReportMap from "@/components/dashboard/roadItems/reports/Map";
export const metadata = {
title: "پراکندگی بر روی نقشه فعالیت روزانه",
};
const Page = () => {
return <RoadItemsReportMap />;
};
export default Page;
import RoadItemsReportMap from "@/components/dashboard/roadItems/reports/Map";
export const metadata = {
title: "پراکندگی بر روی نقشه فعالیت روزانه",
};
const Page = () => {
return <RoadItemsReportMap />;
};
export default Page;

View File

@@ -1,20 +1,20 @@
import WithPermission from "@/core/middlewares/withPermission";
import SubItemsReports from "@/components/dashboard/roadItems/reports/SubItemsReports";
export const metadata = {
title: "کارتابل گزارش تعداد فعالیت ها به تفکیک موارد مشاهده شده",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-road-item-supervise-cartable",
"show-road-item-supervise-cartable-province",
"create-road-item",
]}
>
<SubItemsReports />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import SubItemsReports from "@/components/dashboard/roadItems/reports/SubItemsReports";
export const metadata = {
title: "کارتابل گزارش تعداد فعالیت ها به تفکیک موارد مشاهده شده",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-road-item-supervise-cartable",
"show-road-item-supervise-cartable-province",
"create-road-item",
]}
>
<SubItemsReports />
</WithPermission>
);
};
export default Page;

View File

@@ -1,18 +1,18 @@
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/roadItems/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی فعالیت روزانه",
};
const Page = () => {
return (
<WithPermission
permission_name={["show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province"]}
>
<SupervisorPage />
<ActivityCodeLog activity_code={1148} />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/roadItems/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی فعالیت روزانه",
};
const Page = () => {
return (
<WithPermission
permission_name={["show-road-item-supervise-cartable", "show-road-item-supervise-cartable-province"]}
>
<SupervisorPage />
<ActivityCodeLog activity_code={1148} />
</WithPermission>
);
};
export default Page;

View File

@@ -0,0 +1,17 @@
import ControlPage from "@/components/dashboard/roadMissions/control";
export const metadata = {
title: "کارتابل کنترل",
};
const Page = () => {
return (
<>
{/* <WithPermission permission_name={["create-road-item"]}> */}
<ControlPage />
{/* <ActivityCodeLog activity_code={1152} /> */}
{/* </WithPermission> */}
</>
);
};
export default Page;

View File

@@ -0,0 +1,18 @@
import WithPermission from "@/core/middlewares/withPermission";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
import OperatorPage from "@/components/dashboard/roadMissions/operator";
export const metadata = {
title: "کارتابل ماموریت",
};
const Page = () => {
return (
<>
{/* <WithPermission permission_name={["create-road-item"]}> */}
<OperatorPage />
{/* <ActivityCodeLog activity_code={1152} /> */}
{/* </WithPermission> */}
</>
);
};
export default Page;

View File

@@ -0,0 +1,17 @@
import TransportationPage from "@/components/dashboard/roadMissions/transportation";
export const metadata = {
title: "کارتابل نقلیه",
};
const Page = () => {
return (
<>
{/* <WithPermission permission_name={["create-road-item"]}> */}
<TransportationPage />
{/* <ActivityCodeLog activity_code={1152} /> */}
{/* </WithPermission> */}
</>
);
};
export default Page;

View File

@@ -1,17 +1,17 @@
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadPatrols/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات گشت راهداری",
};
const Page = () => {
return (
<WithPermission permission_name={["add-road-patrol"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1145} />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadPatrols/operator";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات گشت راهداری",
};
const Page = () => {
return (
<WithPermission permission_name={["add-road-patrol"]}>
<OperatorPage />
<ActivityCodeLog activity_code={1145} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,20 +1,20 @@
import WithPermission from "@/core/middlewares/withPermission";
import ReportPage from "@/components/dashboard/roadPatrols/reports";
export const metadata = {
title: "کارتابل گزارش گشت راهداری",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"add-road-patrol",
"show-road-patrol-supervise-cartable",
"show-road-patrol-supervise-cartable-province",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import ReportPage from "@/components/dashboard/roadPatrols/reports";
export const metadata = {
title: "کارتابل گزارش گشت راهداری",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"add-road-patrol",
"show-road-patrol-supervise-cartable",
"show-road-patrol-supervise-cartable-province",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,18 +1,18 @@
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/roadPatrols/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی گشت راهداری",
};
const Page = () => {
return (
<WithPermission
permission_name={["show-road-patrol-supervise-cartable", "show-road-patrol-supervise-cartable-province"]}
>
<SupervisorPage />
<ActivityCodeLog activity_code={1143} />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import SupervisorPage from "@/components/dashboard/roadPatrols/supervisor";
import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی گشت راهداری",
};
const Page = () => {
return (
<WithPermission
permission_name={["show-road-patrol-supervise-cartable", "show-road-patrol-supervise-cartable-province"]}
>
<SupervisorPage />
<ActivityCodeLog activity_code={1143} />
</WithPermission>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadSafety/operator";
// import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات نگهداری حریم",
};
const Page = () => {
return (
<WithPermission permission_name={["show-safety-and-privacy-operator-cartable-edarate-shahri"]}>
<OperatorPage />
{/*<ActivityCodeLog activity_code={1145} />*/}
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import OperatorPage from "@/components/dashboard/roadSafety/operator";
// import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل عملیات نگهداری حریم",
};
const Page = () => {
return (
<WithPermission permission_name={["show-safety-and-privacy-operator-cartable-edarate-shahri"]}>
<OperatorPage />
{/*<ActivityCodeLog activity_code={1145} />*/}
</WithPermission>
);
};
export default Page;

View File

@@ -1,9 +1,9 @@
import RoadSafetyReportMap from "@/components/dashboard/roadSafety/reports/map";
export const metadata = {
title: "پراکندگی بر روی نقشه نگهداری حریم",
};
const Page = () => {
return <RoadSafetyReportMap />;
};
export default Page;
import RoadSafetyReportMap from "@/components/dashboard/roadSafety/reports/map";
export const metadata = {
title: "پراکندگی بر روی نقشه نگهداری حریم",
};
const Page = () => {
return <RoadSafetyReportMap />;
};
export default Page;

View File

@@ -1,19 +1,19 @@
import ReportPage from "@/components/dashboard/roadSafety/reports/reportPage";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل گزارش نگهداری حریم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-safety-and-privacy-operator-cartable",
"show-safety-and-privacy-operator-cartable-province",
"show-safety-and-privacy-operator-cartable-edarate-shahri",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;
import ReportPage from "@/components/dashboard/roadSafety/reports/reportPage";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "کارتابل گزارش نگهداری حریم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-safety-and-privacy-operator-cartable",
"show-safety-and-privacy-operator-cartable-province",
"show-safety-and-privacy-operator-cartable-edarate-shahri",
]}
>
<ReportPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,21 +1,21 @@
import SupervisorPage from "@/components/dashboard/roadSafety/supervisor";
import WithPermission from "@/core/middlewares/withPermission";
// import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی نگهداری حریم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-safety-and-privacy-operator-cartable",
"show-safety-and-privacy-operator-cartable-province",
]}
>
<SupervisorPage />
{/*<ActivityCodeLog activity_code={1145} />*/}
</WithPermission>
);
};
export default Page;
import SupervisorPage from "@/components/dashboard/roadSafety/supervisor";
import WithPermission from "@/core/middlewares/withPermission";
// import ActivityCodeLog from "@/core/components/ActivityCodeLog";
export const metadata = {
title: "کارتابل ارزیابی نگهداری حریم",
};
const Page = () => {
return (
<WithPermission
permission_name={[
"show-safety-and-privacy-operator-cartable",
"show-safety-and-privacy-operator-cartable-province",
]}
>
<SupervisorPage />
{/*<ActivityCodeLog activity_code={1145} />*/}
</WithPermission>
);
};
export default Page;

View File

@@ -1,13 +1,13 @@
import UserActivitiesPage from "@/components/dashboard/userActivities";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "انواع فعالیت کاربران",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-log-list"]}>
<UserActivitiesPage />
</WithPermission>
);
};
export default Page;
import UserActivitiesPage from "@/components/dashboard/userActivities";
import WithPermission from "@/core/middlewares/withPermission";
export const metadata = {
title: "انواع فعالیت کاربران",
};
const Page = () => {
return (
<WithPermission permission_name={["manage-log-list"]}>
<UserActivitiesPage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,7 +1,7 @@
"use client";
import PageLoading from "@/core/components/PageLoading";
const Loading = () => {
return <PageLoading />;
};
export default Loading;
"use client";
import PageLoading from "@/core/components/PageLoading";
const Loading = () => {
return <PageLoading />;
};
export default Loading;

View File

@@ -1,16 +1,16 @@
import WithPermission from "@/core/middlewares/withPermission";
import TollHousePage from "@/components/infrastructure/tollHouse";
export const metadata = {
title: "لیست راهدارخانه ها",
};
const Page = () => {
return (
<WithPermission permission_name={["show-tollhouse", "show-tollhouse-province"]}>
<TollHousePage />
</WithPermission>
);
};
export default Page;
import WithPermission from "@/core/middlewares/withPermission";
import TollHousePage from "@/components/infrastructure/tollHouse";
export const metadata = {
title: "لیست راهدارخانه ها",
};
const Page = () => {
return (
<WithPermission permission_name={["show-tollhouse", "show-tollhouse-province"]}>
<TollHousePage />
</WithPermission>
);
};
export default Page;

View File

@@ -1,17 +1,17 @@
"use client";
import HeaderWithLogo from "@/components/layouts/dashboard/headerWithLogo";
import HeaderWithSidebar from "@/components/layouts/dashboard/headerWithSidebar";
import { Stack } from "@mui/material";
import { SWRConfig } from "swr";
const Layout = ({ children }) => {
return (
<SWRConfig value={{ provider: () => new Map() }}>
<Stack sx={{ width: "100%", height: "100%" }}>
<HeaderWithLogo />
<HeaderWithSidebar>{children}</HeaderWithSidebar>
</Stack>
</SWRConfig>
);
};
export default Layout;
"use client";
import HeaderWithLogo from "@/components/layouts/dashboard/headerWithLogo";
import HeaderWithSidebar from "@/components/layouts/dashboard/headerWithSidebar";
import { Stack } from "@mui/material";
import { SWRConfig } from "swr";
const Layout = ({ children }) => {
return (
<SWRConfig value={{ provider: () => new Map() }}>
<Stack sx={{ width: "100%", height: "100%" }}>
<HeaderWithLogo />
<HeaderWithSidebar>{children}</HeaderWithSidebar>
</Stack>
</SWRConfig>
);
};
export default Layout;

View File

@@ -1,31 +1,31 @@
"use client";
import { useAuth } from "@/lib/contexts/auth";
import { Typography, Stack } from "@mui/material";
import WithAuthMiddleware from "@/core/middlewares/withAuth";
import LoadingHardPage from "@/core/components/LoadingHardPage";
const Layout = ({ children }) => {
const { isAuth, initAuthState, errorState } = useAuth();
if (!initAuthState && !isAuth)
return (
<LoadingHardPage
authState={errorState.status}
label={
errorState.status ? (
<Stack justifyContent={"center"} alignItems={"center"}>
<Typography variant={"body1"}>{errorState.message}</Typography>
<Typography variant={"body1"}> کد : {errorState.status}</Typography>
</Stack>
) : (
<Typography variant={"body1"}>درحال احراز هویت...</Typography>
)
}
loading={true}
/>
);
return <WithAuthMiddleware>{children}</WithAuthMiddleware>;
};
export default Layout;
"use client";
import { useAuth } from "@/lib/contexts/auth";
import { Typography, Stack } from "@mui/material";
import WithAuthMiddleware from "@/core/middlewares/withAuth";
import LoadingHardPage from "@/core/components/LoadingHardPage";
const Layout = ({ children }) => {
const { isAuth, initAuthState, errorState } = useAuth();
if (!initAuthState && !isAuth)
return (
<LoadingHardPage
authState={errorState.status}
label={
errorState.status ? (
<Stack justifyContent={"center"} alignItems={"center"}>
<Typography variant={"body1"}>{errorState.message}</Typography>
<Typography variant={"body1"}> کد : {errorState.status}</Typography>
</Stack>
) : (
<Typography variant={"body1"}>درحال احراز هویت...</Typography>
)
}
loading={true}
/>
);
return <WithAuthMiddleware>{children}</WithAuthMiddleware>;
};
export default Layout;

View File

@@ -1,18 +1,18 @@
const data = [
{
id: 1,
name: "تهران",
},
{
id: 2,
name: "ری",
},
{
id: 3,
name: "اندیشه",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
name: "تهران",
},
{
id: 2,
name: "ری",
},
{
id: 3,
name: "اندیشه",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,41 +1,41 @@
const data = [
{
id: 1,
aplication_number: 1,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 2,
aplication_number: 2,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 3,
aplication_number: 3,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 4,
aplication_number: 4,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 5,
aplication_number: 5,
application_date: "1",
province: "tehran",
city: "tehran",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
aplication_number: 1,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 2,
aplication_number: 2,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 3,
aplication_number: 3,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 4,
aplication_number: 4,
application_date: "1",
province: "tehran",
city: "tehran",
},
{
id: 5,
aplication_number: 5,
application_date: "1",
province: "tehran",
city: "tehran",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,9 +1,9 @@
export async function GET() {
return Response.json({
message:
"به موجب این نامه، به استحضار جنابعالی می رساند، این‌ جانب ……… از تاریخ ……… افتخار همکاری\n" +
"با مجموعه ……… را دارم. اما متاسفانه، به علت ………، تقاضای استعفای خود را از تاریخ ………\n" +
"اعلام میدارم. ضمن تشکر پیشاپیش از همکاری شما خواهشمند است، دستور اقدامات لازم در این\n" +
"زمینه را صادر فرمایید.",
});
}
export async function GET() {
return Response.json({
message:
"به موجب این نامه، به استحضار جنابعالی می رساند، این‌ جانب ……… از تاریخ ……… افتخار همکاری\n" +
"با مجموعه ……… را دارم. اما متاسفانه، به علت ………، تقاضای استعفای خود را از تاریخ ………\n" +
"اعلام میدارم. ضمن تشکر پیشاپیش از همکاری شما خواهشمند است، دستور اقدامات لازم در این\n" +
"زمینه را صادر فرمایید.",
});
}

View File

@@ -1,18 +1,18 @@
const data = [
{
id: 1,
name: "تهران",
},
{
id: 2,
name: "مشهد",
},
{
id: 3,
name: "اصفهان",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
name: "تهران",
},
{
id: 2,
name: "مشهد",
},
{
id: 3,
name: "اصفهان",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,84 +1,84 @@
const data = [
{
id: 1,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
},
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 1,
person_id: [0, 1, 2],
description: "بررسی شد", // Replace with actual description
},
{
id: 2,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
},
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 2, // Replace with actual status
car_id: 10,
person_id: [10, 11, 12],
description: "بررسی شد", // Replace with actual description
},
{
id: 3,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 11,
person_id: [20, 15, 29],
description: "بررسی شد", // Replace with actual description
},
{
id: 4,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 1, // Replace with actual status
car_id: 26,
person_id: [78, 18, 56],
description: "بررسی شد", // Replace with actual description
},
];
export async function GET() {
return new Response(JSON.stringify({ data }), {
headers: { "Content-Type": "application/json" },
});
}
const data = [
{
id: 1,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
},
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 1,
person_id: [0, 1, 2],
description: "بررسی شد", // Replace with actual description
},
{
id: 2,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
},
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 2, // Replace with actual status
car_id: 10,
person_id: [10, 11, 12],
description: "بررسی شد", // Replace with actual description
},
{
id: 3,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 11,
person_id: [20, 15, 29],
description: "بررسی شد", // Replace with actual description
},
{
id: 4,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 1, // Replace with actual status
car_id: 26,
person_id: [78, 18, 56],
description: "بررسی شد", // Replace with actual description
},
];
export async function GET() {
return new Response(JSON.stringify({ data }), {
headers: { "Content-Type": "application/json" },
});
}

View File

@@ -1,84 +1,84 @@
const data = [
{
id: 1,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 1,
person_id: [0, 1, 2],
description: "بررسی شد", // Replace with actual description
},
{
id: 2,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 2, // Replace with actual status
car_id: 10,
person_id: [10, 11, 12],
description: "بررسی شد", // Replace with actual description
},
{
id: 3,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 11,
person_id: [20, 15, 29],
description: "بررسی شد", // Replace with actual description
},
{
id: 4,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 1, // Replace with actual status
car_id: 26,
person_id: [78, 18, 56],
description: "بررسی شد", // Replace with actual description
},
];
export async function GET() {
return new Response(JSON.stringify({ data }), {
headers: { "Content-Type": "application/json" },
});
}
const data = [
{
id: 1,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 1,
person_id: [0, 1, 2],
description: "بررسی شد", // Replace with actual description
},
{
id: 2,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 2, // Replace with actual status
car_id: 10,
person_id: [10, 11, 12],
description: "بررسی شد", // Replace with actual description
},
{
id: 3,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 0, // Replace with actual status
car_id: 11,
person_id: [20, 15, 29],
description: "بررسی شد", // Replace with actual description
},
{
id: 4,
province: "تهران",
office: "اداره کل",
action_item: "بررسی خودرو", // Replace with the correct label
observed_subject: "تنظیم سطح بستر حریم", // Replace with the correct label
value: "1 کیلومتر", // Replace with actual value
images: {
before: "https://cdn-icons-png.flaticon.com/512/783/783154.png",
after: "https://cdn-icons-png.flaticon.com/512/1651/1651833.png",
}, // Add URLs to images if needed
location: [{ lat: 35.6892, lng: 51.389 }], // Add URLs to images if needed
register_date: "2024-11-03T11:01:14.000000Z",
start_date: "2024-11-02T11:48:22.000000Z",
status: 1, // Replace with actual status
car_id: 26,
person_id: [78, 18, 56],
description: "بررسی شد", // Replace with actual description
},
];
export async function GET() {
return new Response(JSON.stringify({ data }), {
headers: { "Content-Type": "application/json" },
});
}

View File

@@ -1,24 +1,24 @@
const data = [
{
id: 1,
operator_name: "امین",
phone_number: "09134849737",
car_id: "33",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
{
id: 2,
operator_name: "امیر",
phone_number: "09134844955",
car_id: "233",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
operator_name: "امین",
phone_number: "09134849737",
car_id: "33",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
{
id: 2,
operator_name: "امیر",
phone_number: "09134844955",
car_id: "233",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,28 +1,28 @@
const data = [
{
id: 1,
operator_name: "امین",
phone_number: "09134849737",
province: "تهران",
office: "اداره کل",
car_id: "33",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
{
id: 2,
operator_name: "امیر",
phone_number: "09134844955",
province: "تهران",
office: "اداره کل",
car_id: "233",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
operator_name: "امین",
phone_number: "09134849737",
province: "تهران",
office: "اداره کل",
car_id: "33",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
{
id: 2,
operator_name: "امیر",
phone_number: "09134844955",
province: "تهران",
office: "اداره کل",
car_id: "233",
start_date: "2024-11-02T11:48:22.000000Z",
end_date: "2024-11-03T11:01:14.000000Z",
register_date: "2024-11-03T11:01:14.000000Z",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,3 +1,3 @@
export async function POST() {
return Response.json({ message: "Done" });
}
export async function POST() {
return Response.json({ message: "Done" });
}

View File

@@ -1,18 +1,18 @@
const data = [
{
id: 1,
name: "تست نوع 1",
},
{
id: 2,
name: "تست نوع 2",
},
{
id: 3,
name: "تست نوع 3",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
name: "تست نوع 1",
},
{
id: 2,
name: "تست نوع 2",
},
{
id: 3,
name: "تست نوع 3",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,71 +1,71 @@
const data = [
{
id: 1,
test_type_name: 1,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 2,
test_type_name: 5,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 3,
test_type_name: 2,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 4,
test_type_name: 4,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 5,
test_type_name: 3,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
];
export async function GET() {
return Response.json({ data });
}
const data = [
{
id: 1,
test_type_name: 1,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 2,
test_type_name: 5,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 3,
test_type_name: 2,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 4,
test_type_name: 4,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
{
id: 5,
test_type_name: 3,
project_name: "نوع پروژه",
employer: "کارفرما",
consultant: "مشاور",
contractor: "پیمانکار",
applicant: "متقاضی",
work_number: "شماره کار",
request_number: "شماره درخواست",
request_date: "تاریخ درخواست",
report_date: "تاریخ گزارش",
},
];
export async function GET() {
return Response.json({ data });
}

View File

@@ -1,3 +1,3 @@
export default function Default() {
return null;
}
export default function Default() {
return null;
}

View File

@@ -1,25 +1,25 @@
import favicon from "@/assets/images/favicon.svg";
import { AuthProvider } from "@/lib/contexts/auth";
import { TableSettingProvider } from "@/lib/contexts/tableSetting";
export const metadata = {
title: {
template: "%s | سامانه جامع راهداری",
default: "سامانه جامع راهداری",
},
};
export default function RootLayout({ children }) {
return (
<html lang="fa" dir={"rtl"}>
<head>
<link rel="icon" href={favicon.src} type="image/svg" sizes="any" />
</head>
<body style={{ height: "100vh", width: "100vw" }}>
<AuthProvider>
<TableSettingProvider>{children}</TableSettingProvider>
</AuthProvider>
</body>
</html>
);
}
import favicon from "@/assets/images/favicon.svg";
import { AuthProvider } from "@/lib/contexts/auth";
import { TableSettingProvider } from "@/lib/contexts/tableSetting";
export const metadata = {
title: {
template: "%s | سامانه جامع راهداری",
default: "سامانه جامع راهداری",
},
};
export default function RootLayout({ children }) {
return (
<html lang="fa" dir={"rtl"}>
<head>
<link rel="icon" href={favicon.src} type="image/svg" sizes="any" />
</head>
<body style={{ height: "100vh", width: "100vw" }}>
<AuthProvider>
<TableSettingProvider>{children}</TableSettingProvider>
</AuthProvider>
</body>
</html>
);
}

View File

@@ -1,61 +1,61 @@
"use client";
import { GET_LOGIN_ROUTE } from "@/core/utils/routes";
import { useAuth } from "@/lib/contexts/auth";
import useRequest from "@/lib/hooks/useRequest";
import { Button, Stack, Typography, Zoom } from "@mui/material";
import Link from "next/link";
import { useEffect, useState } from "react";
const Page = ({ searchParams }) => {
const { getUser } = useAuth();
const { username } = searchParams;
const [login, setLogin] = useState(0);
const request = useRequest();
useEffect(() => {
const login = async () => {
try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser();
setLogin(1);
} catch (error) {
setLogin(2);
}
};
login();
}, []);
const retry = async () => {
setLogin(0);
try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser();
setLogin(1);
} catch (error) {
setLogin(2);
}
};
return (
<Stack alignItems={"center"} justifyContent={"center"} sx={{ height: "100%" }} spacing={2}>
<Typography variant="h5">
{login === 0
? "درحال دریافت مجوز برای ارتباط با سرور..."
: login === 1
? "ارتباط با سرور برقرار شد."
: "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."}
</Typography>
<Zoom in={login === 1}>
<Button component={Link} href="/">
ورود به سامانه
</Button>
</Zoom>
<Zoom in={login === 2}>
<Button onClick={retry}>تلاش مجدد</Button>
</Zoom>
</Stack>
);
};
export default Page;
"use client";
import { GET_LOGIN_ROUTE } from "@/core/utils/routes";
import { useAuth } from "@/lib/contexts/auth";
import useRequest from "@/lib/hooks/useRequest";
import { Button, Stack, Typography, Zoom } from "@mui/material";
import Link from "next/link";
import { useEffect, useState } from "react";
const Page = ({ searchParams }) => {
const { getUser } = useAuth();
const { username } = searchParams;
const [login, setLogin] = useState(0);
const request = useRequest();
useEffect(() => {
const login = async () => {
try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser();
setLogin(1);
} catch (error) {
setLogin(2);
}
};
login();
}, []);
const retry = async () => {
setLogin(0);
try {
await request(`${GET_LOGIN_ROUTE}?username=${username}`);
await getUser();
setLogin(1);
} catch (error) {
setLogin(2);
}
};
return (
<Stack alignItems={"center"} justifyContent={"center"} sx={{ height: "100%" }} spacing={2}>
<Typography variant="h5">
{login === 0
? "درحال دریافت مجوز برای ارتباط با سرور..."
: login === 1
? "ارتباط با سرور برقرار شد."
: "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."}
</Typography>
<Zoom in={login === 1}>
<Button component={Link} href="/">
ورود به سامانه
</Button>
</Zoom>
<Zoom in={login === 2}>
<Button onClick={retry}>تلاش مجدد</Button>
</Zoom>
</Stack>
);
};
export default Page;

View File

@@ -1,16 +1,16 @@
"use client";
import { Box, Stack, Typography } from "@mui/material";
import SvgNotFound from "@/core/components/svgs/SvgNotFound";
export default function NotFound() {
return (
<Stack sx={{ height: "100%" }} justifyContent={"center"} alignItems={"center"} spacing={2}>
<Box>
<SvgNotFound width={200} height={200} />
</Box>
<Typography variant={"body1"} sx={{ color: "primary.main" }}>
صفحه موردنظر یافت نشد ...
</Typography>
</Stack>
);
}
"use client";
import { Box, Stack, Typography } from "@mui/material";
import SvgNotFound from "@/core/components/svgs/SvgNotFound";
export default function NotFound() {
return (
<Stack sx={{ height: "100%" }} justifyContent={"center"} alignItems={"center"} spacing={2}>
<Box>
<SvgNotFound width={200} height={200} />
</Box>
<Typography variant={"body1"} sx={{ color: "primary.main" }}>
صفحه موردنظر یافت نشد ...
</Typography>
</Stack>
);
}

View File

@@ -1,8 +1,8 @@
import { redirect } from "next/navigation";
function Page() {
redirect("/dashboard", "replace");
return null;
}
export default Page;
import { redirect } from "next/navigation";
function Page() {
redirect("/dashboard", "replace");
return null;
}
export default Page;

View File

@@ -1,40 +1,40 @@
import cacheProviderRtl from "@/core/utils/cacheRtl";
import { CssBaseline, GlobalStyles, ThemeProvider } from "@mui/material";
import theme from "@/core/utils/theme";
import { AppRouterCacheProvider } from "@mui/material-nextjs/v14-appRouter";
import "@/assets/scss/global.scss";
import { ToastContainer } from "react-toastify";
const Template = ({ children }) => {
return (
<AppRouterCacheProvider CacheProvider={cacheProviderRtl} options={{ enableCssLayer: true }}>
<ThemeProvider theme={theme}>
<GlobalStyles
styles={{
"*": {
scrollbarWidth: "thin",
scrollbarColor: `#155175 transparent`,
},
"*&::-webkit-scrollbar": {
width: "4px",
},
"*&::-webkit-scrollbar-track": {
boxShadow: "inset 0 0 5px #fff",
borderRadius: "4px",
},
"*&::-webkit-scrollbar-thumb": {
background: "#155175",
borderRadius: "4px",
},
}}
/>
<CssBaseline />
{children}
<ToastContainer rtl containerId="filtering" closeButton={false} />
<ToastContainer rtl containerId="request_data" />
</ThemeProvider>
</AppRouterCacheProvider>
);
};
export default Template;
import cacheProviderRtl from "@/core/utils/cacheRtl";
import { CssBaseline, GlobalStyles, ThemeProvider } from "@mui/material";
import theme from "@/core/utils/theme";
import { AppRouterCacheProvider } from "@mui/material-nextjs/v14-appRouter";
import "@/assets/scss/global.scss";
import { ToastContainer } from "react-toastify";
const Template = ({ children }) => {
return (
<AppRouterCacheProvider CacheProvider={cacheProviderRtl} options={{ enableCssLayer: true }}>
<ThemeProvider theme={theme}>
<GlobalStyles
styles={{
"*": {
scrollbarWidth: "thin",
scrollbarColor: `#155175 transparent`,
},
"*&::-webkit-scrollbar": {
width: "4px",
},
"*&::-webkit-scrollbar-track": {
boxShadow: "inset 0 0 5px #fff",
borderRadius: "4px",
},
"*&::-webkit-scrollbar-thumb": {
background: "#155175",
borderRadius: "4px",
},
}}
/>
<CssBaseline />
{children}
<ToastContainer rtl containerId="filtering" closeButton={false} />
<ToastContainer rtl containerId="request_data" />
</ThemeProvider>
</AppRouterCacheProvider>
);
};
export default Template;

View File

@@ -1,190 +1,190 @@
/**
*
* Name: IRAN Sans-Serif Font
* Version: 5.0
* Author: Moslem Ebrahimi (moslemebrahimi.com)
* Created on: Dec 25, 2012
* Updated on: Sep 01, 2017
* Website: http://fontiran.com
* Copyright: Commercial/Proprietary Software
--------------------------------------------------------------------------------------
فونت های ایران سن سریف یک نرم افزار مالکیتی محسوب می شود. جهت آگاهی از قوانین استفاده از این فونت ها لطفا به وب سایت (فونت ایران دات کام) مراجعه نمایید
--------------------------------------------------------------------------------------
IRAN Sans-serif fonts are considered a proprietary software. To gain information about the laws regarding the use of these fonts, please visit www.fontiran.com
--------------------------------------------------------------------------------------
This set of fonts are used in this project under the license: (.....)
--------------------------------------------------------------------------------------
*
**/
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 900;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Black.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Black.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Black.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Black.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Black.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Bold.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 500;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Medium.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Medium.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Medium.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 300;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Light.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Light.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Light.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Light.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Light.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 200;
src: url("../fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/IRANSansWeb(FaNum).eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum).eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum).woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum).woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum).ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 900;
src: url("../fonts/eot/IRANSansWeb_Black.eot");
src:
url("../fonts/eot/IRANSansWeb_Black.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Black.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Black.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Black.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/IRANSansWeb_Bold.eot");
src:
url("../fonts/eot/IRANSansWeb_Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Bold.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Bold.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 500;
src: url("../fonts/eot/IRANSansWeb_Medium.eot");
src:
url("../fonts/eot/IRANSansWeb_Medium.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Medium.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Medium.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Medium.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 300;
src: url("../fonts/eot/IRANSansWeb_Light.eot");
src:
url("../fonts/eot/IRANSansWeb_Light.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Light.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Light.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Light.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 200;
src: url("../fonts/eot/IRANSansWeb_UltraLight.eot");
src:
url("../fonts/eot/IRANSansWeb_UltraLight.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_UltraLight.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_UltraLight.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_UltraLight.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/IRANSansWeb.eot");
src:
url("../fonts/eot/IRANSansWeb.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb.ttf") format("truetype");
}
@font-face {
font-family: Parastoo;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/Parastoo.eot");
src:
url("../fonts/eot/Parastoo.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff/Parastoo.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/Parastoo.ttf") format("truetype");
}
@font-face {
font-family: Parastoo;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/Parastoo-Bold.eot");
src:
url("../fonts/eot/Parastoo-Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff/Parastoo-Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/Parastoo-Bold.ttf") format("truetype");
}
@font-face {
font-family: Bnazanin;
font-style: normal;
font-weight: normal;
src: url("../fonts/ttf/BNazanin.ttf") format("truetype");
}
/**
*
* Name: IRAN Sans-Serif Font
* Version: 5.0
* Author: Moslem Ebrahimi (moslemebrahimi.com)
* Created on: Dec 25, 2012
* Updated on: Sep 01, 2017
* Website: http://fontiran.com
* Copyright: Commercial/Proprietary Software
--------------------------------------------------------------------------------------
فونت های ایران سن سریف یک نرم افزار مالکیتی محسوب می شود. جهت آگاهی از قوانین استفاده از این فونت ها لطفا به وب سایت (فونت ایران دات کام) مراجعه نمایید
--------------------------------------------------------------------------------------
IRAN Sans-serif fonts are considered a proprietary software. To gain information about the laws regarding the use of these fonts, please visit www.fontiran.com
--------------------------------------------------------------------------------------
This set of fonts are used in this project under the license: (.....)
--------------------------------------------------------------------------------------
*
**/
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 900;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Black.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Black.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Black.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Black.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Black.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Bold.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 500;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Medium.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Medium.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Medium.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 300;
src: url("../fonts/eot/IRANSansWeb(FaNum)_Light.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_Light.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_Light.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_Light.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_Light.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: 200;
src: url("../fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf") format("truetype");
}
@font-face {
font-family: IRANSansFaNum;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/IRANSansWeb(FaNum).eot");
src:
url("../fonts/eot/IRANSansWeb(FaNum).eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb(FaNum).woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb(FaNum).woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb(FaNum).ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 900;
src: url("../fonts/eot/IRANSansWeb_Black.eot");
src:
url("../fonts/eot/IRANSansWeb_Black.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Black.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Black.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Black.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/IRANSansWeb_Bold.eot");
src:
url("../fonts/eot/IRANSansWeb_Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Bold.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Bold.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 500;
src: url("../fonts/eot/IRANSansWeb_Medium.eot");
src:
url("../fonts/eot/IRANSansWeb_Medium.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Medium.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Medium.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Medium.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 300;
src: url("../fonts/eot/IRANSansWeb_Light.eot");
src:
url("../fonts/eot/IRANSansWeb_Light.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_Light.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_Light.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_Light.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: 200;
src: url("../fonts/eot/IRANSansWeb_UltraLight.eot");
src:
url("../fonts/eot/IRANSansWeb_UltraLight.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb_UltraLight.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb_UltraLight.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb_UltraLight.ttf") format("truetype");
}
@font-face {
font-family: IRANSans;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/IRANSansWeb.eot");
src:
url("../fonts/eot/IRANSansWeb.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff2/IRANSansWeb.woff2") format("woff2"),
/* FF39+,Chrome36+, Opera24+*/ url("../fonts/woff/IRANSansWeb.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/IRANSansWeb.ttf") format("truetype");
}
@font-face {
font-family: Parastoo;
font-style: normal;
font-weight: normal;
src: url("../fonts/eot/Parastoo.eot");
src:
url("../fonts/eot/Parastoo.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff/Parastoo.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/Parastoo.ttf") format("truetype");
}
@font-face {
font-family: Parastoo;
font-style: normal;
font-weight: bold;
src: url("../fonts/eot/Parastoo-Bold.eot");
src:
url("../fonts/eot/Parastoo-Bold.eot?#iefix") format("embedded-opentype"),
/* IE6-8 */ url("../fonts/woff/Parastoo-Bold.woff") format("woff"),
/* FF3.6+, IE9, Chrome6+, Saf5.1+*/ url("../fonts/ttf/Parastoo-Bold.ttf") format("truetype");
}
@font-face {
font-family: Bnazanin;
font-style: normal;
font-weight: normal;
src: url("../fonts/ttf/BNazanin.ttf") format("truetype");
}

View File

@@ -1,11 +1,12 @@
@import "fontiran";
@import "leaflet/dist/leaflet.css";
@import "react-toastify/dist/ReactToastify.css";
@import "./map-styles.scss";
.filter-toast {
box-shadow:
rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
background-color: #d0dfe8;
}
@import "fontiran";
@import "leaflet/dist/leaflet.css";
@import "leaflet-draw/dist/leaflet.draw.css";
@import "react-toastify/dist/ReactToastify.css";
@import "./map-styles.scss";
.filter-toast {
box-shadow:
rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
background-color: #d0dfe8;
}

View File

@@ -1,9 +1,29 @@
.custom-marker-cluster {
font-family: IRANSansFaNum;
background-color: rgba(51, 181, 229, 0.6);
color: #fff;
border-radius: 50%;
text-align: center;
font-size: 14px;
line-height: 40px;
}
.custom-marker-cluster {
font-family: IRANSansFaNum;
background-color: rgba(51, 181, 229, 0.6);
color: #fff;
border-radius: 50%;
text-align: center;
font-size: 14px;
line-height: 40px;
}
.leaflet-draw {
display: none;
}
.leaflet-draw-tooltip {
margin-left: 0;
margin-right: 20px;
}
.leaflet-draw-tooltip::before {
border-left: 6px solid black;
border-left-color: rgba(0, 0, 0, 0.5);
border-right: 0;
right: -7px;
left: auto;
}
.leaflet-editing-icon {
border-radius: 50%;
}

View File

@@ -1,33 +1,33 @@
"use client";
import { Button, IconButton, useMediaQuery } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { AddCircle } from "@mui/icons-material";
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
const AzmayeshCreate = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="ثبت آزمایش جدید" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleOpen}>
ثبت آزمایش
</Button>
)}
{open && <CandUAzmayesh open={open} setOpen={setOpen} mutate={mutate} />}
</>
);
};
export default AzmayeshCreate;
"use client";
import { Button, IconButton, useMediaQuery } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { AddCircle } from "@mui/icons-material";
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
const AzmayeshCreate = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="ثبت آزمایش جدید" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleOpen}>
ثبت آزمایش
</Button>
)}
{open && <CandUAzmayesh open={open} setOpen={setOpen} mutate={mutate} />}
</>
);
};
export default AzmayeshCreate;

View File

@@ -1,216 +1,216 @@
"use client";
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import Toolbar from "./Toolbar";
import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
import ShowLocation from "./ShowLocation";
import moment from "jalali-moment";
import RowActions from "./RowActions";
import ShowSampleOfAzmayesh from "./RowActions/ShowSampleOfAzmayesh";
const AzmayeshList = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
grow: false,
size: 100,
},
{
accessorKey: "province_name",
header: "استان",
id: "province_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "azmayesh_type_name",
header: "نوع آزمایش",
id: "azmayesh_type_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "contract_subitem_id",
header: "کد یکتا پروژه",
id: "contract_subitem_id",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "project_name",
header: "پروژه",
id: "project_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "location",
header: "نمایش مختصات",
id: "location",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowLocation lat={row.original.lat} lng={row.original.lng} />,
},
{
accessorKey: "employer",
header: "کارفرما",
id: "employer",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "consultant",
header: "مشاور",
id: "consultant",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "contractor",
header: "پیمانکار",
id: "contractor",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "applicant",
header: "متقاضی",
id: "applicant",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "work_number",
header: "شماره کار",
id: "work_number",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "request_number",
header: "شماره درخواست",
id: "request_number",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "request_date",
header: "تاریخ درخواست",
id: "request_date",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "report_date",
header: "تاریخ گزارش",
id: "report_date",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "samples",
header: "نمونه ها",
id: "samples",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowSampleOfAzmayesh rowData={row.original} />,
},
],
[]
);
return (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"لیست آزمایشات"}
need_filter={false}
columns={columns}
table_url={GET_AZMAYESH_LIST}
page_name={"azmayesh"}
table_name={"azmayeshList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default AzmayeshList;
"use client";
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import Toolbar from "./Toolbar";
import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
import ShowLocation from "./ShowLocation";
import moment from "jalali-moment";
import RowActions from "./RowActions";
import ShowSampleOfAzmayesh from "./RowActions/ShowSampleOfAzmayesh";
const AzmayeshList = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
grow: false,
size: 100,
},
{
accessorKey: "province_name",
header: "استان",
id: "province_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "azmayesh_type_name",
header: "نوع آزمایش",
id: "azmayesh_type_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "contract_subitem_id",
header: "کد یکتا پروژه",
id: "contract_subitem_id",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "project_name",
header: "پروژه",
id: "project_name",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "location",
header: "نمایش مختصات",
id: "location",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowLocation lat={row.original.lat} lng={row.original.lng} />,
},
{
accessorKey: "employer",
header: "کارفرما",
id: "employer",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "consultant",
header: "مشاور",
id: "consultant",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "contractor",
header: "پیمانکار",
id: "contractor",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "applicant",
header: "متقاضی",
id: "applicant",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "work_number",
header: "شماره کار",
id: "work_number",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "request_number",
header: "شماره درخواست",
id: "request_number",
enableColumnFilter: false,
datatype: "text",
filterMode: "equals",
},
{
accessorKey: "request_date",
header: "تاریخ درخواست",
id: "request_date",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "report_date",
header: "تاریخ گزارش",
id: "report_date",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
{
accessorKey: "samples",
header: "نمونه ها",
id: "samples",
enableColumnFilter: false,
datatype: "text",
enableSorting: false,
filterMode: "equals",
grow: false,
size: 100,
muiTableBodyCellProps: {
sx: {
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ row }) => <ShowSampleOfAzmayesh rowData={row.original} />,
},
],
[]
);
return (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"لیست آزمایشات"}
need_filter={false}
columns={columns}
table_url={GET_AZMAYESH_LIST}
page_name={"azmayesh"}
table_name={"azmayeshList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default AzmayeshList;

View File

@@ -1,213 +1,213 @@
"use client";
import { Marker, useMapEvents } from "react-leaflet";
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import AzmayeshIcon from "@/assets/images/examine_marker.png";
import AzmayeshActiveIcon from "@/assets/images/examine_marker_active.png";
import {
Alert,
Box,
Button,
FormControl,
InputAdornment,
InputLabel,
OutlinedInput,
Stack,
Tooltip,
Zoom,
useMediaQuery,
} from "@mui/material";
import NewReleasesIcon from "@mui/icons-material/NewReleases";
import VerifiedIcon from "@mui/icons-material/Verified";
import EditIcon from "@mui/icons-material/Edit";
import { useTheme } from "@emotion/react";
const MAX_ZOOM_FOR_MARKER = 13;
const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [enableSend, setEnableSend] = useState(false);
const mapAzmayeshMarker = useRef();
const defaultIconSize = [35, 35];
const createCustomIcon = (size, iconUrl) => {
return L.icon({
iconUrl: iconUrl,
iconSize: size,
iconAnchor: [size[0] / 2, size[1]],
popupAnchor: [0, -size[1]],
});
};
const map = useMapEvents({
move(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
if (!mapBoxData) {
mapAzmayeshMarker.current.setLatLng(e.target.getCenter());
}
},
movestart() {
if (!mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshIcon.src));
}
},
moveend() {
if (!mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
},
zoom(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
},
});
useEffect(() => {
if (!mapAzmayeshMarker.current) return;
if (mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshActiveIcon.src));
mapAzmayeshMarker.current.setLatLng(mapBoxData);
map.setView(mapBoxData, 14);
} else {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
}, [mapBoxData, mapAzmayeshMarker.current]);
const handleMarkerClick = () => {
if (!enableSend) return;
if (!mapBoxData) {
setMapBoxData({
lat: mapAzmayeshMarker.current.getLatLng().lat,
lng: mapAzmayeshMarker.current.getLatLng().lng,
});
}
};
const handleEditLocation = () => {
setMapBoxData(null);
};
return (
<>
<Marker
position={map.getCenter()}
ref={mapAzmayeshMarker}
eventHandlers={{ click: handleMarkerClick }}
icon={L.divIcon({ className: "" })}
/>
<Stack
direction={"row"}
justifyContent={"center"}
sx={{
zIndex: "400",
width: "100%",
position: "absolute",
top: 0,
left: 0,
}}
>
<Zoom in={!enableSend}>
<Alert sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={"warning"}>
برای ثبت محل آزمایش، لطفاً نقشه را بیشتر زوم کنید.
</Alert>
</Zoom>
</Stack>
<Stack
direction={"row"}
sx={{
zIndex: "400",
width: "100%",
position: "absolute",
bottom: 0,
left: 0,
}}
>
<Box
sx={{
background: "#ffffff94",
flex: isMobile ? 1 : "",
m: 1,
p: 2,
borderRadius: 2,
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
}}
>
<Stack sx={{ gap: 2 }}>
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
<FormControl size="small" variant="outlined">
<InputLabel sx={{ color: mapBoxData ? "success.main" : "" }} htmlFor="lat">
طول جغرافیایی
</InputLabel>
<OutlinedInput
id="lat"
type="text"
size="small"
readOnly
sx={{
"& .MuiOutlinedInput-notchedOutline": {
borderColor: mapBoxData ? "success.main" : "",
},
color: mapBoxData ? "success.main" : "",
}}
value={mapBoxData ? `${mapBoxData.lat}` : ""}
endAdornment={
<InputAdornment position="end">
{mapBoxData ? (
<VerifiedIcon color="success" />
) : (
<NewReleasesIcon color="error" />
)}
</InputAdornment>
}
label="طول جغرافیایی"
/>
</FormControl>
</Tooltip>
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
<FormControl size="small" variant="outlined">
<InputLabel sx={{ color: mapBoxData ? "success.main" : "" }} htmlFor="lng">
عرض جغرافیایی
</InputLabel>
<OutlinedInput
id="lng"
type="text"
size="small"
readOnly
sx={{
"& .MuiOutlinedInput-notchedOutline": {
borderColor: mapBoxData ? "success.main" : "",
},
color: mapBoxData ? "success.main" : "",
}}
value={mapBoxData ? `${mapBoxData.lng}` : ""}
endAdornment={
<InputAdornment position="end">
{mapBoxData ? (
<VerifiedIcon color="success" />
) : (
<NewReleasesIcon color="error" />
)}
</InputAdornment>
}
label="عرض جغرافیایی"
/>
</FormControl>
</Tooltip>
<Button
variant="contained"
color="primary"
disabled={!mapBoxData}
startIcon={<EditIcon />}
onClick={handleEditLocation}
>
ویرایش مختصات
</Button>
</Stack>
</Box>
</Stack>
</>
);
};
export default CandUChooseLocation;
"use client";
import { Marker, useMapEvents } from "react-leaflet";
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import AzmayeshIcon from "@/assets/images/examine_marker.png";
import AzmayeshActiveIcon from "@/assets/images/examine_marker_active.png";
import {
Alert,
Box,
Button,
FormControl,
InputAdornment,
InputLabel,
OutlinedInput,
Stack,
Tooltip,
Zoom,
useMediaQuery,
} from "@mui/material";
import NewReleasesIcon from "@mui/icons-material/NewReleases";
import VerifiedIcon from "@mui/icons-material/Verified";
import EditIcon from "@mui/icons-material/Edit";
import { useTheme } from "@emotion/react";
const MAX_ZOOM_FOR_MARKER = 13;
const CandUChooseLocation = ({ mapBoxData, setMapBoxData }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [enableSend, setEnableSend] = useState(false);
const mapAzmayeshMarker = useRef();
const defaultIconSize = [35, 35];
const createCustomIcon = (size, iconUrl) => {
return L.icon({
iconUrl: iconUrl,
iconSize: size,
iconAnchor: [size[0] / 2, size[1]],
popupAnchor: [0, -size[1]],
});
};
const map = useMapEvents({
move(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
if (!mapBoxData) {
mapAzmayeshMarker.current.setLatLng(e.target.getCenter());
}
},
movestart() {
if (!mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshIcon.src));
}
},
moveend() {
if (!mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
},
zoom(e) {
setEnableSend(e.target.getZoom() > MAX_ZOOM_FOR_MARKER);
},
});
useEffect(() => {
if (!mapAzmayeshMarker.current) return;
if (mapBoxData) {
mapAzmayeshMarker.current.setIcon(createCustomIcon([45, 45], AzmayeshActiveIcon.src));
mapAzmayeshMarker.current.setLatLng(mapBoxData);
map.setView(mapBoxData, 14);
} else {
mapAzmayeshMarker.current.setIcon(createCustomIcon(defaultIconSize, AzmayeshIcon.src));
}
}, [mapBoxData, mapAzmayeshMarker.current]);
const handleMarkerClick = () => {
if (!enableSend) return;
if (!mapBoxData) {
setMapBoxData({
lat: mapAzmayeshMarker.current.getLatLng().lat,
lng: mapAzmayeshMarker.current.getLatLng().lng,
});
}
};
const handleEditLocation = () => {
setMapBoxData(null);
};
return (
<>
<Marker
position={map.getCenter()}
ref={mapAzmayeshMarker}
eventHandlers={{ click: handleMarkerClick }}
icon={L.divIcon({ className: "" })}
/>
<Stack
direction={"row"}
justifyContent={"center"}
sx={{
zIndex: "400",
width: "100%",
position: "absolute",
top: 0,
left: 0,
}}
>
<Zoom in={!enableSend}>
<Alert sx={{ mt: 1, py: 0.5, px: 2, borderRadius: 2, border: 1 }} icon={false} color={"warning"}>
برای ثبت محل آزمایش، لطفاً نقشه را بیشتر زوم کنید.
</Alert>
</Zoom>
</Stack>
<Stack
direction={"row"}
sx={{
zIndex: "400",
width: "100%",
position: "absolute",
bottom: 0,
left: 0,
}}
>
<Box
sx={{
background: "#ffffff94",
flex: isMobile ? 1 : "",
m: 1,
p: 2,
borderRadius: 2,
boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px",
}}
>
<Stack sx={{ gap: 2 }}>
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
<FormControl size="small" variant="outlined">
<InputLabel sx={{ color: mapBoxData ? "success.main" : "" }} htmlFor="lat">
طول جغرافیایی
</InputLabel>
<OutlinedInput
id="lat"
type="text"
size="small"
readOnly
sx={{
"& .MuiOutlinedInput-notchedOutline": {
borderColor: mapBoxData ? "success.main" : "",
},
color: mapBoxData ? "success.main" : "",
}}
value={mapBoxData ? `${mapBoxData.lat}` : ""}
endAdornment={
<InputAdornment position="end">
{mapBoxData ? (
<VerifiedIcon color="success" />
) : (
<NewReleasesIcon color="error" />
)}
</InputAdornment>
}
label="طول جغرافیایی"
/>
</FormControl>
</Tooltip>
<Tooltip title="با کلیک بر روی مارکر، محل آزمایش را انتخاب کنید" arrow>
<FormControl size="small" variant="outlined">
<InputLabel sx={{ color: mapBoxData ? "success.main" : "" }} htmlFor="lng">
عرض جغرافیایی
</InputLabel>
<OutlinedInput
id="lng"
type="text"
size="small"
readOnly
sx={{
"& .MuiOutlinedInput-notchedOutline": {
borderColor: mapBoxData ? "success.main" : "",
},
color: mapBoxData ? "success.main" : "",
}}
value={mapBoxData ? `${mapBoxData.lng}` : ""}
endAdornment={
<InputAdornment position="end">
{mapBoxData ? (
<VerifiedIcon color="success" />
) : (
<NewReleasesIcon color="error" />
)}
</InputAdornment>
}
label="عرض جغرافیایی"
/>
</FormControl>
</Tooltip>
<Button
variant="contained"
color="primary"
disabled={!mapBoxData}
startIcon={<EditIcon />}
onClick={handleEditLocation}
>
ویرایش مختصات
</Button>
</Stack>
</Box>
</Stack>
</>
);
};
export default CandUChooseLocation;

View File

@@ -1,373 +1,373 @@
"use client";
import { Controller } from "react-hook-form";
import {
Autocomplete,
CircularProgress,
FormControl,
FormHelperText,
Grid,
IconButton,
InputAdornment,
InputLabel,
OutlinedInput,
TextField,
Typography,
} from "@mui/material";
import useAzmayesh from "@/lib/hooks/useAzmayesh";
import useProvinces from "@/lib/hooks/useProvince";
import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers";
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import { faIR } from "@mui/x-date-pickers/locales";
import ClearIcon from "@mui/icons-material/Clear";
import React from "react";
const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
const { azmayeshes, errorAzmayeshes, loadingAzmayeshes } = useAzmayesh();
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
return (
<Grid container spacing={2}>
<Grid item xs={12} md={6} sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
<Controller
name="azmayesh_type_id"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.azmayesh_type_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="azmayesh_type_id" />
{errorAzmayeshes ? (
<Typography color={"red"} sx={{ display: "flex", alignItems: "center", gap: 2 }}>
خطایی در دریافت لیست آزمایش ها رخ داده است!
</Typography>
) : loadingAzmayeshes ? (
<Typography sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<CircularProgress size={20} />
درحال دریافت لیست آزمایش ها
</Typography>
) : (
<Autocomplete
id="azmayesh_type_id"
size="small"
value={azmayeshes.find((azmayesh) => azmayesh.id === value) || null}
disablePortal
options={azmayeshes}
getOptionLabel={(azmayesh) => azmayesh.name}
isOptionEqualToValue={(option, value) => option.id === value?.id}
onChange={(event, newValue) => {
onChange(newValue ? newValue.id : "");
setValue("azmayesh_type_name", newValue ? newValue.name : "");
}}
renderInput={(params) => (
<TextField
{...params}
autoComplete="off"
error={!!errors.azmayesh_type_id}
fullWidth
label="نوع آزمایش"
/>
)}
renderOption={(props, option) => (
<li {...props} key={option.id}>
{option.name}
</li>
)}
/>
)}
<FormHelperText id="azmayesh_type_id">
{errors.azmayesh_type_id ? errors.azmayesh_type_id.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6} sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
<Controller
name="province_id"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.province_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="province_id" />
{errorProvinces ? (
<Typography color={"red"} sx={{ display: "flex", alignItems: "center", gap: 2 }}>
خطایی در دریافت لیست استان ها رخ داده است!
</Typography>
) : loadingProvinces ? (
<Typography sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<CircularProgress size={20} />
درحال دریافت لیست استان ها
</Typography>
) : (
<Autocomplete
id="province_id"
size="small"
value={provinces.find((province) => province.id === value) || null}
disablePortal
options={provinces}
getOptionLabel={(province) => province.name_fa}
isOptionEqualToValue={(option, value) => option.id === value?.id}
onChange={(event, newValue) => {
onChange(newValue ? newValue.id : "");
setValue("province_name", newValue ? newValue.name_fa : "");
}}
renderInput={(params) => (
<TextField
{...params}
autoComplete="off"
error={!!errors.province_id}
fullWidth
label="استان"
/>
)}
/>
)}
<FormHelperText id="province_id">
{errors.province_id ? errors.province_id.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.contract_subitem_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="contract_subitem_id">کد یکتا پروژه</InputLabel>
<OutlinedInput
id="contract_subitem_id"
label={"کد یکتا پروژه"}
autoComplete="off"
{...register("contract_subitem_id")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="contract_subitem_id">
{errors.contract_subitem_id ? errors.contract_subitem_id.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.project_name} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="project_name">پروژه</InputLabel>
<OutlinedInput
id="project_name"
label={"پروژه"}
autoComplete="off"
{...register("project_name")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="project_name">
{errors.project_name ? errors.project_name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.employer} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="employer">کارفرما</InputLabel>
<OutlinedInput
id="employer"
label={"کارفرما"}
autoComplete="off"
{...register("employer")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="employer">{errors.employer ? errors.employer.message : null}</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.consultant} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="consultant">مشاور</InputLabel>
<OutlinedInput
id="consultant"
label={"مشاور"}
autoComplete="off"
{...register("consultant")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="consultant">
{errors.consultant ? errors.consultant.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.contractor} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="contractor">پیمانکار</InputLabel>
<OutlinedInput
id="contractor"
label={"پیمانکار"}
autoComplete="off"
{...register("contractor")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="contractor">
{errors.contractor ? errors.contractor.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.applicant} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="applicant">متقاضی</InputLabel>
<OutlinedInput
id="applicant"
label={"متقاضی"}
autoComplete="off"
{...register("applicant")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="applicant">{errors.applicant ? errors.applicant.message : null}</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.work_number} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="work_number">شماره کار</InputLabel>
<OutlinedInput
id="work_number"
label={"شماره کار"}
autoComplete="off"
{...register("work_number")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="work_number">
{errors.work_number ? errors.work_number.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.request_number} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="request_number">شماره درخواست</InputLabel>
<OutlinedInput
id="request_number"
label={"شماره درخواست"}
autoComplete="off"
{...register("request_number")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="request_number">
{errors.request_number ? errors.request_number.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<Controller
name="request_date"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.request_date} fullWidth size="small" variant="outlined">
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<MobileDatePicker
value={value || null}
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",
error: !!errors.request_date,
placeholder: "تاریخ درخواست",
InputProps: {
endAdornment: (
<InputAdornment position="end">
<IconButton
size="small"
onClick={(event) => {
event.stopPropagation();
setValue("request_date", "");
}}
sx={{
color: "#bfbfbf",
"&:hover": {
backgroundColor: "rgba(189, 189, 189, 0.1)",
color: "#363434",
},
}}
>
<ClearIcon />
</IconButton>
</InputAdornment>
),
},
},
}}
/>
</LocalizationProvider>
<FormHelperText id="request_date">
{errors.request_date ? errors.request_date.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<Controller
name="report_date"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.report_date} fullWidth size="small" variant="outlined">
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<MobileDatePicker
value={value || null}
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",
error: !!errors.report_date,
placeholder: "تاریخ گزارش",
InputProps: {
endAdornment: (
<InputAdornment position="end">
<IconButton
size="small"
onClick={(event) => {
event.stopPropagation();
setValue("report_date", "");
}}
sx={{
color: "#bfbfbf",
"&:hover": {
backgroundColor: "rgba(189, 189, 189, 0.1)",
color: "#363434",
},
}}
>
<ClearIcon />
</IconButton>
</InputAdornment>
),
},
},
}}
/>
</LocalizationProvider>
<FormHelperText id="report_date">
{errors.report_date ? errors.report_date.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
</Grid>
);
};
export default CandUGeneralInfo;
"use client";
import { Controller } from "react-hook-form";
import {
Autocomplete,
CircularProgress,
FormControl,
FormHelperText,
Grid,
IconButton,
InputAdornment,
InputLabel,
OutlinedInput,
TextField,
Typography,
} from "@mui/material";
import useAzmayesh from "@/lib/hooks/useAzmayesh";
import useProvinces from "@/lib/hooks/useProvince";
import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers";
import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import { faIR } from "@mui/x-date-pickers/locales";
import ClearIcon from "@mui/icons-material/Clear";
import React from "react";
const CandUGeneralInfo = ({ control, register, setValue, errors }) => {
const { azmayeshes, errorAzmayeshes, loadingAzmayeshes } = useAzmayesh();
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
return (
<Grid container spacing={2}>
<Grid item xs={12} md={6} sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
<Controller
name="azmayesh_type_id"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.azmayesh_type_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="azmayesh_type_id" />
{errorAzmayeshes ? (
<Typography color={"red"} sx={{ display: "flex", alignItems: "center", gap: 2 }}>
خطایی در دریافت لیست آزمایش ها رخ داده است!
</Typography>
) : loadingAzmayeshes ? (
<Typography sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<CircularProgress size={20} />
درحال دریافت لیست آزمایش ها
</Typography>
) : (
<Autocomplete
id="azmayesh_type_id"
size="small"
value={azmayeshes.find((azmayesh) => azmayesh.id === value) || null}
disablePortal
options={azmayeshes}
getOptionLabel={(azmayesh) => azmayesh.name}
isOptionEqualToValue={(option, value) => option.id === value?.id}
onChange={(event, newValue) => {
onChange(newValue ? newValue.id : "");
setValue("azmayesh_type_name", newValue ? newValue.name : "");
}}
renderInput={(params) => (
<TextField
{...params}
autoComplete="off"
error={!!errors.azmayesh_type_id}
fullWidth
label="نوع آزمایش"
/>
)}
renderOption={(props, option) => (
<li {...props} key={option.id}>
{option.name}
</li>
)}
/>
)}
<FormHelperText id="azmayesh_type_id">
{errors.azmayesh_type_id ? errors.azmayesh_type_id.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6} sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
<Controller
name="province_id"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.province_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="province_id" />
{errorProvinces ? (
<Typography color={"red"} sx={{ display: "flex", alignItems: "center", gap: 2 }}>
خطایی در دریافت لیست استان ها رخ داده است!
</Typography>
) : loadingProvinces ? (
<Typography sx={{ display: "flex", alignItems: "center", gap: 2 }}>
<CircularProgress size={20} />
درحال دریافت لیست استان ها
</Typography>
) : (
<Autocomplete
id="province_id"
size="small"
value={provinces.find((province) => province.id === value) || null}
disablePortal
options={provinces}
getOptionLabel={(province) => province.name_fa}
isOptionEqualToValue={(option, value) => option.id === value?.id}
onChange={(event, newValue) => {
onChange(newValue ? newValue.id : "");
setValue("province_name", newValue ? newValue.name_fa : "");
}}
renderInput={(params) => (
<TextField
{...params}
autoComplete="off"
error={!!errors.province_id}
fullWidth
label="استان"
/>
)}
/>
)}
<FormHelperText id="province_id">
{errors.province_id ? errors.province_id.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.contract_subitem_id} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="contract_subitem_id">کد یکتا پروژه</InputLabel>
<OutlinedInput
id="contract_subitem_id"
label={"کد یکتا پروژه"}
autoComplete="off"
{...register("contract_subitem_id")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="contract_subitem_id">
{errors.contract_subitem_id ? errors.contract_subitem_id.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.project_name} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="project_name">پروژه</InputLabel>
<OutlinedInput
id="project_name"
label={"پروژه"}
autoComplete="off"
{...register("project_name")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="project_name">
{errors.project_name ? errors.project_name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.employer} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="employer">کارفرما</InputLabel>
<OutlinedInput
id="employer"
label={"کارفرما"}
autoComplete="off"
{...register("employer")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="employer">{errors.employer ? errors.employer.message : null}</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.consultant} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="consultant">مشاور</InputLabel>
<OutlinedInput
id="consultant"
label={"مشاور"}
autoComplete="off"
{...register("consultant")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="consultant">
{errors.consultant ? errors.consultant.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.contractor} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="contractor">پیمانکار</InputLabel>
<OutlinedInput
id="contractor"
label={"پیمانکار"}
autoComplete="off"
{...register("contractor")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="contractor">
{errors.contractor ? errors.contractor.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.applicant} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="applicant">متقاضی</InputLabel>
<OutlinedInput
id="applicant"
label={"متقاضی"}
autoComplete="off"
{...register("applicant")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="applicant">{errors.applicant ? errors.applicant.message : null}</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.work_number} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="work_number">شماره کار</InputLabel>
<OutlinedInput
id="work_number"
label={"شماره کار"}
autoComplete="off"
{...register("work_number")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="work_number">
{errors.work_number ? errors.work_number.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl error={!!errors.request_number} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="request_number">شماره درخواست</InputLabel>
<OutlinedInput
id="request_number"
label={"شماره درخواست"}
autoComplete="off"
{...register("request_number")}
size="small"
fullWidth
type="text"
/>
<FormHelperText id="request_number">
{errors.request_number ? errors.request_number.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<Controller
name="request_date"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.request_date} fullWidth size="small" variant="outlined">
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<MobileDatePicker
value={value || null}
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",
error: !!errors.request_date,
placeholder: "تاریخ درخواست",
InputProps: {
endAdornment: (
<InputAdornment position="end">
<IconButton
size="small"
onClick={(event) => {
event.stopPropagation();
setValue("request_date", "");
}}
sx={{
color: "#bfbfbf",
"&:hover": {
backgroundColor: "rgba(189, 189, 189, 0.1)",
color: "#363434",
},
}}
>
<ClearIcon />
</IconButton>
</InputAdornment>
),
},
},
}}
/>
</LocalizationProvider>
<FormHelperText id="request_date">
{errors.request_date ? errors.request_date.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
<Grid item xs={12} md={6}>
<Controller
name="report_date"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<FormControl error={!!errors.report_date} fullWidth size="small" variant="outlined">
<LocalizationProvider
dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
>
<MobileDatePicker
value={value || null}
onChange={(newValue) => {
onChange(newValue);
}}
closeOnSelect
slotProps={{
textField: {
size: "small",
error: !!errors.report_date,
placeholder: "تاریخ گزارش",
InputProps: {
endAdornment: (
<InputAdornment position="end">
<IconButton
size="small"
onClick={(event) => {
event.stopPropagation();
setValue("report_date", "");
}}
sx={{
color: "#bfbfbf",
"&:hover": {
backgroundColor: "rgba(189, 189, 189, 0.1)",
color: "#363434",
},
}}
>
<ClearIcon />
</IconButton>
</InputAdornment>
),
},
},
}}
/>
</LocalizationProvider>
<FormHelperText id="report_date">
{errors.report_date ? errors.report_date.message : null}
</FormHelperText>
</FormControl>
)}
/>
</Grid>
</Grid>
);
};
export default CandUGeneralInfo;

View File

@@ -1,41 +1,41 @@
"use client";
import { Box, Stack } from "@mui/material";
import dynamic from "next/dynamic";
import MapLoading from "@/core/components/MapLayer/Loading";
import CandUChooseLocation from "./CandUChooseLocation";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => <MapLoading />,
ssr: false,
});
const CandUMapBox = ({ mapBoxData, setMapBoxData }) => {
return (
<Stack spacing={1} sx={{ height: "500px" }}>
<Box
sx={{
p: 1,
border: "1px dashed",
borderColor: "divider",
borderRadius: 1,
height: "100%",
}}
>
<Box
sx={{
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MapLayer>
<CandUChooseLocation mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
</MapLayer>
</Box>
</Box>
</Stack>
);
};
export default CandUMapBox;
"use client";
import { Box, Stack } from "@mui/material";
import dynamic from "next/dynamic";
import MapLoading from "@/core/components/MapLayer/Loading";
import CandUChooseLocation from "./CandUChooseLocation";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => <MapLoading />,
ssr: false,
});
const CandUMapBox = ({ mapBoxData, setMapBoxData }) => {
return (
<Stack spacing={1} sx={{ height: "500px" }}>
<Box
sx={{
p: 1,
border: "1px dashed",
borderColor: "divider",
borderRadius: 1,
height: "100%",
}}
>
<Box
sx={{
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<MapLayer>
<CandUChooseLocation mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
</MapLayer>
</Box>
</Box>
</Stack>
);
};
export default CandUMapBox;

View File

@@ -1,65 +1,65 @@
"use client";
import { Box, Typography } from "@mui/material";
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
import {
Timeline,
TimelineConnector,
TimelineContent,
TimelineDot,
TimelineItem,
timelineItemClasses,
TimelineSeparator,
} from "@mui/lab";
const CandUCreateTimeLine = ({ tabState }) => {
return (
<Box sx={{ display: "flex", alignItems: "center" }}>
<Timeline
position="right"
sx={{
[`& .${timelineItemClasses.root}:before`]: { flex: 0, padding: 0 },
}}
>
<TimelineItem>
<TimelineSeparator>
<TimelineConnector />
<TimelineDot sx={{ backgroundColor: "#fff" }}>
<TravelExploreIcon
color={tabState === 0 ? "primary" : "error"}
sx={{ width: "1.5rem", height: "1.5rem" }}
/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent sx={{ py: "12px", px: 2 }}>
<Typography variant="h6">نقشه</Typography>
<Typography variant="caption" sx={{ color: "#606060" }}>
ثبت مختصات محل آزمایش
</Typography>
</TimelineContent>
</TimelineItem>
<TimelineItem>
<TimelineSeparator>
<TimelineConnector />
<TimelineDot sx={{ backgroundColor: "#fff" }}>
<TextSnippetIcon
color={tabState === 1 ? "primary" : "error"}
sx={{ width: "1.5rem", height: "1.5rem" }}
/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent sx={{ py: "12px", px: 2 }}>
<Typography variant="h6">مشخصات آزمایش</Typography>
<Typography variant="caption" sx={{ color: "#606060" }}>
ثبت مشخصات اولیه
</Typography>
</TimelineContent>
</TimelineItem>
</Timeline>
</Box>
);
};
export default CandUCreateTimeLine;
"use client";
import { Box, Typography } from "@mui/material";
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
import {
Timeline,
TimelineConnector,
TimelineContent,
TimelineDot,
TimelineItem,
timelineItemClasses,
TimelineSeparator,
} from "@mui/lab";
const CandUCreateTimeLine = ({ tabState }) => {
return (
<Box sx={{ display: "flex", alignItems: "center" }}>
<Timeline
position="right"
sx={{
[`& .${timelineItemClasses.root}:before`]: { flex: 0, padding: 0 },
}}
>
<TimelineItem>
<TimelineSeparator>
<TimelineConnector />
<TimelineDot sx={{ backgroundColor: "#fff" }}>
<TravelExploreIcon
color={tabState === 0 ? "primary" : "error"}
sx={{ width: "1.5rem", height: "1.5rem" }}
/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent sx={{ py: "12px", px: 2 }}>
<Typography variant="h6">نقشه</Typography>
<Typography variant="caption" sx={{ color: "#606060" }}>
ثبت مختصات محل آزمایش
</Typography>
</TimelineContent>
</TimelineItem>
<TimelineItem>
<TimelineSeparator>
<TimelineConnector />
<TimelineDot sx={{ backgroundColor: "#fff" }}>
<TextSnippetIcon
color={tabState === 1 ? "primary" : "error"}
sx={{ width: "1.5rem", height: "1.5rem" }}
/>
</TimelineDot>
<TimelineConnector />
</TimelineSeparator>
<TimelineContent sx={{ py: "12px", px: 2 }}>
<Typography variant="h6">مشخصات آزمایش</Typography>
<Typography variant="caption" sx={{ color: "#606060" }}>
ثبت مشخصات اولیه
</Typography>
</TimelineContent>
</TimelineItem>
</Timeline>
</Box>
);
};
export default CandUCreateTimeLine;

View File

@@ -1,200 +1,200 @@
"use client";
import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
import React, { useState } from "react";
import { useTheme } from "@emotion/react";
import useRequest from "@/lib/hooks/useRequest";
import { object, string } from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import moment from "jalali-moment";
import { CREATE_AZMAYESH, UPDATE_AZMAYESH } from "@/core/utils/routes";
import StyledForm from "@/core/components/StyledForm";
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import BeenhereIcon from "@mui/icons-material/Beenhere";
import CandUMapBox from "./CandUMapBox";
import CandUCreateTimeLine from "./CandUTimeLine";
import CandUGeneralInfo from "./CandUGeneralInfo";
function TabPanel(props) {
const { children, value, index } = props;
return (
<div role="tabpanel" hidden={value !== index}>
{value === index && <Box>{children}</Box>}
</div>
);
}
const validationSchema = object({
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
province_id: string().required("استان را وارد کنید!"),
contract_subitem_id: string().required("کد یکتا پروژه را وارد کنید!"),
project_name: string().required("عنوان پروژه را وارد کنید!"),
employer: string().required("کارفرما را وارد کنید!"),
consultant: string().required("مشاور را وارد کنید!"),
contractor: string().required("پیمانکار را وارد کنید!"),
applicant: string().required("متقاضی را وارد کنید!"),
work_number: string().required("شماره کار را وارد کنید!"),
request_number: string().required("شماره درخواست را وارد کنید!"),
request_date: string().required("تاریخ درخواست را وارد کنید!"),
report_date: string().required("تاریخ گزارش را وارد کنید!"),
});
const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
const theme = useTheme();
const requestServer = useRequest({ notificationSuccess: true });
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [tabState, setTabState] = useState(0);
const [mapBoxData, setMapBoxData] = useState(updateInfo ? { lat: updateInfo.lat, lng: updateInfo.lng } : null);
const handleClose = () => {
setOpen(false);
};
const handleChangeTab = (event, newValue) => {
setTabState(newValue);
};
const handlePrev = () => {
if (tabState === 0) {
handleClose();
} else {
setTabState(tabState - 1);
}
};
const defaultValues = {
azmayesh_type_id: updateInfo ? updateInfo.azmayesh_type_id : "",
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
province_id: updateInfo ? updateInfo.province_id : "",
province_name: updateInfo ? updateInfo.province_name : "",
contract_subitem_id: updateInfo ? updateInfo.contract_subitem_id : "",
project_name: updateInfo ? updateInfo.project_name : "",
employer: updateInfo ? updateInfo.employer : "",
consultant: updateInfo ? updateInfo.consultant : "",
contractor: updateInfo ? updateInfo.contractor : "",
applicant: updateInfo ? updateInfo.applicant : "",
work_number: updateInfo ? updateInfo.work_number : "",
request_number: updateInfo ? updateInfo.request_number : "",
request_date: updateInfo ? moment(updateInfo.request_date, "YYYY-MM-DD").toDate() : "",
report_date: updateInfo ? moment(updateInfo.report_date, "YYYY-MM-DD").toDate() : "",
};
const {
control,
register,
handleSubmit,
setValue,
formState: { isSubmitting, errors },
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "all" });
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("lat", mapBoxData.lat);
formData.append("lng", mapBoxData.lng);
formData.append("azmayesh_type_id", data.azmayesh_type_id);
formData.append("azmayesh_type_name", data.azmayesh_type_name);
formData.append("province_id", data.province_id);
formData.append("province_name", data.province_name);
formData.append("contract_subitem_id", data.contract_subitem_id);
formData.append("project_name", data.project_name);
formData.append("employer", data.employer);
formData.append("consultant", data.consultant);
formData.append("contractor", data.contractor);
formData.append("applicant", data.applicant);
formData.append("work_number", data.work_number);
formData.append("request_number", data.request_number);
formData.append("request_date", moment(new Date(data.request_date)).format("YYYY-MM-DD"));
formData.append("report_date", moment(new Date(data.report_date)).format("YYYY-MM-DD"));
try {
await requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
data: formData,
});
mutate();
handleClose();
} catch (error) {}
};
return (
<StyledForm onSubmit={handleSubmit(onSubmit)}>
<Tabs
allowScrollButtonsMobile
value={tabState}
onChange={handleChangeTab}
variant={`${isMobile ? "scrollable" : "fullWidth"}`}
sx={{
display: "flex",
justifyContent: "space-around",
width: "100%",
backgroundColor: "#efefef",
}}
>
<Tab icon={<TravelExploreIcon />} label="انتخاب محل آزمایش"></Tab>
<Tab disabled={!mapBoxData} icon={<TextSnippetIcon />} label="مشخصات آزمایش"></Tab>
</Tabs>
<DialogContent dividers sx={{ display: "flex" }}>
<Box sx={{ flex: 1 }}>
<TabPanel value={tabState} index={0}>
<CandUMapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
</TabPanel>
<TabPanel value={tabState} index={1}>
<CandUGeneralInfo control={control} register={register} setValue={setValue} errors={errors} />
</TabPanel>
</Box>
{!isMobile && (
<Box sx={{ display: "flex", alignItems: "center" }}>
<CandUCreateTimeLine tabState={tabState} />
</Box>
)}
</DialogContent>
<DialogActions sx={{ alignItems: "center", justifyContent: "center" }}>
<Button
onClick={handlePrev}
variant="outlined"
color="error"
size="large"
startIcon={tabState === 0 ? <ExitToAppIcon /> : <KeyboardDoubleArrowRightIcon />}
>
{tabState === 0 ? "بستن" : "مرحله قبل"}
</Button>
{tabState === 0 ? (
<Button
onClick={(event) => {
event.preventDefault();
setTabState(tabState + 1);
}}
variant="contained"
size="large"
disabled={!mapBoxData}
endIcon={<KeyboardDoubleArrowLeftIcon />}
>
مرحله بعد
</Button>
) : (
<Button
variant="contained"
size="large"
disabled={isSubmitting}
type={"submit"}
endIcon={<BeenhereIcon />}
>
{updateInfo
? isSubmitting
? "در حال ویرایش آزمایش"
: "ویرایش آزمایش"
: isSubmitting
? "در حال ثبت آزمایش"
: "ثبت آزمایش"}
</Button>
)}
</DialogActions>
</StyledForm>
);
};
export default CandUAzmayesh;
"use client";
import { Box, Button, DialogActions, DialogContent, Tab, Tabs, useMediaQuery } from "@mui/material";
import React, { useState } from "react";
import { useTheme } from "@emotion/react";
import useRequest from "@/lib/hooks/useRequest";
import { object, string } from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import moment from "jalali-moment";
import { CREATE_AZMAYESH, UPDATE_AZMAYESH } from "@/core/utils/routes";
import StyledForm from "@/core/components/StyledForm";
import TravelExploreIcon from "@mui/icons-material/TravelExplore";
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
import ExitToAppIcon from "@mui/icons-material/ExitToApp";
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import BeenhereIcon from "@mui/icons-material/Beenhere";
import CandUMapBox from "./CandUMapBox";
import CandUCreateTimeLine from "./CandUTimeLine";
import CandUGeneralInfo from "./CandUGeneralInfo";
function TabPanel(props) {
const { children, value, index } = props;
return (
<div role="tabpanel" hidden={value !== index}>
{value === index && <Box>{children}</Box>}
</div>
);
}
const validationSchema = object({
azmayesh_type_id: string().required("نوع آزمایش را مشخص کنید!"),
province_id: string().required("استان را وارد کنید!"),
contract_subitem_id: string().required("کد یکتا پروژه را وارد کنید!"),
project_name: string().required("عنوان پروژه را وارد کنید!"),
employer: string().required("کارفرما را وارد کنید!"),
consultant: string().required("مشاور را وارد کنید!"),
contractor: string().required("پیمانکار را وارد کنید!"),
applicant: string().required("متقاضی را وارد کنید!"),
work_number: string().required("شماره کار را وارد کنید!"),
request_number: string().required("شماره درخواست را وارد کنید!"),
request_date: string().required("تاریخ درخواست را وارد کنید!"),
report_date: string().required("تاریخ گزارش را وارد کنید!"),
});
const CandUAzmayesh = ({ setOpen, mutate, updateInfo, rowId }) => {
const theme = useTheme();
const requestServer = useRequest({ notificationSuccess: true });
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [tabState, setTabState] = useState(0);
const [mapBoxData, setMapBoxData] = useState(updateInfo ? { lat: updateInfo.lat, lng: updateInfo.lng } : null);
const handleClose = () => {
setOpen(false);
};
const handleChangeTab = (event, newValue) => {
setTabState(newValue);
};
const handlePrev = () => {
if (tabState === 0) {
handleClose();
} else {
setTabState(tabState - 1);
}
};
const defaultValues = {
azmayesh_type_id: updateInfo ? updateInfo.azmayesh_type_id : "",
azmayesh_type_name: updateInfo ? updateInfo.azmayesh_type_name : "",
province_id: updateInfo ? updateInfo.province_id : "",
province_name: updateInfo ? updateInfo.province_name : "",
contract_subitem_id: updateInfo ? updateInfo.contract_subitem_id : "",
project_name: updateInfo ? updateInfo.project_name : "",
employer: updateInfo ? updateInfo.employer : "",
consultant: updateInfo ? updateInfo.consultant : "",
contractor: updateInfo ? updateInfo.contractor : "",
applicant: updateInfo ? updateInfo.applicant : "",
work_number: updateInfo ? updateInfo.work_number : "",
request_number: updateInfo ? updateInfo.request_number : "",
request_date: updateInfo ? moment(updateInfo.request_date, "YYYY-MM-DD").toDate() : "",
report_date: updateInfo ? moment(updateInfo.report_date, "YYYY-MM-DD").toDate() : "",
};
const {
control,
register,
handleSubmit,
setValue,
formState: { isSubmitting, errors },
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "all" });
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("lat", mapBoxData.lat);
formData.append("lng", mapBoxData.lng);
formData.append("azmayesh_type_id", data.azmayesh_type_id);
formData.append("azmayesh_type_name", data.azmayesh_type_name);
formData.append("province_id", data.province_id);
formData.append("province_name", data.province_name);
formData.append("contract_subitem_id", data.contract_subitem_id);
formData.append("project_name", data.project_name);
formData.append("employer", data.employer);
formData.append("consultant", data.consultant);
formData.append("contractor", data.contractor);
formData.append("applicant", data.applicant);
formData.append("work_number", data.work_number);
formData.append("request_number", data.request_number);
formData.append("request_date", moment(new Date(data.request_date)).format("YYYY-MM-DD"));
formData.append("report_date", moment(new Date(data.report_date)).format("YYYY-MM-DD"));
try {
await requestServer(updateInfo ? `${UPDATE_AZMAYESH}/${rowId}` : CREATE_AZMAYESH, "post", {
data: formData,
});
mutate();
handleClose();
} catch (error) {}
};
return (
<StyledForm onSubmit={handleSubmit(onSubmit)}>
<Tabs
allowScrollButtonsMobile
value={tabState}
onChange={handleChangeTab}
variant={`${isMobile ? "scrollable" : "fullWidth"}`}
sx={{
display: "flex",
justifyContent: "space-around",
width: "100%",
backgroundColor: "#efefef",
}}
>
<Tab icon={<TravelExploreIcon />} label="انتخاب محل آزمایش"></Tab>
<Tab disabled={!mapBoxData} icon={<TextSnippetIcon />} label="مشخصات آزمایش"></Tab>
</Tabs>
<DialogContent dividers sx={{ display: "flex" }}>
<Box sx={{ flex: 1 }}>
<TabPanel value={tabState} index={0}>
<CandUMapBox mapBoxData={mapBoxData} setMapBoxData={setMapBoxData} />
</TabPanel>
<TabPanel value={tabState} index={1}>
<CandUGeneralInfo control={control} register={register} setValue={setValue} errors={errors} />
</TabPanel>
</Box>
{!isMobile && (
<Box sx={{ display: "flex", alignItems: "center" }}>
<CandUCreateTimeLine tabState={tabState} />
</Box>
)}
</DialogContent>
<DialogActions sx={{ alignItems: "center", justifyContent: "center" }}>
<Button
onClick={handlePrev}
variant="outlined"
color="error"
size="large"
startIcon={tabState === 0 ? <ExitToAppIcon /> : <KeyboardDoubleArrowRightIcon />}
>
{tabState === 0 ? "بستن" : "مرحله قبل"}
</Button>
{tabState === 0 ? (
<Button
onClick={(event) => {
event.preventDefault();
setTabState(tabState + 1);
}}
variant="contained"
size="large"
disabled={!mapBoxData}
endIcon={<KeyboardDoubleArrowLeftIcon />}
>
مرحله بعد
</Button>
) : (
<Button
variant="contained"
size="large"
disabled={isSubmitting}
type={"submit"}
endIcon={<BeenhereIcon />}
>
{updateInfo
? isSubmitting
? "در حال ویرایش آزمایش"
: "ویرایش آزمایش"
: isSubmitting
? "در حال ثبت آزمایش"
: "ثبت آزمایش"}
</Button>
)}
</DialogActions>
</StyledForm>
);
};
export default CandUAzmayesh;

View File

@@ -1,38 +1,38 @@
"use client";
import { Dialog, IconButton } from "@mui/material";
import FormAndRequest from "./FormAndRequest";
import DialogLoading from "@/core/components/DialogLoading";
import CloseIcon from "@mui/icons-material/Close";
const CandUAzmayesh = ({ open, setOpen, mutate, updateInfo, rowId, loadingOpen, fromUpdate = false }) => {
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
return (
<Dialog open={open} fullWidth maxWidth="lg">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{isUpdateReady ? (
<FormAndRequest
setOpen={setOpen}
mutate={mutate}
rowId={rowId}
{...(fromUpdate ? { updateInfo } : {})}
/>
) : (
<DialogLoading loadingOpen={loadingOpen} />
)}
</Dialog>
);
};
export default CandUAzmayesh;
"use client";
import { Dialog, IconButton } from "@mui/material";
import FormAndRequest from "./FormAndRequest";
import DialogLoading from "@/core/components/DialogLoading";
import CloseIcon from "@mui/icons-material/Close";
const CandUAzmayesh = ({ open, setOpen, mutate, updateInfo, rowId, loadingOpen, fromUpdate = false }) => {
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
return (
<Dialog open={open} fullWidth maxWidth="lg">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{isUpdateReady ? (
<FormAndRequest
setOpen={setOpen}
mutate={mutate}
rowId={rowId}
{...(fromUpdate ? { updateInfo } : {})}
/>
) : (
<DialogLoading loadingOpen={loadingOpen} />
)}
</Dialog>
);
};
export default CandUAzmayesh;

View File

@@ -1,52 +1,52 @@
import { IconButton, Tooltip } from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import EditIcon from "@mui/icons-material/Edit";
import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
const AzmayeshUpdate = ({ rowId, mutate }) => {
const requestServer = useRequest();
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [loadingOpen, setLoadingOpen] = useState(false);
const handleGetInfo = () => {
setLoadingOpen(true);
setOpenUpdateDialog(true);
requestServer(`${GET_AZMAYESH_LIST}/${rowId}`, "get")
.then((response) => {
setUpdateInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setLoadingOpen(false);
});
};
return (
<>
<Tooltip title="ویرایش آزمایش" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetInfo}
>
<EditIcon />
</IconButton>
</Tooltip>
{openUpdateDialog && (
<CandUAzmayesh
open={openUpdateDialog}
setOpen={setOpenUpdateDialog}
mutate={mutate}
updateInfo={updateInfo}
rowId={rowId}
loadingOpen={loadingOpen}
fromUpdate={true}
/>
)}
</>
);
};
export default AzmayeshUpdate;
import { IconButton, Tooltip } from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import EditIcon from "@mui/icons-material/Edit";
import { GET_AZMAYESH_LIST } from "@/core/utils/routes";
import CandUAzmayesh from "@/components/dashboard/azmayesh/Forms/CandUAzmayesh";
const AzmayeshUpdate = ({ rowId, mutate }) => {
const requestServer = useRequest();
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [loadingOpen, setLoadingOpen] = useState(false);
const handleGetInfo = () => {
setLoadingOpen(true);
setOpenUpdateDialog(true);
requestServer(`${GET_AZMAYESH_LIST}/${rowId}`, "get")
.then((response) => {
setUpdateInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setLoadingOpen(false);
});
};
return (
<>
<Tooltip title="ویرایش آزمایش" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetInfo}
>
<EditIcon />
</IconButton>
</Tooltip>
{openUpdateDialog && (
<CandUAzmayesh
open={openUpdateDialog}
setOpen={setOpenUpdateDialog}
mutate={mutate}
updateInfo={updateInfo}
rowId={rowId}
loadingOpen={loadingOpen}
fromUpdate={true}
/>
)}
</>
);
};
export default AzmayeshUpdate;

View File

@@ -1,78 +1,78 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import DeleteIcon from "@mui/icons-material/Delete";
import { DELETE_AZMAYESH } from "@/core/utils/routes";
const DeleteAzmayesh = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_AZMAYESH}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف آزمایش" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف آزمایش</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این آزمایش مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteAzmayesh;
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import DeleteIcon from "@mui/icons-material/Delete";
import { DELETE_AZMAYESH } from "@/core/utils/routes";
const DeleteAzmayesh = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_AZMAYESH}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف آزمایش" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف آزمایش</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این آزمایش مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteAzmayesh;

View File

@@ -1,59 +1,59 @@
import { Button, IconButton, useMediaQuery } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import { useEffect, useState } from "react";
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
import { AddCircle } from "@mui/icons-material";
import { useTheme } from "@emotion/react";
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
const AddSampleToAzmayesh = ({ azmayeshTypeId, mutate, rowId }) => {
const requestServer = useRequest();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [sampleInfo, setSampleInfo] = useState(null);
const [openAddSampleDialog, setOpenAddSampleDialog] = useState(false);
const [defaultValues, setDefaultValues] = useState({});
const handleGetFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setOpenAddSampleDialog(true);
});
};
useEffect(() => {
const initialValues = sampleInfo?.reduce((acc, item) => {
acc[item.id] = "";
return acc;
}, {});
setDefaultValues(initialValues);
}, [sampleInfo]);
return (
<>
{isMobile ? (
<IconButton aria-label="ایجاد نمونه جدید" color="primary" onClick={handleGetFields}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleGetFields}>
ثبت نمونه
</Button>
)}
<CandUSampleOfAzmayesh
openSampleDialog={openAddSampleDialog}
setOpenSampleDialog={setOpenAddSampleDialog}
sampleInfo={sampleInfo}
mutate={mutate}
rowId={rowId}
defaultValues={defaultValues}
setDefaultValues={setDefaultValues}
/>
</>
);
};
export default AddSampleToAzmayesh;
import { Button, IconButton, useMediaQuery } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import { useEffect, useState } from "react";
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
import { AddCircle } from "@mui/icons-material";
import { useTheme } from "@emotion/react";
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
const AddSampleToAzmayesh = ({ azmayeshTypeId, mutate, rowId }) => {
const requestServer = useRequest();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [sampleInfo, setSampleInfo] = useState(null);
const [openAddSampleDialog, setOpenAddSampleDialog] = useState(false);
const [defaultValues, setDefaultValues] = useState({});
const handleGetFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setOpenAddSampleDialog(true);
});
};
useEffect(() => {
const initialValues = sampleInfo?.reduce((acc, item) => {
acc[item.id] = "";
return acc;
}, {});
setDefaultValues(initialValues);
}, [sampleInfo]);
return (
<>
{isMobile ? (
<IconButton aria-label="ایجاد نمونه جدید" color="primary" onClick={handleGetFields}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleGetFields}>
ثبت نمونه
</Button>
)}
<CandUSampleOfAzmayesh
openSampleDialog={openAddSampleDialog}
setOpenSampleDialog={setOpenAddSampleDialog}
sampleInfo={sampleInfo}
mutate={mutate}
rowId={rowId}
defaultValues={defaultValues}
setDefaultValues={setDefaultValues}
/>
</>
);
};
export default AddSampleToAzmayesh;

View File

@@ -1,82 +1,82 @@
"use client";
import { Box, Chip, Divider, Grid, Stack, Typography } from "@mui/material";
import ScienceIcon from "@mui/icons-material/Science";
import LocationCityIcon from "@mui/icons-material/LocationCity";
const AzmayeshInfo = ({ rowData }) => {
return (
<Stack sx={{ p: 2, alignItems: "center" }}>
<Typography variant="body1" sx={{ fontWeight: 600, pb: 4 }}>
{rowData.project_name}
</Typography>
<Grid container spacing={2} sx={{ alignItems: "center", justifyContent: "space-around" }}>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<ScienceIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
نوع آزمایش
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.azmayesh_type_name}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
نام استان
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.province_name}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
شماره کار
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.work_number}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
شماره درخواست
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.request_number}
</Typography>
</Grid>
</Grid>
</Stack>
);
};
export default AzmayeshInfo;
"use client";
import { Box, Chip, Divider, Grid, Stack, Typography } from "@mui/material";
import ScienceIcon from "@mui/icons-material/Science";
import LocationCityIcon from "@mui/icons-material/LocationCity";
const AzmayeshInfo = ({ rowData }) => {
return (
<Stack sx={{ p: 2, alignItems: "center" }}>
<Typography variant="body1" sx={{ fontWeight: 600, pb: 4 }}>
{rowData.project_name}
</Typography>
<Grid container spacing={2} sx={{ alignItems: "center", justifyContent: "space-around" }}>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<ScienceIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
نوع آزمایش
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.azmayesh_type_name}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
نام استان
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.province_name}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
شماره کار
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.work_number}
</Typography>
</Grid>
<Grid item xs={12} sm={6} sx={{ display: "flex", alignItems: "center" }}>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Chip
icon={<LocationCityIcon />}
label={
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.700" }}>
شماره درخواست
</Typography>
}
/>
</Box>
<Divider sx={{ flex: 1, mx: 2 }} />
<Typography variant="body2" sx={{ fontWeight: 600, color: "grey.800" }}>
{rowData.request_number}
</Typography>
</Grid>
</Grid>
</Stack>
);
};
export default AzmayeshInfo;

View File

@@ -1,76 +1,76 @@
import { Button, DialogActions, DialogContent, DialogTitle } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import React, { useState } from "react";
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
import FormMaker from "@/core/components/FormMaker";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const CandUSampleOfAzmayesh = ({
sampleInfo,
mutate,
rowId,
setOpenSampleDialog,
defaultValues,
setDefaultValues,
isUpdate,
azmayesh_id,
}) => {
const requestServer = useRequest({ notificationSuccess: true });
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async () => {
const data = {};
setIsSubmitting(true);
const formData = new FormData();
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
Object.entries(defaultValues).forEach(([key, value]) => {
data[key] = value;
});
formData.append("data", JSON.stringify(data));
try {
await requestServer(
isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`,
"post",
{
data: formData,
}
);
mutate();
setOpenSampleDialog(false);
setIsSubmitting(false);
} catch (error) {
setIsSubmitting(false);
}
};
return (
<>
<DialogHeader>
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
</DialogHeader>
<DialogContent>
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenSampleDialog(false)}
variant="outlined"
color="error"
disabled={isSubmitting}
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
{isUpdate
? isSubmitting
? "در حال ویرایش نمونه"
: "ویرایش نمونه"
: isSubmitting
? "در حال ثبت نمونه"
: "ثبت نمونه"}
</Button>
</DialogActions>
</>
);
};
export default CandUSampleOfAzmayesh;
import { Button, DialogActions, DialogContent, DialogTitle } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import React, { useState } from "react";
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
import FormMaker from "@/core/components/FormMaker";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const CandUSampleOfAzmayesh = ({
sampleInfo,
mutate,
rowId,
setOpenSampleDialog,
defaultValues,
setDefaultValues,
isUpdate,
azmayesh_id,
}) => {
const requestServer = useRequest({ notificationSuccess: true });
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async () => {
const data = {};
setIsSubmitting(true);
const formData = new FormData();
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
Object.entries(defaultValues).forEach(([key, value]) => {
data[key] = value;
});
formData.append("data", JSON.stringify(data));
try {
await requestServer(
isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`,
"post",
{
data: formData,
}
);
mutate();
setOpenSampleDialog(false);
setIsSubmitting(false);
} catch (error) {
setIsSubmitting(false);
}
};
return (
<>
<DialogHeader>
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
</DialogHeader>
<DialogContent>
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenSampleDialog(false)}
variant="outlined"
color="error"
disabled={isSubmitting}
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
{isUpdate
? isSubmitting
? "در حال ویرایش نمونه"
: "ویرایش نمونه"
: isSubmitting
? "در حال ثبت نمونه"
: "ثبت نمونه"}
</Button>
</DialogActions>
</>
);
};
export default CandUSampleOfAzmayesh;

View File

@@ -1,74 +1,74 @@
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import React, { useState } from "react";
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
import FormMaker from "@/core/components/FormMaker";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const CandUSampleOfAzmayesh = ({
sampleInfo,
mutate,
rowId,
openSampleDialog,
setOpenSampleDialog,
defaultValues,
setDefaultValues,
isUpdate,
azmayesh_id,
}) => {
const requestServer = useRequest({ notificationSuccess: true });
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
const data = {};
setIsSubmitting(true);
const formData = new FormData();
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
Object.entries(defaultValues).forEach(([key, value]) => {
data[key] = value;
});
formData.append("data", JSON.stringify(data));
requestServer(isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`, "post", {
data: formData,
})
.then(() => {
mutate();
})
.catch(() => {})
.finally(() => {
setOpenSampleDialog(false);
setIsSubmitting(false);
});
};
return (
<Dialog maxWidth="md" fullWidth open={openSampleDialog}>
<DialogHeader>
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
</DialogHeader>
<DialogContent>
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenSampleDialog(false)}
variant="outlined"
color="error"
disabled={isSubmitting}
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
{isUpdate
? isSubmitting
? "در حال ویرایش نمونه"
: "ویرایش نمونه"
: isSubmitting
? "در حال ثبت نمونه"
: "ثبت نمونه"}
</Button>
</DialogActions>
</Dialog>
);
};
export default CandUSampleOfAzmayesh;
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import React, { useState } from "react";
import { ADD_SAMPLE_TO_AZMAYESH, UPDATE_SAMPLE_OF_AZMAYESH } from "@/core/utils/routes";
import FormMaker from "@/core/components/FormMaker";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const CandUSampleOfAzmayesh = ({
sampleInfo,
mutate,
rowId,
openSampleDialog,
setOpenSampleDialog,
defaultValues,
setDefaultValues,
isUpdate,
azmayesh_id,
}) => {
const requestServer = useRequest({ notificationSuccess: true });
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
const data = {};
setIsSubmitting(true);
const formData = new FormData();
formData.append("azmayesh_id", isUpdate ? azmayesh_id : rowId);
Object.entries(defaultValues).forEach(([key, value]) => {
data[key] = value;
});
formData.append("data", JSON.stringify(data));
requestServer(isUpdate ? `${UPDATE_SAMPLE_OF_AZMAYESH}/${rowId}` : `${ADD_SAMPLE_TO_AZMAYESH}`, "post", {
data: formData,
})
.then(() => {
mutate();
})
.catch(() => {})
.finally(() => {
setOpenSampleDialog(false);
setIsSubmitting(false);
});
};
return (
<Dialog maxWidth="md" fullWidth open={openSampleDialog}>
<DialogHeader>
<DialogTitle>{isUpdate ? "ویرایش نمونه" : "افزودن نمونه"}</DialogTitle>
</DialogHeader>
<DialogContent>
<FormMaker formInfo={sampleInfo} defaultValues={defaultValues} setDefaultValues={setDefaultValues} />
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenSampleDialog(false)}
variant="outlined"
color="error"
disabled={isSubmitting}
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="primary" disabled={isSubmitting}>
{isUpdate
? isSubmitting
? "در حال ویرایش نمونه"
: "ویرایش نمونه"
: isSubmitting
? "در حال ثبت نمونه"
: "ثبت نمونه"}
</Button>
</DialogActions>
</Dialog>
);
};
export default CandUSampleOfAzmayesh;

View File

@@ -1,78 +1,78 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import DeleteIcon from "@mui/icons-material/Delete";
import { DELETE_SAMPLE_LIST } from "@/core/utils/routes";
const DeleteSample = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_SAMPLE_LIST}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف نمونه" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف نمونه</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این نمونه مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteSample;
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import DeleteIcon from "@mui/icons-material/Delete";
import { DELETE_SAMPLE_LIST } from "@/core/utils/routes";
const DeleteSample = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_SAMPLE_LIST}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف نمونه" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف نمونه</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این نمونه مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteSample;

View File

@@ -1,60 +1,60 @@
import { IconButton, Tooltip } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import { useEffect, useState } from "react";
import { GET_AZMAYESH_SAMPLE_FIELDS, GET_SAMPLE_LIST } from "@/core/utils/routes";
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
import EditIcon from "@mui/icons-material/Edit";
const UpdateSample = ({ azmayeshTypeId, mutate, rowId, azmayesh_id }) => {
const requestServer = useRequest();
const [sampleInfo, setSampleInfo] = useState(null);
const [openUpdateSampleDialog, setOpenUpdateSampleDialog] = useState(false);
const [defaultValues, setDefaultValues] = useState({});
const [sampleDetail, setSampleDetail] = useState({});
const handleGetFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {});
requestServer(`${GET_SAMPLE_LIST}/${rowId}`, "get")
.then((response) => {
setSampleDetail(JSON.parse(response.data.data.data));
})
.catch(() => {})
.finally(() => {
setOpenUpdateSampleDialog(true);
});
};
useEffect(() => {
setDefaultValues(sampleDetail);
}, [sampleDetail]);
return (
<>
<Tooltip title="ویرایش نمونه" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetFields}
>
<EditIcon />
</IconButton>
</Tooltip>
<CandUSampleOfAzmayesh
openSampleDialog={openUpdateSampleDialog}
setOpenSampleDialog={setOpenUpdateSampleDialog}
sampleInfo={sampleInfo}
mutate={mutate}
rowId={rowId}
defaultValues={defaultValues}
setDefaultValues={setDefaultValues}
isUpdate={true}
azmayesh_id={azmayesh_id}
/>
</>
);
};
export default UpdateSample;
import { IconButton, Tooltip } from "@mui/material";
import useRequest from "@/lib/hooks/useRequest";
import { useEffect, useState } from "react";
import { GET_AZMAYESH_SAMPLE_FIELDS, GET_SAMPLE_LIST } from "@/core/utils/routes";
import CandUSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/Forms/CandUSampleOfAzmayesh";
import EditIcon from "@mui/icons-material/Edit";
const UpdateSample = ({ azmayeshTypeId, mutate, rowId, azmayesh_id }) => {
const requestServer = useRequest();
const [sampleInfo, setSampleInfo] = useState(null);
const [openUpdateSampleDialog, setOpenUpdateSampleDialog] = useState(false);
const [defaultValues, setDefaultValues] = useState({});
const [sampleDetail, setSampleDetail] = useState({});
const handleGetFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${azmayeshTypeId}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {});
requestServer(`${GET_SAMPLE_LIST}/${rowId}`, "get")
.then((response) => {
setSampleDetail(JSON.parse(response.data.data.data));
})
.catch(() => {})
.finally(() => {
setOpenUpdateSampleDialog(true);
});
};
useEffect(() => {
setDefaultValues(sampleDetail);
}, [sampleDetail]);
return (
<>
<Tooltip title="ویرایش نمونه" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetFields}
>
<EditIcon />
</IconButton>
</Tooltip>
<CandUSampleOfAzmayesh
openSampleDialog={openUpdateSampleDialog}
setOpenSampleDialog={setOpenUpdateSampleDialog}
sampleInfo={sampleInfo}
mutate={mutate}
rowId={rowId}
defaultValues={defaultValues}
setDefaultValues={setDefaultValues}
isUpdate={true}
azmayesh_id={azmayesh_id}
/>
</>
);
};
export default UpdateSample;

View File

@@ -1,18 +1,18 @@
import { Box } from "@mui/material";
import DeleteSample from "./DeleteSample";
import UpdateSample from "./UpdateSample";
const RowActions = ({ rowData, row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<UpdateSample
mutate={mutate}
rowId={row.getValue("id")}
azmayeshTypeId={rowData.azmayesh_type_id}
azmayesh_id={rowData.id}
/>
<DeleteSample mutate={mutate} rowId={row.getValue("id")} />
</Box>
);
};
export default RowActions;
import { Box } from "@mui/material";
import DeleteSample from "./DeleteSample";
import UpdateSample from "./UpdateSample";
const RowActions = ({ rowData, row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<UpdateSample
mutate={mutate}
rowId={row.getValue("id")}
azmayeshTypeId={rowData.azmayesh_type_id}
azmayesh_id={rowData.id}
/>
<DeleteSample mutate={mutate} rowId={row.getValue("id")} />
</Box>
);
};
export default RowActions;

View File

@@ -1,80 +1,80 @@
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import { GET_SAMPLE_LIST } from "@/core/utils/routes";
import RowActions from "./RowActions";
import AzmayeshInfo from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/AzmayeshInfo";
import Toolbar from "./Toolbar";
import moment from "jalali-moment";
const ShowSampleList = ({ sampleInfo, rowData }) => {
const parsedData = (data) => {
return data.data.map((item) => ({
...JSON.parse(item.data),
id: item.id,
updated_at: item.updated_at,
}));
};
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
grow: false,
size: 100,
},
...sampleInfo.map((item) => ({
accessorKey: item.id.toString(),
header: item.unit ? `${item.name} (${item.unit})` : item.name,
id: item.id.toString(),
enableColumnFilter: false,
datatype: "text",
})),
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
],
[sampleInfo]
);
const ToolbarWithRowData = (props) => <Toolbar rowData={rowData} {...props} />;
const RowActionsWithRowData = (props) => <RowActions rowData={rowData} {...props} />;
return (
<Box>
<AzmayeshInfo rowData={rowData} />
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"نمونه های ثبت شده"}
need_filter={false}
columns={columns}
table_url={`${GET_SAMPLE_LIST}/index/${rowData.id}`}
page_name={`azmayesh_${rowData.azmayesh_type_id}`}
table_name={"sample_list"}
TableToolbar={ToolbarWithRowData}
specific_data={parsedData}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActionsWithRowData}
/>
</Box>
</Box>
);
};
export default ShowSampleList;
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import { GET_SAMPLE_LIST } from "@/core/utils/routes";
import RowActions from "./RowActions";
import AzmayeshInfo from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh/AzmayeshInfo";
import Toolbar from "./Toolbar";
import moment from "jalali-moment";
const ShowSampleList = ({ sampleInfo, rowData }) => {
const parsedData = (data) => {
return data.data.map((item) => ({
...JSON.parse(item.data),
id: item.id,
updated_at: item.updated_at,
}));
};
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
grow: false,
size: 100,
},
...sampleInfo.map((item) => ({
accessorKey: item.id.toString(),
header: item.unit ? `${item.name} (${item.unit})` : item.name,
id: item.id.toString(),
enableColumnFilter: false,
datatype: "text",
})),
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
],
[sampleInfo]
);
const ToolbarWithRowData = (props) => <Toolbar rowData={rowData} {...props} />;
const RowActionsWithRowData = (props) => <RowActions rowData={rowData} {...props} />;
return (
<Box>
<AzmayeshInfo rowData={rowData} />
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"نمونه های ثبت شده"}
need_filter={false}
columns={columns}
table_url={`${GET_SAMPLE_LIST}/index/${rowData.id}`}
page_name={`azmayesh_${rowData.azmayesh_type_id}`}
table_name={"sample_list"}
TableToolbar={ToolbarWithRowData}
specific_data={parsedData}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActionsWithRowData}
/>
</Box>
</Box>
);
};
export default ShowSampleList;

View File

@@ -1,10 +1,10 @@
import AddSampleToAzmayesh from "./Actions/Create";
const Toolbar = ({ mutate, rowData }) => {
return (
<>
<AddSampleToAzmayesh mutate={mutate} azmayeshTypeId={rowData.azmayesh_type_id} rowId={rowData.id} />
</>
);
};
export default Toolbar;
import AddSampleToAzmayesh from "./Actions/Create";
const Toolbar = ({ mutate, rowData }) => {
return (
<>
<AddSampleToAzmayesh mutate={mutate} azmayeshTypeId={rowData.azmayesh_type_id} rowId={rowData.id} />
</>
);
};
export default Toolbar;

View File

@@ -1,46 +1,46 @@
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material";
import AssignmentIcon from "@mui/icons-material/Assignment";
import { useState } from "react";
import ShowSampleList from "./ShowSampleList";
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
const ShowSampleOfAzmayesh = ({ rowData }) => {
const requestServer = useRequest();
const [openShowSampleDialog, setOpenShowSampleDialog] = useState(false);
const [sampleInfo, setSampleInfo] = useState(null);
const handleGetSampleFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${rowData.azmayesh_type_id}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setOpenShowSampleDialog(true);
});
};
return (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<Tooltip title="نمایش نمونه های آزمایش" arrow placement="right">
<IconButton
color="primary"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetSampleFields}
>
<AssignmentIcon />
</IconButton>
</Tooltip>
<Dialog maxWidth="lg" fullWidth open={openShowSampleDialog}>
<DialogContent>
<ShowSampleList rowData={rowData} sampleInfo={sampleInfo} />
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenShowSampleDialog(false)} variant="outlined" color="error">
بستن
</Button>
</DialogActions>
</Dialog>
</Box>
);
};
export default ShowSampleOfAzmayesh;
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton, Tooltip } from "@mui/material";
import AssignmentIcon from "@mui/icons-material/Assignment";
import { useState } from "react";
import ShowSampleList from "./ShowSampleList";
import { GET_AZMAYESH_SAMPLE_FIELDS } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
const ShowSampleOfAzmayesh = ({ rowData }) => {
const requestServer = useRequest();
const [openShowSampleDialog, setOpenShowSampleDialog] = useState(false);
const [sampleInfo, setSampleInfo] = useState(null);
const handleGetSampleFields = () => {
requestServer(`${GET_AZMAYESH_SAMPLE_FIELDS}/${rowData.azmayesh_type_id}`, "get")
.then((response) => {
setSampleInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setOpenShowSampleDialog(true);
});
};
return (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<Tooltip title="نمایش نمونه های آزمایش" arrow placement="right">
<IconButton
color="primary"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetSampleFields}
>
<AssignmentIcon />
</IconButton>
</Tooltip>
<Dialog maxWidth="lg" fullWidth open={openShowSampleDialog}>
<DialogContent>
<ShowSampleList rowData={rowData} sampleInfo={sampleInfo} />
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenShowSampleDialog(false)} variant="outlined" color="error">
بستن
</Button>
</DialogActions>
</Dialog>
</Box>
);
};
export default ShowSampleOfAzmayesh;

View File

@@ -1,14 +1,14 @@
import { Box } from "@mui/material";
import DeleteAzmayesh from "./DeleteAzmayesh";
import ShowSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh";
import AzmayeshUpdate from "@/components/dashboard/azmayesh/RowActions/AzmayeshUpdate";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<AzmayeshUpdate mutate={mutate} rowId={row.getValue("id")} />
<DeleteAzmayesh mutate={mutate} rowId={row.getValue("id")} />
</Box>
);
};
export default RowActions;
import { Box } from "@mui/material";
import DeleteAzmayesh from "./DeleteAzmayesh";
import ShowSampleOfAzmayesh from "@/components/dashboard/azmayesh/RowActions/ShowSampleOfAzmayesh";
import AzmayeshUpdate from "@/components/dashboard/azmayesh/RowActions/AzmayeshUpdate";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<AzmayeshUpdate mutate={mutate} rowId={row.getValue("id")} />
<DeleteAzmayesh mutate={mutate} rowId={row.getValue("id")} />
</Box>
);
};
export default RowActions;

View File

@@ -1,52 +1,52 @@
"use client";
import ExploreIcon from "@mui/icons-material/Explore";
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton } from "@mui/material";
import { useState } from "react";
import dynamic from "next/dynamic";
import MapLoading from "@/core/components/MapLayer/Loading";
import ShowLocationMarker from "@/core/components/ShowLocationMarker";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => <MapLoading />,
ssr: false,
});
const ShowLocation = ({ lat, lng }) => {
const [openShowLocationModal, setOpenShowLocationModal] = useState(false);
const handleOpenShowLocationModal = () => {
setOpenShowLocationModal(true);
};
const handleCloseShowLocationModal = () => {
setOpenShowLocationModal(false);
};
return (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<IconButton onClick={handleOpenShowLocationModal} size="small" color="primary">
<ExploreIcon />
</IconButton>
<Dialog
open={openShowLocationModal}
onClose={handleCloseShowLocationModal}
aria-labelledby="responsive-dialog-title"
>
<DialogContent>
<Box sx={{ width: "400px", height: "400px" }}>
<MapLayer>
<ShowLocationMarker start_lat={lat} start_lng={lng} />
</MapLayer>
</Box>
</DialogContent>
<DialogActions>
<Button color="error" variant="outlined" onClick={handleCloseShowLocationModal}>
بستن
</Button>
</DialogActions>
</Dialog>
</Box>
);
};
export default ShowLocation;
"use client";
import ExploreIcon from "@mui/icons-material/Explore";
import { Box, Button, Dialog, DialogActions, DialogContent, IconButton } from "@mui/material";
import { useState } from "react";
import dynamic from "next/dynamic";
import MapLoading from "@/core/components/MapLayer/Loading";
import ShowLocationMarker from "@/core/components/ShowLocationMarker";
const MapLayer = dynamic(() => import("@/core/components/MapLayer"), {
loading: () => <MapLoading />,
ssr: false,
});
const ShowLocation = ({ lat, lng }) => {
const [openShowLocationModal, setOpenShowLocationModal] = useState(false);
const handleOpenShowLocationModal = () => {
setOpenShowLocationModal(true);
};
const handleCloseShowLocationModal = () => {
setOpenShowLocationModal(false);
};
return (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<IconButton onClick={handleOpenShowLocationModal} size="small" color="primary">
<ExploreIcon />
</IconButton>
<Dialog
open={openShowLocationModal}
onClose={handleCloseShowLocationModal}
aria-labelledby="responsive-dialog-title"
>
<DialogContent>
<Box sx={{ width: "400px", height: "400px" }}>
<MapLayer>
<ShowLocationMarker start_lat={lat} start_lng={lng} />
</MapLayer>
</Box>
</DialogContent>
<DialogActions>
<Button color="error" variant="outlined" onClick={handleCloseShowLocationModal}>
بستن
</Button>
</DialogActions>
</Dialog>
</Box>
);
};
export default ShowLocation;

View File

@@ -1,10 +1,10 @@
import AzmayeshCreate from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<AzmayeshCreate mutate={mutate} />
</>
);
};
export default Toolbar;
import AzmayeshCreate from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<AzmayeshCreate mutate={mutate} />
</>
);
};
export default Toolbar;

View File

@@ -1,15 +1,15 @@
"use client";
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import AzmayeshList from "./AzmayeshList";
const AzmayeshPage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"کارتابل آزمایشات (OPTS)"} />
<AzmayeshList />
</Stack>
);
};
export default AzmayeshPage;
"use client";
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import AzmayeshList from "./AzmayeshList";
const AzmayeshPage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"کارتابل آزمایشات (OPTS)"} />
<AzmayeshList />
</Stack>
);
};
export default AzmayeshPage;

View File

@@ -1,33 +1,33 @@
"use client";
import { Button, IconButton, useMediaQuery } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { AddCircle } from "@mui/icons-material";
import CandUAzmayeshType from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType";
const AzmayeshTypeCreate = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="ثبت نوع آزمایش جدید" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleOpen}>
ثبت نوع آزمایش
</Button>
)}
{open && <CandUAzmayeshType open={open} setOpen={setOpen} mutate={mutate} />}
</>
);
};
export default AzmayeshTypeCreate;
"use client";
import { Button, IconButton, useMediaQuery } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { AddCircle } from "@mui/icons-material";
import CandUAzmayeshType from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType";
const AzmayeshTypeCreate = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="ثبت نوع آزمایش جدید" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button variant="contained" color="primary" startIcon={<AddCircle />} onClick={handleOpen}>
ثبت نوع آزمایش
</Button>
)}
{open && <CandUAzmayeshType open={open} setOpen={setOpen} mutate={mutate} />}
</>
);
};
export default AzmayeshTypeCreate;

View File

@@ -1,65 +1,65 @@
"use client";
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import Toolbar from "./Toolbar";
import { GET_AZMAYESH_TYPE_LIST_TABLE } from "@/core/utils/routes";
import moment from "jalali-moment";
import RowActions from "./RowActions";
const AzmayeshTypeList = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "name",
header: "عنوان",
id: "name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
],
[]
);
return (
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"لیست انواع آزمایشات"}
need_filter={false}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_AZMAYESH_TYPE_LIST_TABLE}
page_name={"azmayeshType"}
table_name={"azmayeshTypeList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
);
};
export default AzmayeshTypeList;
"use client";
import { useMemo } from "react";
import { Box, Typography } from "@mui/material";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import Toolbar from "./Toolbar";
import { GET_AZMAYESH_TYPE_LIST_TABLE } from "@/core/utils/routes";
import moment from "jalali-moment";
import RowActions from "./RowActions";
const AzmayeshTypeList = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "name",
header: "عنوان",
id: "name",
enableColumnFilter: false,
datatype: "text",
filterMode: "notEquals",
},
{
accessorKey: "updated_at",
header: "تاریخ بروزرسانی",
id: "updated_at",
enableColumnFilter: false,
datatype: "date",
filterMode: "equals",
Cell: ({ renderedCellValue }) => (
<Typography variant="body2">
{renderedCellValue ? moment(renderedCellValue).locale("fa").format("HH:mm | YYYY/MM/DD") : "-"}
</Typography>
),
},
],
[]
);
return (
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
table_title={"لیست انواع آزمایشات"}
need_filter={false}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_AZMAYESH_TYPE_LIST_TABLE}
page_name={"azmayeshType"}
table_name={"azmayeshTypeList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
);
};
export default AzmayeshTypeList;

View File

@@ -1,181 +1,181 @@
"use client";
import React, { useEffect, useState } from "react";
import {
Button,
Chip,
FormControl,
FormHelperText,
Grid,
InputAdornment,
InputLabel,
MenuItem,
OutlinedInput,
Select,
Typography,
} from "@mui/material";
import ExtensionIcon from "@mui/icons-material/Extension";
import SelectItemBox from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType/SelectItemBox";
import KeyboardIcon from "@mui/icons-material/Keyboard";
import TextFieldsIcon from "@mui/icons-material/TextFields";
import ViewListIcon from "@mui/icons-material/ViewList";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
const fieldTypeList = [
{ value: "input", label: "متن", icon: <TextFieldsIcon /> },
{ value: "select", label: "انتخابی", icon: <ViewListIcon /> },
{ value: "date", label: "تاریخ", icon: <CalendarMonthIcon /> },
];
const AzmayeshFields = ({ errors, selectedListItem, register, setValue, fields, watch }) => {
const watchedFields = watch("fields");
const [isSelectType, setIsSelectType] = useState(false);
const [openSelectItem, setOpenSelectItem] = useState(false);
const [typeIcon, setTypeIcon] = useState(<KeyboardIcon />);
useEffect(() => {
const selectedIcon = fieldTypeList.find((option) => option.value === watchedFields?.[selectedListItem]?.type)
?.icon || <KeyboardIcon />;
setTypeIcon(selectedIcon);
setIsSelectType(watchedFields[selectedListItem]?.type === "select");
}, [watchedFields, selectedListItem]);
return (
<Grid container>
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.type}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields.${selectedListItem}.type`}>نوع</InputLabel>
<Select
id={`fields.${selectedListItem}.type`}
label="نوع"
autoComplete="off"
{...register(`fields.${selectedListItem}.type`)}
size="small"
fullWidth
value={watchedFields?.[selectedListItem]?.type || ""}
onChange={(event) => {
const selectedValue = event.target.value;
const selectedIcon = fieldTypeList.find((option) => option.value === selectedValue)
?.icon || <KeyboardIcon />;
setValue(`fields.${selectedListItem}.type`, selectedValue);
setIsSelectType(selectedValue === "select");
setTypeIcon(selectedIcon);
}}
startAdornment={<InputAdornment position="start">{typeIcon}</InputAdornment>}
>
<MenuItem value="">نوع</MenuItem>
{fieldTypeList.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</Select>
<FormHelperText>{errors.fields?.[selectedListItem]?.type?.message}</FormHelperText>
</FormControl>
</Grid>
{isSelectType && (
<Grid
xs={12}
sm={6}
sx={{
px: { xs: 0, sm: 1 },
py: 1,
mb: 0.5,
display: "flex",
flexDirection: "column",
alignItems: "start",
justifyContent: "space-around",
position: "relative",
}}
>
<Chip
sx={{
position: "absolute",
top: "-6px",
right: "-6px",
zIndex: "1",
}}
color="error"
label={watchedFields?.[selectedListItem].options.length}
/>
<Button
variant="outlined"
color="success"
sx={{ width: "100%", height: "37px" }}
startIcon={<ExtensionIcon />}
onClick={() => setOpenSelectItem(true)}
>
افزودن آیتم نوع انتخابی
</Button>
<Typography variant="caption" color="error">
{errors.fields?.[selectedListItem]?.options?.message}
</Typography>
{openSelectItem && (
<SelectItemBox
open={openSelectItem}
setOpen={setOpenSelectItem}
fields={fields}
setValue={setValue}
index={selectedListItem}
watch={watch}
/>
)}
</Grid>
)}
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.name}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields[${selectedListItem}].name`}>نام فیلد</InputLabel>
<OutlinedInput
id={`fields[${selectedListItem}].name`}
label="نام فیلد"
autoComplete="off"
{...register(`fields[${selectedListItem}].name`)}
value={watchedFields?.[selectedListItem]?.name || ""}
onInput={(event) => setValue(`fields.${selectedListItem}.name`, event.target.value)}
size="small"
fullWidth
type="text"
/>
<FormHelperText>
{errors.fields?.[selectedListItem]?.name ? errors.fields[selectedListItem].name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.unit}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields[${selectedListItem}].unit`}>واحد اندازه گیری</InputLabel>
<OutlinedInput
id={`fields[${selectedListItem}].unit`}
label="واحد اندازه گیری"
autoComplete="off"
{...register(`fields[${selectedListItem}].unit`)}
value={watchedFields?.[selectedListItem]?.unit || ""}
onChange={(event) => setValue(`fields.${selectedListItem}.unit`, event.target.value)}
size="small"
fullWidth
type="text"
/>
<FormHelperText>
{errors.fields?.[selectedListItem]?.unit ? errors.fields[selectedListItem].unit.message : null}
</FormHelperText>
</FormControl>
</Grid>
</Grid>
);
};
export default AzmayeshFields;
"use client";
import React, { useEffect, useState } from "react";
import {
Button,
Chip,
FormControl,
FormHelperText,
Grid,
InputAdornment,
InputLabel,
MenuItem,
OutlinedInput,
Select,
Typography,
} from "@mui/material";
import ExtensionIcon from "@mui/icons-material/Extension";
import SelectItemBox from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType/SelectItemBox";
import KeyboardIcon from "@mui/icons-material/Keyboard";
import TextFieldsIcon from "@mui/icons-material/TextFields";
import ViewListIcon from "@mui/icons-material/ViewList";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
const fieldTypeList = [
{ value: "input", label: "متن", icon: <TextFieldsIcon /> },
{ value: "select", label: "انتخابی", icon: <ViewListIcon /> },
{ value: "date", label: "تاریخ", icon: <CalendarMonthIcon /> },
];
const AzmayeshFields = ({ errors, selectedListItem, register, setValue, fields, watch }) => {
const watchedFields = watch("fields");
const [isSelectType, setIsSelectType] = useState(false);
const [openSelectItem, setOpenSelectItem] = useState(false);
const [typeIcon, setTypeIcon] = useState(<KeyboardIcon />);
useEffect(() => {
const selectedIcon = fieldTypeList.find((option) => option.value === watchedFields?.[selectedListItem]?.type)
?.icon || <KeyboardIcon />;
setTypeIcon(selectedIcon);
setIsSelectType(watchedFields[selectedListItem]?.type === "select");
}, [watchedFields, selectedListItem]);
return (
<Grid container>
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.type}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields.${selectedListItem}.type`}>نوع</InputLabel>
<Select
id={`fields.${selectedListItem}.type`}
label="نوع"
autoComplete="off"
{...register(`fields.${selectedListItem}.type`)}
size="small"
fullWidth
value={watchedFields?.[selectedListItem]?.type || ""}
onChange={(event) => {
const selectedValue = event.target.value;
const selectedIcon = fieldTypeList.find((option) => option.value === selectedValue)
?.icon || <KeyboardIcon />;
setValue(`fields.${selectedListItem}.type`, selectedValue);
setIsSelectType(selectedValue === "select");
setTypeIcon(selectedIcon);
}}
startAdornment={<InputAdornment position="start">{typeIcon}</InputAdornment>}
>
<MenuItem value="">نوع</MenuItem>
{fieldTypeList.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</Select>
<FormHelperText>{errors.fields?.[selectedListItem]?.type?.message}</FormHelperText>
</FormControl>
</Grid>
{isSelectType && (
<Grid
xs={12}
sm={6}
sx={{
px: { xs: 0, sm: 1 },
py: 1,
mb: 0.5,
display: "flex",
flexDirection: "column",
alignItems: "start",
justifyContent: "space-around",
position: "relative",
}}
>
<Chip
sx={{
position: "absolute",
top: "-6px",
right: "-6px",
zIndex: "1",
}}
color="error"
label={watchedFields?.[selectedListItem].options.length}
/>
<Button
variant="outlined"
color="success"
sx={{ width: "100%", height: "37px" }}
startIcon={<ExtensionIcon />}
onClick={() => setOpenSelectItem(true)}
>
افزودن آیتم نوع انتخابی
</Button>
<Typography variant="caption" color="error">
{errors.fields?.[selectedListItem]?.options?.message}
</Typography>
{openSelectItem && (
<SelectItemBox
open={openSelectItem}
setOpen={setOpenSelectItem}
fields={fields}
setValue={setValue}
index={selectedListItem}
watch={watch}
/>
)}
</Grid>
)}
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.name}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields[${selectedListItem}].name`}>نام فیلد</InputLabel>
<OutlinedInput
id={`fields[${selectedListItem}].name`}
label="نام فیلد"
autoComplete="off"
{...register(`fields[${selectedListItem}].name`)}
value={watchedFields?.[selectedListItem]?.name || ""}
onInput={(event) => setValue(`fields.${selectedListItem}.name`, event.target.value)}
size="small"
fullWidth
type="text"
/>
<FormHelperText>
{errors.fields?.[selectedListItem]?.name ? errors.fields[selectedListItem].name.message : null}
</FormHelperText>
</FormControl>
</Grid>
<Grid xs={12} sm={6} sx={{ px: { xs: 0, sm: 1 }, py: 1 }}>
<FormControl
error={!!errors.fields?.[selectedListItem]?.unit}
size="small"
fullWidth
variant="outlined"
>
<InputLabel htmlFor={`fields[${selectedListItem}].unit`}>واحد اندازه گیری</InputLabel>
<OutlinedInput
id={`fields[${selectedListItem}].unit`}
label="واحد اندازه گیری"
autoComplete="off"
{...register(`fields[${selectedListItem}].unit`)}
value={watchedFields?.[selectedListItem]?.unit || ""}
onChange={(event) => setValue(`fields.${selectedListItem}.unit`, event.target.value)}
size="small"
fullWidth
type="text"
/>
<FormHelperText>
{errors.fields?.[selectedListItem]?.unit ? errors.fields[selectedListItem].unit.message : null}
</FormHelperText>
</FormControl>
</Grid>
</Grid>
);
};
export default AzmayeshFields;

View File

@@ -1,218 +1,218 @@
import {
Box,
Button,
Chip,
DialogActions,
DialogContent,
Divider,
FormControl,
FormHelperText,
Grid,
InputLabel,
List,
OutlinedInput,
Typography,
} from "@mui/material";
import StyledForm from "@/core/components/StyledForm";
import useRequest from "@/lib/hooks/useRequest";
import { useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import { array, object, string } from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
import ListItems from "./ListItems";
import AzmayeshFields from "./AzmayeshFields";
import { ADD_AZMAYESH_TYPE, UPDATE_AZMAYESH_TYPE } from "@/core/utils/routes";
const validationSchema = object({
name: string().required("عنوان نوع آزمایش را مشخص کنید!"),
fields: array()
.of(
object({
name: string().required("نام فیلد الزامی است"),
type: string().required("نوع فیلد الزامی است"),
options: array().when("type", {
is: "select",
then: (schema) => schema.min(1, "حداقل باید یک آیتم برای نوع انتخابی ایجاد کنید."),
otherwise: (schema) => schema.notRequired(),
}),
})
)
.min(1, "حداقل باید یک فیلد ایجاد نمایید."),
});
const FormAndRequest = ({ setOpen, mutate, rowId, updateInfo }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [selectedListItem, setSelectedListItem] = useState(null);
const handleClose = () => {
setOpen(false);
};
const defaultValues = {
name: updateInfo?.name || "",
fields: Array.isArray(updateInfo?.azmayesh_fields)
? updateInfo.azmayesh_fields.map((field) => ({
name: field.name || "",
type: field.type || "",
unit: field.unit || "",
options: field.option ? field.option : [],
}))
: [],
};
const {
control,
register,
handleSubmit,
setValue,
watch,
formState: { errors, isSubmitting },
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "all" });
const { fields, append, remove } = useFieldArray({
control,
name: "fields",
});
const handleRemove = (index) => {
remove(index);
if (selectedListItem === index) {
setSelectedListItem(null);
} else if (selectedListItem > index) {
setSelectedListItem((prev) => prev - 1);
}
};
const handleAddField = () => {
append({ name: "", type: "", unit: "", options: [] });
};
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("name", data.name);
data.fields.map((field, index) => {
formData.append(`fields[${index}][name]`, field.name);
if (field.unit !== "") formData.append(`fields[${index}][unit]`, field.unit);
formData.append(`fields[${index}][type]`, field.type);
if (field.options.length !== 0) formData.append(`fields[${index}][option]`, JSON.stringify(field.options));
});
try {
await requestServer(updateInfo ? `${UPDATE_AZMAYESH_TYPE}/${rowId}` : ADD_AZMAYESH_TYPE, "post", {
data: formData,
});
mutate();
handleClose();
} catch (error) {}
};
return (
<StyledForm onSubmit={handleSubmit(onSubmit)}>
<DialogContent dividers>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", my: 2 }}>
<FormControl error={!!errors.name} size="small" variant="outlined" sx={{ width: "250px" }}>
<InputLabel htmlFor="name">عنوان نوع آزمایش</InputLabel>
<OutlinedInput
id="name"
label={"عنوان نوع آزمایش"}
autoComplete="off"
{...register("name")}
size="small"
type="text"
/>
<FormHelperText id="name">{errors.name ? errors.name.message : null}</FormHelperText>
</FormControl>
</Box>
<Grid container spacing={2} sx={{ justifyContent: "space-between" }}>
<Grid xs={12} md={4} lg={3} sx={{ px: 1 }}>
<Divider sx={{ my: 2 }}>
<Chip label="لیست فیلد ها" />
</Divider>
<Button
variant="contained"
color="success"
fullWidth
startIcon={<DataSaverOnIcon />}
sx={{ mb: 2 }}
onClick={handleAddField}
>
ایجاد فیلد جدید
</Button>
<List
sx={{
border: "1px dashed #e1e1e1",
borderRadius: "5px",
p: 1,
maxHeight: "300px",
overflowY: "auto",
}}
>
{fields.length !== 0 ? (
fields.map((item, index) => (
<ListItems
key={index}
index={index}
selectedListItem={selectedListItem}
fields={fields}
handleRemove={handleRemove}
setSelectedListItem={setSelectedListItem}
watch={watch}
/>
))
) : (
<Typography
variant="h6"
sx={{ color: "#a2a2a2", textAlign: "center", letterSpacing: "1px" }}
>
فیلدی وجود ندارد
</Typography>
)}
</List>
<Typography variant="caption" color="error">
{errors.fields ? errors.fields.message : null}
</Typography>
</Grid>
<Divider orientation="vertical" variant="middle" flexItem />
<Grid xs={12} md={7} lg={8} sx={{ pl: 2 }}>
<Divider sx={{ my: 2 }}>
<Chip label="اطلاعات فیلد" />
</Divider>
{selectedListItem !== null ? (
<AzmayeshFields
errors={errors}
selectedListItem={selectedListItem}
register={register}
setValue={setValue}
fields={fields}
watch={watch}
/>
) : (
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", py: 2 }}>
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#a2a2a2" }}>
از بخش لیست فیلد ها یک آیتم را انتخاب نمایید
</Typography>
</Box>
)}
</Grid>
</Grid>
</DialogContent>
<DialogActions sx={{ alignItems: "center", justifyContent: "center", py: 2 }}>
<Button variant="outlined" color="error" onClick={handleClose}>
بستن
</Button>
<Button
type={"submit"}
variant="contained"
color="primary"
disabled={isSubmitting}
sx={{ width: "200px" }}
>
{isSubmitting ? "در حال ثبت..." : "ثبت نوع آزمایش"}
</Button>
</DialogActions>
</StyledForm>
);
};
export default FormAndRequest;
import {
Box,
Button,
Chip,
DialogActions,
DialogContent,
Divider,
FormControl,
FormHelperText,
Grid,
InputLabel,
List,
OutlinedInput,
Typography,
} from "@mui/material";
import StyledForm from "@/core/components/StyledForm";
import useRequest from "@/lib/hooks/useRequest";
import { useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import { array, object, string } from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import DataSaverOnIcon from "@mui/icons-material/DataSaverOn";
import ListItems from "./ListItems";
import AzmayeshFields from "./AzmayeshFields";
import { ADD_AZMAYESH_TYPE, UPDATE_AZMAYESH_TYPE } from "@/core/utils/routes";
const validationSchema = object({
name: string().required("عنوان نوع آزمایش را مشخص کنید!"),
fields: array()
.of(
object({
name: string().required("نام فیلد الزامی است"),
type: string().required("نوع فیلد الزامی است"),
options: array().when("type", {
is: "select",
then: (schema) => schema.min(1, "حداقل باید یک آیتم برای نوع انتخابی ایجاد کنید."),
otherwise: (schema) => schema.notRequired(),
}),
})
)
.min(1, "حداقل باید یک فیلد ایجاد نمایید."),
});
const FormAndRequest = ({ setOpen, mutate, rowId, updateInfo }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [selectedListItem, setSelectedListItem] = useState(null);
const handleClose = () => {
setOpen(false);
};
const defaultValues = {
name: updateInfo?.name || "",
fields: Array.isArray(updateInfo?.azmayesh_fields)
? updateInfo.azmayesh_fields.map((field) => ({
name: field.name || "",
type: field.type || "",
unit: field.unit || "",
options: field.option ? field.option : [],
}))
: [],
};
const {
control,
register,
handleSubmit,
setValue,
watch,
formState: { errors, isSubmitting },
} = useForm({ defaultValues, resolver: yupResolver(validationSchema), mode: "all" });
const { fields, append, remove } = useFieldArray({
control,
name: "fields",
});
const handleRemove = (index) => {
remove(index);
if (selectedListItem === index) {
setSelectedListItem(null);
} else if (selectedListItem > index) {
setSelectedListItem((prev) => prev - 1);
}
};
const handleAddField = () => {
append({ name: "", type: "", unit: "", options: [] });
};
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("name", data.name);
data.fields.map((field, index) => {
formData.append(`fields[${index}][name]`, field.name);
if (field.unit !== "") formData.append(`fields[${index}][unit]`, field.unit);
formData.append(`fields[${index}][type]`, field.type);
if (field.options.length !== 0) formData.append(`fields[${index}][option]`, JSON.stringify(field.options));
});
try {
await requestServer(updateInfo ? `${UPDATE_AZMAYESH_TYPE}/${rowId}` : ADD_AZMAYESH_TYPE, "post", {
data: formData,
});
mutate();
handleClose();
} catch (error) {}
};
return (
<StyledForm onSubmit={handleSubmit(onSubmit)}>
<DialogContent dividers>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", my: 2 }}>
<FormControl error={!!errors.name} size="small" variant="outlined" sx={{ width: "250px" }}>
<InputLabel htmlFor="name">عنوان نوع آزمایش</InputLabel>
<OutlinedInput
id="name"
label={"عنوان نوع آزمایش"}
autoComplete="off"
{...register("name")}
size="small"
type="text"
/>
<FormHelperText id="name">{errors.name ? errors.name.message : null}</FormHelperText>
</FormControl>
</Box>
<Grid container spacing={2} sx={{ justifyContent: "space-between" }}>
<Grid xs={12} md={4} lg={3} sx={{ px: 1 }}>
<Divider sx={{ my: 2 }}>
<Chip label="لیست فیلد ها" />
</Divider>
<Button
variant="contained"
color="success"
fullWidth
startIcon={<DataSaverOnIcon />}
sx={{ mb: 2 }}
onClick={handleAddField}
>
ایجاد فیلد جدید
</Button>
<List
sx={{
border: "1px dashed #e1e1e1",
borderRadius: "5px",
p: 1,
maxHeight: "300px",
overflowY: "auto",
}}
>
{fields.length !== 0 ? (
fields.map((item, index) => (
<ListItems
key={index}
index={index}
selectedListItem={selectedListItem}
fields={fields}
handleRemove={handleRemove}
setSelectedListItem={setSelectedListItem}
watch={watch}
/>
))
) : (
<Typography
variant="h6"
sx={{ color: "#a2a2a2", textAlign: "center", letterSpacing: "1px" }}
>
فیلدی وجود ندارد
</Typography>
)}
</List>
<Typography variant="caption" color="error">
{errors.fields ? errors.fields.message : null}
</Typography>
</Grid>
<Divider orientation="vertical" variant="middle" flexItem />
<Grid xs={12} md={7} lg={8} sx={{ pl: 2 }}>
<Divider sx={{ my: 2 }}>
<Chip label="اطلاعات فیلد" />
</Divider>
{selectedListItem !== null ? (
<AzmayeshFields
errors={errors}
selectedListItem={selectedListItem}
register={register}
setValue={setValue}
fields={fields}
watch={watch}
/>
) : (
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", py: 2 }}>
<Typography variant="h6" sx={{ letterSpacing: "2px", color: "#a2a2a2" }}>
از بخش لیست فیلد ها یک آیتم را انتخاب نمایید
</Typography>
</Box>
)}
</Grid>
</Grid>
</DialogContent>
<DialogActions sx={{ alignItems: "center", justifyContent: "center", py: 2 }}>
<Button variant="outlined" color="error" onClick={handleClose}>
بستن
</Button>
<Button
type={"submit"}
variant="contained"
color="primary"
disabled={isSubmitting}
sx={{ width: "200px" }}
>
{isSubmitting ? "در حال ثبت..." : "ثبت نوع آزمایش"}
</Button>
</DialogActions>
</StyledForm>
);
};
export default FormAndRequest;

View File

@@ -1,77 +1,77 @@
"use client";
import { Box, IconButton, ListItem, Stack, Typography } from "@mui/material";
import React from "react";
import DeleteIcon from "@mui/icons-material/Delete";
import SettingsIcon from "@mui/icons-material/Settings";
import TextFieldsIcon from "@mui/icons-material/TextFields";
import ViewListIcon from "@mui/icons-material/ViewList";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
const fieldsType = {
input: "متن",
date: "تاریخ",
select: "انتخابی",
};
const fieldsTypeIcon = {
input: <TextFieldsIcon sx={{ fontSize: "18px" }} />,
date: <CalendarMonthIcon sx={{ fontSize: "18px" }} />,
select: <ViewListIcon sx={{ fontSize: "18px" }} />,
};
const ListItems = ({ index, handleRemove, selectedListItem, setSelectedListItem, watch }) => {
const watchedFields = watch("fields");
return (
<ListItem
sx={{
transition: "all 0.3s",
boxShadow:
selectedListItem === index
? "rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px"
: "rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px",
borderRadius: 2,
mb: 1.5,
px: 1,
py: 0.7,
backgroundColor: selectedListItem === index ? "#6ea1714d" : "#ebebeb7a",
"&:last-child": {
mb: 0,
},
}}
disablePadding
secondaryAction={
<Box sx={{ display: "flex", alignItems: "center" }}>
<IconButton
edge="start"
aria-label="edit"
color="primary"
onClick={() => setSelectedListItem(index)}
>
<SettingsIcon />
</IconButton>
<IconButton edge="end" aria-label="delete" color="error" onClick={() => handleRemove(index)}>
<DeleteIcon />
</IconButton>
</Box>
}
>
<Stack sx={{ width: "100%" }}>
<Typography
sx={{ color: watchedFields[index].name !== "" ? "" : "error.main" }}
variant="body1"
fontWeight={500}
noWrap
>
{watchedFields[index].name !== "" ? watchedFields[index].name : "نام تعیین نشده"}
</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
{fieldsTypeIcon[watchedFields[index].type] || null}
<Typography sx={{ color: watchedFields[index].type !== "" ? "" : "error.main" }} variant="caption">
{watchedFields[index].type !== "" ? fieldsType[watchedFields[index].type] : "واحد تعیین نشده"}
</Typography>
</Box>
</Stack>
</ListItem>
);
};
export default ListItems;
"use client";
import { Box, IconButton, ListItem, Stack, Typography } from "@mui/material";
import React from "react";
import DeleteIcon from "@mui/icons-material/Delete";
import SettingsIcon from "@mui/icons-material/Settings";
import TextFieldsIcon from "@mui/icons-material/TextFields";
import ViewListIcon from "@mui/icons-material/ViewList";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
const fieldsType = {
input: "متن",
date: "تاریخ",
select: "انتخابی",
};
const fieldsTypeIcon = {
input: <TextFieldsIcon sx={{ fontSize: "18px" }} />,
date: <CalendarMonthIcon sx={{ fontSize: "18px" }} />,
select: <ViewListIcon sx={{ fontSize: "18px" }} />,
};
const ListItems = ({ index, handleRemove, selectedListItem, setSelectedListItem, watch }) => {
const watchedFields = watch("fields");
return (
<ListItem
sx={{
transition: "all 0.3s",
boxShadow:
selectedListItem === index
? "rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px"
: "rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px",
borderRadius: 2,
mb: 1.5,
px: 1,
py: 0.7,
backgroundColor: selectedListItem === index ? "#6ea1714d" : "#ebebeb7a",
"&:last-child": {
mb: 0,
},
}}
disablePadding
secondaryAction={
<Box sx={{ display: "flex", alignItems: "center" }}>
<IconButton
edge="start"
aria-label="edit"
color="primary"
onClick={() => setSelectedListItem(index)}
>
<SettingsIcon />
</IconButton>
<IconButton edge="end" aria-label="delete" color="error" onClick={() => handleRemove(index)}>
<DeleteIcon />
</IconButton>
</Box>
}
>
<Stack sx={{ width: "100%" }}>
<Typography
sx={{ color: watchedFields[index].name !== "" ? "" : "error.main" }}
variant="body1"
fontWeight={500}
noWrap
>
{watchedFields[index].name !== "" ? watchedFields[index].name : "نام تعیین نشده"}
</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
{fieldsTypeIcon[watchedFields[index].type] || null}
<Typography sx={{ color: watchedFields[index].type !== "" ? "" : "error.main" }} variant="caption">
{watchedFields[index].type !== "" ? fieldsType[watchedFields[index].type] : "واحد تعیین نشده"}
</Typography>
</Box>
</Stack>
</ListItem>
);
};
export default ListItems;

View File

@@ -1,108 +1,108 @@
import {
Box,
Button,
Chip,
Dialog,
DialogActions,
DialogContent,
Divider,
IconButton,
List,
ListItem,
ListItemText,
TextField,
Typography,
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import React, { useState } from "react";
const SelectItemBox = ({ open, setOpen, setValue, index, watch }) => {
const watchedFields = watch("fields");
const [itemValue, setItemValue] = useState("");
const [listArr, setListArr] = useState(watchedFields?.[index]?.options);
const addToList = () => {
if (itemValue) {
setListArr([...listArr, itemValue]);
setItemValue("");
}
};
const removeFromList = (index) => {
setListArr(listArr.filter((_, i) => i !== index));
};
const saveAndCloseList = () => {
setValue(`fields.${index}.options`, listArr);
closeModal();
};
const closeModal = () => {
setOpen(false);
};
return (
<Dialog open={open} fullWidth={true} maxWidth={"xs"} onClose={closeModal}>
<DialogContent>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 2 }}>
<TextField
fullWidth
size="small"
id="outlined-controlled"
label="نام آیتم را وارد کنید"
value={itemValue}
onChange={(event) => {
setItemValue(event.target.value);
}}
/>
<Button variant="contained" color="primary" disabled={!itemValue} onClick={addToList}>
افزودن
</Button>
</Box>
<Box sx={{ borderRadius: "5px", mt: 2 }}>
<Divider>
<Chip label="لیست آیتم ها" />
</Divider>
<List>
{listArr.length !== 0 ? (
listArr.map((item, index) => (
<ListItem
key={index}
sx={{
boxShadow:
"rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px",
my: 1,
borderRadius: "5px",
}}
secondaryAction={
<IconButton
edge="end"
aria-label="delete"
color="error"
onClick={() => removeFromList(index)}
>
<DeleteIcon />
</IconButton>
}
>
<ListItemText primary={item} />
</ListItem>
))
) : (
<Typography variant="h6" sx={{ textAlign: "center", letterSpacing: "1px" }}>
هنوز آیتمی ثبت نشده است
</Typography>
)}
</List>
</Box>
</DialogContent>
<DialogActions>
<Button variant="outlined" color="primary" onClick={saveAndCloseList}>
ذخیره لیست
</Button>
</DialogActions>
</Dialog>
);
};
export default SelectItemBox;
import {
Box,
Button,
Chip,
Dialog,
DialogActions,
DialogContent,
Divider,
IconButton,
List,
ListItem,
ListItemText,
TextField,
Typography,
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import React, { useState } from "react";
const SelectItemBox = ({ open, setOpen, setValue, index, watch }) => {
const watchedFields = watch("fields");
const [itemValue, setItemValue] = useState("");
const [listArr, setListArr] = useState(watchedFields?.[index]?.options);
const addToList = () => {
if (itemValue) {
setListArr([...listArr, itemValue]);
setItemValue("");
}
};
const removeFromList = (index) => {
setListArr(listArr.filter((_, i) => i !== index));
};
const saveAndCloseList = () => {
setValue(`fields.${index}.options`, listArr);
closeModal();
};
const closeModal = () => {
setOpen(false);
};
return (
<Dialog open={open} fullWidth={true} maxWidth={"xs"} onClose={closeModal}>
<DialogContent>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 2 }}>
<TextField
fullWidth
size="small"
id="outlined-controlled"
label="نام آیتم را وارد کنید"
value={itemValue}
onChange={(event) => {
setItemValue(event.target.value);
}}
/>
<Button variant="contained" color="primary" disabled={!itemValue} onClick={addToList}>
افزودن
</Button>
</Box>
<Box sx={{ borderRadius: "5px", mt: 2 }}>
<Divider>
<Chip label="لیست آیتم ها" />
</Divider>
<List>
{listArr.length !== 0 ? (
listArr.map((item, index) => (
<ListItem
key={index}
sx={{
boxShadow:
"rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px",
my: 1,
borderRadius: "5px",
}}
secondaryAction={
<IconButton
edge="end"
aria-label="delete"
color="error"
onClick={() => removeFromList(index)}
>
<DeleteIcon />
</IconButton>
}
>
<ListItemText primary={item} />
</ListItem>
))
) : (
<Typography variant="h6" sx={{ textAlign: "center", letterSpacing: "1px" }}>
هنوز آیتمی ثبت نشده است
</Typography>
)}
</List>
</Box>
</DialogContent>
<DialogActions>
<Button variant="outlined" color="primary" onClick={saveAndCloseList}>
ذخیره لیست
</Button>
</DialogActions>
</Dialog>
);
};
export default SelectItemBox;

View File

@@ -1,37 +1,37 @@
import { Dialog, IconButton } from "@mui/material";
import FormAndRequest from "./FormAndRequest";
import DialogLoading from "@/core/components/DialogLoading";
import CloseIcon from "@mui/icons-material/Close";
const CandUAzmayeshType = ({ open, setOpen, mutate, rowId, updateInfo, loadingOpen, fromUpdate = false }) => {
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
return (
<Dialog open={open} fullWidth maxWidth="lg">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{isUpdateReady ? (
<FormAndRequest
setOpen={setOpen}
mutate={mutate}
rowId={rowId}
{...(fromUpdate ? { updateInfo } : {})}
/>
) : (
<DialogLoading loadingOpen={loadingOpen} />
)}
</Dialog>
);
};
export default CandUAzmayeshType;
import { Dialog, IconButton } from "@mui/material";
import FormAndRequest from "./FormAndRequest";
import DialogLoading from "@/core/components/DialogLoading";
import CloseIcon from "@mui/icons-material/Close";
const CandUAzmayeshType = ({ open, setOpen, mutate, rowId, updateInfo, loadingOpen, fromUpdate = false }) => {
const isUpdateReady = fromUpdate ? updateInfo !== null : true;
return (
<Dialog open={open} fullWidth maxWidth="lg">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{isUpdateReady ? (
<FormAndRequest
setOpen={setOpen}
mutate={mutate}
rowId={rowId}
{...(fromUpdate ? { updateInfo } : {})}
/>
) : (
<DialogLoading loadingOpen={loadingOpen} />
)}
</Dialog>
);
};
export default CandUAzmayeshType;

View File

@@ -1,78 +1,78 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import useRequest from "@/lib/hooks/useRequest";
import { useState } from "react";
import { DELETE_AZMAYESH_TYPE_LIST } from "@/core/utils/routes";
const DeleteAzmayeshType = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_AZMAYESH_TYPE_LIST}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف نوع آزمایش" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف نوع آزمایش</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این نوع آزمایش مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteAzmayeshType;
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Tooltip,
Typography,
} from "@mui/material";
import DeleteIcon from "@mui/icons-material/Delete";
import useRequest from "@/lib/hooks/useRequest";
import { useState } from "react";
import { DELETE_AZMAYESH_TYPE_LIST } from "@/core/utils/routes";
const DeleteAzmayeshType = ({ rowId, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
setIsSubmitting(true);
requestServer(`${DELETE_AZMAYESH_TYPE_LIST}/${rowId}`, "post")
.then(() => {
setOpenDeleteDialog(false);
mutate();
})
.catch(() => {})
.finally(() => {
setIsSubmitting(false);
});
};
return (
<>
<Tooltip title="حذف نوع آزمایش" arrow placement="right">
<IconButton
color="error"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenDeleteDialog(true);
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
maxWidth="sm"
open={openDeleteDialog}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<DialogTitle>حذف نوع آزمایش</DialogTitle>
<DialogContent>
<Typography>آیا از حذف این نوع آزمایش مطمئن هستید؟</Typography>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpenDeleteDialog(false)}
variant="outlined"
color="primary"
disabled={isSubmitting}
autoFocus
>
بستن
</Button>
<Button onClick={handleSubmit} variant="contained" color="error" disabled={isSubmitting}>
حذف
</Button>
</DialogActions>
</Dialog>
</>
);
};
export default DeleteAzmayeshType;

View File

@@ -1,53 +1,53 @@
import { IconButton, Tooltip } from "@mui/material";
import EditIcon from "@mui/icons-material/Edit";
import { GET_AZMAYESH_TYPE_LIST_TABLE } from "@/core/utils/routes";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import CandUAzmayeshType from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType";
const UpdateAzmayeshType = ({ rowId, mutate }) => {
const requestServer = useRequest();
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [loadingOpen, setLoadingOpen] = useState(false);
const handleGetInfo = () => {
setLoadingOpen(true);
setOpenUpdateDialog(true);
requestServer(`${GET_AZMAYESH_TYPE_LIST_TABLE}/${rowId}`, "get")
.then((response) => {
setUpdateInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setLoadingOpen(false);
});
};
return (
<>
<Tooltip title="ویرایش آزمایش" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetInfo}
>
<EditIcon />
</IconButton>
</Tooltip>
{openUpdateDialog && (
<CandUAzmayeshType
open={openUpdateDialog}
setOpen={setOpenUpdateDialog}
mutate={mutate}
updateInfo={updateInfo}
rowId={rowId}
loadingOpen={loadingOpen}
fromUpdate={true}
/>
)}
</>
);
};
export default UpdateAzmayeshType;
import { IconButton, Tooltip } from "@mui/material";
import EditIcon from "@mui/icons-material/Edit";
import { GET_AZMAYESH_TYPE_LIST_TABLE } from "@/core/utils/routes";
import { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import CandUAzmayeshType from "@/components/dashboard/azmayeshType/Forms/CandUAzmayeshType";
const UpdateAzmayeshType = ({ rowId, mutate }) => {
const requestServer = useRequest();
const [openUpdateDialog, setOpenUpdateDialog] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [loadingOpen, setLoadingOpen] = useState(false);
const handleGetInfo = () => {
setLoadingOpen(true);
setOpenUpdateDialog(true);
requestServer(`${GET_AZMAYESH_TYPE_LIST_TABLE}/${rowId}`, "get")
.then((response) => {
setUpdateInfo(response.data.data);
})
.catch(() => {})
.finally(() => {
setLoadingOpen(false);
});
};
return (
<>
<Tooltip title="ویرایش آزمایش" arrow placement="right">
<IconButton
color="success"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={handleGetInfo}
>
<EditIcon />
</IconButton>
</Tooltip>
{openUpdateDialog && (
<CandUAzmayeshType
open={openUpdateDialog}
setOpen={setOpenUpdateDialog}
mutate={mutate}
updateInfo={updateInfo}
rowId={rowId}
loadingOpen={loadingOpen}
fromUpdate={true}
/>
)}
</>
);
};
export default UpdateAzmayeshType;

View File

@@ -1,13 +1,13 @@
import { Box } from "@mui/material";
import UpdateAzmayeshType from "./UpdateAzmayeshType";
import DeleteAzmayeshType from "./DeleteAzmayeshType";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<UpdateAzmayeshType rowId={row.getValue("id")} mutate={mutate} />
<DeleteAzmayeshType rowId={row.getValue("id")} mutate={mutate} />
</Box>
);
};
export default RowActions;
import { Box } from "@mui/material";
import UpdateAzmayeshType from "./UpdateAzmayeshType";
import DeleteAzmayeshType from "./DeleteAzmayeshType";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1 }}>
<UpdateAzmayeshType rowId={row.getValue("id")} mutate={mutate} />
<DeleteAzmayeshType rowId={row.getValue("id")} mutate={mutate} />
</Box>
);
};
export default RowActions;

View File

@@ -1,10 +1,10 @@
import AzmayeshTypeCreate from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<AzmayeshTypeCreate mutate={mutate} />
</>
);
};
export default Toolbar;
import AzmayeshTypeCreate from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<AzmayeshTypeCreate mutate={mutate} />
</>
);
};
export default Toolbar;

View File

@@ -1,15 +1,15 @@
"use client";
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import AzmayeshTypeList from "./AzmayeshTypeList";
const AzmayeshTypePage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"کارتابل نوع آزمایشات"} />
<AzmayeshTypeList />
</Stack>
);
};
export default AzmayeshTypePage;
"use client";
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import AzmayeshTypeList from "./AzmayeshTypeList";
const AzmayeshTypePage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"کارتابل نوع آزمایشات"} />
<AzmayeshTypeList />
</Stack>
);
};
export default AzmayeshTypePage;

View File

@@ -1,145 +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: "all",
});
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 (
<>
<DialogHeader>
<DialogTitle>ثبت آیتم جدید</DialogTitle>
</DialogHeader>
<DialogContent dividers>
<StyledForm onSubmit={handleSubmit(onSubmit)} id="createDamageForm">
<Stack spacing={3}>
<Controller
name="title"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="عنوان"
value={value}
onChange={onChange}
placeholder="عنوان را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="unit"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="واحد"
value={value}
onChange={onChange}
error={!!error}
placeholder="واحد را وارد کنید"
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="base_price"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<NumberField
label={`فی`}
error={!!error}
value={value || ""}
type="text"
size={"small"}
unit={"ریال"}
inputProps={{
placeholder: "فی را وارد کنید",
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
onChange={(event) => {
if (!isNaN(event.target.value)) {
onChange(event.target.value);
} else {
onChange(value);
}
}}
helperText={error ? error.message : null}
variant="outlined"
fullWidth
/>
)}
/>
</Stack>
</StyledForm>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} variant="outlined" color="secondary" startIcon={<ExitToApp />}>
بستن
</Button>
<Button
variant="contained"
disabled={isSubmitting}
type={"submit"}
form="createDamageForm"
endIcon={<Beenhere />}
>
{isSubmitting ? "در حال ثبت آیتم" : "ثبت آیتم"}
</Button>
</DialogActions>
</>
);
};
export default CreateFormContent;
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: "all",
});
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 (
<>
<DialogHeader>
<DialogTitle>ثبت آیتم جدید</DialogTitle>
</DialogHeader>
<DialogContent dividers>
<StyledForm onSubmit={handleSubmit(onSubmit)} id="createDamageForm">
<Stack spacing={3}>
<Controller
name="title"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="عنوان"
value={value}
onChange={onChange}
placeholder="عنوان را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="unit"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="واحد"
value={value}
onChange={onChange}
error={!!error}
placeholder="واحد را وارد کنید"
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="base_price"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<NumberField
label={`فی`}
error={!!error}
value={value || ""}
type="text"
size={"small"}
unit={"ریال"}
inputProps={{
placeholder: "فی را وارد کنید",
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
onChange={(event) => {
if (!isNaN(event.target.value)) {
onChange(event.target.value);
} else {
onChange(value);
}
}}
helperText={error ? error.message : null}
variant="outlined"
fullWidth
/>
)}
/>
</Stack>
</StyledForm>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} variant="outlined" color="secondary" startIcon={<ExitToApp />}>
بستن
</Button>
<Button
variant="contained"
disabled={isSubmitting}
type={"submit"}
form="createDamageForm"
endIcon={<Beenhere />}
>
{isSubmitting ? "در حال ثبت آیتم" : "ثبت آیتم"}
</Button>
</DialogActions>
</>
);
};
export default CreateFormContent;

View File

@@ -1,25 +1,25 @@
import { Dialog, IconButton } from "@mui/material";
import CreateFormContent from "./CreateFormContent";
import CloseIcon from "@mui/icons-material/Close";
const CreateForm = ({ open, setOpen, mutate }) => {
return (
<Dialog open={open} fullWidth maxWidth="xs">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{open && <CreateFormContent setOpen={setOpen} mutate={mutate} />}
</Dialog>
);
};
export default CreateForm;
import { Dialog, IconButton } from "@mui/material";
import CreateFormContent from "./CreateFormContent";
import CloseIcon from "@mui/icons-material/Close";
const CreateForm = ({ open, setOpen, mutate }) => {
return (
<Dialog open={open} fullWidth maxWidth="xs">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{open && <CreateFormContent setOpen={setOpen} mutate={mutate} />}
</Dialog>
);
};
export default CreateForm;

View File

@@ -1,36 +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 ? (
<IconButton aria-label="ثبت آیتم" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button
size={"small"}
variant="contained"
color="primary"
startIcon={<AddCircle />}
onClick={handleOpen}
>
ثبت آیتم
</Button>
)}
<CreateForm open={open} setOpen={setOpen} mutate={mutate} />
</>
);
};
export default CreateDamage;
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 ? (
<IconButton aria-label="ثبت آیتم" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button
size={"small"}
variant="contained"
color="primary"
startIcon={<AddCircle />}
onClick={handleOpen}
>
ثبت آیتم
</Button>
)}
<CreateForm open={open} setOpen={setOpen} mutate={mutate} />
</>
);
};
export default CreateDamage;

View File

@@ -1,84 +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 (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
need_filter={true}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_RECEIPT_DAMAGE_ITEMS_LIST}
page_name={"receiptDamagePage"}
table_name={"receiptDamageList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default DamagesList;
"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 (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
need_filter={true}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_RECEIPT_DAMAGE_ITEMS_LIST}
page_name={"receiptDamagePage"}
table_name={"receiptDamageList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default DamagesList;

View File

@@ -1,31 +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 <Switch size="small" disabled={disabled} checked={checked} onChange={handleSwitch} />;
};
export default Activity;
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 <Switch size="small" disabled={disabled} checked={checked} onChange={handleSwitch} />;
};
export default Activity;

View File

@@ -1,145 +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: "all",
});
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 (
<>
<DialogHeader>
<DialogTitle>ویرایش آیتم</DialogTitle>
</DialogHeader>
<DialogContent dividers>
<StyledForm onSubmit={handleSubmit(onSubmit)} id="updateDamageForm">
<Stack spacing={3}>
<Controller
name="title"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="عنوان"
value={value}
onChange={onChange}
placeholder="عنوان را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="unit"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="واحد"
value={value}
onChange={onChange}
error={!!error}
placeholder="واحد را وارد کنید"
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="base_price"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<NumberField
label={`فی`}
error={!!error}
value={value || ""}
type="text"
size={"small"}
unit={"ریال"}
inputProps={{
placeholder: "فی را وارد کنید",
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
onChange={(event) => {
if (!isNaN(event.target.value)) {
onChange(event.target.value);
} else {
onChange(value);
}
}}
helperText={error ? error.message : null}
variant="outlined"
fullWidth
/>
)}
/>
</Stack>
</StyledForm>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} variant="outlined" color="secondary" startIcon={<ExitToApp />}>
بستن
</Button>
<Button
variant="contained"
disabled={isSubmitting}
type={"submit"}
form="updateDamageForm"
endIcon={<Beenhere />}
>
{isSubmitting ? "در حال ویرایش آیتم" : "ویرایش آیتم"}
</Button>
</DialogActions>
</>
);
};
export default EditFormContent;
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: "all",
});
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 (
<>
<DialogHeader>
<DialogTitle>ویرایش آیتم</DialogTitle>
</DialogHeader>
<DialogContent dividers>
<StyledForm onSubmit={handleSubmit(onSubmit)} id="updateDamageForm">
<Stack spacing={3}>
<Controller
name="title"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="عنوان"
value={value}
onChange={onChange}
placeholder="عنوان را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="unit"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="واحد"
value={value}
onChange={onChange}
error={!!error}
placeholder="واحد را وارد کنید"
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
<Controller
name="base_price"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<NumberField
label={`فی`}
error={!!error}
value={value || ""}
type="text"
size={"small"}
unit={"ریال"}
inputProps={{
placeholder: "فی را وارد کنید",
inputMode: "number",
min: 0,
pattern: "[0-9]*",
}}
onChange={(event) => {
if (!isNaN(event.target.value)) {
onChange(event.target.value);
} else {
onChange(value);
}
}}
helperText={error ? error.message : null}
variant="outlined"
fullWidth
/>
)}
/>
</Stack>
</StyledForm>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)} variant="outlined" color="secondary" startIcon={<ExitToApp />}>
بستن
</Button>
<Button
variant="contained"
disabled={isSubmitting}
type={"submit"}
form="updateDamageForm"
endIcon={<Beenhere />}
>
{isSubmitting ? "در حال ویرایش آیتم" : "ویرایش آیتم"}
</Button>
</DialogActions>
</>
);
};
export default EditFormContent;

View File

@@ -1,44 +1,44 @@
import BorderColorIcon from "@mui/icons-material/BorderColor";
import { Dialog, IconButton, Tooltip } from "@mui/material";
import EditFormContent from "./Form";
import { useState } from "react";
import CloseIcon from "@mui/icons-material/Close";
const Edit = ({ row, mutate, rowId }) => {
const [openEditDialog, setOpenEditDialog] = useState(false);
return (
<>
<Tooltip title="ویرایش" arrow placement="right">
<IconButton
color="primary"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenEditDialog(true);
}}
>
<BorderColorIcon />
</IconButton>
</Tooltip>
<Dialog open={openEditDialog} fullWidth maxWidth="xs">
<IconButton
aria-label="close"
onClick={() => setOpenEditDialog(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{openEditDialog && (
<EditFormContent rowId={rowId} row={row} setOpen={setOpenEditDialog} mutate={mutate} />
)}
</Dialog>
</>
);
};
export default Edit;
import BorderColorIcon from "@mui/icons-material/BorderColor";
import { Dialog, IconButton, Tooltip } from "@mui/material";
import EditFormContent from "./Form";
import { useState } from "react";
import CloseIcon from "@mui/icons-material/Close";
const Edit = ({ row, mutate, rowId }) => {
const [openEditDialog, setOpenEditDialog] = useState(false);
return (
<>
<Tooltip title="ویرایش" arrow placement="right">
<IconButton
color="primary"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpenEditDialog(true);
}}
>
<BorderColorIcon />
</IconButton>
</Tooltip>
<Dialog open={openEditDialog} fullWidth maxWidth="xs">
<IconButton
aria-label="close"
onClick={() => setOpenEditDialog(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{openEditDialog && (
<EditFormContent rowId={rowId} row={row} setOpen={setOpenEditDialog} mutate={mutate} />
)}
</Dialog>
</>
);
};
export default Edit;

View File

@@ -1,13 +1,13 @@
import { Box } from "@mui/material";
import Activity from "./Activity";
import Edit from "./Edit";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1, alignItems: "center" }}>
<Edit row={row} mutate={mutate} rowId={row.getValue("id")} />
<Activity mutate={mutate} rowId={row.getValue("id")} status={row.original.status} />
</Box>
);
};
export default RowActions;
import { Box } from "@mui/material";
import Activity from "./Activity";
import Edit from "./Edit";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1, alignItems: "center" }}>
<Edit row={row} mutate={mutate} rowId={row.getValue("id")} />
<Activity mutate={mutate} rowId={row.getValue("id")} status={row.original.status} />
</Box>
);
};
export default RowActions;

View File

@@ -1,10 +1,10 @@
import CreateDamage from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<CreateDamage mutate={mutate} />
</>
);
};
export default Toolbar;
import CreateDamage from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<CreateDamage mutate={mutate} />
</>
);
};
export default Toolbar;

View File

@@ -1,13 +1,13 @@
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import DamagesList from "./DamagesList";
const DamagesPage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"آیتم خسارات"} />
<DamagesList />
</Stack>
);
};
export default DamagesPage;
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import DamagesList from "./DamagesList";
const DamagesPage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"آیتم خسارات"} />
<DamagesList />
</Stack>
);
};
export default DamagesPage;

Some files were not shown because too many files have changed in this diff Show More