feat: implement R42 chat infrastructure with Anthropic API integration and custom design system
All checks were successful
On Push to Main / test (push) Successful in 30s
On Push to Main / publish (push) Successful in 57s
On Push to Main / deploy-dev (push) Successful in 1m31s

This commit is contained in:
RaymondVerhoef
2026-05-17 16:48:40 +02:00
parent 43d01dff58
commit 98e32d8ac0
21 changed files with 2631 additions and 6 deletions

View File

@@ -10,9 +10,21 @@ import Button from '../components/ui/Button';
import Tag from '../components/ui/Tag';
import { useApp } from '../store/AppContext';
import { generateWeeklyQuiz, getCachedQuiz, saveTestResult, getTestResult } from '../lib/testService';
import { storage } from '../lib/storage';
const TIMER_SECONDS = 300; // 5 minutes
function setQuizActive(userId, active) {
if (!userId) return;
if (active) storage.set(`quiz:active:${userId}`, true);
else storage.remove(`quiz:active:${userId}`);
try {
window.dispatchEvent(new CustomEvent('respellion:quiz-state', { detail: { active } }));
} catch {
// ignore
}
}
// ─── Helper: format mm:ss ──────────────────────────────────
function formatTime(sec) {
const m = Math.floor(sec / 60);
@@ -65,6 +77,19 @@ const Testen = () => {
return () => clearInterval(timerRef.current);
}, [phase]);
// ── Clear quiz-active flag whenever we leave the quiz phase or unmount ──
useEffect(() => {
if (phase !== 'quiz' && currentUser) {
setQuizActive(currentUser.id, false);
}
}, [phase, currentUser]);
useEffect(() => {
return () => {
if (currentUser) setQuizActive(currentUser.id, false);
};
}, [currentUser]);
// ── Start quiz ──
const startQuiz = async () => {
setPhase('loading');
@@ -76,6 +101,7 @@ const Testen = () => {
setAnswers({});
setShowFeedback(false);
setTimeLeft(TIMER_SECONDS);
setQuizActive(currentUser.id, true);
setPhase('quiz');
} catch (e) {
setError(e.message);