Apply the sidebar shell and bold primitives across the rest of the app so the whole experience shares one visual language: - Browse/organize: series (keeps stacked-covers/series-card CSS), collections (keeps wood-paneling + carousel classes), browse_detail. - Account/stats: profile + form + modal, progress, analytics (stat-card tiles), devices, conflicts (status semantics), queue (status/priority badges). - Admin: admin sidebar restyled with icons, dashboard/users/library/ processing-issues/settings migrated to .card/.btn/.input primitives. - Docs/setup/misc: docs (keeps prose/highlight.js), api_explorer, setup wizard, unlinked_books, custom_section builder. - Modals/fragments: collection_modal, collection_rules, restore_system_collection_modal, filter_item, book_detail_modals — all overlays use --surface-overlay + --shadow-pop. Every Alpine handler, HTMX attribute, id, name, and data-* is preserved; only presentation changes.
115 lines
5.3 KiB
Templ
115 lines
5.3 KiB
Templ
package templates
|
|
|
|
templ APIExplorer(explorer APIExplorerData) {
|
|
if !explorer.IsLoggedIn {
|
|
<div x-data="devices" class="card p-6 mt-8 space-y-5">
|
|
<div class="flex items-center gap-2 flex-wrap">
|
|
if explorer.Endpoint.Method == "GET" {
|
|
<span class="badge status-completed">{ explorer.Endpoint.Method }</span>
|
|
} else if explorer.Endpoint.Method == "DELETE" {
|
|
<span class="badge status-failed">{ explorer.Endpoint.Method }</span>
|
|
} else if explorer.Endpoint.Method == "POST" {
|
|
<span class="badge" style="background-color: var(--accent-muted); color: var(--accent);">{ explorer.Endpoint.Method }</span>
|
|
} else {
|
|
<span class="badge status-processing">{ explorer.Endpoint.Method }</span>
|
|
}
|
|
<code class="text-sm" style="color: var(--text-secondary);">{ explorer.Endpoint.Path }</code>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<button class="btn btn-primary">Mock Data</button>
|
|
<button class="btn btn-secondary opacity-50 cursor-not-allowed" disabled>Login to Try Real</button>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs uppercase tracking-wide font-medium mb-2" style="color: var(--text-secondary);">Request Body (Example)</p>
|
|
<pre class="card p-4 overflow-x-auto"><code class="text-sm" style="color: var(--text-primary);">{ explorer.Endpoint.RequestBody }</code></pre>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs uppercase tracking-wide font-medium mb-2" style="color: var(--text-secondary);">Response (Mock)</p>
|
|
<pre class="card p-4 overflow-x-auto"><code class="text-sm" style="color: var(--text-primary);">{ explorer.Endpoint.Response }</code></pre>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<button @click="copyToClipboard(JSON.stringify({ explorer.Endpoint.RequestBody }, null, 2))" class="btn btn-secondary text-sm">
|
|
@Icon("copy", "h-4 w-4")
|
|
Copy Request
|
|
</button>
|
|
<button @click="copyToClipboard(JSON.stringify({ explorer.Endpoint.Response }, null, 2))" class="btn btn-secondary text-sm">
|
|
@Icon("copy", "h-4 w-4")
|
|
Copy Response
|
|
</button>
|
|
</div>
|
|
</div>
|
|
} else {
|
|
<div class="card p-6 mt-8 space-y-5" x-data="apiExplorerDoc" x-init="initAPIExplorerDoc('{ explorer.Endpoint.Path }', '{ explorer.Endpoint.RequestBody }', '{ explorer.Endpoint.Response }')">
|
|
<div class="flex items-center gap-2 flex-wrap">
|
|
if explorer.Endpoint.Method == "GET" {
|
|
<span class="badge status-completed">{ explorer.Endpoint.Method }</span>
|
|
} else if explorer.Endpoint.Method == "DELETE" {
|
|
<span class="badge status-failed">{ explorer.Endpoint.Method }</span>
|
|
} else if explorer.Endpoint.Method == "POST" {
|
|
<span class="badge" style="background-color: var(--accent-muted); color: var(--accent);">{ explorer.Endpoint.Method }</span>
|
|
} else {
|
|
<span class="badge status-processing">{ explorer.Endpoint.Method }</span>
|
|
}
|
|
<code class="text-sm" style="color: var(--text-secondary);">{ explorer.Endpoint.Path }</code>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<button class="mode-btn btn btn-secondary text-sm" id="mock-btn" @click="showDocMode('mock')">Mock Data</button>
|
|
<button class="mode-btn btn btn-primary text-sm" id="real-btn" @click="showDocMode('real')">Try It Out</button>
|
|
</div>
|
|
<div>
|
|
<label for="http-method" class="block text-xs uppercase tracking-wide font-medium mb-2" style="color: var(--text-secondary);">Method</label>
|
|
<select id="http-method" class="input">
|
|
<option value="GET" selected?={ explorer.Endpoint.Method == "GET" }>GET</option>
|
|
<option value="POST" selected?={ explorer.Endpoint.Method == "POST" }>POST</option>
|
|
<option value="PUT" selected?={ explorer.Endpoint.Method == "PUT" }>PUT</option>
|
|
<option value="DELETE" selected?={ explorer.Endpoint.Method == "DELETE" }>DELETE</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label for="request-body" class="block text-xs uppercase tracking-wide font-medium mb-2" style="color: var(--text-secondary);">Request Body</label>
|
|
<textarea id="request-body" placeholder="Edit request body…" class="input min-h-[150px] font-mono">{ explorer.Endpoint.RequestBody }</textarea>
|
|
</div>
|
|
<button id="try-it-out" @click="tryDocEndpoint()" class="btn btn-primary">
|
|
@Icon("play", "h-4 w-4")
|
|
Try It Out
|
|
</button>
|
|
<div class="api-response hidden space-y-2">
|
|
<div class="flex justify-between text-sm">
|
|
<span id="response-status" class="font-semibold" style="color: var(--text-primary);"></span>
|
|
<span id="response-time" style="color: var(--text-secondary);"></span>
|
|
</div>
|
|
<pre class="card p-4 overflow-x-auto"><code id="response-body" class="text-sm" style="color: var(--text-primary);"></code></pre>
|
|
</div>
|
|
<div class="flex gap-2 flex-wrap">
|
|
<button @click="copyDocRequest()" class="btn btn-secondary text-sm">
|
|
@Icon("copy", "h-4 w-4")
|
|
Copy Request
|
|
</button>
|
|
<button @click="copyDocResponse()" class="btn btn-secondary text-sm">
|
|
@Icon("copy", "h-4 w-4")
|
|
Copy Response
|
|
</button>
|
|
<button @click="generateDocCURL()" class="btn btn-secondary text-sm">
|
|
@Icon("external", "h-4 w-4")
|
|
Generate cURL
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
// APIExplorerData holds data for the API explorer component
|
|
type APIExplorerData struct {
|
|
Endpoint EndpointInfo
|
|
IsLoggedIn bool
|
|
}
|
|
|
|
// EndpointInfo holds information about an API endpoint
|
|
type EndpointInfo struct {
|
|
Method string
|
|
Path string
|
|
RequestBody string
|
|
Response string
|
|
Description string
|
|
}
|