2023-11-05 17:48:39 +03:30
|
|
|
|
"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";
|
|
|
|
|
|
|
|
|
|
|
|
const Calendar = () => {
|
|
|
|
|
|
const CTX = useContext(AppContext);
|
|
|
|
|
|
const shiftsData = CTX.state.shiftsData;
|
|
|
|
|
|
const searchUserChoose = CTX.state.searchUserChoose;
|
|
|
|
|
|
const usersData = CTX.state.usersData;
|
|
|
|
|
|
|
|
|
|
|
|
console.log("usersData", usersData);
|
|
|
|
|
|
|
|
|
|
|
|
const [searchUserCurrntData, setSearchUserCurrntData] = useState([]);
|
|
|
|
|
|
const [daysUntilEnd, setDaysUntilEnd] = useState([]);
|
|
|
|
|
|
const [selectDay, setSelectDay] = useState(null);
|
|
|
|
|
|
const [selectShift, setselectShift] = useState(0);
|
|
|
|
|
|
const [manageShiftEmployeesData, setManageShiftEmployeesData] = useState([]);
|
|
|
|
|
|
|
|
|
|
|
|
const today = moment().format("jYYYY/jM/jD"); // Get the current Jalali date
|
|
|
|
|
|
const todayJustDay = moment().format("jD"); // Get the current Jalali date
|
|
|
|
|
|
|
|
|
|
|
|
// Find the end of the current month
|
|
|
|
|
|
const endOfMonth = moment(today, "jYYYY/jM/jD").endOf("jMonth");
|
|
|
|
|
|
|
|
|
|
|
|
const daysInCurrentMonth = moment(today, "jYYYY/jM/jD")
|
|
|
|
|
|
.endOf("jMonth")
|
|
|
|
|
|
.jDate();
|
|
|
|
|
|
|
|
|
|
|
|
const daysEndOfMonth = () => {
|
|
|
|
|
|
const days = [];
|
|
|
|
|
|
for (let i = -1; i < daysInCurrentMonth - todayJustDay + 1; i++) {
|
|
|
|
|
|
const currentDate = moment(today, "jYYYY/jM/jD").add(i, "days");
|
|
|
|
|
|
const isToday = currentDate.isSame(moment(), "day");
|
|
|
|
|
|
days.push({
|
|
|
|
|
|
checkDay: currentDate.format("jYYYY/jM/jD"),
|
|
|
|
|
|
date: currentDate.format("jD / jM"),
|
|
|
|
|
|
dayOfWeek: currentDate.format("dddd"),
|
|
|
|
|
|
today: isToday, // Set today: true if it's the current date
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return setDaysUntilEnd(days);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log("daysUntilEnd", daysUntilEnd[selectDay]);
|
|
|
|
|
|
|
|
|
|
|
|
const handleManageShiftEmployeesOpen = (e) => {
|
|
|
|
|
|
setManageShiftEmployeesData(
|
|
|
|
|
|
usersData.map((item) => ({
|
|
|
|
|
|
key:
|
|
|
|
|
|
item.firstName +
|
|
|
|
|
|
" " +
|
|
|
|
|
|
item.lastName +
|
|
|
|
|
|
"( " +
|
|
|
|
|
|
item.roleNames[0] +
|
|
|
|
|
|
" )",
|
|
|
|
|
|
|
|
|
|
|
|
value: item.userId,
|
|
|
|
|
|
}))
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const deleteSearchUser = (id) => {
|
|
|
|
|
|
CTX.setSearchUserChoose(searchUserChoose.filter((el) => el !== id));
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
daysEndOfMonth();
|
|
|
|
|
|
setSelectDay(1);
|
|
|
|
|
|
CTX.GetShifts();
|
|
|
|
|
|
CTX.GetUsers();
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
// if (!!CTX.GetUsers()) {
|
|
|
|
|
|
//
|
|
|
|
|
|
// }
|
|
|
|
|
|
handleManageShiftEmployeesOpen();
|
|
|
|
|
|
}, [usersData]);
|
|
|
|
|
|
|
|
|
|
|
|
console.log("searchUserChooseqqqqqqqqqqqqqqqqqqqqqqqqq", searchUserChoose);
|
|
|
|
|
|
|
|
|
|
|
|
console.log(daysUntilEnd);
|
|
|
|
|
|
|
|
|
|
|
|
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">
|
|
|
|
|
|
<Swiper
|
|
|
|
|
|
spaceBetween={10}
|
|
|
|
|
|
slidesPerView={4.3}
|
|
|
|
|
|
onSlideChange={() => console.log("slide change")}
|
|
|
|
|
|
onSwiper={(swiper) => console.log(swiper)}
|
|
|
|
|
|
>
|
|
|
|
|
|
{daysUntilEnd?.map((e, index) => (
|
|
|
|
|
|
<SwiperSlide>
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={`h-[70px] tr03 ${
|
|
|
|
|
|
selectDay == index ? "bg-white rounded-xl" : " opacity-70"
|
|
|
|
|
|
}`}
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setSelectDay(index);
|
|
|
|
|
|
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)} */}
|
|
|
|
|
|
{PersianDay(e.dayOfWeek)}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</SwiperSlide>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</Swiper>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="bg-body-100 relative top-[-30px] rounded-t-3xl overflow-hidden rtl">
|
|
|
|
|
|
{shiftsData.length > 0 ? (
|
|
|
|
|
|
<div
|
|
|
|
|
|
className="flex overflow-auto whitespace-nowrap"
|
|
|
|
|
|
id="swich-shifts"
|
|
|
|
|
|
>
|
|
|
|
|
|
{shiftsData.map((e, index) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={` shadow-sm relative block max-w-max mx-2 rounded-full mt-2 px-4 py-2 ${
|
|
|
|
|
|
selectShift == index
|
|
|
|
|
|
? "bg-secondary-100 text-white"
|
|
|
|
|
|
: "bg-white opacity-60"
|
|
|
|
|
|
}`}
|
|
|
|
|
|
onClick={() => setselectShift(index)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<p className="mb-0">{e?.title}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<div className="flex justify-center py-5">
|
|
|
|
|
|
<div className="bg-white shadow mt-5 w-fit rounded-full p-4">
|
|
|
|
|
|
چیزی یافت نشد
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="bg-white relative top-[15px] rounded-t-3xl p-4 rtl pt-6 h-screen sm:h-auto ">
|
|
|
|
|
|
<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">
|
|
|
|
|
|
{shiftsData && shiftsData[selectShift]?.title}
|
|
|
|
|
|
</small>{" "}
|
|
|
|
|
|
تاریخ{" "}
|
|
|
|
|
|
<small className=" text-sm font-bold text-primary-300 bg-white px-2 rounded-full">
|
|
|
|
|
|
<PersianNumber
|
|
|
|
|
|
number={daysUntilEnd && daysUntilEnd[selectDay]?.checkDay}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</small>{" "}
|
|
|
|
|
|
میباشد
|
|
|
|
|
|
</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}
|
2023-11-14 16:22:32 +03:30
|
|
|
|
defaultValue={"انتخاب کنید"}
|
2023-11-05 17:48:39 +03:30
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={`flex j flex-wrap mt-3 rtl ${
|
|
|
|
|
|
searchUserChoose.length > 0 ? "" : "justify-center"
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
{searchUserChoose.length > 0 ? (
|
|
|
|
|
|
searchUserChoose.map((e) => (
|
|
|
|
|
|
<div className="flex bg-gray-100 p-1 rounded-full m-1 justify-start">
|
|
|
|
|
|
<div
|
|
|
|
|
|
className="w-[30px] h-[30px] rounded-full bg-gray-400 "
|
|
|
|
|
|
onClick={() => deleteSearchUser(e)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Avatar
|
|
|
|
|
|
size={30}
|
|
|
|
|
|
name={usersData.find((b) => b.userId == e)?.firstName}
|
|
|
|
|
|
variant="beam"
|
|
|
|
|
|
colors={["#9d9f88", "#83af96", "#b2de93"]}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<p className="mb-0 px-3 text-sm mt-1">
|
|
|
|
|
|
{usersData.find((b) => b.userId == e)?.firstName}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<div className="flex justify-center py-5">
|
|
|
|
|
|
<div className="bg-white shadow mt-5 w-fit rounded-full p-4">
|
|
|
|
|
|
چیزی یافت نشد
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="flex jc mt-10">
|
|
|
|
|
|
<button className="btn btn-primary inline-block w-full">
|
|
|
|
|
|
{" "}
|
|
|
|
|
|
ثبت نهایی شیفت
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
|
|
|
className="btn bg-transparent border-[2px] border-info-100 border-dashed text-info-100 text-[12px] mx-2 w-full"
|
|
|
|
|
|
onClick={() => CTX.setBottomManageShiftOpen(true)}
|
|
|
|
|
|
>
|
|
|
|
|
|
تغییر حالت تسک ها{" "}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<BottomManageShift />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default Calendar;
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
/* {shiftsData.map((e, index) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
className={`bg-gray-200 p-5 rounded-3xl relative w-full pb-20 border-[4px] border-white !z-[${index}] `}
|
|
|
|
|
|
style={{ top: `${27 * (shiftsData.length - 1 - index)}px` }}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div className="flex rtl">
|
|
|
|
|
|
<div className="w-[40px] h-[40px] bg-primary-300 rounded-full">
|
|
|
|
|
|
<svg
|
|
|
|
|
|
width="15"
|
|
|
|
|
|
height="15"
|
|
|
|
|
|
viewBox="0 0 150 88"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
|
className="mx-auto mt-[10px]"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path
|
|
|
|
|
|
d="M137.5 75L75 12.5L12.5 75"
|
|
|
|
|
|
stroke="white"
|
|
|
|
|
|
stroke-width="25"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="mx-3 ">
|
|
|
|
|
|
<p className="mb-0 font-bold text-xl text-right">{e?.title}</p>
|
|
|
|
|
|
<p className="mb-0 text-sm text-right">
|
|
|
|
|
|
{e?.title} {}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))} */
|
|
|
|
|
|
}
|