Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Changelog

## [1.1.0] — Engagement features release

### Added

- **Weekly Report Generator** (`client/src/components/WeeklyReport.jsx`)
Per-student weekly summary: SP gained/lost/net, attendance table, poll table,
consistency rate, auto-generated suggestions, and a "Download PDF" button
that opens the browser print dialog with a formatted report (no server-side
PDF generation needed).

- **Activity Heatmap** (`client/src/components/ActivityHeatmap.jsx`)
GitHub-style contribution grid showing daily SP activity over the last 16
weeks. Hover tooltips show date, SP earned, and session name. Tracks active
days, total SP, and current streak.

- **Student Search** (`client/src/components/StudentSearch.jsx`)
Instant client-side filtering by name or email, status pills (All/Active/
Excused), sort by SP or name, trophy league badges, rank medals for top 3,
pagination, and email masking for student-facing privacy.

- **Analytics Dashboard** (`client/src/components/AnalyticsDashboard.jsx`)
Admin-only dashboard: 8 stat cards (avg/max/min SP, active count, at-risk
count, avg attendance %, avg poll %, session count), SP distribution pie,
status breakdown donut, attendance/poll bar charts per session, weekly SP
trend line chart, trophy league distribution bar, and an at-risk students
table (SP < 100).

- **New pages**: `StudentDashboardPage.jsx` (student-facing) and
`AdminAnalyticsPage.jsx` (admin-facing) wiring the above components to live
API data via the new `useFetch` hook.

- **New server endpoints** in `server/server.js`:
`GET /api/me`, `GET /api/leaderboard`, `GET /api/students/search`,
`GET /api/admin/students`, `GET /api/student/:id`,
`GET /api/student/:id/transactions`, `GET /api/student/:id/attendance`,
`GET /api/student/:id/polls`, `GET /api/student/:id/weekly-report`,
`GET /api/sessions`, `GET /api/admin/chat-sp-reviews`,
`POST /api/admin/chat-sp-reviews/:id/accept`,
`POST /api/admin/chat-sp-reviews/:id/reject`,
`GET /api/admin/analytics/latest`.

- **New Mongoose models**: `Student`, `SPTransaction`, `Session`,
`AttendanceRecord`, `PollRecord`, `ChatRecord`, `ChatSPReview`,
`AnalyticsSnapshot`, `SessionEvent` — matching the schema documented in
`CONTEXT.md`.

- **Client scaffold**: Vite + React 18 + React Router + Recharts, with a
proxy from `/api` (port 5291) to the backend (port 5290) for local dev.

### Dependencies added

- `client/package.json`: `react-router-dom@^6.26.0`, `recharts@^2.12.7`,
`@vitejs/plugin-react@^4.3.1`, `vite@^5.4.1`

### Notes

- `AnalyticsDashboard` exposes all student emails and SP — gate the
`/admin/analytics` route behind admin auth before deploying.
- `StudentSearch` defaults to `allowFullSearch={false}` (masked emails); only
the admin page passes `allowFullSearch={true}`.
54 changes: 15 additions & 39 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
},
"dependencies": {
"@vitejs/plugin-react": "^4.3.4",
"vite": "^5.4.11",
"analysis-summership": "file:..",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {}
"react-dom": "^18.3.1",
"vite": "^5.4.11"
}
}
25 changes: 25 additions & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import StudentDashboardPage from './pages/StudentDashboardPage';
import AdminAnalyticsPage from './pages/AdminAnalyticsPage';

export default function App() {
return (
<BrowserRouter basename="/spurti">
<nav style={{ display: 'flex', gap: 16, padding: '14px 20px', borderBottom: '1px solid #e5e7eb',
fontFamily: "'Segoe UI',Arial,sans-serif", fontSize: 13 }}>
<Link to="/dashboard" style={{ color: '#4f46e5', fontWeight: 600, textDecoration: 'none' }}>
My Dashboard
</Link>
<Link to="/admin/analytics" style={{ color: '#4f46e5', fontWeight: 600, textDecoration: 'none' }}>
Admin Analytics
</Link>
</nav>

<Routes>
<Route path="/dashboard" element={<StudentDashboardPage />} />
<Route path="/admin/analytics" element={<AdminAnalyticsPage />} />
<Route path="/" element={<StudentDashboardPage />} />
</Routes>
</BrowserRouter>
);
}
Loading