backend-lehrer (5 files): - alerts_agent/db/repository.py (992 → 5), abitur_docs_api.py (956 → 3) - teacher_dashboard_api.py (951 → 3), services/pdf_service.py (916 → 3) - mail/mail_db.py (987 → 6) klausur-service (5 files): - legal_templates_ingestion.py (942 → 3), ocr_pipeline_postprocess.py (929 → 4) - ocr_pipeline_words.py (876 → 3), ocr_pipeline_ocr_merge.py (616 → 2) - KorrekturPage.tsx (956 → 6) website (5 pages): - mail (985 → 9), edu-search (958 → 8), mac-mini (950 → 7) - ocr-labeling (946 → 7), audit-workspace (871 → 4) studio-v2 (5 files + 1 deleted): - page.tsx (946 → 5), MessagesContext.tsx (925 → 4) - korrektur (914 → 6), worksheet-cleanup (899 → 6) - useVocabWorksheet.ts (888 → 3) - Deleted dead page-original.tsx (934 LOC) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import type { MacMiniStatus } from '../types'
|
|
|
|
export default function DockerSection({
|
|
status,
|
|
actionLoading,
|
|
onDockerUp,
|
|
onDockerDown,
|
|
}: {
|
|
status: MacMiniStatus | null
|
|
actionLoading: string | null
|
|
onDockerUp: () => void
|
|
onDockerDown: () => void
|
|
}) {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-slate-200 p-6 mb-6">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h3 className="font-semibold text-slate-900 flex items-center gap-2">
|
|
<span className="text-2xl">🐳</span> Docker Container
|
|
</h3>
|
|
<div className="flex gap-2">
|
|
<button
|
|
onClick={onDockerUp}
|
|
disabled={actionLoading !== null || !status?.online}
|
|
className="px-3 py-1.5 bg-green-600 text-white text-sm rounded-lg font-medium hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
>
|
|
{actionLoading === 'docker-up' ? '...' : '▶ Start'}
|
|
</button>
|
|
<button
|
|
onClick={onDockerDown}
|
|
disabled={actionLoading !== null || !status?.online}
|
|
className="px-3 py-1.5 bg-red-600 text-white text-sm rounded-lg font-medium hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
>
|
|
{actionLoading === 'docker-down' ? '...' : '⏹ Stop'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{status?.containers && status.containers.length > 0 ? (
|
|
<div className="space-y-2">
|
|
{status.containers.map((container, idx) => (
|
|
<div key={idx} className="flex items-center justify-between bg-slate-50 rounded-lg p-3">
|
|
<div className="flex items-center gap-3">
|
|
<span className={`w-2 h-2 rounded-full ${
|
|
container.status.includes('Up') ? 'bg-green-500' : 'bg-red-500'
|
|
}`}></span>
|
|
<span className="font-medium text-slate-700">{container.name}</span>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
{container.ports && (
|
|
<span className="text-sm text-slate-500 font-mono">{container.ports}</span>
|
|
)}
|
|
<span className={`text-sm ${
|
|
container.status.includes('Up') ? 'text-green-600' : 'text-red-500'
|
|
}`}>
|
|
{container.status}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<p className="text-slate-500 text-center py-4">
|
|
{status?.online ? 'Keine Container gefunden' : 'Server nicht erreichbar'}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|