feat: update tag and timeline share panel copy for clarity and conciseness
Some checks failed
docker-images / resolve-build-targets (push) Successful in 7s
ui-regression / playwright-regression (push) Failing after 13m4s
docker-images / build-and-push (admin) (push) Successful in 1m17s
docker-images / build-and-push (backend) (push) Successful in 28m13s
docker-images / build-and-push (frontend) (push) Successful in 47s
docker-images / submit-indexnow (push) Successful in 13s

style: enhance global CSS for better responsiveness of terminal chips and navigation pills

test: remove inline subscription test and add maintenance mode access code test

feat: implement media library picker dialog for selecting images from the media library

feat: add media URL controls for uploading and managing media assets

feat: add migration for music_enabled and maintenance_mode settings in site settings

feat: implement maintenance mode functionality with access control

feat: create maintenance page with access code input and error handling

chore: add TypeScript declaration for QR code module
This commit is contained in:
2026-04-02 23:05:49 +08:00
parent 6a50dd478c
commit 9665c933b5
94 changed files with 5266 additions and 1612 deletions

View File

@@ -0,0 +1,99 @@
---
import '../styles/global.css'
import { api, DEFAULT_SITE_SETTINGS } from '../lib/api/client'
import { sanitizeMaintenanceReturnTo } from '../lib/maintenance'
const errorCode = Astro.url.searchParams.get('error')
const returnTo = sanitizeMaintenanceReturnTo(Astro.url.searchParams.get('returnTo'))
let siteSettings = DEFAULT_SITE_SETTINGS
try {
siteSettings = await api.getSiteSettings()
} catch (error) {
console.error('Failed to load site settings on maintenance page:', error)
}
const errorMessage =
errorCode === 'empty'
? '请先输入访问口令。'
: errorCode === 'invalid'
? '口令不正确,请重新输入。'
: errorCode === 'unavailable'
? '当前无法校验访问口令,请稍后再试。'
: ''
---
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex, nofollow" />
<title>{siteSettings.siteName} · 维护模式</title>
</head>
<body class="min-h-screen bg-[var(--bg)] text-[var(--text)]">
<main class="mx-auto flex min-h-screen w-full max-w-6xl items-center px-4 py-10 sm:px-6 lg:px-8">
<section class="terminal-toolbar-shell mx-auto w-full max-w-2xl overflow-hidden rounded-[2rem] p-0">
<div class="border-b border-[var(--border-color)] px-6 py-5 sm:px-8">
<div class="flex items-center gap-3">
<span class="flex h-12 w-12 items-center justify-center rounded-2xl border border-[var(--border-color)] bg-[var(--primary)]/10 text-xl font-semibold text-[var(--primary)]">
{siteSettings.siteShortName?.charAt(0) || siteSettings.siteName?.charAt(0) || 'T'}
</span>
<div class="min-w-0">
<p class="terminal-toolbar-label">MAINTENANCE ACCESS</p>
<h1 class="mt-1 text-2xl font-bold text-[var(--title-color)] sm:text-3xl">
{siteSettings.siteName} 正在维护
</h1>
</div>
</div>
</div>
<div class="space-y-6 px-6 py-6 sm:px-8 sm:py-8">
<div class="rounded-3xl border border-[var(--border-color)] bg-[var(--terminal-bg)]/80 p-5">
<p class="text-sm leading-7 text-[var(--text-secondary)]">
当前前台内容暂时对外隐藏。你如果拿到了测试口令,可以直接输入进入站点继续浏览;没有口令的话,等我们开放后再访问即可。
</p>
{errorMessage && (
<div class="mt-4 rounded-2xl border border-[var(--danger)]/20 bg-[var(--danger)]/8 px-4 py-3 text-sm text-[var(--danger)]">
{errorMessage}
</div>
)}
</div>
<form method="post" action="/api/maintenance/unlock" class="space-y-4">
<input type="hidden" name="returnTo" value={returnTo} />
<label class="block">
<span class="terminal-form-label">访问口令</span>
<input
type="password"
name="code"
autocomplete="current-password"
placeholder="请输入测试口令"
class="terminal-form-input"
/>
</label>
<div class="flex flex-col gap-3 sm:flex-row sm:items-center">
<button type="submit" class="terminal-action-button terminal-action-button-primary min-w-[10rem]">
进入站点
</button>
<p class="text-sm leading-6 text-[var(--text-tertiary)]">
口令修改后,旧的访问凭证会自动失效。
</p>
</div>
</form>
<div class="rounded-3xl border border-dashed border-[var(--border-color)] bg-[var(--header-bg)]/40 px-5 py-4">
<p class="text-xs uppercase tracking-[0.22em] text-[var(--text-tertiary)]">
Return Target
</p>
<p class="mt-2 font-mono text-sm text-[var(--title-color)]">{returnTo}</p>
</div>
</div>
</section>
</main>
</body>
</html>