GeoNetAgent, LDAPWeb, server-audit, server-connection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

187 lines
10 KiB

@extends('layouts.app')
@section('title', 'API Documentation — ' . config('app.name'))
@push('head')
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css">
<style>
#swagger-ui .swagger-ui { font-family: ui-sans-serif, system-ui, sans-serif; }
#swagger-ui .swagger-ui .topbar { display: none; }
.swagger-panel { background: #0f172a; border: 1px solid #1e293b; border-radius: 1rem; overflow: hidden; }
.swagger-panel .swagger-ui { background: #0f172a; padding: 1rem; }
html[data-theme='dark'] #swagger-ui .swagger-ui .info .title,
html:not([data-theme]) #swagger-ui .swagger-ui .info .title { color: #e2e8f0; }
html[data-theme='dark'] #swagger-ui .swagger-ui .info p,
html[data-theme='dark'] #swagger-ui .swagger-ui .info li,
html:not([data-theme]) #swagger-ui .swagger-ui .info p,
html:not([data-theme]) #swagger-ui .swagger-ui .info li { color: #94a3b8; }
html[data-theme='dark'] #swagger-ui .swagger-ui .opblock-tag,
html:not([data-theme]) #swagger-ui .swagger-ui .opblock-tag { color: #e2e8f0; border-bottom: 1px solid #1e293b; }
html[data-theme='dark'] #swagger-ui .swagger-ui .opblock,
html:not([data-theme]) #swagger-ui .swagger-ui .opblock { border-radius: 0.5rem; margin-bottom: 0.75rem; box-shadow: none; }
html[data-theme='dark'] #swagger-ui .swagger-ui section.models,
html:not([data-theme]) #swagger-ui .swagger-ui section.models { border: 1px solid #1e293b; border-radius: 0.5rem; }
html[data-theme='dark'] #swagger-ui .swagger-ui section.models h4,
html:not([data-theme]) #swagger-ui .swagger-ui section.models h4 { color: #e2e8f0; }
html[data-theme='dark'] #swagger-ui .swagger-ui .model-box,
html:not([data-theme]) #swagger-ui .swagger-ui .model-box { background: #0f172a; }
html[data-theme='dark'] #swagger-ui .swagger-ui table thead tr th,
html:not([data-theme]) #swagger-ui .swagger-ui table thead tr th { color: #94a3b8; }
html[data-theme='dark'] #swagger-ui .swagger-ui .responses-inner h4,
html[data-theme='dark'] #swagger-ui .swagger-ui .responses-inner h5,
html:not([data-theme]) #swagger-ui .swagger-ui .responses-inner h4,
html:not([data-theme]) #swagger-ui .swagger-ui .responses-inner h5 { color: #e2e8f0; }
html[data-theme='dark'] #swagger-ui .swagger-ui .response-col_status,
html:not([data-theme]) #swagger-ui .swagger-ui .response-col_status { color: #94a3b8; }
html[data-theme='light'] .swagger-panel { background: #ffffff; border-color: #e2e8f0; }
html[data-theme='light'] .swagger-panel .swagger-ui { background: #ffffff; }
html[data-theme='light'] #swagger-ui .swagger-ui .info .title { color: #0f172a; }
html[data-theme='light'] #swagger-ui .swagger-ui .info p,
html[data-theme='light'] #swagger-ui .swagger-ui .info li { color: #475569; }
html[data-theme='light'] #swagger-ui .swagger-ui .opblock-tag { color: #0f172a; border-bottom-color: #e2e8f0; background: #f8fafc; }
html[data-theme='light'] #swagger-ui .swagger-ui section.models { border-color: #e2e8f0; background: #f8fafc; }
html[data-theme='light'] #swagger-ui .swagger-ui section.models h4 { color: #0f172a; }
html[data-theme='light'] #swagger-ui .swagger-ui .model-box { background: #f8fafc; }
html[data-theme='light'] #swagger-ui .swagger-ui .opblock .opblock-summary { border-color: #e2e8f0; }
html[data-theme='light'] #swagger-ui .swagger-ui .responses-inner h4,
html[data-theme='light'] #swagger-ui .swagger-ui .responses-inner h5 { color: #0f172a; }
html[data-theme='light'] #swagger-ui .swagger-ui table thead tr th { color: #475569; }
html[data-theme='light'] #swagger-ui .swagger-ui .response-col_status { color: #64748b; }
html[data-theme='light'] #swagger-ui .swagger-ui .btn.authorize { background: #0891b2; border-color: #0891b2; color: #fff; }
html[data-theme='light'] #swagger-ui .swagger-ui .btn.execute { background: #0891b2; border-color: #0891b2; }
#swagger-ui .swagger-ui .btn.authorize { background: #0891b2; border-color: #0891b2; color: #fff; }
#swagger-ui .swagger-ui .btn.execute { background: #0891b2; border-color: #0891b2; }
</style>
@endpush
@section('content')
<div class="max-w-[1600px] mx-auto px-4 py-8">
<div class="mt-6 mb-6 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div>
<h1 class="text-3xl font-bold text-white">API Docs</h1>
<p class="text-slate-400 mt-2 text-sm">Interactive API seperti FastAPI — uji endpoint langsung dari browser.</p>
</div>
<div class="flex gap-2">
<button type="button" id="tab-live" data-tab="live"
class="tab-btn rounded-lg px-4 py-2 text-sm font-medium bg-cyan-600 text-white">
Live API
</button>
<button type="button" id="tab-guide" data-tab="guide"
class="tab-btn rounded-lg px-4 py-2 text-sm font-medium border border-slate-700 text-slate-300 hover:bg-slate-800">
Panduan
</button>
</div>
</div>
<div id="panel-live">
<div class="mb-4 bg-slate-900 border border-slate-800 rounded-xl p-4 text-sm text-slate-400 space-y-2">
<p><strong class="text-cyan-400">3 metode autentikasi</strong> (semua aktif di backend):</p>
<ul class="list-disc list-inside space-y-1 ml-2">
<li><strong class="text-white">API Token</strong>
@if (session('ldap_is_admin'))
buat di <a href="{{ route('api-clients.index') }}" class="text-cyan-400 hover:underline">API Clients</a>,
@else
minta ke administrator,
@endif
paste <code class="text-cyan-300">dbl_...</code> di <strong>Authorize</strong></li>
<li><strong class="text-white">LDAP JWT</strong> — jalankan <code class="text-cyan-300">POST /api/v1/auth/login</code> di bawah</li>
<li><strong class="text-white">OAuth2</strong> — jalankan <code class="text-cyan-300">POST /oauth/token</code> atau isi client di <strong>Authorize → oauth2ClientCredentials</strong></li>
</ul>
<p>Setelah dapat token → endpoint lain → <strong class="text-white">Try it out</strong><strong class="text-white">Execute</strong>.</p>
</div>
<div class="swagger-panel">
<div id="swagger-ui"></div>
</div>
</div>
<div id="panel-guide" class="hidden">
@include('api-docs.guide')
</div>
<aside class="mt-8 bg-slate-900 border border-slate-800 rounded-2xl p-5 notes-panel">
<h2 class="text-lg font-semibold text-white mb-4">Catatan</h2>
<dl class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm text-slate-400">
<div>
<dt class="font-medium text-cyan-400 mb-1">Live API</dt>
<dd>Tab Swagger UI — klik <strong class="text-slate-300">Try it out</strong> → isi parameter → <strong class="text-slate-300">Execute</strong>. Authorization disimpan di browser.</dd>
</div>
<div>
<dt class="font-medium text-violet-400 mb-1">3 metode auth</dt>
<dd>API Token, LDAP JWT, dan OAuth2 Client Credentials — semua aktif. Pilih sesuai kebutuhan integrasi.</dd>
</div>
<div>
<dt class="font-medium text-emerald-400 mb-1">Panduan</dt>
<dd>Tab Panduan berisi contoh request/response dan kode error umum.</dd>
</div>
<div>
<dt class="font-medium text-amber-400 mb-1">Tema</dt>
<dd>Swagger UI menyesuaikan Light/Dark theme dari toggle navigasi.</dd>
</div>
</dl>
</aside>
</div>
@endsection
@push('scripts')
<script src="https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui-bundle.js"></script>
<script>
(function () {
const tabs = document.querySelectorAll('.tab-btn');
const panelLive = document.getElementById('panel-live');
const panelGuide = document.getElementById('panel-guide');
tabs.forEach(function (btn) {
btn.addEventListener('click', function () {
const isLive = btn.dataset.tab === 'live';
panelLive.classList.toggle('hidden', !isLive);
panelGuide.classList.toggle('hidden', isLive);
tabs.forEach(function (b) {
b.className = 'tab-btn rounded-lg px-4 py-2 text-sm font-medium ' +
(b.dataset.tab === btn.dataset.tab
? 'bg-cyan-600 text-white'
: 'border border-slate-700 text-slate-300 hover:bg-slate-800');
});
});
});
window.ui = SwaggerUIBundle({
url: @json($openapiUrl),
dom_id: '#swagger-ui',
deepLinking: true,
persistAuthorization: true,
displayRequestDuration: true,
tryItOutEnabled: true,
syntaxHighlight: { theme: 'monokai' },
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
layout: 'BaseLayout',
onComplete: function () {
const token = localStorage.getItem('databaselist_api_token');
if (token && window.ui) {
window.ui.preauthorizeApiKey('bearerAuth', token);
}
},
responseInterceptor: function (res) {
try {
const body = JSON.parse(res.text);
if (body && body.data && body.data.access_token) {
localStorage.setItem('databaselist_api_token', body.data.access_token);
if (window.ui) {
window.ui.preauthorizeApiKey('bearerAuth', body.data.access_token);
}
}
if (body && body.access_token && !body.data) {
localStorage.setItem('databaselist_api_token', body.access_token);
if (window.ui) {
window.ui.preauthorizeApiKey('bearerAuth', body.access_token);
}
}
} catch (e) {}
return res;
},
});
})();
</script>
@endpush