A full-stack campus repair marketplace connecting students who need repairs with skilled fixers, promoting sustainability and the circular economy.
Live Demo: https://fixit-bmsce.netlify.app
Backend API: https://fixit-01yy.onrender.com
- Project Overview
- Technology Stack
- System Architecture
- Features
- How It All Works Together
- Deployment Architecture
- Local Development Setup
- API Documentation
- Database Schema
- Key Concepts to Research
Fix-It Hub is a campus-based platform that solves a real problem: students need items repaired but don't know who can help. Instead of throwing things away, students can:
- Post repair requests (broken laptop, torn jeans, wobbly chair)
- Find skilled fixers (other students with repair skills)
- Communicate in-app (private messaging system)
- Track repair progress (status updates and completion)
Why it matters:
- β»οΈ Reduces waste and promotes sustainability
- π° Saves money (student-to-student pricing)
- π€ Builds community connections
- π Skill-sharing and learning opportunities
| Technology | Version | Purpose | Learn More |
|---|---|---|---|
| React | 18.2.0 | UI library for building interactive interfaces | React Docs |
| Vite | 5.0.8 | Fast build tool and dev server (replaces Create React App) | Vite Guide |
| React Router | 6.21.1 | Client-side routing (navigate without page reloads) | Router Tutorial |
| Axios | 1.6.5 | HTTP client for API calls | Axios Docs |
| Tailwind CSS | 3.4.1 | Utility-first CSS framework for styling | Tailwind CSS |
| Technology | Version | Purpose | Learn More |
|---|---|---|---|
| Node.js | 22.16.0 | JavaScript runtime for server-side code | Node.js Docs |
| Express | 4.21.2 | Web framework for building REST APIs | Express Guide |
| MongoDB | - | NoSQL database for storing data | MongoDB Tutorial |
| Mongoose | 8.9.3 | ODM (Object Data Modeling) for MongoDB | Mongoose Guide |
| JWT | 9.0.2 | JSON Web Tokens for authentication | JWT.io |
| bcryptjs | 2.4.3 | Password hashing for security | bcrypt Explained |
| CORS | 2.8.5 | Cross-Origin Resource Sharing (lets frontend talk to backend) | CORS Explained |
| Service | Purpose | Free Tier | Learn More |
|---|---|---|---|
| Netlify | Hosts React frontend | 100GB bandwidth/month | Netlify Docs |
| Render | Hosts Node.js backend | 750 hours/month | Render Docs |
| MongoDB Atlas | Cloud database | 512MB storage | Atlas Guide |
| GitHub | Version control & auto-deployment | Unlimited public repos | Git Handbook |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER'S BROWSER β
β (https://fixit-bmsce.netlify.app) β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β HTTP Requests (AJAX/Axios)
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β FRONTEND (React + Vite) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Components: β β
β β - Navbar, Footer, SearchBar β β
β β - ListingCard, SkillProfileCard β β
β β β β
β β Pages: β β
β β - HomePage, BrowseListingsPage, LoginPage β β
β β - ProfilePage, MessagesPage, ConversationPage β β
β β β β
β β Services (API Calls): β β
β β - api.js (axios setup + interceptors) β β
β β - userService.js (login, register, profile) β β
β β - listingService.js (CRUD operations) β β
β β - messageService.js (chat functionality) β β
β β β β
β β Context (Global State): β β
β β - AuthContext.jsx (user auth state) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β API Calls (REST)
β Example: POST /api/users/login
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β BACKEND (Node.js + Express) β
β (https://fixit-01yy.onrender.com) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β server.js (Entry Point) β β
β β - CORS configuration β β
β β - Body parsing (JSON, up to 10MB for images) β β
β β - Route mounting β β
β ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ β
β β Routes (API Endpoints): β β
β β - /api/users (login, register, profile, update) β β
β β - /api/listings (create, read, update, delete) β β
β β - /api/messages (conversations, send, read) β β
β ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ β
β β Middleware: β β
β β - authMiddleware.js (JWT verification, protect routes) β β
β ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ β
β β Controllers (Business Logic): β β
β β - userController.js (auth, profile updates) β β
β β - listingController.js (CRUD, filtering) β β
β β - messageController.js (chat logic) β β
β ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ β
β β Models (Database Schemas): β β
β β - User.js (users, auth, skills, badges) β β
β β - Listing.js (repair requests, status, category) β β
β β - Message.js (conversations, messages) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
β Mongoose Queries
β (CREATE, READ, UPDATE, DELETE)
β
ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β DATABASE (MongoDB Atlas) β
β (Cloud Hosted) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Collections: β β
β β - users (authentication, profiles, skills) β β
β β - listings (repair requests, images, status) β β
β β - messages (conversations, chat history) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- β Register with email & password
- β Login with JWT token (stored in localStorage)
- β Password hashing with bcrypt (12 salt rounds)
- β Protected routes (can't access profile without login)
- β Auto-logout on token expiration
- β Create repair requests with photos (base64 encoding)
- β Browse all listings with search & filters
- β Category filtering (Tech, Clothing, Furniture, Other)
- β Status tracking (Available, In Progress, Completed)
- β Edit and delete your own listings
- β Clickable cards for detailed view
- β In-platform private messaging (no email needed)
- β Conversation threads per listing
- β Real-time message display with timestamps
- β Unread message counts
- β Message read/unread status
- β Auto-scroll to latest message
- β Upload profile pictures (base64, max 5MB)
- β Add/edit skills (e.g., "Soldering", "Sewing")
- β Display badges and stats
- β View your listings (Available vs In Progress)
- β Clickable usernames to view profiles
- β Real-time search across listings
- β Filter by category
- β Find skilled fixers page
- β Stats dashboard (total repairs, items saved, CO2 reduced)
- User enters email/password β React form captures input
- Frontend calls API β
userService.login()sends POST requestPOST https://fixit-01yy.onrender.com/api/users/login Body: { email: "student@college.edu", password: "password123" }
- Backend receives request β Express routes to
userController.loginUser() - Controller validates β Checks MongoDB for user, compares hashed password
- JWT token generated β Backend creates signed token with user ID
- Response sent β Backend returns
{ token, user }JSON - Frontend stores token β Saved in
localStorageandAuthContext - Future requests authenticated β Axios interceptor adds
Authorization: Bearer <token>header
- User selects image β
<input type="file">triggers - FileReader converts to base64 β Browser reads file as data URL
data:image/jpeg;base64,/9j/4AAQSkZJRg...
- Size validation β Check if < 5MB (frontend), < 10MB (backend)
- API call with base64 β
userService.updateUserProfile({ photoUrl: base64String }) - Backend validates β Checks if string starts with
data:image/ - Mongoose saves to MongoDB β Stored as string in user document
- Frontend updates β AuthContext updates, component re-renders with new photo
- User A clicks "Message" on listing β Navigates to conversation page
- Frontend fetches conversation β
GET /api/messages/conversation/:listingId/:userId - Backend finds or creates β Mongoose searches for existing conversation
- User A types message β Form captures text input
- Frontend sends message β
POST /api/messages/:conversationId - Backend saves to DB β Adds message to messages array in conversation document
- Frontend refetches β Gets updated conversation with new message
- User B opens inbox β Sees unread count, clicks conversation
- Mark as read triggered β
PUT /api/messages/:conversationId/read
GitHub (Code Storage)
β
βββ Netlify (Detects push to main branch)
β ββ Runs: npm install
β ββ Runs: npm run build (Vite builds React to /dist)
β ββ Deploys: Serves static files from /dist
β ββ URL: https://fixit-bmsce.netlify.app
β
βββ Render (Detects push to main branch)
ββ Runs: npm install (in /server directory)
ββ Runs: node server.js
ββ Environment: Loads MONGODB_URI, JWT_SECRET, etc.
ββ URL: https://fixit-01yy.onrender.com
MongoDB Atlas (Always Online)
ββ Connection: Accepts connections from Render's IP (0.0.0.0/0)
ββ Database: fixithub
ββ Collections: users, listings, messages
Environment Variables (Hidden Secrets)
Netlify (Frontend):
VITE_API_URL=https://fixit-01yy.onrender.com/api- Tells React where the backend API is located
VITE_prefix required for Vite to expose to browser
Render (Backend):
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/fixithub
JWT_SECRET=super-secret-random-string-for-signing-tokens
NODE_ENV=production
PORT=5000
CLIENT_URL=https://fixit-bmsce.netlify.appMONGODB_URI: Database connection stringJWT_SECRET: Used to sign/verify authentication tokensCLIENT_URL: Allowed origin for CORS (security)
- You push code β
git push origin main - GitHub receives β Code stored in repository
- Netlify webhook triggered β Detects new commit
- Clones repo
- Installs dependencies (
npm install) - Builds React app (
npm run buildβ creates/distfolder) - Deploys static files to CDN
- Result: https://fixit-bmsce.netlify.app updated
- Render webhook triggered β Detects new commit
- Clones repo
- Enters
/serverdirectory - Installs dependencies (
npm install) - Starts server (
node server.js) - Result: https://fixit-01yy.onrender.com restarted
- Both live in ~2 minutes! π
| Aspect | Explanation |
|---|---|
| Separation of Concerns | Frontend and backend deployed independently |
| Static Frontend | React builds to HTML/CSS/JS files (fast CDN delivery) |
| Dynamic Backend | Node.js server handles business logic and database |
| Scalability | Each part can scale independently |
| Security | API keys and secrets hidden in environment variables |
| Cost | All three platforms free for small projects! |
- Node.js 22.16.0+ (Download)
- npm (comes with Node.js)
- MongoDB (local) or MongoDB Atlas account
- Git
# 1. Clone the repository
git clone https://github.com/GlyphicGuy/fixIt.git
cd fixIt
# 2. Install frontend dependencies
npm install
# 3. Install backend dependencies
cd server
npm install
cd ..
# 4. Create environment file
cat > .env << EOF
PORT=5000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/fixithub
JWT_SECRET=your-dev-secret-key
CLIENT_URL=http://localhost:5173
EOF
# 5. Start MongoDB (if using local)
# macOS/Linux: brew services start mongodb-community
# Windows: net start MongoDB
# 6. Start backend (in one terminal)
cd server
npm run dev # Uses nodemon for auto-restart
# 7. Start frontend (in another terminal)
npm run dev # Runs on http://localhost:5173fixIt/
βββ public/ # Static assets
βββ src/ # Frontend React code
β βββ components/ # Reusable UI components
β βββ pages/ # Route pages
β βββ services/ # API call functions
β βββ context/ # Global state (Auth)
β βββ assets/ # Images, icons
β βββ main.jsx # React entry point
βββ server/ # Backend Node.js code
β βββ models/ # Mongoose schemas
β βββ controllers/ # Business logic
β βββ routes/ # API endpoints
β βββ middleware/ # Auth middleware
β βββ config/ # Database connection
β βββ server.js # Express entry point
βββ .env # Environment variables (gitignored)
βββ package.json # Frontend dependencies
βββ vite.config.js # Vite configuration
βββ netlify.toml # Netlify deployment config
- Production:
https://fixit-01yy.onrender.com/api - Development:
http://localhost:5000/api
Create a new user account.
Request Body:
{
"name": "John Doe",
"email": "john@college.edu",
"password": "securepassword123"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"_id": "abc123",
"name": "John Doe",
"email": "john@college.edu"
}
}Authenticate existing user.
Request Body:
{
"email": "john@college.edu",
"password": "securepassword123"
}Response: Same as register
Get all repair listings (with optional filters).
Query Parameters:
category(optional): Tech, Clothing, Furniture, Othersearch(optional): Search in title/description
Response:
[
{
"_id": "listing123",
"title": "Broken Laptop Screen",
"description": "MacBook Air 2020, cracked display",
"category": "Tech",
"status": "Available",
"photoUrl": "data:image/jpeg;base64,...",
"postedBy": {
"_id": "user123",
"name": "Jane Doe"
},
"createdAt": "2025-12-29T10:30:00.000Z"
}
]Create a new listing (requires authentication).
Headers:
Authorization: Bearer <your-jwt-token>
Request Body:
{
"title": "Torn Jeans Need Patching",
"description": "Ripped at the knee, blue denim",
"category": "Clothing",
"photoUrl": "data:image/jpeg;base64,..."
}Get all conversations for logged-in user.
Get or create a conversation between two users about a listing.
Send a message in a conversation.
Request Body:
{
"content": "Hi, can you fix this by Friday?"
}π = Requires Authorization: Bearer <token> header
{
_id: ObjectId("..."),
name: "John Doe",
email: "john@college.edu",
password: "$2a$12$hashed...", // bcrypt hashed
photoUrl: "data:image/jpeg;base64,...", // optional
skills: ["Soldering", "Screen Replacement"], // optional array
createdAt: ISODate("2025-12-01T..."),
updatedAt: ISODate("2025-12-29T...")
}{
_id: ObjectId("..."),
title: "Broken Laptop Screen",
description: "MacBook Air 2020, cracked display",
category: "Tech", // enum: Tech, Clothing, Furniture, Other
status: "Available", // enum: Available, In Progress, Completed
photoUrl: "data:image/jpeg;base64,...",
postedBy: ObjectId("user123"), // reference to Users
createdAt: ISODate("2025-12-29T..."),
updatedAt: ISODate("2025-12-29T...")
}{
_id: ObjectId("..."),
listing: ObjectId("listing123"), // reference to Listings
participants: [ObjectId("user1"), ObjectId("user2")],
messages: [
{
sender: ObjectId("user1"),
content: "Can you fix this?",
read: false,
timestamp: ISODate("2025-12-29T10:00:00Z")
},
{
sender: ObjectId("user2"),
content: "Yes, I can help!",
read: true,
timestamp: ISODate("2025-12-29T10:05:00Z")
}
],
lastMessageAt: ISODate("2025-12-29T10:05:00Z"),
createdAt: ISODate("2025-12-29T09:50:00Z")
}Here's what you should understand to fully grasp this project:
| Concept | What to Learn | Why It Matters |
|---|---|---|
| React Components | Functional components, props, state | Building blocks of the UI |
| React Hooks | useState, useEffect, useContext | Manage state and side effects |
| React Router | Routes, navigation, URL parameters | Multi-page feel without page reloads |
| Context API | Global state management | Share auth state across components |
| Axios Interceptors | Request/response middleware | Auto-add auth tokens to requests |
| Base64 Encoding | Binary data β text string | Store images in database as text |
| Tailwind CSS | Utility classes, responsive design | Fast styling without writing CSS |
| Vite | Build tool, HMR, environment variables | Faster than Webpack, modern tooling |
| Concept | What to Learn | Why It Matters |
|---|---|---|
| REST API | HTTP methods, status codes, endpoints | How frontend and backend communicate |
| Express Middleware | Request pipeline, next() | Process requests before reaching routes |
| JWT (JSON Web Tokens) | Token structure, signing, verification | Stateless authentication |
| bcrypt | Hashing, salts, rainbow tables | Secure password storage |
| Mongoose | Schemas, models, queries | Object-oriented MongoDB interaction |
| CORS | Same-origin policy, preflight requests | Allow cross-domain API calls |
| Environment Variables | .env files, process.env | Hide secrets, configure environments |
| Async/Await | Promises, error handling | Handle asynchronous operations |
| Concept | What to Learn | Why It Matters |
|---|---|---|
| NoSQL vs SQL | Document vs relational databases | Why MongoDB for this project |
| MongoDB Documents | JSON-like structure, flexibility | How data is stored |
| Mongoose Schemas | Schema definition, validation | Enforce data structure in NoSQL |
| References | ObjectId, populate() | Link documents together |
| Indexing | Query optimization | Fast lookups on participants |
| Concept | What to Learn | Why It Matters |
|---|---|---|
| Git & GitHub | Version control, branches, commits | Track changes, collaborate |
| CI/CD | Continuous integration/deployment | Auto-deploy on git push |
| Static vs Dynamic Hosting | File serving vs server execution | Why Netlify β Render |
| Environment Variables | Config management, secrets | Different settings per environment |
| CDN | Content delivery networks | Fast global asset delivery |
| Webhooks | Event-driven triggers | GitHub β Netlify/Render communication |
| Concept | What to Learn | Why It Matters |
|---|---|---|
| Password Hashing | One-way encryption, salts | Never store plain passwords |
| JWT Security | Token expiration, secret keys | Prevent token forgery |
| CORS Policy | Origin whitelist, credentials | Prevent malicious sites accessing API |
| .gitignore | Exclude sensitive files | Don't commit secrets to GitHub |
| HTTPS | SSL/TLS, encryption | Secure data in transit |
- β HTML/CSS/JavaScript fundamentals
- β React basics (components, props, state)
- β React Hooks (useState, useEffect)
- β React Router (navigation)
- β Axios (API calls)
- β Node.js fundamentals
- β Express.js (routes, middleware)
- β MongoDB basics (CRUD operations)
- β Mongoose (schemas, models)
- β REST API design
- β JWT concept and implementation
- β bcrypt password hashing
- β Protected routes (middleware)
- β Context API for global auth state
- β File uploads (base64 encoding)
- β Real-time features (messaging)
- β Search and filtering
- β CORS configuration
- β Git and GitHub
- β Environment variables
- β Netlify deployment (static sites)
- β Render deployment (Node.js apps)
- β MongoDB Atlas (cloud database)
Ideas to expand the project:
- Real-time messaging (Socket.io for instant updates)
- Image compression (Reduce base64 size before upload)
- Email notifications (Nodemailer for new messages)
- Rating system (5-star reviews for fixers)
- Payment integration (Stripe for transactions)
- Admin dashboard (Moderate listings and users)
- Mobile app (React Native version)
- PWA (Progressive Web App for offline support)
- Search autocomplete (ElasticSearch integration)
- Image storage (AWS S3 instead of base64)
This is a learning project! Feel free to:
- Report bugs
- Suggest features
- Fork and experiment
- Ask questions
This project is open source and available for educational purposes.
Built as a campus sustainability project to promote the circular economy and reduce waste through student collaboration.
Live Site: https://fixit-bmsce.netlify.app
API Health Check: https://fixit-01yy.onrender.com/api/health
For questions about the codebase, refer to the guides:
DEPLOYMENT_GUIDE.md- Detailed deployment instructionsQUICK_DEPLOY.md- 30-minute deployment summaryMESSAGING_SYSTEM.md- How the chat system worksPROFILE_PICTURE_UPLOAD.md- Image upload implementation
Built with β€οΈ by students, for students π
- Home Page - Browse repair listings with search, category filtering, stats dashboard, and featured fixers
- Listing Detail Page - View complete listing information, contact fixers, and see interested helpers
- New Listing Page - Post repair requests with photos, descriptions, and categories
- Profile Page - Manage skills, view badges, and track your repair listings
- Navbar - Responsive navigation with routing
- Footer - Site-wide footer with links and contact info
- ListingCard - Display repair requests with images and status
- SkillProfileCard - Show fixer profiles with ratings and badges
- SearchBar - Real-time search functionality
- StatsSection - Platform impact statistics
- HowItWorks - Step-by-step guide for users
- Node.js 22.12 or higher
- npm or yarn
- Clone the repository
git clone <your-repo-url>
cd fixIt- Install dependencies
npm install- Start the development server
npm run dev- Open your browser and visit
http://localhost:5173
To view and inspect the MongoDB database in your browser:
-
Make sure the backend server is running (
npm run devin theserverdirectory) -
Open
server/db-viewer.htmlin your browser or visit it directly:
open server/db-viewer.html
# or on Linux: xdg-open server/db-viewer.html
# or just drag the file into your browserThe database viewer provides:
- Live Statistics - Total users, listings, open/fixed counts
- Users Collection - View all users with their skills, ratings, and activity
- Listings Collection - Browse all listings with status, interested fixers, and details
- Table & JSON Views - Toggle between formatted table and raw JSON data
- Real-time Refresh - Update data with the refresh button
API Endpoints:
GET /api/db/stats- Database statisticsGET /api/db/users- All users (passwords excluded)GET /api/db/listings- All listings with populated references
- Frontend Framework: React 18 with Vite
- Styling: Tailwind CSS 3
- Routing: React Router DOM
- Backend (Planned): Node.js, Express, MongoDB
fixIt/
βββ src/
β βββ components/ # Reusable UI components
β β βββ Navbar.jsx
β β βββ Footer.jsx
β β βββ ListingCard.jsx
β β βββ SkillProfileCard.jsx
β β βββ SearchBar.jsx
β β βββ StatsSection.jsx
β β βββ HowItWorks.jsx
β βββ pages/ # Main application pages
β β βββ HomePage.jsx
β β βββ ListingDetailPage.jsx
β β βββ NewListingPage.jsx
β β βββ ProfilePage.jsx
β βββ data/ # Mock data (will be replaced with API calls)
β β βββ mockData.js
β βββ App.jsx # Main app component with routes
β βββ main.jsx # Entry point
β βββ index.css # Global styles
βββ public/ # Static assets
βββ package.json # Dependencies and scripts
- Name, email, photo
- Array of skills (e.g., "Sewing", "Soldering", "Bike Repair")
- Badges earned
- Rating and fixes completed
- Title, description, category
- Photo URL
- Status ('open', 'fixed')
- Posted by (user reference)
- Posted date
- Tech - Electronics, computers, phones
- Clothing - Sewing, mending, alterations
- Furniture - Woodworking, assembly, repairs
- Other - Bikes, sports equipment, misc items
- User authentication (oAuth Google)
- Email notifications
- Booking/scheduling system
- Image before/after
- Mobile app version
This is a college project. Contributions and suggestions are welcome!
npm run dev- Start development servernpm run build- Build for productionnpm run preview- Preview production buildnpm run lint- Run ESLint
Fix-It Hub promotes the circular economy by:
- Reducing waste through repair instead of replacement
- Building a skill-sharing community
- Extending the life of products
- Educating students about sustainability
- Creating a culture of resourcefulness
For questions or feedback, contact us at support@fixithub.edu
Copyright 2026