cuhacking / 2025

Flagship platform for cuHacking's 2025 hackathon.
9 stars 8 forks source link

feat: setup initiatives to gameify the hackathon to incentivise participation #76

Open cloverzer0 opened 2 months ago

cloverzer0 commented 2 months ago

Feature Overview for Gamification

Goals:

Increase Competitiveness, Participation and User Experience:

Implement a points-based system to foster a competitive environment among participants. Motivate increased engagement and active participation through competitive elements. Enhance Engagement:

Utilize gamification techniques to make activities more rewarding and enjoyable. Boost user engagement and retention by integrating engaging and interactive features. Components Needed:

Rewards: Types of Rewards: Tangible Rewards: Consider offering physical items such as gift cards, merchandise, or tech gadgets. Intangible Rewards: Recognize participants with non-physical rewards like exclusive access, certificates, or public recognition. Distribution: Reward the highest performers to sustain competitive levels. Common approaches include rewarding the top 3 individuals or the top 10% of participants. Frequency: Determine the schedule for distributing rewards, which could be at the end of each event, or at the conclusion of the entire hackathon.

Categories for Earning Points: Tasks: Points are awarded for completing specific tasks or assignments within the platform. Challenges: Participation in and successful completion of special challenges will earn participants points. Events: Engaging in hackathon events, workshops, or similar activities will contribute to the point total. Performance: Achieving notable milestones or high scores in tasks or challenges will be rewarded with points.

Badges: Purpose: Badges serve as symbols of achievement or expertise, providing visual recognition of accomplishments. Usage: Assign badges to mark significant milestones or skills. For example, a “TypeRace Champion” badge could be awarded for winning a specific challenge. Points:

Unit of Measurement: Points will be the primary metric used to rank and reward participants. Balance: Ensure fair distribution of points to avoid skewed competition and maintain participant motivation. Leaderboard:

Real-Time Updates: Display team rankings in real-time to keep the competition dynamic and engaging. Sorting: Sort teams based on their point totals, with options to view different metrics and performance indicators. Feedback and Adaptation:

group-pictures-06df9033de5141a930bc5a5c6ed71acf

07b9f929-77bf-4913-ad6e-48cdde3bfeef-2t

User Feedback: Collect feedback from participants to refine and enhance the gamification system, ensuring it meets user expectations. Metrics and Analytics: Track engagement and performance metrics to assess the impact of the gamification features and make data-driven improvements. Endpoints:

Progress Page:

URL: https://cuhackplatform.com/user/progress/ Provides an overview of completed and ongoing events for individual users. Leaderboard Page:

URL: https://cuhackplatform.com/Leaderboard Displays real-time rankings of teams based on their accumulated points. History Page:

URL: https://cuhackplatform.com/History/2025/ Keeps track of the top 10 winners for each hackathon, providing historical performance data.

This will be a team based platform so its only reasonable if we look at only the teams points which is going to be the total of each individual points in the team. Database Schema:

User {
    int id "Primary key, unique"
    varchar first_name "First name of the user"
    varchar middle_name "Middle name of the user, optional"
    varchar last_name "Last name of the user"
    varchar preferred_name "Preferred name of the user, optional"
    varchar email "Email of the user, must be unique, verification required"
    date date_of_birth "Date of birth of the user, verification required"
    enum gender "Gender of the user, e.g., male, female, etc."
    enum phone_number_country_code "Country code of phone number, e.g., +1"
    varchar phone_number "Phone number of the user, must be unique, verification required"
    int hackathons_attended "Number of hackathons attended by the user"
    longtext any_other_comments "Any additional comments from the user"
    bool international_or_domestic "Whether the user is international or domestic, optional"
    enum ethnicity "Ethnicity of the user, optional"
    int estimated_grad_year "Estimated graduation year of the user, optional"
    enum mlh_reqs "MLH requirements, default is 'No'"
    int resume_id "References Resume.id, mandatory relationship"
    int school_id "References School.id, mandatory relationship"
    int emergency_contact_id "References EmergencyContact.id, mandatory relationship"
    int team_id "References Team.id, mandatory relationship"
int points "Acquired points, starts at 0p"
}

Team {
    int id "Primary key, unique"
    varchar name "Name of the team"
    varchar project_link_id "URL to the project, verification required"
    int team_admin "References User.id, one-to-one relationship"
    bool has_submitted "Whether the team has submitted a project, default is 'No'"
int team_points "Total number of points of each user in the team, References User.points"
}
cloverzer0 commented 2 months ago

Screen Shot 2024-08-31 at 12 45 01 AM

cloverzer0 commented 2 months ago

Summary of what muktar and I did, could be useful for others when they write unit tests for components and complex structures: --HOW TO DO UNIT TEST FOR LEADERBOARDS---

Examples of failing test w/assertions

TESTS FOR LEADERBOARD POSITIONS (test for a funciton that determines leaderboard positions) --> expect(team[2]).toBe(1) --> expect(team[1]).toBe(2) --> expect(team[0]).toBe(3)

TESTS FOR TOTAL TEAM POINTS (test for a function that determines team points) -->expect(team[0]).toBe(150) -->expect(team[1]).toBe(110)

TEST FOR INDIVIDUAL POINTS (sanity test) --> expect(person[0]).toBe(20) --> expect(person[1]).toBe(50)

MOCK DATA

Mock data for users (simplified)

const mockUsers = [
    {
        name: "Hasith"
        point: 10
        team_id: 12
    },
    {
        name: "Muktar"
        points: 20
        team_id: 5
    },
    {
        name: "Farabi"
        points: 12,
        team_id: 3
    },
    {
        name: "Jowi"
        points: 22,
        team_id: 5
    }
]

Mock data for teams (simplified)

const mockTeams = [
    {
        team_id: 5
        total_points: 42
        team_name: "Husky"
    }, 
    {
        team_id: 3
        total_points: 12
        team_name: "Husky"
    },
    {
        team_id: 12
        total_points: 10
        team_name: "Husky"
    }
]

team 5 points: 42 team 3 points: 12 team 12 points: 10

HOW TO MOCK AN API CALL

import { vi } from 'vitest';
import axios from 'axios';
import { mockUsers } from 'data/mock/users';
import { mockTeams } from 'data/mock/team';

vi.mock('axios', () => ({
  get: vi.fn(() =>
    Promise.resolve({
      data: {
        users: mockUsers,
        team: mockTeams
      },
    })
  ),
}));

Example test (not how the code will actually look)

describe('Team Leader Component', () => {
  it('renders a leaderboard that keeps track of team points', async () => {
    render(
      <Leaderboard
        teams={mockTeams}
      />
    );

    // Check that the events are rendered
    expect(await screen.findByText('Event 1')).toBeInTheDocument();
    expect(await screen.findByText('Event 2')).toBeInTheDocument();
  });
});

DON'T GET CARRIED AWAY!! THINK CAREFULLY ABOUT YOUR DESIGN CHOICES