auto-sync: 2026-05-17 06:16:06

This commit is contained in:
cfdaily
2026-05-17 06:16:07 +08:00
parent 1159c22a0e
commit 1876f71537
+113
View File
@@ -0,0 +1,113 @@
// 系统配置页面
import React, { useState } from 'react';
import { useProjects } from '../hooks/useApi';
import * as api from '../api';
export function Config() {
const { projects, loading, refresh } = useProjects();
const [newName, setNewName] = useState('');
const [newDesc, setNewDesc] = useState('');
const [creating, setCreating] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleCreate = async () => {
if (!newName.trim()) return;
try {
setCreating(true);
setError(null);
await api.createProject({ name: newName, description: newDesc || null });
setNewName('');
setNewDesc('');
refresh();
} catch (e) {
setError(String(e));
} finally {
setCreating(false);
}
};
return (
<div>
<h2 className="page-title"></h2>
{/* 创建项目 */}
<div className="card" style={{ marginBottom: 20 }}>
<div className="card-title"></div>
<div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
<input
type="text"
placeholder="项目名称"
value={newName}
onChange={e => setNewName(e.target.value)}
style={{
flex: 1,
padding: '6px 10px',
borderRadius: 'var(--radius)',
border: '1px solid var(--line)',
background: 'var(--bg)',
color: 'var(--fg)',
}}
/>
<input
type="text"
placeholder="描述(可选)"
value={newDesc}
onChange={e => setNewDesc(e.target.value)}
style={{
flex: 2,
padding: '6px 10px',
borderRadius: 'var(--radius)',
border: '1px solid var(--line)',
background: 'var(--bg)',
color: 'var(--fg)',
}}
/>
<button
className="btn btn-primary"
onClick={handleCreate}
disabled={creating || !newName.trim()}
>
{creating ? '创建中...' : '创建'}
</button>
</div>
{error && <p className="error" style={{ marginTop: 8 }}>{error}</p>}
</div>
{/* 项目列表 */}
<div className="card">
<div className="card-title"></div>
{loading ? (
<div className="loading">...</div>
) : (
<div className="table-wrapper">
<table>
<thead>
<tr>
<th>ID</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{projects.map(p => (
<tr key={p.id}>
<td style={{ fontFamily: 'monospace' }}>{p.id.substring(0, 8)}</td>
<td>{p.name}</td>
<td style={{ color: 'var(--muted)' }}>{p.description || '-'}</td>
<td>
<span className={`badge badge-${p.status === 'active' ? 'done' : 'blocked'}`}>
{p.status}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
</div>
);
}