147 |
148 | );
149 | }
150 |
151 | export default TeachersAbsentAdmin;
152 |
--------------------------------------------------------------------------------
/client/src/components/ui/alert-dialog.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
3 |
4 | import { cn } from "@/lib/utils"
5 | import { buttonVariants } from "@/components/ui/button"
6 |
7 | const AlertDialog = AlertDialogPrimitive.Root
8 |
9 | const AlertDialogTrigger = AlertDialogPrimitive.Trigger
10 |
11 | const AlertDialogPortal = AlertDialogPrimitive.Portal
12 |
13 | const AlertDialogOverlay = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef
16 | >(({ className, ...props }, ref) => (
17 |
25 | ))
26 | AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
27 |
28 | const AlertDialogContent = React.forwardRef<
29 | React.ElementRef,
30 | React.ComponentPropsWithoutRef
31 | >(({ className, ...props }, ref) => (
32 |
33 |
34 |
42 |
43 | ))
44 | AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
45 |
46 | const AlertDialogHeader = ({
47 | className,
48 | ...props
49 | }: React.HTMLAttributes) => (
50 |
57 | )
58 | AlertDialogHeader.displayName = "AlertDialogHeader"
59 |
60 | const AlertDialogFooter = ({
61 | className,
62 | ...props
63 | }: React.HTMLAttributes) => (
64 |
71 | )
72 | AlertDialogFooter.displayName = "AlertDialogFooter"
73 |
74 | const AlertDialogTitle = React.forwardRef<
75 | React.ElementRef,
76 | React.ComponentPropsWithoutRef
77 | >(({ className, ...props }, ref) => (
78 |
83 | ))
84 | AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
85 |
86 | const AlertDialogDescription = React.forwardRef<
87 | React.ElementRef,
88 | React.ComponentPropsWithoutRef
89 | >(({ className, ...props }, ref) => (
90 |
95 | ))
96 | AlertDialogDescription.displayName =
97 | AlertDialogPrimitive.Description.displayName
98 |
99 | const AlertDialogAction = React.forwardRef<
100 | React.ElementRef,
101 | React.ComponentPropsWithoutRef
102 | >(({ className, ...props }, ref) => (
103 |
108 | ))
109 | AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
110 |
111 | const AlertDialogCancel = React.forwardRef<
112 | React.ElementRef,
113 | React.ComponentPropsWithoutRef
114 | >(({ className, ...props }, ref) => (
115 |
124 | ))
125 | AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
126 |
127 | export {
128 | AlertDialog,
129 | AlertDialogPortal,
130 | AlertDialogOverlay,
131 | AlertDialogTrigger,
132 | AlertDialogContent,
133 | AlertDialogHeader,
134 | AlertDialogFooter,
135 | AlertDialogTitle,
136 | AlertDialogDescription,
137 | AlertDialogAction,
138 | AlertDialogCancel,
139 | }
140 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders.
63 | All complaints will be reviewed and investigated promptly and fairly.
64 |
65 | All community leaders are obligated to respect the privacy and security of the
66 | reporter of any incident.
67 |
68 | ## Enforcement Guidelines
69 |
70 | Community leaders will follow these Community Impact Guidelines in determining
71 | the consequences for any action they deem in violation of this Code of Conduct:
72 |
73 | ### 1. Correction
74 |
75 | **Community Impact**: Use of inappropriate language or other behavior deemed
76 | unprofessional or unwelcome in the community.
77 |
78 | **Consequence**: A private, written warning from community leaders, providing
79 | clarity around the nature of the violation and an explanation of why the
80 | behavior was inappropriate. A public apology may be requested.
81 |
82 | ### 2. Warning
83 |
84 | **Community Impact**: A violation through a single incident or series
85 | of actions.
86 |
87 | **Consequence**: A warning with consequences for continued behavior. No
88 | interaction with the people involved, including unsolicited interaction with
89 | those enforcing the Code of Conduct, for a specified period of time. This
90 | includes avoiding interactions in community spaces as well as external channels
91 | like social media. Violating these terms may lead to a temporary or
92 | permanent ban.
93 |
94 | ### 3. Temporary Ban
95 |
96 | **Community Impact**: A serious violation of community standards, including
97 | sustained inappropriate behavior.
98 |
99 | **Consequence**: A temporary ban from any sort of interaction or public
100 | communication with the community for a specified period of time. No public or
101 | private interaction with the people involved, including unsolicited interaction
102 | with those enforcing the Code of Conduct, is allowed during this period.
103 | Violating these terms may lead to a permanent ban.
104 |
105 | ### 4. Permanent Ban
106 |
107 | **Community Impact**: Demonstrating a pattern of violation of community
108 | standards, including sustained inappropriate behavior, harassment of an
109 | individual, or aggression toward or disparagement of classes of individuals.
110 |
111 | **Consequence**: A permanent ban from any sort of public interaction within
112 | the community.
113 |
114 |
--------------------------------------------------------------------------------
/client/src/components/ui/navigation-menu.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { ChevronDownIcon } from "@radix-ui/react-icons"
3 | import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
4 | import { cva } from "class-variance-authority"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const NavigationMenu = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, children, ...props }, ref) => (
12 |
20 | {children}
21 |
22 |
23 | ))
24 | NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName
25 |
26 | const NavigationMenuList = React.forwardRef<
27 | React.ElementRef,
28 | React.ComponentPropsWithoutRef
29 | >(({ className, ...props }, ref) => (
30 |
38 | ))
39 | NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
40 |
41 | const NavigationMenuItem = NavigationMenuPrimitive.Item
42 |
43 | const navigationMenuTriggerStyle = cva(
44 | "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
45 | )
46 |
47 | const NavigationMenuTrigger = React.forwardRef<
48 | React.ElementRef,
49 | React.ComponentPropsWithoutRef
50 | >(({ className, children, ...props }, ref) => (
51 |
56 | {children}{" "}
57 |
61 |
62 | ))
63 | NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName
64 |
65 | const NavigationMenuContent = React.forwardRef<
66 | React.ElementRef,
67 | React.ComponentPropsWithoutRef
68 | >(({ className, ...props }, ref) => (
69 |
77 | ))
78 | NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName
79 |
80 | const NavigationMenuLink = NavigationMenuPrimitive.Link
81 |
82 | const NavigationMenuViewport = React.forwardRef<
83 | React.ElementRef,
84 | React.ComponentPropsWithoutRef
85 | >(({ className, ...props }, ref) => (
86 |
87 |
95 |
96 | ))
97 | NavigationMenuViewport.displayName =
98 | NavigationMenuPrimitive.Viewport.displayName
99 |
100 | const NavigationMenuIndicator = React.forwardRef<
101 | React.ElementRef,
102 | React.ComponentPropsWithoutRef
103 | >(({ className, ...props }, ref) => (
104 |
112 |
113 |
114 | ))
115 | NavigationMenuIndicator.displayName =
116 | NavigationMenuPrimitive.Indicator.displayName
117 |
118 | export {
119 | navigationMenuTriggerStyle,
120 | NavigationMenu,
121 | NavigationMenuList,
122 | NavigationMenuItem,
123 | NavigationMenuContent,
124 | NavigationMenuTrigger,
125 | NavigationMenuLink,
126 | NavigationMenuIndicator,
127 | NavigationMenuViewport,
128 | }
129 |
--------------------------------------------------------------------------------
/server/src/controllers/room.controller.ts:
--------------------------------------------------------------------------------
1 | import { Request, Response } from "express";
2 | import { asyncHandler } from "../utils/asyncHandler";
3 | import { ApiError } from "../utils/ApiError";
4 | import { Room } from "../models/room.model";
5 | import { ApiResponse } from "../utils/ApiResponse";
6 |
7 | const getRooms = asyncHandler(async (_: Request, res: Response) => {
8 | const rooms = await Room.find();
9 | if (!rooms) {
10 | throw new ApiError(404, "Rooms not found");
11 | }
12 |
13 | return res
14 | .status(200)
15 | .json(new ApiResponse(200, rooms, "Rooms were retrieved successfully"));
16 | });
17 |
18 | const getVacantRooms = asyncHandler(async (req: Request, res: Response) => {
19 | const { time } = req.query;
20 | if (!time || !(typeof time === "string")) {
21 | throw new ApiError(400, "Time is required");
22 | }
23 |
24 | const rooms = await Room.aggregate([
25 | {
26 | $lookup: {
27 | from: "occupiedrooms",
28 | pipeline: [
29 | {
30 | $match: {
31 | time,
32 | },
33 | },
34 | {
35 | $project: {
36 | roomId: { $toString: "$room" },
37 | _id: 0,
38 | },
39 | },
40 | ],
41 | as: "occupiedrooms",
42 | },
43 | },
44 | {
45 | $lookup: {
46 | from: "timetables",
47 | pipeline: [
48 | { $unwind: "$classes" },
49 | {
50 | $match: {
51 | "classes.allotedTime": time,
52 | },
53 | },
54 | {
55 | $group: {
56 | _id: null,
57 | rooms: {
58 | $addToSet: {
59 | $toString: "$classes.allotedRoom",
60 | },
61 | },
62 | },
63 | },
64 | ],
65 | as: "timetable",
66 | },
67 | },
68 | {
69 | $project: {
70 | rooms: {
71 | $reduce: {
72 | input: "$timetable.rooms",
73 | initialValue: [],
74 | in: {
75 | $concatArrays: ["$$value", "$$this"],
76 | },
77 | },
78 | },
79 | _id: { $toString: "$_id" },
80 | roomNumber: 1,
81 | capacity: 1,
82 | location: 1,
83 | occupiedrooms: {
84 | $map: {
85 | input: "$occupiedrooms",
86 | as: "item",
87 | in: "$$item.roomId",
88 | },
89 | },
90 | },
91 | },
92 | {
93 | $match: {
94 | $expr: {
95 | $not: {
96 | $in: [
97 | "$_id",
98 | {
99 | $concatArrays: [
100 | "$rooms",
101 | "$occupiedrooms",
102 | ],
103 | },
104 | ],
105 | },
106 | },
107 | },
108 | },
109 | {
110 | $project: {
111 | rooms: 0,
112 | occupiedrooms: 0,
113 | },
114 | },
115 | ])
116 |
117 | if (!rooms || !rooms.length) {
118 | throw new ApiError(404, "No empty rooms found")
119 | }
120 |
121 | return res.status(200).json(
122 | new ApiResponse(200, rooms, "Vacant rooms found")
123 | )
124 | });
125 |
126 | const addRooms = asyncHandler(async (req: Request, res: Response) => {
127 | if (!req.user) {
128 | throw new ApiError(401, "User not verified");
129 | }
130 |
131 | const { isAdmin } = req.user;
132 | if (!isAdmin) {
133 | throw new ApiError(403, "User not authorized");
134 | }
135 |
136 | const { rooms } = req.body;
137 | if (
138 | !rooms ||
139 | !rooms.length ||
140 | !rooms[0].roomNumber ||
141 | !rooms[0].capacity ||
142 | !rooms[0].location
143 | ) {
144 | throw new ApiError(400, "Rooms are required");
145 | }
146 | const roomNumbers = rooms.map(
147 | (room: { roomNumber: string; capacity: number; location: string }) =>
148 | room.roomNumber
149 | );
150 |
151 | const roomExists = await Room.findOne({ roomNumber: { $in: roomNumbers } });
152 | if (roomExists) {
153 | throw new ApiError(400, "Some room already exists with same room number");
154 | }
155 |
156 | const createRooms = await Room.create(rooms);
157 | if (!createRooms) {
158 | throw new ApiError(400, "Rooms not created");
159 | }
160 |
161 | return res
162 | .status(200)
163 | .json(new ApiResponse(200, createRooms, "Rooms were created"));
164 | });
165 |
166 | const deleteRoom = asyncHandler(async (req: Request, res: Response) => {
167 | if (!req.user) {
168 | throw new ApiError(401, "User not verified");
169 | }
170 |
171 | const { roomId } = req.params;
172 | if (!roomId) {
173 | throw new ApiError(400, "Room id is required");
174 | }
175 |
176 | const { isAdmin } = req.user;
177 | if (!isAdmin) {
178 | throw new ApiError(403, "User not authorized");
179 | }
180 |
181 | await Room.findByIdAndDelete(roomId);
182 |
183 | return res
184 | .status(200)
185 | .json(new ApiResponse(200, {}, "Room deleted successfully"));
186 | });
187 |
188 | const updateRoom = asyncHandler(async (req: Request, res: Response) => {
189 | const { roomId, roomNumber, location, capacity } = req.body;
190 | if (!roomId) {
191 | throw new ApiError(400, "Room id is required");
192 | }
193 | if (!roomNumber || !location || !capacity) {
194 | throw new ApiError(400, "All fields are required");
195 | }
196 | const roomExists = await Room.findOne({ _id: roomId });
197 | if (!roomExists) {
198 | throw new ApiError(400, "Room not found");
199 | }
200 | const updatedRoom = await Room.findByIdAndUpdate
201 | (roomId, { roomNumber, location, capacity }, { new: true });
202 | if (!updatedRoom) {
203 | throw new ApiError(400, "Room not updated");
204 | }
205 | return res
206 | .status(200)
207 | .json(new ApiResponse(200, {}, "Room updated successfully"));
208 | });
209 |
210 | export { addRooms, deleteRoom, getRooms, getVacantRooms, updateRoom };
211 |
--------------------------------------------------------------------------------
/client/src/components/ui/select.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import {
3 | CaretSortIcon,
4 | CheckIcon,
5 | ChevronDownIcon,
6 | ChevronUpIcon,
7 | } from "@radix-ui/react-icons"
8 | import * as SelectPrimitive from "@radix-ui/react-select"
9 |
10 | import { cn } from "@/lib/utils"
11 |
12 | const Select = SelectPrimitive.Root
13 |
14 | const SelectGroup = SelectPrimitive.Group
15 |
16 | const SelectValue = SelectPrimitive.Value
17 |
18 | const SelectTrigger = React.forwardRef<
19 | React.ElementRef,
20 | React.ComponentPropsWithoutRef
21 | >(({ className, children, ...props }, ref) => (
22 | span]:line-clamp-1",
26 | className
27 | )}
28 | {...props}
29 | >
30 | {children}
31 |
32 |
33 |
34 |
35 | ))
36 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
37 |
38 | const SelectScrollUpButton = React.forwardRef<
39 | React.ElementRef,
40 | React.ComponentPropsWithoutRef
41 | >(({ className, ...props }, ref) => (
42 |
50 |
51 |
52 | ))
53 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
54 |
55 | const SelectScrollDownButton = React.forwardRef<
56 | React.ElementRef,
57 | React.ComponentPropsWithoutRef
58 | >(({ className, ...props }, ref) => (
59 |
67 |
68 |
69 | ))
70 | SelectScrollDownButton.displayName =
71 | SelectPrimitive.ScrollDownButton.displayName
72 |
73 | const SelectContent = React.forwardRef<
74 | React.ElementRef,
75 | React.ComponentPropsWithoutRef
76 | >(({ className, children, position = "popper", ...props }, ref) => (
77 |
78 |
89 |
90 |
97 | {children}
98 |
99 |
100 |
101 |
102 | ))
103 | SelectContent.displayName = SelectPrimitive.Content.displayName
104 |
105 | const SelectLabel = React.forwardRef<
106 | React.ElementRef,
107 | React.ComponentPropsWithoutRef
108 | >(({ className, ...props }, ref) => (
109 |
114 | ))
115 | SelectLabel.displayName = SelectPrimitive.Label.displayName
116 |
117 | const SelectItem = React.forwardRef<
118 | React.ElementRef,
119 | React.ComponentPropsWithoutRef
120 | >(({ className, children, ...props }, ref) => (
121 |
129 |
130 |
131 |
132 |
133 |
134 | {children}
135 |
136 | ))
137 | SelectItem.displayName = SelectPrimitive.Item.displayName
138 |
139 | const SelectSeparator = React.forwardRef<
140 | React.ElementRef,
141 | React.ComponentPropsWithoutRef
142 | >(({ className, ...props }, ref) => (
143 |
148 | ))
149 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName
150 |
151 | export {
152 | Select,
153 | SelectGroup,
154 | SelectValue,
155 | SelectTrigger,
156 | SelectContent,
157 | SelectLabel,
158 | SelectItem,
159 | SelectSeparator,
160 | SelectScrollUpButton,
161 | SelectScrollDownButton,
162 | }
163 |
--------------------------------------------------------------------------------
/client/src/assets/404.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Learn.md:
--------------------------------------------------------------------------------
1 | # Learn.md ✍
2 | # Campuspace 🖥️
3 | Campuspace is a MERN stack project with TypeScript & Tailwind CSS. Admins manage timetables, teacher absences, & rooms. Students & teachers view timetables, vacant rooms, & teacher absences. Teachers can book rooms for classes. Efficient college resource management.
4 | 
5 |
6 |
7 | # Table of Contents
8 | 1. [Tech Stack](#tech-stack)
9 | 2. [Contributing](#contributing-)
10 | - [Development Workflow](#development-workflow)
11 | - [Issue Report Process](#issue-report-process)
12 | - [Pull Request Process](#pull-request-process-)
13 | 3. [Setting Up on your machine](#setting-up-on-your-machine)
14 | 4. [Usage](#usage)
15 | 5. [Resources for Beginners](#resources-for-beginners-)
16 | - [Basics of Git and GitHub](#basics-of-git-and-github-)
17 | 6. [Documentation](#documentation)
18 | 7. [Code Reviews](#code-reviews-)
19 | 8. [Feature Requests](#feature-requests-)
20 | 9. [Spreading the Word](#spreading-the-word-)
21 |
22 |
23 | ## Tech Stack
24 |
25 | - MongoDB
26 | - Express
27 | - React
28 | - Node. js
29 | - Tailwind CSS
30 | - TypeScript
31 |
32 |
33 | ## Contributing 📝
34 | Raise and issue; Get assigned and then work on fixing the issue.
35 | We welcome contributions to Campuspace! Follow these steps to contribute:
36 |
37 | 1. **Fork the Repository**: Create your own copy of the repository on your GitHub account.
38 | 
39 |
40 |
41 | 2. **Clone the Repository** : Clone the repository for making commits.
42 | ```bash
43 | git clone https://github.com/Salvelop07/Campuspace.git
44 | ```
45 |
46 |
47 | 
48 |
49 |
50 | 3. **Create a New Branch** for your feature or bug fix: Make a separate branch to work on specific features or fixes and switch to the correct branch.
51 | ```bash
52 | git checkout -b
53 | ```
54 | 4. **Make Changes** and commit them: Implement your changes and save them with a descriptive commit message.
55 | ```bash
56 | git add .
57 | git commit -m "Describe your changes"
58 | ```
59 | 5. **Push Your Changes** to your fork: Upload your committed changes to your GitHub fork.
60 | ```bash
61 | git push origin
62 | ```
63 | 6. **Create a Pull Request ✅**: Propose your changes to be merged into the original repository.
64 |
65 | 
66 |
67 |
68 | ### Development Workflow
69 | - Always work on a new branch for each issue or feature.
70 | - Keep your branch up to date with the main repository's master branch.
71 | - Write clear and descriptive commit messages.
72 | - Test your changes thoroughly before submitting a pull request.
73 |
74 | ### Issue Report Process
75 | 1. Go to the project's issues section.
76 | 2. Select the appropriate template for your issue.
77 | 3. Provide a detailed description of the issue.
78 | 4. Wait for the issue to be assigned before starting to work on it.
79 |
80 | ### **Pull Request Process 🚀**
81 |
82 | 1. Ensure that you have self reviewed your code.
83 | 2. Make sure you have added the proper description for the functionality of the code.
84 | 3. I have commented my code, particularly in hard-to-understand areas.
85 | 4. Add screenshot it help in review.
86 | 5. Submit your PR by giving the necesarry information in PR template and hang tight we will review it really soon.
87 |
88 | # Setting Up on your machine
89 |
90 | Follow these steps to set up the project locally:
91 |
92 | Clone the project
93 |
94 | ```bash
95 | git clone https://github.com/Salvelop07/Campuspace.git
96 | ```
97 |
98 | Go to the project directory
99 |
100 | ```bash
101 | cd Campuspace
102 | ```
103 |
104 | Install dependencies
105 |
106 | ```bash
107 | npm run build
108 | ```
109 |
110 | Start the server
111 |
112 | ```bash
113 | npm run start
114 | ```
115 |
116 |
117 | ## Environment Variables
118 |
119 | To run this project, you will need to add the following environment variables to your .env file
120 |
121 | `MONGODB_URI`
122 |
123 | `PORT`
124 |
125 | `ACCESS_TOKEN_SECRET`
126 |
127 | `NODE_ENV`
128 |
129 | * [Click Here](https://github.com/Salvelop07/Campuspace/blob/master/.env.sample) for Server Side .env.sample file.
130 |
131 | > If you want to change the name of the college, image or footer links edit the env.production file in the client folder
132 | `VITE_COLLEGE_NAME`
133 | `VITE_TWITTER`
134 | `VITE_GITHUB`
135 | `VITE_LINKEDIN`
136 | `VITE_LOGO`
137 |
138 | * [Click Here](https://github.com/Salvelop07/Campuspace/blob/master/client/.env.sample) for Client Side .env.sample file.
139 |
140 |
141 | ## Usage
142 |
143 | ### 1. Register a new account or log in with an existing account.
144 | 
145 |
146 | ### 2. You can get all the details about vacant rooms, Your timetable, Teachers absent, list of classes available at a particular period of time
147 | 
148 |
149 |
150 | ### 3. There are more features and various ways to connect.
151 |
152 |
153 | ## **Contributions are welcome!. You can suggest features to add, report any possible bug that might crept in, ideas and changes! 🚀**
154 |
155 | ## Resources for Beginners 📚
156 | ### Basics of Git and GitHub 📂
157 | - [Forking a Repo](https://help.github.com/en/articles/fork-a-repo)
158 | - [Cloning a Repo](https://help.github.com/en/articles/cloning-a-repository)
159 | - [Creating a Pull Request](https://help.github.com/en/articles/creating-a-pull-request)
160 | - [Getting Started with Git and GitHub](https://guides.github.com/introduction/git-handbook/)
161 | - [Learn GitHub from Scratch](https://www.youtube.com/watch?v=w3jLJU7DT5E)
162 |
163 |
164 | ## Documentation
165 | - Document any significant changes or additions to the codebase.
166 | - Provide clear explanations of the functionality, usage, and any relevant considerations.
167 |
168 | ## Code Reviews 🔎
169 | - Be open to feedback and constructive criticism from other contributors.
170 | - Participate in code reviews by reviewing and providing feedback.
171 |
172 | ## Feature Requests 🔥
173 | - Suggest new features or improvements that would enhance the project.
174 |
175 | ## Spreading the Word 👐
176 | - Share your experience and the project with others.
177 | - Spread the word about the project on social media, developer forums, or any relevant community platforms.
178 |
179 |
180 | Thank you for contributing to Campuspace! Together, we can make a significant impact. Happy coding! 🚀
181 | ## Don't forget to ⭐ the repository!
182 |
--------------------------------------------------------------------------------
/client/src/components/CardWithForm.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@/components/ui/button"
2 | import {
3 | Card,
4 | CardContent,
5 | CardFooter,
6 | CardHeader,
7 | CardTitle,
8 | } from "@/components/ui/card"
9 | import { Input } from "@/components/ui/input"
10 | import { Label } from "@/components/ui/label"
11 | import { ChangeEventHandler, FormEventHandler, MouseEventHandler } from "react"
12 | import { ClassInterface } from "./TimetableAdmin"
13 | import {
14 | Select,
15 | SelectContent,
16 | SelectItem,
17 | SelectTrigger,
18 | SelectValue,
19 | } from "@/components/ui/select"
20 | import { useNavigate } from "react-router-dom"
21 |
22 |
23 | export function CardWithForm(
24 | { course, semester, classes, handleChange, handleSubmit, IncreaseClasses, DecreaseClasses, handleClassChange, setDayValue }:
25 | { course: string, semester: string, handleChange: ChangeEventHandler, classes: ClassInterface[], handleSubmit: FormEventHandler, IncreaseClasses: MouseEventHandler, DecreaseClasses: MouseEventHandler, handleClassChange: ChangeEventHandler, setDayValue: (value: string, index: number) => void }
26 | ) {
27 | const navigate = useNavigate()
28 | return (
29 |
132 | )
133 | }
134 |
--------------------------------------------------------------------------------
/client/src/components/Timetable.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Select,
3 | SelectTrigger,
4 | SelectItem,
5 | SelectContent,
6 | SelectValue,
7 | } from "./ui/select";
8 | import { Button } from "./ui/button";
9 | import {
10 | Card,
11 | CardContent,
12 | CardDescription,
13 | CardFooter,
14 | CardHeader,
15 | CardTitle,
16 | } from "./ui/card";
17 | import { Label } from "@radix-ui/react-label";
18 | import {
19 | Table,
20 | TableBody,
21 | TableCell,
22 | TableHead,
23 | TableHeader,
24 | TableRow,
25 | } from "./ui/table";
26 | import { useTimetable } from "@/context/TimetableProvider";
27 | import React from "react";
28 |
29 | function Timetable() {
30 | const { timetable, courses, getCourses, getTimetable } = useTimetable();
31 |
32 | const [body, setBody] = React.useState({
33 | stream: "",
34 | course: "",
35 | semester: "",
36 | });
37 |
38 | const [semester, setSemester] = React.useState([]);
39 | const semesters = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
40 |
41 | React.useEffect(() => {
42 | courses.map((course) => {
43 | if (course.course === body.course) {
44 | return setSemester(course.semester);
45 | }
46 | });
47 | }, [body.course]);
48 |
49 | function handleSubmit(e: React.FormEvent) {
50 | e.preventDefault();
51 | getTimetable(body.stream, body.course, body.semester);
52 | }
53 |
54 | return (
55 |
56 |
148 |