Files
mengya-nav/cf-nav-frontend/admin.html
2026-03-11 20:46:24 +08:00

418 lines
13 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#10b981">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="萌芽导航管理">
<title>萌芽导航-后台管理</title>
<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/logo.png" type="image/png">
<link rel="apple-touch-icon" href="/logo.png">
<link rel="stylesheet" href="styles.css">
<script src="config.js"></script>
<script src="apply-config.js"></script>
<style>
.login-container {
max-width: 480px;
margin: 80px auto;
padding: 32px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
text-align: center;
}
.no-permission h2 {
color: #64748b;
margin-bottom: 12px;
}
.no-permission p {
color: #94a3b8;
font-size: 0.9rem;
}
.admin-container {
display: none;
}
.admin-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding: 15px 20px;
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
}
.logout-btn {
background: #dc2626;
color: white;
border: none;
padding: 8px 16px;
border-radius: 50px;
cursor: pointer;
font-weight: 600;
font-size: 0.9rem;
}
.logout-btn:hover {
background: #b91c1c;
}
.exit-btn {
background: #64748b;
color: white;
border: none;
padding: 8px 16px;
border-radius: 50px;
cursor: pointer;
font-weight: 600;
font-size: 0.9rem;
}
.exit-btn:hover {
background: #475569;
}
.sites-table {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #f1f5f9;
}
th {
background: #f8fafc;
font-weight: 600;
color: #1e293b;
}
.action-btns {
display: flex;
gap: 8px;
}
.btn-edit, .btn-delete {
padding: 6px 12px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
font-weight: 500;
}
.btn-edit {
background: #3b82f6;
color: white;
}
.btn-edit:hover {
background: #2563eb;
}
.btn-delete {
background: #ef4444;
color: white;
}
.btn-delete:hover {
background: #dc2626;
}
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
align-items: center;
justify-content: center;
}
.modal-overlay.active {
display: flex;
}
.error-message {
color: #dc2626;
margin-top: 10px;
font-size: 0.9rem;
}
.success-message {
color: #059669;
margin-top: 10px;
font-size: 0.9rem;
}
.tag-display {
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.tag-display .tag {
background: #e0e7ff;
color: #4338ca;
padding: 2px 8px;
border-radius: 10px;
font-size: 0.75rem;
}
.categories-panel {
background: white;
border-radius: 10px;
padding: 16px 20px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
margin-bottom: 16px;
}
.categories-panel .panel-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.category-add {
display: flex;
align-items: center;
gap: 8px;
}
.category-add input {
padding: 8px 10px;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-size: 0.9rem;
min-width: 160px;
}
.category-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.category-item {
display: inline-flex;
align-items: center;
gap: 6px;
background: #f8fafc;
border: 1px solid #e2e8f0;
padding: 6px 10px;
border-radius: 20px;
font-size: 0.85rem;
}
.category-item .category-actions button {
border: none;
background: transparent;
color: #475569;
cursor: pointer;
font-size: 0.85rem;
padding: 0 2px;
}
.category-item .category-actions button:hover {
color: #1d4ed8;
}
.sites-table-header {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 15px;
}
.sites-table-header h2 {
margin: 0;
}
.sites-filter {
display: flex;
align-items: center;
gap: 8px;
}
.sites-filter label {
font-size: 0.9rem;
color: #64748b;
}
#site-category-filter {
padding: 6px 12px;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-size: 0.9rem;
min-width: 160px;
background: white;
cursor: pointer;
}
#site-category-filter:focus {
outline: none;
border-color: #3b82f6;
}
</style>
</head>
<body>
<div class="container">
<!-- 无 token 或 token 错误时显示 -->
<div class="login-container" id="no-permission">
<h2>⚠️ 无法进入后台</h2>
<p>请使用带 token 的链接访问,例如:</p>
<p style="margin-top: 8px; word-break: break-all; color: #1e293b; font-size: 0.85rem;"><strong>/admin.html?token=管理员密钥</strong></p>
<p style="margin-top: 16px;">链接中的 token 需为后端 Worker 配置的管理员密钥ADMIN_PASSWORD</p>
</div>
<!-- 管理界面(仅 token 正确时显示) -->
<div class="admin-container" id="admin-container">
<div class="admin-header">
<h1 id="admin-title">萌芽导航-管理后台</h1>
<button class="exit-btn" id="logout-btn">退出</button>
</div>
<div class="categories-panel">
<div class="panel-header">
<h2>📁 分类管理</h2>
<div class="category-add">
<input type="text" id="new-category-name" placeholder="新增分类">
<button class="btn-edit" id="add-category-btn">添加分类</button>
</div>
</div>
<div class="category-list" id="category-list">
<!-- 分类标签 -->
</div>
</div>
<div style="margin-bottom: 20px;">
<button class="add-site-btn" id="add-new-site">✚ 添加新网站</button>
</div>
<div class="sites-table">
<div class="sites-table-header">
<h2>网站列表</h2>
<div class="sites-filter">
<label for="site-category-filter">按分类筛选:</label>
<select id="site-category-filter" title="选择分类可快速筛选网站">
<option value="">全部</option>
</select>
</div>
</div>
<table id="sites-table">
<thead>
<tr>
<th>名称</th>
<th>URL</th>
<th>分类</th>
<th>描述</th>
<th>标签</th>
<th>操作</th>
</tr>
</thead>
<tbody id="sites-tbody">
<!-- 动态加载 -->
</tbody>
</table>
</div>
</div>
<!-- 编辑/添加网站模态框 -->
<div class="modal-overlay" id="edit-modal">
<div class="modal-content">
<div class="modal-header">
<h2 id="modal-title">添加网站</h2>
<button class="close-modal" id="close-edit-modal">&times;</button>
</div>
<div class="modal-body">
<form id="edit-site-form">
<input type="hidden" id="edit-site-id">
<div class="form-group">
<label for="edit-site-name">网站名称 *</label>
<input type="text" id="edit-site-name" required>
</div>
<div class="form-group">
<label for="edit-site-url">网站地址 *</label>
<input type="url" id="edit-site-url" required>
</div>
<div class="form-group">
<label for="edit-site-description">网站描述</label>
<textarea id="edit-site-description"></textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="edit-site-category">网站分类 *</label>
<select id="edit-site-category" required>
<option value="">选择分类</option>
<option value="常用">常用</option>
<option value="工作">工作</option>
<option value="学习">学习</option>
<option value="娱乐">娱乐</option>
<option value="社交">社交</option>
<option value="工具">工具</option>
<option value="新闻">新闻</option>
<option value="购物">购物</option>
<option value="其他">其他</option>
</select>
</div>
<div class="form-group">
<label for="edit-site-tags">网站标签</label>
<input type="text" id="edit-site-tags" placeholder="用逗号分隔">
</div>
</div>
<button type="submit" class="submit-btn">保存</button>
</form>
</div>
</div>
</div>
<div class="toast" id="toast">
<span class="toast-icon"></span>
<span class="toast-message">操作成功</span>
</div>
</div>
<script src="admin.js"></script>
<script>
// 注册 Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('✅ Service Worker 注册成功:', registration.scope);
})
.catch(error => {
console.error('❌ Service Worker 注册失败:', error);
});
});
}
</script>
</body>
</html>