Files
dewemoji/app/resources/views/dashboard/user/api-keys.blade.php
2026-02-12 00:52:40 +07:00

118 lines
5.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('dashboard.app')
@section('title', 'API Keys')
@section('page_title', 'API Keys')
@section('page_subtitle', 'Create and manage access tokens for integrations.')
@section('dashboard_content')
<div class="grid gap-6 lg:grid-cols-3">
<div class="lg:col-span-2 rounded-3xl glass-card p-6">
<div class="flex items-center justify-between">
<div>
<div class="text-xs uppercase tracking-[0.25em] text-gray-400">Your keys</div>
<div class="mt-2 text-xl font-semibold text-white">Manage API access</div>
</div>
@if ($canCreate)
<form method="POST" action="{{ route('dashboard.api-keys.create') }}" class="flex items-center gap-2">
@csrf
<input type="text" name="name" placeholder="Key name (optional)" class="rounded-full bg-white/5 border border-white/10 px-4 py-2 text-sm text-gray-200 focus:outline-none focus:border-brand-ocean">
<button type="submit" class="rounded-full bg-brand-ocean text-white font-semibold px-4 py-2 text-sm">Create key</button>
</form>
@endif
</div>
@if (!$canCreate)
<div class="mt-4 rounded-2xl border border-amber-400/30 bg-amber-400/10 p-4 text-sm text-amber-200">
API keys are available on the Personal plan. Upgrade to unlock API access.
</div>
@endif
@if ($newKey)
<div class="mt-6 rounded-2xl border border-emerald-400/30 bg-emerald-400/10 p-4 text-sm text-emerald-200">
New key created. Copy it now; you wont be able to see it again.
<div class="mt-3 flex items-center gap-2">
<code class="rounded-lg bg-black/40 px-3 py-2 text-xs text-emerald-200">{{ $newKey }}</code>
<button type="button" data-copy-key="{{ $newKey }}" class="rounded-full border border-emerald-400/40 px-3 py-1 text-xs text-emerald-200 hover:bg-emerald-400/10">Copy</button>
</div>
</div>
@endif
<div class="mt-6 overflow-hidden rounded-2xl border border-white/10">
<table class="min-w-full text-sm text-gray-300">
<thead class="bg-white/5 text-xs uppercase tracking-[0.2em] text-gray-400">
<tr>
<th class="px-4 py-3 text-left">Prefix</th>
<th class="px-4 py-3 text-left">Name</th>
<th class="px-4 py-3 text-left">Created</th>
<th class="px-4 py-3 text-left">Last used</th>
<th class="px-4 py-3 text-right">Actions</th>
</tr>
</thead>
<tbody>
@forelse ($keys as $key)
<tr class="border-t border-white/5">
<td class="px-4 py-3 font-mono text-xs text-gray-400">{{ $key->key_prefix }}</td>
<td class="px-4 py-3 text-white">{{ $key->name ?? '—' }}</td>
<td class="px-4 py-3 text-xs text-gray-400">{{ $key->created_at?->toDateString() }}</td>
<td class="px-4 py-3 text-xs text-gray-400">{{ $key->last_used_at?->diffForHumans() ?? 'Never' }}</td>
<td class="px-4 py-3 text-right">
@if ($key->revoked_at)
<span class="text-xs text-gray-500">Revoked</span>
@else
<form method="POST" action="{{ route('dashboard.api-keys.revoke', $key->id) }}" class="inline" data-revoke-form>
@csrf
<button type="submit" class="rounded-full border border-white/10 px-3 py-1 text-xs text-gray-200 hover:bg-white/10">Revoke</button>
</form>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-sm text-gray-500">No API keys yet.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
<div class="rounded-3xl glass-card p-6 space-y-4">
<div>
<div class="text-xs uppercase tracking-[0.25em] text-gray-400">Tips</div>
<div class="mt-2 text-xl font-semibold text-white">Keep keys safe</div>
</div>
<div class="rounded-2xl bg-white/5 border border-white/10 p-4 text-sm text-gray-300">
Use separate keys for apps and automate revocation if you suspect compromise.
</div>
<div class="rounded-2xl bg-white/5 border border-white/10 p-4 text-sm text-gray-300">
API keys are required to access private keyword search results.
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
(() => {
document.querySelectorAll('[data-copy-key]').forEach((btn) => {
btn.addEventListener('click', () => {
navigator.clipboard.writeText(btn.dataset.copyKey || '');
btn.textContent = 'Copied';
setTimeout(() => { btn.textContent = 'Copy'; }, 1200);
});
});
document.querySelectorAll('[data-revoke-form]').forEach((form) => {
form.addEventListener('submit', async (e) => {
e.preventDefault();
const ok = await window.dewemojiConfirm('Revoke this API key? This cannot be undone.', {
title: 'Revoke API key',
okText: 'Revoke',
});
if (!ok) return;
form.submit();
});
});
})();
</script>
@endpush