Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/handler/kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
func htmlError(w http.ResponseWriter, code int, msg string) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(code)
_, _ = fmt.Fprintf(w, `<div class="px-4 py-10 text-center text-sm text-red-500">%s</div>`, html.EscapeString(msg))
_, _ = fmt.Fprintf(w, `<div class="px-4 py-10 text-center text-sm text-red-500 dark:text-red-400">%s</div>`, html.EscapeString(msg))
}

func Kill(cfg *config.Config, dbs map[string]*sql.DB, tableTmpl *template.Template) http.HandlerFunc {
Expand Down
10 changes: 5 additions & 5 deletions templates/home.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{{define "content"}}
<div class="max-w-2xl">
<h1 class="text-xl font-semibold text-gray-900 mb-4">Instances</h1>
<h1 class="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">Instances</h1>
<div class="grid gap-3">
{{range .Instances}}
<a href="/instance/{{.}}" class="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow hover:border-blue-300 transition-all group">
<a href="/instance/{{.}}" class="flex items-center justify-between p-4 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm hover:shadow hover:border-blue-300 dark:hover:border-blue-600 transition-all group">
<div class="flex items-center gap-3">
<div class="w-2 h-2 rounded-full bg-gray-300 group-hover:bg-green-400 transition-colors"></div>
<span class="font-medium text-gray-900">{{.}}</span>
<div class="w-2 h-2 rounded-full bg-gray-300 dark:bg-gray-600 group-hover:bg-green-400 transition-colors"></div>
<span class="font-medium text-gray-900 dark:text-gray-100">{{.}}</span>
</div>
<svg class="w-4 h-4 text-gray-400 group-hover:text-blue-500 transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg class="w-4 h-4 text-gray-400 dark:text-gray-500 group-hover:text-blue-500 dark:group-hover:text-blue-400 transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</a>
Expand Down
30 changes: 15 additions & 15 deletions templates/instance.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

<div class="flex items-center justify-between mb-3">
<nav class="flex items-center gap-2 text-sm">
<a href="/" class="text-gray-500 hover:text-gray-700 transition-colors">Instances</a>
<span class="text-gray-300">/</span>
<span class="font-medium text-gray-900">{{$name}}</span>
<a href="/" class="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors">Instances</a>
<span class="text-gray-300 dark:text-gray-600">/</span>
<span class="font-medium text-gray-900 dark:text-gray-100">{{$name}}</span>
</nav>

<div class="flex items-center gap-2">
<span id="refresh-indicator" class="htmx-indicator items-center gap-1.5 text-xs text-gray-400 mr-1">
<span id="refresh-indicator" class="htmx-indicator items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500 mr-1">
<svg class="animate-spin h-3 w-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
Expand All @@ -25,15 +25,15 @@

<a href="/instance/{{$name}}?sort={{$sc}}&dir={{$sd}}{{baseParams $ar (not $hs) $fu $fd}}"
class="px-3 py-1.5 text-xs font-medium border rounded transition-colors
{{if $hs}}bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100
{{else}}bg-white text-gray-600 border-gray-200 hover:bg-gray-50{{end}}">
{{if $hs}}bg-blue-50 dark:bg-blue-950 text-blue-700 dark:text-blue-300 border-blue-200 dark:border-blue-800 hover:bg-blue-100 dark:hover:bg-blue-900
{{else}}bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 border-gray-200 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700{{end}}">
{{if $hs}}Show Idle{{else}}Hide Idle{{end}}
</a>

<a href="/instance/{{$name}}?sort={{$sc}}&dir={{$sd}}{{baseParams (not $ar) $hs $fu $fd}}"
class="px-3 py-1.5 text-xs font-medium border rounded transition-colors
{{if $ar}}bg-green-50 text-green-700 border-green-200 hover:bg-green-100
{{else}}bg-white text-gray-600 border-gray-200 hover:bg-gray-50{{end}}">
{{if $ar}}bg-green-50 dark:bg-green-950 text-green-700 dark:text-green-300 border-green-200 dark:border-green-800 hover:bg-green-100 dark:hover:bg-green-900
{{else}}bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 border-gray-200 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700{{end}}">
{{if $ar}}⏸ Pause{{else}}▶ Auto Refresh{{end}}
</a>
</div>
Expand All @@ -42,23 +42,23 @@
{{/* Active filter tags */}}
{{if or $fu $fd}}
<div class="flex items-center gap-2 mb-3">
<span class="text-xs text-gray-500">Filtered by:</span>
<span class="text-xs text-gray-500 dark:text-gray-400">Filtered by:</span>
{{if $fu}}
<a href="/instance/{{$name}}?sort={{$sc}}&dir={{$sd}}{{baseParams $ar $hs "" $fd}}"
class="inline-flex items-center gap-1 px-2 py-0.5 text-xs bg-violet-100 text-violet-800 rounded-full hover:bg-violet-200 transition-colors">
class="inline-flex items-center gap-1 px-2 py-0.5 text-xs bg-violet-100 dark:bg-violet-900 text-violet-800 dark:text-violet-200 rounded-full hover:bg-violet-200 dark:hover:bg-violet-800 transition-colors">
User: {{$fu}} <span class="font-bold">×</span>
</a>
{{end}}
{{if $fd}}
<a href="/instance/{{$name}}?sort={{$sc}}&dir={{$sd}}{{baseParams $ar $hs $fu ""}}"
class="inline-flex items-center gap-1 px-2 py-0.5 text-xs bg-teal-100 text-teal-800 rounded-full hover:bg-teal-200 transition-colors">
class="inline-flex items-center gap-1 px-2 py-0.5 text-xs bg-teal-100 dark:bg-teal-900 text-teal-800 dark:text-teal-200 rounded-full hover:bg-teal-200 dark:hover:bg-teal-800 transition-colors">
DB: {{$fd}} <span class="font-bold">×</span>
</a>
{{end}}
</div>
{{end}}

<div class="overflow-x-auto bg-white border border-gray-200 rounded-lg shadow-sm">
<div class="overflow-x-auto bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm">
<div id="process-table"
{{if $ar}}
hx-get="/instance/{{$name}}?sort={{$sc}}&dir={{$sd}}{{baseParams true $hs $fu $fd}}"
Expand All @@ -80,10 +80,10 @@
</script>
{{end}}

<details class="mt-4 bg-white border border-gray-200 rounded-lg shadow-sm">
<summary class="px-4 py-3 cursor-pointer text-sm font-medium text-gray-700 hover:bg-gray-50 rounded-lg select-none">
<details class="mt-4 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm">
<summary class="px-4 py-3 cursor-pointer text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg select-none">
InnoDB Status
</summary>
<pre class="px-4 py-3 text-xs font-mono text-gray-600 whitespace-pre overflow-x-auto border-t border-gray-200">{{.InnoDBStatus}}</pre>
<pre class="px-4 py-3 text-xs font-mono text-gray-600 dark:text-gray-400 whitespace-pre overflow-x-auto border-t border-gray-200 dark:border-gray-700">{{.InnoDBStatus}}</pre>
</details>
{{end}}
60 changes: 57 additions & 3 deletions templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,72 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss-browser/4.1.13/index.global.min.js" integrity="sha512-TscjjxDy2iXx5s55Ar78c01JDHUug0K5aw4YKId9Yuocjx3ueX/X9PFyH5XNRVWqagx3TtcQWQVBaHAIPFjiFA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/htmx/2.0.7/htmx.min.js" integrity="sha512-IisGoumHahmfNIhP4wUV3OhgQZaaDBuD6IG4XlyjT77IUkwreZL3T3afO4xXuDanSalZ57Un+UlAbarQjNZCTQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="icon" href="/static/favicon.png" />
<style type="text/tailwindcss">
@custom-variant dark (&:where(.dark, .dark *));
</style>
<style>
.htmx-indicator { display: none; }
.htmx-indicator.htmx-request { display: inline-flex; }
.dark .badge-dynamic { filter: brightness(1.3) saturate(0.85); }
</style>
<script>
(function() {
var t = localStorage.getItem('theme');
if (t === 'dark' || ((!t || t === 'system') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
})();
</script>
</head>
<body class="bg-gray-50 min-h-screen">
<header class="bg-white border-b border-gray-200 px-6 py-3">
<a href="/" class="text-base font-semibold text-gray-900 hover:text-blue-600 transition-colors">MySQL Admin</a>
<body class="bg-gray-50 dark:bg-gray-950 min-h-screen">
<header class="bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700 px-6 py-3 flex items-center justify-between">
<a href="/" class="text-base font-semibold text-gray-900 dark:text-gray-100 hover:text-blue-600 dark:hover:text-blue-400 transition-colors">MySQL Admin</a>
<button id="theme-toggle" type="button"
class="p-1.5 rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
title="Toggle theme">
<svg id="icon-sun" class="w-5 h-5 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m8.66-13.66l-.71.71M4.05 19.95l-.71.71M21 12h-1M4 12H3m16.66 7.66l-.71-.71M4.05 4.05l-.71-.71M16 12a4 4 0 11-8 0 4 4 0 018 0z"/>
</svg>
<svg id="icon-moon" class="w-5 h-5 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/>
</svg>
<svg id="icon-system" class="w-5 h-5 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</button>
</header>
<main class="px-6 py-4">
{{template "content" .}}
</main>
<script>
(function() {
var toggle = document.getElementById('theme-toggle');
var iconSun = document.getElementById('icon-sun');
var iconMoon = document.getElementById('icon-moon');
var iconSystem = document.getElementById('icon-system');
function getTheme() { return localStorage.getItem('theme') || 'system'; }
function applyTheme(theme) {
var isDark = theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.toggle('dark', isDark);
iconSun.classList.toggle('hidden', theme !== 'dark');
iconMoon.classList.toggle('hidden', theme !== 'light');
iconSystem.classList.toggle('hidden', theme !== 'system');
var titles = { light: 'Light mode (click for dark)', dark: 'Dark mode (click for system)', system: 'System mode (click for light)' };
toggle.title = titles[theme];
}
toggle.addEventListener('click', function() {
var order = ['light', 'dark', 'system'];
var current = getTheme();
var next = order[(order.indexOf(current) + 1) % 3];
localStorage.setItem('theme', next);
applyTheme(next);
});
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function() {
if (getTheme() === 'system') applyTheme('system');
});
applyTheme(getTheme());
})();
</script>
</body>
</html>
{{end}}
Loading