(SP: 1) [Frontend] Improve Lighthouse Performance and SEO scores for quiz pages#272
Conversation
…(issues #181, #193, #194) - Refactor QaTabButton to shared CategoryTabButton component - Add category accent colors to QuizCard, buttons, progress indicators - Standardize colors with CSS variables, traffic light timer - Add DynamicGridBackground to quizzes list page - Border-only answer feedback, semi-transparent progress styles
Changed violationsCount > 3 to >= 3 in QuizResult points block to match the warning banner threshold at line 124.
- Configure Vitest for quiz module - Add test factories and setup utilities - Add quiz-crypto tests (13 tests) - Add quiz-session tests (12 tests)
…eat hook (#199) - verify-answer.test.ts: 8 tests for API endpoint - Correct/wrong answer verification - Validation errors (missing fields, tampered data) - Security: rejects modified encrypted answers - quiz-anticheat.test.ts: 10 tests for useAntiCheat hook - Detects copy, paste, context-menu, tab-switch events - Respects isActive flag - Reset and cleanup functionality Total quiz tests: 52 (9 setup + 25 unit + 18 integration)
…UI flow Add 28 new tests covering: - useQuizSession hook (6 tests) - useQuizGuards hook (8 tests) - guest-quiz storage (5 tests) - guest-result API route (5 tests) - quiz-slug API route (3 tests) - QuizContainer UI flow (1 test) Coverage: 35% -> 90.94% (quiz scope) Tests: 52 -> 80
Closes #260, #261, #262 - Add quiz-answers-redis.ts with getOrCreateQuizAnswersCache() - Cache correct answers per quiz (12h TTL) - Replace AES-256-GCM decryption with O(1) Redis lookup - Add initializeQuizCache server action - Update verify-answer route to use Redis - Allow restoring 'completed' sessions (not just 'in_progress') - Only clear session for authenticated users after submit - Guest result screen now survives language switch - Delete PendingResultHandler.tsx (never executes) - Delete start-session/route.ts (broken import, unused) - Delete quiz-crypto.ts (AES replaced by Redis) - Delete quiz-crypto.test.ts (tests dead code) - Rewrite verify-answer.test.ts for Redis API (8 tests) - Fix quiz-session.test.ts for completed session restore
Part of #262 cleanup - route had broken import after Redis migration.
- Validate seed param to prevent NaN breaking question shuffle - Add cache recovery in verify-answer when Redis cache expires - Add DB fallback in getCorrectAnswer when Redis unavailable
Add isQuizzesPath to MainSwitcher to exclude /quiz and /quizzes routes from extra px-6 padding, matching Q&A page behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused Font Awesome CSS import (render-blocking, ~780ms savings) - Add generateMetadata for /quizzes page with i18n support - Add generateMetadata for /quiz/[slug] page with dynamic title/description - Add meta translations to en.json, uk.json, pl.json - Replace emoji with lucide-react Clock icon in CountdownTimer - Add .browserslistrc to target modern browsers (reduce polyfills ~14 KiB)
- Add touch detection to anti-cheat to prevent false contextmenu violations on mobile - Add select-none and webkit-touch-callout CSS to prevent text selection - Fix timer progress bar jump on navigation using isSynced state - Fix TypeScript error in quiz metadata description
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Deploy Preview for develop-devlovers ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughAdds browserslist config, dynamic metadata generation for quizzes, removes Font Awesome import, refactors the quiz countdown timer (icon and sync logic), extends i18n keys for quiz metadata, enhances anti-cheat touch detection, and adds a force-delete option to the quiz seeding script. Changes
Sequence Diagram(s)sequenceDiagram
participant Req as Request (locale, slug)
participant GM as generateMetadata
participant I18n as i18n loader
participant API as Quiz API
participant Next as Next.js
Note over Req,Next: Page request triggers metadata generation
Req->>GM: invoke generateMetadata(params)
GM->>I18n: loadTranslations(locale, namespace)
GM->>API: fetchQuiz(slug) (detail page only)
API-->>GM: quiz | null
I18n-->>GM: translation strings
GM->>Next: return Metadata { title, description } or notFound metadata
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Reset isSynced state when endTime changes to prevent transition jump - Reset isSynced on tab visibility change for instant sync - Add --force flag to JS quiz seed for reseeding with existing attempts - Expand JS Fundamentals quiz from 10 to 40 questions
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/components/quiz/CountdownTimer.tsx`:
- Around line 24-41: Add a new useEffect in the CountdownTimer component that
runs when endTime changes and immediately resets isSynced to false and updates
remainingSeconds to the current computed value (e.g., Math.max(0,
Math.floor((endTime - Date.now())/1000))). This ensures the progress bar
transition is disabled until the next sync interval; reference the setIsSynced
and setRemainingSeconds setters and endTime in the effect dependency array.
Closes #271
Closes #273
Goal
Improve Lighthouse Performance (85->90+) and SEO (82->100) scores for quiz pages, fix timer UX issues, and resolve mobile anti-cheat false positives.
Scope
Expected impact
Out of scope
Summary by CodeRabbit
New Features
Improvements
Style
Chores