backend-lehrer (11 files): - llm_gateway/routes/schools.py (867 → 5), recording_api.py (848 → 6) - messenger_api.py (840 → 5), print_generator.py (824 → 5) - unit_analytics_api.py (751 → 5), classroom/routes/context.py (726 → 4) - llm_gateway/routes/edu_search_seeds.py (710 → 4) klausur-service (12 files): - ocr_labeling_api.py (845 → 4), metrics_db.py (833 → 4) - legal_corpus_api.py (790 → 4), page_crop.py (758 → 3) - mail/ai_service.py (747 → 4), github_crawler.py (767 → 3) - trocr_service.py (730 → 4), full_compliance_pipeline.py (723 → 4) - dsfa_rag_api.py (715 → 4), ocr_pipeline_auto.py (705 → 4) website (6 pages): - audit-checklist (867 → 8), content (806 → 6) - screen-flow (790 → 4), scraper (789 → 5) - zeugnisse (776 → 5), modules (745 → 4) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
75 lines
3.3 KiB
TypeScript
75 lines
3.3 KiB
TypeScript
'use client'
|
|
|
|
import { RefObject } from 'react'
|
|
|
|
interface LivePreviewPanelProps {
|
|
activeTab: string
|
|
iframeRef: RefObject<HTMLIFrameElement | null>
|
|
}
|
|
|
|
export default function LivePreviewPanel({ activeTab, iframeRef }: LivePreviewPanelProps) {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-200 shadow-sm overflow-hidden">
|
|
{/* Preview Header */}
|
|
<div className="bg-slate-50 border-b border-slate-200 px-4 py-3 flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<div className="flex gap-1.5">
|
|
<div className="w-3 h-3 rounded-full bg-red-400"></div>
|
|
<div className="w-3 h-3 rounded-full bg-yellow-400"></div>
|
|
<div className="w-3 h-3 rounded-full bg-green-400"></div>
|
|
</div>
|
|
<span className="text-xs text-slate-500 ml-2">localhost:3000</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-xs font-medium text-slate-600 bg-slate-200 px-2 py-1 rounded">
|
|
{activeTab === 'hero' && 'Hero Section'}
|
|
{activeTab === 'features' && 'Features'}
|
|
{activeTab === 'faq' && 'FAQ'}
|
|
{activeTab === 'pricing' && 'Pricing'}
|
|
{activeTab === 'other' && 'Trust & Testimonial'}
|
|
</span>
|
|
<button
|
|
onClick={() => iframeRef.current?.contentWindow?.location.reload()}
|
|
className="p-1.5 text-slate-500 hover:text-slate-700 hover:bg-slate-200 rounded transition-colors"
|
|
title="Preview neu laden"
|
|
>
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{/* Preview Frame */}
|
|
<div className="relative h-[calc(100vh-340px)] bg-slate-100">
|
|
<iframe
|
|
ref={iframeRef}
|
|
src={`/?preview=true§ion=${activeTab}#${activeTab}`}
|
|
className="w-full h-full border-0 scale-75 origin-top-left"
|
|
style={{
|
|
width: '133.33%',
|
|
height: '133.33%',
|
|
transform: 'scale(0.75)',
|
|
transformOrigin: 'top left',
|
|
}}
|
|
title="Website Preview"
|
|
sandbox="allow-same-origin allow-scripts"
|
|
/>
|
|
<div className="absolute bottom-4 left-4 right-4 bg-blue-600 text-white px-4 py-2 rounded-lg shadow-lg flex items-center gap-2 text-sm">
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<span>
|
|
Du bearbeitest: <strong>
|
|
{activeTab === 'hero' && 'Hero Section (Startbereich)'}
|
|
{activeTab === 'features' && 'Features (Funktionen)'}
|
|
{activeTab === 'faq' && 'FAQ (Haeufige Fragen)'}
|
|
{activeTab === 'pricing' && 'Pricing (Preise)'}
|
|
{activeTab === 'other' && 'Trust & Testimonial'}
|
|
</strong>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|