Skip to content

Advanced-Computer-Lab-2025/Bindly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

683 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Bindly

A unified, role-aware, capacity-safe, university-specific event management platform for students, professors, staff, vendors, and administrators.

Bindly is a comprehensive campus web application built to centralize university event operations and campus stakeholder workflows into one smart system.
Its main purpose is to handle event creation, approval transparency, capacity-safe registration, document-verified vendor onboarding, real-time notifications, and campus bookings (courts & gym sessions) β€” reducing operational chaos and human errors while improving collaboration and efficiency across the university.

πŸš€ Motivation

We built Bindly to remove the fragmentation and operational chaos that happens when campus event workflows are managed across different groups and tools.
It solves the lack of coordination between:

  • Students
  • Professors
  • Teaching Assistants
  • University Staff
  • Vendors
  • Administrators
  • Event Office

Bindly introduces:

  • A structured approval and edit–request workflow
  • Capacity-safe event registration
  • Role-based event access and restrictions
  • Centralized communication and transparency
  • Vendor onboarding with verified documents
  • Real-time notifications and centralized dashboards

This platform is important because it:

βœ… saves time
βœ… reduces human errors
βœ… ensures transparency
βœ… improves collaboration
βœ… organizes data reliably
βœ… and makes campus operations smoother and more dependable.

🚧 Build Status

The Bindly platform is fully developed, operational, and stable with all core and optional modules implemented successfully.
The system has undergone end-to-end workflow testing, including event approvals, capacity-safe registration, vendor onboarding, payment webhooks, and notification delivery, and is now ready for deployment or future enhancements.

⚠️ Known Issues & Limitations

The following issues have been identified and are planned for future improvements:

  1. High CPU consumption β€” The scheduler for notifications and workshop completion emails can consume significant CPU resources when processing large batches of reminders or completion emails.

  2. Slow dashboard rendering β€” Some pages, especially dashboards, take a long time to render due to multiple API calls and data processing. This is particularly noticeable when loading dashboards with many events or registrations.

  3. N+1 query problem in court availability β€” In getAllCourts, when a date is provided, the code loops through each court and queries bookings individually, causing multiple database queries instead of a single optimized query. This can lead to performance degradation with many courts.

  4. No API rate limiting β€” The application lacks rate limiting middleware, which could allow API abuse, DDoS attacks, or excessive resource consumption from repeated requests. This is a security and performance concern for production deployment.

  5. File upload storage accumulation β€” Uploaded files (vendor documents, profile pictures, event banners) are stored locally in the uploads directory without automatic cleanup. Over time, this can consume significant disk space, especially with vendor document uploads and event images.

βœ… Current State

  • Core functionality is stable and production-ready
  • All major features are implemented and tested
  • Future updates will focus on:
    • Performance optimizations (addressing the issues above)
    • Scalability improvements
    • System maintenance
    • Minor UX and interface refinements
    • Campus-specific feature extensions

❗ Note: Any references to upcoming issues or feature requests can be tracked via GitHub Issues or Pull Requests.

πŸ’» Code Style

This project follows consistent coding conventions and naming patterns:

Naming Conventions

  • Files & Components:

    • React components use PascalCase (e.g., StudentDashboard.jsx, AuthContext.jsx)
    • Backend controllers use camelCase with descriptive names (e.g., authController.js, eventController.js)
    • Utility files use camelCase (e.g., sendReceiptEmail.js, calculateVendorFee.js)
  • Variables & Functions:

    • camelCase for variables and functions (e.g., loadDashboardData, handleRegisterClick)
    • Constants use UPPER_SNAKE_CASE (e.g., JWT_SECRET, MONGO_URI)
    • Boolean variables often use is, has, should prefixes (e.g., isRegistered, hasTaxCard)
  • Database Models:

    • Model files use PascalCase (e.g., UserModel.js, EventModel.js)
    • Schema fields use camelCase (e.g., startDate, registeredCount)
  • API Routes:

    • RESTful conventions with kebab-case in URLs (e.g., /api/vendor-requests, /api/gym-sessions)
    • Route handlers use descriptive verbs (e.g., registerForEvent, createVendorRequest)

Code Formatting

  • Indentation: 2 spaces (consistent across frontend and backend)
  • Quotes: Single quotes for JavaScript/JSX strings
  • Semicolons: Used consistently
  • Line Length: Aim for 100-120 characters max per line
  • Comments: Used for complex logic, API endpoints, and important business rules

React Component Structure

// Standard component structure:
import React, { useState, useEffect } from 'react';
// ... other imports

const ComponentName = () => {
  // 1. State declarations
  // 2. Hooks (useEffect, useCallback, etc.)
  // 3. Handler functions
  // 4. Render logic
  return (/* JSX */);
};

export default ComponentName;

Backend Controller Structure

// Standard controller structure:
const Model = require('../models/modelName');

exports.functionName = async (req, res) => {
  try {
    // Validation
    // Business logic
    // Database operations
    // Response
  } catch (error) {
    // Error handling
  }
};

πŸ›  Tech Stack

Backend

  • Runtime & Framework
    • Node.js (Express.js)
    • MongoDB with Mongoose ODM
  • Auth & Security
    • JWT for authentication
    • bcryptjs for password hashing
  • Validation & APIs
    • express-validator for request validation
    • cors for cross-origin resource sharing
  • Payments & Emails
    • Stripe for payment processing
    • Nodemailer for email services
  • Files, Docs & QR
    • Multer for file uploads
    • PDFKit for PDF generation
    • qrcode for QR code generation
  • Scheduling & Utilities
    • node-cron for scheduled jobs (e.g., notifications)
    • xlsx for Excel import/export
  • Tooling
    • ESLint (with @eslint/js, globals) for linting
    • nodemon / supervisor for auto-restart in development
    • concurrently for running backend & frontend together

Frontend

  • Core
    • React + React DOM
    • React Router for SPA routing
  • Data & Realtime
    • Axios for HTTP/API calls
    • socket.io-client for real-time features
  • Build & Dev Tools
    • create-react-app tooling via react-scripts
    • http-proxy-middleware for local API proxying
    • web-vitals for basic performance metrics
  • Testing
    • @testing-library/react
    • @testing-library/jest-dom
    • @testing-library/user-event

πŸ“Έ Screenshots

1. Login Page

Login Page

2. signup page

Sign up page

3. eventoffice dashboard

Event office dashboard

4. Admin Dashboard

TA dashboard

5. vendor dashboard

vendor dashboard

6. vendor dashboard (continue)

vendor dashboard

6. staff dashboard

staff dashboard

7. staff dashboard (continue)

staff dashboard

✨ Features

Event Management

  • Multiple Event Types: Bazaars, Trips, Workshops, Conferences, Booth Setups, Sports Fields, and Gym/Fitness sessions
  • Event Registration: Students, professors, and staff can register with capacity limits
  • Event Approval Workflow: Admin and Events Office approval system with edit requests
  • Event Restrictions: Support for restricted events with stakeholder/type-based access
  • Event Archiving: Archive past events for historical reference
  • Event Editing: Update event details even after publishing if needed
  • Automated Reminders: Users get reminders 1 day and 1 hour before registered events
  • Commenting System: Users can leave feedback/comments on events
  • Role Management: Admin can assign roles to staff/TA/professor accounts
  • Vendor Validation: Vendors can be verified using uploaded tax card + company logo
  • Booth Requests: Vendors can apply to join bazaars or request campus booth setups
  • QR Distribution: Approved vendors receive QR codes for registered visitors
  • Fee System: Accepted vendors pay participation fees and receive receipts
  • Loyalty Program Support: Vendors can apply to join or cancel from GUC loyalty partnerships
  • Moderation Tools: Admins can block users or delete inappropriate comments

