'use client' import React, { useState, useTransition, useRef } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { KeyRound, Search, Loader2, CheckCircle2, AlertTriangle, XCircle, Building2, User, CalendarDays, Package, ShieldCheck, Hash, ChevronDown, ChevronUp, Fingerprint, } from 'lucide-react' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { lookupLicenseFromLicServer } from '@/lib/actions/licserver-config' // ─── MOCK DATA (until real LicServer API is wired up) ─────────────────────── const MOCK_LICENSES: Record = { 'CAS-2023-PRO-00123': { licenseKey: 'CAS-2023-PRO-00123', status: 'active', product: 'CAS genesisWorld Professional', edition: 'Professional', version: '14.1.2', seats: 10, customer: 'Mustermann GmbH', contact: 'Max Mustermann', issuedAt: '2023-04-01', expiresAt: '2026-03-31', maintenanceUntil: '2025-03-31', modules: ['CRM', 'ERP-Link', 'Mobile Client', 'Web Client'], }, 'CAS-2020-STD-00456': { licenseKey: 'CAS-2020-STD-00456', status: 'expired', product: 'CAS genesisWorld Standard', edition: 'Standard', version: '12.0.0', seats: 5, customer: 'Beispiel AG', contact: 'Erika Muster', issuedAt: '2020-01-15', expiresAt: '2023-01-14', maintenanceUntil: '2022-01-14', modules: ['CRM'], }, 'CAS-2024-ENT-00789': { licenseKey: 'CAS-2024-ENT-00789', status: 'active', product: 'CAS genesisWorld Enterprise', edition: 'Enterprise', version: '15.0.0', seats: 50, customer: 'Tech Solutions GmbH & Co. KG', contact: 'Julia Schneider', issuedAt: '2024-01-01', expiresAt: '2026-12-31', maintenanceUntil: '2026-12-31', modules: ['CRM', 'ERP-Link', 'Mobile Client', 'Web Client', 'AI Assistant', 'Analytics Pro'], }, } // ─── TYPES ─────────────────────────────────────────────────────────────────── export type LicenseStatus = 'active' | 'expired' | 'invalid' | 'suspended' export interface LicenseInfo { licenseKey: string status: LicenseStatus product: string edition: string version: string seats: number customer: string contact: string issuedAt: string expiresAt: string maintenanceUntil: string modules: string[] } interface LicenseLookupPanelProps { /** Called when a valid license is found – so the wizard can prefill fields */ onLicenseResolved?: (info: LicenseInfo) => void } // ─── HELPERS ───────────────────────────────────────────────────────────────── function statusConfig(status: LicenseStatus) { switch (status) { case 'active': return { label: 'Aktiv', icon: , cls: 'bg-emerald-500/20 text-emerald-300 border-emerald-500/40', ring: 'border-emerald-500/30', glow: 'shadow-emerald-500/10', } case 'expired': return { label: 'Abgelaufen', icon: , cls: 'bg-amber-500/20 text-amber-300 border-amber-500/40', ring: 'border-amber-500/30', glow: 'shadow-amber-500/10', } case 'suspended': return { label: 'Gesperrt', icon: , cls: 'bg-red-500/20 text-red-300 border-red-500/40', ring: 'border-red-500/30', glow: 'shadow-red-500/10', } default: return { label: 'Ungültig', icon: , cls: 'bg-red-500/20 text-red-300 border-red-500/40', ring: 'border-red-500/30', glow: 'shadow-red-500/10', } } } function fmt(dateStr: string) { if (!dateStr) return '—' return new Date(dateStr).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', }) } // ─── LOOKUP (tries real LicServer API call, falls back to MOCK in dev) ────────────────────── async function lookupLicense(key: string): Promise { try { return await lookupLicenseFromLicServer(key) } catch (err) { console.error('Lookup failed, falling back to mock details:', err) return MOCK_LICENSES[key.trim().toUpperCase()] ?? null } } // ─── MAIN COMPONENT ─────────────────────────────────────────────────────────── export function LicenseLookupPanel({ onLicenseResolved }: LicenseLookupPanelProps) { const [licenseKey, setLicenseKey] = useState('') const [result, setResult] = useState(null) const [notFound, setNotFound] = useState(false) const [isPending, startTransition] = useTransition() const [expanded, setExpanded] = useState(true) const [modulesOpen, setModulesOpen] = useState(false) const inputRef = useRef(null) const handleSearch = () => { if (!licenseKey.trim()) return setResult(null) setNotFound(false) startTransition(async () => { const info = await lookupLicense(licenseKey) if (info) { setResult(info) onLicenseResolved?.(info) } else { setNotFound(true) } }) } const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') handleSearch() } const handleClear = () => { setLicenseKey('') setResult(null) setNotFound(false) inputRef.current?.focus() } const sc = result ? statusConfig(result.status) : null return (
{/* ── Panel Header (toggle) ─────────────────────────────────────────── */} {/* ── Collapsible Body ──────────────────────────────────────────────── */} {expanded && (
{/* ── Input + Search Button ──────────────────────────────── */}

Geben Sie Ihre bisherige CAS-Lizenznummer ein, um Lizenzinformationen automatisch abzurufen.

{/* Input */}
{ setLicenseKey(e.target.value) setResult(null) setNotFound(false) }} onKeyDown={handleKeyDown} placeholder="z. B. CAS-2023-PRO-00123" className="pl-9 pr-8 bg-white/5 border-white/10 text-white placeholder:text-slate-500 focus:border-violet-500/60 focus:ring-violet-500/20 rounded-xl text-sm h-10" /> {licenseKey && ( )}
{/* Search Button */}
{/* Demo quick-fill hints */}

Demo:  setLicenseKey('CAS-2023-PRO-00123')} > CAS-2023-PRO-00123 {' · '} setLicenseKey('CAS-2020-STD-00456')} > CAS-2020-STD-00456

{/* ── Animated Result Area ──────────────────────────────── */} {/* Loading skeleton */} {isPending && ( {[1, 2, 3].map(i => (
))}

Lizenzserver wird abgefragt…

)} {/* Not Found */} {notFound && !isPending && (

Lizenz nicht gefunden

Die eingegebene Nummer wurde im Lizenzsystem nicht gefunden. Bitte prüfen Sie die Eingabe.

)} {/* Result Card */} {result && !isPending && sc && ( {/* Status Bar */}
{result.licenseKey}
{sc.icon} {sc.label}
{/* Info Rows */}
{/* Product */}

Produkt

{result.product}

{result.edition} · v{result.version} · {result.seats} Arbeitsplätze

{/* Customer */}

Lizenznehmer

{result.customer}

{result.contact}

{/* Date Grid */}

Ausgestellt

{fmt(result.issuedAt)}

Läuft ab

{fmt(result.expiresAt)}

Wartung bis

{fmt(result.maintenanceUntil)}

{/* Modules (collapsible) */} {result.modules.length > 0 && (
{modulesOpen && (
{result.modules.map(m => ( {m} ))}
)}
)}
{/* Bottom hint */} {result.status === 'active' && (

Lizenz erkannt — Daten können für die Bestellung übernommen werden.

)} {result.status === 'expired' && (

Lizenz abgelaufen — Upgrade empfohlen.

)}
)}
)}
) }