commit 089cabc6c5f92d907a5f1d6bf57e29b2b2e77de4 Author: حسین معصومی پور Date: Thu Oct 19 11:44:56 2023 +0330 initioal diff --git a/.env b/.env new file mode 100644 index 0000000..92be40f --- /dev/null +++ b/.env @@ -0,0 +1,16 @@ +NODE_ENV="development" + +NEXT_PUBLIC_SERVER_URL=http://192.168.88.12:32769 +NEXT_PUBLIC_PUBLIC_URL=http://192.168.88.12:32769 +NEXT_PUBLIC_API_URL=http://192.168.88.12:32769/api +# 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 + + + +# NEXT_PUBLIC_SERVER_URL=https://api.macsonline.ir +# NEXT_PUBLIC_PUBLIC_URL=https://api.macsonline.ir +# NEXT_PUBLIC_API_URL=https://api.macsonline.ir/api/v1 +# NEXT_PUBLIC_API_URL_IMAGE=https://api.macsonline.ir/Files/ReportImages +# NEXT_PUBLIC_API_URL_BackUp=https://api.macsonline.ir/Files/BackUps \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..8393465 --- /dev/null +++ b/.env.production @@ -0,0 +1,6 @@ +NODE_ENV="production" +NEXT_PUBLIC_SERVER_URL=https://api.macsonline.ir +NEXT_PUBLIC_PUBLIC_URL=https://api.macsonline.ir +NEXT_PUBLIC_API_URL=https://api.macsonline.ir/api/v1 +NEXT_PUBLIC_API_URL_IMAGE=https://api.macsonline.ir/Files/ReportImages +NEXT_PUBLIC_API_URL_BackUp=https://api.macsonline.ir/Files/BackUps \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f322f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ee3bdd7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Next.js: debug server-side", + "type": "node-terminal", + "request": "launch", + "command": "npm run dev" + }, + { + "name": "Next.js: debug client-side", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000" + }, + { + "name": "Next.js: debug full stack", + "type": "node-terminal", + "request": "launch", + "command": "npm run dev", + "serverReadyAction": { + "pattern": "- Local:.+(https?://.+)", + "uriFormat": "%s", + "action": "debugWithChrome" + } + } + ] +} diff --git a/Contexts/AppContext.js b/Contexts/AppContext.js new file mode 100644 index 0000000..f535c73 --- /dev/null +++ b/Contexts/AppContext.js @@ -0,0 +1,6 @@ +import { createContext } from 'react' + +const AppContext = createContext({ + state: {}, +}) +export default AppContext diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5f733e --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/ZDOCUMENT.md b/ZDOCUMENT.md new file mode 100644 index 0000000..51a7c67 --- /dev/null +++ b/ZDOCUMENT.md @@ -0,0 +1,7 @@ +state conditionTask = { +0 : حالت عادی تسک +1 : تسک آماده تغیر است میچرخد و انتخاب میکند که تسک انجام شده است یا خیر +2 : تسک انجام نشده و اینپوت جزییات میاد +3 : تسک انجام شده و سبز میشود +4 : تسک انجام نشده است و قرمز میشود +} diff --git a/components/AppHeader/page.jsx b/components/AppHeader/page.jsx new file mode 100644 index 0000000..180160d --- /dev/null +++ b/components/AppHeader/page.jsx @@ -0,0 +1,137 @@ +import Link from "next/link"; +import React from "react"; + +const AppHeader = ({ + title, + sub, + icon1, + iconName1, + iconHref1, + iconEvent1, + icon2, + iconName2, + iconHref2, + iconEvent2, + userIcon, +}) => { + const icons = [ + { + iconName: "ACOUNT", + icon: ( + + + + ), + }, + { + iconName: "NINJA", + icon: ( + + + + ), + }, + + { + iconName: "ARROW", + icon: ( + + + + ), + }, + + { + iconName: "PLUS", + icon: ( + + + + ), + }, + ]; + + return ( +
+
+ {userIcon && ( +
+ )} +
+

{title}

+

{sub}

