refactor: API-Keys in Einstellungen kompakter (gleicher Stil wie Kunden-Panel)
This commit is contained in:
parent
4023a14fe1
commit
cdb2443d8f
@ -349,53 +349,53 @@ function APIKeysSection() {
|
|||||||
|
|
||||||
{/* Key Liste */}
|
{/* Key Liste */}
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="px-4 py-3 text-gray-500 text-sm">Laden...</div>
|
<div className="px-4 py-3 text-gray-500 text-xs">Laden...</div>
|
||||||
) : keys.length === 0 ? (
|
) : keys.length === 0 ? (
|
||||||
<div className="px-4 py-6 text-center text-gray-500 text-sm">Keine API-Keys vorhanden</div>
|
<div className="px-4 py-4 text-center text-gray-500 text-xs">Keine API-Keys vorhanden</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="divide-y divide-gray-800">
|
<div className="divide-y divide-gray-800/60">
|
||||||
{keys.map((k) => {
|
{keys.map((k) => {
|
||||||
const perm = PERM_LABELS[k.permissions] || PERM_LABELS.read
|
const perm = PERM_LABELS[k.permissions] || PERM_LABELS.read
|
||||||
const customer = k.customer_id ? customers.find(c => c.id === k.customer_id) : null
|
const customer = k.customer_id ? customers.find(c => c.id === k.customer_id) : null
|
||||||
|
const lastUsedAgo = k.last_used
|
||||||
|
? (() => {
|
||||||
|
const s = (Date.now() - new Date(k.last_used)) / 1000
|
||||||
|
if (s < 120) return 'gerade eben'
|
||||||
|
if (s < 3600) return `${Math.floor(s/60)}m`
|
||||||
|
if (s < 86400) return `${Math.floor(s/3600)}h`
|
||||||
|
return `${Math.floor(s/86400)}d`
|
||||||
|
})()
|
||||||
|
: null
|
||||||
return (
|
return (
|
||||||
<div key={k.id} className="px-4 py-2.5 flex items-center justify-between">
|
<div key={k.id} className="px-4 py-1.5 flex items-center gap-2.5 hover:bg-gray-800/30 group">
|
||||||
<div className="min-w-0 flex-1">
|
<span className={`text-[10px] font-bold px-1.5 py-0.5 rounded border leading-none w-16 text-center flex-shrink-0 ${perm.color}`}>
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span className="text-sm text-white">{k.name}</span>
|
|
||||||
<span className={`text-[10px] font-bold px-1.5 py-0.5 rounded border leading-none ${perm.color}`}>
|
|
||||||
{perm.label}
|
{perm.label}
|
||||||
</span>
|
</span>
|
||||||
|
<span className="text-xs text-gray-300 flex-1 min-w-0 truncate">{k.name}</span>
|
||||||
{customer && (
|
{customer && (
|
||||||
<span className="text-[10px] px-1.5 py-0.5 rounded border text-gray-400 bg-gray-800 border-gray-700 leading-none">
|
<span className="text-[10px] text-gray-600 flex-shrink-0 hidden sm:block">{customer.number}</span>
|
||||||
{customer.number}
|
)}
|
||||||
|
<code className="text-xs text-gray-600 font-mono flex-shrink-0">
|
||||||
|
{k.key.substring(0, 8)}…{k.key.substring(k.key.length - 4)}
|
||||||
|
</code>
|
||||||
|
{lastUsedAgo && (
|
||||||
|
<span className="text-[10px] text-gray-700 flex-shrink-0 hidden md:block" title={`Zuletzt benutzt: ${new Date(k.last_used).toLocaleString('de-DE')}`}>
|
||||||
|
{lastUsedAgo}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3 mt-0.5">
|
|
||||||
<span className="text-xs text-gray-600 font-mono">{k.key.substring(0, 8)}...{k.key.substring(k.key.length - 4)}</span>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => copyText(k.key, k.id)}
|
onClick={() => copyText(k.key, k.id)}
|
||||||
className="text-gray-600 hover:text-orange-400 transition-colors"
|
className="text-gray-600 hover:text-orange-400 transition-colors flex-shrink-0 opacity-0 group-hover:opacity-100"
|
||||||
title="Key kopieren"
|
title="Key kopieren"
|
||||||
>
|
>
|
||||||
{copied === k.id ? <Check className="w-3 h-3 text-green-400" /> : <Copy className="w-3 h-3" />}
|
{copied === k.id ? <Check className="w-3.5 h-3.5 text-green-400" /> : <Copy className="w-3.5 h-3.5" />}
|
||||||
</button>
|
</button>
|
||||||
<span className="text-xs text-gray-600">
|
|
||||||
Erstellt: {new Date(k.created_at).toLocaleDateString('de-DE')}
|
|
||||||
</span>
|
|
||||||
{k.last_used && (
|
|
||||||
<span className="text-xs text-gray-600">
|
|
||||||
Zuletzt: {new Date(k.last_used).toLocaleString('de-DE')}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(k.id, k.name)}
|
onClick={() => handleDelete(k.id, k.name)}
|
||||||
className="text-gray-500 hover:text-red-400 p-1 rounded hover:bg-gray-800 transition-colors ml-2"
|
className="text-gray-700 hover:text-red-400 transition-colors flex-shrink-0 opacity-0 group-hover:opacity-100"
|
||||||
title="Key loeschen"
|
title="Key loeschen"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-3.5 h-3.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user