Files
breakpilot-compliance/admin-compliance/app/sdk/sso/_components/shared.tsx
Sharang Parnerkar 2fb6b98bc5 refactor(admin): split sso page.tsx into colocated components
Extract types, constants, helpers, and UI pieces (shared LoadingSkeleton/
EmptyState/StatusBadge/CopyButton, SSOConfigFormModal, DeleteConfirmModal,
ConnectionTestPanel, SSOConfigCard, SSOUsersTable, SSOInfoSection) into
_components/ and _types.ts to bring page.tsx from 1482 LOC to 339 LOC
(under the 500 hard cap). Behavior preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:53:08 +02:00

72 lines
1.9 KiB
TypeScript

'use client'
import React, { useState } from 'react'
import { CheckCircle2, Copy, XCircle } from 'lucide-react'
export function LoadingSkeleton({ rows = 3 }: { rows?: number }) {
return (
<div className="space-y-4 animate-pulse">
{Array.from({ length: rows }).map((_, i) => (
<div key={i} className="h-16 bg-slate-100 rounded-lg" />
))}
</div>
)
}
export function EmptyState({
icon,
title,
description,
action,
}: {
icon: React.ReactNode
title: string
description: string
action?: React.ReactNode
}) {
return (
<div className="text-center py-12">
<div className="w-16 h-16 mx-auto bg-slate-100 rounded-full flex items-center justify-center mb-4">
{icon}
</div>
<h3 className="text-lg font-semibold text-slate-900">{title}</h3>
<p className="mt-2 text-sm text-slate-500 max-w-md mx-auto">{description}</p>
{action && <div className="mt-4">{action}</div>}
</div>
)
}
export function StatusBadge({ enabled }: { enabled: boolean }) {
return enabled ? (
<span className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium bg-green-100 text-green-700 rounded-full">
<CheckCircle2 className="w-3 h-3" />
Aktiv
</span>
) : (
<span className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium bg-slate-100 text-slate-600 rounded-full">
<XCircle className="w-3 h-3" />
Deaktiviert
</span>
)
}
export function CopyButton({ value }: { value: string }) {
const [copied, setCopied] = useState(false)
const handleCopy = () => {
navigator.clipboard.writeText(value)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return (
<button
onClick={handleCopy}
className="p-1 text-slate-400 hover:text-slate-600 transition-colors"
title="In Zwischenablage kopieren"
>
{copied ? <CheckCircle2 className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
</button>
)
}