diff --git a/client/.gitignore b/client/.gitignore index d3614a66..20d447a7 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -14,6 +14,7 @@ dist-ssr .env *.css.map +*.css # Editor directories and files .vscode/* diff --git a/client/package-lock.json b/client/package-lock.json index e61eba51..5f74488a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -8,17 +8,15 @@ "name": "client", "version": "0.0.0", "dependencies": { - "@reduxjs/toolkit": "^2.0.1", - "@heroicons/react": "^2.0.18", - + "@reduxjs/toolkit": "^2.0.1", "axios": "^1.6.2", "normalize.css": "^8.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-redux": "^9.0.2", "react-router-dom": "^6.21.0", + "react-toastify": "^9.1.3", "sass": "^1.69.5" }, "devDependencies": { @@ -1288,6 +1286,14 @@ "node": ">= 6" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3154,6 +3160,18 @@ "react-dom": ">=16.8" } }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", diff --git a/client/package.json b/client/package.json index c5c6a20a..78f1aeeb 100644 --- a/client/package.json +++ b/client/package.json @@ -4,21 +4,21 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite --host", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { - "@reduxjs/toolkit": "^2.0.1", "@heroicons/react": "^2.0.18", + "@reduxjs/toolkit": "^2.0.1", "axios": "^1.6.2", "normalize.css": "^8.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-redux": "^9.0.2", "react-router-dom": "^6.21.0", + "react-toastify": "^9.1.3", "sass": "^1.69.5" }, "devDependencies": { diff --git a/client/src/App.jsx b/client/src/App.jsx index 042e44ef..470df060 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -4,11 +4,21 @@ import "./theme.scss"; import "./assets/styles/global/global.scss"; // Import Routes import Routes from "./routes"; +// Import Store +import store from "./redux/store"; +// Import Provider +import { Provider } from "react-redux"; +// Import Toastify +import { ToastContainer } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; function App() { return ( <> - + + + + ); } diff --git a/client/src/assets/styles/_vars.scss b/client/src/assets/styles/_vars.scss index acdc3eb9..7186fd13 100644 --- a/client/src/assets/styles/_vars.scss +++ b/client/src/assets/styles/_vars.scss @@ -1,5 +1,11 @@ $--grey-800: #1F2A37; +$--grey-700: #374151; +$--grey-600: #4b5563; $--grey-300: #D1D5DB; +$--Teal-900: #014451; $--Teal-500: #0694A2; $--Red-700: #C81E1E; -$--Yellow-500: #C27803; \ No newline at end of file +$--green-700: #046C4E; +$--Yellow-500: #C27803; +$--Primary-900: #0e0218; +$--text-color: #e2efee; \ No newline at end of file diff --git a/client/src/assets/styles/components/Alert.scss b/client/src/assets/styles/components/Alert.scss index 156bc8a7..62c53daf 100644 --- a/client/src/assets/styles/components/Alert.scss +++ b/client/src/assets/styles/components/Alert.scss @@ -12,7 +12,7 @@ padding: 15px 15px; justify-content: center; - align-items: end; + align-items: end; gap: 10px; } diff --git a/client/src/assets/styles/components/Button.scss b/client/src/assets/styles/components/Button.scss index b21570cb..9af0126b 100644 --- a/client/src/assets/styles/components/Button.scss +++ b/client/src/assets/styles/components/Button.scss @@ -3,6 +3,11 @@ border: none; padding: 12px 20px; border-radius: 6px; + cursor: pointer; + color: inherit; + font-size: 19px; + font-weight: 500; + text-align: center; a { color: inherit; @@ -20,5 +25,16 @@ color: var(--grey-50); } + &--medium { + a { + font-size: 1rem; + } + } + + &--success { + background-color: var(--green-400); + color: var(--grey-900); + } + // TODO: Add more button styles and maybe sizes } diff --git a/client/src/assets/styles/components/FancyBlobs.scss b/client/src/assets/styles/components/FancyBlobs.scss index 7d2054bc..5ebf7ded 100644 --- a/client/src/assets/styles/components/FancyBlobs.scss +++ b/client/src/assets/styles/components/FancyBlobs.scss @@ -6,6 +6,8 @@ top: 20vh; left: 0; z-index: -1; + --animation-duration: 8s; + --max-distance: 300px; > * { position: absolute; @@ -18,7 +20,7 @@ fill: linear-gradient(82deg, #8900c9 38.7%, #fcf 76.51%); filter: blur(150px); top: -167px; - animation: BlobMove1 10s ease-in-out infinite forwards; + animation: BlobMove1 var(--animation-duration) ease-in-out infinite forwards; } .Blob-2 { @@ -26,7 +28,7 @@ filter: blur(125px); top: 66px; left: -71px; - animation: BlobMove2 10s ease-in-out infinite forwards; + animation: BlobMove2 var(--animation-duration) ease-in-out infinite forwards; } .Blob-3 { @@ -37,7 +39,7 @@ filter: blur(150px); top: 460px; left: 0; - animation: BlobMove3 10s ease-in-out infinite forwards; + animation: BlobMove3 var(--animation-duration) ease-in-out infinite forwards; } .Blob-4 { @@ -48,7 +50,7 @@ filter: blur(150px); top: 503px; left: 150px; - animation: BlobMove4 10s ease-in-out infinite forwards; + animation: BlobMove4 var(--animation-duration) ease-in-out infinite forwards; } } @@ -105,7 +107,7 @@ transform: translate(0, 50px); } 75% { - transform: translate(-100px, 0); + transform: translate(-var(--max-distance), 0); } 100% { transform: translate(0, 0); diff --git a/client/src/assets/styles/components/Footer.scss b/client/src/assets/styles/components/Footer.scss index 824625cf..37f62e3b 100644 --- a/client/src/assets/styles/components/Footer.scss +++ b/client/src/assets/styles/components/Footer.scss @@ -1,8 +1,14 @@ .Footer { padding: 2rem 20px; + margin-bottom: 0; text-align: center; position: relative; box-sizing: content-box; + margin-bottom: 50px; + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; &::before { content: ""; @@ -23,6 +29,7 @@ } a { + border-radius: 5px; padding: 5px; background-color: var(--primary-50); color: var(--grey-900); diff --git a/client/src/assets/styles/components/Inputs.scss b/client/src/assets/styles/components/Inputs.scss new file mode 100644 index 00000000..448be953 --- /dev/null +++ b/client/src/assets/styles/components/Inputs.scss @@ -0,0 +1,34 @@ +.input { + display: flex; + flex-direction: column; + gap: 0.5rem; + color: var(--grey-100); + font-size: 1rem; + direction: rtl; + width: 100%; + + .radio-buttons { + display: flex; + flex-direction: row; + gap: 0.5rem; + width: 100%; + margin: 0.5rem 0; + } + + input[type="text"], + input[type="password"], + input[type="email"], + input[type="number"], + input[type="tel"], + input[type="date"], + input[type="time"] { + width: 100%; + outline: none; + border-radius: 4px; + border: 1px solid var(--grey-600, #4b5563); + background: var(--grey-700, #374151); + padding: 0 4px; + line-height: 1rem; + color: var(--grey-100); + } +} diff --git a/client/src/assets/styles/components/infoBox.scss b/client/src/assets/styles/components/infoBox.scss new file mode 100644 index 00000000..03986681 --- /dev/null +++ b/client/src/assets/styles/components/infoBox.scss @@ -0,0 +1,35 @@ +.info-box { + height: 97px; + flex-shrink: 0; + border-radius: 12px; + + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: end; + + padding-right: 2rem; + + &.narrow { + width: 40%; + } + + &.wide { + width: 90%; + } + + &.dark { + + background: var(--simnle-grid, linear-gradient(113deg, #1F2A37 6.36%, rgba(31, 42, 55, 0.00) 108.22%)); + } + + &.purple { + background: var(--pur-grid, linear-gradient(115deg, #B773E9 2.95%, #5B1092 95.69%)); + + } + + &.colorfull { + background: linear-gradient(96deg, #650DA6 -11.62%, #650DA6 -11.61%, #DF1846 119.72%); + box-shadow: 4px 5px 103.7px 0px var(--Primary-800, #2B0547); + } +} \ No newline at end of file diff --git a/client/src/assets/styles/components/logIn.css b/client/src/assets/styles/components/logIn.css deleted file mode 100644 index 133f3432..00000000 --- a/client/src/assets/styles/components/logIn.css +++ /dev/null @@ -1,64 +0,0 @@ -.hero { - display: flex; - width: 22.5rem; - height: 40rem; - flex-direction: column; - align-items: center; - justify-content: center; - margin: auto; - padding: 1.75rem 0.25rem; - gap: 1.1875rem; -} - -.card { - background-color: #1f2a37; - border-radius: 1.875rem; - display: flex; - width: 16.9375rem; - padding: 1.0625rem 0rem; - margin-top: 3rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 0.875rem; -} -.card .input-field { - display: flex; - width: 14.16319rem; - padding: 0.125rem 0.75rem; - justify-content: flex-end; - align-items: center; - align-content: center; - gap: 0rem 9.25rem; - flex-wrap: wrap; -} -.card .input-field input { - background: #374151; - margin-block: 0.3rem; - border: 1px solid #4b5563; - border-radius: 0.25rem; - width: 12.66319rem; - height: 1.75rem; - flex-shrink: 0; -} - -.no-account { - color: #0694A2; - font-family: "Noto Kufi Arabic"; - margin-bottom: 1rem; -} - -button { - color: #e2efee; - font-family: "Noto Kufi Arabic"; - background: #046C4E; - border: 0px solid; - border-radius: 0.3125rem; - display: flex; - width: 7.25rem; - height: 1.875rem; - padding: 0.8125rem 0.625rem; - justify-content: center; - align-items: center; - gap: 1.25rem; -}/*# sourceMappingURL=logIn.css.map */ \ No newline at end of file diff --git a/client/src/assets/styles/components/logIn.scss b/client/src/assets/styles/components/logIn.scss deleted file mode 100644 index 7b4053b1..00000000 --- a/client/src/assets/styles/components/logIn.scss +++ /dev/null @@ -1,74 +0,0 @@ -$Teal-900: #014451; -$Teal-500: #0694A2; -$grey-800: #1f2a37; -$grey-700: #374151; -$grey-600: #4b5563; -$green-700: #046C4E; -$Primary-900: #0e0218; -$text-color: #e2efee; -$font: 'Noto Kufi Arabic'; - -.hero { - display: flex; - width: 22.5rem; - height: 40rem; - flex-direction: column; - align-items: center; - justify-content: center; - margin: auto; - padding: 1.75rem 0.25rem; - gap: 1.1875rem; -} - -.card { - background-color: $grey-800; - border-radius: 1.875rem; - display: flex; - width: 16.9375rem; - padding: 1.0625rem 0rem; - margin-top: 3rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 0.875rem; - .input-field { - display: flex; - width: 14.16319rem; - padding: 0.125rem 0.75rem; - justify-content: flex-end; - align-items: center; - align-content: center; - gap: 0rem 9.25rem; - flex-wrap: wrap; - input { - background: $grey-700; - margin-block: 0.3rem; - border: 1px solid $grey-600; - border-radius: 0.25rem; - width: 12.66319rem; - height: 1.75rem; - flex-shrink: 0; - } - } -} - -.no-account { - color: $Teal-500; - font-family: $font; - margin-bottom: 1rem; -} - -button { - color: $text-color; - font-family: $font; - background: $green-700; - border: 0px solid; - border-radius: 0.3125rem; - display: flex; - width: 7.25rem; - height: 1.875rem; - padding: 0.8125rem 0.625rem; - justify-content: center; - align-items: center; - gap: 1.25rem; -} diff --git a/client/src/assets/styles/components/signUp.css b/client/src/assets/styles/components/signUp.css deleted file mode 100644 index e40032e3..00000000 --- a/client/src/assets/styles/components/signUp.css +++ /dev/null @@ -1,87 +0,0 @@ -.hero { - display: flex; - width: 22.5rem; - height: 93.375rem; - flex-direction: column; - align-items: center; - margin: auto; - padding: 1.75rem 0.25rem; - gap: 1.1875rem; -} - -.container { - background: #014451; - border-radius: 1.25rem; - display: flex; - width: 19rem; - padding: 1.5rem 0.4375rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 1.0625rem; -} - -.card { - background-color: #1f2a37; - border-radius: 1.875rem; - display: flex; - width: 16.9375rem; - padding: 1.0625rem 0rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 0.875rem; -} -.card .input-field { - display: flex; - width: 14.16319rem; - padding: 0.125rem 0.75rem; - justify-content: flex-end; - align-items: center; - align-content: center; - gap: 0rem 9.25rem; - flex-wrap: wrap; -} -.card .input-field input { - background: #374151; - margin-block: 0.3rem; - border: 1px solid #4b5563; - border-radius: 0.25rem; - width: 12.66319rem; - height: 1.75rem; - flex-shrink: 0; -} -.card .radio-field { - display: flex; - width: 14.16319rem; - padding: 0.5625rem 0.75rem; - flex-direction: column; - justify-content: flex-end; - align-items: flex-end; - flex-wrap: wrap; - gap: 0.0625rem; -} -.card .radio-field .radio-buttons { - display: flex; - padding: 0.3125rem 0.5rem; - margin: auto; - gap: 3.1875rem; -} -.card .radio-field .radio-buttons small input { - margin: 0.5rem; -} - -button { - color: #e2efee; - font-family: "Noto Kufi Arabic"; - background: #0e0218; - border: 0px solid; - border-radius: 0.3125rem; - display: flex; - width: 12.5rem; - height: 3.125rem; - padding: 0.8125rem 0.6875rem 0.8125rem 0.625rem; - justify-content: center; - align-items: center; - gap: 2.5rem; -}/*# sourceMappingURL=signUp.css.map */ \ No newline at end of file diff --git a/client/src/assets/styles/components/signUp.scss b/client/src/assets/styles/components/signUp.scss deleted file mode 100644 index 9705ee79..00000000 --- a/client/src/assets/styles/components/signUp.scss +++ /dev/null @@ -1,97 +0,0 @@ -$Teal-900: #014451; -$grey-800: #1f2a37; -$grey-700: #374151; -$grey-600: #4b5563; -$Primary-900: #0e0218; -$text-color: #e2efee; -$font: 'Noto Kufi Arabic'; - -.hero { - display: flex; - width: 22.5rem; - height: 93.375rem; - flex-direction: column; - align-items: center; - margin: auto; - padding: 1.75rem 0.25rem; - gap: 1.1875rem; -} - -.container { - background: $Teal-900; - border-radius: 1.25rem; - display: flex; - width: 19rem; - padding: 1.5rem 0.4375rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 1.0625rem; -} - -.card { - background-color: $grey-800; - border-radius: 1.875rem; - display: flex; - width: 16.9375rem; - padding: 1.0625rem 0rem; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 0.875rem; - .input-field { - display: flex; - width: 14.16319rem; - padding: 0.125rem 0.75rem; - justify-content: flex-end; - align-items: center; - align-content: center; - gap: 0rem 9.25rem; - flex-wrap: wrap; - input { - background: $grey-700; - margin-block: 0.3rem; - border: 1px solid $grey-600; - border-radius: 0.25rem; - width: 12.66319rem; - height: 1.75rem; - flex-shrink: 0; - } - } - - .radio-field { - display: flex; - width: 14.16319rem; - padding: 0.5625rem 0.75rem; - flex-direction: column; - justify-content: flex-end; - align-items: flex-end; - flex-wrap: wrap; - gap: 0.0625rem; - .radio-buttons { - display: flex; - padding: 0.3125rem 0.5rem; - margin: auto; - gap: 3.1875rem; - small input { - margin: 0.5rem; - } - } - } -} - - -button { - color: $text-color; - font-family: $font; - background: $Primary-900; - border: 0px solid; - border-radius: 0.3125rem; - display: flex; - width: 12.5rem; - height: 3.125rem; - padding: 0.8125rem 0.6875rem 0.8125rem 0.625rem; - justify-content: center; - align-items: center; - gap: 2.5rem; -} diff --git a/client/src/assets/styles/global/global.scss b/client/src/assets/styles/global/global.scss index 7fee132f..2ddba2b7 100644 --- a/client/src/assets/styles/global/global.scss +++ b/client/src/assets/styles/global/global.scss @@ -10,11 +10,13 @@ body { font-family: var(--font-primary); + font-size: var(--font-base-size); background-color: var(--bg); - color: var(--grey-50); + color: var(--text-color); + overflow-x: hidden; } a { - color: var(--grey-50); + color: var(--text-color); text-decoration: none; -} +} \ No newline at end of file diff --git a/client/src/components/common/Alerts.jsx b/client/src/components/common/Alerts.jsx index 1d25b7d2..21657456 100644 --- a/client/src/components/common/Alerts.jsx +++ b/client/src/components/common/Alerts.jsx @@ -24,7 +24,7 @@ const Alert = ({ title, info, buttontext, Onclick, showRightBox, color }) => { className={ showRightBox ? "right-box " + color : "right-box hide " + color } - /> + / > {info} diff --git a/client/src/components/common/Button.jsx b/client/src/components/common/Button.jsx index 0d501194..861f338c 100644 --- a/client/src/components/common/Button.jsx +++ b/client/src/components/common/Button.jsx @@ -8,9 +8,17 @@ export default function Button(props) { const { children, className, linkTo, ...rest } = props; return ( - + <> + {linkTo ? ( + + {children} + + ) : ( + + )} + ); } diff --git a/client/src/components/common/InfoBox.jsx b/client/src/components/common/InfoBox.jsx new file mode 100644 index 00000000..62d9420a --- /dev/null +++ b/client/src/components/common/InfoBox.jsx @@ -0,0 +1,12 @@ +import React from "react"; +import "../../assets/styles/components/infoBox.scss"; +const InfoBox = ({ title, value, width = "narrow", color = "dark" }) => { + return ( +
+ {title} + {value} +
+ ); +}; + +export default InfoBox; diff --git a/client/src/components/common/Inputs.jsx b/client/src/components/common/Inputs.jsx new file mode 100644 index 00000000..5e4c69e8 --- /dev/null +++ b/client/src/components/common/Inputs.jsx @@ -0,0 +1,67 @@ +import "./../../assets/styles/components/Inputs.scss"; + +import PropTypes from "prop-types"; + +function TextInput({ + label, + type, + name, + value, + onChange, + placeholder, + required, +}) { + return ( + + ); +} +TextInput.propTypes = { + label: PropTypes.string.isRequired, + type: PropTypes.string, + name: PropTypes.string, + value: PropTypes.string, + onChange: PropTypes.func, + placeholder: PropTypes.string, + required: PropTypes.bool, +}; +function RadioInput({ label, name, required, valuesArr, onChange }) { + return ( + + ); +} +RadioInput.propTypes = { + label: PropTypes.string.isRequired, + name: PropTypes.string, + valuesArr: PropTypes.array, + onChange: PropTypes.func, + required: PropTypes.bool, +}; + +export { RadioInput }; +export default TextInput; diff --git a/client/src/components/common/PageTitle.jsx b/client/src/components/common/PageTitle.jsx new file mode 100644 index 00000000..3bc8069e --- /dev/null +++ b/client/src/components/common/PageTitle.jsx @@ -0,0 +1,9 @@ +import React from 'react' + +const PageTitle = ({title}) => { + return ( +

{title}

+ ) +} + +export default PageTitle \ No newline at end of file diff --git a/client/src/components/landingpage/LandingPage.jsx b/client/src/components/landingpage/LandingPage.jsx index 478f5f19..0203440c 100644 --- a/client/src/components/landingpage/LandingPage.jsx +++ b/client/src/components/landingpage/LandingPage.jsx @@ -1,21 +1,84 @@ -import Nav from "../common/nav"; import Button from "../common/Button"; -import Footer from "../common/Footer"; import FancyBlobs from "./FancyBlobs"; +import "./LandingPage.scss"; + +import PageTitle from "../common/PageTitle"; + +import { + FolderIcon, + AcademicCapIcon, + PresentationChartLineIcon, + PencilSquareIcon, + BanknotesIcon, + FlagIcon, + BellAlertIcon, +} from "@heroicons/react/24/solid"; + +const features = [ + { + icon: , + text: "إدارة الغياب والاشتراك الاسبوعي", + }, + { + icon: , + text: "تقييم الأفراد ووضع النتائج", + }, + { + icon: , + text: "وضع الاحصاءيات والتقارير", + }, + { + icon: , + text: "تسجيل المواضيع والانشطة المتنوعة", + }, + { + icon: , + text: "إدارة الماليات والخزنة", + }, + { + icon: , + text: "إنشاء التقارير وتسجيل مجالس الشرف", + }, + { + icon: , + text: "إرسال التنبيهات والاشعارات للقادة", + }, +]; + export default function LandingPage() { return ( - <> -