Files

61 lines
2.5 KiB
HTML

{{/*
Shared empty / error / pending state blocks.
state-empty — genuine empty state (no data yet, nothing to show)
state-error — request failed; includes optional Retry button
state-pending — in-flight indicator (spinner + optional label)
Fields (all optional unless noted):
.Title string — main heading text
.Subtext string — secondary supporting copy
.Icon string — icon sprite id (defaults per block)
.ActionURL string — primary CTA href (state-empty only)
.ActionLabel string — primary CTA label (state-empty only)
.RetryURL string — htmx GET URL for retry (state-error only)
.RetryTarget string — htmx target selector (default: "closest [data-state-container]")
*/}}
{{ define "state-empty" }}
<div class="py-12 text-center" role="status">
<div class="text-base-content/60 mb-4">
{{ icon (or .Icon "inbox") "size-12 mx-auto mb-4" }}
</div>
<p class="text-lg">{{ or .Title "Nothing here yet." }}</p>
{{ if .Subtext }}<p class="text-base-content/70 text-sm mt-2">{{ .Subtext }}</p>{{ end }}
{{ if and .ActionURL .ActionLabel }}
<a href="{{ .ActionURL }}" class="btn btn-primary btn-sm mt-4">{{ .ActionLabel }}</a>
{{ end }}
</div>
{{ end }}
{{ define "state-error" }}
<div class="py-12 text-center" role="alert" aria-live="assertive">
<div class="text-error mb-4">
{{ icon (or .Icon "alert-triangle") "size-12 mx-auto mb-4" }}
</div>
<p class="text-lg">{{ or .Title "Something went wrong" }}</p>
{{ if .Subtext }}<p class="text-base-content/70 text-sm mt-2">{{ .Subtext }}</p>{{ end }}
{{ if .RetryURL }}
{{ if .RetryTarget }}
{{/* Partial retry: swap just the container back in via htmx. */}}
<button class="btn btn-outline btn-sm mt-4"
hx-get="{{ .RetryURL }}"
hx-target="{{ .RetryTarget }}"
hx-swap="outerHTML">
Try again
</button>
{{ else }}
{{/* Full-page retry: regular anchor, falls back gracefully without htmx. */}}
<a href="{{ .RetryURL }}" class="btn btn-outline btn-sm mt-4">Try again</a>
{{ end }}
{{ end }}
</div>
{{ end }}
{{ define "state-pending" }}
<div class="py-12 text-center" role="status" aria-live="polite">
<span class="loading loading-spinner loading-md"></span>
{{ if .Title }}<p class="text-base-content/70 text-sm mt-2">{{ .Title }}</p>{{ end }}
</div>
{{ end }}