# Project export: ConnectHer

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2025
- Tagline: ConnectHer is a platform that helps women connect, learn, and grow through mentorship, networking, and shared experiences. Find support, build skills, and empower each other—anytime, anywhere!
- Devpost: https://devpost.com/software/connecther-3bnhze
- GitHub: https://github.com/aayahosman/TreeHacks-Project.git
- Demo: https://www.figma.com/design/ck49Gyz99y8R9G5eNm1mht/TreeHacks-App?node-id=13-1443&t=IyWq8WAGR6ZKwyyw-1
- Video: https://www.youtube.com/embed/enFZciOQXG8?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — Aayah Osman (37 commits), vichedanarith (13 commits), zshakirova (7 commits)

## Devpost submission (written by the team)

### Inspiration

Women often face barriers in networking, mentorship, and career growth due to limited access to supportive communities. We created ConnectHer to foster meaningful connections, mentorship, and skill-building, empowering women at every stage of their journey.

### What it does

ConnectHer helps women find mentors, connect with peers, join communities, and access valuable resources for personal and professional growth. Users can match with mentors, discover like-minded peers, share experiences, and build lasting support networks.

### How we built it

We developed ConnectHer using React for the front end to ensure a seamless and interactive user experience. The backend is powered by MongoDB, Node.js, Express, Zoom API, and JavaScript. As well as an attempt at Redis database.

### Challenges we ran into

We faced challenges with database complexity, integrating the Zoom API (but we got it working—yay!), and using AI for web scraping.

### Accomplishments we're proud of

We’re proud of how much we learned, especially as a team new to full-stack development. We successfully tackled key technical challenges and got most of our features working!

### What we learned

We gained experience with databases, storage, and full-stack development. While most of our prior experience was in frontend/UI, this project helped us expand our technical skills.

### What's next

Integrate Backend with Frontend: Test the API endpoints for user interactions. User Profiles & Data Storage: How will users input preferences and see recommendations? Testing & Feedback: Once the matching system is live, test it with real users.

## README (from the GitHub repository)

# ConnectHer

By Aayah Osman, Jasmine Ma, Vicheda Narith, Zhamilya Shakirova 
### **Empowering Women Through Learning & Mentorship**  

ConnectHer is a **web application** designed to connect women with **mentors, mentees, and study partners** through a **smart matching system**. It supports **all subjects** and **experience levels**, fostering a space for learning, collaboration, and empowerment.  

🔍 **Matches are based on:**  
✅ Interests  
✅ Availability  
✅ Learning & career goals  

---

## **🌍 Our Inspiration**  
Women make up **more than two-thirds of the world's 796 million illiterate people**. Many lack **resources and access to mentors**—especially those from **third-world countries and underrepresented backgrounds**.  

🚀 **With ConnectHer, women can:**  
- Find **mentors & friends** with shared experiences  
- **Learn through communication & resource-sharing**  
- **Build a supportive global community**  

We aim to **improve the learning experience for women worldwide**, fostering **education, mentorship, and connections** that can change lives.  

---

## **🛠️ Tools & Prizes**  

### 🤖 **Google Gemini AI**  
✅ We leveraged **Google Gemini AI** to enhance various aspects of our application:  
- **Frontend Development:** Used Gemini AI to **generate UI components and improve design consistency**.  
- **Smart Matching Algorithm:** Implemented **AI-powered swiping logic** to intelligently pair users based on **interests, goals, and availability**.  
- **Content Assistance:** Used Gemini AI to **generate educational resources and conversational AI assistance** for mentorship guidance.

### **🎥 Zoom - Best Use of Zoom APIs**   
We integrated **Zoom’s API** to facilitate **real-time mentorship sessions, group discussions, and networking events**.  
✅ Users can schedule and join **one-on-one or group mentorship calls** without leaving the platform.  
✅ Zoom’s features help create an **engaging, seamless communication experience** for mentors and mentees.

### 🔍 **Perplexity AI**  
✅ **Perplexity AI** played a key role in our **development process**, assisting with:  
- **Code Generation & Debugging:** Provided **optimized solutions for frontend and backend challenges**.  
- **Idea Brainstorming:** Helped us refine our **user experience (UX) and feature design**.
- Help with **swiping and matching** profiles 

### 🛠️ Codegen 
🏆 Using **developer tools & AI** for:  
- Improved **code efficiency**  
- Advanced **static analysis & UI enhancements**  

### **🎨 LumaLabs - Reimagining Visual Creation with AI**  🏆 **Exploring generative AI for:**  
- **Visual storytelling & interactive experiences**  
- **Transforming text, images, and video for learning & mentorship**   


