Website (14 monoliths split): - compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20) - quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11) - i18n.ts (1,173 → 8 language files) - unity-bridge (1,094 → 12), backlog (1,087 → 6) - training (1,066 → 8), rag (1,063 → 8) - Deleted index_original.ts (4,899 LOC dead backup) Studio-v2 (5 monoliths split): - meet/page.tsx (1,481 → 9), messages (1,166 → 9) - AlertsB2BContext.tsx (1,165 → 5 modules) - alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6) All existing imports preserved. Zero new TypeScript errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
134 lines
5.4 KiB
TypeScript
134 lines
5.4 KiB
TypeScript
'use client'
|
|
|
|
import type { UnitDefinition, GeneratedContent } from './types'
|
|
|
|
export function ContentTab({
|
|
units,
|
|
selectedUnit,
|
|
generatedContent,
|
|
isGenerating,
|
|
onSelectUnit,
|
|
onFetchUnits,
|
|
onGenerateH5P,
|
|
onGenerateWorksheet,
|
|
onDownloadPdf,
|
|
onClearContent,
|
|
}: {
|
|
units: UnitDefinition[]
|
|
selectedUnit: UnitDefinition | null
|
|
generatedContent: GeneratedContent | null
|
|
isGenerating: boolean
|
|
onSelectUnit: (unit: UnitDefinition) => void
|
|
onFetchUnits: () => void
|
|
onGenerateH5P: (unitId: string) => void
|
|
onGenerateWorksheet: (unitId: string) => void
|
|
onDownloadPdf: (unitId: string) => void
|
|
onClearContent: () => void
|
|
}) {
|
|
return (
|
|
<div className="space-y-6">
|
|
<h2 className="text-lg font-semibold text-gray-900">Content Generator</h2>
|
|
|
|
{/* Unit Selector */}
|
|
{units.length > 0 ? (
|
|
<div className="bg-white rounded-lg border border-gray-200 p-4">
|
|
<h3 className="font-medium text-gray-900 mb-3">Unit auswählen</h3>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2">
|
|
{units.map((unit) => (
|
|
<button
|
|
key={unit.unit_id}
|
|
onClick={() => onSelectUnit(unit)}
|
|
className={`
|
|
p-3 text-left rounded-lg border transition-colors
|
|
${selectedUnit?.unit_id === unit.unit_id
|
|
? 'border-primary-500 bg-primary-50'
|
|
: 'border-gray-200 hover:border-gray-300'
|
|
}
|
|
`}
|
|
>
|
|
<span className="font-medium text-gray-900">{unit.unit_id}</span>
|
|
<span className="text-xs text-gray-500 ml-2">{unit.template}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<button
|
|
onClick={onFetchUnits}
|
|
className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700"
|
|
>
|
|
Units laden
|
|
</button>
|
|
)}
|
|
|
|
{/* Generate Buttons */}
|
|
{selectedUnit && (
|
|
<div className="bg-white rounded-lg border border-gray-200 p-4">
|
|
<h3 className="font-medium text-gray-900 mb-3">
|
|
Content generieren für: <span className="text-primary-600">{selectedUnit.unit_id}</span>
|
|
</h3>
|
|
<div className="flex flex-wrap gap-3">
|
|
<button
|
|
onClick={() => onGenerateH5P(selectedUnit.unit_id)}
|
|
disabled={isGenerating}
|
|
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 flex items-center gap-2"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
</svg>
|
|
H5P generieren
|
|
</button>
|
|
<button
|
|
onClick={() => onGenerateWorksheet(selectedUnit.unit_id)}
|
|
disabled={isGenerating}
|
|
className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50 flex items-center gap-2"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
Arbeitsblatt HTML
|
|
</button>
|
|
<button
|
|
onClick={() => onDownloadPdf(selectedUnit.unit_id)}
|
|
disabled={isGenerating}
|
|
className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 disabled:opacity-50 flex items-center gap-2"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
PDF Download
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Generated Content Preview */}
|
|
{generatedContent && (
|
|
<div className="bg-white rounded-lg border border-gray-200 p-4">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-medium text-gray-900">Generierter Content</h3>
|
|
<button
|
|
onClick={onClearContent}
|
|
className="text-gray-400 hover:text-gray-600"
|
|
>
|
|
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
{generatedContent.html ? (
|
|
<div
|
|
className="prose prose-sm max-w-none p-4 bg-gray-50 rounded-lg border"
|
|
dangerouslySetInnerHTML={{ __html: generatedContent.html }}
|
|
/>
|
|
) : (
|
|
<pre className="p-4 bg-gray-900 text-gray-100 rounded-lg text-xs overflow-x-auto max-h-96">
|
|
{JSON.stringify(generatedContent, null, 2)}
|
|
</pre>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|