[add] README.md [add] client/.gitignore [add] client/README.md [add] client/eslint.config.js [add] client/index.html [add] client/package.json [add] client/public/vite.svg [add] client/src/App.css [add] client/src/App.tsx [add] client/src/api.ts [add] client/src/assets/react.svg [add] client/src/components/EntryCard.tsx [add] client/src/components/ItemPanels.tsx [add] client/src/components/QuizRunner.tsx [add] client/src/components/VideoPlayer.tsx [add] client/src/index.css [add] client/src/main.tsx [add] client/src/pages/EntryPage.tsx [add] client/src/pages/OverviewPage.tsx [add] client/src/pages/QuizPage.tsx [add] client/src/types.ts [add] client/tsconfig.app.json [add] client/tsconfig.json [add] client/tsconfig.node.json [add] client/vite.config.ts [add] gemini_replicate_batch.py [add] package.json [add] prompt.txt [add] server/package.json [add] server/src/index.ts [add] server/tsconfig.json
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import EntryCard from '../components/EntryCard';
|
|
import { fetchEntries } from '../api';
|
|
import type { EntrySummary } from '../types';
|
|
|
|
export default function OverviewPage() {
|
|
const [entries, setEntries] = useState<EntrySummary[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
fetchEntries()
|
|
.then((data) => setEntries(data))
|
|
.catch(() => setError('Could not load entries'))
|
|
.finally(() => setLoading(false));
|
|
}, []);
|
|
|
|
if (loading) return <div className="loading">Loading entries…</div>;
|
|
if (error) return <div className="error">{error}</div>;
|
|
|
|
return (
|
|
<div>
|
|
<div className="page-header">
|
|
<div>
|
|
<p className="eyebrow">IG Japanese Quizzer</p>
|
|
<h1>Choose a reel to study</h1>
|
|
<p className="muted">Each card bundles grammar, vocab, phrases, and quizzes pulled from your local data folder.</p>
|
|
</div>
|
|
<Link className="button" to="/quiz">Jump to Quiz Wizard</Link>
|
|
</div>
|
|
{entries.length === 0 ? (
|
|
<div className="error">No entries detected in data/. Add mp4 + json pairs and restart the server.</div>
|
|
) : (
|
|
<div className="grid">
|
|
{entries.map((entry) => (
|
|
<EntryCard key={entry.id} entry={entry} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|