import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useLicense } from '../../contexts/LicenseContext'; import api from '../../services/api'; import './LicenseManager.css'; export default function LicenseManager() { const navigate = useNavigate(); const { status, refreshStatus } = useLicense(); const [blob, setBlob] = useState(''); const [message, setMessage] = useState(''); const [error, setError] = useState(''); const [saving, setSaving] = useState(false); const [copied, setCopied] = useState(''); const copy = (text, label) => { navigator.clipboard?.writeText(text).then( () => { setCopied(label); setTimeout(() => setCopied(''), 2000); }, () => setError('Could not copy - select and copy manually') ); }; const handleInstall = async () => { if (!blob.trim()) return; setSaving(true); setError(''); setMessage(''); try { await api.post('/api/license/', { key_blob: blob.trim() }); await refreshStatus(); setBlob(''); setMessage('Licence installed.'); } catch (err) { setError(err.response?.data?.detail || 'Could not install licence'); } finally { setSaving(false); } }; if (!status) { return (
Loading licence...
); } const componentsJson = JSON.stringify(status.components || {}); return (
{message &&
{message}
} {error &&
{error}
} {/* Current state */}

Licence

{status.valid ? (
Licensed
Customer
{status.customer || '—'}
Stations
{status.stations_used} of {status.stations} in use
) : (
{status.in_grace ? 'Not licensed' : 'Licence expired'}

{status.reason}

{status.in_grace ? (

Everything keeps working for {status.grace_days_left} more days. After that only {1} station can measure. Send the fingerprint below to your supplier to get a licence key.

) : (

The grace period has ended, so only {status.stations} station can measure. Send the fingerprint below to your supplier.

)}
)}
{/* Fingerprint to send */}

This machine

Send this to your supplier to obtain a licence key. It identifies this server only — the values are one-way hashes, not hardware serial numbers.

{status.fingerprint}
Full details (needed to issue the key)
{componentsJson}
{/* Install */}

Install a licence key