试卷编辑页三处布局优化:头部标题独立成行可换行、网格显式单列+元素自适应、题目编辑表单渲染在被编辑题下方
test / test (push) Failing after 6m52s

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
jacobxu666
2026-08-20 15:24:10 +08:00
co-authored by Claude Haiku 4.5
parent 131ee41ac8
commit 95994b14d0
4 changed files with 46 additions and 39 deletions
+2 -2
View File
@@ -17,11 +17,11 @@ export default async function EditExamPage({ params }: { params: Promise<{ paper
return (
<main className="relative mx-auto max-w-3xl space-y-5 p-4 pb-10">
<BackgroundBlobs />
<header className="flex items-center justify-between">
<header className="space-y-2">
<Link href="/parent/exams" className="text-sm font-medium text-indigo-600">
← 试卷列表
</Link>
<h1 className="text-xl font-extrabold text-slate-900">{paper.title}</h1>
<h1 className="text-xl font-extrabold break-words text-slate-900">{paper.title}</h1>
</header>
<div className="rounded-2xl border border-slate-100 bg-white p-5 shadow-soft">
<PaperForm
+2 -2
View File
@@ -13,11 +13,11 @@ export default async function NewExamPage() {
return (
<main className="relative mx-auto max-w-3xl space-y-5 p-4 pb-10">
<BackgroundBlobs />
<header className="flex items-center justify-between">
<header className="space-y-2">
<Link href="/parent/exams" className="text-sm font-medium text-indigo-600">
← 试卷列表
</Link>
<h1 className="text-xl font-extrabold text-slate-900">新建试卷</h1>
<h1 className="text-xl font-extrabold break-words text-slate-900">新建试卷</h1>
</header>
<div className="rounded-2xl border border-slate-100 bg-white p-5 shadow-soft">
<PaperForm paper={null} isNew />
+2 -2
View File
@@ -89,7 +89,7 @@ export function PaperForm({ paper, isNew }: { paper: PaperMeta | null; isNew: bo
return (
<div className="space-y-4">
<div className="grid gap-3 sm:grid-cols-2">
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
<div className="space-y-1">
<Label>试卷编号(唯一,如 g7s1-m09-2)</Label>
<Input disabled={!isNew} placeholder="g7s1-m09-2" {...n("paperId")} />
@@ -165,7 +165,7 @@ export function PaperForm({ paper, isNew }: { paper: PaperMeta | null; isNew: bo
</div>
{msg && <p className={msg.ok ? "text-sm font-medium text-emerald-600" : "text-sm font-medium text-destructive"}>{msg.text}</p>}
<div className="flex items-center gap-2">
<div className="flex flex-wrap items-center gap-2">
<Button disabled={pending} onClick={save}>
<Save className="size-4" /> {pending ? "保存中…" : "保存"}
</Button>
+40 -33
View File
@@ -1,6 +1,6 @@
"use client";
import { useState } from "react";
import { Fragment, useState } from "react";
import { ArrowDown, ArrowUp, Pencil, Plus, Trash2, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -72,37 +72,10 @@ export function QuestionList({
onChange(next);
};
return (
<div className="space-y-3">
{value.map((q, i) => {
const def = q as QuizQ;
return (
<div key={i} className="rounded-xl border border-slate-100 bg-slate-50/60 p-3">
<div className="flex items-center gap-2">
<span className="rounded-full bg-indigo-100 px-2 py-0.5 text-xs font-medium text-indigo-700">{TYPE_LABEL[def.type]}</span>
<span className="truncate text-sm font-medium text-slate-800">{def.stem}</span>
<span className="ml-auto flex items-center gap-1.5">
<button type="button" aria-label={`上移第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => move(i, -1)}>
<ArrowUp className="size-4" />
</button>
<button type="button" aria-label={`下移第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => move(i, 1)}>
<ArrowDown className="size-4" />
</button>
<button type="button" aria-label={`编辑第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => startEdit(i)}>
<Pencil className="size-4" />
</button>
<button type="button" aria-label={`删除第 ${i + 1} 题`} className="text-muted-foreground hover:text-destructive" onClick={() => remove(i)}>
<Trash2 className="size-4" />
</button>
</span>
</div>
</div>
);
})}
{draft ? (
<div className="rounded-xl border border-indigo-200 bg-white p-3">
<div className="mb-2 flex items-center justify-between">
// xuchao: 编辑表单——编辑存量题渲染在该题卡片下方,新增时渲染在列表末尾
const draftForm = draft ? (
<div className="rounded-xl border border-indigo-200 bg-white p-3">
<div className="mb-2 flex flex-wrap items-center justify-between gap-2">
<label className="text-sm font-medium text-slate-700">
题型
<select
@@ -231,7 +204,41 @@ export function QuestionList({
</Button>
</div>
</div>
) : (
) : null;
return (
<div className="space-y-3">
{value.map((q, i) => {
const def = q as QuizQ;
return (
<Fragment key={i}>
<div className="rounded-xl border border-slate-100 bg-slate-50/60 p-3">
<div className="flex items-center gap-2">
<span className="rounded-full bg-indigo-100 px-2 py-0.5 text-xs font-medium text-indigo-700">{TYPE_LABEL[def.type]}</span>
<span className="truncate text-sm font-medium text-slate-800">{def.stem}</span>
<span className="ml-auto flex items-center gap-1">
<button type="button" aria-label={`上移第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => move(i, -1)}>
<ArrowUp className="size-4" />
</button>
<button type="button" aria-label={`下移第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => move(i, 1)}>
<ArrowDown className="size-4" />
</button>
<button type="button" aria-label={`编辑第 ${i + 1} 题`} className="text-muted-foreground hover:text-indigo-600" onClick={() => startEdit(i)}>
<Pencil className="size-4" />
</button>
<button type="button" aria-label={`删除第 ${i + 1} 题`} className="text-muted-foreground hover:text-destructive" onClick={() => remove(i)}>
<Trash2 className="size-4" />
</button>
</span>
</div>
</div>
{draft && editIndex === i && draftForm}
</Fragment>
);
})}
{draft && editIndex == null && draftForm}
{!draft && (
<Button variant="outline" onClick={startNew}>
<Plus className="size-4" /> + 新增题目
</Button>