2026-06-18 22:48:16 +08:00
|
|
|
|
{{define "head"}}
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>PR-Helper</title>
|
|
|
|
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
|
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
|
|
|
|
<script src="/static/js/htmx.min.js"></script>
|
2026-06-20 00:05:56 +08:00
|
|
|
|
<style>
|
|
|
|
|
|
.toast-enter { transform: translateX(100%); opacity: 0; }
|
|
|
|
|
|
.toast-active { transform: translateX(0); opacity: 1; transition: transform 0.3s ease, opacity 0.3s ease; }
|
|
|
|
|
|
.toast-exit { transform: translateX(100%); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; }
|
|
|
|
|
|
</style>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
// Global toast notification system
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
function ensureContainer() {
|
|
|
|
|
|
var c = document.getElementById('toast-container');
|
|
|
|
|
|
if (!c) {
|
|
|
|
|
|
c = document.createElement('div');
|
|
|
|
|
|
c.id = 'toast-container';
|
|
|
|
|
|
c.className = 'fixed top-4 right-4 z-50 flex flex-col items-end space-y-2';
|
|
|
|
|
|
document.body.appendChild(c);
|
|
|
|
|
|
}
|
|
|
|
|
|
return c;
|
|
|
|
|
|
}
|
|
|
|
|
|
window.showToast = function(message, type) {
|
|
|
|
|
|
type = type || 'info';
|
|
|
|
|
|
var colors = {
|
|
|
|
|
|
success: 'bg-green-50 border-green-200 text-green-800',
|
|
|
|
|
|
error: 'bg-red-50 border-red-200 text-red-800',
|
|
|
|
|
|
info: 'bg-blue-50 border-blue-200 text-blue-800',
|
|
|
|
|
|
warning: 'bg-yellow-50 border-yellow-200 text-yellow-800'
|
|
|
|
|
|
};
|
|
|
|
|
|
var icons = { success: '✓', error: '✗', info: 'ℹ', warning: '⚠' };
|
|
|
|
|
|
var container = ensureContainer();
|
|
|
|
|
|
var el = document.createElement('div');
|
|
|
|
|
|
el.className = 'px-4 py-3 rounded-md border text-sm shadow-lg max-w-sm toast-enter ' + (colors[type] || colors.info);
|
|
|
|
|
|
el.innerHTML = '<span class="mr-2 font-bold">' + (icons[type] || icons.info) + '</span>' +
|
|
|
|
|
|
'<span>' + message + '</span>' +
|
|
|
|
|
|
'<button onclick="this.parentElement.remove()" class="ml-3 text-current opacity-50 hover:opacity-100">×</button>';
|
|
|
|
|
|
container.appendChild(el);
|
|
|
|
|
|
requestAnimationFrame(function() { el.className = el.className.replace('toast-enter', 'toast-active'); });
|
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
|
el.className = el.className.replace('toast-active', 'toast-exit');
|
|
|
|
|
|
setTimeout(function() { el.remove(); }, 300);
|
|
|
|
|
|
}, 4000);
|
|
|
|
|
|
};
|
|
|
|
|
|
})();
|
|
|
|
|
|
</script>
|
2026-06-18 22:48:16 +08:00
|
|
|
|
</head>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
|
|
|
|
|
{{define "nav"}}
|
|
|
|
|
|
<nav class="bg-white shadow-sm border-b border-gray-200">
|
|
|
|
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
|
|
<div class="flex justify-between h-14">
|
|
|
|
|
|
<div class="flex items-center space-x-8">
|
|
|
|
|
|
<a href="/" class="text-lg font-bold text-indigo-600 hover:text-indigo-700">🔀 PR-Helper</a>
|
|
|
|
|
|
<a href="/" class="text-sm text-gray-600 hover:text-gray-900">首页</a>
|
|
|
|
|
|
<a href="/settings" class="text-sm text-gray-600 hover:text-gray-900">设置</a>
|
|
|
|
|
|
</div>
|
2026-06-20 21:57:46 +08:00
|
|
|
|
<div class="flex items-center space-x-4">
|
|
|
|
|
|
{{if .User}}
|
|
|
|
|
|
<span class="text-sm text-gray-500">{{.User.Email}}</span>
|
|
|
|
|
|
<form method="POST" action="/api/auth/logout" class="inline">
|
|
|
|
|
|
<button type="submit" class="text-sm text-gray-500 hover:text-gray-700">退出</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
</div>
|
2026-06-18 22:48:16 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
|
|
|
|
|
{{define "footer"}}
|
|
|
|
|
|
<footer class="bg-white border-t border-gray-200 py-4">
|
|
|
|
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center text-sm text-gray-400">
|
2026-06-21 15:11:20 +08:00
|
|
|
|
PR-Helper — AI 驱动的 PR 描述与代码审查
|
2026-06-18 22:48:16 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
{{end}}
|