diff --git a/src/api/directus.js b/src/api/directus.js index a05e5f6..a4331c5 100644 --- a/src/api/directus.js +++ b/src/api/directus.js @@ -90,6 +90,26 @@ export async function getFeedPairs(userToken, lang = 'de', limit = 20) { return data } +// ── Fortschritt / EP ──────────────────────────────────────────────────────── + +// Verbucht eine gelöste Karte: aktualisiert EP, Streak und Pair-Statistik. +// Gibt { total_ep, streak_days, level } zurück. +export async function saveProgress({ pairId, correct, points, userToken }) { + const res = await fetch(`${BASE}/auth/progress`, { + method: 'POST', headers: auth(userToken), + body: JSON.stringify({ pair_id: pairId, correct: !!correct, points: points || 0 }), + }) + const data = await res.json().catch(() => ({})) + if (!res.ok) throw new Error(data.error || 'Fortschritt konnte nicht gespeichert werden.') + return data +} + +// Aktueller Gesamtfortschritt des Users (EP, Streak, Level) via /auth/me. +export async function getUserProgress(userToken) { + const me = await getMe(userToken) + return { total_ep: me.total_ep || 0, streak_days: me.streak_days || 0, level: me.level || 0 } +} + // ── Stubs (content-Endpunkte kommen später) ─────────────────────────────────── export async function getActiveLearningPair() { return null } @@ -97,8 +117,6 @@ export async function addPointsToPair() { return false } export async function getWords() { return [] } export async function getQuestions() { return [] } export async function getQAPairsAtLevel() { return [] } -export async function getUserProgress() { return [] } -export async function saveProgress() { return null } export function assetUrl(fileId) { return fileId || null } export async function getProfilData(userToken) { return getMe(userToken) } export async function addPointsToUser() { return true } diff --git a/src/pages/Feed.jsx b/src/pages/Feed.jsx index de12d06..460e2ed 100644 --- a/src/pages/Feed.jsx +++ b/src/pages/Feed.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import './Feed.css' import { useAuth } from '../context/AuthContext' -import { getFeedPairs } from '../api/directus' +import { getFeedPairs, saveProgress, getUserProgress } from '../api/directus' import PairSentenceCard from '../components/PairSentenceCard' import PairYesNoCard from '../components/PairYesNoCard' import PairWordCard from '../components/PairWordCard' @@ -23,6 +23,7 @@ export default function Feed() { const [done, setDone] = useState(new Set()) const [loading, setLoading] = useState(true) const [empty, setEmpty] = useState(false) + const [totalEp, setTotalEp] = useState(null) // Target language from user profile, fall back to 'de' const lang = user?.language_target_short || 'de' @@ -38,8 +39,23 @@ export default function Feed() { .finally(() => setLoading(false)) }, [token, lang]) - function handleComplete(item) { + useEffect(() => { + getUserProgress(token) + .then(p => setTotalEp(p.total_ep)) + .catch(() => {}) + }, [token]) + + function handleComplete(item, result) { setDone(prev => new Set([...prev, item.meta.pairId])) + const correct = result === 'correct' + saveProgress({ + pairId: item.meta.pairId, + correct, + points: correct ? item.meta.points : 0, + userToken: token, + }) + .then(res => { if (res?.total_ep != null) setTotalEp(res.total_ep) }) + .catch(err => console.error('saveProgress error', err)) } const visible = cards.filter(c => !done.has(c.meta.pairId)) @@ -68,9 +84,19 @@ export default function Feed() { return (