## Detected evidence (automated analysis)

Indexed codebase: 43 recognized source files, 53 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- MongoDB (technology) — detected in the code
- React (technology) — detected in the code
- Next.js (technology) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (54 of 54)

```
client/.gitignore
client/package.json
client/postcss.config.js
client/public/index.html
client/public/manifest.json
client/public/robots.txt
client/src/App.css
client/src/App.js
client/src/App.test.js
client/src/components/Home.jsx
client/src/components/InterestedIn.jsx
client/src/components/Login.jsx
client/src/components/LookingFor.jsx
client/src/components/Matched.jsx
client/src/components/NavBar.jsx
client/src/components/SignUp.jsx
client/src/components/SwipeCard.js
client/src/components/SwipeCard.jsx
client/src/components/SwipeMatch.jsx
client/src/css/match.css
client/src/index.css
client/src/index.js
client/src/InterestedIn.css
client/src/json/profiles.json
client/src/Login.module.css
client/src/LookingFor.css
client/src/pages/Home.jsx
client/src/pages/Matches.jsx
client/src/pages/Messages.jsx
client/src/reportWebVitals.js
client/src/services/api.jsx
client/src/setupTests.js
client/src/SignUp.css
client/tailwind.config.js
package.json
README.md
server/.env
server/app.js
server/config/db.js
server/config/redis.js
server/controllers/swipecontroller.js
server/controllers/usercontroller.js
server/json/matches.json
server/json/messages.json
server/json/swipes.json
server/json/users.json
server/models/swipe.js
server/models/user.js
server/routes/swiperoutes.js
server/routes/userroutes.js
server/server.js
server/services/swipeservice.js
server/utils/responsehandler.js
server/zoom/zoom_service.js
```

### Dependencies

- client/package.json: @testing-library/dom@^10.4.0, @testing-library/jest-dom@^6.6.3, @testing-library/react@^16.2.0, @testing-library/user-event@^13.5.0, @zoom/videosdk@^2.1.5, @zoomus/websdk@^2.18.3, framer-motion@^12.4.3, lucide-react@^0.475.0, react@^19.0.0, react-dom@^19.0.0, react-icons@^5.4.0, react-router-dom@^7.1.5, react-scripts@5.0.1, web-vitals@^2.1.4
- package.json: axios@^1.7.9, base-64@^1.0.0, cors@^2.8.5, dotenv@^16.4.7, express@^4.21.2, mongoose@^8.10.1, node-fetch@^3.3.2, nodemon@^3.1.9

### Recent commits (newest first)

- Merge pull request #20 from aayahosman/work2
- everything working for now TT
- i messed up
- Update README.md
- Update README.md
- Update README.md
- Merge pull request #19 from aayahosman/aayahBranch
- Fix messages page
- Fix messages
- Merge pull request #18 from aayahosman/aayahBranch
- Added navbar to matched page
- Added navbar to matched page
- Merge pull request #17 from aayahosman/aayahBranch
- Finished frontend
- Merge pull request #16 from aayahosman/aayahBranch
- Fixing minor youre matched page
- Minor fixes for youre matched
- Merge pull request #15 from aayahosman/aayahBranch
- Finalizing frontend
- Merge pull request #14 from aayahosman/vee

## Key source files (fetched from GitHub, selected and truncated for size)

### package.json

```
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "type": "module",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.7.9",
    "base-64": "^1.0.0",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^4.21.2",
    "mongoose": "^8.10.1",
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "nodemon": "^3.1.9"
  }
}
```

### client/package.json

```
{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/dom": "^10.4.0",
    "@testing-library/jest-dom": "^6.6.3",
    "@testing-library/react": "^16.2.0",
    "@testing-library/user-event": "^13.5.0",
    "@zoom/videosdk": "^2.1.5",
    "@zoomus/websdk": "^2.18.3",
    "framer-motion": "^12.4.3",
    "lucide-react": "^0.475.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-icons": "^5.4.0",
    "react-router-dom": "^7.1.5",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

### server/server.js

```javascript
import 'dotenv/config';
import { connectDB } from './config/db.js';
import app from './app.js'; // Import the app from app.js

// ✅ Connect to MongoDB
connectDB();

// ✅ Start Express Server
const PORT = process.env.PORT || 5001;
app.listen(PORT, () => console.log(`🚀 Server running on port ${PORT}`));


```

### server/app.js

```javascript
import express from 'express';
import cors from 'cors';
import fs from 'fs';
import { generateZoomMeeting } from './zoom/zoom_service.js';
import userRoutes from './routes/userroutes.js';
import swipeRoutes from './routes/swiperoutes.js';

