import React, { useEffect, useState } from 'react'; import { request } from '../api/client.js'; import { showSnackbar } from '../lib/utils.js'; const THEMES = [ { color: '#6750a4', name: 'default', label: '默认' }, { color: '#0288d1', name: 'ocean', label: '海洋' }, { color: '#2e7d32', name: 'nature', label: '自然' }, { color: '#e65100', name: 'sunset', label: '日落' }, ]; /** * 初始化向导(迁移自 setup.html + routes/setup.js 三步流程): * 1. 管理员密码(≥6 位、两次一致、不能等于 admin123)→ 2. 网站名称 + 主题色 → 3. 确认并完成。 * 提交 POST /api/setup/complete;已完成初始化时提示并跳首页。 */ export default function Setup() { const [status, setStatus] = useState(null); // null=检查中 const [step, setStep] = useState(1); const [adminPw, setAdminPw] = useState(''); const [adminPwConfirm, setAdminPwConfirm] = useState(''); const [siteName, setSiteName] = useState('RainWeb'); const [theme, setTheme] = useState({ color: '#6750a4', name: 'default', label: '默认' }); const [error, setError] = useState(''); const [busy, setBusy] = useState(false); useEffect(() => { request('/setup/status') .then((s) => setStatus(s || {})) .catch(() => setStatus({ setup_complete: true })); // 接口异常不阻塞,视为已完成 }, []); const next = (n) => { setError(''); if (n === 2) { if (adminPw.length < 6) { setError('密码至少6位'); return; } if (adminPw !== adminPwConfirm) { setError('两次密码不一致'); return; } if (adminPw === 'admin123') { setError('新密码不能与默认密码相同'); return; } } setStep(n); }; const complete = async () => { setBusy(true); try { await request('/setup/complete', { method: 'POST', body: { password: adminPw, site_name: siteName.trim() || 'RainWeb', primary_color: theme.color, theme_preset: theme.name, }, }); showSnackbar('初始化完成!'); setTimeout(() => { window.location.href = '/'; }, 1000); } catch (e) { setError(e.message || '初始化失败'); setBusy(false); } }; if (status === null) { return
; } // 已完成初始化:提示并跳首页 if (status.setup_complete) { return (

✅ 已完成初始化

RainWeb 已初始化完成,可正常使用。

进入首页
); } const stepDot = (n) => ({ width: n === step ? 28 : 10, height: 10, borderRadius: n === step ? 5 : '50%', background: n < step ? 'var(--md-ref-primary-container)' : (n === step ? 'var(--md-ref-primary)' : 'var(--md-ref-outline-variant)'), transition: 'all 0.3s', }); return (

🌧️ RainWeb

欢迎使用!请完成以下初始化设置

{[1, 2, 3].map((n) =>
)}
{step === 1 && (

设置管理员密码

setAdminPw(e.target.value)} placeholder="至少6位" autoComplete="new-password" />
setAdminPwConfirm(e.target.value)} placeholder="再次输入" autoComplete="new-password" onKeyDown={(e) => { if (e.key === 'Enter') next(2); }} />
)} {step === 2 && (

网站设置

setSiteName(e.target.value)} placeholder="我的网站" />
{THEMES.map((t) => (
setTheme({ color: t.color, name: t.name, label: t.label })} style={{ padding: 16, borderRadius: 12, border: '2px solid ' + (theme.name === t.name ? 'var(--md-ref-primary)' : 'var(--md-ref-outline-variant)'), cursor: 'pointer', textAlign: 'center', background: theme.name === t.name ? 'var(--md-ref-primary-container)' : 'transparent', transition: 'all 0.2s', }} >
{t.label}
))}
)} {step === 3 && (

确认并完成

管理员密码: 已设置
网站名称: {siteName.trim() || 'RainWeb'}
主题色: {theme.label}
)} {error &&
{error}
}
); }