'use client' import * as React from 'react' import { useState } from 'react' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Loader2, Save, FolderOpen, Eye, EyeOff, Key } from 'lucide-react' import { Header } from '@/components/Header' const DEFAULT_COURSES_ROOT = './My_Courses' const DEFAULT_QUIZ_API_SOURCE = 'quizapi' function parseBoolean(value: string | null | undefined) { return value === 'true' } export default function SettingsPage() { const [coursesRoot, setCoursesRoot] = useState(DEFAULT_COURSES_ROOT) const [autoFetchQuizzes, setAutoFetchQuizzes] = useState(false) const [quizApiSource, setQuizApiSource] = useState(DEFAULT_QUIZ_API_SOURCE) const [quizApiKey, setQuizApiKey] = useState('') const [showApiKey, setShowApiKey] = useState(false) const [saving, setSaving] = useState(false) const [status, setStatus] = useState<'idle' | 'success' | 'error'>('idle') const [statusMessage, setStatusMessage] = useState('') const fetchSettings = async () => { try { const res = await fetch('/api/settings') if (res.ok) { const data = await res.json() setCoursesRoot(data.coursesRoot || DEFAULT_COURSES_ROOT) setAutoFetchQuizzes(parseBoolean(data.autoFetchQuizzes)) setQuizApiSource(data.quizApiSource || DEFAULT_QUIZ_API_SOURCE) setQuizApiKey(data.quizApiKey || '') return } } catch (error) { console.error('Failed to fetch settings:', error) } setCoursesRoot(DEFAULT_COURSES_ROOT) setAutoFetchQuizzes(false) setQuizApiSource(DEFAULT_QUIZ_API_SOURCE) setQuizApiKey('') } const handleSave = async (e: React.FormEvent) => { e.preventDefault() setSaving(true) setStatus('idle') try { const saveSettings = { coursesRoot, autoFetchQuizzes: autoFetchQuizzes ? 'true' : 'false', quizApiSource, quizApiKey, } const res = await fetch('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(saveSettings), }) if (!res.ok) { const data = await res.json().catch(() => ({})) throw new Error(data?.error || 'Failed to save') } setStatus('success') setStatusMessage('Settings saved. Next scan will use the new directory.') } catch (error) { setStatus('error') setStatusMessage(error instanceof Error ? error.message : 'Failed to save settings') } finally { setSaving(false) } } React.useEffect(() => { fetchSettings() }, []) return (

Settings

Configure your OfflineAcademy preferences

Courses Directory The root folder where OfflineAcademy scans for courses. Use an absolute path for best results. Add course folders using the structure shown on the Scan page.
setCoursesRoot(e.target.value)} className="flex-1" disabled={saving} />

Current default: ./My_Courses

Quiz Settings

Source used when auto-fetching quiz content.

Fetch quiz data when a module is opened.

setAutoFetchQuizzes(event.target.checked)} disabled={saving} />
{quizApiSource === 'quizapi' && (
setQuizApiKey(e.target.value)} className="pr-10" disabled={saving} autoComplete="off" />

Get your key at quizapi.io. Stored securely in local database.

)}

Quiz settings

Auto-fetch is {autoFetchQuizzes ? 'enabled' : 'disabled'} with source {quizApiSource}.

{quizApiSource === 'quizapi' && quizApiKey && (

✓ QuizAPI key configured ({quizApiKey.length} characters)

)} {quizApiSource === 'quizapi' && !quizApiKey && (

⚠ QuizAPI selected but no API key configured. Quizzes will fall back to The Trivia API.

)}
{status === 'success' && (

Settings saved successfully.

)} {status === 'error' && (

{statusMessage}

)}
) }