feat: implement content management dashboard and update proxy configurations to support AI-assisted learning material generation
This commit is contained in:
@@ -16,8 +16,8 @@ const ContentManager = () => {
|
||||
const [actionState, setActionState] = useState({}); // { [topicId]: { loading, error, success } }
|
||||
const [refineText, setRefineText] = useState('');
|
||||
|
||||
const refresh = () => {
|
||||
const fresh = getAllGeneratedContent();
|
||||
const refresh = async () => {
|
||||
const fresh = await getAllGeneratedContent();
|
||||
setItems(fresh);
|
||||
// Keep detail view in sync if its topic was updated
|
||||
if (selected) {
|
||||
@@ -56,8 +56,8 @@ const ContentManager = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (topicId) => {
|
||||
deleteCachedContent(topicId);
|
||||
const handleDelete = async (topicId) => {
|
||||
await deleteCachedContent(topicId);
|
||||
if (selected?.topic.id === topicId) setSelected(null);
|
||||
setActionState(prev => { const n = { ...prev }; delete n[topicId]; return n; });
|
||||
refresh();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import PocketBase from 'pocketbase';
|
||||
|
||||
const pbUrl = import.meta.env.VITE_PB_URL ||
|
||||
(typeof window !== 'undefined' ? window.location.origin + '/pb' : 'http://localhost:8090');
|
||||
(typeof window !== 'undefined' ? window.location.origin : 'http://localhost:8090');
|
||||
|
||||
export const pb = new PocketBase(pbUrl);
|
||||
|
||||
@@ -53,14 +53,14 @@ const Leren = () => {
|
||||
}
|
||||
}, [state.currentUser, state.weekNumber]);
|
||||
|
||||
const handleOpenTopic = (topic) => {
|
||||
const handleOpenTopic = async (topic) => {
|
||||
setActiveTopic(topic);
|
||||
setView('detail');
|
||||
setSessionDone(false);
|
||||
setError(null);
|
||||
setFeedbackText('');
|
||||
setFeedbackPrompted(false);
|
||||
const cached = getCachedContent(topic.id);
|
||||
const cached = await getCachedContent(topic.id);
|
||||
if (cached) {
|
||||
setContent(cached);
|
||||
} else {
|
||||
|
||||
@@ -37,11 +37,14 @@ const Testen = () => {
|
||||
// ── Check for existing result ──
|
||||
useEffect(() => {
|
||||
if (currentUser) {
|
||||
const existing = getTestResult(currentUser.id, weekNumber);
|
||||
if (existing) {
|
||||
setResult(existing);
|
||||
setPhase('results');
|
||||
}
|
||||
const check = async () => {
|
||||
const existing = await getTestResult(currentUser.id, weekNumber);
|
||||
if (existing) {
|
||||
setResult(existing);
|
||||
setPhase('results');
|
||||
}
|
||||
};
|
||||
check();
|
||||
}
|
||||
}, [currentUser, weekNumber]);
|
||||
|
||||
@@ -98,7 +101,7 @@ const Testen = () => {
|
||||
};
|
||||
|
||||
// ── Finish quiz & score ──
|
||||
const finishQuiz = useCallback(() => {
|
||||
const finishQuiz = useCallback(async () => {
|
||||
clearInterval(timerRef.current);
|
||||
if (!quiz) return;
|
||||
|
||||
@@ -129,7 +132,7 @@ const Testen = () => {
|
||||
breakdown,
|
||||
};
|
||||
|
||||
const { pointsEarned } = saveTestResult(currentUser.id, weekNumber, testResult);
|
||||
const { pointsEarned } = await saveTestResult(currentUser.id, weekNumber, testResult);
|
||||
testResult.pointsEarned = pointsEarned;
|
||||
setResult(testResult);
|
||||
setPhase('results');
|
||||
|
||||
@@ -38,8 +38,13 @@ export function AppProvider({ children }) {
|
||||
let members = await db.getTeamMembers();
|
||||
|
||||
if (!members || members.length === 0) {
|
||||
const created = await db.addTeamMember({ name: 'Admin', role: 'admin', pin: '0000' });
|
||||
members = [created];
|
||||
try {
|
||||
const created = await db.addTeamMember({ name: 'Admin', role: 'admin', pin: '0000' });
|
||||
members = [created];
|
||||
} catch (e) {
|
||||
console.warn('[AppContext] Could not auto-create admin user:', e.message,
|
||||
'— Run scripts/setup-pb-collections.mjs to configure the database.');
|
||||
}
|
||||
}
|
||||
|
||||
const storedWeek = Number(await db.getSetting('admin:current_week', 1));
|
||||
|
||||
Reference in New Issue
Block a user