+
+
+ +
+ {icon1 ? ( + +
+ {icons.find((e) => e.iconName == iconName1)?.icon} +
+ + ) : ( + "" + )} + + {icon2 ? ( + +
+ {icons.find((e) => e.iconName == iconName2)?.icon} +
+ + ) : ( + "" + )} +
+
+ ); +}; + +export default AppHeader; diff --git a/components/EmployeesComponent/Roles/page.jsx b/components/EmployeesComponent/Roles/page.jsx new file mode 100644 index 0000000..fd34f82 --- /dev/null +++ b/components/EmployeesComponent/Roles/page.jsx @@ -0,0 +1,75 @@ +"use client"; + +import AppContext from "@ctx/AppContext"; +import React, { useContext } from "react"; + +const RolesEmployees = () => { + const CTX = useContext(AppContext); + const rolesData = CTX.state.rolesData; + + return ( + <> + {rolesData && rolesData.length > 0 ? ( +
+ {rolesData.map((e) => ( +
+
+

+ {e.persianName} +

+
+
+ + + + + + + + + + + + + + + +
+
+ ))} +
+ ) : ( +
+
+ چیزی یافت نشد +
+
+ )} + + ); +}; + +export default RolesEmployees; diff --git a/components/EmployeesComponent/Users/page.jsx b/components/EmployeesComponent/Users/page.jsx new file mode 100644 index 0000000..df1dc08 --- /dev/null +++ b/components/EmployeesComponent/Users/page.jsx @@ -0,0 +1,81 @@ +import React from "react"; + +const UsersEmployees = () => { + const data = []; + return ( + <> + {data.length > 0 ? ( + <> + {data.map((e) => ( +
+
+
+
+
+

+ نگین اسلامیپور{" "} +

+

صندوق دار

+
+
+
+ + + + + + + + + + + +
+
+ + + +
+
+
+
+
+ ))} + + ) : ( +
+
+ چیزی یافت نشد +
+
+ )} + + ); +}; + +export default UsersEmployees; diff --git a/components/LoginComponents/LoginStep.jsx b/components/LoginComponents/LoginStep.jsx new file mode 100644 index 0000000..434bb81 --- /dev/null +++ b/components/LoginComponents/LoginStep.jsx @@ -0,0 +1,91 @@ +"use client"; + +import AppContext from "@ctx/AppContext"; +import Buttonbriz from "plugins/Buttonbriz/page"; +import Input from "plugins/Input/page"; +import validateIranPhone from "plugins/IranPhoneRegex"; +import React, { useContext, useState } from "react"; +import { toast } from "react-toastify"; + +const LoginStep = (props) => { + const [roleCheckBox, setRoleCheckBox] = useState(false); + const [alertRolCheckBox, setAlertRolCheckBox] = useState(false); + const CTX = useContext(AppContext); + const phoneNumber = CTX.state.phoneNumber; + // console.log(alertRolCheckBox); + + const handleConfirmPhoneNumber = () => { + setAlertRolCheckBox(false); + + if (validateIranPhone(phoneNumber) && roleCheckBox) { + CTX.ConfirmPhoneNumber(phoneNumber); + } else { + if (!validateIranPhone(phoneNumber)) { + toast.error(" شماره تماس را درست وارد کنید ", { + position: "bottom-right", + closeOnClick: true, + }); + } else if (!roleCheckBox) { + setTimeout(() => { + setAlertRolCheckBox(true); + }, 100); + } + } + }; + + return ( +
+

+ {" "} + برای ورود یا ثبت نام به اپلیکیشن مدیریت وظایف رستوران باید شماره تلفن + همراه خود را وارد کنید +

+ +
+ CTX.setPhoneNumber(e.target.value)} + /> +
+ + handleConfirmPhoneNumber()} + /> + +
+
+ {/* */} + + setRoleCheckBox(e.target.checked)} + /> +
+

+ با تایید شماره تلفن همراه با همه شرایط حریم خصوص اپلیکیشن مدیریت توک + موافقت می کنم +