πŸ’‘ Code Examples

Here are key code snippets demonstrating core functionality:

1. User Signup Function (Backend)

// backend/controllers/authController.js
const signup = async (req, res) => {
  try {
    const { email, password, firstName, lastName, userType, gucId, companyName } = req.body;
    
    // Normalize email
    const normalizedEmail = String(email).toLowerCase().trim();
    
    // Check for existing user
    const existingUser = await User.findOne({ email: normalizedEmail });
    if (existingUser) {
      return res.status(409).json({ 
        success: false, 
        message: 'User with this email already exists' 
      });
    }
    
    // GUC email validation for academic users
    if (['Student', 'Staff', 'TA', 'Professor'].includes(userType)) {
      const gucEmailRegex = /^[a-z0-9._%+-]+@student\.guc\.edu\.eg$|^[a-z0-9._%+-]+@guc\.edu\.eg$/;
      if (!gucEmailRegex.test(normalizedEmail)) {
        return res.status(400).json({
          success: false,
          message: 'GUC users must use a valid GUC email address'
        });
      }
    }
    
    // Create user with appropriate defaults
    const userData = {
      email: normalizedEmail,
      password,
      isVerified: false
    };
    
    if (userType === 'Student' || userType === 'Vendor') {
      userData.userType = userType;
    }
    
    const user = await User.create(userData);
    // ... send verification email
    
    res.status(201).json({
      success: true,
      message: 'User created. Verification email sent.',
      user: { id: user._id, email: user.email, userType: user.userType }
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
};

2. Event Registration with Capacity Check (Backend)

// backend/controllers/eventController.js
exports.registerForEvent = async (req, res) => {
  try {
    const id = req.params.id;
    const userId = req.user?._id || req.user?.id;
    
    // Find event or trip
    let holder = await Event.findById(id);
    let holderType = holder ? "event" : null;
    
    if (!holder) {
      holder = await Trip.findById(id);
      holderType = holder ? "trip" : null;
    }
    
    if (!holder) {
      return res.status(404).json({ msg: "Event/Trip not found" });
    }
    
    // Capacity check
    const regCount = await Registration.countDocuments({ event: id });
    if (holder.capacity && regCount >= holder.capacity) {
      return res.status(400).json({ 
        msg: `${holderType === 'trip' ? 'Trip' : 'Event'} is full` 
      });
    }
    
    // Prevent duplicate registration
    const existing = await Registration.findOne({ event: id, user: userId });
    if (existing) {
      return res.status(400).json({ msg: "You are already registered" });
    }
    
    // Create registration
    const registration = await Registration.create({
      event: id,
      user: userId,
      role: req.user.userType.toLowerCase(),
      status: "approved",
      paid: (holder.price || 0) <= 0
    });
    
    res.status(201).json({
      success: true,
      message: "Registration successful",
      registration
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
};

3. Authentication Context (Frontend)

// frontend/src/contexts/AuthContext.jsx
export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const socketRef = useRef(null);

  useEffect(() => {
    // Check if user is logged in on app start
    const token = localStorage.getItem('token');
    if (token) {
      axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
      
      const userData = localStorage.getItem('user');
      if (userData) {
        const parsed = JSON.parse(userData);
        setUser(parsed);
        
        // Initialize socket connection for real-time notifications
        if (!socketRef.current) {
          const socket = ioClient('http://localhost:5000', {
            auth: { token },
            transports: ['websocket']
          });
          socketRef.current = socket;
          
          socket.on('connect', () => {
            if (parsed && parsed._id) socket.emit('join', parsed._id);
          });
          
          socket.on('new_notification', (notif) => {
            window.dispatchEvent(new CustomEvent('new_notification', { detail: notif }));
          });
        }
      }
    }
    setLoading(false);
  }, []);

  const login = async (email, password) => {
    try {
      const response = await axios.post('http://localhost:5000/api/auth/login', {
        email,
        password
      });
      
      if (response.data.success) {
        const { token, user } = response.data;
        localStorage.setItem('token', token);
        localStorage.setItem('user', JSON.stringify(user));
        setUser(user);
        return { success: true };
      }
    } catch (error) {
      return { success: false, message: error.response?.data?.message || 'Login failed' };
    }
  };
  
  // ... logout, signup functions
  
  return (
    <AuthContext.Provider value={{ user, login, logout, signup, loading }}>
      {children}
    </AuthContext.Provider>
  );
};

4. Event Reminder Notification Service (Backend)

// backend/services/notificationService.js
async function processEventReminders(events, timeframe) {
  for (const event of events) {
    try {
      // Get student registrations (for workshops/trips)
      const studentRegistrations = await StudentRegistration.find({
        event: event._id,
        status: { $ne: 'cancelled' }
      });
      
      // Get regular registrations (for Staff, TA, Professor, etc.)
      const regularRegistrations = await Registration.find({
        event: event._id,
        status: { $in: ['approved', 'pending'] }
      });
      
      // Process regular registrations
      for (const registration of regularRegistrations) {
        const userId = registration.user;
        if (!userId) continue;
        
        const existingNotification = await Notification.findOne({
          type: 'event_reminder',
          recipient: userId,
          'metadata.timeframe': timeframe,
          'metadata.eventId': event._id.toString()
        });
        
        if (!existingNotification) {
          await Notification.create({
            recipient: userId,
            type: 'event_reminder',
            title: `Reminder: ${event.title} starts in ${timeframe}`,
            message: `The event "${event.title}" will start in ${timeframe} at ${event.location}`,
            relatedEvent: event._id,
            priority: timeframe === '1 hour' ? 'high' : 'medium',
            metadata: {
              eventTitle: event.title,
              eventDate: event.startDate,
              location: event.location,
              timeframe: timeframe,
              eventId: event._id.toString()
            }
          });
        }
      }
    } catch (error) {
      console.error(`Error processing event ${event._id}:`, error);
    }
  }
}

5. Dashboard Data Loading with Error Handling (Frontend)

// frontend/src/components/StudentDashboard.jsx
const loadDashboardData = async () => {
  try {
    setLoading(true);
    
    // Fetch events from discover events
    const eventsResult = await eventsApiService.getStudentEvents({});
    
    if (eventsResult.success) {
      let eventsList = [];
      if (Array.isArray(eventsResult.data)) {
        eventsList = eventsResult.data;
      } else if (eventsResult.data?.events) {
        eventsList = eventsResult.data.events;
      }
      
      const now = new Date();
      const upcoming = eventsList.filter(ev => {
        if (!ev.startDate) return false;
        const date = new Date(ev.startDate);
        return !isNaN(date.getTime()) && date > now;
      }).sort((a, b) => {
        const dateA = new Date(a.startDate || 0);
        const dateB = new Date(b.startDate || 0);
        return dateA - dateB;
      });
      
      // Generate upcoming deadlines from upcoming events
      const deadlines = upcoming
        .map(reg => {
          const eventDate = reg.eventDate || reg.event?.startDate;
          if (!eventDate) return null;
          const date = new Date(eventDate);
          if (isNaN(date.getTime())) return null;
          
          const timeDiff = date.getTime() - now.getTime();
          const isUrgent = timeDiff < 7 * 24 * 60 * 60 * 1000;
          
          return {
            id: reg.id || reg._id,
            month: date.toLocaleDateString('en-US', { month: 'short' }).toUpperCase(),
            day: date.getDate(),
            title: reg.eventTitle || reg.event?.title || 'Event',
            description: 'Event date',
            color: isUrgent 
              ? 'bg-red-100 dark:bg-red-900/50 text-red-600 dark:text-red-300'
              : 'bg-blue-100 dark:bg-blue-900/50 text-blue-600 dark:text-blue-300'
          };
        })
        .filter(d => d !== null)
        .sort((a, b) => {
          const year = new Date().getFullYear();
          const dateA = new Date(`${a.month} ${a.day}, ${year}`);
          const dateB = new Date(`${b.month} ${b.day}, ${year}`);
          return dateA - dateB;
        })
        .slice(0, 3);
      
      setUpcomingDeadlines(deadlines);
    }
  } catch (error) {
    console.error('Error loading dashboard data:', error);
    setError('Failed to load dashboard data');
  } finally {
    setLoading(false);
  }
};

6. Vendor Request Creation with File Upload (Backend)

// backend/controllers/vendorRequestController.js
const createVendorRequest = async (req, res) => {
  try {
    const {
      eventType,
      attendees: rawAttendees,
      boothSize,
      durationWeeks,
      boothLocation
    } = req.body;

    // Parse attendees if sent as JSON string (multipart/form-data)
    let attendees = rawAttendees;
    if (typeof attendees === 'string') {
      try {
        attendees = JSON.parse(attendees);
      } catch (e) {
        attendees = [];
      }
    }

    // Validate required fields
    if (!eventType || !attendees || !Array.isArray(attendees) || attendees.length === 0) {
      return res.status(400).json({
        message: 'Event type and at least one attendee are required',
        error: 'Missing required fields'
      });
    }

    // Validate attendees structure
    for (let i = 0; i < attendees.length; i++) {
      const attendee = attendees[i];
      if (!attendee.name || !attendee.email) {
        return res.status(400).json({
          message: `Attendee at index ${i} must have a valid name and email`,
          error: 'Invalid attendee structure'
        });
      }
      attendees[i] = {
        name: attendee.name.trim(),
        email: attendee.email.trim()
      };
    }

    // Prepare request data
    const requestData = {
      vendor: req.user._id,
      eventType,
      attendees,
      status: 'pending'
    };

    // Add optional fields if valid
    if (boothSize && ['2x2', '4x4'].includes(boothSize)) {
      requestData.boothSize = boothSize;
    }

    if (durationWeeks) {
      const duration = parseInt(durationWeeks);
      if (!isNaN(duration) && duration >= 1 && duration <= 4) {
        requestData.durationWeeks = duration;
      }
    }

    // If files were uploaded (multipart), include their stored paths
    if (req.files && Array.isArray(req.files) && req.files.length > 0) {
      requestData.individualIdsPaths = req.files.map(f => '/uploads/' + f.filename);
    }

    // Create the vendor request
    const vendorRequest = new VendorRequest(requestData);
    await vendorRequest.save();

    res.status(201).json({
      message: 'Vendor request created successfully',
      request: vendorRequest
    });
  } catch (error) {
    console.error('Error creating vendor request:', error);
    res.status(500).json({
      message: 'Server error',
      error: error.message
    });
  }
};

πŸ‘₯ Stakeholders & Permissions

πŸŽ“ Student

  • Sign up using GUC email (First name, Last name, password, phone…)
  • Verify email with received activation link
  • Log in to dashboard
  • Browse all university events
  • Register to events (if capacity available)
  • Cannot register if event is full
  • Book sports fields (football/tennis/basketball) at available time slots
  • Register to gym/fitness sessions (yoga, pilates, zumba…)
  • Receive reminders before attending
  • Receive notifications if an event/session is edited or cancelled
  • Leave comments/feedback on events
  • Participate in campus polls (e.g., vendors to invite, services to request…)

πŸ§‘β€πŸ’Ό Staff & TA

  • Sign up using GUC email
  • Admin assigns internal role
  • Log in and view dashboard
  • Browse all university events
  • Register just like students
  • Book sports fields and gym sessions
  • Leave feedback/comments
  • Receive all notifications/reminders for what they register to

πŸ‘¨β€πŸ« Professor

  • All student capabilities +
  • Create workshops by filling:
    • Workshop name
    • Location (Campus Room)
    • Date & Time
    • Short Description
    • Capacity limit
    • Source of funding (External or GUC)
    • Extra required resources
    • Registration deadline
  • Edit workshop details after creation
  • View list of workshops they created
  • View number of registered attendees + remaining spots
  • Receive notifications if accepted, rejected, or asked to edit

🏒 Events Office

  • Create official events:
    • Bazaars β†’ name, start/end time, location, description, registration deadline
    • Trips β†’ name, transportation, location, date/time, capacity, description, deadline
    • Conferences β†’ name, funding source, date/time, location, resources, description
  • Edit any event details after creation
  • Receive alerts when professors submit workshop requests
  • Accept/publish professor workshops
  • Reject workshops or request edits
  • Review vendor requests to join bazaars and booths
  • Approve/reject vendor participation
  • System notifies vendors automatically

πŸ›‘ Admin

  • Assign correct roles to staff/TA/professor after they sign up
  • Create or delete Events Office/Admin accounts
  • Block any user if needed
  • View list of all users + status (active or blocked)
  • Delete inappropriate comments
  • Moderate platform behavior and user activity

🧾 Vendor

  • Sign up using company email + password + company name
  • Upload tax card and company logo to prove validity
  • Verify email link via system email
  • Admin/Events Office reviews and approves files
  • Once approved vendor can log in
  • View list of upcoming bazaars
  • Apply to join a bazaar from available list
  • Apply for campus booth setups by filling:
    • Company name
    • Products/Category
    • IDs of attending individuals
    • Booth size
    • Duration and location
    • Setup dates/times
  • Upload attendee IDs for full participation period
  • Receive email when bazaar/booth request is accepted/rejected
  • If accepted β†’ vendor must pay participation fees
  • Receive payment receipt via email
  • Receive visitor QR codes via email
  • Cancel participation request anytime before payment
  • Apply or cancel from GUC Loyalty Program:
    • Form includes discount rate, promo code, terms & conditions

πŸ” System Flows

βœ… 1. User Sign-Up & Verification (Students / Staff / TA / Professors / Vendors)

  1. User enters university/company registration info + email & password
  2. System enforces GUC email for university stakeholders
  3. Vendor uploads business proof files
  4. System sends verification link email
  5. User clicks verification link β†’ account activated
  6. Admin assigns role if internal university user
  7. Vendor account is validated by Admin or Events Office before full activation

βœ… 2. Event Creation Flow (Admin / Events Office / Professor Workshops)

  1. Creator opens β€œCreate Event” form
  2. Selects event type
  3. Inputs all details (time, location, description, capacity, resources, funding, deadline…)
  4. Submits event for review if professor workshop
  5. System publishes immediately if Admin/Events Office
  6. If workshop:
    • Events Office can accept β†’ publish, reject, request edits
  7. Creator receives status notifications

βœ… 3. Registration Flow (Student / Staff / TA / Professor)

  1. User opens Events page
  2. Filters by type
  3. Reads event details
  4. Clicks register
  5. System checks capacity
  6. If full β†’ block registration
  7. If success β†’ add to β€œMy Events”
  8. System sends confirmation and later reminders

βœ… 4. Vendor Participation Request Flow

  1. Vendor views bazaar list
  2. Selects bazaar
  3. Fills participation/booth form
  4. System marks as β€œPending” and notifies Events Office
  5. Events Office/Admin reviews:
    • Approve β†’ vendor pays fees β†’ gets receipt + visitor QR codes
    • Reject β†’ vendor notified and remains not included
  6. Vendor can cancel request anytime before payment

βœ… 5. Sports & Gym Booking Flow

  1. Student opens facility page (Sports/Gym)
  2. System shows free slots/sessions
  3. Student selects and confirms
  4. Booking saved to dashboard
  5. User receives notification if cancelled or edited

βœ… 6. Comment Moderation Flow

  1. Users post feedback on events
  2. Admin views comments
  3. If inappropriate β†’ Admin deletes comment
  4. If user continues abuse β†’ Admin blocks user

πŸ“ Project Structure

Below is the full project layout (excluding node_modules). Generated folders such as uploads and build assets are included but grouped where appropriate.

Bindly-/
β”œβ”€β”€ (_CSEN704_) 1 - Project Requirements (Project).xlsx
β”œβ”€β”€ BLOCK_USER_FEATURE.md
β”œβ”€β”€ BLOCK_USER_POSTMAN_TESTS.md
β”œβ”€β”€ create-admin.js
β”œβ”€β”€ DETAILED_CHANGES.md
β”œβ”€β”€ IMPLEMENTATION_CHECKLIST.md
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ PAYMENT_RECEIPT_EMAIL_ARCHITECTURE.md
β”œβ”€β”€ PAYMENT_RECEIPT_EMAIL_COMPLETE.md
β”œβ”€β”€ PAYMENT_RECEIPT_EMAIL_IMPLEMENTATION.md
β”œβ”€β”€ PAYMENT_RECEIPT_EMAIL_TEST_GUIDE.md
β”œβ”€β”€ POSTMAN_EVENT_PAYMENT_TEST.md
β”œβ”€β”€ POSTMAN_FINAL_TESTING_GUIDE.md
β”œβ”€β”€ POSTMAN_LIVE_TEST_STEPS.md
β”œβ”€β”€ POSTMAN_TEST_STEPS.md
β”œβ”€β”€ postman-admin-features-tests.json
β”œβ”€β”€ README.md
β”œβ”€β”€ STRIPE_COMPLETE.md
β”œβ”€β”€ STRIPE_PAYMENT_SUMMARY.md
β”œβ”€β”€ STRIPE_QUICK_START.md
β”œβ”€β”€ TEST_STRIPE_PAYMENT.md
β”œβ”€β”€ test-professor-events.js
β”œβ”€β”€ VERIFICATION_FLOW_IMPLEMENTATION.md
β”œβ”€β”€ verify-stripe.ps1
β”œβ”€β”€ verify-stripe.sh
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ AUTH_API_DOCUMENTATION.md
β”‚   β”œβ”€β”€ check-events.js
β”‚   β”œβ”€β”€ check-payments.js
β”‚   β”œβ”€β”€ check-registrations.js
β”‚   β”œβ”€β”€ check-users.js
β”‚   β”œβ”€β”€ create-sample-booths.js
β”‚   β”œβ”€β”€ create-sample-vendor-requests.js
β”‚   β”œβ”€β”€ EMAIL_SETUP_GUIDE.md
β”‚   β”œβ”€β”€ ENV_SETUP.md
β”‚   β”œβ”€β”€ eslint.config.mjs
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ package-lock.json
β”‚   β”œβ”€β”€ POSTMAN_TESTING_GUIDE.md
β”‚   β”œβ”€β”€ server.js
β”‚   β”œβ”€β”€ standalone-booth-events-final.json
β”‚   β”œβ”€β”€ standalone-booth-events.json
β”‚   β”œβ”€β”€ standalone-booths-data.json
β”‚   β”œβ”€β”€ standalone-booths.json
β”‚   β”œβ”€β”€ STRIPE_PAYMENT_SETUP.md
β”‚   β”œβ”€β”€ test-admin-features.js
β”‚   β”œβ”€β”€ test-archived-events.js
β”‚   β”œβ”€β”€ test-booth-poll.js
β”‚   β”œβ”€β”€ test-complete-flow.js
β”‚   β”œβ”€β”€ test-email-webhook.js
β”‚   β”œβ”€β”€ test-gym-sessions.js
β”‚   β”œβ”€β”€ test-image.png
β”‚   β”œβ”€β”€ test-restrictions.js
β”‚   β”œβ”€β”€ test-webhook-sim.js
β”‚   β”œβ”€β”€ vendor-requests.json
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”œβ”€β”€ adminAccountsController.js
β”‚   β”‚   β”œβ”€β”€ adminController.js
β”‚   β”‚   β”œβ”€β”€ announcementController.js
β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   β”œβ”€β”€ authVerifyController.js
β”‚   β”‚   β”œβ”€β”€ bazaarController.js
β”‚   β”‚   β”œβ”€β”€ boothController.js
β”‚   β”‚   β”œβ”€β”€ courtController.js
β”‚   β”‚   β”œβ”€β”€ dashboardController.js
β”‚   β”‚   β”œβ”€β”€ devEmailController.js
β”‚   β”‚   β”œβ”€β”€ eventController.js
β”‚   β”‚   β”œβ”€β”€ gymController.js
β”‚   β”‚   β”œβ”€β”€ gymSessionController.js
β”‚   β”‚   β”œβ”€β”€ notificationController.js
β”‚   β”‚   β”œβ”€β”€ paymentVerificationController.js
β”‚   β”‚   β”œβ”€β”€ professorController.js
β”‚   β”‚   β”œβ”€β”€ stripeSuccessController.js
β”‚   β”‚   β”œβ”€β”€ stripeWebhookController.js
β”‚   β”‚   β”œβ”€β”€ studentRegistrationController.js
β”‚   β”‚   β”œβ”€β”€ tripController.js
β”‚   β”‚   β”œβ”€β”€ vendorController.js
β”‚   β”‚   β”œβ”€β”€ vendorDocumentController.js
β”‚   β”‚   β”œβ”€β”€ vendorRequestController.js
β”‚   β”‚   β”œβ”€β”€ workshopCompletionController.js
β”‚   β”‚   └── workshopController.js
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ authMiddleware.js
β”‚   β”‚   └── uploadMiddleware.js
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ AdminModel.js
β”‚   β”‚   β”œβ”€β”€ announcementModel.js
β”‚   β”‚   β”œβ”€β”€ bazaarModel.js
β”‚   β”‚   β”œβ”€β”€ boothModel.js
β”‚   β”‚   β”œβ”€β”€ boothPollModel.js
β”‚   β”‚   β”œβ”€β”€ courtBookingModel.js
β”‚   β”‚   β”œβ”€β”€ courtModel.js
β”‚   β”‚   β”œβ”€β”€ EmailModel.js
β”‚   β”‚   β”œβ”€β”€ eventModel.js
β”‚   β”‚   β”œβ”€β”€ gymRegistrationModel.js
β”‚   β”‚   β”œβ”€β”€ GymSession.js
β”‚   β”‚   β”œβ”€β”€ gymSessionModel.js
β”‚   β”‚   β”œβ”€β”€ notificationModel.js
β”‚   β”‚   β”œβ”€β”€ paymentModel.js
β”‚   β”‚   β”œβ”€β”€ Professor.js
β”‚   β”‚   β”œβ”€β”€ registrationModel.js
β”‚   β”‚   β”œβ”€β”€ studentRegistrationModel.js
β”‚   β”‚   β”œβ”€β”€ tripModel.js
β”‚   β”‚   β”œβ”€β”€ userModel.js
β”‚   β”‚   β”œβ”€β”€ vendorLoyaltyProgramModel.js
β”‚   β”‚   β”œβ”€β”€ vendorRequest.js
β”‚   β”‚   β”œβ”€β”€ vendorVoteModel.js
β”‚   β”‚   └── Workshop.js
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ adminRoutes.js
β”‚   β”‚   β”œβ”€β”€ announcementRoutes.js
β”‚   β”‚   β”œβ”€β”€ authRoutes.js
β”‚   β”‚   β”œβ”€β”€ bazaarRoutes.js
β”‚   β”‚   β”œβ”€β”€ boothRoutes.js
β”‚   β”‚   β”œβ”€β”€ courtRoutes.js
β”‚   β”‚   β”œβ”€β”€ dashboardRoutes.js
β”‚   β”‚   β”œβ”€β”€ devEmailRoutes.js
β”‚   β”‚   β”œβ”€β”€ devEmailTestRoutes.js
β”‚   β”‚   β”œβ”€β”€ eventRoutes.js
β”‚   β”‚   β”œβ”€β”€ gymRoutes.js
β”‚   β”‚   β”œβ”€β”€ gymSessionRoutes.js
β”‚   β”‚   β”œβ”€β”€ notificationRoutes.js
β”‚   β”‚   β”œβ”€β”€ professorRoutes.js
β”‚   β”‚   β”œβ”€β”€ studentRegistrationRoutes.js
β”‚   β”‚   β”œβ”€β”€ tripRoutes.js
β”‚   β”‚   β”œβ”€β”€ vendorRequestRoutes.js
β”‚   β”‚   β”œβ”€β”€ vendorRoutes.js
β”‚   β”‚   └── workshopRoutes.js
β”‚   β”œβ”€β”€ scripts/
β”‚   β”‚   β”œβ”€β”€ check-and-delete-email.js
β”‚   β”‚   β”œβ”€β”€ create-test-events.js
β”‚   β”‚   β”œβ”€β”€ create-test-users.js
β”‚   β”‚   β”œβ”€β”€ insert-dev-email.js
β”‚   β”‚   β”œβ”€β”€ migrateEventRatings.js
β”‚   β”‚   β”œβ”€β”€ README.md
β”‚   β”‚   β”œβ”€β”€ seedCourts.js
β”‚   β”‚   β”œβ”€β”€ setup-test-uploads.js
β”‚   β”‚   β”œβ”€β”€ TEST_EVENTS_README.md
β”‚   β”‚   β”œβ”€β”€ test-sales-report.js
β”‚   β”‚   β”œβ”€β”€ test-vendor-loyalty-program.js
β”‚   β”‚   β”œβ”€β”€ trigger-send-qrcodes.js
β”‚   β”‚   └── updateWorkshopPrices.js
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ notificationScheduler.js
β”‚   β”‚   β”œβ”€β”€ notificationService.js
β”‚   β”‚   └── socket.js
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ calculateVendorFee.js
β”‚   β”‚   β”œβ”€β”€ cleanupUserRegistrations.js
β”‚   β”‚   β”œβ”€β”€ generateCertificate.js
β”‚   β”‚   β”œβ”€β”€ generateQRCode.js
β”‚   β”‚   β”œβ”€β”€ mailer.js
β”‚   β”‚   β”œβ”€β”€ sendCommentWarningEmail.js
β”‚   β”‚   β”œβ”€β”€ sendGymCancellationEmail.js
β”‚   β”‚   β”œβ”€β”€ sendGymEditEmail.js
β”‚   β”‚   β”œβ”€β”€ sendQRCodesToVendor.js
β”‚   β”‚   β”œβ”€β”€ sendReceiptEmail.js
β”‚   β”‚   β”œβ”€β”€ sendRefundEmail.js
β”‚   β”‚   β”œβ”€β”€ sendVendorRequestStatusEmail.js
β”‚   β”‚   └── sendWorkshopCompletionEmail.js
β”‚   β”œβ”€β”€ test-uploads/
β”‚   β”‚   └── vendors/
β”‚   β”‚       β”œβ”€β”€ abc/
β”‚   β”‚       β”‚   └── logo.png
β”‚   β”‚       β”œβ”€β”€ athlete-hub/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ booknook-publishers/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ campus-coffee-roasters/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ mindful-meals/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ ro/
β”‚   β”‚       β”‚   └── logo.png
β”‚   β”‚       β”œβ”€β”€ syn/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ tech-solutions-inc/
β”‚   β”‚       β”‚   β”œβ”€β”€ individual-ids.pdf
β”‚   β”‚       β”‚   β”œβ”€β”€ logo.png
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       β”œβ”€β”€ testco/
β”‚   β”‚       β”‚   └── tax-card.pdf
β”‚   β”‚       └── vendorv/
β”‚   β”‚           β”œβ”€β”€ logo.png
β”‚   β”‚           └── tax-card.pdf
β”‚   └── uploads/
β”‚       └── ... (runtime uploaded images and PDFs)
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ devServer.js
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ package-lock.json
β”‚   β”œβ”€β”€ webpackDevServer.config.js
β”‚   β”œβ”€β”€ build/
β”‚   β”‚   β”œβ”€β”€ assets/
β”‚   β”‚   β”‚   └── images/
β”‚   β”‚   β”‚       └── ... (optimized build images)
β”‚   β”‚   └── manifest.json
β”‚   β”œβ”€β”€ public/
β”‚   β”‚   β”œβ”€β”€ index.html
β”‚   β”‚   β”œβ”€β”€ manifest.json
β”‚   β”‚   └── assets/
β”‚   β”‚       └── images/
β”‚   β”‚           β”œβ”€β”€ ad.png
β”‚   β”‚           β”œβ”€β”€ admin-users.jpg
β”‚   β”‚           β”œβ”€β”€ basketball.webp
β”‚   β”‚           β”œβ”€β”€ bazaar-background.jpg
β”‚   β”‚           β”œβ”€β”€ booth-background.jpg
β”‚   β”‚           β”œβ”€β”€ campus-courts.png
β”‚   β”‚           β”œβ”€β”€ conference-background.jpg
β”‚   β”‚           β”œβ”€β”€ dashboardimage.jpg
β”‚   β”‚           β”œβ”€β”€ events-banner.jpeg
β”‚   β”‚           β”œβ”€β”€ football.jpg
β”‚   β”‚           β”œβ”€β”€ gym.jpg
β”‚   β”‚           β”œβ”€β”€ login-background.jpg
β”‚   β”‚           β”œβ”€β”€ LoyaltyProgram.png
β”‚   β”‚           β”œβ”€β”€ map.jpg
β”‚   β”‚           β”œβ”€β”€ platform-booth.jpg
β”‚   β”‚           β”œβ”€β”€ README.md
β”‚   β”‚           β”œβ”€β”€ tennis.jpg
β”‚   β”‚           β”œβ”€β”€ trip-background.png
β”‚   β”‚           β”œβ”€β”€ VendorAD.png
β”‚   β”‚           β”œβ”€β”€ workshop-background.jpg
β”‚   β”‚           └── workshop.jpg
β”‚   └── src/
β”‚       β”œβ”€β”€ App.jsx
β”‚       β”œβ”€β”€ index.js
β”‚       β”œβ”€β”€ routes.js
β”‚       β”œβ”€β”€ setupProxy.js
β”‚       β”œβ”€β”€ api/
β”‚       β”‚   β”œβ”€β”€ adminApi.js
β”‚       β”‚   β”œβ”€β”€ bazaarApi.js
β”‚       β”‚   β”œβ”€β”€ courtsApi.js
β”‚       β”‚   β”œβ”€β”€ eventManagementApi.js
β”‚       β”‚   β”œβ”€β”€ eventsApi.js
β”‚       β”‚   β”œβ”€β”€ gymApi.js
β”‚       β”‚   β”œβ”€β”€ gymSessionApi.js
β”‚       β”‚   β”œβ”€β”€ notificationApi.js
β”‚       β”‚   β”œβ”€β”€ professorApi.js
β”‚       β”‚   β”œβ”€β”€ studentRegistrationApi.js
β”‚       β”‚   β”œβ”€β”€ vendorApi.js
β”‚       β”‚   └── vendorRequestApi.js
β”‚       β”œβ”€β”€ components/
β”‚       β”‚   β”œβ”€β”€ BazaarForm.jsx
β”‚       β”‚   β”œβ”€β”€ BoothApplicationForm.jsx
β”‚       β”‚   β”œβ”€β”€ BoothList.jsx
β”‚       β”‚   β”œβ”€β”€ CampusMapSelector.jsx
β”‚       β”‚   β”œβ”€β”€ ConferenceForm.jsx
β”‚       β”‚   β”œβ”€β”€ FileChooser.jsx
β”‚       β”‚   β”œβ”€β”€ GymSessionForm.jsx
β”‚       β”‚   β”œβ”€β”€ GymSessionRegistrationForm.jsx
β”‚       β”‚   β”œβ”€β”€ IDUploadModal.jsx
β”‚       β”‚   β”œβ”€β”€ Navbar.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformBoothMapSelector.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformBoothsModal.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformMapSelector.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ StaffDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ StandaloneBoothsBrowser.jsx
β”‚       β”‚   β”œβ”€β”€ StudentDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ StudentRegistrationForm.jsx
β”‚       β”‚   β”œβ”€β”€ TADashboard.jsx
β”‚       β”‚   β”œβ”€β”€ TripForm.jsx
β”‚       β”‚   β”œβ”€β”€ VendorDocumentsModal.jsx
β”‚       β”‚   β”œβ”€β”€ VendorNotificationBell.jsx
β”‚       β”‚   └── WorkshopEditRequestModal.jsx
β”‚       β”œβ”€β”€ contexts/
β”‚       β”‚   └── AuthContext.jsx
β”‚       β”œβ”€β”€ pages/
β”‚       β”‚   β”œβ”€β”€ AdminDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ AdminEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ AdminLogin.jsx
β”‚       β”‚   β”œβ”€β”€ AdminLoyaltyProgramVendors.jsx
β”‚       β”‚   β”œβ”€β”€ AdminPlatformBoothRequests.jsx
β”‚       β”‚   β”œβ”€β”€ AdminProfile.jsx
β”‚       β”‚   β”œβ”€β”€ AdminUsers.jsx
β”‚       β”‚   β”œβ”€β”€ AdminVendors.jsx
β”‚       β”‚   β”œβ”€β”€ BoothPolls.jsx
β”‚       β”‚   β”œβ”€β”€ Confrences.jsx
β”‚       β”‚   β”œβ”€β”€ CourtAvailability.jsx
β”‚       β”‚   β”œβ”€β”€ CreateBooth.jsx
β”‚       β”‚   β”œβ”€β”€ CreateWorkshop.jsx
β”‚       β”‚   β”œβ”€β”€ Dashboard.jsx
β”‚       β”‚   β”œβ”€β”€ EditBazaar.jsx
β”‚       β”‚   β”œβ”€β”€ EditConfrences.jsx
β”‚       β”‚   β”œβ”€β”€ EditTrip.jsx
β”‚       β”‚   β”œβ”€β”€ EventPayment.jsx
β”‚       β”‚   β”œβ”€β”€ Events.jsx
β”‚       β”‚   β”œβ”€β”€ EventsList.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeCreatePoll.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeLoyaltyProgramVendors.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeNotificationBell.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeVendors.jsx
β”‚       β”‚   β”œβ”€β”€ EventsOfficeWorkshops.jsx
β”‚       β”‚   β”œβ”€β”€ GymManage.jsx
β”‚       β”‚   β”œβ”€β”€ GymSchedule.jsx
β”‚       β”‚   β”œβ”€β”€ Login.jsx
β”‚       β”‚   β”œβ”€β”€ MyWallet.jsx
β”‚       β”‚   β”œβ”€β”€ MyWorkshops.jsx
β”‚       β”‚   β”œβ”€β”€ PaymentCancel.jsx
β”‚       β”‚   β”œβ”€β”€ PaymentSuccess.jsx
β”‚       β”‚   β”œβ”€β”€ PendingVerification.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformBoothRequests.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformBoothReservation.jsx
β”‚       β”‚   β”œβ”€β”€ PlatformBooths.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorFavorites.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorLoyaltyVendorsView.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorMyRegistrations.jsx
β”‚       β”‚   β”œβ”€β”€ ProfessorProfile.jsx
β”‚       β”‚   β”œβ”€β”€ Signup.jsx
β”‚       β”‚   β”œβ”€β”€ StaffEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ StaffFavorites.jsx
β”‚       β”‚   β”œβ”€β”€ StaffLoyaltyVendorsView.jsx
β”‚       β”‚   β”œβ”€β”€ StaffMyRegistrations.jsx
β”‚       β”‚   β”œβ”€β”€ StudentCourtsView.jsx
β”‚       β”‚   β”œβ”€β”€ StudentEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ StudentFavorites.jsx
β”‚       β”‚   β”œβ”€β”€ StudentLoyaltyVendorsView.jsx
β”‚       β”‚   β”œβ”€β”€ StudentMyRegistrations.jsx
β”‚       β”‚   β”œβ”€β”€ TAEventsView.jsx
β”‚       β”‚   β”œβ”€β”€ TAFavorites.jsx
β”‚       β”‚   β”œβ”€β”€ TALoyaltyVendorsView.jsx
β”‚       β”‚   β”œβ”€β”€ TAMyRegistrations.jsx
β”‚       β”‚   β”œβ”€β”€ VendorAccepted.jsx
β”‚       β”‚   β”œβ”€β”€ VendorAcceptedEvents.jsx
β”‚       β”‚   β”œβ”€β”€ VendorBazaars.jsx
β”‚       β”‚   β”œβ”€β”€ VendorBoothsSection.jsx
β”‚       β”‚   β”œβ”€β”€ VendorDashboard.jsx
β”‚       β”‚   β”œβ”€β”€ VendorLoyaltyProgram.jsx
β”‚       β”‚   β”œβ”€β”€ VendorMyRequests.jsx
β”‚       β”‚   β”œβ”€β”€ VendorRequestPayment.jsx
β”‚       β”‚   β”œβ”€β”€ VendorRequests.jsx
β”‚       β”‚   └── VerifyEmail.jsx
β”‚       └── styles/
β”‚           β”œβ”€β”€ BazaarForm.css
β”‚           β”œβ”€β”€ conference.css
β”‚           β”œβ”€β”€ CreateBazaar.css
β”‚           β”œβ”€β”€ CreateGymSession.css
β”‚           β”œβ”€β”€ CreateTrip.css
β”‚           β”œβ”€β”€ EditBazaar.css
β”‚           β”œβ”€β”€ EditTrip.css
β”‚           β”œβ”€β”€ EventsList.css
β”‚           β”œβ”€β”€ GymSessionForm.css
β”‚           β”œβ”€β”€ index.css
β”‚           β”œβ”€β”€ StudentRegistrationForm.css
β”‚           β”œβ”€β”€ TripForm.css
β”‚           └── VendorBazaars.css

πŸ“š API Documentation

Authentication API

See backend/AUTH_API_DOCUMENTATION.md for detailed authentication endpoints.

Main API Endpoints

  • /api/auth - Authentication (signup, login, verification)
  • /api/admin - Admin operations
  • /api/events - Event management
  • /api/workshops - Workshop management
  • /api/bazaars - Bazaar management
  • /api/trips - Trip management
  • /api/vendor - Vendor operations
  • /api/vendor-requests - Vendor request management
  • /api/courts - Court booking
  • /api/gym - Gym management
  • /api/gym-sessions - Gym session management
  • /api/booths - Booth management
  • /api/announcements - Announcements
  • /api/dashboard - Dashboard data
  • /api/notifications - Notifications
  • /api/student-registrations - Student registrations
  • /api/professors - Professor operations

Testing

  • See POSTMAN_FINAL_TESTING_GUIDE.md for a single, comprehensive Postman guide covering:
    • Authentication and user onboarding
    • Event creation, approval, and registration
    • Payments, webhooks, and receipt emails
    • Vendor onboarding, booths, and loyalty program flows
    • Gym sessions, court bookings, notifications, and admin tools

πŸ§ͺ Tests

The application uses Postman for API testing. All tests are documented with step-by-step instructions and expected responses.

Test Coverage

The following test scenarios are covered:

1. Authentication Tests

Test: User Signup

  • Endpoint: POST /api/auth/signup
  • Purpose: Verify user registration with email validation
  • Test Cases:
    • Student signup with GUC email
    • Vendor signup with file uploads
    • Duplicate email rejection
    • Invalid email format rejection

Test: User Login

  • Endpoint: POST /api/auth/login
  • Purpose: Verify authentication and JWT token generation
  • Test Cases:
    • Valid credentials return token
    • Invalid credentials are rejected
    • Unverified accounts cannot login

2. Event Management Tests

Test: Create Event

  • Endpoint: POST /api/events
  • Purpose: Verify event creation with proper validation
  • Test Cases:
    • Events Office can create events
    • Required fields validation
    • Date validation (startDate < endDate)

Test: Register for Event

  • Endpoint: POST /api/events/:id/register
  • Purpose: Verify capacity-safe registration
  • Test Cases:
    • Successful registration when capacity available
    • Registration blocked when event is full
    • Duplicate registration prevention

3. Vendor Request Tests

Test: Create Vendor Request

  • Endpoint: POST /api/vendor-requests
  • Purpose: Verify vendor booth/bazaar application
  • Test Cases:
    • Vendor can submit request with attendees
    • File upload validation (ID documents)
    • Request status set to 'pending'

Test: Approve/Reject Vendor Request

  • Endpoint: POST /api/vendor-requests/:id/approve or /reject
  • Purpose: Verify Events Office can process vendor requests
  • Test Cases:
    • Request approval sends notification to vendor
    • Request rejection sends notification with reason
    • Status updates correctly in database

4. Payment Tests

Test: Stripe Payment Processing

  • Endpoint: POST /api/vendor-requests/:id/payment
  • Purpose: Verify payment integration
  • Test Cases:
    • Payment intent creation
    • Webhook handling for payment confirmation
    • Receipt email delivery after successful payment

5. Admin Functionality Tests

Test: Block User

  • Endpoint: POST /api/admin/users/:id/block
  • Purpose: Verify admin can block users
  • Test Cases:
    • User status changes to 'blocked'
    • Blocked user cannot login
    • Block reason is stored

Test: Delete Comment

  • Endpoint: DELETE /api/admin/comments/:id
  • Purpose: Verify comment moderation
  • Test Cases:
    • Comment is removed from database
    • Warning email sent to comment author
    • Event ratings remain intact

Postman Test Collections

All tests are organized in Postman collections with:

  • Pre-configured test users (see POSTMAN_FINAL_TESTING_GUIDE.md)
  • Environment variables for tokens and IDs
  • Assertions for response validation
  • Test scripts for automated verification

Running Tests

  1. Import Postman Collection: Import the test collection from postman-admin-features-tests.json
  2. Set Environment Variables: Configure test user credentials and base URL
  3. Run Tests: Execute individual requests or run the entire collection
  4. Verify Results: Check response status codes, data structure, and business logic

Test Screenshots

Screenshots of Postman tests are available in:

  • POSTMAN_FINAL_TESTING_GUIDE.md - Comprehensive testing guide
  • BLOCK_USER_POSTMAN_TESTS.md - Admin block user feature tests
  • POSTMAN_EVENT_PAYMENT_TEST.md - Payment flow tests

Note: All tests use test credentials and Stripe test keys. Never use production credentials in tests.

How to Use?

Even experienced engineers appreciate clear instructions, and newcomers rely on them. Please follow this detailed walkthrough when testing or demoing Bindly:

  1. Start the stack
    • Open two terminals.
    • In the first terminal run npm run start:backend (or npm run dev for simultaneous front + back).
    • In the second terminal run npm run start:frontend.
  2. Create initial users (if needed)
    • Use backend/create-admin.js or the POSTMAN admin collection to seed an admin account.
    • Run any relevant scripts from backend/scripts/ (e.g., create-test-events.js) to populate sample data.
  3. Login via the frontend
    • Visit http://localhost:3000 and log in using the credentials you created or seeded.
  4. Walk through core flows
    • Create an event (as Staff/Professor).
    • Approve it via the Admin/Event Office dashboard.
    • Register students/vendors, run through payment (Stripe test keys), and verify email notifications.
    • Try vendor onboarding and booth assignments if applicable.
  5. Run automated tests
    • Follow the exact steps outlined in POSTMAN_FINAL_TESTING_GUIDE.md to replay all validated API flows using Postman.

Document anything unexpected in GitHub Issues so others can reproduce and resolve it.

πŸ“ Additional Documentation

πŸš€ Installation

  1. Clone the repository

    git clone https://github.com/Advanced-Computer-Lab-2025/Bindly
    cd Bindly
  2. Install dependencies

    npm run install:all

    This will install dependencies for:

    • Root directory
    • Backend directory
    • Frontend directory

βš™οΈ Environment Setup

Backend Environment Variables

Create a .env file in the backend directory with the following variables:

# MongoDB Configuration
MONGO_URI=mongodb+srv://<username>:<password>@<cluster-host>/<db-name>?retryWrites=true&w=majority

# Server Configuration
PORT=5000
NODE_ENV=development

# JWT Configuration
JWT_SECRET=your-jwt-secret-key
JWT_EXPIRE=7d

# Email Configuration (for Nodemailer)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-app-password

# Stripe Configuration (optional, for payment features)
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret

Frontend Configuration

The frontend is configured to proxy API requests to http://localhost:5000 by default (see frontend/package.json).

πŸƒ Running the Application

Run Separately

Backend only:

npm run start:backend
# or
cd backend
npm start

Frontend only:

npm run start:frontend
# or
cd frontend
npm start

🀝 How Can Others Contribute?

We welcome contributions from the community! While Bindly is fully functional, there are several areas where improvements and contributions would be valuable. Here's how you can help:

🎯 Areas That Need Improvement

Based on our current limitations and future goals, here are specific areas where contributions would be most impactful:

1. Performance Optimization

  • High CPU consumption in schedulers: The notification and workshop completion email schedulers can consume significant CPU when processing large batches. Contributions to optimize batch processing, implement queue systems, or add rate limiting would be valuable.
  • Slow dashboard rendering: Some dashboards take a long time to load due to multiple API calls. Contributions to implement data caching, pagination, or lazy loading would improve user experience.
  • N+1 query problem in court availability: The getAllCourts function queries bookings individually for each court. Contributions to optimize this with aggregation pipelines or batch queries would significantly improve performance.

2. Security & Reliability

  • API rate limiting: The application lacks rate limiting middleware, which could allow API abuse or DDoS attacks. Contributions to implement rate limiting (e.g., using express-rate-limit) would enhance security.
  • File upload cleanup: Uploaded files accumulate in the uploads directory without automatic cleanup. Contributions to implement file lifecycle management, automatic cleanup of orphaned files, or integration with cloud storage would prevent disk space issues.

3. Code Quality & Testing

  • Test coverage: While we have Postman tests, automated unit and integration tests would improve code reliability. Contributions to add Jest/Mocha tests for critical functions would be valuable.
  • Error handling: Some error handling could be more comprehensive. Contributions to improve error messages, logging, and user-facing error handling would enhance the developer and user experience.
  • Code documentation: Additional JSDoc comments, API documentation, and inline comments for complex logic would help new contributors understand the codebase.

4. Feature Enhancements

  • Search and filtering: Enhanced search functionality across events, users, and vendor requests would improve usability.
  • Analytics and reporting: Dashboard analytics, event attendance reports, and vendor performance metrics would provide valuable insights.
  • Mobile responsiveness: While the application works on mobile, dedicated mobile optimizations and responsive design improvements would enhance the mobile experience.
  • Accessibility: Improvements to ARIA labels, keyboard navigation, and screen reader support would make the platform more accessible.

5. Developer Experience

  • Development tools: Docker setup, development environment scripts, and improved local setup documentation would make it easier for new contributors to get started.
  • Code refactoring: Some controllers and components are quite large. Contributions to break them into smaller, more maintainable modules would improve code organization.
  • TypeScript migration: Gradual migration to TypeScript would improve type safety and developer experience.

πŸš€ How to Contribute

Getting Started

  1. Fork the repository and clone your fork:

    git clone https://github.com/YOUR_USERNAME/Bindly.git
    cd Bindly
  2. Set up your development environment:

    • Follow the Installation and Environment Setup sections
    • Ensure you can run both backend and frontend locally
    • Test that you can create an admin account and log in
  3. Choose an area to contribute:

    • Check the Known Issues & Limitations section
    • Look for open GitHub Issues labeled good first issue, help wanted, or enhancement
    • Or propose your own improvement in a new issue

Contribution Workflow

  1. Create a feature branch:

    git checkout -b feature/your-feature-name
    # or
    git checkout -b fix/your-bug-fix
  2. Make your changes:

    • Follow the Code Style guidelines
    • Write clear, descriptive commit messages
    • Test your changes thoroughly
    • Update documentation if needed
  3. Test your changes:

    • Run the application locally and test the functionality
    • Use Postman to test API endpoints (see Testing section)
    • Check for console errors and warnings
    • Test edge cases and error scenarios
  4. Commit your changes:

    git add .
    git commit -m "Add: Description of your changes"

    Use clear commit messages:

    • Add: for new features
    • Fix: for bug fixes
    • Update: for improvements to existing features
    • Refactor: for code refactoring
    • Docs: for documentation changes
  5. Push to your fork:

    git push origin feature/your-feature-name
  6. Open a Pull Request:

    • Provide a clear description of what your PR does
    • Reference any related issues
    • Include screenshots or examples if applicable
    • Explain any breaking changes

πŸ“‹ Pull Request Guidelines

When submitting a PR, please ensure:

  • Code follows the project's style guide (see Code Style)
  • Changes are tested and don't break existing functionality
  • Documentation is updated if you're adding new features or changing existing behavior
  • Commit messages are clear and descriptive
  • PR description explains:
    • What the PR does
    • Why the change is needed
    • How to test the changes
    • Any breaking changes

πŸ› Reporting Issues

If you find a bug or have a suggestion:

  1. Check existing issues to see if it's already reported
  2. Create a new issue with:
    • A clear, descriptive title
    • Steps to reproduce (for bugs)
    • Expected vs. actual behavior
    • Screenshots if applicable
    • Environment details (OS, Node version, etc.)

πŸ’‘ Questions or Need Help?

  • Open a GitHub Discussion for questions or ideas
  • Check existing documentation in the backend/ directory
  • Review the API Documentation section
  • Look at similar code in the codebase for examples

πŸ™ Recognition

Contributors will be recognized in:

  • The README's credits section (for significant contributions)
  • Release notes
  • Project documentation

Thank you for considering contributing to Bindly! Every contribution, no matter how small, helps make the platform better for the entire campus community.

πŸ“„ License

This project is licensed under the ISC License.

Third-Party Licenses

The following third-party services and libraries are used in this project:

  • Stripe - Payment processing service

    • License: Apache License 2.0
    • Used for: Payment processing, webhook handling, receipt generation
    • More information: Stripe License
  • React - Frontend framework

    • License: MIT License
    • Used for: UI component library and state management
  • Express.js - Backend framework

    • License: MIT License
    • Used for: RESTful API server
  • MongoDB - Database

    • License: Server Side Public License (SSPL)
    • Used for: Data storage and retrieval

All other dependencies follow their respective open-source licenses as specified in package.json files.

πŸ™ Credits & Acknowledgments

This project was created and developed by students from the German University in Cairo (GUC) to centralize and structure campus event operations.

πŸŽ“ Development Team

  • Nourhan Ehab (Scrum Master) β†’ @NourhanEhab-04
  • Salma Ahmed β†’ @salmaahmed21
  • Youssef Khaled β†’ @youssefelgenany
  • Eyad Emara β†’ @EyadEmara11
  • Mazen Mossad β†’ @MazenMossad1
  • Mohamed El Sayed β†’ @ME312241
  • Hagar Lotfyβ†’ @hagarlotfy
  • Dyala Elsmeary β†’ @dyalaelsmery
  • Leena El Badawi β†’ @9leeeawi10

πŸ“š External Resources & References

The following online resources, documentation, and tutorials were referenced during the development of this project:

Official Documentation

YouTube Tutorials

Additional Resources

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages