'use client'
/**
* SpreadsheetTab — Fortune Sheet editor for vocabulary data.
*
* Converts VocabularyEntry[] into a Fortune Sheet workbook
* where users can edit vocabulary in a familiar Excel-like UI.
*/
import React, { useMemo, useCallback } from 'react'
import dynamic from 'next/dynamic'
import type { VocabWorksheetHook } from '../types'
const Workbook = dynamic(
() => import('@fortune-sheet/react').then((m) => m.Workbook),
{ ssr: false, loading: () =>
Spreadsheet wird geladen...
},
)
import '@fortune-sheet/react/dist/index.css'
/** Convert VocabularyEntry[] to Fortune Sheet sheet data */
function vocabToSheet(vocabulary: VocabWorksheetHook['vocabulary']) {
const headers = ['Englisch', 'Deutsch', 'Beispielsatz', 'Wortart', 'Seite']
const numCols = headers.length
const numRows = vocabulary.length + 1 // +1 for header
const celldata: any[] = []
// Header row
headers.forEach((label, c) => {
celldata.push({
r: 0,
c,
v: { v: label, m: label, bl: 1, bg: '#f0f4ff', fc: '#1e293b' },
})
})
// Data rows
vocabulary.forEach((entry, idx) => {
const r = idx + 1
celldata.push({ r, c: 0, v: { v: entry.english, m: entry.english } })
celldata.push({ r, c: 1, v: { v: entry.german, m: entry.german } })
celldata.push({ r, c: 2, v: { v: entry.example_sentence || '', m: entry.example_sentence || '' } })
celldata.push({ r, c: 3, v: { v: entry.word_type || '', m: entry.word_type || '' } })
celldata.push({ r, c: 4, v: { v: entry.source_page != null ? String(entry.source_page) : '', m: entry.source_page != null ? String(entry.source_page) : '' } })
})
// Column widths
const columnlen: Record = {
'0': 180, // Englisch
'1': 180, // Deutsch
'2': 280, // Beispielsatz
'3': 100, // Wortart
'4': 60, // Seite
}
// Row heights
const rowlen: Record = {}
rowlen['0'] = 28 // header
// Borders: light grid
const borderInfo = numRows > 0 && numCols > 0 ? [{
rangeType: 'range',
borderType: 'border-all',
color: '#e5e7eb',
style: 1,
range: [{ row: [0, numRows - 1], column: [0, numCols - 1] }],
}] : []
return {
name: 'Vokabeln',
id: 'vocab_sheet',
celldata,
row: numRows,
column: numCols,
status: 1,
config: {
columnlen,
rowlen,
borderInfo,
},
}
}
export function SpreadsheetTab({ h }: { h: VocabWorksheetHook }) {
const { isDark, glassCard, vocabulary } = h
const sheets = useMemo(() => {
if (!vocabulary || vocabulary.length === 0) return []
return [vocabToSheet(vocabulary)]
}, [vocabulary])
const estimatedHeight = Math.max(500, (vocabulary.length + 2) * 26 + 80)
const handleSaveFromSheet = useCallback(async () => {
await h.saveVocabulary()
}, [h])
if (vocabulary.length === 0) {
return (
Keine Vokabeln vorhanden. Bitte zuerst Seiten verarbeiten.
)
}
return (
Spreadsheet-Editor
{vocabulary.length} Vokabeln
{sheets.length > 0 && (
)}
)
}