+
+
+ ); +}; + +export default LoginStep; diff --git a/components/LoginComponents/SignUp.jsx b/components/LoginComponents/SignUp.jsx new file mode 100644 index 0000000..63b3a49 --- /dev/null +++ b/components/LoginComponents/SignUp.jsx @@ -0,0 +1,188 @@ +"use client"; + +import AppContext from "@ctx/AppContext"; +import { useRouter } from "next/navigation"; +import Buttonbriz from "plugins/Buttonbriz/page"; +import Input from "plugins/Input/page"; +import PersianNumber from "plugins/PersianNumber"; +import React, { useContext, useEffect, useRef, useState } from "react"; +import { toast } from "react-toastify"; +import SimpleReactValidator from "simple-react-validator"; +import { useSearchParams } from "next/navigation"; + +const SignUp = (props) => { + const CTX = useContext(AppContext); + const router = useRouter(); + const query = useSearchParams(); + + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); + const [complexName, setComplexName] = useState(""); + const [supportPhoneNumber, setSupportPhoneNumber] = useState( + CTX.state.phoneNumber + ); + const [complexAddress, setComplexAddress] = useState(""); + const [, forceUpdate] = useState(); + + const validator = useRef( + new SimpleReactValidator({ + messages: { + required: "پر کردن این فیلد الزامی میباشد", + }, + element: (message) => ( + <> +
+ {message} +
+ + ), + }) + ); + + const body = { + firstName, + lastName, + complexName, + supportPhoneNumber, + complexAddress, + }; + + useEffect(() => { + if (!!query.get("phoneNumber")) { + setSupportPhoneNumber(query.get("phoneNumber")); + } + }, []); + + const handleSingnUp = () => { + if (validator.current.allValid()) { + CTX.SignUpLogin(body); + } else { + toast.error("پرکردن همه ی فیلد ها واجب است", { + position: "bottom-right", + autoClose: 2000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + + validator.current.showMessages(); + forceUpdate(1); + } + }; + + console.log(body); + + return ( +
+

+ برای ورود یا ثبت نام به اپلیکیشن مدیریت وظایف رستوران باید شماره تلفن + همراه خود را وارد کنید +

+ +
+ { + setFirstName(e.target.value); + validator.current.showMessageFor("firstName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "firstName", + firstName, + "required" + )} + /> +
+
+ { + setLastName(e.target.value); + validator.current.showMessageFor("lastName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "lastName", + lastName, + "required" + )} + /> +
+ +
+ { + setComplexName(e.target.value); + validator.current.showMessageFor("complexName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "complexName", + complexName, + "required" + )} + /> +
+
+ setSupportPhoneNumber(e.target.value)} + style="text-right" + readOnly={true} + /> +
+
+ { + setComplexAddress(e.target.value); + validator.current.showMessageFor("complexAddress"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "complexAddress", + complexAddress, + "required" + )} + /> +
+ + handleSingnUp()} + /> +
+ ); +}; + +export default SignUp; diff --git a/components/LoginComponents/VerifyCodeStep.jsx b/components/LoginComponents/VerifyCodeStep.jsx new file mode 100644 index 0000000..f6691be --- /dev/null +++ b/components/LoginComponents/VerifyCodeStep.jsx @@ -0,0 +1,57 @@ +"use client"; + +import AppContext from "@ctx/AppContext"; +import Buttonbriz from "plugins/Buttonbriz/page"; +import Input from "plugins/Input/page"; +import PersianNumber from "plugins/PersianNumber"; +import React, { useContext } from "react"; + +const VerifyCodeStep = () => { + const CTX = useContext(AppContext); + const phoneNumber = CTX.state.phoneNumber; + const verifyCode = CTX.state.verifyCode; + + const handleSendVerify = () => { + if (verifyCode.length <= 5) { + toast.error(" کد را صحیح وارد کنید ", { + position: "bottom-right", + closeOnClick: true, + }); + } else { + CTX.LoginWhitVerifyCode(); + } + }; + + return ( +
+

+ {" "} + پیامک حاوی کد تایید برای شماره + + + + ارسال شده است +

+ +
+ CTX.setVerifyCode(e.target.value)} + /> +
+ + handleSendVerify()} + /> +
+ ); +}; + +export default VerifyCodeStep; diff --git a/components/NavBar/NavBAr.jsx b/components/NavBar/NavBAr.jsx new file mode 100644 index 0000000..369d138 --- /dev/null +++ b/components/NavBar/NavBAr.jsx @@ -0,0 +1,207 @@ +"use client"; + +import Link from "next/link"; +import React, { useContext } from "react"; +import { usePathname } from "next/navigation"; +import Image from "next/image"; +import logo from "@img/logo.png"; +import AppContext from "@ctx/AppContext"; + +const NavBAr = (props) => { + const usePath = usePathname(); + const CTX = useContext(AppContext); + + console.log("vvvvv", CTX.state.BigPlusOpen); + + const openBigPlus = () => { + setTimeout(() => { + CTX.setBigPlusRotateIcon(true); + }, 500); + CTX.setBigPlusOpen(true); + }; + + return ( +
+ {/*
+ +
*/} +
+ + <> + {usePath.includes("/home") ? ( +
+ + + +
+ ) : ( +
+ + + +
+ )} + + + + + <> + {usePath.includes("/shifts") ? ( +
+ + + + +
+ ) : ( +
+ + + + +
+ )} + + +
{ + openBigPlus(); + }} + > +
+ + + +
+
+ + + <> + {usePath.includes("/employees") ? ( +
+ + + +
+ ) : ( +
+ + + +
+ )} + + + + + <> + {usePath.includes("/dashboard") ? ( +
+
+ +
+
+ ) : ( +
+
+ +
+
+ )} + + +
+
+ ); +}; + +export default NavBAr; diff --git a/components/TaskCard/page.jsx b/components/TaskCard/page.jsx new file mode 100644 index 0000000..ed9242a --- /dev/null +++ b/components/TaskCard/page.jsx @@ -0,0 +1,214 @@ +"use client"; +import Buttonbriz from "plugins/Buttonbriz/page"; +import Input from "plugins/Input/page"; +import React, { useState } from "react"; + +const TaskCard = () => { + const [conditionTask, setConditionTask] = useState(0); + + const handleConditionTaskCircle = () => { + if (conditionTask == 3 || conditionTask == 4) { + return; + } else { + setConditionTask(1); + } + }; + + return ( +
+
+
handleConditionTaskCircle()} + > + {conditionTask == 2 || conditionTask == 4 ? ( + + + + ) : conditionTask == 3 ? ( + + + + + ) : ( + "" + )} +
+
+

+ پاک کردن شیشه های روبرویی رستوران +

+

+ لطفا دو شیشه روبرو رستوران را با دقت تمیز کنید و جارو بکشید +

+
+
+
+
+ اهمیت بالا{" "} +
+
+ شیفت صبح +
+
+ +
+
setConditionTask(0)} + > + + + +
+
+ {" "} +
setConditionTask(3)} + > + + + + +
+
setConditionTask(2)} + > + + + +
+
+
+ +
+
+ + + setConditionTask(4)} + /> +
+
+
+ ); +}; + +export default TaskCard; diff --git a/components/UnderDevelopeTimer.jsx b/components/UnderDevelopeTimer.jsx new file mode 100644 index 0000000..4ca5c3a --- /dev/null +++ b/components/UnderDevelopeTimer.jsx @@ -0,0 +1,91 @@ +"use client"; +import { useEffect, useState } from "react"; +import PersianNumber from "../plugins/PersianNumber"; +import Link from "next/link"; + +const UnderDevelopeTimer = () => { + const targetTimestamp = 1698635992 * 1000; // Convert to milliseconds + + const [timeRemaining, setTimeRemaining] = useState({ + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + }); + + useEffect(() => { + const interval = setInterval(() => { + const now = new Date(); + const timeDifference = targetTimestamp - now.getTime(); + + if (timeDifference > 0) { + const days = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); + const hours = Math.floor( + (timeDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) + ); + const minutes = Math.floor( + (timeDifference % (1000 * 60 * 60)) / (1000 * 60) + ); + const seconds = Math.floor((timeDifference % (1000 * 60)) / 1000); + const milliseconds = timeDifference % 1000; + + setTimeRemaining({ + days, + hours, + minutes, + seconds, + milliseconds, + }); + } else { + clearInterval(interval); + } + }, 1000); + + return () => clearInterval(interval); + }, []); + + return ( +
+
+
+

+ +

+
+

روز

+
+ +
+
+

+ +

+
+

ساعت

+
+ +
+
+

+ +

+
+

دقیقه

+
+ +
+ +
+

+ +

+
+ +

ثانیه

+
+
+ ); +}; + +export default UnderDevelopeTimer; diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..98728ac --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "module": "commonjs", + "target": "es2020", + "paths": { + "@comp/*": ["components/*"], + "@styles/*": ["styles/*"], + "@assets/*": ["assets/*"], + "@ctx/*": ["Contexts/*"], + "@img/*": ["public/images/*"], + "@layout/*": ["layout/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.js", "**/*.jsx"], + "exclude": ["node_modules"] +} diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..767719f --- /dev/null +++ b/next.config.js @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/package.json b/package.json new file mode 100644 index 0000000..c32df44 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "brizco", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "autoprefixer": "10.4.15", + "axios": "^1.5.1", + "framer-motion": "^10.16.1", + "next": "13.4.19", + "postcss": "8.4.28", + "react": "18.2.0", + "react-datepicker2": "^3.3.13", + "react-dom": "18.2.0", + "react-persian-datepicker": "^3.0.2", + "react-spring-bottom-sheet": "^3.4.1", + "react-toastify": "^9.1.3", + "simple-react-validator": "^1.6.2", + "swiper": "^10.2.0", + "tailwindcss": "3.3.3", + "zaman": "^2.0.8" + } +} diff --git a/plugins/BottomSheet/BottomSheetCreateEmployees.jsx b/plugins/BottomSheet/BottomSheetCreateEmployees.jsx new file mode 100644 index 0000000..989ce49 --- /dev/null +++ b/plugins/BottomSheet/BottomSheetCreateEmployees.jsx @@ -0,0 +1,248 @@ +"use client"; + +import React, { useContext, 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"; + +const BottomSheetCreateEmployees = (props) => { + const CTX = useContext(AppContext); + const [firstName, setFirstName] = useState(""); + const [lastName, setLastName] = useState(""); + const [phoneNumber, setPhoneNumber] = useState(""); + const [nationalId, setNationalId] = useState(""); + const [gender, setGender] = useState(0); + const [roleSelectData, setRoleSelectData] = useState(""); + const [, forceUpdate] = useState(); + + const validator = useRef( + new SimpleReactValidator({ + messages: { + required: "پر کردن این فیلد الزامی میباشد", + }, + element: (message) => ( + <> +
+ {message} +
+ + ), + }) + ); + const rolesChoose = CTX.state.rolesChoose; + const rolesData = CTX.state.rolesData; + + const body = { + phoneNumber, + firstName, + lastName, + // birthDate, + gender, + nationalId, + roleIds: rolesChoose, + }; + + const handleCreateUser = () => { + if (validator.current.allValid()) { + CTX.CreateUser(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 deleteRole = (id) => { + CTX.setRolesChoose(rolesChoose.filter((el) => el !== id)); + }; + + return ( + { + if (e.type == "OPEN") { + CTX.GetRoles(); + } + }} + open={CTX.state.BottomSheetCreateEmployeesOpen} + onDismiss={() => CTX.setBottomSheetCreateEmployeesOpen(false)} + > +
+

افزودن کاربر جدید

+
+ +
+
+ { + setFirstName(e.target.value); + validator.current.showMessageFor("firstName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "firstName", + firstName, + "required" + )} + /> +
+ +
+ { + setLastName(e.target.value); + validator.current.showMessageFor("lastName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "lastName", + lastName, + "required" + )} + /> +
+ +
+ { + setGender(e.target.value); + validator.current.showMessageFor("gender"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "gender", + gender, + "required" + )} + select={true} + selectData={[ + { key: "مرد", value: "0" }, + { key: "زن", value: "1" }, + ]} + /> +
+ +
+ { + setPhoneNumber(e.target.value); + validator.current.showMessageFor("phoneNumber"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "phoneNumber", + phoneNumber, + "required" + )} + /> +
+ +
+ { + setNationalId(e.target.value); + }} + style="text-right" + /> +
+ +
+ { + setRoleSelectData(e.target.value); + console.log("s11515", e.target.value); + + if (!!rolesChoose.find((b) => b == e.target.value)) { + toast.error("نقش تکراری است", { + position: "bottom-right", + closeOnClick: true, + }); + } else { + CTX.setRolesChoose((current) => [...current, e.target.value]); + } + }} + style="text-right" + validatorData={validator.current.message( + "phoneNumber", + phoneNumber, + "required" + )} + select={true} + selectData={CTX.state.rolesData} + /> +
+ +
+ {rolesChoose && + rolesChoose.map((e) => ( +
+
deleteRole(e)} + >
+ +
+

+ {rolesData?.find((b) => b.id == e).persianName} +

+
+
+ ))} +
+ handleCreateUser()} + /> +
+
+ ); +}; + +export default BottomSheetCreateEmployees; diff --git a/plugins/BottomSheet/BottomSheetCreateRole.jsx b/plugins/BottomSheet/BottomSheetCreateRole.jsx new file mode 100644 index 0000000..56918ea --- /dev/null +++ b/plugins/BottomSheet/BottomSheetCreateRole.jsx @@ -0,0 +1,165 @@ +"use client"; + +import React, { useContext, 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 CheckBoxBriz from "plugins/CheckBoxBriz/page"; +import Buttonbriz from "plugins/Buttonbriz/page"; +import { toast } from "react-toastify"; + +const BottomSheetCreateRole = (props) => { + const CTX = useContext(AppContext); + const [persianName, setPersianName] = useState(""); + const [englishName, setEnglishName] = useState(""); + const [description, setDescription] = useState(""); + const [, forceUpdate] = useState(); + + const permissionsData = CTX.state.permissions; + const permissionsChoose = CTX.state.permissionsChoose; + + const validator = useRef( + new SimpleReactValidator({ + messages: { + required: "پر کردن این فیلد الزامی میباشد", + }, + element: (message) => ( + <> +
+ {message} +
+ + ), + }) + ); + + const body = { + persianName, + englishName, + description, + permissions: permissionsChoose, + }; + + const handleCreateRole = () => { + if (validator.current.allValid()) { + CTX.CreateRole(body); + } else { + toast.error("پرکردن همه ی فیلد ها واجب است", { + position: "bottom-right", + autoClose: 2000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + + validator.current.showMessages(); + forceUpdate(1); + } + }; + + return ( + { + if (e.type == "OPEN") { + CTX.GetPermissions(); + } + }} + open={CTX.state.BottomSheetCreateRoleOpen} + onDismiss={() => CTX.setBottomSheetCreateRoleOpen(false)} + > +
+

افزودن نقش جدید

+
+ +
+
+ { + setPersianName(e.target.value); + validator.current.showMessageFor("persianName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "persianName", + persianName, + "required" + )} + /> +
+ +
+ { + setEnglishName(e.target.value); + validator.current.showMessageFor("englishName"); + }} + style="text-right" + validator={true} + validatorData={validator.current.message( + "englishName", + englishName, + "required" + )} + /> +
+ +
+ { + setDescription(e.target.value); + validator.current.showMessageFor("description"); + }} + textarea={true} + style="text-right" + /> +
+ +
+
+

+ دسترسی های مورد نظر{" "} +

+
+ + {permissionsData && + permissionsData.map((e) => ( + setRoleCheckBox(e.target.checked)} + /> + ))} +
+ + handleCreateRole()} + /> +
+
+ ); +}; + +export default BottomSheetCreateRole; diff --git a/plugins/BottomSheet/BottomSheetCreateShifts.jsx b/plugins/BottomSheet/BottomSheetCreateShifts.jsx new file mode 100644 index 0000000..d001059 --- /dev/null +++ b/plugins/BottomSheet/BottomSheetCreateShifts.jsx @@ -0,0 +1,124 @@ +"use client"; + +import React, { useContext } from "react"; +import { BottomSheet } from "react-spring-bottom-sheet"; +import Input from "plugins/Input/page"; +import AppContext from "@ctx/AppContext"; + +const BottomSheetCreateShifts = (props) => { + const CTX = useContext(AppContext); + + return ( + CTX.setBottomSheetCreateShiftsOpen(false)} + > +
+

+ افزودن شیفت کاری جدید +

+
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+
+
+
+ + + +
+

شنبه

+
+
+
+
+ +
+ +
+ +
+
+ +
+ + {/*
+

بستن

+
*/} +
+
+
+ ); +}; + +export default BottomSheetCreateShifts; diff --git a/plugins/Buttonbriz/page.jsx b/plugins/Buttonbriz/page.jsx new file mode 100644 index 0000000..cc1c453 --- /dev/null +++ b/plugins/Buttonbriz/page.jsx @@ -0,0 +1,83 @@ +import React from "react"; + +const Buttonbriz = ({ title, color, buttonEvent, icon }) => { + const icons = [ + { + iconName: "PHONE", + icon: ( + + + + ), + }, + { + iconName: "CHECK", + icon: ( + + + + ), + }, + ]; + + return ( +
+
+ +
+ + {/*
+

بستن

+
*/} +
+ ); +}; + +export default Buttonbriz; diff --git a/plugins/Chapar/index.js b/plugins/Chapar/index.js new file mode 100644 index 0000000..242fc7e --- /dev/null +++ b/plugins/Chapar/index.js @@ -0,0 +1,41 @@ +import axios from "axios"; + +export const getToken = () => { + return "Bearer " + localStorage.token; +}; + +const Chapar = axios.create({ + baseURL: process.env.NEXT_PUBLIC_API_URL, + timeout: 10000, + headers: { + common: { + "Content-type": "application/json", + "Access-Control-Allow-Origin": "*", + ...(typeof window !== "undefined" && + localStorage.token && { + Authorization: getToken(), + }), + }, + }, +}); + +Chapar.interceptors.response.use( + function (response) { + // Any status code that lie within the range of 2xx cause this function to trigger + // Do something with response data + + return response.data; + }, + function (error) { + // Any status codes that falls outside the range of 2xx cause this function to trigger + // Do something with response error + + // if (error.response.status === 401) { + // localStorage.removeItem("token"); + // window.location.href = "/"; + // } + return Promise.reject({ error, status: error?.response?.status }); + } +); + +export default Chapar; diff --git a/plugins/CheckBoxBriz/page.jsx b/plugins/CheckBoxBriz/page.jsx new file mode 100644 index 0000000..258569c --- /dev/null +++ b/plugins/CheckBoxBriz/page.jsx @@ -0,0 +1,37 @@ +"use client"; + +import AppContext from "@ctx/AppContext"; +import React, { useContext, useState } from "react"; + +const page = ({ title, detail, value }) => { + const CTX = useContext(AppContext); + + const [isChecked, setIsChecked] = useState(false); + + const hanslePermissionsChoose = (e) => { + setIsChecked(e.target.checked); + CTX.setPermissionsChoose((current) => [...current, value]); + }; + return ( +
+
+ hanslePermissionsChoose(e)} + /> +
+ +
+

{title}

+

{detail}

+
+
+ ); +}; + +export default page; diff --git a/plugins/Input/page.jsx b/plugins/Input/page.jsx new file mode 100644 index 0000000..b96efd3 --- /dev/null +++ b/plugins/Input/page.jsx @@ -0,0 +1,91 @@ +import React from "react"; + +const Input = ({ + id, + lable, + name, + type, + textarea, + mt, + disabled, + theme, + inputEvent, + style, + value, + readOnly, + validator, + validatorData, + select, + selectData, +}) => { + return ( +
+ {textarea ? ( +