add chart for phe & add notif && add strp 6 in setting && and ....

main
حسین معصومی پور 2024-07-29 21:25:55 +03:30
parent d00c061772
commit 5d221c1a2c
35 changed files with 2038 additions and 389 deletions

12
.env
View File

@ -1,9 +1,9 @@
NODE_ENV="development"
NEXT_PUBLIC_SERVER_URL=http://192.168.1.100:32767
NEXT_PUBLIC_PUBLIC_URL=http://192.168.1.100:32767
NEXT_PUBLIC_API_URL=http://192.168.1.100:32767/api
NEXT_PUBLIC_VERSION=1.0.1.2
NEXT_PUBLIC_SERVER_URL=http://192.168.1.10:32767
NEXT_PUBLIC_PUBLIC_URL=http://192.168.1.10:32767
NEXT_PUBLIC_API_URL=http://192.168.1.10:32767/api
# NEXT_PUBLIC_VERSION=1.0.1.2
# SECURE_LOCAL_STORAGE_HASH_KEY=f1da2b2c7a4c446934267fea631102ec389b5b99
# NEXT_PUBLIC_API_URL_IMAGE=https://192.168.88.12:49154/Files/ReportImages
# NEXT_PUBLIC_API_URL_BackUp=https://192.168.88.12:49154/Files/BackUps
@ -17,6 +17,6 @@ NEXT_PUBLIC_VERSION=1.0.1.2
# NEXT_PUBLIC_SERVER_URL=https://api.brizco.io
# NEXT_PUBLIC_PUBLIC_URL=https://api.brizco.io
# NEXT_PUBLIC_API_URL=https://api.brizco.io/api
# NEXT_PUBLIC_VERSION=1.0.1.2
# NEXT_PUBLIC_VERSION=1.0.3.4
# NEXT_PUBLIC_API_URL_IMAGE=https://api.macsonline.ir/Files/ReportImages
# NEXT_PUBLIC_API_URL_BackUp=https://api.macsonline.ir/Files/BackUps
# NEXT_PUBLIC_API_URL_BackUp=https://api.macsonline.ir/Files/Back1.10

View File

@ -2,4 +2,4 @@ NODE_ENV="production"
NEXT_PUBLIC_SERVER_URL=https://api.brizco.io
NEXT_PUBLIC_PUBLIC_URL=https://api.brizco.io
NEXT_PUBLIC_API_URL=https://api.brizco.io/api
NEXT_PUBLIC_VERSION=1.0.1.2
NEXT_PUBLIC_VERSION=1.0.3.4

View File

@ -14,5 +14,5 @@ CMD ["/app/node_modules/.bin/next", "start"]
# docker build -f Dockerfile.emergency -t registry.vnfco.ir/brizco/web:1.0.1.2 .
# docker push registry.vnfco.ir/brizco/web:1.0.1.2
# docker build -f Dockerfile.emergency -t registry.vnfco.ir/brizco/web:1.0.3.4 .
# docker push registry.vnfco.ir/brizco/web:1.0.3.4

View File

