From 96835cf13fcdf350aa7dc70a73512d099599f279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=AD=D8=B3=DB=8C=D9=86=20=D9=85=D8=B9=D8=B5=D9=88=D9=85?= =?UTF-8?q?=DB=8C=20=D9=BE=D9=88=D8=B1?= Date: Thu, 22 Feb 2024 12:13:03 +0330 Subject: [PATCH] report --- .env | 6 +- components/LoginComponents/LoginStep.jsx | 6 - plugins/BottomSheet/BottomSheetReport.jsx | 62 ++++++ plugins/Buttonbriz/page.jsx | 6 +- src/app/layout.jsx | 222 ++++++++++++++++------ src/app/shifts/complete-shift/page.jsx | 85 ++++++--- src/app/shifts/manage-shift/page.jsx | 220 +++++++++++++-------- src/app/shifts/page.jsx | 108 ++++++++++- src/app/tasks/page.jsx | 23 +++ 9 files changed, 553 insertions(+), 185 deletions(-) create mode 100644 plugins/BottomSheet/BottomSheetReport.jsx diff --git a/.env b/.env index 023304b..bf70d31 100644 --- a/.env +++ b/.env @@ -1,8 +1,8 @@ NODE_ENV="development" -NEXT_PUBLIC_SERVER_URL=http://192.168.88.12:32769 -NEXT_PUBLIC_PUBLIC_URL=http://192.168.88.12:32769 -NEXT_PUBLIC_API_URL=http://192.168.88.12:32769/api +NEXT_PUBLIC_SERVER_URL=http://192.168.189.123:32769 +NEXT_PUBLIC_PUBLIC_URL=http://192.168.189.123:32769 +NEXT_PUBLIC_API_URL=http://192.168.189.123:32769/api # SECURE_LOCAL_STORAGE_HASH_KEY=f1da2b2c7a4c446934267fea631102ec389b5b99 # NEXT_PUBLIC_API_URL_IMAGE=https://192.168.88.12:49154/Files/ReportImages diff --git a/components/LoginComponents/LoginStep.jsx b/components/LoginComponents/LoginStep.jsx index e57c4ea..4107123 100644 --- a/components/LoginComponents/LoginStep.jsx +++ b/components/LoginComponents/LoginStep.jsx @@ -63,12 +63,6 @@ const LoginStep = (props) => { }`} >
- {/* */} - { + const CTX = useContext(AppContext); + const reportDetail = CTX.state.reportDetail; + + const handleSendReport_SHIFTPLAN = () => { + CTX.ReportShiftPlan(reportDetail?.shiftId); + CTX.setBottomSheetReportOpen(false); + }; + + const handleSendReport_TASK = () => { + CTX.ReportTask(); + CTX.setBottomSheetReportOpen(false); + }; + + return ( + CTX.setBottomSheetReportOpen(false)} + blocking={false} + > +
+

گزارشات

+
+ +
+

+ شما در حال گرفتن گزارش برای + {reportDetail?.title} + هستید +

+
+ +
+ { + if (reportDetail.typeReport == "TASK") { + handleSendReport_TASK(); + } else if (reportDetail.typeReport == "SHIFTPLAN") { + handleSendReport_SHIFTPLAN(); + } + }} + /> +
+
+ ); +}; + +export default BottomSheetReport; diff --git a/plugins/Buttonbriz/page.jsx b/plugins/Buttonbriz/page.jsx index e651cf9..8c662af 100644 --- a/plugins/Buttonbriz/page.jsx +++ b/plugins/Buttonbriz/page.jsx @@ -86,7 +86,7 @@ const Buttonbriz = ({ > {icons.find((e) => e.iconName == icon)?.icon}
- {title} + {title}
@@ -102,7 +102,9 @@ const Buttonbriz = ({ >

{subButtonTitle} diff --git a/src/app/layout.jsx b/src/app/layout.jsx index 3a18bba..92c3d62 100644 --- a/src/app/layout.jsx +++ b/src/app/layout.jsx @@ -19,6 +19,7 @@ import Chapar, { getToken } from "plugins/Chapar"; import TimePicker from "plugins/TimePicker/page"; import axios from "axios"; import "rc-slider/assets/index.css"; +import BottomSheetReport from "plugins/BottomSheet/BottomSheetReport"; const inter = Inter({ subsets: ["latin"] }); @@ -55,6 +56,8 @@ export default function RootLayout({ children }) { const [BottomSheetChangeRoleOpen, setBottomSheetChangeRoleOpen] = useState(false); + const [BottomSheetReportOpen, setBottomSheetReportOpen] = useState(false); + // BigPlus const [BigPlusOpen, setBigPlusOpen] = useState(false); const [BigPlusRotateIcon, setBigPlusRotateIcon] = useState(false); @@ -117,6 +120,7 @@ export default function RootLayout({ children }) { const [goToEditShift, setGoToEditShift] = useState(false); const [idEditShift, setIdEditShift] = useState(null); const [shiftPlanData, setShiftPlanData] = useState([]); + const [shiftPlansData, setShifPlansData] = useState([]); // task const [routineForTaskChoose, setRoutineForTaskChoose] = useState([]); @@ -145,6 +149,9 @@ export default function RootLayout({ children }) { // closeShift const [completeActivities, setCompleteActivities] = useState([]); + //report + const [reportDetail, setReportDetail] = useState(null); + const pathname = usePathname(); const router = useRouter(); const hiddenUrls = ["/login", "/pricing", "/about-us", "/"]; @@ -263,7 +270,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateRole = async (body) => { setLoading(true); try { @@ -388,7 +394,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateUser = async (body) => { setLoading(true); try { @@ -514,7 +519,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateShift = async (body) => { setLoading(true); try { @@ -600,57 +604,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - - const GetShiftPlan = async (id) => { - setLoading(true); - try { - const data = await Chapar.get( - `${process.env.NEXT_PUBLIC_API_URL}/shift/plan/${id}`, - { - headers: { - Authorization: getToken(), - }, - } - ); - setShiftPlanData(data); - setLoading(false); - } catch ({ error, status }) { - toast.error(`${error?.response?.data?.message}`, { - position: "bottom-right", - closeOnClick: true, - }); - setLoading(false); - } - }; - const UpdateShiftPlan = async (body, id) => { - setLoading(true); - try { - const data = await Chapar.put( - `${process.env.NEXT_PUBLIC_API_URL}/shift/plan`, - body, - - { - headers: { - Authorization: getToken(), - }, - } - ); - toast.success(`شیفت ویرایش شد`, { - position: "bottom-right", - closeOnClick: true, - }); - - setLoading(false); - setShiftPlanData(id); - } catch ({ error, status }) { - toast.error(`${error?.response?.data?.message}`, { - position: "bottom-right", - closeOnClick: true, - }); - setLoading(false); - } - }; - const GetShift = async (id) => { setLoading(true); try { @@ -697,7 +650,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateSection = async (body) => { setLoading(true); try { @@ -822,7 +774,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateRoutine = async (body) => { setLoading(true); try { @@ -927,7 +878,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const GetRoutineShiftPlan = async (id, time) => { setLoading(true); try { @@ -951,6 +901,56 @@ export default function RootLayout({ children }) { setLoading(false); } }; + const GetShiftPlan = async (id) => { + setLoading(true); + try { + const data = await Chapar.get( + `${process.env.NEXT_PUBLIC_API_URL}/shift/plan/${id}`, + { + headers: { + Authorization: getToken(), + }, + } + ); + setShiftPlanData(data); + setLoading(false); + } catch ({ error, status }) { + toast.error(`${error?.response?.data?.message}`, { + position: "bottom-right", + closeOnClick: true, + }); + setLoading(false); + } + }; + const UpdateShiftPlan = async (body, id) => { + setLoading(true); + try { + const data = await Chapar.put( + `${process.env.NEXT_PUBLIC_API_URL}/shift/plan`, + body, + + { + headers: { + Authorization: getToken(), + }, + } + ); + toast.success(`شیفت ویرایش شد`, { + position: "bottom-right", + closeOnClick: true, + }); + + setLoading(false); + setShiftPlanData(id); + router.push("/shifts"); + } catch ({ error, status }) { + toast.error(`${error?.response?.data?.message}`, { + position: "bottom-right", + closeOnClick: true, + }); + setLoading(false); + } + }; const CreateShifPlan = async (body) => { setLoading(true); try { @@ -967,6 +967,8 @@ export default function RootLayout({ children }) { position: "bottom-right", closeOnClick: true, }); + + router.push("/shifts"); } catch ({ error, status }) { toast.error(`${error?.response?.data?.message}`, { position: "bottom-right", @@ -975,7 +977,31 @@ export default function RootLayout({ children }) { setLoading(false); } }; + const GetShifPlans = async (page) => { + setLoading(true); + try { + const data = await Chapar.get( + `${process.env.NEXT_PUBLIC_API_URL}/shift/plan?page=${page}`, + { + headers: { + Authorization: getToken(), + }, + } + ); + console.log(data); + + setShifPlansData(data); + + setLoading(false); + } catch ({ error, status }) { + toast.error(`${error?.response?.data?.message}`, { + position: "bottom-right", + closeOnClick: true, + }); + setLoading(false); + } + }; const DeleteRoutine = async (id) => { setLoading(true); try { @@ -1000,7 +1026,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreatePosition = async (body) => { setLoading(true); try { @@ -1125,7 +1150,6 @@ export default function RootLayout({ children }) { setLoading(false); } }; - const CreateTask = async (body) => { setLoading(true); try { @@ -1427,6 +1451,76 @@ export default function RootLayout({ children }) { } }; + const ReportShiftPlan = async (shiftPlanId) => { + setLoading(true); + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/report/shift/plan/${shiftPlanId}`, + { + headers: { + Authorization: getToken(), + }, + } + ); + + if (!response.ok) { + throw new Error("Failed to download report"); + } + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "report.xlsx"; // Change the filename if needed + document.body.appendChild(a); + a.click(); + a.remove(); + + setLoading(false); + } catch (error) { + toast.error(error.message, { + position: "bottom-right", + closeOnClick: true, + }); + setLoading(false); + } + }; + + const ReportTask = async () => { + setLoading(true); + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/report/task`, + { + headers: { + Authorization: getToken(), + }, + } + ); + + if (!response.ok) { + throw new Error("Failed to download report"); + } + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "report.xlsx"; // Change the filename if needed + document.body.appendChild(a); + a.click(); + a.remove(); + + setLoading(false); + } catch (error) { + toast.error(error.message, { + position: "bottom-right", + closeOnClick: true, + }); + setLoading(false); + } + }; + useEffect(() => { console.log(` bbbbbbbb @@ -1526,6 +1620,9 @@ export default function RootLayout({ children }) { pageGetTasks, stopGetActivities, pageGetActivity, + shiftPlansData, + BottomSheetReportOpen, + reportDetail, }, setBottomSheetCreateRoleOpen, setBottomSheetCreateEmployeesOpen, @@ -1641,6 +1738,12 @@ export default function RootLayout({ children }) { setPageGetTasks, setStopGetActivities, setPageGetActivity, + setShifPlansData, + GetShifPlans, + setBottomSheetReportOpen, + setReportDetail, + ReportShiftPlan, + ReportTask, }} > @@ -1649,6 +1752,7 @@ export default function RootLayout({ children }) { {shouldRenderComponent && } + {openTimePicker && } {BigPlusOpen ? ( diff --git a/src/app/shifts/complete-shift/page.jsx b/src/app/shifts/complete-shift/page.jsx index c7e0b69..30c8c10 100644 --- a/src/app/shifts/complete-shift/page.jsx +++ b/src/app/shifts/complete-shift/page.jsx @@ -134,6 +134,15 @@ const CompleteShift = () => { // ; }; + const handleGoToReport = (title, shiftId) => { + CTX.setReportDetail({ + title: title, + shiftId: shiftId, + typeReport: "SHIFTPLAN", + }); + CTX.setBottomSheetReportOpen(true); + }; + useEffect(() => { handleDayCloseShift(1); }, []); @@ -173,7 +182,7 @@ const CompleteShift = () => { />

-
+
{ className={`bg-gray-200 p-2 rounded-full flex justify-between ${ activeShifPlan == index ? "bg-gray-300 " : "bg-gray-200 " } `} - onClick={() => - handleOpenShift( - e?.isCompleted, - e?.id, - index, - e?.hasCurrentShiftPlan - ) - } > -

{e?.title}

- -
-
-

- {" "} - - فعالیت -

-
- - {e?.undoneActivitiesCount != 0 && ( -
-

+

+ handleOpenShift( + e?.isCompleted, + e?.id, + index, + e?.hasCurrentShiftPlan + ) + } + > +

{e?.title}

+
+
+

{" "} + {!e?.isCompleted && "فعالیت"}

- )} + {e?.undoneActivitiesCount != 0 && ( +
+

+ {" "} + +

+
+ )} +
+
+ +
{e?.isCompleted && ( -
+
+ handleGoToReport(e.title, e.currentShiftPlanId) + } + >

{" "} - بسته شده + گزارش شیفت{" "}

)} diff --git a/src/app/shifts/manage-shift/page.jsx b/src/app/shifts/manage-shift/page.jsx index 140686e..8f56b1f 100644 --- a/src/app/shifts/manage-shift/page.jsx +++ b/src/app/shifts/manage-shift/page.jsx @@ -33,6 +33,8 @@ const Calendar = () => { const [shiftsPlan, setShiftsPlan] = useState([]); const [manageShiftEmployeesData, setManageShiftEmployeesData] = useState([]); const [editManageShift, setEditManageShift] = useState(false); + const [superId, setSuperId] = useState(null); + const [superData, setSuperData] = useState(false); const [shiftPlanSteps, setShiftPlanSteps] = useState(0); @@ -110,6 +112,7 @@ const Calendar = () => { 1000, shiftId: shiftsPlan && shiftsPlan[selectShift]?.id, routineId: routinesData && routinesData[selectRoutine]?.id, + supervisionUserId: superId, userAndPositionIds, }; @@ -121,6 +124,7 @@ const Calendar = () => { shiftId: shiftsPlan && shiftsPlan[selectShift]?.id, routineId: routinesData && routinesData[selectRoutine]?.id, userAndPositionIds, + supervisionUserId: superId, id: currentShiftPlanId, }; @@ -143,10 +147,8 @@ const Calendar = () => { const handleCreateShiftPlan = (update) => { if (update == "UPDATE") { CTX.UpdateShiftPlan(bodyUpdate); - setShiftPlanSteps(1); } else { CTX.CreateShifPlan(body); - setShiftPlanSteps(1); } }; @@ -195,8 +197,25 @@ const Calendar = () => { setUserAndPositionIds( shiftPlanData?.users?.map((e) => ({ key: e.positionId, value: e.userId })) ); + + setSuperId(shiftPlanData?.supervisorId); }, [shiftPlanData]); + useEffect(() => { + const userJustSuper = usersData?.filter((obj) => + obj.roleNames.includes("سوپروایزر") + ); + + setSuperData( + userJustSuper?.map((item) => ({ + key: item.firstName + " " + item.lastName, + value: item.userId, + })) + ); + }, [usersData]); + + console.log(superData, usersData); + return (
{ }} /> -
-
+
+

روتین را انتخاب کنید

{ } }} > -

{e.name}

+

{e.name}

))}
+
- {shiftPlanSteps >= 1 && ( + {shiftPlanSteps >= 0 && ( +
<> -
+

تاریخ را انتخاب کنید

{ : " opacity-70" }`} key={index} - onClick={() => handleRoutineShiftPlanWithDay(index)} + onClick={() => { + if (shiftPlanSteps >= 1) { + handleRoutineShiftPlanWithDay(index); + } else { + toast.error(`ابتدا روتین را انتخاب کنید`, { + position: "bottom-right", + closeOnClick: true, + }); + } + }} >

@@ -309,14 +339,13 @@ const Calendar = () => { ))} - )} -

- - {shiftPlanSteps >= 2 && ( +
+ )} + {shiftPlanSteps >= 0 && ( <>
<> -
+

شیفت را انتخاب کنید

{!!routineShiftPlan?.find( @@ -338,7 +367,7 @@ const Calendar = () => { setShiftPlanSteps(3); }} > -

{e?.title}

+

{e?.title}

))}
@@ -357,8 +386,8 @@ const Calendar = () => { )} {shiftPlanSteps >= 3 && ( -
-
+
+

ویرایش برای{" "} @@ -376,6 +405,9 @@ const Calendar = () => {

+
+

پرسنل را انتخاب کنید

+
{positionsData.map((e) => (
@@ -397,84 +429,104 @@ const Calendar = () => {
- {/*
- { - setSearchUserCurrntData(e.target.value); - - if (!!searchUserChoose.find((b) => b == e.target.value)) { - toast.error("نقش تکراری است", { - position: "bottom-right", - closeOnClick: true, - }); - } else { - CTX.setSearchUserChoose((current) => [ - ...current, - e.target.value, - ]); - } - }} - style="text-right" - select={true} - selectData={manageShiftEmployeesData} - theme={1} - defaultValue={"انتخاب کنید"} - /> -
*/} -
0 ? "" : "justify-center" }`} > - {userAndPositionIds?.length > 0 ? ( - userAndPositionIds?.map((item) => ( - <> - {e.id == item.key && ( -
-
deleteSearchUser(e)} - > - b?.userId == item?.value) - ?.firstName - } - variant="beam" - colors={["#9d9f88", "#83af96", "#b2de93"]} - /> -
+ {userAndPositionIds?.length > 0 + ? userAndPositionIds?.map((item) => ( + <> + {e.id == item.key && ( +
+
deleteSearchUser(e)} + > + b?.userId == item?.value + )?.firstName + } + variant="beam" + colors={["#9d9f88", "#83af96", "#b2de93"]} + /> +
-
-

- { - usersData.find((b) => b.userId == item?.value) - ?.firstName - } -

+
+

+ { + usersData.find((b) => b.userId == item?.value) + ?.firstName + } +

+
-
- )} - - )) - ) : ( -
-
- چیزی یافت نشد -
-
- )} + )} + + )) + : ""}
))} -
+ +
+
+

