425 lines
14 KiB
JavaScript
425 lines
14 KiB
JavaScript
"use client";
|
|
|
|
import React, { useContext, useEffect, useState } from "react";
|
|
import moment from "jalali-moment";
|
|
import "moment/locale/fa"; // Set the locale to Farsi (Persian)
|
|
import AppHeader from "@comp/AppHeader/page";
|
|
import { Swiper, SwiperSlide } from "swiper/react";
|
|
import PersianNumber from "plugins/PersianNumber";
|
|
import { PersianD, PersianDay, PersianM, holidays } from "datacalender";
|
|
import AppContext from "@ctx/AppContext";
|
|
import Input from "plugins/Input/page";
|
|
import { toast } from "react-toastify";
|
|
import Avatar from "boring-avatars";
|
|
import BottomManageShift from "plugins/BottomSheet/BottomManageShift";
|
|
import BottomSheetAddUserToPositionShiftPlan from "plugins/BottomSheet/BottomSheetAddUserToPositionShiftPlan";
|
|
import Buttonbriz from "plugins/Buttonbriz/page";
|
|
|
|
const Calendar = () => {
|
|
const CTX = useContext(AppContext);
|
|
const shiftsData = CTX.state.shiftsData;
|
|
const searchUserChoose = CTX.state.searchUserChoose;
|
|
const usersData = CTX.state.usersData;
|
|
const routinesData = CTX.state.routinesData;
|
|
const routineShiftPlan = CTX.state.routineShiftPlan;
|
|
const positionsData = CTX.state.positionsData;
|
|
|
|
const [daysUntilWeek, setDaysUntilWeek] = useState([]);
|
|
const [selectDay, setSelectDay] = useState(null);
|
|
const [selectShift, setselectShift] = useState(-1);
|
|
const [selectRoutine, setSelectRoutine] = useState(-1);
|
|
const [shiftsPlan, setShiftsPlan] = useState([]);
|
|
const [manageShiftEmployeesData, setManageShiftEmployeesData] = useState([]);
|
|
|
|
const [shiftPlanSteps, setShiftPlanSteps] = useState(0);
|
|
|
|
const [positionSelectNameBottomSheet, setPositionSelectNameBottomSheet] =
|
|
useState([]);
|
|
const [positionSelectIdBottomSheet, setPositionSelectIdBottomSheet] =
|
|
useState([]);
|
|
const [userAndPositionIds, setUserAndPositionIds] = useState([]);
|
|
|
|
const week = [
|
|
{ key: "شنبه", value: 6 },
|
|
{ key: "یکشنبه", value: 0 },
|
|
{ key: "دوشنبه", value: 1 },
|
|
{ key: "سه شنبه", value: 2 },
|
|
{ key: "چهار شنبه", value: 3 },
|
|
{ key: "پنج شنبه", value: 4 },
|
|
{ key: "جمعه", value: 5 },
|
|
];
|
|
const today = moment().format("jYYYY/jM/jD"); // Get the current Jalali date
|
|
|
|
const daysInCurrentMonth = moment(today, "jYYYY/jM/jD")
|
|
.endOf("jMonth")
|
|
.jDate();
|
|
|
|
const daysEndOfMonth = () => {
|
|
const daysOfWeek = [];
|
|
const startOfNextWeek = moment(today, "jYYYY/jM/jD")
|
|
.startOf("jWeek")
|
|
.add(7, "days");
|
|
// Iterate from شنبه (Saturday) to جمعه (Friday) and add each day to the array
|
|
for (let i = 0; i < 7; i++) {
|
|
const currentDay = startOfNextWeek.clone().add(i, "days");
|
|
const isToday = currentDay.isSame(today, "day");
|
|
const dayOfWeekName = week[i].key; // Get the day name from the week array
|
|
|
|
daysOfWeek.push({
|
|
checkDay: currentDay.format("jYYYY/jM/jD"),
|
|
date: currentDay.format("jD / jM"),
|
|
dayOfWeek: dayOfWeekName,
|
|
today: isToday,
|
|
value: week[i].value,
|
|
});
|
|
}
|
|
|
|
return setDaysUntilWeek(daysOfWeek);
|
|
};
|
|
|
|
const handleManageShiftEmployeesOpen = (e) => {
|
|
setManageShiftEmployeesData(
|
|
usersData.map((item) => ({
|
|
key:
|
|
item.firstName +
|
|
" " +
|
|
item.lastName +
|
|
"( " +
|
|
item.roleNames[0] +
|
|
" )",
|
|
|
|
value: item.userId,
|
|
}))
|
|
);
|
|
};
|
|
|
|
const body = {
|
|
planDate:
|
|
daysUntilWeek[selectDay]?.checkDay &&
|
|
moment.utc(daysUntilWeek[selectDay].checkDay, "jYYYY-jMM-jDDTHH").unix(),
|
|
shiftId: shiftsPlan && shiftsPlan[selectShift]?.id,
|
|
routineId: routinesData && routinesData[selectRoutine]?.id,
|
|
userAndPositionIds,
|
|
};
|
|
|
|
const handleRoutineShiftPlan = (index, id) => {
|
|
setSelectRoutine(index);
|
|
CTX.GetRoutineShiftPlan(id);
|
|
setShiftPlanSteps(1);
|
|
};
|
|
|
|
const handleCreateShiftPlan = (update) => {
|
|
if (update == "UPDATE") {
|
|
// CTX.UpdateShiftPlan(bodyUpdate);
|
|
} else {
|
|
CTX.CreateShifPlan(body);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
CTX.GetRoutines();
|
|
daysEndOfMonth();
|
|
setSelectDay(-1);
|
|
CTX.GetShifts();
|
|
CTX.GetPositions();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
handleManageShiftEmployeesOpen();
|
|
}, [usersData]);
|
|
|
|
useEffect(() => {
|
|
setShiftsPlan(
|
|
routineShiftPlan?.find((e) => e?.day == daysUntilWeek[selectDay]?.value)
|
|
?.shifts
|
|
);
|
|
|
|
setselectShift(-1);
|
|
}, [selectDay]);
|
|
|
|
return (
|
|
<div className="pb-20">
|
|
<AppHeader
|
|
title=" شیفت بندی های هفتگی"
|
|
sub={`شیفت بندی
|
|
تا
|
|
${daysInCurrentMonth}
|
|
${PersianM(moment().format("jM"))}
|
|
|
|
`}
|
|
icon2={true}
|
|
iconName2="ARROW"
|
|
iconHref2="/home"
|
|
/>
|
|
|
|
<div className="bg-body-100 relative top-[-30px] rounded-t-3xl overflow-hidden p-4 rtl">
|
|
<div
|
|
className="flex overflow-auto whitespace-nowrap mb-5"
|
|
id="swich-shifts"
|
|
>
|
|
{routinesData?.map((e, index) => (
|
|
<div
|
|
className={` shadow-sm relative block max-w-max mx-2 rounded-full mt-2 px-4 py-2 tr03 ${
|
|
selectRoutine == index
|
|
? "bg-secondary-100 text-white"
|
|
: "bg-white opacity-60"
|
|
}`}
|
|
onClick={() => {
|
|
if (shiftPlanSteps >= 1) {
|
|
toast.error("برای تغییر روتین باید رفرش کنید", {
|
|
position: "bottom-right",
|
|
autoClose: 2000,
|
|
hideProgressBar: false,
|
|
closeOnClick: true,
|
|
pauseOnHover: true,
|
|
draggable: true,
|
|
progress: undefined,
|
|
});
|
|
} else {
|
|
handleRoutineShiftPlan(index, e.id);
|
|
}
|
|
}}
|
|
>
|
|
<p className="mb-0">{e.name}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{shiftPlanSteps >= 1 && (
|
|
<Swiper
|
|
spaceBetween={10}
|
|
slidesPerView={4.3}
|
|
onSlideChange={() => console.log("slide change")}
|
|
onSwiper={(swiper) => console.log(swiper)}
|
|
>
|
|
{daysUntilWeek?.map((e, index) => (
|
|
<SwiperSlide>
|
|
<div
|
|
className={`h-[70px] tr03 ${
|
|
selectDay == index ? "bg-white rounded-xl" : " opacity-70"
|
|
}`}
|
|
key={index}
|
|
onClick={() => {
|
|
setSelectDay(index);
|
|
setShiftPlanSteps(2);
|
|
console.log(index);
|
|
}}
|
|
>
|
|
<div className="py-2">
|
|
<p className="mb-0 text-center ">
|
|
<PersianNumber
|
|
number={e.date}
|
|
style={`text-[20px] ${
|
|
selectDay == index
|
|
? "font-bold"
|
|
: !!holidays.y1402?.find(
|
|
(b) => b.date == e.checkDay
|
|
)
|
|
? "text-red-500"
|
|
: ""
|
|
} `}
|
|
/>
|
|
</p>
|
|
</div>
|
|
|
|
<div
|
|
className={`w-fit mx-auto sahdow px-1 rounded-full ${
|
|
selectDay == index
|
|
? "bg-secondary-100 text-gray-100"
|
|
: !!holidays.y1402?.find((b) => b.date == e.checkDay)
|
|
? "bg-transparent text-red-500"
|
|
: "bg-white text-gray-500"
|
|
}`}
|
|
>
|
|
<p className="mb-0 text-center text-sm ">
|
|
{/* {PersianD.find((i) => i == e.dayOfWeek)} */}
|
|
{e.dayOfWeek}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</SwiperSlide>
|
|
))}
|
|
</Swiper>
|
|
)}
|
|
</div>
|
|
|
|
{shiftPlanSteps >= 2 && (
|
|
<div className="bg-body-100 relative top-[-30px] rounded-t-3xl overflow-hidden rtl">
|
|
<>
|
|
{!!routineShiftPlan?.find(
|
|
(e) => e?.day == daysUntilWeek[selectDay]?.value
|
|
) && shiftsData.length > 0 ? (
|
|
<div
|
|
className="flex overflow-auto whitespace-nowrap"
|
|
id="swich-shifts"
|
|
>
|
|
{shiftsPlan?.map((e, index) => (
|
|
<div
|
|
className={` shadow-sm relative block max-w-fit mx-2 rounded-full mt-2 px-4 py-2 tr03 ${
|
|
selectShift == index
|
|
? "bg-secondary-100 text-white w-full"
|
|
: "bg-white opacity-60 "
|
|
}`}
|
|
onClick={() => {
|
|
setselectShift(index);
|
|
setShiftPlanSteps(3);
|
|
}}
|
|
>
|
|
<p className="mb-0">{e?.title}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="flex justify-center ">
|
|
<div className="bg-gray-300 mt-5 w-fit rounded-full p-2 !px-4">
|
|
<p className="mb-0 text-gray-600 text-sm">
|
|
شما شیفتی دراین روز ندارید
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
</div>
|
|
)}
|
|
|
|
{shiftPlanSteps >= 3 && (
|
|
<div className="bg-white relative top-[15px] rounded-t-3xl p-4 rtl pt-6 sm:h-auto pb-20">
|
|
<div className="mx-3 flex justify-center">
|
|
<div className=" bg-gray-100 rounded-xl w-fit mr-0 p-3">
|
|
<p className="mb-0 text-right text-sm rtl opacity-80">
|
|
ویرایش برای{" "}
|
|
<small className=" text-sm font-bold">
|
|
{shiftsPlan && shiftsPlan[selectShift]?.title}
|
|
</small>{" "}
|
|
تاریخ{" "}
|
|
<small className=" text-sm font-bold text-primary-300 bg-white px-2 rounded-full">
|
|
<PersianNumber
|
|
number={daysUntilWeek && daysUntilWeek[selectDay]?.checkDay}
|
|
/>
|
|
</small>{" "}
|
|
میباشد
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{positionsData.map((e) => (
|
|
<div>
|
|
<div className="flex justify-between mt-7 bg-gray-200 rounded-2xl">
|
|
<div className="flex p-2">
|
|
<div className="m-2">
|
|
<h4 className="text-base font-bold">{e.name} </h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
className=" bg-gray-600 shadow-sm rounded-xl m-[15px] h-fit relative "
|
|
onClick={() => {
|
|
setPositionSelectIdBottomSheet(e.id);
|
|
setPositionSelectNameBottomSheet(e.name);
|
|
CTX.setBottomSheetAddUserToPositionShiftPlanOpen(true);
|
|
}}
|
|
>
|
|
<p className="mb-0 text-sm text-white px-2 ">کاربران +</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* <div className=" m-1">
|
|
<Input
|
|
lable="جستجوی افراد"
|
|
id="SearchUser-id"
|
|
name="SearchUser"
|
|
type={"text"}
|
|
value={searchUserCurrntData}
|
|
inputEvent={(e) => {
|
|
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={"انتخاب کنید"}
|
|
/>
|
|
</div> */}
|
|
|
|
<div
|
|
className={`flex j flex-wrap mt-3 rtl ${
|
|
userAndPositionIds?.length > 0 ? "" : "justify-center"
|
|
}`}
|
|
>
|
|
{userAndPositionIds?.length > 0 ? (
|
|
userAndPositionIds?.map((item) => (
|
|
<>
|
|
{e.id == item.key && (
|
|
<div className="flex bg-gray-100 p-1 rounded-full m-1 justify-start mb-5">
|
|
<div
|
|
className="w-[30px] h-[30px] rounded-full bg-gray-400 "
|
|
// onClick={() => deleteSearchUser(e)}
|
|
>
|
|
<Avatar
|
|
size={30}
|
|
name={
|
|
usersData.find((b) => b?.userId == item?.value)
|
|
?.firstName
|
|
}
|
|
variant="beam"
|
|
colors={["#9d9f88", "#83af96", "#b2de93"]}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<p className="mb-0 px-3 text-sm mt-1">
|
|
{
|
|
usersData.find((b) => b.userId == item?.value)
|
|
?.firstName
|
|
}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
))
|
|
) : (
|
|
<div className="flex justify-center ">
|
|
<div className="bg-gray-100 w-fit rounded-full p-2 px-4">
|
|
چیزی یافت نشد
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
<div>
|
|
<Buttonbriz
|
|
title="ثبت فعالیت"
|
|
color="PRIMARY"
|
|
icon="CHECK"
|
|
buttonEvent={() => handleCreateShiftPlan()}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
<BottomManageShift />
|
|
<BottomSheetAddUserToPositionShiftPlan
|
|
positionName={positionSelectNameBottomSheet}
|
|
positionId={positionSelectIdBottomSheet}
|
|
userAndPositionIds={userAndPositionIds}
|
|
setUserAndPositionIds={setUserAndPositionIds}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Calendar;
|