diff --git a/Procfile b/Procfile
deleted file mode 100644
index dc14c0b63..000000000
--- a/Procfile
+++ /dev/null
@@ -1 +0,0 @@
-web: npm start --prefix backend
\ No newline at end of file
diff --git a/README.md b/README.md
index 31466b54c..9cb961fa6 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,30 @@
-# Final Project
+# Frontend part of Final Project
-Replace this readme with your own information about your project.
+The ADHD Community Project is a web application designed to support and empower individuals with ADHD by providing a safe space and understanding community. Users can sign up as either a "Listener" or a "Seeker" to offer or receive support, respectively. The application includes features such as event listings, community guidelines, and user profiles.
-Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
+## About the project
-## The problem
+Developed using React for the frontend and Node.js with Express for the backend, the application integrates MongoDB for data storage and utilizes Passport.js with JWT for secure authentication. Key features include user authentication with roles (Listener and Seeker), event listings, and user profile management
-Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
+Future enhancements include a live chat feature to facilitate real-time communication within the community
+
+## Challenges
+
+Handling Modal Popups:
+
+Challenge: Managing the state and functionality of modal popups for login and signup forms.
+Solution: Created a custom modal context using React's Context API to manage the display and state of modals. This centralized approach streamlined modal management, making it easier to maintain and extend the functionality.
+
+API Integration:
+
+Challenge: Integrating the frontend with the backend API and ensuring seamless data flow.
+Solution: Developed a consistent API service layer to handle requests and responses between the frontend and backend. Implemented error handling and loading states to enhance user experience during data fetching operations.
+
+Profile Management:
+
+Challenge: Allowing users to view and update their profiles securely.
+Solution: Implemented profile fetching and updating functionalities with secure token-based authentication. Ensured data validation and used React forms to allow users to edit their profiles, providing real-time feedback and updates.
## View it live
-Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
\ No newline at end of file
+https://adhd-connect.netlify.app
\ No newline at end of file
diff --git a/backend/README.md b/backend/README.md
index d1438c910..2ef8dede2 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -1,8 +1,19 @@
# Backend part of Final Project
-This project includes the packages and babel setup for an express server, and is just meant to make things a little simpler to get up and running with.
+The backend serves as the core logic and data management system for the application. It provides the necessary endpoints to handle user authentication, registration and profile management.
-## Getting Started
+## Process
-1. Install the required dependencies using `npm install`.
-2. Start the development server using `npm run dev`.
\ No newline at end of file
+Technologies Used:
+
+Node.js
+Express.js
+MongoDB
+Mongoose
+JWT
+Passport.js
+Multer
+
+## LINK
+
+https://project-final-rmn2.onrender.com
diff --git a/backend/config/passport.js b/backend/config/passport.js
new file mode 100644
index 000000000..aa3d25004
--- /dev/null
+++ b/backend/config/passport.js
@@ -0,0 +1,41 @@
+import passport from "passport";
+import { Strategy as LocalStrategy } from "passport-local";
+import User from "../models/User";
+
+passport.use(
+ new LocalStrategy(
+ { usernameField: "username" },
+ async (username, password, done) => {
+ try {
+ const user = await User.findOne({ username });
+ if (!user) {
+ return done(null, false, { message: "Incorrect username." });
+ }
+
+ const isMatch = await user.comparePassword(password);
+ if (!isMatch) {
+ return done(null, false, { message: "Incorrect password." });
+ }
+
+ return done(null, user);
+ } catch (error) {
+ return done(error);
+ }
+ }
+ )
+);
+
+passport.serializeUser((user, done) => {
+ done(null, user.id);
+});
+
+passport.deserializeUser(async (id, done) => {
+ try {
+ const user = await User.findById(id);
+ done(null, user);
+ } catch (error) {
+ done(error);
+ }
+});
+
+export default passport;
diff --git a/backend/models/User.js b/backend/models/User.js
new file mode 100644
index 000000000..1c0844e21
--- /dev/null
+++ b/backend/models/User.js
@@ -0,0 +1,29 @@
+import mongoose from "mongoose";
+import bcrypt from "bcryptjs";
+
+const userSchema = new mongoose.Schema({
+ username: { type: String, required: true, unique: true, minlength: 3 },
+ password: { type: String, required: true, minlength: 6 },
+ role: { type: String, enum: ["Listener", "Seeker"], required: true },
+ name: { type: String },
+ bio: { type: String },
+ hobby: { type: String },
+});
+
+// Middleware to hash the password before saving
+userSchema.pre("save", async function (next) {
+ if (!this.isModified("password")) {
+ return next();
+ }
+ const salt = await bcrypt.genSalt(10);
+ this.password = await bcrypt.hash(this.password, salt);
+ next();
+});
+
+// Method to compare the entered password with the hashed password
+userSchema.methods.comparePassword = function (enteredPassword) {
+ return bcrypt.compare(enteredPassword, this.password);
+};
+
+const User = mongoose.model("User", userSchema);
+export default User;
diff --git a/backend/package.json b/backend/package.json
index 08f29f244..654e07e77 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -12,9 +12,15 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
+ "bcryptjs": "^2.4.3",
"cors": "^2.8.5",
+ "dotenv": "^16.4.5",
"express": "^4.17.3",
+ "express-list-endpoints": "^7.1.0",
+ "jsonwebtoken": "^9.0.2",
"mongoose": "^8.4.0",
- "nodemon": "^3.0.1"
+ "nodemon": "^3.0.1",
+ "passport": "^0.7.0",
+ "passport-local": "^1.0.0"
}
-}
\ No newline at end of file
+}
diff --git a/backend/routes/authProfile.js b/backend/routes/authProfile.js
new file mode 100644
index 000000000..d1493c1c9
--- /dev/null
+++ b/backend/routes/authProfile.js
@@ -0,0 +1,138 @@
+import express from "express";
+import jwt from "jsonwebtoken";
+import passport from "../config/passport";
+import User from "../models/User";
+
+const router = express.Router();
+
+// Function to generate JWT access token
+const generateAccessToken = (userId) => {
+ try {
+ return jwt.sign({ userId }, process.env.JWT_SECRET, {
+ expiresIn: "24h",
+ });
+ } catch (error) {
+ console.error("Error generating token:", error);
+ throw new Error("Token generation failed");
+ }
+};
+
+// Middleware to athenticate the token
+const authenticateToken = async (req, res, next) => {
+ const authHeader = req.headers["authorization"];
+ const token = authHeader && authHeader.split(" ")[1];
+
+ if (token == null) {
+ return res.status(401).json({ error: "Token is missing" });
+ }
+
+ jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
+ if (err) {
+ return res.status(403).json({ error: "Token is invalid" });
+ }
+ req.user = user;
+ next();
+ });
+};
+
+// Route to register a new user
+router.post("/users", async (req, res) => {
+ const { username, password, role } = req.body;
+ if (password.length < 6) {
+ return res
+ .status(400)
+ .json({ error: "Password must be at least 6 characters long" });
+ }
+
+ try {
+ const newUser = new User({ username, password, role });
+ await newUser.save();
+ const accessToken = generateAccessToken(newUser._id);
+ res.status(201).json({ id: newUser._id, accessToken });
+ } catch (error) {
+ console.error("Error registering user:", error);
+ if (error.code === 11000) {
+ res.status(400).json({ error: "Username already exists" });
+ } else {
+ res.status(500).json({ error: "Something went wrong" });
+ }
+ }
+});
+
+// Route to log in a user
+router.post("/sessions", async (req, res, next) => {
+ passport.authenticate("local", { session: false }, (err, user, info) => {
+ if (err || !user) {
+ console.log("Error during authentication:", err);
+ return res
+ .status(400)
+ .json({ error: info ? info.message : "Login failed" });
+ }
+ req.login(user, { session: false }, async (err) => {
+ if (err) {
+ return res.send(err);
+ }
+ const token = generateAccessToken(user._id);
+ const userWithoutAccessToken = user.toObject();
+ delete userWithoutAccessToken.accessToken;
+ return res.json({ user: userWithoutAccessToken, token });
+ });
+ })(req, res, next);
+});
+
+
+// Route for the current session (logged-in user)
+router.get("/session", authenticateToken, async (req, res) => {
+ try {
+ const user = req.user;
+ const loggedInUser = await User.findById(user.userId).select("-password");
+ if (!loggedInUser) {
+ return res.status(404).json({ error: "User not found" });
+ }
+ res.json(loggedInUser);
+ } catch (error) {
+ console.error("Error fetching logged-in user:", error);
+ res.status(500).json({ error: "Failed to fetch logged-in user" });
+ }
+});
+
+// Route to fetch profile
+router.get("/profile", authenticateToken, async (req, res) => {
+ console.log("GET /profile called");
+ try {
+ const user = await User.findById(req.user.userId).select("-password");
+ if (!user) {
+ return res.status(404).json({ error: "User not found" });
+ }
+ res.json(user);
+ } catch (error) {
+ console.error("Error fetching profile:", error);
+ res.status(500).json({ error: "Failed to fetch profile" });
+ }
+});
+
+//Route to update user profile
+router.put("/profile", authenticateToken, async (req, res) => {
+ const { name, bio, hobby } = req.body;
+ const updatedData = { name, bio, hobby };
+
+ try {
+ const user = await User.findByIdAndUpdate(req.user.userId, updatedData, {
+ new: true,
+ });
+ if (!user) {
+ return res.status(404).json({ error: "User not found" });
+ }
+ res.json(user);
+ } catch (error) {
+ console.error("Error updating profile:", error);
+ res.status(500).json({ error: "Failed to update profile" });
+ }
+});
+
+// Authenticated endpoint
+router.get("/secrets", authenticateToken, (req, res) => {
+ res.json({ secret: "This is secret content" });
+});
+
+export default router;
diff --git a/backend/server.js b/backend/server.js
index 2c00e4802..e4e2d1846 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -1,31 +1,39 @@
-import express from "express";
import cors from "cors";
-import mongoose from 'mongoose'
+import dotenv from "dotenv";
+import express from "express";
+import expressListEndpoints from "express-list-endpoints";
+import mongoose from "mongoose";
-const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/flowershop"
-mongoose.connect(mongoUrl)
-mongoose.Promise = Promise
+import passport from "./config/passport";
+import authProfileRoutes from "./routes/authProfile";
+dotenv.config();
+const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/project-final";
+mongoose.connect(mongoUrl);
+mongoose.Promise = global.Promise;
-// Defines the port the app will run on. Defaults to 8080, but can be overridden
-// when starting the server. Example command to overwrite PORT env variable value:
-// PORT=9000 npm start
-const port = process.env.PORT || 8080;
+const port = process.env.PORT || 9000;
const app = express();
-// Add middlewares to enable cors and json body parsing
-app.use(cors());
+// middlewares to enable cors and json body parsing
+const corsOptions = {
+ origin: "https://adhd-connect.netlify.app",
+ credentials: true,
+};
+
+app.use(cors(corsOptions));
app.use(express.json());
+app.use(passport.initialize());
+
+app.use("/api", authProfileRoutes);
-// Start defining your routes here
-// http://localhost:8080/
app.get("/", (req, res) => {
- res.send("Hello Technigo!");
+ const endpoints = expressListEndpoints(app);
+ res.json(endpoints);
});
-
// Start the server
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
-});
\ No newline at end of file
+});
diff --git a/frontend/README.md b/frontend/README.md
index 5cdb1d9cf..5108a6476 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -1,8 +1,37 @@
# Frontend part of Final Project
-This boilerplate is designed to give you a head start in your React projects, with a focus on understanding the structure and components. As a student of Technigo, you'll find this guide helpful in navigating and utilizing the repository.
+This document provides an overview of the frontend development process, tools used, and key features implemented for the ADHD Community project.
-## Getting Started
+# Tools and Technologies
-1. Install the required dependencies using `npm install`.
-2. Start the development server using `npm run dev`.
\ No newline at end of file
+React: Building the user interface.
+Tailwind CSS: Styling the application.
+Axios: HTTP requests to the backend.
+React Router: Navigation between pages.
+Context API: Managing global state.
+
+# Key Components
+
+1. # AuthForm.jsx
+ Handles both login and signup functionalities within a modal.
+ Switches between login and signup modes.
+ Validates user input and displays error messages.
+ Integrates with the backend for authentication.
+ Shows a loading animation during network requests.
+2. # ModalContext.jsx
+ Provides context for showing and hiding modals.
+3. # EventCard.jsx
+ Displays event details with a flip animation for more information.
+ Responsive design for different screen sizes.
+4. #ProfilePage.jsx
+ Displays and updates user profile information.
+ Allows users to log out.
+5. # Menu.jsx and Footer.jsx
+ Navigation menu and footer for the application.
+6. # AboutUsPage.jsx and FindOutMorePage.jsx
+ About Us page with information on the community's mission, values, and team.
+ Find Out More page with facts about ADHD and roles in the community.
+
+# Conclusion
+
+This project integrates various frontend technologies to create a responsive, user-friendly web application. Using React, Tailwind CSS, and context API, it offers seamless user experiences and robust authentication mechanisms.
diff --git a/frontend/index.html b/frontend/index.html
index 664410b5b..01602a047 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -2,9 +2,9 @@
-
+
- Technigo React Vite Boiler Plate
+ ADHD Connect
diff --git a/frontend/netlify.toml b/frontend/netlify.toml
new file mode 100644
index 000000000..f3634fd06
--- /dev/null
+++ b/frontend/netlify.toml
@@ -0,0 +1,9 @@
+[build]
+ base = "frontend"
+ publish = "dist"
+ command = "npm run build"
+
+[[redirects]]
+ from = "/*"
+ to = "/index.html"
+ status = 200
\ No newline at end of file
diff --git a/frontend/package.json b/frontend/package.json
index 41a2a3164..5c30886ce 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,17 +10,22 @@
"preview": "vite preview"
},
"dependencies": {
+ "axios": "^1.7.2",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.23.1"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
+ "autoprefixer": "^10.4.19",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
+ "postcss": "^8.4.38",
+ "tailwindcss": "^3.4.3",
"vite": "^4.4.5"
}
-}
\ No newline at end of file
+}
diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js
new file mode 100644
index 000000000..2e7af2b7f
--- /dev/null
+++ b/frontend/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/frontend/public/icons/burger-menu.svg b/frontend/public/icons/burger-menu.svg
new file mode 100644
index 000000000..9ddd45b6a
--- /dev/null
+++ b/frontend/public/icons/burger-menu.svg
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/icons/gear.svg b/frontend/public/icons/gear.svg
new file mode 100644
index 000000000..19c27265a
--- /dev/null
+++ b/frontend/public/icons/gear.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/icons/hamburger.png b/frontend/public/icons/hamburger.png
new file mode 100644
index 000000000..f4ee40792
Binary files /dev/null and b/frontend/public/icons/hamburger.png differ
diff --git a/frontend/public/icons/profile.png b/frontend/public/icons/profile.png
new file mode 100644
index 000000000..389355efe
Binary files /dev/null and b/frontend/public/icons/profile.png differ
diff --git a/frontend/public/images/Villads.jpg b/frontend/public/images/Villads.jpg
new file mode 100644
index 000000000..ad12991ca
Binary files /dev/null and b/frontend/public/images/Villads.jpg differ
diff --git a/frontend/public/images/alice.jpg b/frontend/public/images/alice.jpg
new file mode 100644
index 000000000..1a8bdc314
Binary files /dev/null and b/frontend/public/images/alice.jpg differ
diff --git a/frontend/public/images/event-hero.jpg b/frontend/public/images/event-hero.jpg
new file mode 100644
index 000000000..c2f75c63f
Binary files /dev/null and b/frontend/public/images/event-hero.jpg differ
diff --git a/frontend/public/images/guidelines.jpg b/frontend/public/images/guidelines.jpg
new file mode 100644
index 000000000..8483a9ddd
Binary files /dev/null and b/frontend/public/images/guidelines.jpg differ
diff --git a/frontend/public/images/hero-image.jpg b/frontend/public/images/hero-image.jpg
new file mode 100644
index 000000000..2cc409f18
Binary files /dev/null and b/frontend/public/images/hero-image.jpg differ
diff --git a/frontend/public/images/jake.jpg b/frontend/public/images/jake.jpg
new file mode 100644
index 000000000..423e15e74
Binary files /dev/null and b/frontend/public/images/jake.jpg differ
diff --git a/frontend/public/images/john.jpg b/frontend/public/images/john.jpg
new file mode 100644
index 000000000..6546c4ebb
Binary files /dev/null and b/frontend/public/images/john.jpg differ
diff --git a/frontend/public/images/logo.png b/frontend/public/images/logo.png
new file mode 100644
index 000000000..e5b69c177
Binary files /dev/null and b/frontend/public/images/logo.png differ
diff --git a/frontend/public/images/mindful-event.jpg b/frontend/public/images/mindful-event.jpg
new file mode 100644
index 000000000..edb626f29
Binary files /dev/null and b/frontend/public/images/mindful-event.jpg differ
diff --git a/frontend/public/images/plan-event.jpg b/frontend/public/images/plan-event.jpg
new file mode 100644
index 000000000..d7f789198
Binary files /dev/null and b/frontend/public/images/plan-event.jpg differ
diff --git a/frontend/public/images/profile-bg.jpg b/frontend/public/images/profile-bg.jpg
new file mode 100644
index 000000000..70b8e7e03
Binary files /dev/null and b/frontend/public/images/profile-bg.jpg differ
diff --git a/frontend/public/images/signUp.jpg b/frontend/public/images/signUp.jpg
new file mode 100644
index 000000000..c4d9cf7ae
Binary files /dev/null and b/frontend/public/images/signUp.jpg differ
diff --git a/frontend/public/images/social-event.jpg b/frontend/public/images/social-event.jpg
new file mode 100644
index 000000000..953afe3f2
Binary files /dev/null and b/frontend/public/images/social-event.jpg differ
diff --git a/frontend/public/images/support-event.jpg b/frontend/public/images/support-event.jpg
new file mode 100644
index 000000000..01ba1723c
Binary files /dev/null and b/frontend/public/images/support-event.jpg differ
diff --git a/frontend/public/images/team.jpg b/frontend/public/images/team.jpg
new file mode 100644
index 000000000..6a20b090f
Binary files /dev/null and b/frontend/public/images/team.jpg differ
diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg
deleted file mode 100644
index e7b8dfb1b..000000000
--- a/frontend/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 0a24275e6..7dc85eef0 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -1,8 +1,28 @@
-export const App = () => {
+import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
+import { EventsPage } from "./components/eventPage/EventsPage";
+import { AboutUsPage } from "./components/AboutUsPage";
+import { CommunityGuidelines } from "./components/CommunityGuidelines";
+import { Profile } from "./components/Auth/Profile";
+import { ModalProvider } from "./components/Auth/ModalContext";
+import { FindOutMorePage } from "./mainPage/FindOutMorePage";
+import { HomePage } from "./mainPage/HomePage";
+export const App = () => {
return (
- <>
-
+ We strive to create a supportive and inclusive environment for all
+ our members. Please adhere to the following guidelines to help us
+ maintain a respectful and positive community.
+
+
+
+
+
+ Respect & Kindness
+
+
+ Please treat all members with respect and kinsdness. We value
+ diverse perspectives and expect everyone to engage in
+ constructive and respectful discussions.
+
+
+
+
+
+ Confidentiality
+
+
+ We may be an ADHD-focused community group, however, it is your
+ choice whether you talk about your ADHD.
+
+
+
+
+
+ Age Requirement
+
+
+ The group is aimed at adults with suspected or diagnosed ADHD
+ aged 18 and over. Unfortunately, we cannot accept attendees
+ under the age of 18.
+
+
+
+
+
+ No Medical Advice
+
+
+ Our community is here to provide support and share experiences.
+ However, please refrain from giving medical advice. Always
+ consult with a healthcare professional for medical issues.
+
+
+
+
+
+ Alcohol Consumption
+
+
+ Some of our events are held in bars, and we are happy for
+ alcoholic beverages to be consumed. You are responsible for your
+ own behavior, however, if it negatively affects any other
+ attendees, an event host may speak to you and, if necessary, ask
+ you to leave.
+
+
+
+
+
+ Inclusivity
+
+
+ Use inclusive language and avoid offensive or discriminatory
+ remarks. This includes avoiding language that may be considered
+ sexist, racist, homophobic, or otherwise insensitive.
+
+
+
+
+
+ Diversity and Respect
+
+
+ We welcome everyone regardless of their ethnicity, religion,
+ age, culture, gender identity, sexual orientation, and
+ disability. Please remember that other attendees may have views
+ and beliefs that differ from your own - please try and respect
+ these.
+
+
+
+
+
+ Reporting Issues
+
+
+ If you feel uncomfortable or upset by another attendee’s
+ actions, please speak to the event host during the event, or
+ send a message at{" "}
+
+ support@adhdcommunity.com
+ {" "}
+ after the event has taken place.
+
+ );
+};
diff --git a/frontend/src/data/communityData.json b/frontend/src/data/communityData.json
new file mode 100644
index 000000000..4ed8413d1
--- /dev/null
+++ b/frontend/src/data/communityData.json
@@ -0,0 +1,23 @@
+[
+ {
+ "id": 1,
+ "name": "John Doe",
+ "bio": "Loves helping others and playing guitar.",
+ "role": "Listener",
+ "image": "/images/john.jpg"
+ },
+ {
+ "id": 2,
+ "name": "Jake Smith",
+ "bio": "Enjoys reading and sharing experiences.",
+ "role": "Seeker",
+ "image": "/images/Villads.jpg"
+ },
+ {
+ "id": 3,
+ "name": "Alice Johnson",
+ "bio": "Passionate about mental health awareness.",
+ "role": "Listener",
+ "image": "/images/alice.jpg"
+ }
+]
\ No newline at end of file
diff --git a/frontend/src/data/events.json b/frontend/src/data/events.json
new file mode 100644
index 000000000..7398662cf
--- /dev/null
+++ b/frontend/src/data/events.json
@@ -0,0 +1,42 @@
+[
+ {
+ "title": "How to Plan Your Days with ADHD",
+ "description": "Join us for an interactive session where we'll explore various strategies and tools to help you plan and organize your days more effectively with ADHD.",
+ "imageUrl": "/images/plan-event.jpg",
+ "details": {
+ "time": "2:00 PM - 4:00 PM",
+ "place": "Conference Room A",
+ "info": "This workshop is ideal for anyone struggling with time management due to ADHD. We'll cover planning methods that accommodate impulsivity and fluctuating motivation."
+ }
+ },
+ {
+ "title": "Social Activities for ADHD",
+ "description": "Engage in fun and supportive social activities specifically designed for individuals with ADHD. Meet new friends, build a community, and enjoy a relaxed, understanding environment where you can be yourself.",
+ "imageUrl": "/images/social-event.jpg",
+ "details": {
+ "time": "10:00 AM - 12:00 PM",
+ "place": "Community Center",
+ "info": "Our event features team games, creative workshops, and discussions that are tailored to encourage interaction in a pressure-free setting."
+ }
+ },
+ {
+ "title": "Mindfulness and ADHD",
+ "description": "Explore mindfulness techniques to help manage ADHD symptoms more effectively. This session will guide you through methods to improve your focus, emotional regulation, and overall mental well-being. Learn to navigate daily challenges with a mindful approach that can be integrated seamlessly into your lifestyle.",
+ "imageUrl": "/images/mindful-event.jpg",
+ "details": {
+ "time": "2:00 PM - 4:00 PM",
+ "place": "Yoga Studio",
+ "info": "Participants will learn grounding techniques, breathing exercises, and daily mindfulness practices suited for managing impulsivity and anxiety."
+ }
+ },
+ {
+ "title": "ADHD Support Group",
+ "description": "Join our support group to share experiences, tips, and support with others living with ADHD. This regular meeting offers a safe space to discuss challenges, celebrate achievements, and learn from each other in a supportive and non-judgmental environment.",
+ "imageUrl": "/images/support-event.jpg",
+ "details": {
+ "time": "5:00 PM - 7:00 PM",
+ "place": "Library Hall",
+ "info": "The group is facilitated by experienced counselors who specialize in ADHD, providing insights into coping strategies and behavioral techniques."
+ }
+ }
+]
\ No newline at end of file
diff --git a/frontend/src/data/testimonials.json b/frontend/src/data/testimonials.json
new file mode 100644
index 000000000..fc7696448
--- /dev/null
+++ b/frontend/src/data/testimonials.json
@@ -0,0 +1,42 @@
+[
+ {
+ "name": "Jane Doe",
+ "review": "This community has been a lifesaver. Connecting with others who understand ADHD has made such a difference in my life.",
+ "rating": 5
+ },
+ {
+ "name": "John Smith",
+ "review": "Finding someone to talk to when I'm having a hard day has been invaluable. Thank you for creating this space.",
+ "rating": 4
+ },
+ {
+ "name": "Emily Tran",
+ "review": "The resources and people here have helped me manage my symptoms and feel less alone in my struggles.",
+ "rating": 5
+ },
+ {
+ "name": "Mark Johnson",
+ "review": "I've learned so much about managing ADHD through the workshops and events offered here.",
+ "rating": 4
+ },
+ {
+ "name": "Sarah Lee",
+ "review": "Everyone is so supportive and understanding. It's comforting to be part of such a nurturing community.",
+ "rating": 5
+ },
+ {
+ "name": "Michael Brown",
+ "review": "The practical tips and strategies shared by the community have been extremely helpful.",
+ "rating": 4
+ },
+ {
+ "name": "Lisa Marie",
+ "review": "I appreciate the sense of belonging and acceptance I've found in this community.",
+ "rating": 5
+ },
+ {
+ "name": "David Wilson",
+ "review": "It's refreshing to meet so many people who genuinely understand what it's like to live with ADHD.",
+ "rating": 4
+ }
+]
\ No newline at end of file
diff --git a/frontend/src/index.css b/frontend/src/index.css
index e69de29bb..747c55fd5 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -0,0 +1,27 @@
+@import url("https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&family=STIX+Two+Text:wght@400;700&display=swap");
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ --link-color: #191818;
+ --link-hover-color: #d1510a;
+}
+
+p {
+ @apply font-serif;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ @apply font-sans;
+}
+
+.link {
+ @apply text-link-color hover:text-link-hover-color;
+}
diff --git a/frontend/src/mainPage/FindOutMorePage.jsx b/frontend/src/mainPage/FindOutMorePage.jsx
new file mode 100644
index 000000000..8b50bafb2
--- /dev/null
+++ b/frontend/src/mainPage/FindOutMorePage.jsx
@@ -0,0 +1,96 @@
+import { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
+
+import { Button } from "../common/Button";
+import Footer from "../common/Footer";
+import Menu from "../common/Menu";
+import { AuthForm } from "../components/Auth/AuthForm";
+import { useModal } from "../components/Auth/ModalContext";
+
+export const FindOutMorePage = () => {
+ const { isAuthenticated, showModal } = useModal();
+ const navigate = useNavigate();
+ const [currentFact, setCurrentFact] = useState(0);
+
+ const facts = [
+ "Many adults with ADHD were not diagnosed as children.",
+ "ADHD in adults can affect job performance, relationships, and daily functioning.",
+ "Adults with ADHD may experience symptoms such as restlessness, difficulty in maintaining focus, and impulsiveness.",
+ "Therapy and medication can be effective in managing ADHD symptoms in adults.",
+ "Joining a support group can provide valuable connections and coping strategies.",
+ ];
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setCurrentFact((prevFact) => (prevFact + 1) % facts.length);
+ }, 8000);
+ return () => clearInterval(interval);
+ }, [facts.length]);
+
+ const handleAuthSuccess = () => {
+ navigate("/profile");
+ };
+
+ const handleRoleSelection = (type) => {
+ showModal();
+ };
+
+ return (
+
+
+
+
+
Did You Know?
+
+
+
+ {facts[currentFact]}
+
+
+
+
+
+
+
+
+
Roles in Our Community
+
+
+
+
+ Help Someone
+
+
+ As a listener, you provide support and understanding to those in
+ need. You offer a compassionate ear and empathetic response to
+ their challenges and experiences with ADHD.
+
+
+
+
+ Talk with Someone
+
+
+ As a seeker, you have the opportunity to express your thoughts
+ and feelings about living with ADHD. You can share your
+ experiences, seek advice, or simply connect with others who
+ understand your journey.
+
+
+
+
+ {!isAuthenticated && (
+
+
+ )}
+
+
+
+
+ );
+};
diff --git a/frontend/src/mainPage/HomePage.jsx b/frontend/src/mainPage/HomePage.jsx
new file mode 100644
index 000000000..5e50860e6
--- /dev/null
+++ b/frontend/src/mainPage/HomePage.jsx
@@ -0,0 +1,95 @@
+import heroImage from "/images/hero-image.jpg";
+import { useNavigate } from "react-router-dom";
+import { Button } from "../common/Button";
+import Footer from "../common/Footer";
+import Menu from "../common/Menu";
+import { AuthForm } from "../components/Auth/AuthForm";
+import { useModal } from "../components/Auth/ModalContext";
+import Testimonials from "./Testimonials";
+
+export const HomePage = () => {
+ const { showModal, isAuthenticated } = useModal();
+ const navigate = useNavigate();
+
+ const handleGetStartedClick = () => {
+ showModal(
+ navigate("/profile")} />
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
Welcome to the ADHD Connect
+
+ A safe space to share, connect, and find support
+
+
+
+
+
+
+
+
+ {!isAuthenticated && (
+
+
+
Why Join us?
+
+ Connect with others who understand your journey
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ Don't just take our word for it...
+
+
+
+
+
+
+
+
+
+
+ Join Our Upcoming Events
+
+
+ Discover events designed to help you connect, learn, and grow with
+ the ADHD community.
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/mainPage/Testimonials.jsx b/frontend/src/mainPage/Testimonials.jsx
new file mode 100644
index 000000000..0fb4a6cba
--- /dev/null
+++ b/frontend/src/mainPage/Testimonials.jsx
@@ -0,0 +1,85 @@
+import { useState } from "react";
+import testimonialsData from "../data/testimonials.json";
+
+const Testimonials = () => {
+ const [index, setIndex] = useState(0);
+
+ const nextTestimonial = () => {
+ setIndex((prevIndex) => (prevIndex + 1) % testimonialsData.length); // Loop back to the first
+ };
+
+ const prevTestimonial = () => {
+ setIndex(
+ (prevIndex) =>
+ (prevIndex - 1 + testimonialsData.length) % testimonialsData.length
+ ); // Loop to the last
+ };
+
+ return (
+