diff --git a/Caddyfile b/Caddyfile index 0a1d66a..cb63768 100644 --- a/Caddyfile +++ b/Caddyfile @@ -1,7 +1,4 @@ :80 { - root * /srv - file_server - encode gzip zstd header { @@ -13,16 +10,6 @@ Permissions-Policy "geolocation=(), microphone=(), camera=()" } - @static { - path *.css *.js *.png *.jpg *.jpeg *.gif *.webp *.svg *.woff *.woff2 *.ttf - } - header @static Cache-Control "public, max-age=31536000, immutable" - - @html { - path *.html / - } - header @html Cache-Control "public, max-age=0, must-revalidate" - handle /api/anthropic/* { uri strip_prefix /api/anthropic reverse_proxy https://api.anthropic.com { @@ -30,7 +17,22 @@ } } - try_files {path} /index.html + handle { + root * /srv + + @static { + path *.css *.js *.png *.jpg *.jpeg *.gif *.webp *.svg *.woff *.woff2 *.ttf + } + header @static Cache-Control "public, max-age=31536000, immutable" + + @html { + path *.html / + } + header @html Cache-Control "public, max-age=0, must-revalidate" + + try_files {path} /index.html + file_server + } handle_errors { rewrite * /index.html diff --git a/src/pages/Leren.jsx b/src/pages/Leren.jsx index e857b84..70114a4 100644 --- a/src/pages/Leren.jsx +++ b/src/pages/Leren.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { BookOpen, CheckCircle, Loader, ArrowRight, Plus, Search, ChevronLeft } from 'lucide-react'; +import { BookOpen, CheckCircle, Loader, ArrowRight, Plus, Search, ChevronLeft, MessageSquare } from 'lucide-react'; import { motion, AnimatePresence } from 'framer-motion'; import { Link } from 'react-router-dom'; import Card from '../components/ui/Card'; @@ -32,6 +32,11 @@ const Leren = () => { const [weeklyDone, setWeeklyDone] = useState(false); const [sessionDone, setSessionDone] = useState(false); + // Feedback + const [showFeedbackModal, setShowFeedbackModal] = useState(false); + const [feedbackText, setFeedbackText] = useState(''); + const [feedbackPrompted, setFeedbackPrompted] = useState(false); + useEffect(() => { if (state.currentUser) { const assigned = getAssignedTopic(state.currentUser.id, state.weekNumber); @@ -48,6 +53,8 @@ const Leren = () => { setView('detail'); setSessionDone(false); setError(null); + setFeedbackText(''); + setFeedbackPrompted(false); const cached = getCachedContent(topic.id); if (cached) { setContent(cached); @@ -90,7 +97,7 @@ const Leren = () => { } }; - const handleComplete = () => { + const doComplete = () => { setSessionDone(true); if (!weeklyDone) { setWeeklyDone(true); @@ -98,6 +105,33 @@ const Leren = () => { } }; + const handleComplete = () => { + if (!feedbackPrompted) { + setFeedbackPrompted(true); + setShowFeedbackModal(true); + return; + } + doComplete(); + }; + + const handleSubmitFeedback = () => { + if (feedbackText.trim()) { + storage.set(`user:${state.currentUser.id}:feedback:${activeTopic.id}`, { + text: feedbackText.trim(), + topicId: activeTopic.id, + week: state.weekNumber, + timestamp: Date.now(), + }); + } + setShowFeedbackModal(false); + doComplete(); + }; + + const handleSkipFeedback = () => { + setShowFeedbackModal(false); + doComplete(); + }; + // ── Detail View ────────────────────────────────────────── if (view === 'detail' && activeTopic) { if (sessionDone) { @@ -123,6 +157,50 @@ const Leren = () => { return (
+ + {showFeedbackModal && ( + + + +
+
+ +
+

How was this content?

+
+

+ Your feedback helps improve future learning content. This is optional — you can skip if you prefer. +

+