fix: UI overhaul — align all HTMX views with Lumina Design System (46 fixes)

- All 7 pages rewritten: Dashboard, Terminal, Snippets, Keychain, SFTP, Settings, Brief
- Apply consistent Lumina glassmorphic theme (rounded-2xl, shadows, borders, tracking)
- Fix SVG icons not rendering — return template.HTML instead of string
- Fix Alpine x-data scoping: terminal tabs, SFTP modals, snippet tag buttons
- Fix dashboard search sending literal ?q=...
- Rebuild CSS with all new Tailwind classes (62KB)
- Add .air.toml with hot-reload config, docs/PERBAIKANUI.md checklist
- Remove unused backup partials
This commit is contained in:
swanadiva
2026-07-07 14:55:42 +07:00
parent fd7361aa14
commit 8357d9d76e
29 changed files with 3321 additions and 924 deletions
+44 -19
View File
@@ -1,32 +1,57 @@
{{define "snippet_grid"}}
<div id="snippet-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<div id="snippet-grid" class="space-y-6">
{{range .Snippets}}
<div class="rounded-xl bg-white border border-outline-variant/30 p-4 hover:shadow-md transition-shadow animate-fade-in">
<div class="flex items-start justify-between mb-3">
<div>
<p class="text-sm font-medium text-on-surface">{{.Name}}</p>
<span class="text-xs font-medium px-1.5 py-0.5 rounded-full bg-tertiary/10 text-tertiary">{{.Language}}</span>
<div class="bg-white border border-outline-variant/30 rounded-2xl overflow-hidden shadow-sm flex flex-col group">
<div class="p-5 flex justify-between items-start gap-4">
<div class="space-y-1">
<div class="flex flex-wrap items-center gap-2">
<h3 class="font-bold text-on-surface text-base group-hover:text-primary transition-colors">{{.Name}}</h3>
<div class="flex flex-wrap gap-1">
{{range .Tags}}
<span class="px-2 py-0.5 bg-surface-container text-[10px] font-bold rounded text-on-surface-variant">{{.}}</span>
{{end}}
</div>
</div>
{{if .Description}}
<p class="text-xs text-on-surface-variant leading-relaxed">{{.Description}}</p>
{{end}}
</div>
<button class="p-1.5 rounded-lg hover:bg-red-50 text-on-surface-variant hover:text-red-500 transition-colors shrink-0"
hx-delete="/snippets/{{.ID}}" hx-target="#snippet-grid" hx-confirm="Delete {{.Name}}?">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
<div class="flex items-center gap-2 shrink-0">
<button onclick="copyToClipboard(`{{.Content}}`)"
class="p-1.5 border border-outline-variant/40 rounded-lg bg-surface-container-low hover:border-primary text-outline hover:text-primary transition-colors"
title="Copy code to clipboard">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
</button>
<button hx-delete="/snippets/{{.ID}}" hx-target="#snippet-grid" hx-confirm="Delete {{.Name}}?"
class="p-1.5 border border-outline-variant/40 rounded-lg bg-surface-container-low hover:border-error text-outline hover:text-error transition-colors"
title="Delete code snippet">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
</button>
</div>
</div>
<div class="bg-surface-container-low border-t border-outline-variant/40 p-4 font-mono text-xs text-on-surface relative group/code overflow-x-auto">
<pre class="text-on-surface select-all leading-relaxed whitespace-pre font-medium">{{.Content}}</pre>
<button onclick="copyToClipboard(`{{.Content}}`)"
class="absolute right-4 top-4 bg-white/90 backdrop-blur border border-outline-variant/30 shadow px-2.5 py-1 rounded text-[10px] font-mono font-bold hover:border-primary hover:text-primary transition-colors opacity-0 group-hover/code:opacity-100">
COPY
</button>
</div>
<pre class="text-xs text-on-surface-variant bg-surface-container-low/50 rounded-lg p-3 mb-3 overflow-x-auto font-mono leading-relaxed">{{.Content}}</pre>
<div class="flex items-center justify-between pt-3 border-t border-outline-variant/20">
<span class="text-xs text-on-surface-variant">{{.CreatedAt}}</span>
<button class="p-1.5 rounded-lg hover:bg-primary/10 text-on-surface-variant hover:text-primary transition-colors"
onclick="copyToClipboard(`{{.Content}}`)" title="Copy">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
</button>
<div class="px-5 py-2 border-t border-outline-variant/20 bg-surface-container-lowest flex justify-between items-center text-[10px] text-outline font-semibold">
<span>Last adjusted {{.CreatedAt}}</span>
<span class="flex items-center gap-1 text-primary">
<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
Ready to inject to shell
</span>
</div>
</div>
{{end}}
{{if eq (len .Snippets) 0}}
<div class="col-span-full text-center py-12 text-on-surface-variant">
<p class="text-lg font-medium">No snippets found</p>
<p class="text-sm mt-1">Add your first snippet to get started</p>
<div class="p-12 border border-dashed border-outline-variant/40 rounded-2xl text-center text-outline">
No matching snippet found.
</div>
{{end}}
</div>