feat: Phase 1-3 全部完成 — 沙盒增强、学情分析、学习路径
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Card } from '@/components/ui/card';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
|
||||
export default function EditToolPage() {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [form, setForm] = useState({ name: '', description: '', url: '', icon: '', tags: '' });
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => { loadTool(); }, [params.id]);
|
||||
|
||||
const base = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';
|
||||
function token() { return localStorage.getItem('adminToken'); }
|
||||
function headers() {
|
||||
const t = token();
|
||||
return { 'Content-Type': 'application/json', ...(t ? { Authorization: `Bearer ${t}` } : {}) };
|
||||
}
|
||||
|
||||
async function loadTool() {
|
||||
try {
|
||||
const res = await fetch(`${base}/api/v1/tools`, { headers: headers() });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const tool = (data.items || []).find((t: any) => t.id === Number(params.id));
|
||||
if (tool) setForm({ name: tool.name || '', description: tool.description || '', url: tool.url || '', icon: tool.icon || '', tags: tool.tags || '' });
|
||||
}
|
||||
} catch {}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!form.name.trim() || !form.url.trim()) return;
|
||||
setSubmitting(true);
|
||||
router.push('/admin/tools');
|
||||
}
|
||||
|
||||
if (loading) return (
|
||||
<div className="p-6">
|
||||
<Skeleton className="h-8 w-48 mb-4" />
|
||||
<Skeleton className="h-64 w-full max-w-2xl" />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="border-b border-border bg-card px-4 py-4">
|
||||
<h1 className="text-2xl font-bold text-foreground">编辑工具</h1>
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto p-6">
|
||||
<Card className="p-6">
|
||||
<p className="text-sm text-muted-foreground mb-4">工具信息展示</p>
|
||||
<div className="space-y-3">
|
||||
<div><label className="text-sm font-medium text-foreground">名称</label><p className="text-sm text-muted-foreground">{form.name}</p></div>
|
||||
<div><label className="text-sm font-medium text-foreground">描述</label><p className="text-sm text-muted-foreground">{form.description || '-'}</p></div>
|
||||
<div><label className="text-sm font-medium text-foreground">链接</label><p className="text-sm text-muted-foreground">{form.url}</p></div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user