├── .eslintrc.json
├── src
├── redux
│ ├── rootReducer.ts
│ ├── hooks.ts
│ └── store.ts
├── app
│ ├── favicon.ico
│ ├── loading.tsx
│ ├── not-found.tsx
│ ├── error.tsx
│ ├── (withlayout)
│ │ ├── student
│ │ │ └── page.tsx
│ │ ├── super-admin
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── globals.css
│ ├── layout.tsx
│ ├── login
│ │ └── page.tsx
│ ├── page.tsx
│ └── page.module.css
├── assets
│ └── login-image.png
├── constants
│ ├── role.ts
│ └── sidebarItems.tsx
├── lib
│ ├── Providers.tsx
│ └── AntdRegistry.tsx
└── components
│ ├── ui
│ ├── Contents.tsx
│ ├── UMBreadCrumb.tsx
│ └── Sidebar.tsx
│ └── Forms
│ ├── Form.tsx
│ └── FormInput.tsx
├── next.config.js
├── .gitignore
├── public
├── vercel.svg
└── next.svg
├── tsconfig.json
├── package.json
├── LICENCE
└── README.md
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 | // eslintrc
--------------------------------------------------------------------------------
/src/redux/rootReducer.ts:
--------------------------------------------------------------------------------
1 | export const reducer = {
2 |
3 | }
4 |
5 | // Root Reducer
--------------------------------------------------------------------------------
/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hazrat-Ali9/University-Management-Frontend/HEAD/src/app/favicon.ico
--------------------------------------------------------------------------------
/src/assets/login-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hazrat-Ali9/University-Management-Frontend/HEAD/src/assets/login-image.png
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {}
3 |
4 | module.exports = nextConfig
5 | // next config
6 |
--------------------------------------------------------------------------------
/src/constants/role.ts:
--------------------------------------------------------------------------------
1 | export enum USER_ROLE{
2 | STUDENT = "student",
3 | FACULTY = "faculty",
4 | ADMIN = "admin",
5 | SUPER_ADMIN = "super_admin"
6 | }
7 |
8 | // Role
--------------------------------------------------------------------------------
/src/app/loading.tsx:
--------------------------------------------------------------------------------
1 | const Loading = () => {
2 | return (
3 |
4 |
Loading....
5 |
6 | );
7 | };
8 | // Loading tsx
9 | export default Loading;
10 |
--------------------------------------------------------------------------------
/src/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | const NotFoundPage = () => {
2 | return (
3 |
4 |
404!!! Page not found!
5 |
6 | );
7 | };
8 | // Not found
9 | export default NotFoundPage;
10 |
--------------------------------------------------------------------------------
/src/app/error.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | // error
3 | const ErrorPage = () => {
4 | return (
5 |
6 |
Something went wrong!
7 |
8 | );
9 | };
10 |
11 | export default ErrorPage;
12 |
--------------------------------------------------------------------------------
/src/app/(withlayout)/student/page.tsx:
--------------------------------------------------------------------------------
1 | const StudentPage = () => {
2 | return (
3 |
4 |
This page is for student
5 |
6 | );
7 | };
8 | // Student Page
9 | export default StudentPage;
10 |
--------------------------------------------------------------------------------
/src/app/(withlayout)/super-admin/page.tsx:
--------------------------------------------------------------------------------
1 | const SuperAdminPage = () => {
2 | return (
3 |
4 |
This page is for super admin
5 |
6 | );
7 | };
8 | // Super Admin Page
9 | export default SuperAdminPage;
10 |
--------------------------------------------------------------------------------
/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@300;400;700&display=swap');
2 | * {
3 | box-sizing: border-box;
4 | padding: 0;
5 | margin: 0;
6 | font-family: 'Roboto Condensed', sans-serif;
7 | }
8 | /* globals css */
--------------------------------------------------------------------------------
/src/redux/hooks.ts:
--------------------------------------------------------------------------------
1 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
2 | import type { RootState, AppDispatch } from './store'
3 | // hooks
4 | // Use throughout your app instead of plain `useDispatch` and `useSelector`
5 | export const useAppDispatch: () => AppDispatch = useDispatch
6 | export const useAppSelector: TypedUseSelectorHook = useSelector
--------------------------------------------------------------------------------
/src/app/(withlayout)/layout.tsx:
--------------------------------------------------------------------------------
1 | import Contents from "@/components/ui/Contents";
2 | import SideBar from "@/components/ui/Sidebar";
3 | import { Layout } from "antd";
4 | // Super Admin Layout
5 | const DashboardLayout = ({ children }: { children: React.ReactNode }) => {
6 | return (
7 |
8 |
9 | {children}
10 |
11 | );
12 | };
13 |
14 | export default DashboardLayout;
15 |
--------------------------------------------------------------------------------
/src/lib/Providers.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { store } from "@/redux/store";
3 | import { Provider } from "react-redux";
4 | import StyledComponentsRegistry from "./AntdRegistry";
5 | // Providers
6 | const Providers = ({ children }: { children: React.ReactNode }) => {
7 | return (
8 |
9 | {children}
10 |
11 | );
12 | };
13 |
14 | export default Providers;
15 |
--------------------------------------------------------------------------------
/src/redux/store.ts:
--------------------------------------------------------------------------------
1 | // Store js
2 | import { reducer } from './rootReducer';
3 | import { configureStore } from '@reduxjs/toolkit'
4 |
5 | export const store = configureStore({
6 | reducer
7 | })
8 |
9 |
10 |
11 | // Infer the `RootState` and `AppDispatch` types from the store itself
12 | export type RootState = ReturnType
13 | // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
14 | export type AppDispatch = typeof store.dispatch
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 | # gitignore
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "./globals.css";
2 | import type { Metadata } from "next";
3 | import { Inter } from "next/font/google";
4 | import Providers from "@/lib/Providers";
5 | // layout tsx
6 | const inter = Inter({ subsets: ["latin"] });
7 |
8 | export const metadata: Metadata = {
9 | title: "Create Next App",
10 | description: "Generated by create next app",
11 | };
12 |
13 | export default function RootLayout({
14 | children,
15 | }: {
16 | children: React.ReactNode;
17 | }) {
18 | return (
19 |
20 |
21 | {children}
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/lib/AntdRegistry.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | // ant regisrty
3 | import React from "react";
4 | import { createCache, extractStyle, StyleProvider } from "@ant-design/cssinjs";
5 | import type Entity from "@ant-design/cssinjs/es/Cache";
6 | import { useServerInsertedHTML } from "next/navigation";
7 |
8 | const StyledComponentsRegistry = ({ children }: React.PropsWithChildren) => {
9 | const cache = React.useMemo(() => createCache(), []);
10 | useServerInsertedHTML(() => (
11 |
15 | ));
16 | return {children};
17 | };
18 |
19 | export default StyledComponentsRegistry;
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
29 | //Ts config
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "university-management-frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@ant-design/cssinjs": "^1.17.0",
13 | "@reduxjs/toolkit": "^1.9.5",
14 | "@types/node": "20.6.3",
15 | "@types/react": "18.2.22",
16 | "@types/react-dom": "18.2.7",
17 | "antd": "^5.9.2",
18 | "eslint": "8.49.0",
19 | "eslint-config-next": "13.5.2",
20 | "next": "13.5.2",
21 | "react": "18.2.0",
22 | "react-dom": "18.2.0",
23 | "react-hook-form": "^7.46.2",
24 | "react-redux": "^8.1.2",
25 | "typescript": "5.2.2"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/components/ui/Contents.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Layout } from "antd";
3 | import UMBreadCrumb from "./UMBreadCrumb";
4 | // Contents
5 | const { Content } = Layout;
6 |
7 | const Contents = ({ children }: { children: React.ReactNode }) => {
8 | const base = "admin";
9 | return (
10 |
16 |
28 | {children}
29 |
30 | );
31 | };
32 |
33 | export default Contents;
34 |
--------------------------------------------------------------------------------
/src/components/ui/UMBreadCrumb.tsx:
--------------------------------------------------------------------------------
1 | import { Breadcrumb } from "antd";
2 | import Link from "next/link";
3 | import { HomeOutlined } from "@ant-design/icons";
4 | // Um bread crumb
5 | const UMBreadCrumb = ({
6 | items,
7 | }: {
8 | items: {
9 | label: string;
10 | link: string;
11 | }[];
12 | }) => {
13 | const breadCrumbItems = [
14 | {
15 | title: (
16 |
17 |
18 |
19 | ),
20 | },
21 | ...items.map((item) => {
22 | return {
23 | title: item.link ? (
24 | {item.label}
25 | ) : (
26 | {item.label}
27 | ),
28 | };
29 | }),
30 | ];
31 |
32 | return ;
33 | };
34 |
35 | export default UMBreadCrumb;
36 |
--------------------------------------------------------------------------------
/src/components/Forms/Form.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | // Form
3 | import { ReactElement, ReactNode } from "react";
4 | import { useForm, FormProvider, SubmitHandler } from "react-hook-form";
5 |
6 | type FormConfig = {
7 | defaultValues?: Record;
8 | };
9 |
10 | type FormProps = {
11 | children?: ReactElement | ReactNode;
12 | submitHandler: SubmitHandler;
13 | } & FormConfig;
14 |
15 | const Form = ({ children, submitHandler, defaultValues }: FormProps) => {
16 | const formConfig: FormConfig = {};
17 |
18 | if (!!defaultValues) formConfig["defaultValues"] = defaultValues;
19 |
20 | const methods = useForm(formConfig);
21 |
22 | const { handleSubmit, reset } = methods;
23 |
24 | const onSubmit = (data: any) => {
25 | submitHandler(data);
26 | reset();
27 | };
28 |
29 | return (
30 |
31 |
32 |
33 | );
34 | };
35 |
36 | export default Form;
37 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Hazrat Ali
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/components/ui/Sidebar.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | // Sidebar
3 | import { useState } from "react";
4 | import { Layout, Menu } from "antd";
5 |
6 | import { sidebarItems } from "@/constants/sidebarItems";
7 | import { USER_ROLE } from "@/constants/role";
8 |
9 | const { Sider } = Layout;
10 |
11 | const SideBar = () => {
12 | const [collapsed, setCollapsed] = useState(false);
13 |
14 | const role = USER_ROLE.ADMIN;
15 |
16 | return (
17 | setCollapsed(value)}
21 | width={280}
22 | style={{
23 | overflow: "auto",
24 | height: "100vh",
25 | position: "sticky",
26 | left: 0,
27 | top: 0,
28 | bottom: 0,
29 | }}
30 | >
31 |
40 | PH-University
41 |
42 |
48 |
49 | );
50 | };
51 |
52 | export default SideBar;
53 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Forms/FormInput.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | // From input
3 | import { Input } from "antd";
4 | import { useFormContext, Controller } from "react-hook-form";
5 | interface IInput {
6 | name: string;
7 | type?: string;
8 | size?: "large" | "small";
9 | value?: string | string[] | undefined;
10 | id?: string;
11 | placeholder?: string;
12 | validation?: object;
13 | label?: string;
14 | }
15 |
16 | const FormInput = ({
17 | name,
18 | type,
19 | size,
20 | value,
21 | id,
22 | placeholder,
23 | validation,
24 | label,
25 | }: IInput) => {
26 | const { control } = useFormContext();
27 |
28 | return (
29 | <>
30 | {label ? label : null}
31 |
35 | type === "password" ? (
36 |
43 | ) : (
44 |
51 | )
52 | }
53 | />
54 | >
55 | );
56 | };
57 |
58 | export default FormInput;
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🦁 Hazrat Ali
2 |
3 | # 🐲 Programmer || Software Engineering
4 |
5 | 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).
6 |
7 | ## Getting Started
8 |
9 | First, run the development server:
10 |
11 | ```bash
12 | npm run dev
13 | # or
14 | yarn dev
15 | # or
16 | pnpm dev
17 | # or
18 | bun dev
19 | ```
20 |
21 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
22 |
23 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
24 |
25 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
26 |
27 | ## Learn More
28 |
29 | To learn more about Next.js, take a look at the following resources:
30 |
31 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
32 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
33 |
34 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
35 |
36 | ## Deploy on Vercel
37 |
38 | 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.
39 |
40 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
41 |
--------------------------------------------------------------------------------
/src/app/login/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Button, Col, Input, Row } from "antd";
3 | import loginImage from "../../assets/login-image.png";
4 | import Image from "next/image";
5 | import Form from "@/components/Forms/Form";
6 | import FormInput from "@/components/Forms/FormInput";
7 | import { SubmitHandler } from "react-hook-form";
8 | // login Page
9 | type FormValues = {
10 | id: string;
11 | password: string;
12 | };
13 |
14 | const LoginPage = () => {
15 | const onSubmit: SubmitHandler = (data) => {
16 | try {
17 | console.log(data);
18 | } catch (err) {}
19 | };
20 | return (
21 |
28 |
29 |
30 |
31 |
32 |
37 | First login your account
38 |
39 |
61 |
62 |
63 | );
64 | };
65 |
66 | export default LoginPage;
67 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 | import styles from './page.module.css'
3 | // Page Modules
4 | export default function Home() {
5 | return (
6 |
7 |
8 |
9 | Get started by editing
10 | src/app/page.tsx
11 |
12 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
93 |
94 | )
95 | }
96 |
--------------------------------------------------------------------------------
/src/app/page.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: space-between;
5 | align-items: center;
6 | padding: 6rem;
7 | min-height: 100vh;
8 | }
9 | /* Page Module CSS comment */
10 | .description {
11 | display: inherit;
12 | justify-content: inherit;
13 | align-items: inherit;
14 | font-size: 0.85rem;
15 | max-width: var(--max-width);
16 | width: 100%;
17 | z-index: 2;
18 | font-family: var(--font-mono);
19 | }
20 |
21 | .description a {
22 | display: flex;
23 | justify-content: center;
24 | align-items: center;
25 | gap: 0.5rem;
26 | }
27 |
28 | .description p {
29 | position: relative;
30 | margin: 0;
31 | padding: 1rem;
32 | background-color: rgba(var(--callout-rgb), 0.5);
33 | border: 1px solid rgba(var(--callout-border-rgb), 0.3);
34 | border-radius: var(--border-radius);
35 | }
36 |
37 | .code {
38 | font-weight: 700;
39 | font-family: var(--font-mono);
40 | }
41 |
42 | .grid {
43 | display: grid;
44 | grid-template-columns: repeat(4, minmax(25%, auto));
45 | max-width: 100%;
46 | width: var(--max-width);
47 | }
48 |
49 | .card {
50 | padding: 1rem 1.2rem;
51 | border-radius: var(--border-radius);
52 | background: rgba(var(--card-rgb), 0);
53 | border: 1px solid rgba(var(--card-border-rgb), 0);
54 | transition: background 200ms, border 200ms;
55 | }
56 |
57 | .card span {
58 | display: inline-block;
59 | transition: transform 200ms;
60 | }
61 |
62 | .card h2 {
63 | font-weight: 600;
64 | margin-bottom: 0.7rem;
65 | }
66 |
67 | .card p {
68 | margin: 0;
69 | opacity: 0.6;
70 | font-size: 0.9rem;
71 | line-height: 1.5;
72 | max-width: 30ch;
73 | }
74 |
75 | .center {
76 | display: flex;
77 | justify-content: center;
78 | align-items: center;
79 | position: relative;
80 | padding: 4rem 0;
81 | }
82 |
83 | .center::before {
84 | background: var(--secondary-glow);
85 | border-radius: 50%;
86 | width: 480px;
87 | height: 360px;
88 | margin-left: -400px;
89 | }
90 |
91 | .center::after {
92 | background: var(--primary-glow);
93 | width: 240px;
94 | height: 180px;
95 | z-index: -1;
96 | }
97 |
98 | .center::before,
99 | .center::after {
100 | content: '';
101 | left: 50%;
102 | position: absolute;
103 | filter: blur(45px);
104 | transform: translateZ(0);
105 | }
106 |
107 | .logo {
108 | position: relative;
109 | }
110 | /* Enable hover only on non-touch devices */
111 | @media (hover: hover) and (pointer: fine) {
112 | .card:hover {
113 | background: rgba(var(--card-rgb), 0.1);
114 | border: 1px solid rgba(var(--card-border-rgb), 0.15);
115 | }
116 |
117 | .card:hover span {
118 | transform: translateX(4px);
119 | }
120 | }
121 |
122 | @media (prefers-reduced-motion) {
123 | .card:hover span {
124 | transform: none;
125 | }
126 | }
127 |
128 | /* Mobile */
129 | @media (max-width: 700px) {
130 | .content {
131 | padding: 4rem;
132 | }
133 |
134 | .grid {
135 | grid-template-columns: 1fr;
136 | margin-bottom: 120px;
137 | max-width: 320px;
138 | text-align: center;
139 | }
140 |
141 | .card {
142 | padding: 1rem 2.5rem;
143 | }
144 |
145 | .card h2 {
146 | margin-bottom: 0.5rem;
147 | }
148 |
149 | .center {
150 | padding: 8rem 0 6rem;
151 | }
152 |
153 | .center::before {
154 | transform: none;
155 | height: 300px;
156 | }
157 |
158 | .description {
159 | font-size: 0.8rem;
160 | }
161 |
162 | .description a {
163 | padding: 1rem;
164 | }
165 |
166 | .description p,
167 | .description div {
168 | display: flex;
169 | justify-content: center;
170 | position: fixed;
171 | width: 100%;
172 | }
173 |
174 | .description p {
175 | align-items: center;
176 | inset: 0 0 auto;
177 | padding: 2rem 1rem 1.4rem;
178 | border-radius: 0;
179 | border: none;
180 | border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
181 | background: linear-gradient(
182 | to bottom,
183 | rgba(var(--background-start-rgb), 1),
184 | rgba(var(--callout-rgb), 0.5)
185 | );
186 | background-clip: padding-box;
187 | backdrop-filter: blur(24px);
188 | }
189 |
190 | .description div {
191 | align-items: flex-end;
192 | pointer-events: none;
193 | inset: auto 0 0;
194 | padding: 2rem;
195 | height: 200px;
196 | background: linear-gradient(
197 | to bottom,
198 | transparent 0%,
199 | rgb(var(--background-end-rgb)) 40%
200 | );
201 | z-index: 1;
202 | }
203 | }
204 |
205 | /* Tablet and Smaller Desktop */
206 | @media (min-width: 701px) and (max-width: 1120px) {
207 | .grid {
208 | grid-template-columns: repeat(2, 50%);
209 | }
210 | }
211 |
212 | @media (prefers-color-scheme: dark) {
213 | .vercelLogo {
214 | filter: invert(1);
215 | }
216 |
217 | .logo {
218 | filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
219 | }
220 | }
221 |
222 | @keyframes rotate {
223 | from {
224 | transform: rotate(360deg);
225 | }
226 | to {
227 | transform: rotate(0deg);
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/src/constants/sidebarItems.tsx:
--------------------------------------------------------------------------------
1 | import type { MenuProps } from "antd";
2 | import {
3 | ProfileOutlined,
4 | TableOutlined,
5 | AppstoreOutlined,
6 | ScheduleOutlined,
7 | ThunderboltOutlined,
8 | CreditCardOutlined,
9 | FileTextOutlined,
10 | } from "@ant-design/icons";
11 | import Link from "next/link";
12 | import { USER_ROLE } from "./role";
13 | export const sidebarItems = (role: string) => {
14 | const defaultSidebarItems: MenuProps["items"] = [
15 | {
16 | label: "Profile",
17 | key: "profile",
18 | icon: ,
19 | children: [
20 | {
21 | label: Account Profile,
22 | key: `/${role}/profile`,
23 | },
24 | {
25 | label: Change Password,
26 | key: `/${role}/change-password`,
27 | },
28 | ],
29 | },
30 | ];
31 |
32 | const commonAdminSidebarItems: MenuProps["items"] = [
33 | {
34 | label: Manage Students,
35 | icon: ,
36 | key: `/${role}/manage-student`,
37 | },
38 | {
39 | label: Manage Faculty,
40 | icon: ,
41 | key: `/${role}/manage-faculty`,
42 | },
43 | ];
44 |
45 | const adminSidebarItems: MenuProps["items"] = [
46 | ...defaultSidebarItems,
47 | ...commonAdminSidebarItems,
48 | {
49 | label: "Manage academic",
50 | key: "manage-academic",
51 | icon: ,
52 | children: [
53 | {
54 | label: Faculties,
55 | key: `/${role}/academic/faculty`,
56 | },
57 | {
58 | label: Departments,
59 | key: `/${role}/academic/department`,
60 | },
61 | {
62 | label: Semesters,
63 | key: `/${role}/academic/semester`,
64 | },
65 | ],
66 | },
67 | {
68 | label: "Management",
69 | key: "management",
70 | icon: ,
71 | children: [
72 | {
73 | label: Department,
74 | key: `/${role}/department`,
75 | },
76 | {
77 | label: Building,
78 | key: `/${role}/building`,
79 | },
80 | {
81 | label: Rooms,
82 | key: `/${role}/room`,
83 | },
84 | {
85 | label: Course,
86 | key: `/${role}/course`,
87 | },
88 | {
89 | label: (
90 |
91 | Semester registration
92 |
93 | ),
94 | key: `/${role}/semester-registration`,
95 | },
96 | {
97 | label: Offered courses,
98 | key: `/${role}/offered-course`,
99 | },
100 | {
101 | label: (
102 |
103 | Course sections
104 |
105 | ),
106 | key: `/${role}/offered-course-section`,
107 | },
108 | {
109 | label: (
110 |
111 | Course schedules
112 |
113 | ),
114 | key: `/${role}/offered-course-schedule`,
115 | },
116 | ],
117 | },
118 | ];
119 |
120 | const superAdminSidebarItems: MenuProps["items"] = [
121 | ...defaultSidebarItems,
122 | ...commonAdminSidebarItems,
123 | {
124 | label: Manage Admin,
125 | icon: ,
126 | key: `/${role}/admin`,
127 | },
128 | {
129 | label: Manage User,
130 | icon: ,
131 | key: `/${role}/user`,
132 | },
133 | {
134 | label: "Manage permission",
135 | key: "manage-permission",
136 | icon: ,
137 | children: [
138 | {
139 | label: View permissions,
140 | key: `/${role}/permission`,
141 | },
142 | ],
143 | },
144 | {
145 | label: "Management",
146 | key: "management",
147 | icon: ,
148 | children: [
149 | {
150 | label: Department,
151 | key: `/${role}/department`,
152 | },
153 | ],
154 | },
155 | ];
156 |
157 | const facultySidebarItems: MenuProps["items"] = [
158 | ...defaultSidebarItems,
159 | {
160 | label: Courses,
161 | icon: ,
162 | key: `/${role}/courses`,
163 | },
164 | ];
165 |
166 | const studentSidebarItems: MenuProps["items"] = [
167 | ...defaultSidebarItems,
168 | {
169 | label: Courses,
170 | icon: ,
171 | key: `/${role}/courses`,
172 | },
173 | {
174 | label: Course schedules,
175 | icon: ,
176 | key: `/${role}/courses/schedule`,
177 | },
178 | {
179 | label: Registration,
180 | icon: ,
181 | key: `/${role}/registration`,
182 | },
183 | {
184 | label: Payment,
185 | icon: ,
186 | key: `/${role}/payment`,
187 | },
188 | {
189 | label: Academic report,
190 | icon: ,
191 | key: `/${role}/academic-report`,
192 | },
193 | ];
194 |
195 | if (role === USER_ROLE.SUPER_ADMIN) return superAdminSidebarItems;
196 | else if (role === USER_ROLE.ADMIN) return adminSidebarItems;
197 | else if (role === USER_ROLE.FACULTY) return facultySidebarItems;
198 | else if (role === USER_ROLE.STUDENT) return studentSidebarItems;
199 | else {
200 | return defaultSidebarItems;
201 | }
202 | };
203 |
204 | // Sidebar team
--------------------------------------------------------------------------------