Files
2026-09-21 10:14:57 +01:00

177 lines
9.3 KiB
PHP
Executable File

@extends('chatgpt::layouts.master')
@section('content')
<section class="mx-auto max-w-5xl space-y-6 p-6">
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
<div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 class="text-2xl font-semibold text-slate-900">ChatGPT API Settings</h1>
<p class="mt-1 text-sm text-slate-600">
Store the OpenAI API key used by the module command. Keys are encrypted at rest by Laravel.
</p>
</div>
<code class="rounded-lg bg-slate-100 px-3 py-2 text-sm text-slate-700">
php artisan chatgpt:delete-api-files
</code>
</div>
</div>
@if (session('status'))
<div class="rounded-xl border border-green-200 bg-green-50 px-4 py-3 text-sm font-medium text-green-800">
{{ session('status') }}
</div>
@endif
@if ($errors->any())
<div class="rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800">
<strong>Unable to save the API key.</strong>
<ul class="mt-2 list-disc pl-5">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
<h2 class="text-lg font-semibold text-slate-900">Create API Key</h2>
<form method="POST" action="{{ route('chatgpt.settings.store') }}" class="mt-5 grid gap-4">
@csrf
<div>
<label for="name" class="block text-sm font-medium text-slate-700">Name</label>
<input
id="name"
name="name"
type="text"
value="{{ old('name', 'OpenAI API Key') }}"
class="mt-1 w-full rounded-lg border-slate-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
>
</div>
<div>
<label for="api_key" class="block text-sm font-medium text-slate-700">API Key</label>
<input
id="api_key"
name="api_key"
type="password"
value=""
autocomplete="new-password"
required
class="mt-1 w-full rounded-lg border-slate-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"
>
</div>
<label class="inline-flex items-center gap-2 text-sm text-slate-700">
<label for="sonar-input-a09f3b253f" class="visually-hidden">is active</label>
<input type="checkbox" name="is_active" value="1" checked class="rounded border-slate-300 text-blue-600 focus:ring-blue-500" id="sonar-input-a09f3b253f">
Make active key
</label>
<div>
<button type="submit" class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700">
Save API Key
</button>
</div>
</form>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
<h2 class="text-lg font-semibold text-slate-900">Stored API Keys</h2>
<div class="mt-5 overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<caption class="sr-only">Data table</caption>
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
<tr>
<th class="px-4 py-3">Name</th>
<th class="px-4 py-3">Key</th>
<th class="px-4 py-3">Active</th>
<th class="px-4 py-3">Updated</th>
<th class="px-4 py-3 text-right">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 bg-white">
@forelse ($settings as $setting)
<tr>
<td class="px-4 py-4 align-top font-medium text-slate-900">
<form id="setting-update-{{ $setting->id }}" method="POST" action="{{ route('chatgpt.settings.update', $setting) }}" class="grid gap-3">
@csrf
@method('PUT')
<label for="sonar-input-30f47d1294" class="visually-hidden">name</label>
<input
name="name"
type="text"
value="{{ old('name', $setting->name) }}"
class="w-full rounded-lg border-slate-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
id="name">
<label for="sonar-input-707eb8d2ba" class="visually-hidden">Leave blank to keep existing key</label>
<input
name="api_key"
type="password"
value=""
autocomplete="new-password"
placeholder="Leave blank to keep existing key"
class="w-full rounded-lg border-slate-300 text-sm shadow-sm focus:border-blue-500 focus:ring-blue-500"
id="sonar-input-707eb8d2ba">
<label class="inline-flex items-center gap-2 text-xs text-slate-600">
<label for="sonar-input-da782f0360" class="visually-hidden">is active</label>
<input
type="checkbox"
name="is_active"
value="1"
@checked($setting->is_active)
class="rounded border-slate-300 text-blue-600 focus:ring-blue-500"
>
Active
</label>
</form>
</td>
<td class="px-4 py-4 align-top font-mono text-slate-700">{{ $setting->maskedApiKey() }}</td>
<td class="px-4 py-4 align-top">
@if ($setting->is_active)
<span class="rounded-full bg-green-100 px-2.5 py-1 text-xs font-semibold text-green-800">Yes</span>
@else
<span class="rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-600">No</span>
@endif
</td>
<td class="px-4 py-4 align-top text-slate-600">{{ $setting->updated_at?->format('d M Y H:i') }}</td>
<td class="px-4 py-4 align-top">
<div class="flex justify-end gap-2">
<button
type="submit"
form="setting-update-{{ $setting->id }}"
class="rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-700"
>
Update
</button>
<form method="POST" action="{{ route('chatgpt.settings.destroy', $setting) }}">
@csrf
@method('DELETE')
<button type="submit" class="rounded-lg bg-red-600 px-3 py-2 text-xs font-semibold text-white hover:bg-red-700">
Delete
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-slate-500">
No API keys have been stored yet.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</section>
@endsection