@ -7,6 +7,8 @@ import React, { useContext } from "react";
import { useLongPress } from "@uidotdev/usehooks";
import { toast } from "react-toastify";
import AppContext from "@ctx/AppContext";
import notifIcon from "@img/notif.png";
import Image from "next/image";
const AppHeader = ({
title,
@ -26,9 +28,11 @@ const AppHeader = ({
userIconHref,
userRole,
logOut,
notif,
}) => {
const router = useRouter();
const CTX = useContext(AppContext);
const notifUnreadData = CTX.state.notifUnreadData;
const handlelogOut = () => {
CTX.setStepLogin(0);
@ -187,6 +191,18 @@ const AppHeader = ({
) : (
""
)}
{notif && (
<Link href={"/news"} className="ml-5">
{notifUnreadData > 0 && (
<div className="absolute">
<div className="w-3 h-3 rounded-full bg-red-300 border-2 border-black"></div>
</div>
)}
<Image src={notifIcon} className="w-[25px]" />
</Link>
)}
</div>
) : (
<div

View File

@ -0,0 +1,117 @@
"use client";
import AppContext from "@ctx/AppContext";
import React, { useContext } from "react";
import Avatar from "boring-avatars";
import PersianNumber from "plugins/PersianNumber";
import HasPermission from "plugins/HasPermission/page";
import NothingFound from "plugins/NothingFound/page";
import InfiniteScroll from "react-infinite-scroll-component";
import TasksCard from "@comp/TaskPage/TasksCard/page";
import { useState } from "react";
const TasksEmployees = () => {
const CTX = useContext(AppContext);
const tasksData = CTX.state.tasksData;
const stopGetTasks = CTX.state.stopGetTasks;
const pageGetTasks = CTX.state.pageGetTasks;
const shiftsData = CTX.state.shiftsData;
const permissions = CTX.state.profile?.permissions;
const [listTaskActive, setListTaskActive] = useState(-1);
const handleInfiniteNextFetchTask = () => {
CTX.setPageGetTasks((e) => e + 1);
CTX.GetTasks(pageGetTasks + 1);
};
const handleListTaskActive = (id, index) => {
if (index == listTaskActive) {
setListTaskActive(-1);
} else {
setListTaskActive(index);
CTX.GetTasks(0, id);
}
};
return (
<>
{shiftsData.length > 0 ? (
<>
{shiftsData?.map((e, index) => (
<>
<div
className={`px-1 rounded-2xl ${
listTaskActive == index ? "pt-1" : "py-1"
}`}
key={index}
>
<div
className={`flex justify-between bg-white p-2 ${
listTaskActive == index
? " rounded-b-0 rounded-t-xl"
: "rounded-xl"
}`}
onClick={() => handleListTaskActive(e?.id, index)}
>
<p className="mb-0 text-[13px] mt-1">{e?.title}</p>
<div className="bg-gray-100 w-[30px] h-[30px] rounded-xl">
<svg
width="11"
height="11"
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={`opacity-80 mt-2 mx-auto tr03 ${
listTaskActive == index ? "rotate-180" : ""
}`}
>
<path
d="M13.0444 13.1674L75.3606 75.8506L138.044 13.5345"
stroke="#424242"
stroke-opacity="0.81"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
</div>
{listTaskActive == index && (
<div
className={`bg-white py-2 mx-1 ${
listTaskActive == index
? " rounded-t-0 rounded-b-xl mb-1"
: "rounded-xl"
}`}
>
{tasksData.length != 0 ? (
<InfiniteScroll
dataLength={tasksData.length}
next={handleInfiniteNextFetchTask}
hasMore={!stopGetTasks}
>
<TasksCard
tasksData={tasksData}
permissions={permissions}
/>
</InfiniteScroll>
) : (
<NothingFound />
)}
</div>
)}
</>
))}
</>
) : (
<NothingFound />
)}
</>
);
};
export default TasksEmployees;

View File

@ -25,6 +25,11 @@ const LoginStep = (props) => {
closeOnClick: true,
});
} else if (!roleCheckBox) {
toast.error(`برای ورود تایید قوانین الزامی است`, {
position: "bottom-right",
closeOnClick: true,
});
setTimeout(() => {
setAlertRolCheckBox(true);
}, 100);

View File

@ -5,12 +5,14 @@ import React, { useContext, useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import Image from "next/image";
import logo from "@img/logo.png";
import setting from "@img/setting.png";
import AppContext from "@ctx/AppContext";
import HasPermission from "plugins/HasPermission/page";
const NavBAr = (props) => {
const usePath = usePathname();
const CTX = useContext(AppContext);
const notifUnreadData = CTX.state.notifUnreadData;
const [profileFill, setProfileFill] = useState(false);
const permissions = CTX.state.profile?.permissions;
@ -145,34 +147,16 @@ const NavBAr = (props) => {
<Link href={"/employees"} className="w-full !no-underline ">
<>
{usePath.includes("/employees") ? (
<div className="flex justify-center w-full">
<svg
width="30"
height="30"
viewBox="0 0 256 256"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M125.18 156.94C135.231 148.492 142.44 137.157 145.83 124.473C149.22 111.789 148.627 98.369 144.131 86.0333C139.635 73.6976 131.454 63.043 120.698 55.5146C109.941 47.9861 97.1294 43.9481 84 43.9481C70.8706 43.9481 58.0588 47.9861 47.3022 55.5146C36.5456 63.043 28.3647 73.6976 23.8689 86.0333C19.3732 98.369 18.7801 111.789 22.1702 124.473C25.5603 137.157 32.7694 148.492 42.82 156.94C27.1258 164.036 13.5251 175.057 3.32997 188.94C1.44694 191.506 0.660351 194.715 1.14326 197.861C1.62616 201.007 3.339 203.832 5.90497 205.715C8.47094 207.598 11.6799 208.385 14.8258 207.902C17.9717 207.419 20.7969 205.706 22.68 203.14C29.7374 193.501 38.9676 185.662 49.6217 180.258C60.2758 174.854 72.0538 172.038 84 172.038C95.9462 172.038 107.724 174.854 118.378 180.258C129.032 185.662 138.263 193.501 145.32 203.14C147.203 205.707 150.029 207.421 153.176 207.905C156.322 208.389 159.533 207.603 162.1 205.72C164.667 203.837 166.381 201.011 166.865 197.864C167.349 194.717 166.563 191.507 164.68 188.94C154.479 175.059 140.875 164.039 125.18 156.94ZM44 108C44 100.089 46.3459 92.3552 50.7412 85.7772C55.1364 79.1992 61.3836 74.0723 68.6926 71.0448C76.0017 68.0173 84.0443 67.2252 91.8036 68.7686C99.5628 70.312 106.69 74.1216 112.284 79.7157C117.878 85.3098 121.688 92.4372 123.231 100.196C124.775 107.956 123.983 115.998 120.955 123.307C117.928 130.616 112.801 136.864 106.223 141.259C99.6448 145.654 91.9112 148 84 148C73.3913 148 63.2172 143.786 55.7157 136.284C48.2142 128.783 44 118.609 44 108ZM250.1 205.67C248.83 206.604 247.388 207.278 245.857 207.654C244.326 208.03 242.736 208.1 241.177 207.862C239.619 207.623 238.123 207.08 236.775 206.263C235.427 205.446 234.253 204.371 233.32 203.1C226.245 193.48 217.011 185.654 206.361 180.253C195.711 174.851 183.942 172.024 172 172C168.817 172 165.765 170.736 163.515 168.485C161.264 166.235 160 163.183 160 160C160 156.817 161.264 153.765 163.515 151.515C165.765 149.264 168.817 148 172 148C177.89 147.993 183.705 146.686 189.031 144.171C194.357 141.657 199.062 137.997 202.809 133.454C206.557 128.91 209.255 123.596 210.712 117.889C212.168 112.182 212.345 106.224 211.232 100.44C210.119 94.657 207.743 89.1907 204.273 84.4319C200.802 79.6732 196.324 75.7395 191.158 72.9118C185.991 70.0841 180.264 68.4322 174.385 68.0741C168.507 67.7159 162.621 68.6604 157.15 70.84C155.684 71.4401 154.114 71.7442 152.531 71.7347C150.947 71.7251 149.381 71.4022 147.922 70.7845C146.464 70.1667 145.142 69.2664 144.034 68.1355C142.925 67.0045 142.051 65.6653 141.463 64.195C140.874 62.7247 140.582 61.1524 140.604 59.5688C140.626 57.9852 140.961 56.4216 141.59 54.9682C142.219 53.5147 143.13 52.2002 144.27 51.1003C145.409 50.0005 146.755 49.1371 148.23 48.56C162.353 42.9054 178.029 42.4667 192.446 47.3225C206.863 52.1783 219.079 62.0109 226.904 75.0575C234.729 88.1041 237.65 103.511 235.144 118.517C232.638 133.522 224.869 147.144 213.23 156.94C228.924 164.036 242.525 175.057 252.72 188.94C254.584 191.508 255.355 194.711 254.864 197.846C254.373 200.981 252.66 203.795 250.1 205.67Z"
fill="black"
/>
</svg>
<div className="flex justify-center w-full">
<div className="w-[32px]">
<Image src={setting} />
</div>
</div>
) : (
<div className="flex justify-center opacity-20 w-full">
<svg
width="30"
height="30"
viewBox="0 0 256 256"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M125.18 156.94C135.231 148.492 142.44 137.157 145.83 124.473C149.22 111.789 148.627 98.369 144.131 86.0333C139.635 73.6976 131.454 63.043 120.698 55.5146C109.941 47.9861 97.1294 43.9481 84 43.9481C70.8706 43.9481 58.0588 47.9861 47.3022 55.5146C36.5456 63.043 28.3647 73.6976 23.8689 86.0333C19.3732 98.369 18.7801 111.789 22.1702 124.473C25.5603 137.157 32.7694 148.492 42.82 156.94C27.1258 164.036 13.5251 175.057 3.32997 188.94C1.44694 191.506 0.660351 194.715 1.14326 197.861C1.62616 201.007 3.339 203.832 5.90497 205.715C8.47094 207.598 11.6799 208.385 14.8258 207.902C17.9717 207.419 20.7969 205.706 22.68 203.14C29.7374 193.501 38.9676 185.662 49.6217 180.258C60.2758 174.854 72.0538 172.038 84 172.038C95.9462 172.038 107.724 174.854 118.378 180.258C129.032 185.662 138.263 193.501 145.32 203.14C147.203 205.707 150.029 207.421 153.176 207.905C156.322 208.389 159.533 207.603 162.1 205.72C164.667 203.837 166.381 201.011 166.865 197.864C167.349 194.717 166.563 191.507 164.68 188.94C154.479 175.059 140.875 164.039 125.18 156.94ZM44 108C44 100.089 46.3459 92.3552 50.7412 85.7772C55.1364 79.1992 61.3836 74.0723 68.6926 71.0448C76.0017 68.0173 84.0443 67.2252 91.8036 68.7686C99.5628 70.312 106.69 74.1216 112.284 79.7157C117.878 85.3098 121.688 92.4372 123.231 100.196C124.775 107.956 123.983 115.998 120.955 123.307C117.928 130.616 112.801 136.864 106.223 141.259C99.6448 145.654 91.9112 148 84 148C73.3913 148 63.2172 143.786 55.7157 136.284C48.2142 128.783 44 118.609 44 108ZM250.1 205.67C248.83 206.604 247.388 207.278 245.857 207.654C244.326 208.03 242.736 208.1 241.177 207.862C239.619 207.623 238.123 207.08 236.775 206.263C235.427 205.446 234.253 204.371 233.32 203.1C226.245 193.48 217.011 185.654 206.361 180.253C195.711 174.851 183.942 172.024 172 172C168.817 172 165.765 170.736 163.515 168.485C161.264 166.235 160 163.183 160 160C160 156.817 161.264 153.765 163.515 151.515C165.765 149.264 168.817 148 172 148C177.89 147.993 183.705 146.686 189.031 144.171C194.357 141.657 199.062 137.997 202.809 133.454C206.557 128.91 209.255 123.596 210.712 117.889C212.168 112.182 212.345 106.224 211.232 100.44C210.119 94.657 207.743 89.1907 204.273 84.4319C200.802 79.6732 196.324 75.7395 191.158 72.9118C185.991 70.0841 180.264 68.4322 174.385 68.0741C168.507 67.7159 162.621 68.6604 157.15 70.84C155.684 71.4401 154.114 71.7442 152.531 71.7347C150.947 71.7251 149.381 71.4022 147.922 70.7845C146.464 70.1667 145.142 69.2664 144.034 68.1355C142.925 67.0045 142.051 65.6653 141.463 64.195C140.874 62.7247 140.582 61.1524 140.604 59.5688C140.626 57.9852 140.961 56.4216 141.59 54.9682C142.219 53.5147 143.13 52.2002 144.27 51.1003C145.409 50.0005 146.755 49.1371 148.23 48.56C162.353 42.9054 178.029 42.4667 192.446 47.3225C206.863 52.1783 219.079 62.0109 226.904 75.0575C234.729 88.1041 237.65 103.511 235.144 118.517C232.638 133.522 224.869 147.144 213.23 156.94C228.924 164.036 242.525 175.057 252.72 188.94C254.584 191.508 255.355 194.711 254.864 197.846C254.373 200.981 252.66 203.795 250.1 205.67Z"
fill="black"
/>
</svg>
<div className="w-[32px] ">
<Image src={setting} />
</div>
</div>
)}
</>
@ -182,6 +166,13 @@ const NavBAr = (props) => {
{HasPermission("ViewActivities", permissions) && (
<Link href={"/tasks"} className="w-full !no-underline ">
<>
{notifUnreadData > 0 && (
<div className="relative flex justify-center">
<div className="absolute top-[-10px]">
<div className="w-[8px] h-[8px] rounded-full bg-red-300"></div>
</div>
</div>
)}
{usePath.includes("/tasks") ? (
<div className="flex justify-center w-full">
<div className="w-[32px] mt-2">

View File

@ -15,67 +15,111 @@ const TasksCard = ({ tasksData, permissions }) => {
const goToEditTask = (id) => {
if (!!HasPermission("ManageTasks", permissions)) {
CTX.setGoToEditTask(true);
router.push("/tasks/add-task?new=false");
CTX.GetTask(id);
CTX.setIdEditTask(id);
CTX.setBottomSheetCreateTaskOpen(true);
}
};
return (
<div className="mt-3">
<div>
{tasksData?.map((e, index) => (
<div
className=" py-3 overflow-hidden relative border-b border-gray-200"
onClick={() => {
goToEditTask(e.id);
}}
>
<div className="flex whitespace-nowrap overflow-auto">
{/* <div className=" w-fit relative px-2 text-[12px] my-2 mx-1 rounded-3xl text-primary-300 bg-red-200 px-2">
<div className="bg-gray-100 shadow-sm rounded-xl mx-2 my-2 p-2">
<div className="flex justify-between">
<div className="flex whitespace-nowrap overflow-auto w-10/12">
{/* <div className=" w-fit relative px-2 text-[12px] my-2 mx-1 rounded-3xl text-primary-300 bg-red-200 px-2">
<PersianNumber number={index + 1} />
</div> */}
<div className="flex">
<div className="relative pr-2 text-[11px] text-primary-500">
{e?.scheduleType == 0
? "روزانه"
: e?.scheduleType == 1
? "هفتگی"
: e?.scheduleType == 2
? "مخصوص"
: ""}
<div className="flex">
<div className="relative pr-2 text-[11px] text-primary-500">
{e?.scheduleType == 0
? "روزانه"
: e?.scheduleType == 1
? "هفتگی"
: e?.scheduleType == 2
? "مخصوص"
: ""}
</div>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-75 mt-[2px]"></div>
<div className=" w-fit relative text-[11px] text-secondary-800 h-fit">
{e?.shifts[0]}
</div>
{e?.days?.length > 0 && (
<>
{e?.days.map((s) => (
<>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-75 mt-[2px]"></div>
<div className=" w-fit relative text-[11px] text-primary-600 h-fit ">
{" "}
{s}
</div>
</>
))}
</>
)}
</div>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-75 mt-[2px]"></div>
<div className=" w-fit relative text-[11px] text-secondary-800 h-fit">
{e?.shifts[0]}
<div className=" w-fit relative text-[11px] text-secondary-950 h-fit ">
{" "}
{e?.positions[0]}
</div>
{e?.days?.length > 0 && (
<>
{e?.days.map((s) => (
<>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-75 mt-[2px]"></div>
<div className=" w-fit relative text-[11px] text-primary-600 h-fit ">
{" "}
{s}
</div>
</>
))}
</>
)}
</div>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-75 mt-[2px]"></div>
<div className=" w-fit relative text-[11px] text-secondary-950 h-fit ">
{" "}
{e?.positions[0]}
</div>
{HasPermission("ManageShifts", permissions) && (
<div className="w-1/12">
<div
className="w-[22px] h-[22px] bg-secondary-950 rounded-full relative pt-1"
onClick={() => goToEditTask(e.id)}
>
<svg
width="12"
height="12"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto"
>
<g clip-path="url(#clip0_72_994)">
<path
d="M11.4653 2.36397L10.77 3.05922L4.37926 9.44922C3.94651 9.88272 3.72976 10.0995 3.54376 10.338C3.32409 10.6194 3.13573 10.924 2.98201 11.2462C2.85226 11.5192 2.75551 11.8102 2.56201 12.3907L1.74151 14.8515L1.54051 15.453C1.4935 15.5932 1.48652 15.7437 1.52037 15.8877C1.55422 16.0316 1.62755 16.1633 1.73212 16.2679C1.83669 16.3724 1.96835 16.4458 2.1123 16.4796C2.25626 16.5135 2.4068 16.5065 2.54701 16.4595L3.14851 16.2585L5.60926 15.438C6.19051 15.2445 6.48076 15.1477 6.75376 15.018C7.07626 14.8642 7.38076 14.676 7.66201 14.4562C7.90051 14.2702 8.11726 14.0535 8.55001 13.6207L14.9408 7.22997L15.636 6.53472C16.1891 5.98165 16.4998 5.23152 16.4998 4.44935C16.4998 3.66718 16.1891 2.91705 15.636 2.36397C15.0829 1.8109 14.3328 1.50018 13.5506 1.50018C12.7685 1.50018 12.0183 1.8109 11.4653 2.36397Z"
stroke="black"
stroke-width="1.5"
/>
<path
d="M11.4653 2.36397L10.77 3.05922L4.37926 9.44922C3.94651 9.88272 3.72976 10.0995 3.54376 10.338C3.32409 10.6194 3.13573 10.924 2.98201 11.2462C2.85226 11.5192 2.75551 11.8102 2.56201 12.3907L1.74151 14.8515L1.54051 15.453C1.4935 15.5932 1.48652 15.7437 1.52037 15.8877C1.55422 16.0316 1.62755 16.1633 1.73212 16.2679C1.83669 16.3724 1.96835 16.4458 2.1123 16.4796C2.25626 16.5135 2.4068 16.5065 2.54701 16.4595L3.14851 16.2585L5.60926 15.438C6.19051 15.2445 6.48076 15.1477 6.75376 15.018C7.07626 14.8642 7.38076 14.676 7.66201 14.4562C7.90051 14.2702 8.11726 14.0535 8.55001 13.6207L14.9408 7.22997L15.636 6.53472C16.1891 5.98165 16.4998 5.23152 16.4998 4.44935C16.4998 3.66718 16.1891 2.91705 15.636 2.36397C15.0829 1.8109 14.3328 1.50018 13.5506 1.50018C12.7685 1.50018 12.0183 1.8109 11.4653 2.36397Z"
stroke="white"
stroke-width="1.5"
/>
<g opacity="0.5">
<path
d="M10.77white 3.05847C10.77 3.05847 10.857 4.53597 12.1605 5.83947C13.464 7.14297 14.9408 7.22922 14.9408 7.22922M3.14852 16.2585L1.74152 14.85"
stroke="white"
stroke-width="1.5"
/>
<path
d="M10.77 3.05847C10.77 3.05847 10.857 4.53597 12.1605 5.83947C13.464 7.14297 14.9408 7.22922 14.9408 7.22922M3.14852 16.2585L1.74152 14.85"
stroke="white"
stroke-width="1.5"
/>
</g>
</g>
<defs>
<clipPath id="clip0_72_994">
<rect width="18" height="18" fill="white" />
</clipPath>
</defs>
</svg>
</div>
</div>
)}
</div>
<div className=" relative m-1 text-white">
<div className="text-right max-h-[40px] overflow-hidden">
<h4 className="mb-0 text-secondary-950 font-medium text-sm">
<h4 className="mb-0 text-secondary-950 font-medium text-[12px] relative w-full ellipsis">
{e?.title}{" "}
</h4>
</div>

View File

@ -12,16 +12,22 @@ import moment from "jalali-moment";
import HasPermission from "plugins/HasPermission/page";
import PersianNumber from "plugins/PersianNumber";
const BottomFilterActivities = (props) => {
const BottomFilterActivities = ({
dateQueryFilterValue,
setActiveStaffIdValue,
activeStaffId,
setActiveStaff,
}) => {
const CTX = useContext(AppContext);
const [typeFilter, setTypeFilter] = useState(0);
const handleFilterActivity = (num) => {
setTypeFilter(num);
setActiveStaffIdValue(num);
};
const handleChangeFilter = () => {
CTX.GetActivity(null, null, 0, typeFilter);
setActiveStaff(-1);
CTX.GetUserStaff(dateQueryFilterValue);
// CTX.GetActivity(null, null, 0, dateQueryFilterValue, activeStaffId);
CTX.setBottomFilterActivitiesOpen(false);
CTX.setStopGetActivities(false);
CTX.setPageGetActivity(0);
@ -32,7 +38,7 @@ const BottomFilterActivities = (props) => {
// onSpringStart={(e) => handleBottomSheetCreateRole(e)}
open={CTX.state.BottomFilterActivitiesOpen}
onDismiss={() => CTX.setBottomFilterActivitiesOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">
@ -43,9 +49,9 @@ const BottomFilterActivities = (props) => {
<div className="bg-body-100 p-3 ">
<div
className={`rounded-xl border-[1px] border-gray-200 p-3 m-2 tr03 ${
typeFilter == 3 ? " bg-primary-100" : "bg-gray-100 "
dateQueryFilterValue == 2 ? " bg-primary-100" : "bg-gray-100 "
}`}
onClick={() => handleFilterActivity(3)}
onClick={() => handleFilterActivity(2)}
>
<p className="mb-0 text-right">
اکتیویتی های دیروز
@ -63,9 +69,9 @@ const BottomFilterActivities = (props) => {
<div
className={`rounded-xl border-[1px] border-gray-200 p-3 m-2 tr03 ${
typeFilter == 0 ? " bg-primary-100" : "bg-gray-100 "
dateQueryFilterValue == 1 ? " bg-primary-100" : "bg-gray-100 "
}`}
onClick={() => handleFilterActivity(0)}
onClick={() => handleFilterActivity(1)}
>
<p className="mb-0 text-right">
اکتیویتی های امروز
@ -80,9 +86,9 @@ const BottomFilterActivities = (props) => {
<div
className={`rounded-xl border-[1px] border-gray-200 p-3 m-2 tr03 ${
typeFilter == 1 ? " bg-primary-100" : "bg-gray-100 "
dateQueryFilterValue == 3 ? " bg-primary-100" : "bg-gray-100 "
}`}
onClick={() => handleFilterActivity(1)}
onClick={() => handleFilterActivity(3)}
>
<p className="mb-0 text-right">
اکتیویتی های فردا
@ -100,9 +106,9 @@ const BottomFilterActivities = (props) => {
<div
className={`rounded-xl border-[1px] border-gray-200 p-3 m-2 tr03 ${
typeFilter == 2 ? " bg-primary-100" : "bg-gray-100 "
dateQueryFilterValue == 12 ? " bg-primary-100" : "bg-gray-100 "
}`}
onClick={() => handleFilterActivity(2)}
onClick={() => handleFilterActivity(12)}
>
<p className="mb-0 text-right">اکتیویتی های هفته</p>
</div>

View File

@ -179,7 +179,7 @@ const BottomManageShift = (props) => {
onSpringStart={(e) => handleBottomSheetCreateEmployeesOpen(e)}
open={CTX.state.BottomManageShiftOpen}
onDismiss={() => CTX.setBottomManageShiftOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-primary-300 ">
<p className="mb-0 text-white relative top-[-5px]">

View File

@ -39,7 +39,7 @@ const BottomSheetAddUserToPositionShiftPlan = ({
<BottomSheet
open={CTX.state.BottomSheetAddUserToPositionShiftPlanOpen}
onDismiss={() => CTX.setBottomSheetAddUserToPositionShiftPlanOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -24,7 +24,7 @@ const BottomSheetChangeRole = (props) => {
<BottomSheet
open={CTX.state.BottomSheetChangeRoleOpen}
onDismiss={() => CTX.setBottomSheetChangeRoleOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -195,7 +195,7 @@ const BottomSheetCreateEmployees = (props) => {
onSpringStart={(e) => handleBottomSheetCreateEmployeesOpen(e)}
open={CTX.state.BottomSheetCreateEmployeesOpen}
onDismiss={() => CTX.setBottomSheetCreateEmployeesOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -44,6 +44,7 @@ const BottomSheetCreatePosition = (props) => {
description,
title,
sectionId,
permissions: [""],
};
const bodyUpdate = {
@ -51,6 +52,7 @@ const BottomSheetCreatePosition = (props) => {
title,
sectionId,
id: idEditPosition,
permissions: [""],
};
const clear = () => {
@ -119,7 +121,7 @@ const BottomSheetCreatePosition = (props) => {
onSpringStart={(e) => handleBottomSheetCreatePositionOpen(e)}
open={CTX.state.BottomSheetCreatePositionOpen}
onDismiss={() => CTX.setBottomSheetCreatePositionOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -109,7 +109,7 @@ const BottomSheetCreateRole = (props) => {
onSpringStart={(e) => handleBottomSheetCreateRole(e)}
open={CTX.state.BottomSheetCreateRoleOpen}
onDismiss={() => CTX.setBottomSheetCreateRoleOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-primary-300 ">
<p className="mb-0 text-white relative top-[-5px]">افزودن نقش جدید</p>

View File

@ -98,7 +98,7 @@ const BottomSheetCreateRoutine = (props) => {
onSpringStart={(e) => handleBottomSheetCreateRoutineOpen(e)}
open={CTX.state.BottomSheetCreateRoutineOpen}
onDismiss={() => CTX.setBottomSheetCreateRoutineOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -98,7 +98,7 @@ const BottomSheetCreateSection = (props) => {
onSpringStart={(e) => handleBottomSheetCreateSectionOpen(e)}
open={CTX.state.BottomSheetCreateSectionOpen}
onDismiss={() => CTX.setBottomSheetCreateSectionOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -149,7 +149,7 @@ const BottomSheetCreateShifts = (props) => {
onSpringStart={(e) => handleBottomSheetCreateShift(e)}
open={CTX.state.BottomSheetCreateShiftsOpen}
onDismiss={() => CTX.setBottomSheetCreateShiftsOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">

View File

@ -0,0 +1,745 @@
"use client";
import React, { useContext, useEffect, useRef, useState } from "react";
import { BottomSheet } from "react-spring-bottom-sheet";
import Input from "plugins/Input/page";
import AppContext from "@ctx/AppContext";
import SimpleReactValidator from "simple-react-validator";
import { toast } from "react-toastify";
import Buttonbriz from "plugins/Buttonbriz/page";
import { useRouter } from "next/navigation";
import DatePickerIran from "plugins/DatePickerIran/page";
import moment from "jalali-moment";
import Chapar from "plugins/Chapar";
const BottomSheetCreateTask = (props) => {
const CTX = useContext(AppContext);
const router = useRouter();
const [routinesSelectData, setRoutinesSelectData] = useState([]);
const [routineForTaskCurrent, setRoutineForTaskCurrent] = useState([]);
const [positionsSelectData, setPositionsSelectData] = useState([]);
const [positionsForTaskCurrent, setPositionsForTaskCurrent] = useState([]);
const [shiftsSelectData, setShiftsSelectData] = useState([]);
const [shiftsForTaskCurrent, setShiftsForTaskCurrent] = useState([]);
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [scheduleType, setScheduleType] = useState(1);
const [birthDateTimeStamp, setBirthDateTimeStamp] = useState(0);
const [shiftsDaysSelectData, setShiftsDaysSelectData] = useState(null);
const [shiftsDaysCurrent, setShiftsDaysCurrent] = useState(null);
const [, forceUpdate] = useState();
const routinesData = CTX.state.routinesData;
const positionsData = CTX.state.positionsData;
const shiftsData = CTX.state.shiftsData;
const routineForTaskChoose = CTX.state.routineForTaskChoose;
const positionsForTaskChoose = CTX.state.positionsForTaskChoose;
const shiftsForTaskChoose = CTX.state.shiftsForTaskChoose;
const shiftsDaysChoose = CTX.state.shiftsDaysChoose;
const goToEditTask = CTX.state.goToEditTask;
const taskData = CTX.state.taskData;
const idEditTask = CTX.state.idEditTask;
const schedule = [
{ key: "هفتگی", value: 1 },
{ key: "روزانه", value: 0 },
{ key: "مخصوص یک روز ", value: 2 },
];
const week = [
{ key: "شنبه", value: 6 },
{ key: "یکشنبه", value: 0 },
{ key: "دوشنبه", value: 1 },
{ key: "سه شنبه", value: 2 },
{ key: "چهار شنبه", value: 3 },
{ key: "پنج شنبه", value: 4 },
{ key: "جمعه", value: 5 },
];
const validator = useRef(
new SimpleReactValidator({
messages: {
required: "پر کردن این فیلد الزامی میباشد",
},
element: (message) => (
<>
<div className="text-right px-1 ">
<small className="text-red-600 t-ig-small ">{message}</small>
</div>
</>
),
})
);
const body = {
title,
description,
routines: routineForTaskChoose,
positions: positionsForTaskChoose,
shifts: shiftsForTaskChoose,
scheduleType,
setFor:
birthDateTimeStamp &&
moment
.utc(
[
birthDateTimeStamp.year,
birthDateTimeStamp.month,
birthDateTimeStamp.day,
],
"jYYYY-jMM-jDDTHH"
)
.unix(),
days: shiftsDaysChoose,
};
const bodyUpdate = {
title,
description,
routines: routineForTaskChoose,
positions: positionsForTaskChoose,
shifts: shiftsForTaskChoose,
scheduleType,
setFor:
birthDateTimeStamp &&
moment
.utc(
[
birthDateTimeStamp.year,
birthDateTimeStamp.month,
birthDateTimeStamp.day,
],
"jYYYY-jMM-jDDTHH"
)
.unix(),
days: shiftsDaysChoose,
id: idEditTask,
};
const clear = () => {
setPositionsForTaskCurrent([]);
// setPositionsSelectData([]);
setRoutineForTaskCurrent([]);
// setRoutinesSelectData([]);
setBirthDateTimeStamp(0);
setScheduleType([]);
setDescription("");
setTitle("");
setShiftsForTaskCurrent([]);
// setShiftsSelectData([]);
setShiftsDaysCurrent([]);
// setShiftsDaysSelectData([]);
CTX.setRoutineForTaskChoose([]);
CTX.setPositionsForTaskChoose([]);
CTX.setShiftsForTaskChoose([]);
CTX.setShiftsDaysChoose([]);
};
const CreateTask = async (body) => {
CTX.setLoading(true);
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/task`,
JSON.stringify(body),
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
toast.success(`فعالیت ساخته شد`, {
position: "bottom-right",
closeOnClick: true,
});
clear();
CTX.setBottomSheetCreateTaskOpen(false);
CTX.setLoading(false);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
CTX.setLoading(false);
}
};
const UpdateTask = async (body) => {
CTX.setLoading(true);
try {
const data = await Chapar.put(
`${process.env.NEXT_PUBLIC_API_URL}/task`,
body,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
toast.success(`فعالیت ویرایش شد`, {
position: "bottom-right",
closeOnClick: true,
});
// router->
CTX.setLoading(false);
CTX.setStopGetTasks(false);
CTX.setPageGetTasks(0);
CTX.setBottomSheetCreateTaskOpen(false);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
setLoading(false);
}
};
const handleCreateTask = (update) => {
if (scheduleType == 0) {
validator.current.message("shiftsDaysChoose", true, "required");
validator.current.message("birthDateTimeStamp", true, "required");
}
if (scheduleType == 1) {
validator.current.message("birthDateTimeStamp", true, "required");
}
if (scheduleType == 2) {
validator.current.message("shiftsDaysChoose", true, "required");
}
if (validator.current.allValid()) {
if (update == "UPDATE") {
UpdateTask(bodyUpdate);
} else {
CreateTask(body);
}
} else {
toast.error("پرکردن همه ی فیلد ها واجب است", {
position: "bottom-right",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
validator.current.showMessages();
forceUpdate(1);
}
};
const deleteRoutineForTask = (value) => {
CTX.setRoutineForTaskChoose(
routineForTaskChoose.filter((el) => el !== value)
);
};
const deletePositionForTask = (value) => {
CTX.setPositionsForTaskChoose(
positionsForTaskChoose.filter((el) => el !== value)
);
};
const deleteShiftForTask = (value) => {
CTX.setShiftsForTaskChoose(
shiftsForTaskChoose.filter((el) => el !== value)
);
};
const deleteShiftsDaysForTask = (value) => {
CTX.setShiftsDaysChoose(shiftsDaysChoose.filter((el) => el !== value));
};
const handleBottomSheetCreateTaskOpen = (e) => {
if (e.type == "OPEN") {
CTX.GetRoutines();
CTX.GetPositions();
} else if (e.type == "CLOSE") {
clear();
}
};
useEffect(() => {
setRoutinesSelectData(
routinesData?.map((item) => ({
key: item?.name,
value: item?.id,
}))
);
}, [routinesData]);
useEffect(() => {
setPositionsSelectData(
positionsData?.map((item) => ({
key: item?.name,
value: item?.id,
}))
);
}, [positionsData]);
useEffect(() => {
setShiftsSelectData(
shiftsData?.map((item) => ({
key: item?.title,
value: item?.id,
}))
);
}, [shiftsData]);
useEffect(() => {
setShiftsDaysSelectData(
shiftsForTaskChoose?.length > 0 &&
shiftsData
?.find((e) => e?.id == shiftsForTaskChoose[0])
?.days?.map((item) => ({
key: week?.find((e) => e.value == item)?.key,
value: item,
}))
);
}, [shiftsForTaskChoose]);
useEffect(() => {
switch (scheduleType) {
case 0:
setBirthDateTimeStamp(0);
CTX.setShiftsDaysChoose([]);
break;
case 1:
setBirthDateTimeStamp(0);
break;
case 2:
CTX.setShiftsDaysChoose([]);
break;
default:
break;
}
}, [scheduleType]);
useEffect(() => {
if (goToEditTask) {
// const date = moment
// .unix(taskData.birthDateTimeStamp)
// .locale("fa")
// .format("YYYY/MM/DD")
// .split("/");
// setBirthDateTimeStamp({
// day: parseInt(date[2]),
// month: parseInt(date[1]),
// year: parseInt(date[0]),
// });
setScheduleType(taskData.scheduleType);
setDescription(taskData.description);
setTitle(taskData.title);
CTX.setRoutineForTaskChoose(
taskData.routines?.map((item) => item.routineId)
);
CTX.setPositionsForTaskChoose(
taskData.positions?.map((item) => item.positionId)
);
CTX.setShiftsDaysChoose(taskData.days?.map((item) => item.dayOfWeek));
CTX.setShiftsForTaskChoose(taskData.shifts?.map((item) => item.shiftId));
}
}, [taskData]);
return (
<BottomSheet
onSpringStart={(e) => handleBottomSheetCreateTaskOpen(e)}
open={CTX.state.BottomSheetCreateTaskOpen}
onDismiss={() => CTX.setBottomSheetCreateTaskOpen(false)}
blocking={true}
>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">
افزودن تسک جدید{" "}
</p>
</div>
<div className="bg-white overflow-hidden p-5 rtl">
<div>
<div className="">
<Input
lable="عنوان فعالیت"
theme={1}
mt={6}
id="title-id"
name="title"
type={"text"}
value={title}
inputEvent={(e) => {
setTitle(e.target.value);
validator.current.showMessageFor("title");
}}
style="text-right"
validator={true}
validatorData={validator.current.message(
"title",
title,
"required"
)}
/>
</div>
<div className="">
<Input
lable=" توضیحات"
theme={1}
mt={6}
id="description-id"
name="description"
type={"text"}
value={description}
inputEvent={(e) => {
setDescription(e.target.value);
}}
textarea={true}
style="text-right"
/>
</div>
{/* ===========routine=============== */}
<div className="">
<Input
lable="روتین فعالیت"
theme={1}
mt={6}
id="routines-id"
name="routines"
type={"text"}
value={setRoutineForTaskCurrent}
inputEvent={(e) => {
setRoutineForTaskCurrent(e.target.value);
validator.current.showMessageFor("routines");
if (!!routineForTaskChoose.find((b) => b == e.target.value)) {
toast.error("روز تکراری است", {
position: "bottom-right",
closeOnClick: true,
});
} else {
CTX.setRoutineForTaskChoose(() => [e.target.value]);
}
}}
style="text-right"
validator={true}
validatorData={validator.current.message(
"routines",
routineForTaskChoose,
["required", { min: 1 }]
)}
select={true}
selectData={routinesSelectData}
defaultValue={"انتخاب کنید"}
/>
</div>
<div className="flex flex-wrap rtl">
{routineForTaskChoose &&
routineForTaskChoose.map((e, index) => (
<div
className="flex bg-gray-300 p-1 rounded-full m-1 justify-start mt-3"
key={index}
>
{/* <div
className="w-[30px] h-[30px] rounded-full bg-gray-400 "
onClick={() => deleteRoutineForTask(e)}
></div> */}
<div>
<p className="mb-0 px-3 text-sm">
{routinesData?.find((b) => b.id == e)?.name}
</p>
</div>
</div>
))}
</div>
{/* ===========position=============== */}
<div className="">
<Input
lable="پوزیشن فعالیت"
theme={1}
mt={6}
id="positions-id"
name="positions"
value={setPositionsForTaskCurrent}
type={"text"}
inputEvent={(e) => {
setPositionsForTaskCurrent(e.target.value);
validator.current.showMessageFor("positions");
if (positionsForTaskChoose.length >= 1) {
toast.error("شما فقط یک پوزیشن را میتوانید انتخاب کنید", {
position: "bottom-right",
closeOnClick: true,
});
} else {
if (
!!positionsForTaskChoose.find((b) => b == e.target.value)
) {
toast.error("پوزیشن تکراری است", {
position: "bottom-right",
closeOnClick: true,
});
} else {
CTX.setPositionsForTaskChoose((current) => [
...current,
e.target.value,
]);
}
}
}}
style="text-right"
validatorData={validator.current.message(
"positions",
positionsForTaskChoose,
["required", { min: 1 }]
)}
select={true}
selectData={positionsSelectData}
defaultValue={"انتخاب کنید"}
/>
</div>
<div className="flex flex-wrap rtl">
{positionsForTaskChoose &&
positionsForTaskChoose.map((e, index) => (
<div
className="flex bg-gray-300 p-1 rounded-full m-1 justify-start mt-3"
key={index}
>
<div
className="w-[20px] h-[20px] rounded-full bg-gray-400 "
onClick={() => deletePositionForTask(e)}
></div>
<div>
<p className="mb-0 px-3 text-sm ">
{positionsData?.find((b) => b.id == e)?.name}
</p>
</div>
</div>
))}
</div>
{/* ===========shifts=============== */}
<div className="">
<Input
lable="شیفت فعالیت"
theme={1}
mt={6}
id="shifts-id"
name="shifts"
type={"text"}
value={setShiftsForTaskCurrent}
inputEvent={(e) => {
setShiftsForTaskCurrent(e.target.value);
validator.current.showMessageFor("shifts");
if (!!shiftsForTaskChoose.find((b) => b == e.target.value)) {
toast.error("روز تکراری است", {
position: "bottom-right",
closeOnClick: true,
});
} else {
CTX.setShiftsForTaskChoose(() => [e.target.value]);
}
}}
style="text-right"
validatorData={validator.current.message(
"shifts",
shiftsForTaskChoose,
["required", { min: 1 }]
)}
select={true}
selectData={shiftsSelectData}
defaultValue={"انتخاب کنید"}
/>
</div>
<div className="flex flex-wrap rtl">
{shiftsForTaskChoose &&
shiftsForTaskChoose.map((e, index) => (
<div
className="flex bg-gray-300 p-1 rounded-full m-1 justify-start mt-3"
key={index}
>
{/* <div
className="w-[20px] h-[20px] rounded-full bg-gray-400 "
onClick={() => deleteShiftForTask(e)}
></div> */}
<div>
<p className="mb-0 px-3 text-sm ">
{shiftsData?.find((b) => b?.id == e)?.title}
</p>
</div>
</div>
))}
</div>
{/* ===========scheduleType=============== */}
<div className="">
<Input
lable="تکرار پذیری فعالیت"
id="scheduleType-id"
theme={1}
mt={6}
name="scheduleType"
type={"text"}
value={scheduleType}
inputEvent={(e) => {
setScheduleType(parseInt(e.target.value));
validator.current.showMessageFor("scheduleType");
}}
style="text-right"
validator={true}
validatorData={validator.current.message(
"scheduleType",
scheduleType,
["required"]
)}
select={true}
selectData={[
{ key: "هفتگی", value: 1 },
{ key: "روزانه", value: 0 },
{ key: "مخصوص یک روز ", value: 2 },
]}
defaultValue={"انتخاب کنید"}
/>
</div>
{/* <div className="flex flex-wrap mt-3 rtl">
<div className="flex bg-gray-300 p-1 rounded-full m-1 justify-start">
<div>
<p className="mb-0 px-3 text-sm mt-1">
{schedule?.find((b) => b.value == scheduleType)?.key}
</p>
</div>
</div>
</div> */}
{/* ===========scheduleType setFor=============== */}
{scheduleType == 2 && (
<DatePickerIran
title="تاریخ مورد نظر فعالیت"
name="birthDateTimeStamp"
datePickerEvent={(e) => {
setBirthDateTimeStamp(e);
validator.current.showMessageFor("birthDateTimeStamp");
}}
date={birthDateTimeStamp}
zindex="z-[101]"
validator={true}
validatorData={validator.current.message(
"birthDateTimeStamp",
birthDateTimeStamp,
["required"]
)}
/>
)}
</div>
{/* ===========shiftsDaysTask=============== */}
{scheduleType == 1 && (
<>
<div className="">
<Input
lable="انتخاب روزهای این فعالیت در هفته"
theme={1}
mt={6}
id="shiftsDaysChoose-id"
name="shiftsDaysChoose"
type={"text"}
value={setShiftsDaysCurrent}
inputEvent={(e) => {
setShiftsDaysCurrent(e.target.value);
validator.current.showMessageFor("shiftsDaysChoose");
if (!!shiftsDaysChoose.find((b) => b == e.target.value)) {
toast.error("روز تکراری است", {
position: "bottom-right",
closeOnClick: true,
});
} else {
CTX.setShiftsDaysChoose((current) => [
...current,
parseInt(e.target.value),
]);
}
}}
validator={true}
validatorData={validator.current.message(
"shiftsDaysChoose",
shiftsDaysChoose,
["required", { min: 1 }]
)}
style="text-right"
select={true}
selectData={shiftsDaysSelectData}
defaultValue={"انتخاب کنید"}
/>
</div>
<div className="flex flex-wrap mt-3 rtl">
{shiftsDaysChoose &&
shiftsDaysChoose.map((e, index) => (
<div
className="flex bg-gray-300 p-1 rounded-full m-1 justify-start"
key={index}
>
<div
className="w-[20px] h-[20px] rounded-full bg-gray-400 "
onClick={() => deleteShiftsDaysForTask(e)}
></div>
<div>
<p className="mb-0 px-3 text-sm ">
{week?.find((b) => b.value == e).key}
</p>
</div>
</div>
))}
</div>
</>
)}
{goToEditTask ? (
<Buttonbriz
title="ویرایش فعالبت"
color="INFO"
icon="CHECK"
buttonEvent={() => handleCreateTask("UPDATE")}
subButton={true}
subButtonTitle="حذف فعالیت"
subButtonEvent={() => CTX.DeleteTask(idEditTask)}
/>
) : (
<Buttonbriz
title="ثبت فعالیت"
color="PRIMARY"
icon="CHECK"
buttonEvent={() => handleCreateTask()}
/>
)}{" "}
</div>
</BottomSheet>
);
};
export default BottomSheetCreateTask;

View File

@ -27,10 +27,10 @@ const BottomSheetReport = (props) => {
<BottomSheet
open={CTX.state.BottomSheetReportOpen}
onDismiss={() => CTX.setBottomSheetReportOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-primary-300 ">
<p className="mb-0 text-white relative top-[-5px]">گزارشات</p>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">گزارشات </p>
</div>
<div className="px-3 pt-10 ">

View File

@ -15,6 +15,7 @@ const BottomSheetReportManageShift = (props) => {
const CTX = useContext(AppContext);
const shiftplansData = CTX.state.shiftPlansData;
const [shiftplans, setShiftplans] = useState([]);
const [type, setType] = useState(0);
// const reportDetail = CTX.state.reportDetail;
@ -31,9 +32,16 @@ const BottomSheetReportManageShift = (props) => {
const handleBottomSheetCreateRole = (e) => {
if (e.type == "OPEN") {
CTX.GetShifPlans(0, 12);
} else if (e.type == "CLOSE") {
setType(0);
}
};
const handleReportManageShift = (num, filterId) => {
setType(num);
CTX.GetShifPlans(0, filterId);
};
const groupObjectsByPlanFor = (responseData) => {
const groupedData = {};
@ -107,12 +115,42 @@ const BottomSheetReportManageShift = (props) => {
onSpringStart={(e) => handleBottomSheetCreateRole(e)}
open={CTX.state.BottomSheetReportManageShiftOpen}
onDismiss={() => CTX.setBottomSheetReportManageShiftOpen(false)}
blocking={false}
blocking={true}
>
<div className="text-center py-2 bg-primary-300 ">
<p className="mb-0 text-white relative top-[-5px]">گزارشات</p>
<div className="text-center py-2 bg-secondary-950 ">
<p className="mb-0 text-primary-300 relative top-[-5px]">گزارشات </p>
</div>
<div className="flex bg-gray-100 rounded-xl m-3 rtl">
<div
className={` p-2 w-full rounded-xl tr03 ${
type == 0 ? "bg-secondary-950" : ""
} `}
onClick={() => handleReportManageShift(0, 12)}
>
<p
className={`mb-0 text-center text-sm ${
type == 0 ? "text-white" : " text-secondary-900"
}`}
>
همین هفته{" "}
</p>
</div>
<div
className={` p-2 w-full rounded-xl tr03 ${
type == 1 ? "bg-secondary-950" : ""
} `}
onClick={() => handleReportManageShift(1, 11)}
>
<p
className={`mb-0 text-center text-sm ${
type == 1 ? "text-white" : " text-secondary-900"
}`}
>
هفته بعد{" "}
</p>
</div>
</div>
<div className="px-3 pt-10 ">
<p id="MYTEXT" className="mb-0 text-center text-sm font-light">
{shiftplans?.map((e, index) => (

View File

@ -0,0 +1,113 @@
// components/RecipeChart.js
import React from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from "chart.js";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const CoffeeBrewChart = ({ data }) => {
console.log("data", data);
const chartData = {
labels: data?.map((entry) =>
new Date(entry?.logAt).toLocaleDateString("fa-IR", {
month: "numeric",
day: "numeric",
})
), // X-axis labels
datasets: [
{
label: "Ratio",
data: data?.map((entry) => entry?.ratio),
borderColor: "rgba(75, 192, 192, 1)",
backgroundColor: "rgba(75, 192, 192, 0.2)",
fill: false,
},
{
label: "Extraction Time",
data: data?.map((entry) => entry?.extractionTime),
borderColor: "rgba(153, 102, 255, 1)",
backgroundColor: "rgba(153, 102, 255, 0.2)",
fill: false,
},
{
label: "Final Yield",
data: data?.map((entry) => entry?.finalYield),
borderColor: "rgba(255, 159, 64, 1)",
backgroundColor: "rgba(255, 159, 64, 0.2)",
fill: false,
},
],
};
const options = {
responsive: true,
maintainAspectRatio: false, // Disable aspect ratio to allow custom sizing
plugins: {
legend: {
display: false, // Hide the legend
},
title: {
display: false, // Hide the title
},
},
scales: {
x: {
title: {
display: false,
text: "Date",
font: {
size: 16,
family: "KalamehWeb", // Customize font family if needed
style: "normal",
},
},
ticks: {
font: {
size: 12,
family: "KalamehWeb", // Customize font family if needed
style: "normal",
},
},
},
y: {
title: {
display: false, // Hide the y-axis title
},
ticks: {
font: {
size: 12,
family: "Arial", // Customize font family if needed
style: "normal",
},
},
},
},
};
return (
<div style={{ height: "200px", overflowX: "auto" }}>
<div style={{ height: "200px" }}>
<Line data={chartData} options={options} />
</div>
</div>
);
};
export default CoffeeBrewChart;

View File

@ -31,7 +31,7 @@ const DatePickerIran = ({
<div
className={`flex justify-end relative top-[22px] right-3 ltr ${zindex}`}
>
<div className="bg-body-100 px-2">
<div className="bg-white px-2">
<p className="mb-0 text-sm mr-0 mx-auto">{title}</p>
</div>
</div>
@ -41,7 +41,7 @@ const DatePickerIran = ({
onChange={datePickerEvent}
shouldHighlightWeekends
inputClassName={`peer w-full border-b placeholder:text-transparent relative !text-right ${
2 == 1 ? "form-control-white" : "form-control"
1 == 1 ? "form-control-white" : "form-control"
}`}
locale="fa"
name={name}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

View File

@ -18,8 +18,8 @@ const page = () => {
const [fistName, setFistName] = useState("");
const [lastName, setLastName] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [nationalId, setNationalId] = useState("");
const [birthDateTimeStamp, setBirthDateTimeStamp] = useState("");
// const [nationalId, setNationalId] = useState("");
// const [birthDateTimeStamp, setBirthDateTimeStamp] = useState("");
const [, forceUpdate] = useState();
const validator = useRef(
@ -49,7 +49,7 @@ const page = () => {
setFistName(profile?.firstName);
setLastName(profile?.lastName);
setPhoneNumber(profile?.phoneNumber);
setNationalId(profile?.nationalId);
// setNationalId(profile?.nationalId);
// setBirthDateTimeStamp(
// profile.birthDateTimeStamp < 0 ? ["1376", "09", "14"] : ""
@ -135,6 +135,7 @@ const page = () => {
fistName,
"required"
)}
theme={1}
/>
</div>
<div className="">
@ -155,6 +156,7 @@ const page = () => {
lastName,
"required"
)}
theme={1}
/>
</div>
@ -176,35 +178,16 @@ const page = () => {
phoneNumber,
"required"
)}
theme={1}
readOnly={true}
/>
</div>
<div className="">
<Input
lable="کد ملی "
id="nationalId-id"
name="nationalId"
type={"text"}
value={nationalId}
inputEvent={(e) => {
setNationalId(e.target.value);
validator.current.showMessageFor("nationalId");
}}
style="text-right"
validator={true}
validatorData={validator.current.message(
"nationalId",
nationalId,
"required"
)}
/>
</div>
<DatePickerIran
{/* <DatePickerIran
datePickerEvent={(e) => setBirthDateTimeStamp(e)}
date={birthDateTimeStamp}
zindex="z-[101]"
/>
/> */}
</div>
<Buttonbriz title="ثبت تغییرات" color="INFO" icon="CHECK" />

View File

@ -10,6 +10,7 @@ import CoffeeBrewCard from "@comp/CoffeeBrew/CoffeeBrewCard/page";
import AppContext from "@ctx/AppContext";
import Chapar from "plugins/Chapar";
import { toast } from "react-toastify";
import CoffeeBrewChart from "plugins/Charts/CoffeeBrewChart";
const page = () => {
const router = useRouter();
@ -175,7 +176,8 @@ const page = () => {
<h3 className="text-right px-3 pb-1 font-medium mt-7 text-sm">
تاریخچه ادجاست ها
</h3>
<div className="w-[60px] h-[2px] bg-gray-300 mx-3 mb-3"></div>
<CoffeeBrewChart data={coffeeBrewData?.pastRecipes} />
{coffeeBrewData?.pastRecipes?.map((e) => (
<CoffeeBrewCard data={e} />

View File

@ -20,16 +20,23 @@ import ShiftsEmployees from "@comp/EmployeesComponent/Shifts/page";
import ParseJwt from "plugins/ParseJwt/page";
import GoBack from "plugins/GoBack/page";
import HasPermission from "plugins/HasPermission/page";
import { useRouter } from "next/navigation";
import TasksEmployees from "@comp/EmployeesComponent/Tasks/page";
import BottomSheetCreateTask from "plugins/BottomSheet/BottomSheetCreateTask";
// import second from "@img/test.png";
const Employees = (props) => {
const CTX = useContext(AppContext);
const permissions = CTX.state.profile?.permissions;
const pageGetTasks = CTX.state.pageGetTasks;
const router = useRouter();
const [activeSection, setActiveSection] = useState(0);
useEffect(() => {
CTX.GetUnReadNotif();
CTX.GetRoutines();
}, []);
@ -67,6 +74,11 @@ const Employees = (props) => {
}
break;
case 5:
if (activeSection != num) {
CTX.GetShifts();
}
break;
default:
break;
}
@ -79,12 +91,6 @@ const Employees = (props) => {
<AppHeader
title=" مدیریت کارکنان و نقش ها"
sub=" هسته اصلی تنظیمات مجموعه"
icon2={true}
iconName2="ARROW"
iconHref2="#"
iconEvent2={() => {
GoBack();
}}
/>
<div className="bg-white overflow-hidden p-5 rtl">
@ -103,7 +109,7 @@ const Employees = (props) => {
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={1} style="!text-[20px] " />
<PersianNumber number={1} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
@ -158,7 +164,7 @@ const Employees = (props) => {
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={2} style="!text-[20px] " />
<PersianNumber number={2} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
@ -209,7 +215,7 @@ const Employees = (props) => {
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={3} style="!text-[20px] " />
<PersianNumber number={3} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
@ -263,7 +269,7 @@ const Employees = (props) => {
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={4} style="!text-[20px] " />
<PersianNumber number={4} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
@ -317,7 +323,7 @@ const Employees = (props) => {
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={5} style="text-[30px] " />
<PersianNumber number={5} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
@ -357,6 +363,65 @@ const Employees = (props) => {
</div>
{activeSection == 4 && <ShiftsEmployees />}
</div>
<div
className={` ${
activeSection == 5
? "bg-secondary-50 rounded-b-2xl pb-3"
: "border-b border-gray-200 p-2"
}`}
>
<div
className="flex justify-between "
onClick={() => handleGetApi(5)}
>
<div className="flex p-2">
<div className="bg-secondary-50 rounded-lg w-[30px] h-[30px]">
<p className="mb-0 text-center pt-1 ">
<PersianNumber number={6} style="!text-[15px] " />
</p>
</div>
<div className="pt-1 pr-2 ">
<h4 className="text-sm font-bold">افزودن تسک مجموعه</h4>
</div>
</div>
{HasPermission("ManageTasks", permissions) && (
<>
{activeSection == 5 ? (
<div
className="w-[30px] h-[30px] bg-secondary-50 shadow-sm rounded-lg mt-2 ml-3 "
onClick={() => {
CTX.setTaskData([]);
CTX.setIdEditTask("");
CTX.setGoToEditTask(false);
CTX.setBottomSheetCreateTaskOpen(true);
}}
>
<svg
width="15"
height="15"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-2 opacity-70"
>
<path
d="M8 1V15M1 8H15"
stroke="#2B2B2B"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
) : (
<div className="w-[10px] h-[10px] bg-gray-200 shadow-sm rounded-xl m-[15px] "></div>
)}
</>
)}
</div>
{activeSection == 5 && <TasksEmployees />}
</div>
</div>
{/* <BottomSheetCreateRole /> */}
<BottomSheetCreateEmployees />
@ -364,6 +429,7 @@ const Employees = (props) => {
<BottomSheetCreateRoutine />
<BottomSheetCreatePosition />
<BottomSheetCreateShifts />
<BottomSheetCreateTask />
</div>
);
};

View File

@ -34,6 +34,7 @@ const Home = (props) => {
useEffect(() => {
CTX.GetHomePageData();
CTX.GetLatesCoffeeBrewData();
CTX.GetUnReadNotif();
}, []);
const dataChart = (totalActivitiesCount, doneActivitiesCount) => {
@ -65,9 +66,19 @@ const Home = (props) => {
CTX.setBottomSheetReportOpen(true);
};
const handleActiveShiftPlanHom = (index) => {
if (activeShiftPlanHome == index) {
setActiveShiftPlanHome(-1);
} else {
setActiveShiftPlanHome(index);
}
};
const today = new Date();
const formattedDate = FormatJalaliDate(today);
console.log(latesCoffeeBrewData);
return (
<div className="pb-20">
<AppHeader
@ -129,27 +140,37 @@ const Home = (props) => {
</div>
</div>
<div className="col-span-2 mt-5">
{latesCoffeeBrewData.logBy !== "" ? (
<div className="col-span-2 mt-5">
<Link href={"/coffee-brew"}>
<CoffeeBrewCard data={latesCoffeeBrewData} />
</Link>
</div>
) : (
<Link href={"/coffee-brew"}>
<CoffeeBrewCard data={latesCoffeeBrewData} />
<div className="bg-gray-50 rounded-lg p-6 mt-3 text-center text-gray-500 ">
<p className="bg-white p-2 w-fit mx-auto rounded-2xl text-sm">
افزودن ادجاست جدید
</p>
</div>
</Link>
</div>
)}
<div className="col-span-2">
{homePageData?.shiftPlans?.map((e, index) => (
<>
<div
className="flex justify-between mt-5 bg-gray-50 p-2 rounded-xl"
onClick={() => setActiveShiftPlanHome(index)}
onClick={() => handleActiveShiftPlanHom(index)}
>
<div className="flex">
{homePageData?.currentShiftId == e.id && (
<div className="relative mt-1 ml-1 ">
<div className="relative mt-2 ml-1 ">
<div className="blink_me w-3 h-3 rounded-full bg-green-600 "></div>
</div>
)}
<p className="mb-0 text-sm">{e.shiftTitle} </p>
<p className="mb-0 text-[13px] mt-1">{e.shiftTitle} </p>
</div>
<div className="bg-gray-100 w-[30px] h-[30px] rounded-xl">
@ -159,7 +180,9 @@ const Home = (props) => {
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-80 mt-2 mx-auto"
className={`opacity-80 mt-2 mx-auto tr03 ${
activeShiftPlanHome == index ? "rotate-180" : ""
}`}
>
<path
d="M13.0444 13.1674L75.3606 75.8506L138.044 13.5345"
@ -381,114 +404,6 @@ const Home = (props) => {
</div>
</div>
</div>
<div className="rtl mt-4">
<div className="flex ">
<div className="w-[50px] h-[50px] rounded-2xl bg-white shadow">
<svg
width="25"
height="25"
viewBox="0 0 251 226"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-3 opacity-50"
s
>
<path
d="M246.65 100.5L196.612 13.0002C194.463 9.19349 191.338 6.02857 187.559 3.83143C183.78 1.63429 179.483 0.48438 175.112 0.50016H75.062C70.6812 0.545125 66.3859 1.71914 62.5912 3.9088C58.7966 6.09846 55.6307 9.22974 53.3995 13.0002L3.36204 100.5C1.16661 104.3 0.0107422 108.611 0.0107422 113C0.0107422 117.389 1.16661 121.7 3.36204 125.5L53.3995 213C55.6307 216.771 58.7966 219.902 62.5912 222.092C66.3859 224.281 70.6812 225.455 75.062 225.5H175.137C179.507 225.515 183.801 224.365 187.578 222.167C191.355 219.97 194.478 216.806 196.625 213L246.662 125.5C248.857 121.7 250.013 117.389 250.013 113C250.013 108.611 248.845 104.3 246.65 100.5ZM175 200.5H74.9995L24.9995 113L74.9995 25.5002H175L225 113L175 200.5Z"
fill="#ABABAB"
/>
<path
d="M112 63.5C112 56.5964 117.596 51 124.5 51V51C131.404 51 137 56.5964 137 63.5V126C137 132.904 131.404 138.5 124.5 138.5V138.5C117.596 138.5 112 132.904 112 126V63.5Z"
fill="#ABABAB"
/>
<path
d="M124.5 173C131.404 173 137 167.404 137 160.5C137 153.596 131.404 148 124.5 148C117.596 148 112 153.596 112 160.5C112 167.404 117.596 173 124.5 173Z"
fill="#ABABAB"
/>
</svg>
</div>
<div className="mx-2 mt-1 opacity-50">
<h3 className="text-sm font-bold "> شیفت های تمام شده </h3>
<p className="mb-0 text-right text-sm text-gray-500">
خروجی اکسل
</p>
</div>
</div>
</div>
<div className="rtl mt-4">
<div className="flex ">
<div className="w-[50px] h-[50px] rounded-2xl bg-white shadow">
<svg
width="25"
height="25"
viewBox="0 0 251 226"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-3 opacity-50"
s
>
<path
d="M246.65 100.5L196.612 13.0002C194.463 9.19349 191.338 6.02857 187.559 3.83143C183.78 1.63429 179.483 0.48438 175.112 0.50016H75.062C70.6812 0.545125 66.3859 1.71914 62.5912 3.9088C58.7966 6.09846 55.6307 9.22974 53.3995 13.0002L3.36204 100.5C1.16661 104.3 0.0107422 108.611 0.0107422 113C0.0107422 117.389 1.16661 121.7 3.36204 125.5L53.3995 213C55.6307 216.771 58.7966 219.902 62.5912 222.092C66.3859 224.281 70.6812 225.455 75.062 225.5H175.137C179.507 225.515 183.801 224.365 187.578 222.167C191.355 219.97 194.478 216.806 196.625 213L246.662 125.5C248.857 121.7 250.013 117.389 250.013 113C250.013 108.611 248.845 104.3 246.65 100.5ZM175 200.5H74.9995L24.9995 113L74.9995 25.5002H175L225 113L175 200.5Z"
fill="#ABABAB"
/>
<path
d="M112 63.5C112 56.5964 117.596 51 124.5 51V51C131.404 51 137 56.5964 137 63.5V126C137 132.904 131.404 138.5 124.5 138.5V138.5C117.596 138.5 112 132.904 112 126V63.5Z"
fill="#ABABAB"
/>
<path
d="M124.5 173C131.404 173 137 167.404 137 160.5C137 153.596 131.404 148 124.5 148C117.596 148 112 153.596 112 160.5C112 167.404 117.596 173 124.5 173Z"
fill="#ABABAB"
/>
</svg>
</div>
<div className="mx-2 mt-1 opacity-50">
<h3 className="text-sm font-bold "> شیفت های مجموعه </h3>
<p className="mb-0 text-right text-sm text-gray-500">
خروجی اکسل
</p>
</div>
</div>
</div>
<div className="rtl mt-4">
<div className="flex ">
<div className="w-[50px] h-[50px] rounded-2xl bg-white shadow">
<svg
width="25"
height="25"
viewBox="0 0 251 226"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="mx-auto mt-3 opacity-50"
s
>
<path
d="M246.65 100.5L196.612 13.0002C194.463 9.19349 191.338 6.02857 187.559 3.83143C183.78 1.63429 179.483 0.48438 175.112 0.50016H75.062C70.6812 0.545125 66.3859 1.71914 62.5912 3.9088C58.7966 6.09846 55.6307 9.22974 53.3995 13.0002L3.36204 100.5C1.16661 104.3 0.0107422 108.611 0.0107422 113C0.0107422 117.389 1.16661 121.7 3.36204 125.5L53.3995 213C55.6307 216.771 58.7966 219.902 62.5912 222.092C66.3859 224.281 70.6812 225.455 75.062 225.5H175.137C179.507 225.515 183.801 224.365 187.578 222.167C191.355 219.97 194.478 216.806 196.625 213L246.662 125.5C248.857 121.7 250.013 117.389 250.013 113C250.013 108.611 248.845 104.3 246.65 100.5ZM175 200.5H74.9995L24.9995 113L74.9995 25.5002H175L225 113L175 200.5Z"
fill="#ABABAB"
/>
<path
d="M112 63.5C112 56.5964 117.596 51 124.5 51V51C131.404 51 137 56.5964 137 63.5V126C137 132.904 131.404 138.5 124.5 138.5V138.5C117.596 138.5 112 132.904 112 126V63.5Z"
fill="#ABABAB"
/>
<path
d="M124.5 173C131.404 173 137 167.404 137 160.5C137 153.596 131.404 148 124.5 148C117.596 148 112 153.596 112 160.5C112 167.404 117.596 173 124.5 173Z"
fill="#ABABAB"
/>
</svg>
</div>
<div className="mx-2 mt-1 opacity-50">
<h3 className="text-sm font-bold ">
{" "}
کاست تمام شده آیتم ها{" "}
</h3>
<p className="mb-0 text-right text-sm text-gray-500">
خروجی اکسل
</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -66,6 +66,9 @@ export default function RootLayout({ children }) {
setBottomSheetReportManageShiftOpen,
] = useState(false);
const [BottomSheetCreateTaskOpen, setBottomSheetCreateTaskOpen] =
useState(false);
// BigPlus
const [BigPlusOpen, setBigPlusOpen] = useState(false);
const [BigPlusRotateIcon, setBigPlusRotateIcon] = useState(false);
@ -94,6 +97,7 @@ export default function RootLayout({ children }) {
// createUser/ user
const [usersData, setUsersData] = useState([]);
const [userStaffData, setUserStaffData] = useState([]);
const [rolesChoose, setRolesChoose] = useState([]);
const [userData, setUserData] = useState([]);
const [goToEditUser, setGoToEditUser] = useState(false);
@ -166,6 +170,9 @@ export default function RootLayout({ children }) {
const [coffeeBrewData, setCoffeeBrewData] = useState([]);
const [latesCoffeeBrewData, setLatesCoffeeBrewData] = useState([]);
//notif
const [notifUnreadData, setNotifUnreadData] = useState("");
const pathname = usePathname();
const router = useRouter();
const hiddenUrls = ["/login", "/pricing", "/about-us", "/"];
@ -510,6 +517,30 @@ export default function RootLayout({ children }) {
setLoading(false);
}
};
const GetUserStaff = async (FilterDate) => {
setLoading(true);
try {
const data = await Chapar.get(
`${
process.env.NEXT_PUBLIC_API_URL
}/user/staff?filter=${FilterDate}&page=${0}`,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
}
);
setUserStaffData(data);
setLoading(false);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
setLoading(false);
}
};
const DeleteUser = async (id) => {
setLoading(true);
try {
@ -1122,7 +1153,6 @@ export default function RootLayout({ children }) {
// router->
setLoading(false);
GetTasks(0);
router.push("/tasks");
} catch ({ error, status }) {
@ -1154,7 +1184,6 @@ export default function RootLayout({ children }) {
// router->
setLoading(false);
GetTasks(0);
router.push("/tasks");
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
@ -1164,11 +1193,11 @@ export default function RootLayout({ children }) {
setLoading(false);
}
};
const GetTasks = async (page) => {
const GetTasks = async (page, shiftId) => {
setLoading(true);
try {
const data = await Chapar.get(
`${process.env.NEXT_PUBLIC_API_URL}/task?page=${page}`,
`${process.env.NEXT_PUBLIC_API_URL}/task?page=${page}&shiftId=${shiftId}`,
{
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
@ -1230,8 +1259,7 @@ export default function RootLayout({ children }) {
);
setLoading(false);
GetTasks();
router.push("/tasks");
setBottomSheetCreateTaskOpen(false);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
@ -1241,7 +1269,7 @@ export default function RootLayout({ children }) {
}
};
const GetActivity = async (date, shift, page, dateQueryFilter) => {
const GetActivity = async (date, shift, page, dateQueryFilter, userId) => {
setLoading(true);
try {
const data = await Chapar.get(
@ -1249,7 +1277,7 @@ export default function RootLayout({ children }) {
date ? `&selectedDate=${date}` : ""
}${shift ? `&selectedShiftPlanId=${shift}` : ""}${
dateQueryFilter != null ? `&dateQueryFilter=${dateQueryFilter}` : ""
}`,
}${userId != null ? `&userId=${userId}` : ""}`,
{
headers: {
@ -1540,15 +1568,34 @@ export default function RootLayout({ children }) {
}
};
const GetUnReadNotif = async () => {
setLoading(true);
try {
const data = await Chapar.get(
`${process.env.NEXT_PUBLIC_API_URL}/notification/unread/count`
);
setNotifUnreadData(data);
setLoading(false);
return data;
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
setLoading(false);
}
};
useEffect(() => {
console.log(`
bbbbbbbb
b::::::b iiii
b::::::b i::::i
b::::::b iiii
b:::::b
b:::::bbbbbbbbb rrrrr rrrrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
b::::::::::::::bb r::::rrr:::::::::ri:::::iz:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
bbbbbbbb
b::::::b iiii
b::::::b i::::i
b::::::b iiii
b:::::b
b:::::bbbbbbbbb rrrrr rrrrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
b::::::::::::::bb r::::rrr:::::::::ri:::::iz:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
b::::::::::::::::br:::::::::::::::::ri::::iz::::::::::::::z c:::::::::::::::::o:::::::::::::::o
b:::::bbbbb:::::::rr::::::rrrrr::::::i::::izzzzzzzz::::::z c:::::::cccccc:::::o:::::ooooo:::::o
b:::::b b::::::br:::::r r:::::i::::i z::::::z c::::::c cccccco::::o o::::o
@ -1557,18 +1604,20 @@ export default function RootLayout({ children }) {
b:::::b b:::::br:::::r i::::i z::::::z c::::::c cccccco::::o o::::o
b:::::bbbbbb::::::br:::::r i::::::i z::::::zzzzzzzc:::::::cccccc:::::o:::::ooooo:::::o
b::::::::::::::::b r:::::r i::::::iz::::::::::::::zc:::::::::::::::::o:::::::::::::::o
b:::::::::::::::b r:::::r i::::::z:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
bbbbbbbbbbbbbbbb rrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
b:::::::::::::::b r:::::r i::::::z:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
bbbbbbbbbbbbbbbb rrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
soli chizi bood bgo hossein__masoomi
soli chizi bood bgo hossein__masoomi
`);
const token = localStorage.getItem("token");
// if (!token) {
// router.push("/login");
// }
if (profile.length <= 0 && token) CheckUser();
if (profile.length <= 0 && token) {
CheckUser();
}
}, []);
return (
@ -1652,6 +1701,9 @@ export default function RootLayout({ children }) {
BottomSheetReportManageShiftOpen,
coffeeBrewData,
latesCoffeeBrewData,
BottomSheetCreateTaskOpen,
userStaffData,
notifUnreadData,
},
setBottomSheetCreateRoleOpen,
setBottomSheetCreateEmployeesOpen,
@ -1782,6 +1834,11 @@ export default function RootLayout({ children }) {
GetCoffeeBrewData,
GetLatesCoffeeBrewData,
setLatesCoffeeBrewData,
setBottomSheetCreateTaskOpen,
setUserStaffData,
GetUserStaff,
setNotifUnreadData,
GetUnReadNotif,
}}
>
<html lang="en">

View File

@ -0,0 +1,557 @@
"use client";
import AppHeader from "@comp/AppHeader/page";
import { useRouter } from "next/navigation";
import React, { useContext, useEffect, useState } from "react";
import AppContext from "@ctx/AppContext";
import Chapar from "plugins/Chapar";
import { toast } from "react-toastify";
import Avatar from "boring-avatars";
import PersianNumber from "../../../plugins/PersianNumber";
import moment from "jalali-moment";
import InfiniteScroll from "react-infinite-scroll-component";
const page = () => {
const router = useRouter();
const CTX = useContext(AppContext);
const [typeNews, setTypeNews] = useState(1);
const [notifData, setNotifData] = useState([]);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(0);
const [hasMore, setHasMore] = useState(true);
const markAsRead = async (id, notifData, setNotifData) => {
console.log("ssssssssssssssssssssssssssss");
try {
const data = await Chapar.post(
`${process.env.NEXT_PUBLIC_API_URL}/notification/${id}/read`
);
// Update the local state to mark the notification as read
const updatedNotifData = notifData.map((notif) =>
notif.id === id ? { ...notif, isRead: true } : notif
);
setNotifData(updatedNotifData);
return data;
} catch ({ error, status }) {
toast.error(`در خواندن نوتیف مشکلی هست`, {
position: "bottom-right",
closeOnClick: true,
});
}
};
const loadNotifications = async () => {
setLoading(true);
try {
const data = await Chapar.get(
`${
process.env.NEXT_PUBLIC_API_URL
}/notification?page=${page}&count=${40}`
);
if (data.length === 0) {
setHasMore(false);
} else {
setNotifData((prevData) => [...prevData, ...data]);
setPage((prevPage) => prevPage + 1);
}
setLoading(false);
} catch ({ error, status }) {
toast.error(`${error?.response?.data?.message}`, {
position: "bottom-right",
closeOnClick: true,
});
setLoading(false);
}
};
useEffect(() => {
loadNotifications();
}, []);
let lastDate = null;
return (
<>
{" "}
<div className="pb-10">
<AppHeader title="خبر های مجموعه" sub="اخبار و نوتیف های مجموعه" />
{}
<div className="bg-white overflow-hidden p-5 rtl relative">
{" "}
<div className="flex bg-gray-100 rounded-xl">
<div
className={` p-2 w-full rounded-xl tr03 ${
typeNews == 0 ? "bg-secondary-950" : ""
} `}
onClick={() => setTypeNews(0)}
>
<p
className={`mb-0 text-center text-sm ${
typeNews == 0 ? "text-white" : " text-secondary-900"
}`}
>
اخبار{" "}
</p>
</div>
<div
className={` p-2 w-full rounded-xl tr03 ${
typeNews == 1 ? "bg-secondary-950" : ""
} `}
onClick={() => setTypeNews(1)}
>
<p
className={`mb-0 text-center text-sm ${
typeNews == 1 ? "text-white" : " text-secondary-900"
}`}
>
نوتیف{" "}
</p>
</div>
</div>
{typeNews == 0 ? (
<div className="blur-sm">
<div className=" mt-5 mb-[20px]">
<div className="my-4 flex sticky top-0">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"hamed hossein"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center mt-3">
<div className="absolute">
<div className="h-[80px] bg-gray-100 opacity-70 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-5 mt-1">
<h4 className="text-sm font-bold">محمد کاشغی</h4>
<div className="flex mt-2 gap-2">
<div className="bg-gray-100 flex rounded-2xl px-1">
<svg
width="15"
height="15"
viewBox="0 0 235 124"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-50 mt-[2px]"
>
<path
d="M160.75 124C152.328 124 145.5 117.172 145.5 108.75C145.5 100.327 152.328 93.4995 160.75 93.4995L219.75 93.4995C228.172 93.4995 235 100.327 235 108.75C235 117.172 228.172 124 219.75 124L160.75 124ZM88.4999 26.4998C81.3202 26.4998 75.5 20.6795 75.5 13.4999C75.5 6.32025 81.3202 0.499996 88.4999 0.499996L222 0.499998C229.18 0.499998 235 6.32025 235 13.4999C235 20.6795 229.18 26.4998 222 26.4998L88.4999 26.4998ZM13 72.4996C6.09643 72.4996 0.499998 66.9031 0.499997 59.9996C0.499997 53.096 6.09643 47.4996 13 47.4996L222.5 47.4996C229.404 47.4996 235 53.096 235 59.9996C235 66.9031 229.404 72.4996 222.5 72.4996L13 72.4996Z"
fill="#374151"
/>
</svg>
<p className="mb-0 text-[12px] text-gray-700 opacity-50 mr-1">
نظر سنجی
</p>
</div>
<div className="bg-gray-100 flex rounded-2xl px-1">
<svg
width="15"
height="15"
viewBox="0 0 228 228"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="opacity-50 mt-[2px]"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M92.017 23.8636C93.874 24.095 95.6672 24.6899 97.2943 25.6144C98.9214 26.5388 100.35 27.7747 101.5 29.2514C102.649 30.7281 103.497 32.4168 103.994 34.221C104.49 36.0252 104.627 37.9096 104.396 39.7666L101.052 66.4996H138.823L142.614 36.2326C143.083 32.4822 145.022 29.0717 148.005 26.7511C150.988 24.4306 154.771 23.3902 158.522 23.8589C162.272 24.3275 165.683 26.2668 168.003 29.25C170.324 32.2333 171.364 36.0162 170.896 39.7666L167.551 66.4996H190C193.779 66.4996 197.404 68.0009 200.076 70.6733C202.749 73.3457 204.25 76.9703 204.25 80.7496C204.25 84.5289 202.749 88.1535 200.076 90.8259C197.404 93.4983 193.779 94.9996 190 94.9996H163.989L159.239 133H185.25C189.029 133 192.654 134.501 195.326 137.173C197.999 139.846 199.5 143.47 199.5 147.25C199.5 151.029 197.999 154.653 195.326 157.326C192.654 159.998 189.029 161.5 185.25 161.5H155.676L151.896 191.767C151.427 195.517 149.488 198.928 146.504 201.248C143.521 203.569 139.738 204.609 135.988 204.14C132.237 203.672 128.827 201.732 126.506 198.749C124.186 195.766 123.145 191.983 123.614 188.233L126.948 161.5H89.186L85.405 191.767C84.9364 195.517 82.9971 198.928 80.0138 201.248C77.0305 203.569 73.2476 204.609 69.4972 204.14C65.7469 203.672 62.3363 201.732 60.0158 198.749C57.6952 195.766 56.6549 191.983 57.1235 188.233L60.4485 161.5H42.75C38.9707 161.5 35.3461 159.998 32.6737 157.326C30.0013 154.653 28.5 151.029 28.5 147.25C28.5 143.47 30.0013 139.846 32.6737 137.173C35.3461 134.501 38.9707 133 42.75 133H64.011L68.761 94.9996H47.5C43.7207 94.9996 40.0961 93.4983 37.4237 90.8259C34.7513 88.1535 33.25 84.5289 33.25 80.7496C33.25 76.9703 34.7513 73.3457 37.4237 70.6733C40.0961 68.0009 43.7207 66.4996 47.5 66.4996H72.3235L76.114 36.2326C76.3443 34.3748 76.9383 32.5805 77.8623 30.9523C78.7862 29.3242 80.0219 27.894 81.4988 26.7436C82.9756 25.5932 84.6647 24.745 86.4695 24.2476C88.2742 23.7502 90.1593 23.6132 92.017 23.8446V23.8636ZM130.53 133L135.28 94.9996H97.4985L92.7485 133H130.53Z"
fill="black"
/>
</svg>
<p className="mb-0 text-[12px] text-gray-700 opacity-50 mr-1">
اختصاصی{" "}
</p>
</div>
</div>
<div className="mt-2">
<textarea
type="text"
className="form-control-white !border !border-gray-100 text-[12px] !p-2 !min-h-[70px]"
placeholder="منتظر بودیم خبر بدی !!"
/>
</div>
</div>
</div>
</div>
<div className="mt-5">
<p className="mb-0 font-medium text-sm">امروز</p>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"hamed hossein"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[78px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-5 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">محمد کاشغی</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"علی سلامیان"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[20px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">علی سلامیان اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"بیاب اصل"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[137px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">شهاب اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و
برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با
هدف بهبود ابزارهای کاربردی می باشد کتابهای زیادی در شصت
و سه درصد گذشته حال و آینده شناخت فراوان جامعه و متخصصان
را می طلبد{" "}
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"بیاب اصل"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">شهاب اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"hamed hossein"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[78px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-5 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">محمد کاشغی</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"علی سلامیان"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[20px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">علی سلامیان اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"بیاب اصل"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
<div className="flex justify-center">
<div className="absolute">
<div className="h-[137px] bg-gray-200 w-[2px]"></div>
</div>
</div>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">شهاب اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و
برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با
هدف بهبود ابزارهای کاربردی می باشد کتابهای زیادی در شصت
و سه درصد گذشته حال و آینده شناخت فراوان جامعه و متخصصان
را می طلبد{" "}
</p>
</div>
</div>
</div>
<div>
<div className="mt-4 flex">
<div className="w-1/12">
<div className="w-[40px] h-[40px] rounded-full bg-red-200">
<Avatar
size={40}
name={"بیاب اصل"}
variant="beam"
colors={["#9d9f88", "#83af96", "#b2de93"]}
/>
</div>
</div>
<div className="w-11/12 mr-4 mt-1">
<div className="flex justify-between">
<h4 className="text-sm font-bold">شهاب اصل</h4>
<small>
{" "}
<PersianNumber
number={moment().locale("fa").format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
</div>
<p className="mb-0 text-[13px] text-gray-500">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت
چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون
بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است
</p>
</div>
</div>
</div>
</div>
</div>
) : (
<div className="mt-5 mb-[20px]">
<InfiniteScroll
dataLength={notifData.length}
next={loadNotifications}
hasMore={hasMore}
loader={
<h4 className="mt-5 text-center text-sm">صبر کنید...</h4>
}
>
{notifData.map((e) => {
const notificationDate = moment(e.createdAt).format(
"YYYY-MM-DD"
);
const showDateHeader = notificationDate !== lastDate;
lastDate = notificationDate;
return (
<div key={e.id}>
{showDateHeader && (
<div className="mt-6">
<p className="mb-0 font-medium text-sm text-gray-400">
{notificationDate === moment().format("YYYY-MM-DD")
? "امروز"
: moment(notificationDate)
.locale("fa")
.format("YYYY/MM/DD")}
</p>
</div>
)}
<div className="mt-4 flex">
<div className="">
<div className="w-1 h-[40px] rounded-full bg-gray-100"></div>
</div>
<div className="w-full mr-2 mt-1">
<div className="flex justify-between">
<p className="mb-0 text-sm font-bold">
توک :
<small className="text-sm font-normal">
{" "}
{e.message}
</small>
<small className="bg-gray-100 rounded-full px-2">
{" "}
<PersianNumber
number={moment(e.createdAt)
.locale("fa")
.format("hh:mm")}
style={"!text-[12px] font-bold"}
/>
</small>
{!e.isRead && (
<small
className="mr-1 bg-gray-100 px-2 rounded-full font-normal"
onClick={() =>
markAsRead(e.id, notifData, setNotifData)
}
>
دیدم
</small>
)}
</p>
</div>
</div>
</div>
</div>
);
})}
</InfiniteScroll>
</div>
)}
</div>
</div>
</>
);
};
export default page;

View File

@ -95,6 +95,7 @@ const Shifts = (props) => {
}
useEffect(() => {
CTX.GetUnReadNotif();
CTX.GetShifPlans(0, 12);
setFilterShifPlaneSelect(1);
}, []);
@ -123,12 +124,6 @@ const Shifts = (props) => {
// iconEvent1={() => {
// CTX.setBottomSheetCreateShiftsOpen(true);
// }}
icon2={true}
iconName2="ARROW"
iconHref2="#"
iconEvent2={() => {
return router.back();
}}
/>
<div className="bg-white overflow-hidden p-5 rtl">

View File

@ -20,96 +20,54 @@ import NothingFound from "plugins/NothingFound/page";
const page = () => {
const CTX = useContext(AppContext);
const router = useRouter();
const activities = CTX.state.activitiesData;
const tasksData = CTX.state.tasksData;
const permissions = CTX.state.profile?.permissions;
const pageGetTasks = CTX.state.pageGetTasks;
const pageGetActivity = CTX.state.pageGetActivity;
const stopGetTasks = CTX.state.stopGetTasks;
const stopGetActivities = CTX.state.stopGetActivities;
const typeTask = CTX.state.typeTask;
const userStaffData = CTX.state.userStaffData;
useEffect(() => {
CTX.GetTasks(pageGetTasks);
CTX.GetActivity(
moment().locale("fa").startOf("day").unix() * 1000,
null,
pageGetActivity
);
}, []);
const handleInfiniteNextFetchTask = () => {
CTX.setPageGetTasks((e) => e + 1);
CTX.GetTasks(pageGetTasks + 1);
};
const [activeStaff, setActiveStaff] = useState(-1);
const [activeStaffId, setActiveStaffId] = useState(-1);
const [dateQueryFilterValue, setActiveStaffIdValue] = useState(1);
const handleInfiniteNextFetchActivity = () => {
CTX.setPageGetActivity((e) => e + 1);
CTX.GetActivity(
moment().locale("fa").startOf("day").unix() * 1000,
null,
pageGetActivity + 1
null,
pageGetActivity + 1,
dateQueryFilterValue,
activeStaffId
);
};
const habdleActiveStaff = (num, userId) => {
if (num == activeStaff) {
setActiveStaff(-1);
} else {
CTX.setStopGetActivities(false);
CTX.setPageGetActivity(0);
setActiveStaffId(userId);
setActiveStaff(num);
CTX.GetActivity(null, null, 0, dateQueryFilterValue, userId);
}
};
useEffect(() => {
CTX.GetUserStaff(dateQueryFilterValue);
CTX.GetUnReadNotif();
}, []);
return (
<div className="pb-20">
<AppHeader
title=" مدیریت فعالیت مجموعه"
sub=" مدیریت فعالیت ها"
icon1={!!HasPermission("ManageTasks", permissions) ? true : false}
iconName1="PLUS"
iconHref1="/tasks/add-task?new=true"
iconEvent1={() => {
CTX.setTaskData([]);
CTX.setIdEditTask("");
CTX.setGoToEditTask(false);
}}
icon2={true}
iconName2="ARROW"
iconHref2="#"
iconEvent2={() => {
GoBack();
}}
notif={true}
/>
<div className="bg-white overflow-hidden p-5 rtl">
{" "}
{!!HasPermission("ManageTasks", permissions) && (
<div className="flex bg-gray-100 rounded-full rtl ">
<div
className={` p-2 w-full rounded-3xl tr03 ${
CTX.state.typeTask == 0 ? "bg-secondary-950" : ""
} `}
onClick={() => CTX.setTypeTask(0)}
>
<p
className={`mb-0 text-center text-sm ${
CTX.state.typeTask == 0 ? "text-white" : " text-secondary-900"
}`}
>
تسک های روزانه
</p>
</div>
<div
className={` p-2 w-full rounded-3xl tr03 ${
CTX.state.typeTask == 1 ? "bg-secondary-950" : ""
} `}
onClick={() => CTX.setTypeTask(1)}
>
<p
className={`mb-0 text-center text-sm ${
CTX.state.typeTask == 1 ? "text-white" : " text-secondary-900"
}`}
>
اکتیویتی های روزانه
</p>
</div>
</div>
)}
<div className="flex justify-start">
<div className="flex justify-start mb-3">
<div
className="border-2 border-secondary-300 px-2 py-1 w-fit rounded-full flex mt-2"
onClick={() => CTX.setBottomFilterActivitiesOpen(true)}
@ -179,45 +137,78 @@ const page = () => {
</div>
</div>
</div>
{typeTask == 0 ? (
{userStaffData?.map((e, index) => (
<>
{tasksData.length != 0 ? (
<InfiniteScroll
dataLength={tasksData.length}
next={handleInfiniteNextFetchTask}
hasMore={!stopGetTasks}
<div
className={`px-1 rounded-2xl ${
activeStaff == index ? "pt-1" : "py-1"
}`}
key={index}
onClick={() => habdleActiveStaff(index, e?.id)}
>
<div
className={`flex justify-between bg-gray-50 p-2 ${
activeStaff == index
? " rounded-b-0 rounded-t-xl"
: "rounded-xl"
}`}
// onClick={() => handleListTaskActive(e?.id, index)}
>
<TasksCard
tasksData={tasksData}
permissions={permissions}
pageGetTasks={pageGetTasks}
/>
</InfiniteScroll>
) : (
<NothingFound />
<p className="mb-0 text-[13px] mt-1">
{e?.firstName + " " + e?.lastName}
</p>
<div className="bg-gray-100 w-[30px] h-[30px] rounded-xl">
<svg
width="11"
height="11"
viewBox="0 0 151 89"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={`opacity-80 mt-2 mx-auto tr03 ${
activeStaff == index ? "rotate-180" : ""
}`}
>
<path
d="M13.0444 13.1674L75.3606 75.8506L138.044 13.5345"
stroke="#424242"
stroke-opacity="0.81"
stroke-width="25"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</div>
</div>
{activeStaff == index && (
<div className=" mt-3">
{activities.length != 0 ? (
<InfiniteScroll
dataLength={activities.length}
next={handleInfiniteNextFetchActivity}
hasMore={!stopGetActivities}
>
{activities?.map((e) => (
<ActivityCard data={e} />
))}
</InfiniteScroll>
) : (
<NothingFound />
)}
</div>
)}
</>
) : (
<div className=" mt-3">
{activities.length != 0 ? (
<InfiniteScroll
dataLength={activities.length}
next={handleInfiniteNextFetchActivity}
hasMore={!stopGetActivities}
>
{activities?.map((e) => (
<ActivityCard data={e} />
))}
</InfiniteScroll>
) : (
<NothingFound />
)}
</div>
)}
))}
</div>
<BottomSheetCreateRoutine />
<BottomFilterActivities />
<BottomFilterActivities
setActiveStaffIdValue={setActiveStaffIdValue}
dateQueryFilterValue={dateQueryFilterValue}
activeStaffId={activeStaffId}
setActiveStaff={setActiveStaff}
/>
</div>
);
};

View File

@ -113,10 +113,10 @@ body {
}
}
[data-rsbs-backdrop] {
/* [data-rsbs-backdrop] {
z-index: 100000 !important;
background-color: rgba(0, 0, 0, 0.8) !important;
}
} */
[data-rsbs-overlay] {
z-index: 999 !important;
overflow: hidden;
@ -494,3 +494,9 @@ body {
opacity: 0;
}
}
.ellipsis {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}