import { useState, useEffect, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { openUrl } from "@tauri-apps/plugin-opener"; import { KeyRound, CheckCircle, AlertCircle, Loader2, ExternalLink, Monitor, ChevronDown, ChevronUp } from "lucide-react"; import { useLicense } from "../../hooks/useLicense"; import { MachineInfo, ActivationStatus, activateMachine, deactivateMachine, listActivatedMachines, getActivationStatus, } from "../../services/licenseService"; const PURCHASE_URL = "https://lacompagniemaximus.com/simpl-resultat"; export default function LicenseCard() { const { t } = useTranslation(); const { state, submitKey } = useLicense(); const [keyInput, setKeyInput] = useState(""); const [showInput, setShowInput] = useState(false); const [showMachines, setShowMachines] = useState(false); const [machines, setMachines] = useState([]); const [activation, setActivation] = useState(null); const [machineLoading, setMachineLoading] = useState(false); const [deactivatingId, setDeactivatingId] = useState(null); const [machineError, setMachineError] = useState(null); const hasLicense = state.edition !== "free"; const loadActivation = useCallback(async () => { if (!hasLicense) return; try { const status = await getActivationStatus(); setActivation(status); } catch { // Ignore — activation status is best-effort } }, [hasLicense]); const loadMachines = useCallback(async () => { setMachineLoading(true); setMachineError(null); try { const list = await listActivatedMachines(); setMachines(list); } catch (e) { setMachineError(e instanceof Error ? e.message : String(e)); } finally { setMachineLoading(false); } }, []); useEffect(() => { void loadActivation(); }, [loadActivation]); const handleActivate = async () => { setMachineLoading(true); setMachineError(null); try { await activateMachine(); await loadActivation(); } catch (e) { setMachineError(e instanceof Error ? e.message : String(e)); } finally { setMachineLoading(false); } }; const handleDeactivate = async (machineId: string) => { setDeactivatingId(machineId); try { await deactivateMachine(machineId); await loadActivation(); await loadMachines(); } catch (e) { setMachineError(e instanceof Error ? e.message : String(e)); } finally { setDeactivatingId(null); } }; const toggleMachines = async () => { const next = !showMachines; setShowMachines(next); if (next && machines.length === 0) { await loadMachines(); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const trimmed = keyInput.trim(); if (!trimmed) return; const result = await submitKey(trimmed); if (result.ok) { setKeyInput(""); setShowInput(false); } }; const handlePurchase = () => { void openUrl(PURCHASE_URL); }; const formatExpiry = (timestamp: number) => { return new Date(timestamp * 1000).toLocaleDateString(); }; const editionLabel = t(`license.editions.${state.edition}`); return (

{t("license.title")}

{t("license.currentEdition")}

{editionLabel} {state.edition !== "free" && ( )}

{state.info && state.info.expires_at > 0 && (

{t("license.expiresAt")}

{formatExpiry(state.info.expires_at)}

)}
{state.status === "error" && state.error && (

{state.error}

)} {!showInput && (
{state.edition === "free" && ( )}
)} {showInput && (
setKeyInput(e.target.value)} placeholder={t("license.keyPlaceholder")} className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-sm font-mono focus:outline-none focus:border-[var(--primary)]" autoFocus />
)} {hasLicense && (

{t("license.machines.title")}

{activation && !activation.is_activated && ( )} {activation?.is_activated && ( {t("license.machines.activated")} )}
{machineError && (

{machineError}

)} {showMachines && (
{machineLoading && machines.length === 0 && (
{t("common.loading")}
)} {!machineLoading && machines.length === 0 && (

{t("license.machines.noMachines")}

)} {machines.map((m) => { const isThis = activation?.machine_id === m.machine_id; return (
{m.machine_name || m.machine_id.slice(0, 12)} {isThis && ( ({t("license.machines.thisMachine")}) )}

{new Date(m.activated_at).toLocaleDateString()}

); })}
)}
)}
); }