Files
breakpilot-lehrer/website/app/admin/docs/_components/ServicesTab.tsx
Benjamin Admin 0b37c5e692 [split-required] Split website + studio-v2 monoliths (Phase 3 continued)
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>
2026-04-24 17:52:36 +02:00

79 lines
3.5 KiB
TypeScript

'use client'
import { useState } from 'react'
import { services, docPaths, PROJECT_BASE_PATH } from '../data'
import { getServiceTypeColor } from '../helpers'
export default function ServicesTab() {
const [selectedService, setSelectedService] = useState<string | null>(null)
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{services.map((service) => (
<div
key={service.id}
className={`bg-white rounded-xl border border-slate-200 p-5 cursor-pointer transition-all hover:shadow-md ${
selectedService === service.id ? 'ring-2 ring-primary-600' : ''
}`}
onClick={() => setSelectedService(selectedService === service.id ? null : service.id)}
>
<div className="flex items-start justify-between mb-3">
<div>
<h3 className="font-semibold text-slate-900">{service.name}</h3>
<span className={`text-xs px-2 py-0.5 rounded-full ${getServiceTypeColor(service.type)}`}>
{service.type}
</span>
</div>
<div className="text-right">
<div className="text-sm font-mono text-slate-600">:{service.port}</div>
</div>
</div>
<p className="text-sm text-slate-600 mb-3">{service.description}</p>
<div className="flex flex-wrap gap-1 mb-3">
{service.tech.map((t) => (
<span key={t} className="text-xs bg-slate-100 text-slate-600 px-2 py-0.5 rounded">
{t}
</span>
))}
</div>
{selectedService === service.id && (
<div className="mt-4 pt-4 border-t border-slate-200 space-y-2">
{/* Purpose/Warum dieser Service */}
<div className="bg-primary-50 border border-primary-200 rounded-lg p-3 mb-3">
<div className="text-xs font-medium text-primary-700 mb-1">Warum dieser Service?</div>
<div className="text-sm text-primary-900">{service.purpose}</div>
</div>
<div className="text-xs text-slate-500">Container: {service.container}</div>
{service.healthEndpoint && (
<div className="text-xs text-slate-500">
Health: <code className="bg-slate-100 px-1 rounded">localhost:{service.port}{service.healthEndpoint}</code>
</div>
)}
<div className="text-xs text-slate-500">
Endpoints: {service.endpoints.length}
</div>
{/* VS Code Link */}
{docPaths[service.id] && (
<a
href={`vscode://file/${PROJECT_BASE_PATH}/${docPaths[service.id]}`}
onClick={(e) => e.stopPropagation()}
className="mt-3 flex items-center gap-2 text-xs bg-blue-50 text-blue-700 px-3 py-2 rounded-lg hover:bg-blue-100 transition-colors"
>
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">
<path d="M23.15 2.587L18.21.21a1.494 1.494 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a.999.999 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a.999.999 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.492 1.492 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352zm-5.146 14.861L10.826 12l7.178-5.448v10.896z"/>
</svg>
In VS Code oeffnen
</a>
)}
</div>
)}
</div>
))}
</div>
)
}