+ سوپروایزر را انتخاب کنید + (ضروری) +

+

+ شیفت توسط سوپروایزر بسته میشود لطفا برای هر شیفت آن را مشخص کنید +

+
+ +
+ { + setSuperId(e.target.value); + console.log(e.target.value); + }} + style="text-right" + select={true} + selectData={superData} + defaultValue={"انتخاب کنید"} + theme={1} + /> +
+
+ +
+

غیر فعال کردن شیفت

+
+
+ setRoleCheckBox(e.target.checked)} + /> +
+

+ با خاموش کردن شیفت فعالیت ها برای افراد داخل شیفت خاموش میشود{" "} +

+
+
+ +
{editManageShift ? ( { const CTX = useContext(AppContext); const router = useRouter(); + const [shiftplans, setShiftplans] = useState([]); + const [shiftPlansSelect, setShiftPlansSelect] = useState(0); + + const shiftplansData = CTX.state.shiftPlansData; + + const groupObjectsByPlanFor = (responseData) => { + const groupedData = {}; + + // Iterate through the array + responseData.forEach((obj) => { + const { planFor } = obj; + + // If the planFor value is not in the groupedData object, create a new array + if (!groupedData[planFor]) { + groupedData[planFor] = [obj]; + } else { + // If the planFor value already exists, push the object into the existing array + groupedData[planFor].push(obj); + } + }); + + // Sort the objects within each group by the planFor date + Object.keys(groupedData).forEach((key) => { + groupedData[key].sort( + (a, b) => new Date(a.planFor) - new Date(b.planFor) + ); + }); + + // Convert the groupedData object into an array of objects + const groupedArray = Object.keys(groupedData).map((key) => ({ + planFor: key, + data: groupedData[key], + })); + + // Sort the groupedArray by the planFor date + groupedArray.sort((a, b) => new Date(a.planFor) - new Date(b.planFor)); + + console.log(groupedArray); + setShiftplans(groupedArray); + }; + + useEffect(() => { + CTX.GetShifPlans(0); + }, []); + + useEffect(() => { + groupObjectsByPlanFor(shiftplansData); + }, [shiftplansData]); + return ( <>
@@ -62,7 +113,62 @@ const Shifts = (props) => {
-
+
+ {shiftplans?.map((e, index) => ( + <> +
+
setShiftPlansSelect(index)} + > +
+ +
+ +
+

+ + شیفت +

+
+
+ + {shiftPlansSelect == index && ( +
+ {e.data.map((e) => ( +
+

+ {" "} + {e.shiftTitle} +

+ +
+

+ + فعالیت +

+
+
+ ))} +
+ )} +
+ + ))} +
); diff --git a/src/app/tasks/page.jsx b/src/app/tasks/page.jsx index dbe8cf1..9d38c3c 100644 --- a/src/app/tasks/page.jsx +++ b/src/app/tasks/page.jsx @@ -44,6 +44,7 @@ const page = () => { CTX.setPageGetTasks((e) => e + 1); CTX.GetTasks(pageGetTasks + 1); }; + const handleInfiniteNextFetchActivity = () => { CTX.setPageGetActivity((e) => e + 1); CTX.GetActivity( @@ -53,6 +54,15 @@ const page = () => { ); }; + const handleGoToReport = () => { + CTX.setReportDetail({ + title: "فعالیت های مجموعه", + shiftId: "", + typeReport: "TASK", + }); + CTX.setBottomSheetReportOpen(true); + }; + console.log(activities.length); return ( @@ -75,7 +85,20 @@ const page = () => { GoBack(); }} /> +
+
handleGoToReport()} + > +
+

خروجی گرفتن از فعالیت ها

+
+
+
+
+
+
{!!HasPermission("ManageTasks", permissions) && (