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
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
|
|
|