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
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:
99
frontend/src/pages/maintenance.astro
Normal file
99
frontend/src/pages/maintenance.astro
Normal 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>
|
||||
Reference in New Issue
Block a user