import { useState } 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 { useLicenseContext } from "../../contexts/LicenseContext"; import { useLicenseMachines } from "../../hooks/useLicenseMachines"; import type { LicenseError } from "../../services/licenseService"; import { purchaseUrl } from "../../shared/purchaseUrl"; import { logError } from "../../services/logService"; export default function LicenseCard() { const { t, i18n } = useTranslation(); const { status: licenseStatus, edition, info, error, validating, validationError, submitKey } = useLicenseContext(); const [keyInput, setKeyInput] = useState(""); const [showInput, setShowInput] = useState(false); const hasLicense = edition !== "free"; const { state: machines, activate, deactivate, toggleList, showEmptyState, canDeactivate, canActivate, } = useLicenseMachines(hasLicense); 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(purchaseUrl(i18n.language)).catch((e) => logError("Product page: openUrl failed", e), ); }; const formatExpiry = (timestamp: number) => { return new Date(timestamp * 1000).toLocaleDateString(); }; const errorMessage = (err: LicenseError) => t(err.i18nKey, err.params); const editionLabel = t(`license.editions.${edition}`); return (

{t("license.title")}

{t("license.currentEdition")}

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

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

{t("license.expiresAt")}

{formatExpiry(info.expires_at)}

)}
{licenseStatus === "error" && error && (

{error}

)} {!showInput && (
{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 /> {validationError && (

{validationError}

)}
)} {hasLicense && (

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

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

{errorMessage(machines.activationError)}

)} {machines.listOpen && (
{machines.listLoading && machines.machines.length === 0 && (
{t("common.loading")}
)} {machines.listError && (

{errorMessage(machines.listError)}

)} {showEmptyState && (

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

)} {machines.machines.map((m) => { const isThis = machines.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()}

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