From 089cabc6c5f92d907a5f1d6bf57e29b2b2e77de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=AD=D8=B3=DB=8C=D9=86=20=D9=85=D8=B9=D8=B5=D9=88=D9=85?= =?UTF-8?q?=DB=8C=20=D9=BE=D9=88=D8=B1?= Date: Thu, 19 Oct 2023 11:44:56 +0330 Subject: [PATCH] initioal --- .env | 16 + .env.production | 6 + .gitignore | 35 + .vscode/launch.json | 28 + Contexts/AppContext.js | 6 + README.md | 34 + ZDOCUMENT.md | 7 + components/AppHeader/page.jsx | 137 + components/EmployeesComponent/Roles/page.jsx | 75 + components/EmployeesComponent/Users/page.jsx | 81 + components/LoginComponents/LoginStep.jsx | 91 + components/LoginComponents/SignUp.jsx | 188 ++ components/LoginComponents/VerifyCodeStep.jsx | 57 + components/NavBar/NavBAr.jsx | 207 ++ components/TaskCard/page.jsx | 214 ++ components/UnderDevelopeTimer.jsx | 91 + jsconfig.json | 17 + next.config.js | 4 + package.json | 28 + .../BottomSheetCreateEmployees.jsx | 248 ++ plugins/BottomSheet/BottomSheetCreateRole.jsx | 165 ++ .../BottomSheet/BottomSheetCreateShifts.jsx | 124 + plugins/Buttonbriz/page.jsx | 83 + plugins/Chapar/index.js | 41 + plugins/CheckBoxBriz/page.jsx | 37 + plugins/Input/page.jsx | 91 + plugins/IranPhoneRegex/index.js | 7 + plugins/Loading/page.jsx | 28 + plugins/ParseJwt/page.jsx | 8 + plugins/PersianNumber/index.js | 19 + pnpm-lock.yaml | 2425 +++++++++++++++++ postcss.config.js | 6 + public/images/cloud1.png | Bin 0 -> 81138 bytes public/images/cloud2.png | Bin 0 -> 43345 bytes public/images/cloud3.png | Bin 0 -> 70691 bytes public/images/core.png | Bin 0 -> 153870 bytes public/images/loading.gif | Bin 0 -> 22634 bytes public/images/logo-t.png | Bin 0 -> 12252 bytes public/images/logo.png | Bin 0 -> 20031 bytes public/images/person.png | Bin 0 -> 66561 bytes public/images/task.png | Bin 0 -> 15861 bytes public/next.svg | 1 + public/vercel.svg | 1 + src/app/acount/page.jsx | 107 + src/app/add-buy/page.jsx | 57 + src/app/add-task/page.jsx | 169 ++ src/app/employees/page.jsx | 117 + src/app/favicon.ico | Bin 0 -> 25931 bytes src/app/home/page.jsx | 258 ++ src/app/layout.jsx | 398 +++ src/app/login/page.jsx | 63 + src/app/page.jsx | 82 + src/app/shifts/complete-shift/page.jsx | 44 + src/app/shifts/page.jsx | 254 ++ style/fontiran.css | 92 + style/fonts/woff/KalamehWeb-Black.woff | Bin 0 -> 63544 bytes style/fonts/woff/KalamehWeb-Bold.woff | Bin 0 -> 65920 bytes style/fonts/woff/KalamehWeb-ExtraBold.woff | Bin 0 -> 65416 bytes style/fonts/woff/KalamehWeb-ExtraLight.woff | Bin 0 -> 61716 bytes style/fonts/woff/KalamehWeb-Light.woff | Bin 0 -> 63540 bytes style/fonts/woff/KalamehWeb-Medium.woff | Bin 0 -> 65724 bytes style/fonts/woff/KalamehWeb-Regular.woff | Bin 0 -> 63376 bytes style/fonts/woff/KalamehWeb-SemiBold.woff | Bin 0 -> 64604 bytes style/fonts/woff/KalamehWeb-Thin.woff | Bin 0 -> 59664 bytes style/fonts/woff2/KalamehWeb-Black.woff2 | Bin 0 -> 49304 bytes style/fonts/woff2/KalamehWeb-Bold.woff2 | Bin 0 -> 51572 bytes style/fonts/woff2/KalamehWeb-ExtraBold.woff2 | Bin 0 -> 51244 bytes style/fonts/woff2/KalamehWeb-ExtraLight.woff2 | Bin 0 -> 48412 bytes style/fonts/woff2/KalamehWeb-Light.woff2 | Bin 0 -> 49640 bytes style/fonts/woff2/KalamehWeb-Medium.woff2 | Bin 0 -> 51584 bytes style/fonts/woff2/KalamehWeb-Regular.woff2 | Bin 0 -> 49584 bytes style/fonts/woff2/KalamehWeb-SemiBold.woff2 | Bin 0 -> 50632 bytes style/fonts/woff2/KalamehWeb-Thin.woff2 | Bin 0 -> 46160 bytes style/globals.css | 282 ++ style/style.css | 9 + tailwind.config.js | 74 + 76 files changed, 6612 insertions(+) create mode 100644 .env create mode 100644 .env.production create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 Contexts/AppContext.js create mode 100644 README.md create mode 100644 ZDOCUMENT.md create mode 100644 components/AppHeader/page.jsx create mode 100644 components/EmployeesComponent/Roles/page.jsx create mode 100644 components/EmployeesComponent/Users/page.jsx create mode 100644 components/LoginComponents/LoginStep.jsx create mode 100644 components/LoginComponents/SignUp.jsx create mode 100644 components/LoginComponents/VerifyCodeStep.jsx create mode 100644 components/NavBar/NavBAr.jsx create mode 100644 components/TaskCard/page.jsx create mode 100644 components/UnderDevelopeTimer.jsx create mode 100644 jsconfig.json create mode 100644 next.config.js create mode 100644 package.json create mode 100644 plugins/BottomSheet/BottomSheetCreateEmployees.jsx create mode 100644 plugins/BottomSheet/BottomSheetCreateRole.jsx create mode 100644 plugins/BottomSheet/BottomSheetCreateShifts.jsx create mode 100644 plugins/Buttonbriz/page.jsx create mode 100644 plugins/Chapar/index.js create mode 100644 plugins/CheckBoxBriz/page.jsx create mode 100644 plugins/Input/page.jsx create mode 100644 plugins/IranPhoneRegex/index.js create mode 100644 plugins/Loading/page.jsx create mode 100644 plugins/ParseJwt/page.jsx create mode 100644 plugins/PersianNumber/index.js create mode 100644 pnpm-lock.yaml create mode 100644 postcss.config.js create mode 100644 public/images/cloud1.png create mode 100644 public/images/cloud2.png create mode 100644 public/images/cloud3.png create mode 100644 public/images/core.png create mode 100644 public/images/loading.gif create mode 100644 public/images/logo-t.png create mode 100644 public/images/logo.png create mode 100644 public/images/person.png create mode 100644 public/images/task.png create mode 100644 public/next.svg create mode 100644 public/vercel.svg create mode 100644 src/app/acount/page.jsx create mode 100644 src/app/add-buy/page.jsx create mode 100644 src/app/add-task/page.jsx create mode 100644 src/app/employees/page.jsx create mode 100644 src/app/favicon.ico create mode 100644 src/app/home/page.jsx create mode 100644 src/app/layout.jsx create mode 100644 src/app/login/page.jsx create mode 100644 src/app/page.jsx create mode 100644 src/app/shifts/complete-shift/page.jsx create mode 100644 src/app/shifts/page.jsx create mode 100644 style/fontiran.css create mode 100644 style/fonts/woff/KalamehWeb-Black.woff create mode 100644 style/fonts/woff/KalamehWeb-Bold.woff create mode 100644 style/fonts/woff/KalamehWeb-ExtraBold.woff create mode 100644 style/fonts/woff/KalamehWeb-ExtraLight.woff create mode 100644 style/fonts/woff/KalamehWeb-Light.woff create mode 100644 style/fonts/woff/KalamehWeb-Medium.woff create mode 100644 style/fonts/woff/KalamehWeb-Regular.woff create mode 100644 style/fonts/woff/KalamehWeb-SemiBold.woff create mode 100644 style/fonts/woff/KalamehWeb-Thin.woff create mode 100644 style/fonts/woff2/KalamehWeb-Black.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-Bold.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-ExtraBold.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-ExtraLight.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-Light.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-Medium.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-Regular.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-SemiBold.woff2 create mode 100644 style/fonts/woff2/KalamehWeb-Thin.woff2 create mode 100644 style/globals.css create mode 100644 style/style.css create mode 100644 tailwind.config.js 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 ? ( +