Skip to content

feat: add Spurti Recognition & Growth Hub - achievement gallery, cert… - #101

Open
kwalgovind1011 wants to merge 1 commit into
vicharanashala:mainfrom
kwalgovind1011:feat/recognition-growth-hub
Open

feat: add Spurti Recognition & Growth Hub - achievement gallery, cert…#101
kwalgovind1011 wants to merge 1 commit into
vicharanashala:mainfrom
kwalgovind1011:feat/recognition-growth-hub

Conversation

@kwalgovind1011

Copy link
Copy Markdown

Overview

This PR introduces the Spurti Recognition & Growth Hub — a unified
system that combines recognition, forward-looking growth tracking, and
tangible rewards into the student dashboard.

The design is inspired by how real companies run employee recognition and
rewards programs (e.g. Bonusly, Achievers, Motivosity) — platforms built
around a simple loop: Earn → Track → Showcase → Redeem. Instead of
shipping three unrelated features, this PR ties them into one cohesive
system, each layer feeding into the next.


🏅 Recognition Layer

Achievement Gallery

  • Adds a new "Achievements" tab on the student dashboard showing every
    possible badge (Top 50, Top 10, Consistent Attendee, Poll Champion, Above
    Average, Legend Badge) — not just the ones already earned.
  • Locked badges are shown greyed out with a 🔒 icon and their unlock
    criteria, so students know exactly what to work toward next, not just
    what they've already achieved.
  • Built on top of the existing buildBadges() logic — added a new
    buildAchievementGallery() function rather than modifying the original,
    so nothing that currently depends on buildBadges() is affected.

Milestone Certificate

  • When a student unlocks the Legend Badge (1500+ SP) or reaches Top 10, an
    auto-generated certificate appears — rendered entirely client-side via
    the HTML5 Canvas API (no image assets or server-side rendering needed).
  • Includes a "Download Certificate" button (exports as PNG) and a "Share
    on LinkedIn" button (opens a pre-filled LinkedIn share dialog).
  • Certificate only renders when the student is actually eligible — this is
    computed from data the profile payload already returns
    (legendBadgeUnlocked, rank), so no new backend logic was needed for
    this part.

📈 Growth Layer

Weekly Goal Tracker

  • Students can set a personal SP target for the current week and see a
    live progress bar (SP earned this week vs. target).
  • The "current week" is calculated Monday-based on the backend
    (weekStart() helper), so progress resets automatically without needing
    a cron job or scheduled task.
  • Added two new fields to the Student model: weeklyGoalSp and
    weeklyGoalSetAt. A new POST /api/goal endpoint lets a student update
    their target; the response is the full updated profile so the UI stays
    in sync in one round trip.

SP Forecast & Pace Planner

  • Projects a student's likely final SP by the end of the internship, based
    on their average SP earned per completed session so far.
  • Splits existing Session records into completed vs. remaining (by
    comparing endDateTime to now), and calculates average pace from
    attendance/poll category SPTransaction entries — no new database
    model was needed for this.
  • Includes a small interactive calculator: a student enters a target SP
    and immediately sees the pace per remaining session needed to hit it.
    This calculation runs entirely client-side (on data already in the
    profile response) to avoid an unnecessary extra API call.
  • Handles edge cases gracefully: zero completed sessions (pace shows 0, no
    crash), and zero remaining sessions (shows "not reachable this cohort"
    instead of dividing by zero).

🎁 Rewards Layer

SP Redemption Marketplace

  • Adds a "Redeem SP" tab where students can trade earned SP for real
    rewards: Resume Review (150 SP), Spurti Swag Kit (100 SP), Course
    Discount Code (200 SP), Priority Mentor Session (250 SP).
  • This includes the full backend that was previously missing from an
    earlier UI-only version of this idea — reward costs live in a
    server-side constant (REWARD_CATALOG) so the client can never submit
    its own price, balance is checked server-side before any deduction, and
    the whole redemption is atomic per-request (balance check → deduct →
    log transaction → record redemption).
  • New RewardRedemption model tracks what was redeemed, when, and its
    fulfilment status — kept separate from SPTransaction (which just
    records the point movement) so admins get a clean, readable view of
    what students are actually redeeming.
  • Every redemption also creates a normal SPTransaction entry (category:
    manual, negative delta), so it shows up correctly in the student's
    existing SP Bank statement — no special-casing needed there.
  • New endpoints: GET /api/rewards/catalog (public reward list),
    POST /api/redeem (redeem a reward), GET /api/redeem/history
    (a student's own redemption history).

Testing

  • Manually tested all three layers locally against a seeded test student
    with sample sessions and transactions (past + future sessions, partial
    attendance/poll data).
  • Verified zero-data edge cases don't crash: no sessions, no transactions,
    weekly goal not yet set, insufficient SP for any reward.
  • Confirmed redemption correctly deducts SP, logs a transaction, and
    reflects the updated balance without a page reload.

Files changed

  • server/models/Student.js — added weeklyGoalSp, weeklyGoalSetAt
  • server/models/RewardRedemption.js — new model
  • server/server.js — forecast calculation in studentPayload; new routes:
    /api/goal, /api/rewards/catalog, /api/redeem, /api/redeem/history
  • client/src/main.jsx — new components: AchievementGallery,
    MilestoneCertificate, WeeklyGoalWidget, ForecastWidget,
    RedemptionMarketplace
  • client/src/styles.css — styling for all five new components

…ificates, goal tracking, forecast, and reward redemption

Co-authored-by: Ankita Choudhary <ankitachoudhary95773@gmail.com>
Co-authored-by: Swati Kumari <swatikumari301204@gmail.com>
@kwalgovind1011
kwalgovind1011 force-pushed the feat/recognition-growth-hub branch from 79f348a to 8979549 Compare July 21, 2026 05:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant