/* @component-map * App — Main container, tab navigation [app.jsx] * WordJournal — Add/manage vocabulary words [components/WordJournal.jsx] * QuizMode — Quiz testing on saved words [components/QuizMode.jsx] * WordList — Display and filter saved words [components/WordList.jsx] * Stats — Mastery statistics overview [components/Stats.jsx] * @end-component-map */ // DEPLOY_CONFIG: {"cron": [{"name": "daily-vocab-mini-quiz", "schedule": "0 9 * * *", "action": "event", "config": {"event_type": "vocab.daily_review"}}], "triggers": [{"name": "send-vocab-mini-quiz-email", "on": "event", "event_type": "vocab.daily_review", "actions": [{"type": "email", "to": "{{user.email}}", "subject": "Your daily vocabulary mini quiz", "body": "Here are your 5 words due for review today:\n\n{{#each dueWords}}\n- {{word}} — {{definition}}\n Last reviewed: {{lastReviewAt}}\n Next review: {{nextReviewAt}}\n{{/each}}\n\nReply with your answers to continue your spaced-repetition schedule."}]}]} import { useMemo, useState } from 'react'; import { WordJournal } from './components/WordJournal.jsx'; import { QuizMode } from './components/QuizMode.jsx'; import { WordList } from './components/WordList.jsx'; import { Stats } from './components/Stats.jsx'; import { useCollection } from '@deplixo/sdk'; import { exportCSV, exportJSON } from '@deplixo/sdk'; function ExportControls({ words, loading }) { const exportableWords = useMemo(() => { return (words || []).map((word) => ({ word: word.word ?? '', definition: word.definition ?? word.translation ?? '', pronunciation: word.pronunciation ?? '', example: word.example ?? '', language: word.language ?? '', mastery: word.mastery ?? 0, createdAt: word.createdAt ?? '', updatedAt: word.updatedAt ?? '', lastReviewAt: word.lastReviewAt ?? '', nextReviewAt: word.nextReviewAt ?? '', })); }, [words]); const handleCSV = () => { exportCSV(exportableWords, { filename: 'vocabulary-export.csv', columns: [ 'word', 'definition', 'pronunciation', 'example', 'language', 'mastery', 'createdAt', 'updatedAt', 'lastReviewAt', 'nextReviewAt', ], }); }; const handleJSON = () => { exportJSON(exportableWords, { filename: 'vocabulary-export.json' }); }; return (

Export Vocabulary

{loading ? 'Loading…' : `${exportableWords.length} words`}

Download your full vocabulary list as CSV or JSON. The export uses the words currently saved in your collection.

); } function App() { const [activeTab, setActiveTab] = useState('journal'); const { items: words, loading } = useCollection('vocabulary', { personal: true }); const tabs = [ { id: 'journal', label: '📖 Journal', icon: '📖' }, { id: 'list', label: '📚 Words', icon: '📚' }, { id: 'quiz', label: '🧠 Quiz', icon: '🧠' }, { id: 'stats', label: '📊 Stats', icon: '📊' }, { id: 'export', label: '⬇️ Export', icon: '⬇️' }, ]; return (

Vocabulary Journal

Build your language mastery, one word at a time

{activeTab === 'journal' && } {activeTab === 'list' && } {activeTab === 'quiz' && } {activeTab === 'stats' && } {activeTab === 'export' && }
); } ReactDOM.createRoot(document.getElementById("root")).render();