const app = express();
app.use(express.json());
app.use(cors()); // Enable CORS for frontend access

// Helper function to read JSON data from the 'json' folder
const readJsonFile = (filePath) => {
    const fullPath = `./json/${filePath}`;
    if (!fs.existsSync(fullPath)) {
        // If file doesn't exist, return an empty array
        return [];
    }
    const data = fs.readFileSync(fullPath, 'utf-8');
    return JSON.parse(data);
};

// Helper function to write to JSON file in the 'json' folder
const writeJsonFile = (filePath, data) => {
    const fullPath = `./json/${filePath}`;
    fs.writeFileSync(fullPath, JSON.stringify(data, null, 2));
};


// ✅ Default route
app.get('/', (req, res) => {
    res.send('Server is running!');
});

// ✅ User & Swipe Routes
app.use('/api/users', userRoutes);
app.use('/api/swipes', swipeRoutes);

// ✅ Zoom API Route
app.post('/api/zoom/create-meeting', async (req, res) => {
    try {
        const { topic } = req.body;
        const meeting = await generateZoomMeeting(topic || 'Default Meeting');
        res.json(meeting);
    } catch (error) {
        console.error('Error creating Zoom meeting:', error);
        res.status(500).json({ error: 'Failed to create Zoom meeting' });
    }
});

// Route to register a new user (for demo, we just add the user to the JSON file)
app.post('/register', (req, res) => {
    console.log('Received request body:', req.body);  // Log the incoming request body
    const users = readJsonFile('users.json');
    const newUser = req.body;
    users.push(newUser);
    writeJsonFile('users.json', users);
    res.status(201).send({ message: 'User registered successfully', newUser });
});


// Route for swiping (left or right)
app.post('/swipe', (req, res) => {
    const { userId, profileId, direction } = req.body;
    const swipes = readJsonFile('swipes.json');
    const newSwipe = { userId, profileId, direction, createdAt: new Date().toISOString() };
    
    // Save the swipe
    swipes.push(newSwipe);
    writeJsonFile('swipes.json', swipes);

    // Check for a match if the swipe is 'right'
    if (direction === 'right') {
        const oppositeSwipe = swipes.find(swipe => swipe.userId === profileId && swipe.profileId === userId && swipe.direction === 'right');
        if (oppositeSwipe) {
            const matches = readJsonFile('matches.json');
            const newMatch = { userId, profileId, createdAt: new Date().toISOString() };
            matches.push(newMatch);
            writeJsonFile('matches.json', matches);
            res.status(200).send({ message: 'It\'s a match!' });
        } else {
            res.status(200).send({ message: 'Swipe recorded' });
        }
    } else {
        res.status(200).send({ message: 'Swipe recorded' });
    }
});

// Route for sending messages
app.post('/message', (req, res) => {
    const { matchId, senderId, receiverId, content } = req.body;
    const messages = readJsonFile('messages.json');
    const newMessage = { matchId, senderId, receiverId, content, createdAt: new Date().toISOString() };
    messages.push(newMessage);
    writeJsonFile('messages.json', messages);
    res.status(200).send({ message: 'Message sent successfully' });
});

export default app;
```

### client/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

```

### client/src/App.js

```javascript
import React, { useState } from "react";
import SwipeMatch from "./components/SwipeMatch";
import Home from "./components/Home";
import Login from "./components/Login.jsx";
import Profile from "./components/SignUp.jsx";
import LookingFor from './components/LookingFor.jsx';
import Matched from './components/Matched.jsx';
import profilesData from "./json/profiles.json";
import InterestedIn from "./components/InterestedIn.jsx";
import { Route, Routes, BrowserRouter } from "react-router-dom";
import Messages from "./pages/Messages";


const App = () => {
  const [profilesQueue, setProfilesQueue] = useState(profilesData);

  return (
    <BrowserRouter>
    <div className="container">
        <Routes>
          <Route path = "matched" element={<Matched />} />
          <Route path="/" element={<Home />}></Route>
          <Route path="/profile" element={<Profile />} />
          <Route path="/messages" element={<Messages />} />
          <Route path="/login" element={<Login />} />
          <Route path="/InterestedIn" element={<InterestedIn />} />
          <Route path="/profile/lookingfor" element={<LookingFor />} />
          <Route path="/swipe-match" element={<SwipeMatch />} />
          {/* <Route path="/zoom-meeting" element={<ZoomMeeting />} /> */}
        </Routes>
    </div>
    </BrowserRouter>
  );
};

export default App;

```

### client/postcss.config.js

```javascript
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

```

### client/tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

### client/src/setupTests.js

```javascript
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

```

### client/src/App.test.js

```javascript
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});

```

[34 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]