LoopKitFrontend
Import & Export Hooks
useImport, useExport, and useTags hooks
useImport
Import flashcards from CSV or JSON files.
import { useImport } from '@loopkit/react';
function ImportPage() {
const { loading, error, result, importCSV, importJSON } = useImport();
}Return Type
interface UseImportReturn {
loading: boolean;
error: string | null;
result: ImportResult | null;
importCSV: (
file: File,
mapping: Record<string, string>,
deckId: string,
noteTypeId: string,
tags?: string[],
) => Promise<ImportResult>;
importJSON: (file: File) => Promise<ImportResult>;
}Example: CSV Import
function CSVImporter({ deckId, noteTypeId }: { deckId: string; noteTypeId: string }) {
const { importCSV, loading, result, error } = useImport();
const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
await importCSV(
file,
{ question: 'Front', answer: 'Back' },
deckId,
noteTypeId,
);
};
return (
<div>
<input type="file" accept=".csv" onChange={handleFile} disabled={loading} />
{result && (
<p>
Imported {result.notesCreated} notes, {result.cardsCreated} cards
{result.errors.length > 0 && ` (${result.errors.length} errors)`}
</p>
)}
{error && <p>{error}</p>}
</div>
);
}useExport
Export deck data as CSV or JSON files.
import { useExport } from '@loopkit/react';
function ExportPage() {
const { loading, error, exportCSV, exportJSON } = useExport();
}Return Type
interface UseExportReturn {
loading: boolean;
error: string | null;
exportCSV: (deckId: string) => Promise<void>;
exportJSON: (deckId: string, includeReviewLogs?: boolean) => Promise<void>;
}Both methods trigger a browser file download automatically.
Example
function ExportButtons({ deckId }: { deckId: string }) {
const { exportCSV, exportJSON, loading } = useExport();
return (
<div>
<button onClick={() => exportCSV(deckId)} disabled={loading}>
Export CSV
</button>
<button onClick={() => exportJSON(deckId, true)} disabled={loading}>
Export JSON (with review logs)
</button>
</div>
);
}useTags
Fetches all unique tags across all notes.
import { useTags } from '@loopkit/react';
function TagFilter() {
const { tags, loading, error, refetch } = useTags();
}Return Type
interface UseTagsReturn {
tags: string[];
loading: boolean;
error: string | null;
refetch: () => Promise<void>;
}Tags are fetched on mount and can be refreshed with refetch(). The hook calls GET /tags on the API.
Example: Tag Filter
function TagFilter({ onFilterChange }: { onFilterChange: (tags: string[]) => void }) {
const { tags, loading } = useTags();
const [selected, setSelected] = useState<string[]>([]);
const toggle = (tag: string) => {
const next = selected.includes(tag)
? selected.filter((t) => t !== tag)
: [...selected, tag];
setSelected(next);
onFilterChange(next);
};
if (loading) return <p>Loading tags...</p>;
return (
<div>
{tags.map((tag) => (
<button
key={tag}
onClick={() => toggle(tag)}
style={{ fontWeight: selected.includes(tag) ? 'bold' : 'normal' }}
>
{tag}
</button>
))}
</div>
);
}