Donation checkout via Ladill Pay (9% fee), church/giving QR pages, SSO, and platform scan forwarding. Co-authored-by: Cursor <cursoragent@cursor.com>
88 lines
6.0 KiB
PHP
88 lines
6.0 KiB
PHP
<x-user-layout>
|
|
<x-slot name="title">Developers</x-slot>
|
|
<div class="mx-auto max-w-3xl">
|
|
<h1 class="text-xl font-semibold tracking-tight text-slate-900">Developers</h1>
|
|
<p class="mt-0.5 text-sm text-slate-500">API tokens to manage your QR codes programmatically.</p>
|
|
|
|
@if($newToken)
|
|
<div class="mt-6 rounded-2xl border border-emerald-200 bg-emerald-50 p-5">
|
|
<p class="text-sm font-semibold text-emerald-900">Your new token — copy it now</p>
|
|
<p class="mt-1 text-xs text-emerald-700">This is the only time it will be shown.</p>
|
|
<div class="mt-3 flex items-center gap-2" x-data="{ copied: false }">
|
|
<code class="flex-1 truncate rounded-lg bg-white px-3 py-2 font-mono text-xs text-slate-800 ring-1 ring-emerald-200">{{ $newToken }}</code>
|
|
<button @click="navigator.clipboard.writeText('{{ $newToken }}'); copied = true; setTimeout(() => copied = false, 1500)"
|
|
class="rounded-lg bg-emerald-600 px-3 py-2 text-xs font-semibold text-white hover:bg-emerald-700">
|
|
<span x-show="!copied">Copy</span><span x-show="copied" x-cloak>Copied ✓</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="mt-6 rounded-2xl border border-slate-200 bg-white p-5">
|
|
<h2 class="text-sm font-semibold text-slate-900">Create a token</h2>
|
|
<form method="POST" action="{{ route('account.developers.store') }}" class="mt-4 flex flex-col gap-3 sm:flex-row sm:items-end">
|
|
@csrf
|
|
<div class="flex-1">
|
|
<label class="block text-[11px] font-medium text-slate-500">Token name</label>
|
|
<input type="text" name="name" required placeholder="e.g. CI server"
|
|
class="mt-1 w-full rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none focus:ring-2 focus:ring-indigo-100">
|
|
@error('name')<p class="mt-1 text-xs text-rose-600">{{ $message }}</p>@enderror
|
|
</div>
|
|
<button class="btn-primary">Generate token</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="mt-6 rounded-2xl border border-slate-200 bg-white">
|
|
<div class="border-b border-slate-100 px-5 py-3.5"><h2 class="text-sm font-semibold text-slate-900">Your tokens</h2></div>
|
|
@forelse($tokens as $token)
|
|
<div class="flex items-center justify-between px-5 py-3.5 {{ ! $loop->last ? 'border-b border-slate-50' : '' }}">
|
|
<div>
|
|
<p class="text-sm font-medium text-slate-900">{{ $token->name }}</p>
|
|
<p class="text-xs text-slate-400">
|
|
Created {{ $token->created_at->diffForHumans() }} ·
|
|
{{ $token->last_used_at ? 'last used '.$token->last_used_at->diffForHumans() : 'never used' }}
|
|
</p>
|
|
</div>
|
|
<x-confirm-dialog
|
|
:name="'revoke-token-'.$token->id"
|
|
title="Revoke API token?"
|
|
:message="'Revoke '.$token->name.'? Apps using this token will stop working.'"
|
|
:action="route('account.developers.destroy', $token->id)"
|
|
method="DELETE"
|
|
confirm-label="Revoke"
|
|
>
|
|
<x-slot:trigger>
|
|
<button type="button" class="text-xs font-medium text-rose-600 hover:underline">Revoke</button>
|
|
</x-slot:trigger>
|
|
</x-confirm-dialog>
|
|
</div>
|
|
@empty
|
|
<p class="px-5 py-8 text-center text-sm text-slate-400">No tokens yet.</p>
|
|
@endforelse
|
|
</div>
|
|
|
|
<div class="mt-6 rounded-2xl border border-slate-200 bg-slate-900 p-5 text-slate-200">
|
|
<h2 class="text-sm font-semibold text-white">Quick start</h2>
|
|
<p class="mt-1 text-xs text-slate-400">Authenticate with a Bearer token. Base URL:</p>
|
|
<code class="mt-2 block rounded-lg bg-black/40 px-3 py-2 font-mono text-[11px] text-emerald-300">{{ $apiBase }}</code>
|
|
<pre class="mt-3 overflow-x-auto rounded-lg bg-black/40 px-3 py-3 font-mono text-[11px] leading-relaxed text-slate-300"><code>curl {{ $apiBase }}/qr-codes \
|
|
-H "Authorization: Bearer <your-token>" \
|
|
-H "Accept: application/json"</code></pre>
|
|
<p class="mt-3 text-[11px] text-slate-400">Endpoints:</p>
|
|
<ul class="mt-1.5 space-y-1 text-[11px] text-slate-400">
|
|
<li><span class="font-mono text-slate-300">GET /me</span> — token user and acting account</li>
|
|
<li><span class="font-mono text-slate-300">GET /qr-codes</span> — list your codes</li>
|
|
<li><span class="font-mono text-slate-300">GET /qr-codes/{id}</span> — code details</li>
|
|
<li><span class="font-mono text-slate-300">GET /qr-codes/{id}/analytics</span> — scan stats</li>
|
|
<li><span class="font-mono text-slate-300">POST /qr-codes</span> — create (url, link_list, wifi, business, app)</li>
|
|
<li><span class="font-mono text-slate-300">PATCH /qr-codes/{id}</span> — update label, content, pause/resume</li>
|
|
</ul>
|
|
<pre class="mt-3 overflow-x-auto rounded-lg bg-black/40 px-3 py-3 font-mono text-[11px] leading-relaxed text-slate-300"><code>curl -X POST {{ $apiBase }}/qr-codes \
|
|
-H "Authorization: Bearer <your-token>" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"label":"Homepage","type":"url","destination_url":"https://example.com"}'</code></pre>
|
|
<p class="mt-3 text-[11px] text-slate-500">Team access: pass <span class="font-mono text-slate-300">X-Ladill-Account: <owner-user-id></span>. PDF codes need the web app. Regenerate tokens to get write access if yours only has read.</p>
|
|
</div>
|
|
</div>
|
|
</x-user-layout>
|