Add student delight features: celebrations, sounds, animations, and background patterns
- Confetti + pop sound on lesson/assignment completion - Done stamp animation (awaitable, shows below toast) - Welcome toast on first login only (not back-navigation) - Web Audio ding/buzz during spelling practice and flashcards - Fanfare on all-day completion - Score counter animate-up on practice/test results - 3D flashcard flip animation (rotateY via CSS keyframes) - Tab slide transition (Today/Courses/Spelling, directional) - Staggered card entrance + time-of-day greeting on home screen - Emoji wobble on kid card hover - Word card green/red flash on correct/wrong spelling answer - Combo streak celebration at milestones (3, 5, 7, 10 in a row) - Random cheer messages for generic celebrations - Button bounce on :active (scale + translateY) - Progress bar smooth transition (0.5s ease-out) - Background pattern picker: dots, stripes, grid, stars, bubbles - bg_pattern persisted per-student via PATCH /api/students/:id/bg-pattern - Theme switching preserves bg pattern class Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f73acd03e
commit
61f9288aa5
5 files changed
+523
-13
No files matched your search
@@ -323,10 +323,11 @@ const GRADABLE_TYPES = ['assignment', 'quiz', 'matching', 'crossword', 'spelling
|
||||
// ---------- kid picker ----------
|
||||
|
||||
app.get('/api/students', (req, res) => {
|
||||
res.json(db.prepare(`SELECT id, name, emoji, theme, streak_count, streak_date FROM students ORDER BY name`).all());
|
||||
res.json(db.prepare(`SELECT id, name, emoji, theme, bg_pattern, streak_count, streak_date FROM students ORDER BY name`).all());
|
||||
});
|
||||
|
||||
const VALID_THEMES = ['blue','green','purple','orange','pink','red','teal','yellow','indigo'];
|
||||
const VALID_BG_PATTERNS = ['none','dots','stripes','grid','stars','bubbles'];
|
||||
|
||||
app.patch('/api/students/:id/theme', (req, res) => {
|
||||
const theme = VALID_THEMES.includes(req.body.theme) ? req.body.theme : 'blue';
|
||||
@@ -334,6 +335,12 @@ app.patch('/api/students/:id/theme', (req, res) => {
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
app.patch('/api/students/:id/bg-pattern', (req, res) => {
|
||||
const pattern = VALID_BG_PATTERNS.includes(req.body.pattern) ? req.body.pattern : 'none';
|
||||
db.prepare(`UPDATE students SET bg_pattern = ? WHERE id = ?`).run(pattern, req.params.id);
|
||||
res.json({ ok: true });
|
||||
});
|
||||
|
||||
app.patch('/api/students/:id/emoji', (req, res) => {
|
||||
const emoji = req.body.emoji ? String(req.body.emoji).trim() : null;
|
||||
if (!emoji) return res.status(400).json({ error: 'emoji required' });
|
||||
@@ -361,7 +368,7 @@ app.post('/api/students/:id/complete-day', (req, res) => {
|
||||
// Everything the standalone spelling home screen needs
|
||||
app.get('/api/state/:studentId', (req, res) => {
|
||||
const id = req.params.studentId;
|
||||
const student = db.prepare(`SELECT id, name, emoji, theme FROM students WHERE id = ?`).get(id);
|
||||
const student = db.prepare(`SELECT id, name, emoji, theme, bg_pattern FROM students WHERE id = ?`).get(id);
|
||||
if (!student) return res.status(404).json({ error: 'No such student' });
|
||||
|
||||
const assignment = db.prepare(`
|
||||
|
||||
Reference in new issue
Block a user