feat: add Spurti Recognition & Growth Hub - achievement gallery, cert… - #101
Open
kwalgovind1011 wants to merge 1 commit into
Open
feat: add Spurti Recognition & Growth Hub - achievement gallery, cert…#101kwalgovind1011 wants to merge 1 commit into
kwalgovind1011 wants to merge 1 commit into
Conversation
…ificates, goal tracking, forecast, and reward redemption Co-authored-by: Ankita Choudhary <ankitachoudhary95773@gmail.com> Co-authored-by: Swati Kumari <swatikumari301204@gmail.com>
kwalgovind1011
force-pushed
the
feat/recognition-growth-hub
branch
from
July 21, 2026 05:51
79f348a to
8979549
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
possible badge (Top 50, Top 10, Consistent Attendee, Poll Champion, Above
Average, Legend Badge) — not just the ones already earned.
criteria, so students know exactly what to work toward next, not just
what they've already achieved.
buildBadges()logic — added a newbuildAchievementGallery()function rather than modifying the original,so nothing that currently depends on
buildBadges()is affected.Milestone Certificate
auto-generated certificate appears — rendered entirely client-side via
the HTML5 Canvas API (no image assets or server-side rendering needed).
on LinkedIn" button (opens a pre-filled LinkedIn share dialog).
computed from data the profile payload already returns
(
legendBadgeUnlocked,rank), so no new backend logic was needed forthis part.
📈 Growth Layer
Weekly Goal Tracker
live progress bar (SP earned this week vs. target).
(
weekStart()helper), so progress resets automatically without needinga cron job or scheduled task.
Studentmodel:weeklyGoalSpandweeklyGoalSetAt. A newPOST /api/goalendpoint lets a student updatetheir target; the response is the full updated profile so the UI stays
in sync in one round trip.
SP Forecast & Pace Planner
on their average SP earned per completed session so far.
Sessionrecords into completed vs. remaining (bycomparing
endDateTimeto now), and calculates average pace fromattendance/pollcategorySPTransactionentries — no new databasemodel was needed for this.
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.
crash), and zero remaining sessions (shows "not reachable this cohort"
instead of dividing by zero).
🎁 Rewards Layer
SP Redemption Marketplace
rewards: Resume Review (150 SP), Spurti Swag Kit (100 SP), Course
Discount Code (200 SP), Priority Mentor Session (250 SP).
earlier UI-only version of this idea — reward costs live in a
server-side constant (
REWARD_CATALOG) so the client can never submitits 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).
RewardRedemptionmodel tracks what was redeemed, when, and itsfulfilment status — kept separate from
SPTransaction(which justrecords the point movement) so admins get a clean, readable view of
what students are actually redeeming.
SPTransactionentry (category:manual, negative delta), so it shows up correctly in the student'sexisting SP Bank statement — no special-casing needed there.
GET /api/rewards/catalog(public reward list),POST /api/redeem(redeem a reward),GET /api/redeem/history(a student's own redemption history).
Testing
with sample sessions and transactions (past + future sessions, partial
attendance/poll data).
weekly goal not yet set, insufficient SP for any reward.
reflects the updated balance without a page reload.
Files changed
server/models/Student.js— addedweeklyGoalSp,weeklyGoalSetAtserver/models/RewardRedemption.js— new modelserver/server.js— forecast calculation instudentPayload; new routes:/api/goal,/api/rewards/catalog,/api/redeem,/api/redeem/historyclient/src/main.jsx— new components:AchievementGallery,MilestoneCertificate,WeeklyGoalWidget,ForecastWidget,RedemptionMarketplaceclient/src/styles.css— styling for all five new components