diff --git a/package-lock.json b/package-lock.json index 58d90a0..97b8cae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "image-to-file-converter": "^1.0.6", "material-react-table": "^1.11.1", "moment": "^2.29.4", + "moment-jalaali": "^0.10.0", "next": "^13.3.0", "next-intl": "^2.13.1", "next-useragent": "^2.8.0", @@ -3417,6 +3418,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/jalaali-js": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.6.tgz", + "integrity": "sha512-io974va+Qyu+UfuVX3UIAgJlxLhAMx9Y8VMfh+IG00Js7hXQo1qNQuwSiSa0xxco0SVgx5HWNkaiCcV+aZ8WPw==" + }, "node_modules/js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -3671,6 +3677,28 @@ "node": "*" } }, + "node_modules/moment-jalaali": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.0.tgz", + "integrity": "sha512-XICH1+UHd3zyaE1bXWQBlhoXBqbzEyFfT0TrifNobHxLALRuTSwXn376bX8FmkYg9mZimevwwdd6EB57s5wuFA==", + "dependencies": { + "jalaali-js": "^1.1.0", + "moment": "^2.22.2", + "moment-timezone": "^0.5.21", + "rimraf": "^3.0.2" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7413,6 +7441,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "jalaali-js": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.6.tgz", + "integrity": "sha512-io974va+Qyu+UfuVX3UIAgJlxLhAMx9Y8VMfh+IG00Js7hXQo1qNQuwSiSa0xxco0SVgx5HWNkaiCcV+aZ8WPw==" + }, "js-sdsl": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", @@ -7601,6 +7634,25 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, + "moment-jalaali": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.10.0.tgz", + "integrity": "sha512-XICH1+UHd3zyaE1bXWQBlhoXBqbzEyFfT0TrifNobHxLALRuTSwXn376bX8FmkYg9mZimevwwdd6EB57s5wuFA==", + "requires": { + "jalaali-js": "^1.1.0", + "moment": "^2.22.2", + "moment-timezone": "^0.5.21", + "rimraf": "^3.0.2" + } + }, + "moment-timezone": { + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", + "requires": { + "moment": "^2.29.4" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/package.json b/package.json index 37f61a8..1ff9b56 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "image-to-file-converter": "^1.0.6", "material-react-table": "^1.11.1", "moment": "^2.29.4", + "moment-jalaali": "^0.10.0", "next": "^13.3.0", "next-intl": "^2.13.1", "next-useragent": "^2.8.0", diff --git a/public/fontiran.scss b/public/fontiran.scss index e263b42..33b59b4 100644 --- a/public/fontiran.scss +++ b/public/fontiran.scss @@ -16,6 +16,71 @@ 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; diff --git a/public/fonts/eot/IRANSansWeb(FaNum).eot b/public/fonts/eot/IRANSansWeb(FaNum).eot new file mode 100644 index 0000000..5a6fdd0 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum).eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot new file mode 100644 index 0000000..a012bc6 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Black.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot new file mode 100644 index 0000000..82525e5 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Bold.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot new file mode 100644 index 0000000..f899008 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Light.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot b/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot new file mode 100644 index 0000000..117c2c8 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_Medium.eot differ diff --git a/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot b/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot new file mode 100644 index 0000000..9cd9b66 Binary files /dev/null and b/public/fonts/eot/IRANSansWeb(FaNum)_UltraLight.eot differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum).ttf b/public/fonts/ttf/IRANSansWeb(FaNum).ttf new file mode 100644 index 0000000..cd74265 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum).ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf new file mode 100644 index 0000000..0f84dbf Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Black.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf new file mode 100644 index 0000000..6fa2412 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Bold.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf new file mode 100644 index 0000000..d9000c9 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Light.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf new file mode 100644 index 0000000..e20001c Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_Medium.ttf differ diff --git a/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf b/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf new file mode 100644 index 0000000..0072606 Binary files /dev/null and b/public/fonts/ttf/IRANSansWeb(FaNum)_UltraLight.ttf differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum).woff b/public/fonts/woff/IRANSansWeb(FaNum).woff new file mode 100644 index 0000000..e34dfc4 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum).woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff new file mode 100644 index 0000000..bbbca77 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Black.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff new file mode 100644 index 0000000..05d933e Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Bold.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff new file mode 100644 index 0000000..fe80d47 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Light.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff b/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff new file mode 100644 index 0000000..f13a870 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_Medium.woff differ diff --git a/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff b/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff new file mode 100644 index 0000000..9c653a4 Binary files /dev/null and b/public/fonts/woff/IRANSansWeb(FaNum)_UltraLight.woff differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum).woff2 b/public/fonts/woff2/IRANSansWeb(FaNum).woff2 new file mode 100644 index 0000000..30a377d Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum).woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 new file mode 100644 index 0000000..0b15441 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Black.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 new file mode 100644 index 0000000..f2353b2 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Bold.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 new file mode 100644 index 0000000..562d663 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Light.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 new file mode 100644 index 0000000..a69f4d0 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_Medium.woff2 differ diff --git a/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 b/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 new file mode 100644 index 0000000..1114f71 Binary files /dev/null and b/public/fonts/woff2/IRANSansWeb(FaNum)_UltraLight.woff2 differ diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 98bb15d..d77b6b8 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -94,6 +94,18 @@ }, "PassengerOffice": { "name": "نام", + "id": "کد یکتا", + "national_id": "کد ملی", + "phone_number": "موبایل", + "created_at": "تاریخ درخواست", + "updated_at": "تاریخ بروزرسانی", + "navgan_id": "کد ناوگان", + "vehicle_type": "نوع ماشین", + "state_name": "وضعیت درخواست" + }, + "TransportationAssistance": { + "name": "نام", + "id": "کد یکتا", "national_id": "کد ملی", "phone_number": "موبایل", "created_at": "تاریخ درخواست", @@ -104,6 +116,7 @@ }, "MachinaryOffice": { "name": "نام", + "id": "کد یکتا", "national_id": "کد ملی", "phone_number": "موبایل", "created_at": "تاریخ درخواست", @@ -118,7 +131,10 @@ "context": "آیا از تایید این آیتم اطمینان دارید", "button-confirm": "تایید", "button-cancel": "بستن", - "amount_error": "وارد کردن مقدار پیشنهادی الزامیست" + "amount_error": "وارد کردن مقدار پیشنهادی الزامیست", + "description_error": "وارد کردن توضیحات الزامی است!", + "description": "توضیحات", + "choose_file": "انتخاب فایل" }, "RejectDialog": { "reject": "عدم تایید", diff --git a/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx b/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx index 754abce..4e7ac76 100644 --- a/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx +++ b/src/components/dashboard/machinary-office/Form/ConfirmForm.jsx @@ -41,7 +41,9 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { setDescription(event.target.value); }; const handleAmountChange = (event) => { - setProposedAmount(event.target.value); + if (/^\d*$/.test(event.target.value)) { + setProposedAmount(event.target.value); + } formik.handleChange(event); }; @@ -65,6 +67,11 @@ const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { name="proposed_amount" label={t("MachinaryOffice.proposed_amount")} type="number" + inputProps={{ + min: 0, + inputMode: "numeric", + pattern: "[0-9]*", + }} variant="outlined" value={proposedAmount} onChange={handleAmountChange} diff --git a/src/components/dashboard/machinary-office/index.jsx b/src/components/dashboard/machinary-office/index.jsx index bcd3eb4..44b2a79 100644 --- a/src/components/dashboard/machinary-office/index.jsx +++ b/src/components/dashboard/machinary-office/index.jsx @@ -6,11 +6,36 @@ import { useMemo } from "react"; import { GET_MACHINARY_OFFICE } from "@/core/data/apiRoutes"; import { useTranslations } from "next-intl"; import TableRowActions from "./TableRowActions"; - +import { format } from "date-fns-jalali"; +import { + LocalizationProvider, + MobileDateTimePicker, +} from "@mui/x-date-pickers"; +import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import moment from "moment"; function DashboardMachinaryOfficeComponent() { const t = useTranslations(); const columns = useMemo( () => [ + { + accessorFn: (row) => row.id, + id: "id", + header: t("PassengerOffice.id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, { accessorFn: (row) => row.name, id: "name", @@ -62,39 +87,55 @@ function DashboardMachinaryOfficeComponent() { ), }, { - accessorFn: (row) => row.created_at, + accessorFn: (row) => + format(new Date(row.created_at), "HH:mm | yyyy/mm/dd"), id: "created_at", header: t("MachinaryOffice.created_at"), enableColumnFilter: true, - datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains", - "lessThan", - "greaterThan", - "between", - ], - Cell: ({ renderedCellValue }) => ( - {renderedCellValue} - ), + datatype: "date", + filterFn: "lessThan", + columnFilterModeOptions: ["lessThan", "greaterThan"], + Cell: ({ renderedCellValue }) => { + return ( + + {renderedCellValue} + + ); + }, + Header: ({ column }) => {column.columnDef.header}, + Filter: ({ column }) => { + return ( + + { + const date = new Date(newValue); + const formattedDate = moment(date) + .locale("en") + .format("YYYY-MM-DD HH:mm"); + column.setFilterValue(formattedDate); + }} + slotProps={{ + textField: { + helperText: `Filter Mode: ${column.columnDef._filterFn}`, + sx: { minWidth: "120px" }, + variant: "standard", + }, + }} + value={moment(column.getFilterValue()) + .locale("fa") + .format("yyyy/mm/dd HH:mm")} + /> + + ); + }, }, { - accessorFn: (row) => row.updated_at, + accessorFn: (row) => + format(new Date(row.updated_at), "HH:mm | yyyy/mm/dd"), id: "updated_at", header: t("MachinaryOffice.updated_at"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "numeric", - filterFn: "equals", - columnFilterModeOptions: [ - "equals", - "notEquals", - "contains", - "lessThan", - "greaterThan", - "between", - ], Cell: ({ renderedCellValue }) => ( {renderedCellValue} ), @@ -134,14 +175,12 @@ function DashboardMachinaryOfficeComponent() { accessorFn: (row) => row.state_name, id: "state_id", header: t("MachinaryOffice.state_name"), - enableColumnFilter: true, + enableColumnFilter: false, datatype: "numeric", - filterFn: "equals", - filterSelectOptions: [ - { text: "Active", value: "0" }, - { text: "Deactive", value: "1" }, - ], - filterVariant: "select", + // filterFn: "equals", + // filterSelectOptions: [ + // ], + // filterVariant: "select", Cell: ({ renderedCellValue }) => ( {renderedCellValue} ), diff --git a/src/components/dashboard/passenger-office/Form/ConfirmForm.jsx b/src/components/dashboard/passenger-office/Form/ConfirmForm.jsx index 43c6bb3..8d39af1 100644 --- a/src/components/dashboard/passenger-office/Form/ConfirmForm.jsx +++ b/src/components/dashboard/passenger-office/Form/ConfirmForm.jsx @@ -6,23 +6,116 @@ import { DialogContentText, DialogActions, Button, + TextField, + FormHelperText, } from "@mui/material"; +import { useFormik } from "formik"; import { useTranslations } from "next-intl"; +import { useRef, useState } from "react"; +const MAX_FILE_SIZE_IN_BYTES = 2 * 1024 * 1024; const ConfirmForm = ({ open, handleClose, rowId, confirmData }) => { const t = useTranslations(); - const handleConfirm = () => { - handleClose(); - confirmData(CONFIRM_PASSENGER_OFFICE, rowId); + const [description, setDescription] = useState(""); + const [fileData, setFileData] = useState(null); + const inputRef = useRef(null); + + const formik = useFormik({ + initialValues: { + description: "", + fileData: null, + }, + onSubmit: () => { + const formData = new FormData(); + if (description !== "") + formData.append("expert_description", description); + if (fileData !== null) formData.append("file", fileData); + handleClose(); + confirmData(CONFIRM_PASSENGER_OFFICE, rowId, formData); + }, + }); + + const handleUploadClick = () => { + // 👇 We redirect the click event onto the hidden input element + inputRef.current?.click(); }; + + const handleDescriptionChange = (event) => { + setDescription(event.target.value); + formik.handleChange(event); + }; + + const handleFileChange = (e) => { + const selectedFile = e.target.files[0]; + if (selectedFile) { + const fileSizeInBytes = selectedFile.size; + if (fileSizeInBytes > MAX_FILE_SIZE_IN_BYTES) { + formik.setFieldError( + "fileData", + `File size exceeds the limit (${MAX_FILE_SIZE_IN_BYTES / 1000000} MB)` + ); + e.target.value = null; + } else { + setFileData(selectedFile); + formik.setFieldValue("fileData", selectedFile); + formik.setFieldError("fileData", ""); + } + } + }; + return ( {t("ConfirmDialog.confirm")} {t("ConfirmDialog.context")} + +
+ + +
+ + {formik.errors.fileData && formik.errors.fileData} +
- + + +
+ ); +}; +export default ConfirmForm; diff --git a/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx b/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx new file mode 100644 index 0000000..262f9db --- /dev/null +++ b/src/components/dashboard/transportation-assistance/Form/RejectForm.jsx @@ -0,0 +1,75 @@ +import { REJECT_TRANSPORTATION_ASSISTANCE } from "@/core/data/apiRoutes"; +import { + Dialog, + DialogTitle, + DialogContent, + DialogContentText, + DialogActions, + Button, + TextField, +} from "@mui/material"; +import { useTranslations } from "next-intl"; +import { useFormik } from "formik"; +import * as Yup from "yup"; +import { useState } from "react"; + +const RejectForm = ({ open, handleClose, rowId, rejectData }) => { + const [description, setDescription] = useState(""); + const t = useTranslations(); + + const validationSchema = Yup.object().shape({ + description: Yup.string().required(t("RejectDialog.description_error")), + }); + + const formik = useFormik({ + initialValues: { + description: "", + }, + validationSchema, + onSubmit: () => { + const formData = new FormData(); + formData.append("expert_description", description); + handleClose(); + rejectData(REJECT_TRANSPORTATION_ASSISTANCE, rowId, formData); + }, + }); + + const handleDescriptionChange = (event) => { + setDescription(event.target.value); + formik.handleChange(event); + }; + + return ( + + {t("RejectDialog.reject")} + + {t("RejectDialog.context")} + + + + + + + + ); +}; +export default RejectForm; diff --git a/src/components/dashboard/transportation-assistance/TableRowActions.jsx b/src/components/dashboard/transportation-assistance/TableRowActions.jsx new file mode 100644 index 0000000..e9e815e --- /dev/null +++ b/src/components/dashboard/transportation-assistance/TableRowActions.jsx @@ -0,0 +1,54 @@ +import ThumbUpAltIcon from "@mui/icons-material/ThumbUpAlt"; +import ThumbDownIcon from "@mui/icons-material/ThumbDown"; +import { Box, IconButton } from "@mui/material"; +import { useContext } from "react"; +import { DataTableContext } from "@/lib/app/contexts/DataTableContext"; +import ConfirmForm from "./Form/ConfirmForm"; +import RejectForm from "./Form/RejectForm"; + +const TableRowActions = ({ row }) => { + const { + openConfirmDialog, + openRejectDialog, + handleOpenConfirmDialog, + handleOpenRejectDialog, + handleCloseConfirmDialog, + handleCloseRejectDialog, + rowId, + confirmData, + rejectData, + } = useContext(DataTableContext); + return ( + + { + handleOpenConfirmDialog(row); + }} + > + + + {openConfirmDialog && ( + + )} + handleOpenRejectDialog(row)}> + + + {openRejectDialog && ( + + )} + + ); +}; + +export default TableRowActions; diff --git a/src/components/dashboard/transportation-assistance/TableTollbar.jsx b/src/components/dashboard/transportation-assistance/TableTollbar.jsx new file mode 100644 index 0000000..3f06d3b --- /dev/null +++ b/src/components/dashboard/transportation-assistance/TableTollbar.jsx @@ -0,0 +1,13 @@ +import { Stack, Tooltip } from "@mui/material"; +import { useTranslations } from "next-intl"; + +function TableToolbar() { + const t = useTranslations(); + return ( + + + + ); +} + +export default TableToolbar; diff --git a/src/components/dashboard/transportation-assistance/index.jsx b/src/components/dashboard/transportation-assistance/index.jsx new file mode 100644 index 0000000..3b6b630 --- /dev/null +++ b/src/components/dashboard/transportation-assistance/index.jsx @@ -0,0 +1,215 @@ +import DataTableStructure from "@/core/components/DatatableStructure"; +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import { Box, Typography } from "@mui/material"; +import { useMemo } from "react"; +// import TableToolbar from "./TableTollbar"; +import { GET_TRANSPORTATION_ASSISTANCE } from "@/core/data/apiRoutes"; +import { useTranslations } from "next-intl"; +import TableRowActions from "./TableRowActions"; +import { format } from "date-fns-jalali"; +import { + LocalizationProvider, + MobileDateTimePicker, +} from "@mui/x-date-pickers"; +import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali"; +import moment from "moment"; +function DashboardTransportationAssistanceComponent() { + const t = useTranslations(); + const columns = useMemo( + () => [ + { + accessorFn: (row) => row.id, + id: "id", + header: t("TransportationAssistance.id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.name, + id: "name", + header: t("TransportationAssistance.name"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + + { + accessorFn: (row) => row.national_id, + id: "national_id", + header: t("TransportationAssistance.national_id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.phone_number, + id: "phone_number", + header: t("TransportationAssistance.phone_number"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => + format(new Date(row.created_at), "HH:mm | yyyy/mm/dd"), + id: "created_at", + header: t("TransportationAssistance.created_at"), + enableColumnFilter: true, + datatype: "date", + filterFn: "lessThan", + columnFilterModeOptions: ["lessThan", "greaterThan"], + Cell: ({ renderedCellValue }) => ( + + {renderedCellValue} + + ), + Header: ({ column }) => {column.columnDef.header}, + Filter: ({ column }) => { + return ( + + { + const date = new Date(newValue); + const formattedDate = moment(date) + .locale("en") + .format("YYYY-MM-DD HH:mm"); + column.setFilterValue(formattedDate); + }} + slotProps={{ + textField: { + helperText: `Filter Mode: ${column.columnDef._filterFn}`, + sx: { minWidth: "120px" }, + variant: "standard", + }, + }} + value={moment(column.getFilterValue()) + .locale("fa") + .format("yyyy/mm/dd HH:mm")} + /> + + ); + }, + }, + { + accessorFn: (row) => + format(new Date(row.updated_at), "HH:mm | yyyy/mm/dd"), + id: "updated_at", + header: t("TransportationAssistance.updated_at"), + enableColumnFilter: false, + datatype: "numeric", + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.navgan_id, + id: "navgan_id", + header: t("TransportationAssistance.navgan_id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.vehicle_type, + id: "vehicle_type", + header: t("TransportationAssistance.vehicle_type"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.state_name, + id: "state_id", + header: t("TransportationAssistance.state_name"), + enableColumnFilter: false, + datatype: "numeric", + // filterFn: "equals", + // filterSelectOptions: [ + // ], + // filterVariant: "select", + Cell: ({ renderedCellValue }) => ( + {renderedCellValue} + ), + }, + ], + [] + ); + return ( + + + } + enableLastUpdate={true} + enablePinning={true} + enableDensityToggle={true} + enableColumnFilters={true} + enableHiding={true} + enableFullScreenToggle={false} + enableGlobalFilter={false} + enableColumnResizing={false} // if you want true this you shold change renderRowActions props ** see https://www.material-react-table.com/docs/guides/row-actions + enableRowActions={true} + renderRowActions={({ row }) => } + /> + + + ); +} + +export default DashboardTransportationAssistanceComponent; diff --git a/src/core/components/Datatable.jsx b/src/core/components/Datatable.jsx index 149c543..04be089 100644 --- a/src/core/components/Datatable.jsx +++ b/src/core/components/Datatable.jsx @@ -3,7 +3,7 @@ import useLanguage from "@/lib/app/hooks/useLanguage"; import { Typography } from "@mui/material"; import axios from "axios"; import MaterialReactTable from "material-react-table"; -import moment from "moment"; +import moment from "moment-jalaali"; import { useTranslations } from "next-intl"; import { useContext, useEffect, useMemo, useState } from "react"; import useSWR from "swr"; @@ -12,6 +12,7 @@ const DataTable = (props) => { const { reloadDataTable, setReloadDataTable } = useContext( ReloadDataTableContext ); + const fetcher = (...args) => { return axios .get(args, { @@ -43,8 +44,9 @@ const DataTable = (props) => { const [sorting, setSorting] = useState([]); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); const [rowCount, setRowCount] = useState(0); + console.log(moment()); const [updateTime, setupdateTime] = useState( - moment().locale(languageApp).format("LL (HH:mm:ss)") + moment().format("HH:mm | jYYYY/jM/jD") ); const tableLocalization = useMemo( @@ -97,7 +99,7 @@ const DataTable = (props) => { }, [reloadDataTable, setReloadDataTable]); useEffect(() => { - setupdateTime(moment().locale(languageApp).format("LL (HH:mm:ss)")); + setupdateTime(moment().format("HH:mm | jYYYY/jM/jD")); }, [isValidating, languageApp]); return ( diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index 79046bc..716ca0f 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -23,6 +23,16 @@ export const REJECT_PASSENGER_OFFICE = BASE_URL + "/dashboard/passenger_office_chief/reject"; //passenger office +//transportation assistance +export const GET_TRANSPORTATION_ASSISTANCE = + BASE_URL + "/dashboard/transportation_assistant/show"; + +export const CONFIRM_TRANSPORTATION_ASSISTANCE = + BASE_URL + "/dashboard/transportation_assistant/confirm"; + +export const REJECT_TRANSPORTATION_ASSISTANCE = + BASE_URL + "/dashboard/transportation_assistant/reject"; +//transportation assistance //machinary office export const GET_MACHINARY_OFFICE = BASE_URL + "/dashboard/machinery_expert/show"; diff --git a/src/core/utils/theme-rtl.jsx b/src/core/utils/theme-rtl.jsx index c36abeb..2d0fdab 100644 --- a/src/core/utils/theme-rtl.jsx +++ b/src/core/utils/theme-rtl.jsx @@ -4,7 +4,7 @@ import theme from "./theme"; const themeRtl = createTheme({ direction: "rtl", typography: { - fontFamily: `IRANSans, sans-serif`, + fontFamily: `IRANSansFaNum, sans-serif`, }, ...theme, }); diff --git a/src/pages/dashboard/transportation-assistance/index.jsx b/src/pages/dashboard/transportation-assistance/index.jsx new file mode 100644 index 0000000..9c089ad --- /dev/null +++ b/src/pages/dashboard/transportation-assistance/index.jsx @@ -0,0 +1,23 @@ +import DashboardTransportationAssistanceComponent from "@/components/dashboard/transportation-assistance"; +import TitlePage from "@/core/components/TitlePage"; +import WithAuthMiddleware from "@/middlewares/WithAuth"; +import { parse } from "next-useragent"; + +export default function TransportationAssistance() { + return ( + + + + + ); +} + +export async function getServerSideProps({ req, locale }) { + const { isBot } = parse(req.headers["user-agent"]); + return { + props: { + messages: (await import(`&/locales/${locale}/app.json`)).default, + isBot, + }, + }; +}