openlearn-next 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/assets/{ActivityWorkspaceWidget-5PzyxF6a.js → ActivityWorkspaceWidget-CMN8elwQ.js} +1 -1
  2. package/dist/assets/{AdminDirectoryView-BCtmQTEK.js → AdminDirectoryView-Dlz7q-xf.js} +1 -1
  3. package/dist/assets/{AssessmentCenter-B43ojHG-.js → AssessmentCenter-CaoAI9Ke.js} +1 -1
  4. package/dist/assets/{BatchPickerModal-CbmjInp7.js → BatchPickerModal-CzutdtIz.js} +1 -1
  5. package/dist/assets/{ClassesView-DEnMaDOt.js → ClassesView-RkFPpWRu.js} +1 -1
  6. package/dist/assets/{ClassroomCountdownWidget-CHq4983w.js → ClassroomCountdownWidget-gs42lIGW.js} +1 -1
  7. package/dist/assets/{CloudDriveModal-D2t3Uyzr.js → CloudDriveModal-C6JtK08M.js} +1 -1
  8. package/dist/assets/{ComputerLabView-YtnoT5Rb.js → ComputerLabView-Dr-g8FrU.js} +1 -1
  9. package/dist/assets/{CourseManagement-DOXyJ_j-.js → CourseManagement-DNeaJcT9.js} +1 -1
  10. package/dist/assets/{CourseWizardModal-Dbi6Caw2.js → CourseWizardModal-vw876VJr.js} +1 -1
  11. package/dist/assets/{Dashboard-2rLu_ZBy.js → Dashboard-C1iYnfCh.js} +1 -1
  12. package/dist/assets/{ExportWeightModal-BrmAh6VX.js → ExportWeightModal-CTZ-O_wi.js} +1 -1
  13. package/dist/assets/{HelpView-CVBrKDrd.js → HelpView-wyKldm_R.js} +1 -1
  14. package/dist/assets/{ImportLessonsModal-PhHtX31R.js → ImportLessonsModal-C09Z-qtx.js} +1 -1
  15. package/dist/assets/{InteractiveCoursewareViewer-Vi6lLz7a.js → InteractiveCoursewareViewer-V97euiJF.js} +1 -1
  16. package/dist/assets/{InteractiveWhiteboard-lTzeayX5.js → InteractiveWhiteboard-COLMh_-w.js} +1 -1
  17. package/dist/assets/{LazyCourseware-KIt0rGtW.js → LazyCourseware-0iFYlRGj.js} +2 -2
  18. package/dist/assets/{LazyWhiteboard-CCN3pYcW.js → LazyWhiteboard-CcoBIx6V.js} +2 -2
  19. package/dist/assets/{LessonEditorView-D_GVhHuM.js → LessonEditorView-BWmtKwmP.js} +1 -1
  20. package/dist/assets/{LiveClassroomView-BRsZ6QEq.js → LiveClassroomView-CaS1DzSS.js} +1 -1
  21. package/dist/assets/{NotificationDetailModal-tY5rxYCN.js → NotificationDetailModal-4MdNF4tw.js} +1 -1
  22. package/dist/assets/{PluginView-CedpAW6d.js → PluginView-BqTbAp30.js} +1 -1
  23. package/dist/assets/{QuizGeneratorModal-bUA002kP.js → QuizGeneratorModal-xTq22vDq.js} +1 -1
  24. package/dist/assets/{StudentAssignmentView-BhAz6Hfk.js → StudentAssignmentView-Cy_JdPYB.js} +1 -1
  25. package/dist/assets/{StudentLessonView-DC1yX4kG.js → StudentLessonView-B3fKejCU.js} +1 -1
  26. package/dist/assets/{StudentView-PHKxIV9T.js → StudentView-CpJsG7FT.js} +2 -2
  27. package/dist/assets/{SystemResourceLibraryModal-DgXYe6_x.js → SystemResourceLibraryModal-YZ85mv_v.js} +1 -1
  28. package/dist/assets/{TeacherView-DscJtOJ9.js → TeacherView-B3zhzd5g.js} +2 -2
  29. package/dist/assets/{TimetableView-D2ozoj_D.js → TimetableView-D_4XmrRN.js} +1 -1
  30. package/dist/assets/{index-2676X8YB.js → index-BzXADCXZ.js} +5 -5
  31. package/dist/assets/{pluginParsers-e4PSm2Iy.js → pluginParsers-PzgFzxS9.js} +1 -1
  32. package/dist/cli-migrator.cjs +18 -1
  33. package/dist/index.html +1 -1
  34. package/dist/server.cjs +339 -249
  35. package/package.json +3 -2
@@ -1 +1 @@
1
- import{r as o,j as e}from"./vendor-react-Kv_JATwr.js";import{e as D}from"./index-2676X8YB.js";import{$ as q,X as H,j as J,i as Q,B as V,o as X,y as _,w as G,U as K,b1 as Y,b0 as Z,b2 as ee,e as te,P as se}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";async function ie(n="all"){const a=await fetch(`/api/activities?role=${encodeURIComponent(n)}`,{headers:{Accept:"application/json"}});if(!a.ok)throw new Error(`Failed to load activities (${a.status})`);return(await a.json()).activities??[]}async function k(){const n=await fetch("/api/activities/running",{headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`Failed to load running activities (${n.status})`);return(await n.json()).activities??[]}async function ne(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/finish`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to finish activity (${a.status})`)}}async function ae(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/pause`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to pause activity (${a.status})`)}}async function re(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/resume`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to resume activity (${a.status})`)}}async function oe(n,a,s){const l=await fetch(`/api/activities/${encodeURIComponent(n)}/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({payload:a??{},actorId:s})}),c=await l.json();if(!l.ok||c.ok===!1)throw new Error(c.error||`Failed to start activity (${l.status})`);return c}const x={padding:"12px",color:"#e2e8f0",fontSize:"13px"},ce={HelpCircle:te,Vote:ee,BarChart3:Z,MessagesSquare:Y,Users:K,FileText:G,Trophy:_,CheckCircle2:X,BookOpen:V};function le({name:n,className:a}){const s=n&&ce[n]||se;return e.jsx(s,{size:18,className:a})}function de(n,a){if(!n)return a==="zh"?"进行中":"In progress";const s=Math.max(0,Math.floor((Date.now()-n)/1e3)),l=Math.floor(s/60),c=s%60;return a==="zh"?`${l} 分 ${c} 秒`:`${l}m ${c}s`}const ge=({role:n,actorId:a,lang:s="en",classroomId:l,mode:c="launcher"})=>{const[p,E]=o.useState([]),[A,j]=o.useState(!0),[b,$]=o.useState(null),[v,m]=o.useState({}),[h,w]=o.useState([]),[T,R]=o.useState(!0),[P,I]=o.useState(null),[y,u]=o.useState(null),[f,z]=o.useState(!1),[S,C]=o.useState(null),B=D(i=>i.setTeacherTab),F=o.useMemo(()=>{const i=new Map;for(const t of p){const r=t.category;i.has(r)||i.set(r,[]),i.get(r).push(t)}return Array.from(i.entries())},[p]);o.useEffect(()=>{if(c!=="launcher")return;let i=!1;return j(!0),ie(n).then(t=>{i||E(t)}).catch(t=>{i||$(t instanceof Error?t.message:String(t))}).finally(()=>{i||j(!1)}),()=>{i=!0}},[n,c]),o.useEffect(()=>{if(c!=="status")return;let i=!1;const t=async()=>{try{const d=await k();i||w(d)}catch(d){i||I(d instanceof Error?d.message:String(d))}finally{i||R(!1)}};t();const r=setInterval(t,5e3);return()=>{i=!0,clearInterval(r)}},[c]);const g=async i=>{if(y){z(!0),C(null);try{await i(y),w(await k())}catch(t){C(t instanceof Error?t.message:String(t))}finally{z(!1)}}},W=()=>g(ne),M=()=>g(ae),O=()=>g(re),L=()=>{u(null),B("live_class")};if(c==="status"){if(T)return e.jsx("div",{className:"bg-white border border-slate-200/80 rounded-2xl p-5 shadow-sm h-24 animate-pulse"});if(P||h.length===0)return null;const i=h.find(t=>t.id===y)||null;return e.jsxs("div",{className:"bg-white border border-slate-200/80 rounded-2xl p-5 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-slate-800 font-extrabold",children:[e.jsx("span",{children:"🧩"}),e.jsx("span",{children:s==="zh"?"进行中的活动":"Activities in Progress"})]}),e.jsx("span",{className:"text-xs font-bold bg-indigo-50 text-indigo-700 px-2 py-0.5 rounded-full",children:h.length})]}),e.jsx("div",{className:"flex flex-col gap-2",children:h.map(t=>{const r=t.state==="running";return e.jsxs("button",{onClick:()=>u(t.id),className:"w-full flex items-center gap-3 text-left bg-slate-50 hover:bg-slate-100 border border-slate-200/70 rounded-xl p-3 transition-colors",children:[e.jsx(le,{name:t.icon,className:"text-indigo-600 shrink-0"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-bold text-slate-800 truncate",children:t.name}),t.category&&e.jsx("div",{className:"text-xs text-slate-500 truncate",children:t.category})]}),e.jsxs("div",{className:"flex flex-col items-end gap-1 shrink-0",children:[e.jsx("span",{className:`text-xs font-bold px-2 py-0.5 rounded-full ${r?"bg-emerald-100 text-emerald-700":"bg-amber-100 text-amber-700"}`,children:r?s==="zh"?"进行中":"Running":s==="zh"?"已暂停":"Paused"}),e.jsxs("span",{className:"text-xs text-slate-400 flex items-center gap-1",children:[e.jsx(q,{size:10})," ",de(t.startedAt,s)]})]})]},t.id)})}),i&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/30 p-4",onClick:()=>u(null),children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl w-full max-w-sm p-5",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"font-bold text-slate-800",children:i.name}),e.jsx("button",{onClick:()=>u(null),className:"text-slate-400 hover:text-slate-600","aria-label":"close",children:e.jsx(H,{size:18})})]}),e.jsxs("div",{className:"text-sm text-slate-500 mb-1",children:[s==="zh"?"状态":"Status",":"," ",i.state==="running"?s==="zh"?"进行中":"Running":s==="zh"?"已暂停":"Paused"]}),e.jsxs("div",{className:"text-sm text-slate-500 mb-4",children:[s==="zh"?"开始时间":"Started",":"," ",i.startedAt?new Date(i.startedAt).toLocaleString():"-"]}),S&&e.jsx("div",{className:"text-xs text-rose-600 mb-2",children:S}),e.jsxs("div",{className:"flex gap-2",children:[i.state==="running"?e.jsxs("button",{disabled:f,onClick:M,className:"flex-1 flex items-center justify-center gap-1 bg-amber-500 hover:bg-amber-600 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:[e.jsx(J,{size:14})," ",s==="zh"?"暂停":"Pause"]}):e.jsxs("button",{disabled:f,onClick:O,className:"flex-1 flex items-center justify-center gap-1 bg-indigo-500 hover:bg-indigo-600 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:[e.jsx(Q,{size:14})," ",s==="zh"?"恢复":"Resume"]}),e.jsx("button",{disabled:f,onClick:W,className:"flex-1 flex items-center justify-center gap-1 bg-rose-600 hover:bg-rose-700 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:f?s==="zh"?"处理中…":"Working…":s==="zh"?"结束":"End"})]}),e.jsx("button",{onClick:L,className:"w-full mt-2 bg-slate-100 hover:bg-slate-200 text-slate-700 rounded-lg py-2 text-sm font-bold",children:s==="zh"?"进入课堂":"Enter Classroom"})]})})]})}const U=async i=>{m(t=>({...t,[i.id]:s==="zh"?"启动中…":"Starting…"}));try{const t=await oe(i.id,{classroomId:l,role:n},a);m(r=>({...r,[i.id]:t.dispatched?s==="zh"?"已启动 ✓":"Started ✓":s==="zh"?"已通知 ✓":"Notified ✓"}))}catch(t){m(r=>({...r,[i.id]:t instanceof Error?t.message:String(t)}))}};if(A)return e.jsx("div",{style:x,children:s==="zh"?"加载活动中…":"Loading activities…"});if(b)return e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:6},children:["🧩 ",s==="zh"?"活动中心":"Activity Center"]}),e.jsx("div",{style:{opacity:.7},children:b})]});const N=n==="teacher"?s==="zh"?"活动中心(教师)":"Activity Center":s==="zh"?"活动(学生)":"Activities";return p.length===0?e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:6},children:["🧩 ",N]}),e.jsx("div",{style:{opacity:.7},children:s==="zh"?"暂无可用活动。":"No activities available."})]}):e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:8},children:["🧩 ",N]}),F.map(([i,t])=>e.jsxs("div",{style:{marginBottom:10},children:[e.jsx("div",{style:{opacity:.6,fontSize:12,textTransform:"uppercase",marginBottom:4},children:i}),e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8},children:t.map(r=>e.jsxs("div",{style:{border:"1px solid #334155",borderRadius:8,padding:"8px 10px",minWidth:150,background:"#0f172a"},children:[e.jsxs("div",{style:{fontWeight:600},children:[r.icon?`${r.icon} `:"▫️ ",r.name]}),r.description&&e.jsx("div",{style:{opacity:.7,fontSize:12,margin:"2px 0 6px"},children:r.description}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("button",{onClick:()=>U(r),style:{cursor:"pointer",background:n==="teacher"?"#2563eb":"#0ea5e9",color:"#fff",border:"none",borderRadius:6,padding:"4px 10px",fontSize:12},children:n==="teacher"?s==="zh"?"启动":"Start":s==="zh"?"参与":"Open"}),v[r.id]&&e.jsx("span",{style:{fontSize:12,opacity:.85},children:v[r.id]})]}),e.jsx("div",{style:{opacity:.5,fontSize:12,marginTop:4},children:r.provider==="official"?"official":r.provider})]},r.id))})]},i))]})};export{ge as ActivityWorkspaceWidget};
1
+ import{r as o,j as e}from"./vendor-react-Kv_JATwr.js";import{e as D}from"./index-BzXADCXZ.js";import{$ as q,X as H,j as J,i as Q,B as V,o as X,y as _,w as G,U as K,b1 as Y,b0 as Z,b2 as ee,e as te,P as se}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";async function ie(n="all"){const a=await fetch(`/api/activities?role=${encodeURIComponent(n)}`,{headers:{Accept:"application/json"}});if(!a.ok)throw new Error(`Failed to load activities (${a.status})`);return(await a.json()).activities??[]}async function k(){const n=await fetch("/api/activities/running",{headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`Failed to load running activities (${n.status})`);return(await n.json()).activities??[]}async function ne(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/finish`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to finish activity (${a.status})`)}}async function ae(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/pause`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to pause activity (${a.status})`)}}async function re(n){const a=await fetch(`/api/activities/${encodeURIComponent(n)}/resume`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to resume activity (${a.status})`)}}async function oe(n,a,s){const l=await fetch(`/api/activities/${encodeURIComponent(n)}/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({payload:a??{},actorId:s})}),c=await l.json();if(!l.ok||c.ok===!1)throw new Error(c.error||`Failed to start activity (${l.status})`);return c}const x={padding:"12px",color:"#e2e8f0",fontSize:"13px"},ce={HelpCircle:te,Vote:ee,BarChart3:Z,MessagesSquare:Y,Users:K,FileText:G,Trophy:_,CheckCircle2:X,BookOpen:V};function le({name:n,className:a}){const s=n&&ce[n]||se;return e.jsx(s,{size:18,className:a})}function de(n,a){if(!n)return a==="zh"?"进行中":"In progress";const s=Math.max(0,Math.floor((Date.now()-n)/1e3)),l=Math.floor(s/60),c=s%60;return a==="zh"?`${l} 分 ${c} 秒`:`${l}m ${c}s`}const ge=({role:n,actorId:a,lang:s="en",classroomId:l,mode:c="launcher"})=>{const[p,E]=o.useState([]),[A,j]=o.useState(!0),[b,$]=o.useState(null),[v,m]=o.useState({}),[h,w]=o.useState([]),[T,R]=o.useState(!0),[P,I]=o.useState(null),[y,u]=o.useState(null),[f,z]=o.useState(!1),[S,C]=o.useState(null),B=D(i=>i.setTeacherTab),F=o.useMemo(()=>{const i=new Map;for(const t of p){const r=t.category;i.has(r)||i.set(r,[]),i.get(r).push(t)}return Array.from(i.entries())},[p]);o.useEffect(()=>{if(c!=="launcher")return;let i=!1;return j(!0),ie(n).then(t=>{i||E(t)}).catch(t=>{i||$(t instanceof Error?t.message:String(t))}).finally(()=>{i||j(!1)}),()=>{i=!0}},[n,c]),o.useEffect(()=>{if(c!=="status")return;let i=!1;const t=async()=>{try{const d=await k();i||w(d)}catch(d){i||I(d instanceof Error?d.message:String(d))}finally{i||R(!1)}};t();const r=setInterval(t,5e3);return()=>{i=!0,clearInterval(r)}},[c]);const g=async i=>{if(y){z(!0),C(null);try{await i(y),w(await k())}catch(t){C(t instanceof Error?t.message:String(t))}finally{z(!1)}}},W=()=>g(ne),M=()=>g(ae),O=()=>g(re),L=()=>{u(null),B("live_class")};if(c==="status"){if(T)return e.jsx("div",{className:"bg-white border border-slate-200/80 rounded-2xl p-5 shadow-sm h-24 animate-pulse"});if(P||h.length===0)return null;const i=h.find(t=>t.id===y)||null;return e.jsxs("div",{className:"bg-white border border-slate-200/80 rounded-2xl p-5 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-slate-800 font-extrabold",children:[e.jsx("span",{children:"🧩"}),e.jsx("span",{children:s==="zh"?"进行中的活动":"Activities in Progress"})]}),e.jsx("span",{className:"text-xs font-bold bg-indigo-50 text-indigo-700 px-2 py-0.5 rounded-full",children:h.length})]}),e.jsx("div",{className:"flex flex-col gap-2",children:h.map(t=>{const r=t.state==="running";return e.jsxs("button",{onClick:()=>u(t.id),className:"w-full flex items-center gap-3 text-left bg-slate-50 hover:bg-slate-100 border border-slate-200/70 rounded-xl p-3 transition-colors",children:[e.jsx(le,{name:t.icon,className:"text-indigo-600 shrink-0"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-bold text-slate-800 truncate",children:t.name}),t.category&&e.jsx("div",{className:"text-xs text-slate-500 truncate",children:t.category})]}),e.jsxs("div",{className:"flex flex-col items-end gap-1 shrink-0",children:[e.jsx("span",{className:`text-xs font-bold px-2 py-0.5 rounded-full ${r?"bg-emerald-100 text-emerald-700":"bg-amber-100 text-amber-700"}`,children:r?s==="zh"?"进行中":"Running":s==="zh"?"已暂停":"Paused"}),e.jsxs("span",{className:"text-xs text-slate-400 flex items-center gap-1",children:[e.jsx(q,{size:10})," ",de(t.startedAt,s)]})]})]},t.id)})}),i&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/30 p-4",onClick:()=>u(null),children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl w-full max-w-sm p-5",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"font-bold text-slate-800",children:i.name}),e.jsx("button",{onClick:()=>u(null),className:"text-slate-400 hover:text-slate-600","aria-label":"close",children:e.jsx(H,{size:18})})]}),e.jsxs("div",{className:"text-sm text-slate-500 mb-1",children:[s==="zh"?"状态":"Status",":"," ",i.state==="running"?s==="zh"?"进行中":"Running":s==="zh"?"已暂停":"Paused"]}),e.jsxs("div",{className:"text-sm text-slate-500 mb-4",children:[s==="zh"?"开始时间":"Started",":"," ",i.startedAt?new Date(i.startedAt).toLocaleString():"-"]}),S&&e.jsx("div",{className:"text-xs text-rose-600 mb-2",children:S}),e.jsxs("div",{className:"flex gap-2",children:[i.state==="running"?e.jsxs("button",{disabled:f,onClick:M,className:"flex-1 flex items-center justify-center gap-1 bg-amber-500 hover:bg-amber-600 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:[e.jsx(J,{size:14})," ",s==="zh"?"暂停":"Pause"]}):e.jsxs("button",{disabled:f,onClick:O,className:"flex-1 flex items-center justify-center gap-1 bg-indigo-500 hover:bg-indigo-600 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:[e.jsx(Q,{size:14})," ",s==="zh"?"恢复":"Resume"]}),e.jsx("button",{disabled:f,onClick:W,className:"flex-1 flex items-center justify-center gap-1 bg-rose-600 hover:bg-rose-700 disabled:opacity-60 text-white rounded-lg py-2 text-sm font-bold",children:f?s==="zh"?"处理中…":"Working…":s==="zh"?"结束":"End"})]}),e.jsx("button",{onClick:L,className:"w-full mt-2 bg-slate-100 hover:bg-slate-200 text-slate-700 rounded-lg py-2 text-sm font-bold",children:s==="zh"?"进入课堂":"Enter Classroom"})]})})]})}const U=async i=>{m(t=>({...t,[i.id]:s==="zh"?"启动中…":"Starting…"}));try{const t=await oe(i.id,{classroomId:l,role:n},a);m(r=>({...r,[i.id]:t.dispatched?s==="zh"?"已启动 ✓":"Started ✓":s==="zh"?"已通知 ✓":"Notified ✓"}))}catch(t){m(r=>({...r,[i.id]:t instanceof Error?t.message:String(t)}))}};if(A)return e.jsx("div",{style:x,children:s==="zh"?"加载活动中…":"Loading activities…"});if(b)return e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:6},children:["🧩 ",s==="zh"?"活动中心":"Activity Center"]}),e.jsx("div",{style:{opacity:.7},children:b})]});const N=n==="teacher"?s==="zh"?"活动中心(教师)":"Activity Center":s==="zh"?"活动(学生)":"Activities";return p.length===0?e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:6},children:["🧩 ",N]}),e.jsx("div",{style:{opacity:.7},children:s==="zh"?"暂无可用活动。":"No activities available."})]}):e.jsxs("div",{style:x,children:[e.jsxs("div",{style:{fontWeight:600,marginBottom:8},children:["🧩 ",N]}),F.map(([i,t])=>e.jsxs("div",{style:{marginBottom:10},children:[e.jsx("div",{style:{opacity:.6,fontSize:12,textTransform:"uppercase",marginBottom:4},children:i}),e.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8},children:t.map(r=>e.jsxs("div",{style:{border:"1px solid #334155",borderRadius:8,padding:"8px 10px",minWidth:150,background:"#0f172a"},children:[e.jsxs("div",{style:{fontWeight:600},children:[r.icon?`${r.icon} `:"▫️ ",r.name]}),r.description&&e.jsx("div",{style:{opacity:.7,fontSize:12,margin:"2px 0 6px"},children:r.description}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[e.jsx("button",{onClick:()=>U(r),style:{cursor:"pointer",background:n==="teacher"?"#2563eb":"#0ea5e9",color:"#fff",border:"none",borderRadius:6,padding:"4px 10px",fontSize:12},children:n==="teacher"?s==="zh"?"启动":"Start":s==="zh"?"参与":"Open"}),v[r.id]&&e.jsx("span",{style:{fontSize:12,opacity:.85},children:v[r.id]})]}),e.jsx("div",{style:{opacity:.5,fontSize:12,marginTop:4},children:r.provider==="official"?"official":r.provider})]},r.id))})]},i))]})};export{ge as ActivityWorkspaceWidget};
@@ -1,4 +1,4 @@
1
- import{r,j as e}from"./vendor-react-Kv_JATwr.js";import{ba as as,ak as fe,P as rs,a9 as $,ao as is,aZ as ns,X as ye,c as K,ap as E,R as A,o as Ie,$ as os,K as ls,T as ie,z as ds,ac as Ee,S as se,e as cs,U as te,by as xs,bw as ae,a3 as ms,cd as hs,af as ps,ab as bs,bq as Re,q as $e,as as us,a$ as gs,bt as fs,b as ys}from"./vendor-icons-CXrZ3R2V.js";import{E as re,b as js}from"./index-2676X8YB.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function Ns({lang:a,aiProviders:x,onAIProvidersChanged:s}){const[T,f]=r.useState(!1),[N,y]=r.useState(null),[p,S]=r.useState(""),[v,g]=r.useState(""),[U,P]=r.useState(""),[z,b]=r.useState(""),[L,k]=r.useState(!1),_=()=>{y(null),S(""),g(""),P(""),b(""),f(!0)},D=n=>{y(n),S(n.name),g(n.api_url),P(n.api_key||""),b(n.model_name),f(!0)},M=async n=>{if(n.preventDefault(),!p.trim()||!v.trim()||!z.trim()){alert(a==="zh"?"名称、API URL 和模型名称不可为空":"Name, API URL and Model Name are required.");return}try{k(!0);const m=!!N,u=m?`/api/ai-providers/${N.id}`:"/api/ai-providers",O=await fetch(u,{method:m?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),api_url:v.trim(),api_key:U,model_name:z.trim()})});if(O.ok)f(!1),y(null),s();else{const G=await O.json().catch(()=>({}));alert(G.error||"Server error")}}catch(m){alert(m.message||"Error")}finally{k(!1)}},l=async(n,m)=>{if(confirm(a==="zh"?`确认要删除 AI 提供商 [${m}] 吗?`:`Confirm deleting AI Provider [${m}]?`))try{(await fetch(`/api/ai-providers/${n}`,{method:"DELETE"})).ok?s():alert("Delete failed")}catch(u){alert(u.message||"Error")}},c=async n=>{try{const m=await fetch("/api/ai-providers/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_url:n.api_url,api_key:n.api_key,model_name:n.model_name})});if(m.ok)alert(a==="zh"?`[${n.name}] 连接测试成功!`:`[${n.name}] Connection test successful!`);else{const u=await m.json().catch(()=>({}));alert(a==="zh"?`测试失败: ${u.error||"未知错误"}`:`Test failed: ${u.error||"Unknown error"}`)}}catch(m){alert(a==="zh"?`网络异常: ${m.message}`:`Network error: ${m.message}`)}};return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-1 overflow-y-auto p-6 space-y-6 animate-fade-in text-gray-800",children:e.jsxs("div",{className:"bg-white border border-gray-200 rounded-xl shadow-3xs overflow-hidden",children:[e.jsxs("div",{className:"p-4 sm:p-5 border-b border-gray-100 flex items-center justify-between bg-gray-50/60",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"font-bold text-gray-800 flex items-center gap-2 text-sm sm:text-base",children:[e.jsx(as,{className:"text-indigo-600",size:18}),a==="zh"?"OpenAI 兼容 / 自定义模型 AI 提供商列表":"AI Providers List (OpenAI-Compatible)"]}),e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:a==="zh"?"配置好的端点将可被测验生成器、讲座生成器和 AI Agent 进行热切调用。":"Configured backends accessible by Quiz Generator, Lecture Generator and AI Agent."})]}),e.jsxs("button",{onClick:_,className:"flex items-center gap-1.5 px-3.5 py-1.5 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-lg shadow-sm transition-all text-xs cursor-pointer",children:[e.jsx(fe,{size:14}),a==="zh"?"添加 AI 提供商":"Add AI Provider"]})]}),e.jsx("div",{className:"p-4 sm:p-5",children:x.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-gray-400 text-center",children:[e.jsx(rs,{size:40,className:"mb-3 opacity-30 text-indigo-500"}),e.jsx("span",{className:"font-semibold text-sm",children:a==="zh"?"暂未配置任何 AI 提供商":"No AI Providers Registered"}),e.jsx("p",{className:"text-xs text-gray-400 mt-1 max-w-xs",children:a==="zh"?"点击右上角按钮新建。":"Click the button above to add one."})]}):e.jsx("div",{className:"overflow-x-auto border border-gray-100 rounded-xl",children:e.jsxs("table",{className:"w-full text-left border-collapse min-w-[700px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-slate-50/70 border-b border-gray-100 text-gray-500 font-bold text-xs uppercase tracking-wider",children:[e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"名称":"Name"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"API 端点 URL":"API Endpoint URL"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"模型代号":"Model Identifier"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"密钥状态":"API Key"}),e.jsx("th",{className:"py-3.5 px-4 text-center",children:a==="zh"?"操作":"Actions"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-100 text-xs text-gray-700",children:x.map(n=>e.jsxs("tr",{className:"hover:bg-slate-50/50 transition-colors",children:[e.jsx("td",{className:"py-4 px-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-2 h-2 rounded-full bg-indigo-500"}),e.jsx("span",{className:"font-extrabold text-gray-800 text-sm",children:n.name})]})}),e.jsx("td",{className:"py-4 px-4 font-mono text-gray-550 truncate max-w-[220px]",children:n.api_url}),e.jsx("td",{className:"py-4 px-4",children:e.jsx("span",{className:"bg-slate-100 text-slate-800 font-bold px-2 py-1 rounded font-mono text-xs border border-slate-200",children:n.model_name})}),e.jsx("td",{className:"py-4 px-4",children:n.api_key?e.jsxs("span",{className:"text-emerald-600 font-bold flex items-center gap-1 font-mono",children:[e.jsx($,{size:12})," Key Saved"]}):e.jsx("span",{className:"text-amber-500/90 font-mono italic",children:"Not Set"})}),e.jsx("td",{className:"py-4 px-4 text-center",children:e.jsxs("div",{className:"flex items-center justify-center gap-2",children:[e.jsxs("button",{onClick:()=>c(n),className:"px-2.5 py-1 text-xs font-semibold rounded-lg border transition-all cursor-pointer flex items-center gap-1.5 shadow-3xs bg-emerald-50 border-emerald-200 text-emerald-700 hover:bg-emerald-100",title:a==="zh"?"测试连通性":"Test Connection",children:[e.jsx(is,{size:11}),e.jsx("span",{children:a==="zh"?"测试":"Test"})]}),e.jsx("button",{onClick:()=>D(n),className:"px-2.5 py-1 text-indigo-700 hover:bg-indigo-100 border border-indigo-200 rounded-lg bg-indigo-50 cursor-pointer font-semibold transition-all shadow-3xs",title:a==="zh"?"编辑配置":"Edit",children:a==="zh"?"编辑":"Edit"}),e.jsx("button",{onClick:()=>l(n.id,n.name),className:"px-2.5 py-1 text-rose-600 hover:bg-rose-100 border border-rose-200 rounded-lg bg-rose-50 cursor-pointer font-semibold transition-all shadow-3xs",title:a==="zh"?"删除":"Delete",children:a==="zh"?"删除":"Delete"})]})})]},n.id))})]})})})]})}),T&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-xs flex items-center justify-center p-4 z-50 overflow-y-auto",children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl border border-gray-200/60 w-full max-w-md overflow-hidden text-gray-800 text-left",children:[e.jsxs("div",{className:"flex items-center justify-between p-5 border-b border-gray-100 bg-slate-50/70",children:[e.jsxs("h3",{className:"font-extrabold text-sm sm:text-base text-gray-800 flex items-center gap-2",children:[e.jsx(ns,{className:"text-indigo-600",size:18}),N?a==="zh"?"编辑 AI 提供商配置":"Edit AI Provider":a==="zh"?"添加全新 AI 提供商":"Add New AI Provider"]}),e.jsx("button",{onClick:()=>{f(!1),y(null)},className:"p-1 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100 transition-colors",children:e.jsx(ye,{size:16})})]}),e.jsxs("form",{onSubmit:M,className:"p-5 space-y-4 text-left",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"服务商名称 *":"Provider Name *"}),e.jsx("input",{type:"text",required:!0,placeholder:"e.g. Deepseek, Minimax",value:p,onChange:n=>S(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-semibold"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"API 端点 URL *":"API Endpoint URL *"}),e.jsx("input",{type:"url",required:!0,placeholder:"https://api.deepseek.com/v1",value:v,onChange:n=>g(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"}),e.jsx("span",{className:"text-xs text-gray-400 mt-1 block",children:a==="zh"?"符合 OpenAI 规范的标准 API 统一基准 URL。":"OpenAI-compatible base URL (e.g. /v1)."})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"模型代号 *":"Model Identifier *"}),e.jsx("input",{type:"text",required:!0,placeholder:"e.g. deepseek-chat",value:z,onChange:n=>b(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"API Key (可选)":"API Key (Optional)"}),e.jsx("input",{type:"password",placeholder:a==="zh"?"不修改请留空":"Leave empty to keep existing",value:U,onChange:n=>P(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"})]}),e.jsxs("div",{className:"flex items-center justify-end gap-3 pt-4 border-t border-gray-100",children:[e.jsx("button",{type:"button",onClick:()=>{f(!1),y(null)},className:"px-4 py-2 text-xs font-bold text-gray-500 bg-slate-100 hover:bg-slate-200 rounded-lg cursor-pointer transition-colors",children:a==="zh"?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:L,className:"px-4 py-2 text-xs font-bold text-white bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 rounded-lg shadow-sm transition-all cursor-pointer flex items-center gap-1.5",children:[L?e.jsx(K,{size:13,className:"animate-spin"}):e.jsx($,{size:14}),e.jsx("span",{children:L?a==="zh"?"保存中...":"Saving...":a==="zh"?"保存至数据库":"Save Connection"})]})]})]})]})})]})}const vs=[{key:"lesson",zh:"课程",en:"Lessons"},{key:"class",zh:"班级",en:"Classes"},{key:"student",zh:"学生",en:"Students"},{key:"class_student",zh:"班级关系",en:"Enrollments"},{key:"schedule",zh:"课表",en:"Schedules"},{key:"user",zh:"账号",en:"Accounts"}];function ws({lang:a}){const[x,s]=r.useState(null),[T,f]=r.useState(!1),[N,y]=r.useState(!1),[p,S]=r.useState(!1),[v,g]=r.useState(null),U=async l=>{const c=await l.json().catch(()=>({}));return c&&c.success?c.result:null},P=async l=>{const c=await l.json().catch(()=>({}));return{result:c&&c.success?c.result:null,message:c?.message}},z=r.useCallback(async()=>{try{f(!0);const l=await fetch("/api/demo-data/status");if(l.ok){const c=await U(l);c&&s(c)}}catch(l){console.error("Failed to fetch demo data status",l)}finally{f(!1)}},[]);r.useEffect(()=>{z()},[z]);const b=!!(x&&(x.seeded||x.total>0)),L=async()=>{try{y(!0),g(null);const l=await fetch(`/api/demo-data/seed${b?"?reset=true":""}`,{method:"POST"}),c=await U(l);l.ok&&c?(s(c),g({type:"success",text:a==="zh"?"演示数据已就绪,可用下方演示教师账号登录体验。":"Demo data is ready. Log in with the demo teacher account below."})):g({type:"error",text:a==="zh"?"初始化演示数据失败,请稍后重试。":"Failed to seed demo data, please retry."})}catch(l){g({type:"error",text:a==="zh"?`初始化失败:${l.message||"网络异常"}`:`Seed failed: ${l.message||"Network error"}`})}finally{y(!1)}},k=async()=>{if(confirm(a==="zh"?`确定要清理演示数据吗?
1
+ import{r,j as e}from"./vendor-react-Kv_JATwr.js";import{ba as as,ak as fe,P as rs,a9 as $,ao as is,aZ as ns,X as ye,c as K,ap as E,R as A,o as Ie,$ as os,K as ls,T as ie,z as ds,ac as Ee,S as se,e as cs,U as te,by as xs,bw as ae,a3 as ms,cd as hs,af as ps,ab as bs,bq as Re,q as $e,as as us,a$ as gs,bt as fs,b as ys}from"./vendor-icons-CXrZ3R2V.js";import{E as re,b as js}from"./index-BzXADCXZ.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function Ns({lang:a,aiProviders:x,onAIProvidersChanged:s}){const[T,f]=r.useState(!1),[N,y]=r.useState(null),[p,S]=r.useState(""),[v,g]=r.useState(""),[U,P]=r.useState(""),[z,b]=r.useState(""),[L,k]=r.useState(!1),_=()=>{y(null),S(""),g(""),P(""),b(""),f(!0)},D=n=>{y(n),S(n.name),g(n.api_url),P(n.api_key||""),b(n.model_name),f(!0)},M=async n=>{if(n.preventDefault(),!p.trim()||!v.trim()||!z.trim()){alert(a==="zh"?"名称、API URL 和模型名称不可为空":"Name, API URL and Model Name are required.");return}try{k(!0);const m=!!N,u=m?`/api/ai-providers/${N.id}`:"/api/ai-providers",O=await fetch(u,{method:m?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),api_url:v.trim(),api_key:U,model_name:z.trim()})});if(O.ok)f(!1),y(null),s();else{const G=await O.json().catch(()=>({}));alert(G.error||"Server error")}}catch(m){alert(m.message||"Error")}finally{k(!1)}},l=async(n,m)=>{if(confirm(a==="zh"?`确认要删除 AI 提供商 [${m}] 吗?`:`Confirm deleting AI Provider [${m}]?`))try{(await fetch(`/api/ai-providers/${n}`,{method:"DELETE"})).ok?s():alert("Delete failed")}catch(u){alert(u.message||"Error")}},c=async n=>{try{const m=await fetch("/api/ai-providers/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_url:n.api_url,api_key:n.api_key,model_name:n.model_name})});if(m.ok)alert(a==="zh"?`[${n.name}] 连接测试成功!`:`[${n.name}] Connection test successful!`);else{const u=await m.json().catch(()=>({}));alert(a==="zh"?`测试失败: ${u.error||"未知错误"}`:`Test failed: ${u.error||"Unknown error"}`)}}catch(m){alert(a==="zh"?`网络异常: ${m.message}`:`Network error: ${m.message}`)}};return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-1 overflow-y-auto p-6 space-y-6 animate-fade-in text-gray-800",children:e.jsxs("div",{className:"bg-white border border-gray-200 rounded-xl shadow-3xs overflow-hidden",children:[e.jsxs("div",{className:"p-4 sm:p-5 border-b border-gray-100 flex items-center justify-between bg-gray-50/60",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"font-bold text-gray-800 flex items-center gap-2 text-sm sm:text-base",children:[e.jsx(as,{className:"text-indigo-600",size:18}),a==="zh"?"OpenAI 兼容 / 自定义模型 AI 提供商列表":"AI Providers List (OpenAI-Compatible)"]}),e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:a==="zh"?"配置好的端点将可被测验生成器、讲座生成器和 AI Agent 进行热切调用。":"Configured backends accessible by Quiz Generator, Lecture Generator and AI Agent."})]}),e.jsxs("button",{onClick:_,className:"flex items-center gap-1.5 px-3.5 py-1.5 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-lg shadow-sm transition-all text-xs cursor-pointer",children:[e.jsx(fe,{size:14}),a==="zh"?"添加 AI 提供商":"Add AI Provider"]})]}),e.jsx("div",{className:"p-4 sm:p-5",children:x.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-gray-400 text-center",children:[e.jsx(rs,{size:40,className:"mb-3 opacity-30 text-indigo-500"}),e.jsx("span",{className:"font-semibold text-sm",children:a==="zh"?"暂未配置任何 AI 提供商":"No AI Providers Registered"}),e.jsx("p",{className:"text-xs text-gray-400 mt-1 max-w-xs",children:a==="zh"?"点击右上角按钮新建。":"Click the button above to add one."})]}):e.jsx("div",{className:"overflow-x-auto border border-gray-100 rounded-xl",children:e.jsxs("table",{className:"w-full text-left border-collapse min-w-[700px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-slate-50/70 border-b border-gray-100 text-gray-500 font-bold text-xs uppercase tracking-wider",children:[e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"名称":"Name"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"API 端点 URL":"API Endpoint URL"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"模型代号":"Model Identifier"}),e.jsx("th",{className:"py-3.5 px-4",children:a==="zh"?"密钥状态":"API Key"}),e.jsx("th",{className:"py-3.5 px-4 text-center",children:a==="zh"?"操作":"Actions"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-100 text-xs text-gray-700",children:x.map(n=>e.jsxs("tr",{className:"hover:bg-slate-50/50 transition-colors",children:[e.jsx("td",{className:"py-4 px-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-2 h-2 rounded-full bg-indigo-500"}),e.jsx("span",{className:"font-extrabold text-gray-800 text-sm",children:n.name})]})}),e.jsx("td",{className:"py-4 px-4 font-mono text-gray-550 truncate max-w-[220px]",children:n.api_url}),e.jsx("td",{className:"py-4 px-4",children:e.jsx("span",{className:"bg-slate-100 text-slate-800 font-bold px-2 py-1 rounded font-mono text-xs border border-slate-200",children:n.model_name})}),e.jsx("td",{className:"py-4 px-4",children:n.api_key?e.jsxs("span",{className:"text-emerald-600 font-bold flex items-center gap-1 font-mono",children:[e.jsx($,{size:12})," Key Saved"]}):e.jsx("span",{className:"text-amber-500/90 font-mono italic",children:"Not Set"})}),e.jsx("td",{className:"py-4 px-4 text-center",children:e.jsxs("div",{className:"flex items-center justify-center gap-2",children:[e.jsxs("button",{onClick:()=>c(n),className:"px-2.5 py-1 text-xs font-semibold rounded-lg border transition-all cursor-pointer flex items-center gap-1.5 shadow-3xs bg-emerald-50 border-emerald-200 text-emerald-700 hover:bg-emerald-100",title:a==="zh"?"测试连通性":"Test Connection",children:[e.jsx(is,{size:11}),e.jsx("span",{children:a==="zh"?"测试":"Test"})]}),e.jsx("button",{onClick:()=>D(n),className:"px-2.5 py-1 text-indigo-700 hover:bg-indigo-100 border border-indigo-200 rounded-lg bg-indigo-50 cursor-pointer font-semibold transition-all shadow-3xs",title:a==="zh"?"编辑配置":"Edit",children:a==="zh"?"编辑":"Edit"}),e.jsx("button",{onClick:()=>l(n.id,n.name),className:"px-2.5 py-1 text-rose-600 hover:bg-rose-100 border border-rose-200 rounded-lg bg-rose-50 cursor-pointer font-semibold transition-all shadow-3xs",title:a==="zh"?"删除":"Delete",children:a==="zh"?"删除":"Delete"})]})})]},n.id))})]})})})]})}),T&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-xs flex items-center justify-center p-4 z-50 overflow-y-auto",children:e.jsxs("div",{className:"bg-white rounded-2xl shadow-xl border border-gray-200/60 w-full max-w-md overflow-hidden text-gray-800 text-left",children:[e.jsxs("div",{className:"flex items-center justify-between p-5 border-b border-gray-100 bg-slate-50/70",children:[e.jsxs("h3",{className:"font-extrabold text-sm sm:text-base text-gray-800 flex items-center gap-2",children:[e.jsx(ns,{className:"text-indigo-600",size:18}),N?a==="zh"?"编辑 AI 提供商配置":"Edit AI Provider":a==="zh"?"添加全新 AI 提供商":"Add New AI Provider"]}),e.jsx("button",{onClick:()=>{f(!1),y(null)},className:"p-1 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100 transition-colors",children:e.jsx(ye,{size:16})})]}),e.jsxs("form",{onSubmit:M,className:"p-5 space-y-4 text-left",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"服务商名称 *":"Provider Name *"}),e.jsx("input",{type:"text",required:!0,placeholder:"e.g. Deepseek, Minimax",value:p,onChange:n=>S(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-semibold"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"API 端点 URL *":"API Endpoint URL *"}),e.jsx("input",{type:"url",required:!0,placeholder:"https://api.deepseek.com/v1",value:v,onChange:n=>g(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"}),e.jsx("span",{className:"text-xs text-gray-400 mt-1 block",children:a==="zh"?"符合 OpenAI 规范的标准 API 统一基准 URL。":"OpenAI-compatible base URL (e.g. /v1)."})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"模型代号 *":"Model Identifier *"}),e.jsx("input",{type:"text",required:!0,placeholder:"e.g. deepseek-chat",value:z,onChange:n=>b(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5 text-left",children:a==="zh"?"API Key (可选)":"API Key (Optional)"}),e.jsx("input",{type:"password",placeholder:a==="zh"?"不修改请留空":"Leave empty to keep existing",value:U,onChange:n=>P(n.target.value),className:"w-full text-xs sm:text-sm bg-gray-50 hover:bg-gray-100/50 focus:bg-white border border-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all font-mono"})]}),e.jsxs("div",{className:"flex items-center justify-end gap-3 pt-4 border-t border-gray-100",children:[e.jsx("button",{type:"button",onClick:()=>{f(!1),y(null)},className:"px-4 py-2 text-xs font-bold text-gray-500 bg-slate-100 hover:bg-slate-200 rounded-lg cursor-pointer transition-colors",children:a==="zh"?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:L,className:"px-4 py-2 text-xs font-bold text-white bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 rounded-lg shadow-sm transition-all cursor-pointer flex items-center gap-1.5",children:[L?e.jsx(K,{size:13,className:"animate-spin"}):e.jsx($,{size:14}),e.jsx("span",{children:L?a==="zh"?"保存中...":"Saving...":a==="zh"?"保存至数据库":"Save Connection"})]})]})]})]})})]})}const vs=[{key:"lesson",zh:"课程",en:"Lessons"},{key:"class",zh:"班级",en:"Classes"},{key:"student",zh:"学生",en:"Students"},{key:"class_student",zh:"班级关系",en:"Enrollments"},{key:"schedule",zh:"课表",en:"Schedules"},{key:"user",zh:"账号",en:"Accounts"}];function ws({lang:a}){const[x,s]=r.useState(null),[T,f]=r.useState(!1),[N,y]=r.useState(!1),[p,S]=r.useState(!1),[v,g]=r.useState(null),U=async l=>{const c=await l.json().catch(()=>({}));return c&&c.success?c.result:null},P=async l=>{const c=await l.json().catch(()=>({}));return{result:c&&c.success?c.result:null,message:c?.message}},z=r.useCallback(async()=>{try{f(!0);const l=await fetch("/api/demo-data/status");if(l.ok){const c=await U(l);c&&s(c)}}catch(l){console.error("Failed to fetch demo data status",l)}finally{f(!1)}},[]);r.useEffect(()=>{z()},[z]);const b=!!(x&&(x.seeded||x.total>0)),L=async()=>{try{y(!0),g(null);const l=await fetch(`/api/demo-data/seed${b?"?reset=true":""}`,{method:"POST"}),c=await U(l);l.ok&&c?(s(c),g({type:"success",text:a==="zh"?"演示数据已就绪,可用下方演示教师账号登录体验。":"Demo data is ready. Log in with the demo teacher account below."})):g({type:"error",text:a==="zh"?"初始化演示数据失败,请稍后重试。":"Failed to seed demo data, please retry."})}catch(l){g({type:"error",text:a==="zh"?`初始化失败:${l.message||"网络异常"}`:`Seed failed: ${l.message||"Network error"}`})}finally{y(!1)}},k=async()=>{if(confirm(a==="zh"?`确定要清理演示数据吗?
2
2
 
3
3
  只删除演示数据(演示教师、演示课程/班级/学生/课表),系统本身的数据不受影响,管理员账号不会被删除。`:`Purge demo data?
4
4
 
@@ -1 +1 @@
1
- import{r as n,j as e}from"./vendor-react-Kv_JATwr.js";import{a as k,$ as U,E as ae,c as re,a0 as K}from"./index-2676X8YB.js";import{ay as X,R as Y,c as T,o as ie,z as oe,D as de,ae as ce,aZ as xe,ak as V,aq as ne,ce as me,bQ as ue,ac as ee,N as be,U as pe,E as he,an as Z,x as ge,T as fe,f as ye}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";const se="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function je(l){return l==null?"(未作答)":Array.isArray(l)?l.map(i=>String(i)).join(" | "):typeof l=="object"?JSON.stringify(l):String(l)}function ve({assignment:l,lang:i,onBack:c}){const t=i==="zh",[h,f]=n.useState(null),[b,y]=n.useState(null),[x,o]=n.useState(null),[v,u]=n.useState({}),[w,C]=n.useState({}),[A,g]=n.useState(!1),[j,S]=n.useState(null),[$,a]=n.useState(null),[N,P]=n.useState(null),[I,E]=n.useState({}),[L,m]=n.useState(null),[p,M]=n.useState(new Set),F=n.useCallback(async()=>{g(!0),a(null);try{const s=await k.listAttempts(l.id);f(s.items)}catch(s){a(s instanceof U?s.message:String(s?.message??s))}finally{g(!1)}},[l.id]);n.useEffect(()=>{F()},[F]);const _=async s=>{y(s),o(null),a(null),E({}),M(new Set);try{const r=await k.getTeacherView(s);o(r),u(Object.fromEntries(r.items.map(d=>[d.itemId,d.score===null?"":String(d.score)]))),C(Object.fromEntries(r.items.map(d=>[d.itemId,d.feedback??""])))}catch(r){a(r?.message??String(r))}},Q=async s=>{if(x){m(s.itemId),a(null);try{const r=await k.aiSuggestGrade(x.attempt.id,s.itemId);E(d=>({...d,[s.itemId]:r})),M(d=>{const B=new Set(d);return B.delete(s.itemId),B})}catch(r){a(t?"AI 建议不可用:"+(r?.message??String(r)):"AI suggestion unavailable: "+(r?.message??String(r)))}finally{m(null)}}},H=s=>{const r=I[s.itemId];r&&(u(d=>({...d,[s.itemId]:String(r.suggestedScore)})),M(d=>new Set(d).add(s.itemId)))},J=async s=>{if(!x)return;const r=v[s.itemId];if(r===""||r===void 0){a(t?"请填写分数":"Score is required");return}S(s.itemId),a(null);try{await k.gradeAnswer(x.attempt.id,s.itemId,{score:Number(r),feedback:w[s.itemId]||null,acceptedAiSuggestion:p.has(s.itemId),suggestedScore:I[s.itemId]?.suggestedScore});const d=await k.getTeacherView(x.attempt.id);o(d),P(t?"已保存该题评分(自动判分不再覆盖)":"Score saved — auto-grading will not override it."),await F()}catch(d){a(d?.message??String(d))}finally{S(null)}};return e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface text-muted hover:text-main cursor-pointer","aria-label":t?"返回试卷":"Back to assessment",children:e.jsx(X,{size:15})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("h1",{className:"text-sm font-bold text-main truncate",children:[t?"人工批改":"Manual grading"," · ",l.className??l.classId]}),e.jsx("p",{className:"text-2xs text-muted",children:t?"简答题与「无法自动判分」的题在这里给分;保存后该题不再被自动判分覆盖。":"Grade short answers and any item the grader could not score. Saved scores are never auto-overwritten."})]}),e.jsxs("button",{type:"button",onClick:()=>void F(),disabled:A,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:A?"animate-spin":""}),t?"刷新":"Refresh"]})]}),($||N)&&e.jsx("div",{role:$?"alert":"status",className:`mx-5 mt-3 px-3 py-2 rounded-xl border text-xs ${$?"border-rose-200 bg-rose-50 text-rose-700":"border-emerald-200 bg-emerald-50 text-emerald-700"}`,children:$??N}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-5 grid grid-cols-1 lg:grid-cols-[280px_1fr] gap-4",children:[e.jsxs("section",{"aria-labelledby":"attempts-heading",children:[e.jsxs("h2",{id:"attempts-heading",className:"text-xs font-bold text-main mb-2",children:[t?"作答列表":"Attempts","(",h?.length??0,")"]}),h===null&&A?e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),t?"加载中…":"Loading…"]}):(h?.length??0)===0?e.jsx("p",{className:"text-xs text-muted",children:t?"还没有人交卷。":"No submissions yet."}):e.jsx("ul",{"data-testid":"grading-attempt-list",className:"space-y-1.5",children:h.map(s=>{const r=b===s.id,d=Number(s.proctor?.summary?.total??0);return e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>void _(s.id),"aria-pressed":r,className:`w-full text-left px-3 py-2 rounded-xl border text-xs cursor-pointer ${r?"border-indigo-400 bg-indigo-50 dark:bg-indigo-950/40":"border-theme hover:bg-surface-secondary"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsx("span",{className:"font-semibold text-main block truncate",children:s.anonymousLabel??s.studentId??s.id}),d>0&&e.jsxs("span",{className:"px-1.5 py-0.2 rounded text-3xs font-bold bg-rose-100 text-rose-700 dark:bg-rose-950/50 dark:text-rose-300 shrink-0",title:t?`监考异常事件 ${d} 次`:`${d} proctor violations`,children:["⚠️ ",d]})]}),e.jsxs("span",{className:"text-2xs text-muted",children:[s.status," · ",s.score??"—","/",s.maxScore??"—",s.needsManualReview&&e.jsx("span",{className:"ml-1 text-amber-700 dark:text-amber-300",children:t?"待批改":"pending"})]})]})},s.id)})})]}),e.jsxs("section",{"aria-labelledby":"grade-heading",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h2",{id:"grade-heading",className:"text-xs font-bold text-main",children:t?"逐题批改":"Grade items"}),x&&Number(x.attempt.proctor?.summary?.total??0)>0&&e.jsxs("div",{className:"px-2 py-0.5 rounded-lg border border-rose-200 bg-rose-50 text-rose-700 dark:bg-rose-950/40 dark:text-rose-300 dark:border-rose-800 text-2xs font-semibold",children:["⚠️ ",t?"监考异常":"Proctor alert",":",t?"切屏":"tab switch"," ",x.attempt.proctor?.summary?.visibility_hidden??0," · ",t?"失焦":"blur"," ",x.attempt.proctor?.summary?.blur??0," · ",t?"退出全屏":"exit fullscreen"," ",x.attempt.proctor?.summary?.fullscreen_exit??0]})]}),x?e.jsx("ul",{className:"space-y-3",children:x.items.map((s,r)=>e.jsxs("li",{"data-testid":`grading-item-${s.itemId}`,className:"border border-theme rounded-xl p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-2xs font-bold text-muted",children:["#",r+1]}),e.jsx("span",{className:"text-xs font-semibold text-main flex-1 min-w-0 line-clamp-2",children:s.stem}),e.jsxs("span",{className:"text-2xs text-muted",children:[s.score??"—","/",s.maxScore]}),s.manualOverride&&e.jsxs("span",{className:"text-2xs text-indigo-600 inline-flex items-center gap-0.5",children:[e.jsx(ie,{size:11}),t?"已人工批改":"manual"]})]}),e.jsx("p",{className:"text-xs text-main bg-surface-secondary rounded-lg px-2 py-1.5 whitespace-pre-wrap break-words",children:je(s.answer)}),s.needsManualReview&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("button",{type:"button",onClick:()=>void Q(s),disabled:L===s.itemId,className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary disabled:opacity-50 cursor-pointer",children:[L===s.itemId?e.jsx(T,{size:11,className:"animate-spin"}):e.jsx(oe,{size:11}),t?"AI 建议":"AI suggestion"]}),I[s.itemId]&&e.jsxs("div",{className:"text-2xs text-muted bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-900 rounded-lg px-2 py-1.5 space-y-1",children:[e.jsxs("p",{className:"text-main",children:[t?"建议分":"Suggested"," ",I[s.itemId].suggestedScore,"/",s.maxScore,I[s.itemId].confidence!==null&&" · "+(t?"置信度":"confidence")+" "+Math.round(I[s.itemId].confidence*100)+"%",p.has(s.itemId)&&" · "+(t?"已填入,待保存":"applied, pending save")]}),e.jsx("p",{className:"whitespace-pre-wrap break-words",children:I[s.itemId].rationale}),e.jsx("button",{type:"button",onClick:()=>H(s),className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-indigo-600 text-white text-2xs font-bold hover:bg-indigo-700 cursor-pointer",children:t?"采纳并填入分数":"Apply to score"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[100px_1fr_auto] gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:`score-${s.itemId}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"得分":"Score"}),e.jsx("input",{id:`score-${s.itemId}`,type:"number",min:0,max:s.maxScore,step:.5,value:v[s.itemId]??"",onChange:d=>u(B=>({...B,[s.itemId]:d.target.value})),className:se})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:`feedback-${s.itemId}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"评语(可选)":"Feedback (optional)"}),e.jsx("input",{id:`feedback-${s.itemId}`,type:"text",value:w[s.itemId]??"",onChange:d=>C(B=>({...B,[s.itemId]:d.target.value})),className:se})]}),e.jsxs("button",{type:"button",onClick:()=>void J(s),disabled:j===s.itemId,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[j===s.itemId&&e.jsx(T,{size:13,className:"animate-spin"}),t?"保存评分":"Save"]})]})]},s.itemId))}):e.jsx("p",{className:"text-xs text-muted",children:t?"从左侧选择一份作答。":"Pick an attempt on the left."})]})]})]})}function Ne(l){return{id:l.id,kind:l.kind,title:l.title,description:l.description,status:l.status,itemCount:l.itemCount,totalScore:l.totalScore,settings:l.settings,createdAt:l.createdAt,updatedAt:l.updatedAt}}function ke(l){return{attemptCount:l.attemptCount,submittedCount:l.submittedCount,gradedCount:l.gradedCount,needsManualReviewCount:l.needsManualReviewCount,averageScore:l.averageScore,averagePercent:l.averagePercent,maxScore:l.maxScore,items:l.items.map(i=>({itemId:i.itemId,type:i.type,stem:i.stem,maxScore:i.maxScore,answered:i.answered,graded:i.graded,correct:i.correct,correctRate:i.correctRate,avgScore:i.avgScore,distribution:i.distribution}))}}function Se({assignment:l,lang:i,onBack:c}){const t=i==="zh",[h,f]=n.useState(null),[b,y]=n.useState(!1),[x,o]=n.useState(null),v=n.useCallback(async()=>{y(!0),o(null);try{f(await k.stats(l.id))}catch(u){o(u instanceof U?u.message:String(u?.message??u))}finally{y(!1)}},[l.id]);return n.useEffect(()=>{v()},[v]),e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface text-muted hover:text-main cursor-pointer","aria-label":t?"返回试卷":"Back to assessment",children:e.jsx(X,{size:15})}),e.jsx("div",{className:"min-w-0 flex-1",children:e.jsxs("h1",{className:"text-sm font-bold text-main truncate",children:[t?"统计":"Statistics"," · ",l.className??l.classId]})}),e.jsxs("a",{href:k.exportCsvUrl(l.id),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main hover:bg-surface-secondary",children:[e.jsx(de,{size:13}),t?"导出 CSV":"Export CSV"]}),e.jsxs("button",{type:"button",onClick:()=>void v(),disabled:b,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:b?"animate-spin":""}),t?"刷新":"Refresh"]})]}),x&&e.jsx("p",{role:"alert",className:"mx-5 mt-3 px-3 py-2 rounded-xl border border-rose-200 bg-rose-50 text-rose-700 text-xs",children:x}),e.jsx("div",{className:"flex-1 overflow-y-auto p-5 space-y-4",children:h?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[[{label:t?"作答数":"Attempts",value:h.attemptCount},{label:t?"已交卷":"Submitted",value:h.submittedCount},{label:t?"待人工批改":"Pending review",value:h.needsManualReviewCount},{label:t?"平均分":"Average",value:h.averageScore===null?"—":`${h.averageScore}${h.averagePercent!==null?` (${h.averagePercent}%)`:""}`}].map(u=>e.jsxs("div",{className:"border border-theme rounded-xl px-3 py-2 bg-surface-secondary/40",children:[e.jsx("p",{className:"text-2xs text-muted",children:u.label}),e.jsx("p",{className:"text-sm font-bold text-main",children:u.value})]},u.label)),e.jsx(ae,{slot:"assessment.stats.card",slotProps:{assignmentId:l.id,stats:ke(h),lang:i},lang:i})]}),e.jsxs("table",{"data-testid":"stats-table",className:"w-full text-xs border border-theme rounded-xl overflow-hidden",children:[e.jsx("caption",{className:"sr-only",children:t?"逐题统计":"Per-item statistics"}),e.jsx("thead",{className:"bg-surface-secondary text-muted",children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",className:"text-left px-3 py-2 font-semibold",children:"#"}),e.jsx("th",{scope:"col",className:"text-left px-3 py-2 font-semibold",children:t?"题干":"Stem"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"作答":"Answered"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"正确率":"Correct rate"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"均分":"Avg score"})]})}),e.jsx("tbody",{children:h.items.map((u,w)=>e.jsxs("tr",{className:"border-t border-theme",children:[e.jsx("td",{className:"px-3 py-2 text-muted",children:w+1}),e.jsx("td",{className:"px-3 py-2 text-main max-w-[320px] truncate",title:u.stem,children:u.stem}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.answered}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.correctRate===null?"—":`${u.correctRate}%`}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.avgScore===null?"—":`${u.avgScore}/${u.maxScore}`})]},u.itemId))})]}),e.jsx("p",{className:"text-2xs text-muted",children:t?"待人工批改的题不计入正确率与均分;匿名问卷的导出不含身份信息。":"Items awaiting manual review are excluded from correct-rate and averages. Anonymous exports contain no identity."})]}):e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),t?"正在统计…":"Computing…"]})})]})}const q="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function we({assessmentId:l,lang:i,onBack:c}){const t=i==="zh",f=re()?.classes??[],[b,y]=n.useState(null),[x,o]=n.useState([]),[v,u]=n.useState([]),[w,C]=n.useState(!0),[A,g]=n.useState(null),[j,S]=n.useState(null),[$,a]=n.useState(null),[N,P]=n.useState(null),[I,E]=n.useState(null),[L,m]=n.useState(null),p=b?.status==="draft",M=n.useMemo(()=>(K.subscribe(()=>{}),K.list().filter(s=>s.supports.includes(b?.kind??"quiz"))),[b?.kind]),F=n.useCallback(async()=>{C(!0),S(null);try{const s=await k.get(l);y(s),o(s.items.map(d=>({id:d.id,type:d.type,stem:d.stem,config:d.config??{},answerKey:d.answerKey??null,maxScore:d.maxScore})));const r=await k.getAssignments(l).catch(()=>({items:[]}));u(r.items)}catch(s){S(s instanceof U?s.message:String(s?.message??s))}finally{C(!1)}},[l]);n.useEffect(()=>{F()},[F]);const _=async s=>{g("settings"),S(null);try{const r=await k.update(l,{settings:s});y(r),a(t?"设置已保存":"Settings saved")}catch(r){S(r?.message??String(r))}finally{g(null)}},Q=async()=>{g("items"),S(null);try{const s=await k.replaceItems(l,x.map((r,d)=>({id:r.id,type:r.type,stem:r.stem,config:r.config,answerKey:r.answerKey,maxScore:r.maxScore,sortOrder:d})));y(s),o(s.items.map(r=>({id:r.id,type:r.type,stem:r.stem,config:r.config??{},answerKey:r.answerKey??null,maxScore:r.maxScore}))),a(t?"题目已保存":"Items saved")}catch(s){S(s?.message??String(s))}finally{g(null)}},H=s=>{const r=K.get(s);o(d=>[...d,{id:`new-${Date.now()}-${d.length}`,type:s,stem:"",config:r?.createDefaultConfig?.()??{},answerKey:r?.createDefaultAnswerKey?.()??null,maxScore:5}])},J=async()=>{try{const s=await k.listBank();m(s.items)}catch(s){S(s?.message??String(s))}};return w?e.jsxs("div",{className:"flex-1 flex items-center justify-center gap-2 py-16 text-sm text-muted",children:[e.jsx(T,{size:16,className:"animate-spin"}),t?"正在加载试卷…":"Loading assessment…"]}):b?N?e.jsx(ve,{assignment:N,lang:i,onBack:()=>{P(null),F()}}):I?e.jsx(Se,{assignment:I,lang:i,onBack:()=>E(null)}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface hover:bg-surface-secondary text-muted hover:text-main cursor-pointer","aria-label":t?"返回测评列表":"Back to assessment list",children:e.jsx(X,{size:15})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h1",{className:"text-sm font-bold text-main truncate",children:b.title}),e.jsxs("p",{className:"text-2xs text-muted",children:[t?"类型":"Kind",":",b.kind," · ",t?"状态":"Status",":",b.status," · ",x.length," ",t?"题":"items"," · ",t?"满分":"total"," ",x.reduce((s,r)=>s+r.maxScore,0)]})]}),p&&e.jsxs("button",{type:"button",onClick:()=>void Q(),disabled:A!==null,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[A==="items"?e.jsx(T,{size:13,className:"animate-spin"}):e.jsx(ce,{size:13}),t?"保存题目":"Save items"]})]}),(j||$)&&e.jsx("div",{role:j?"alert":"status",className:`mx-5 mt-3 px-3 py-2 rounded-xl border text-xs ${j?"border-rose-200 bg-rose-50 text-rose-700":"border-emerald-200 bg-emerald-50 text-emerald-700"}`,children:j??$}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-5 space-y-5",children:[e.jsxs("section",{"aria-labelledby":"settings-heading",className:"border border-theme rounded-xl p-4",children:[e.jsxs("h2",{id:"settings-heading",className:"text-xs font-bold text-main flex items-center gap-1.5 mb-3",children:[e.jsx(xe,{size:13}),t?"测评设置":"Settings",!p&&e.jsxs("span",{className:"text-2xs font-normal text-muted",children:["(",t?"已发布,只读":"published, read-only",")"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-attempts",className:"block text-2xs font-semibold text-muted mb-1",children:t?"允许作答次数":"Max attempts"}),e.jsx("input",{id:"set-attempts",type:"number",min:1,max:10,value:b.settings.maxAttempts,disabled:!p||b.kind!=="quiz",onChange:s=>void _({maxAttempts:Number(s.target.value)||1}),className:q})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-policy",className:"block text-2xs font-semibold text-muted mb-1",children:t?"多次作答取哪次":"Score policy"}),e.jsxs("select",{id:"set-policy",value:b.settings.scorePolicy,disabled:!p||b.kind!=="quiz",onChange:s=>void _({scorePolicy:s.target.value}),className:q,children:[e.jsx("option",{value:"last",children:t?"最后一次":"Last"}),e.jsx("option",{value:"first",children:t?"第一次":"First"}),e.jsx("option",{value:"highest",children:t?"最高分":"Highest"}),e.jsx("option",{value:"average",children:t?"平均分":"Average"})]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-visibility",className:"block text-2xs font-semibold text-muted mb-1",children:t?"结果可见性":"Result visibility"}),e.jsxs("select",{id:"set-visibility",value:b.settings.resultVisibility,disabled:!p||b.kind==="survey",onChange:s=>void _({resultVisibility:s.target.value}),className:q,children:[e.jsx("option",{value:"immediate",children:t?"交卷即显示":"Immediately"}),e.jsx("option",{value:"after_release",children:t?"教师发布成绩后":"After release"}),e.jsx("option",{value:"score_only",children:t?"只显示分数":"Score only"})]})]})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-4",children:[{key:"singleAttempt",zh:"严格单次作答(禁止重考)",en:"Single attempt only",disabled:!p},{key:"shuffleItems",zh:"题目乱序",en:"Shuffle items",disabled:!p},{key:"shuffleOptions",zh:"选项乱序",en:"Shuffle options",disabled:!p},{key:"strictProctor",zh:"严格监考(切屏/失焦/防复制)",en:"Strict proctoring",disabled:!p},{key:"partialCredit",zh:"多选少选给部分分",en:"Partial credit for multi-choice",disabled:!p},{key:"caseSensitive",zh:"填空题区分大小写",en:"Case-sensitive blanks",disabled:!p},{key:"showItemAnalysis",zh:"允许查看逐题解析",en:"Show item analysis",disabled:!p||b.kind==="survey"},{key:"anonymous",zh:"匿名问卷",en:"Anonymous survey",disabled:!p||b.kind!=="survey"}].map(s=>e.jsxs("label",{className:"inline-flex items-center gap-1.5 text-xs text-main",children:[e.jsx("input",{type:"checkbox",checked:!!b.settings[s.key],disabled:s.disabled||!p,onChange:r=>void _({[s.key]:r.target.checked}),className:"accent-indigo-600"}),s[t?"zh":"en"]]},s.key))})]}),e.jsxs("section",{"aria-labelledby":"items-heading",className:"border border-theme rounded-xl p-4 space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("h2",{id:"items-heading",className:"text-xs font-bold text-main",children:[t?"题目列表":"Items","(",x.length,")"]}),p&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[M.map(s=>e.jsxs("button",{type:"button",onClick:()=>H(s.type),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[e.jsx(V,{size:11}),s.label[t?"zh":"en"]]},s.type)),e.jsxs("button",{type:"button",onClick:()=>void J(),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[e.jsx(ne,{size:11}),t?"从题库添加":"From bank"]})]})]}),x.length===0?e.jsx("p",{className:"text-xs text-muted py-6 text-center",children:t?"还没有题目。用上方按钮添加第一道题。":"No items yet — add your first question above."}):e.jsx("ol",{className:"space-y-3",children:x.map((s,r)=>{const d=K.get(s.type),B=d?.Editor;return e.jsxs("li",{"data-testid":`item-row-${r}`,className:"border border-theme rounded-xl p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-2xs font-bold text-muted",children:["#",r+1]}),e.jsx("span",{className:"px-2 py-0.5 rounded-full bg-surface-secondary border border-theme text-2xs font-semibold text-main",children:d?.label[t?"zh":"en"]??s.type}),e.jsx("label",{htmlFor:`item-score-${s.id}`,className:"ml-auto text-2xs text-muted",children:t?"分值":"Score"}),e.jsx("input",{id:`item-score-${s.id}`,type:"number",min:1,value:s.maxScore,disabled:!p,onChange:D=>o(z=>z.map((R,O)=>O===r?{...R,maxScore:Number(D.target.value)||1}:R)),className:"w-16 px-2 py-1 border border-theme rounded-lg text-xs bg-surface text-main"}),p&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",disabled:r===0,onClick:()=>o(D=>{const z=[...D];return[z[r-1],z[r]]=[z[r],z[r-1]],z}),"aria-label":t?`上移第 ${r+1} 题`:`Move item ${r+1} up`,className:"p-1 rounded-md text-muted hover:text-main hover:bg-surface-secondary disabled:opacity-30 cursor-pointer",children:e.jsx(me,{size:12})}),e.jsx("button",{type:"button",disabled:r===x.length-1,onClick:()=>o(D=>{const z=[...D];return[z[r+1],z[r]]=[z[r],z[r+1]],z}),"aria-label":t?`下移第 ${r+1} 题`:`Move item ${r+1} down`,className:"p-1 rounded-md text-muted hover:text-main hover:bg-surface-secondary disabled:opacity-30 cursor-pointer",children:e.jsx(ue,{size:12})}),e.jsx("button",{type:"button",onClick:()=>o(D=>D.filter((z,R)=>R!==r)),"aria-label":t?`删除第 ${r+1} 题`:`Delete item ${r+1}`,className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer",children:e.jsx(ee,{size:12})})]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:`item-stem-${s.id}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"题干":"Stem"}),e.jsx("textarea",{id:`item-stem-${s.id}`,rows:2,value:s.stem,disabled:!p,onChange:D=>o(z=>z.map((R,O)=>O===r?{...R,stem:D.target.value}:R)),className:`${q} resize-none`})]}),B?e.jsx(B,{config:s.config,answerKey:s.answerKey,lang:i,disabled:!p,onChange:({config:D,answerKey:z})=>o(R=>R.map((O,le)=>le===r?{...O,config:D,answerKey:z}:O))}):e.jsx("p",{className:"text-2xs text-amber-700 dark:text-amber-300",children:t?`题型「${s.type}」没有注册出题编辑器(可能来自未启用/已卸载的插件)。`:`No editor registered for "${s.type}" (plugin missing or disabled).`})]},s.id)})})]}),e.jsx(Ce,{lang:i,detail:b,classes:f,assignments:v,disabled:!p,onPublished:async()=>{await F()},onGrading:P,onStats:E,onError:S})]}),L&&e.jsx(ze,{lang:i,items:L,allowedTypes:M.map(s=>s.type),onClose:()=>m(null),onPick:s=>{o(r=>[...r,{id:`new-${Date.now()}-${r.length}`,type:s.type,stem:s.stem,config:s.config??{},answerKey:s.answerKey??null,maxScore:5}]),m(null)}})]}):e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-3 py-16",children:[e.jsx("p",{role:"alert",className:"text-sm text-rose-600",children:j??(t?"加载失败":"Failed to load")}),e.jsx("button",{type:"button",onClick:c,className:"text-xs font-semibold text-indigo-600 underline cursor-pointer",children:t?"返回列表":"Back to list"})]})}function Ce({lang:l,detail:i,classes:c,assignments:t,disabled:h,onPublished:f,onGrading:b,onStats:y,onError:x}){const o=l==="zh",[v,u]=n.useState(""),[w,C]=n.useState(""),[A,g]=n.useState(""),[j,S]=n.useState(!1),$=async()=>{if(!v){x(o?"请选择班级":"Pick a class first");return}S(!0);try{await k.publish(i.id,{classId:v,durationSec:w?Number(w)*60:null,closesAt:A?new Date(A).getTime():null}),await f()}catch(a){x(a?.message??String(a))}finally{S(!1)}};return e.jsxs("section",{"aria-labelledby":"publish-heading",className:"border border-theme rounded-xl p-4 space-y-3",children:[e.jsxs("h2",{id:"publish-heading",className:"text-xs font-bold text-main flex items-center gap-1.5",children:[e.jsx(be,{size:13}),o?"发布到班级":"Publish to a class"]}),h?e.jsx("p",{className:"text-2xs text-muted",children:o?"试卷已发布,内容只读。需要改题请新建一份试卷。":"Published papers are read-only. Create a new one to change items."}):e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[1.2fr_1fr_1fr_auto] gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-class",className:"block text-2xs font-semibold text-muted mb-1",children:o?"班级":"Class"}),e.jsxs("select",{id:"pub-class",value:v,onChange:a=>u(a.target.value),className:q,children:[e.jsx("option",{value:"",children:o?"请选择班级":"Select a class"}),c.map(a=>e.jsx("option",{value:a.id,children:a.name},a.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-duration",className:"block text-2xs font-semibold text-muted mb-1",children:o?"限时(分钟,可选)":"Time limit (min)"}),e.jsx("input",{id:"pub-duration",type:"number",min:1,value:w,onChange:a=>C(a.target.value),className:q})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-closes",className:"block text-2xs font-semibold text-muted mb-1",children:o?"截止时间(可选)":"Closes at"}),e.jsx("input",{id:"pub-closes",type:"datetime-local",value:A,onChange:a=>g(a.target.value),className:q})]}),e.jsxs("button",{type:"button",onClick:()=>void $(),disabled:j,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-emerald-600 text-white text-xs font-bold hover:bg-emerald-700 disabled:opacity-50 cursor-pointer",children:[j&&e.jsx(T,{size:13,className:"animate-spin"}),o?"发布":"Publish"]})]}),t.length>0&&e.jsx("ul",{"data-testid":"assignment-list",className:"space-y-2 pt-1",children:t.map(a=>e.jsxs("li",{"data-testid":`assignment-row-${a.id}`,className:"flex flex-wrap items-center gap-2 border border-theme rounded-xl px-3 py-2",children:[e.jsx(pe,{size:13,className:"text-muted"}),e.jsx("span",{className:"text-xs font-semibold text-main",children:a.className??a.classId}),e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-semibold border ${a.status==="open"?"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800":"bg-surface-secondary text-muted border-theme"}`,children:a.status==="open"?o?"进行中":"Open":o?"已关闭":"Closed"}),e.jsxs("span",{className:"text-2xs text-muted",children:[o?"已交卷":"Submitted"," ",a.submittedCount,"/",a.attemptCount," ·"," ",o?"待批改":"Pending"," ",a.pendingReviewCount]}),a.scoreReleased&&e.jsx("span",{className:"text-2xs text-indigo-600",children:o?"成绩已发布":"Scores released"}),e.jsxs("span",{className:"ml-auto flex items-center gap-1.5",children:[e.jsxs("a",{href:k.exportCsvUrl(a.id),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary",children:[e.jsx(he,{size:11}),"CSV"]}),e.jsx("button",{type:"button",onClick:()=>y(a),className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"统计":"Stats"}),e.jsx("button",{type:"button",onClick:()=>b(a),className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"批改":"Grade"}),a.scoreReleased?e.jsx("button",{type:"button",onClick:async()=>{try{await k.syncGradebook(a.id),await f()}catch(N){x(N?.message??String(N))}},title:o?"将本场成绩同步至系统成绩单":"Sync scores to gradebook",className:"px-2 py-1 rounded-lg border border-indigo-200 text-indigo-700 bg-indigo-50/50 hover:bg-indigo-100 dark:border-indigo-800 dark:text-indigo-300 dark:bg-indigo-950/40 text-2xs font-semibold cursor-pointer",children:o?"同步成绩单":"Sync Grades"}):e.jsx("button",{type:"button",onClick:async()=>{try{await k.releaseScores(a.id),await f()}catch(N){x(N?.message??String(N))}},title:o?"发布成绩并自动同步至成绩单":"Release scores and sync to gradebook",className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"发布成绩":"Release"}),a.status==="open"&&e.jsx("button",{type:"button",onClick:async()=>{try{await k.closeAssignment(a.id),await f()}catch(N){x(N?.message??String(N))}},className:"px-2 py-1 rounded-lg border border-amber-300 text-2xs font-semibold text-amber-700 hover:bg-amber-50 cursor-pointer",children:o?"关闭":"Close"})]})]},a.id))})]})}function ze({lang:l,items:i,allowedTypes:c,onClose:t,onPick:h}){const f=l==="zh",b=i.filter(y=>c.includes(y.type));return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"bank-picker-title",className:"w-full max-w-lg max-h-[80vh] flex flex-col bg-surface border border-theme rounded-2xl shadow-2xl",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-theme flex items-center justify-between",children:[e.jsx("h2",{id:"bank-picker-title",className:"text-sm font-bold text-main",children:f?"从题库添加":"Add from question bank"}),e.jsx("button",{type:"button",onClick:t,className:"text-xs font-semibold text-muted hover:text-main cursor-pointer",children:f?"关闭":"Close"})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-2",children:b.length===0?e.jsx("p",{className:"text-xs text-muted py-6 text-center",children:f?"题库里还没有可用于本测评类型的题目。":"No bank items usable for this assessment kind."}):b.map(y=>e.jsxs("button",{type:"button",onClick:()=>h(y),className:"w-full text-left border border-theme rounded-xl px-3 py-2 hover:border-indigo-300 hover:bg-surface-secondary cursor-pointer",children:[e.jsx("p",{className:"text-xs font-semibold text-main line-clamp-2",children:y.stem}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:y.type})]},y.id))})]})})}const W="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function Ae({lang:l}){const i=l==="zh",[c,t]=n.useState(null),[h,f]=n.useState(null),[b,y]=n.useState(!1),[x,o]=n.useState("single_choice"),[v,u]=n.useState(""),[w,C]=n.useState({}),[A,g]=n.useState(null),[j,S]=n.useState("private"),[$,a]=n.useState(!1),N=K.list(),I=K.get(x)?.Editor,E=n.useCallback(async()=>{y(!0),f(null);try{const m=await k.listBank();t(m.items)}catch(m){f(m instanceof U?m.message:String(m?.message??m))}finally{y(!1)}},[]);n.useEffect(()=>{E()},[E]),n.useEffect(()=>{const m=K.get(x);C(m?.createDefaultConfig?.()??{}),g(m?.createDefaultAnswerKey?.()??null)},[x]);const L=async m=>{if(m.preventDefault(),!v.trim()){f(i?"题干不能为空":"Stem is required");return}a(!0),f(null);try{await k.createBankItem({type:x,stem:v.trim(),config:w,answerKey:A,visibility:j}),u(""),await E()}catch(p){f(p?.message??String(p))}finally{a(!1)}};return e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-5",children:[e.jsxs("section",{"aria-labelledby":"bank-create-heading",className:"border border-theme rounded-xl p-4 max-w-3xl mx-auto",children:[e.jsxs("h2",{id:"bank-create-heading",className:"text-xs font-bold text-main flex items-center gap-1.5 mb-3",children:[e.jsx(V,{size:13}),i?"新增题库题目":"New bank item"]}),e.jsxs("form",{onSubmit:L,className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-type",className:"block text-2xs font-semibold text-muted mb-1",children:i?"题型":"Type"}),e.jsx("select",{id:"bank-type",value:x,onChange:m=>o(m.target.value),className:W,children:N.map(m=>e.jsx("option",{value:m.type,children:m.label[i?"zh":"en"]},m.type))})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-stem",className:"block text-2xs font-semibold text-muted mb-1",children:i?"题干":"Stem"}),e.jsx("textarea",{id:"bank-stem",rows:2,value:v,onChange:m=>u(m.target.value),className:`${W} resize-none`})]}),I&&e.jsx(I,{config:w,answerKey:A,lang:l,onChange:({config:m,answerKey:p})=>{C(m),g(p)}}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-visibility",className:"block text-2xs font-semibold text-muted mb-1",children:i?"可见范围":"Visibility"}),e.jsxs("select",{id:"bank-visibility",value:j,onChange:m=>S(m.target.value==="school"?"school":"private"),className:W,children:[e.jsx("option",{value:"private",children:i?"仅自己":"Private"}),e.jsx("option",{value:"school",children:i?"同校教师可见":"Teachers on this instance"})]})]}),h&&e.jsx("p",{role:"alert",className:"text-xs text-rose-600",children:h}),e.jsxs("button",{type:"submit",disabled:$,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[$&&e.jsx(T,{size:13,className:"animate-spin"}),i?"存入题库":"Save to bank"]})]})]}),e.jsxs("section",{"aria-labelledby":"bank-list-heading",className:"max-w-3xl mx-auto",children:[e.jsxs("h2",{id:"bank-list-heading",className:"text-xs font-bold text-main mb-2 flex items-center gap-1.5",children:[e.jsx(ne,{size:13}),i?"题库题目":"Bank items","(",c?.length??0,")"]}),c===null&&b?e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),i?"加载中…":"Loading…"]}):(c?.length??0)===0?e.jsx("p",{className:"text-xs text-muted",children:i?"题库还是空的。":"The bank is empty."}):e.jsx("ul",{"data-testid":"bank-list",className:"space-y-2",children:c.map(m=>e.jsxs("li",{"data-testid":`bank-row-${m.id}`,className:"flex items-start gap-2 border border-theme rounded-xl px-3 py-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-xs font-semibold text-main line-clamp-2",children:m.stem}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:K.get(m.type)?.label[i?"zh":"en"]??m.type})]}),e.jsx("button",{type:"button",onClick:async()=>{if(window.confirm(i?"从题库删除该题?":"Delete this bank item?"))try{await k.removeBankItem(m.id),await E()}catch(p){f(p?.message??String(p))}},"aria-label":i?`删除题库题目:${m.stem.slice(0,20)}`:"Delete bank item",className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer shrink-0",children:e.jsx(ee,{size:13})})]},m.id))})]})]})}const G={quiz:{zh:"测试",en:"Quiz",cls:"bg-indigo-50 text-indigo-700 border-indigo-200 dark:bg-indigo-950/40 dark:text-indigo-300 dark:border-indigo-800"},exam:{zh:"考试",en:"Exam",cls:"bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-950/40 dark:text-rose-300 dark:border-rose-800"},survey:{zh:"问卷",en:"Survey",cls:"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800"}},te={draft:{zh:"草稿",en:"Draft",cls:"bg-surface-secondary text-muted border-theme"},published:{zh:"已发布",en:"Published",cls:"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800"},closed:{zh:"已关闭",en:"Closed",cls:"bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-950/40 dark:text-amber-300 dark:border-amber-800"},archived:{zh:"已归档",en:"Archived",cls:"bg-surface-secondary text-muted border-theme"}};function Re(){const i=re()?.lang==="en"?"en":"zh",c=i==="zh",[t,h]=n.useState("papers"),[f,b]=n.useState(null),[y,x]=n.useState(!1),[o,v]=n.useState(null),[u,w]=n.useState(null),[C,A]=n.useState("all"),[g,j]=n.useState(!1),S=n.useCallback(async()=>{x(!0),v(null);try{const a=await k.list(C==="all"?{}:{kind:C});b(a.items)}catch(a){v(a instanceof U?a.message:String(a?.message??a))}finally{x(!1)}},[C]);n.useEffect(()=>{t==="papers"&&u===null&&S()},[t,u,S]);const $=n.useMemo(()=>[...f??[]].sort((N,P)=>P.updatedAt-N.updatedAt),[f]);return u?e.jsx(we,{assessmentId:u,lang:i,onBack:()=>{w(null),S()}}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-6 py-4 border-b border-theme bg-surface-secondary/70 flex flex-col lg:flex-row lg:items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("h1",{className:"text-base font-bold text-main flex items-center gap-2",children:[e.jsx(Z,{size:18,className:"text-indigo-500"}),c?"测评中心":"Assessment Center"]}),e.jsx("p",{className:"text-xs text-muted mt-0.5",children:c?"组卷、发布到班级、批改与统计。测试 / 考试 / 问卷共用同一套题目与判分模型。":"Build papers, publish to classes, grade and analyse. Quizzes, exams and surveys share one item model."})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("div",{className:"inline-flex p-1 bg-surface-secondary border border-theme rounded-xl text-xs font-semibold",children:[{id:"papers",label:c?"试卷":"Papers",icon:Z},{id:"bank",label:c?"题库":"Question bank",icon:ge}].map(a=>{const N=a.icon,P=t===a.id;return e.jsxs("button",{type:"button",onClick:()=>h(a.id),"aria-pressed":P,className:`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg transition-colors cursor-pointer ${P?"bg-surface text-main shadow-3xs font-bold":"text-muted hover:text-main"}`,children:[e.jsx(N,{size:13}),a.label]},a.id)})}),e.jsxs("button",{type:"button",onClick:()=>void S(),disabled:y||t!=="papers",className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface hover:bg-surface-secondary text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:y?"animate-spin":""}),c?"刷新":"Refresh"]}),t==="papers"&&e.jsxs("button",{type:"button",onClick:()=>j(!0),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 cursor-pointer",children:[e.jsx(V,{size:13}),c?"新建测评":"New assessment"]})]})]}),o&&e.jsxs("div",{role:"alert",className:"mx-6 mt-4 px-3 py-2 rounded-xl border border-rose-200 bg-rose-50 text-rose-700 text-xs flex items-center gap-2",children:[e.jsx(fe,{size:14}),o]}),t==="bank"?e.jsx(Ae,{lang:i}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"px-6 py-3 border-b border-theme flex flex-wrap items-center gap-2 shrink-0",children:[e.jsx("span",{className:"text-xs font-semibold text-muted",children:c?"类型筛选":"Filter by kind"}),["all","quiz","exam","survey"].map(a=>e.jsx("button",{type:"button",onClick:()=>A(a),"aria-pressed":C===a,className:`px-2.5 py-1 rounded-full text-xs font-semibold border cursor-pointer ${C===a?"bg-indigo-600 text-white border-indigo-600":"bg-surface text-muted border-theme hover:text-main"}`,children:a==="all"?c?"全部":"All":G[a]?.[c?"zh":"en"]??a},a))]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-6",children:f===null&&y?e.jsxs("div",{className:"flex items-center justify-center gap-2 py-16 text-sm text-muted",children:[e.jsx(T,{size:16,className:"animate-spin"}),c?"正在加载试卷…":"Loading papers…"]}):$.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-3 py-16 text-center",children:[e.jsx(Z,{size:40,className:"text-muted opacity-40"}),e.jsx("p",{className:"text-sm font-semibold text-main",children:c?"还没有任何测评":"No assessments yet"}),e.jsx("p",{className:"text-xs text-muted max-w-sm",children:c?"新建一份测试、考试或问卷,组卷后发布到班级,学生就能在「我的测评」里作答。":"Create a quiz, exam or survey, add questions, then publish it to a class."}),e.jsxs("button",{type:"button",onClick:()=>j(!0),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 cursor-pointer",children:[e.jsx(V,{size:13}),c?"新建测评":"New assessment"]})]}):e.jsx("ul",{"data-testid":"assessment-list",className:"grid grid-cols-1 xl:grid-cols-2 gap-3 max-w-[1400px] mx-auto",children:$.map(a=>{const N=G[a.kind]??G.quiz,P=te[a.status]??te.draft;return e.jsxs("li",{"data-testid":`assessment-row-${a.id}`,className:"bg-surface border border-theme rounded-xl p-4 flex flex-col gap-2.5 hover:border-indigo-300 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-bold text-sm text-main truncate",title:a.title,children:a.title}),a.description&&e.jsx("p",{className:"text-xs text-muted mt-0.5 line-clamp-2",children:a.description})]}),e.jsxs("div",{className:"flex flex-col items-end gap-1 shrink-0",children:[e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-bold border ${N.cls}`,children:N[c?"zh":"en"]}),e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-semibold border ${P.cls}`,children:P[c?"zh":"en"]})]})]}),e.jsxs("div",{className:"flex items-center gap-3 text-2xs text-muted flex-wrap",children:[e.jsxs("span",{children:[a.itemCount," ",c?"题":"items"]}),e.jsxs("span",{children:[c?"满分":"Total"," ",a.totalScore]}),a.settings.anonymous&&e.jsxs("span",{children:["🔒 ",c?"匿名":"Anonymous"]}),a.settings.maxAttempts>1&&e.jsx("span",{children:c?`可作答 ${a.settings.maxAttempts} 次`:`${a.settings.maxAttempts} attempts`}),e.jsxs("span",{className:"ml-auto flex items-center gap-2",children:[a.status==="draft"&&e.jsx("button",{type:"button",onClick:async()=>{if(window.confirm(c?`删除「${a.title}」?`:`Delete "${a.title}"?`))try{await k.remove(a.id),S()}catch(I){v(I?.message??String(I))}},"aria-label":c?`删除 ${a.title}`:`Delete ${a.title}`,className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer",children:e.jsx(ee,{size:13})}),e.jsxs("button",{type:"button",onClick:()=>w(a.id),className:"inline-flex items-center gap-1 px-2.5 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[a.status==="draft"?c?"继续编辑":"Edit":c?"查看与批改":"Open",e.jsx(ye,{size:12})]})]})]}),e.jsx(ae,{slot:"assessment.list.card",slotProps:{assessment:Ne(a),viewer:"teacher",lang:i},lang:i})]},a.id)})})})]}),g&&e.jsx(Ie,{lang:i,onClose:()=>j(!1),onCreated:a=>{j(!1),w(a)}})]})}function Ie({lang:l,onClose:i,onCreated:c}){const t=l==="zh",[h,f]=n.useState("quiz"),[b,y]=n.useState(""),[x,o]=n.useState(""),[v,u]=n.useState(!1),[w,C]=n.useState(null),A=async g=>{if(g.preventDefault(),!b.trim()){C(t?"请填写标题":"Title is required");return}u(!0),C(null);try{const j=await k.create({kind:h,title:b.trim(),description:x.trim()||null});c(j.id)}catch(j){C(j?.message??String(j))}finally{u(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"create-assessment-title",className:"w-full max-w-md bg-surface border border-theme rounded-2xl shadow-2xl p-5 space-y-4",children:[e.jsx("h2",{id:"create-assessment-title",className:"text-sm font-bold text-main",children:t?"新建测评":"New assessment"}),e.jsxs("form",{onSubmit:A,className:"space-y-3",children:[e.jsxs("fieldset",{children:[e.jsx("legend",{className:"text-xs font-semibold text-muted mb-1",children:t?"类型":"Kind"}),e.jsx("div",{className:"grid grid-cols-3 gap-2",children:["quiz","exam","survey"].map(g=>e.jsxs("label",{className:`flex flex-col items-center gap-1 px-2 py-2 rounded-xl border text-xs cursor-pointer ${h===g?"border-indigo-500 bg-indigo-50 text-indigo-700 dark:bg-indigo-950/40 dark:text-indigo-300":"border-theme text-muted hover:text-main"}`,children:[e.jsx("input",{type:"radio",name:"assessment-kind",value:g,checked:h===g,onChange:()=>f(g),className:"sr-only"}),e.jsx("span",{className:"font-bold",children:G[g][t?"zh":"en"]}),e.jsx("span",{className:"text-2xs text-center leading-snug",children:g==="quiz"?t?"计分,可多次作答":"Scored, retakes allowed":g==="exam"?t?"一次作答,发布成绩后可见":"Single attempt, released later":t?"不计分,可匿名":"Not scored, can be anonymous"})]},g))})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"assessment-title",className:"block text-xs font-semibold text-muted mb-1",children:t?"标题":"Title"}),e.jsx("input",{id:"assessment-title",value:b,onChange:g=>y(g.target.value),className:"w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500",placeholder:t?"例如:第三单元小测":"e.g. Unit 3 quiz"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"assessment-description",className:"block text-xs font-semibold text-muted mb-1",children:t?"说明(可选)":"Description (optional)"}),e.jsx("textarea",{id:"assessment-description",value:x,onChange:g=>o(g.target.value),rows:2,className:"w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none"})]}),w&&e.jsx("p",{role:"alert",className:"text-xs text-rose-600",children:w}),e.jsxs("div",{className:"flex justify-end gap-2 pt-1",children:[e.jsx("button",{type:"button",onClick:i,className:"px-3 py-1.5 rounded-xl border border-theme text-xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:t?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:v,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[v&&e.jsx(T,{size:13,className:"animate-spin"}),t?"创建并开始组卷":"Create & build"]})]})]})]})})}export{Re as AssessmentCenter};
1
+ import{r as n,j as e}from"./vendor-react-Kv_JATwr.js";import{a as k,$ as U,E as ae,c as re,a0 as K}from"./index-BzXADCXZ.js";import{ay as X,R as Y,c as T,o as ie,z as oe,D as de,ae as ce,aZ as xe,ak as V,aq as ne,ce as me,bQ as ue,ac as ee,N as be,U as pe,E as he,an as Z,x as ge,T as fe,f as ye}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";const se="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function je(l){return l==null?"(未作答)":Array.isArray(l)?l.map(i=>String(i)).join(" | "):typeof l=="object"?JSON.stringify(l):String(l)}function ve({assignment:l,lang:i,onBack:c}){const t=i==="zh",[h,f]=n.useState(null),[b,y]=n.useState(null),[x,o]=n.useState(null),[v,u]=n.useState({}),[w,C]=n.useState({}),[A,g]=n.useState(!1),[j,S]=n.useState(null),[$,a]=n.useState(null),[N,P]=n.useState(null),[I,E]=n.useState({}),[L,m]=n.useState(null),[p,M]=n.useState(new Set),F=n.useCallback(async()=>{g(!0),a(null);try{const s=await k.listAttempts(l.id);f(s.items)}catch(s){a(s instanceof U?s.message:String(s?.message??s))}finally{g(!1)}},[l.id]);n.useEffect(()=>{F()},[F]);const _=async s=>{y(s),o(null),a(null),E({}),M(new Set);try{const r=await k.getTeacherView(s);o(r),u(Object.fromEntries(r.items.map(d=>[d.itemId,d.score===null?"":String(d.score)]))),C(Object.fromEntries(r.items.map(d=>[d.itemId,d.feedback??""])))}catch(r){a(r?.message??String(r))}},Q=async s=>{if(x){m(s.itemId),a(null);try{const r=await k.aiSuggestGrade(x.attempt.id,s.itemId);E(d=>({...d,[s.itemId]:r})),M(d=>{const B=new Set(d);return B.delete(s.itemId),B})}catch(r){a(t?"AI 建议不可用:"+(r?.message??String(r)):"AI suggestion unavailable: "+(r?.message??String(r)))}finally{m(null)}}},H=s=>{const r=I[s.itemId];r&&(u(d=>({...d,[s.itemId]:String(r.suggestedScore)})),M(d=>new Set(d).add(s.itemId)))},J=async s=>{if(!x)return;const r=v[s.itemId];if(r===""||r===void 0){a(t?"请填写分数":"Score is required");return}S(s.itemId),a(null);try{await k.gradeAnswer(x.attempt.id,s.itemId,{score:Number(r),feedback:w[s.itemId]||null,acceptedAiSuggestion:p.has(s.itemId),suggestedScore:I[s.itemId]?.suggestedScore});const d=await k.getTeacherView(x.attempt.id);o(d),P(t?"已保存该题评分(自动判分不再覆盖)":"Score saved — auto-grading will not override it."),await F()}catch(d){a(d?.message??String(d))}finally{S(null)}};return e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface text-muted hover:text-main cursor-pointer","aria-label":t?"返回试卷":"Back to assessment",children:e.jsx(X,{size:15})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("h1",{className:"text-sm font-bold text-main truncate",children:[t?"人工批改":"Manual grading"," · ",l.className??l.classId]}),e.jsx("p",{className:"text-2xs text-muted",children:t?"简答题与「无法自动判分」的题在这里给分;保存后该题不再被自动判分覆盖。":"Grade short answers and any item the grader could not score. Saved scores are never auto-overwritten."})]}),e.jsxs("button",{type:"button",onClick:()=>void F(),disabled:A,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:A?"animate-spin":""}),t?"刷新":"Refresh"]})]}),($||N)&&e.jsx("div",{role:$?"alert":"status",className:`mx-5 mt-3 px-3 py-2 rounded-xl border text-xs ${$?"border-rose-200 bg-rose-50 text-rose-700":"border-emerald-200 bg-emerald-50 text-emerald-700"}`,children:$??N}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-5 grid grid-cols-1 lg:grid-cols-[280px_1fr] gap-4",children:[e.jsxs("section",{"aria-labelledby":"attempts-heading",children:[e.jsxs("h2",{id:"attempts-heading",className:"text-xs font-bold text-main mb-2",children:[t?"作答列表":"Attempts","(",h?.length??0,")"]}),h===null&&A?e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),t?"加载中…":"Loading…"]}):(h?.length??0)===0?e.jsx("p",{className:"text-xs text-muted",children:t?"还没有人交卷。":"No submissions yet."}):e.jsx("ul",{"data-testid":"grading-attempt-list",className:"space-y-1.5",children:h.map(s=>{const r=b===s.id,d=Number(s.proctor?.summary?.total??0);return e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>void _(s.id),"aria-pressed":r,className:`w-full text-left px-3 py-2 rounded-xl border text-xs cursor-pointer ${r?"border-indigo-400 bg-indigo-50 dark:bg-indigo-950/40":"border-theme hover:bg-surface-secondary"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsx("span",{className:"font-semibold text-main block truncate",children:s.anonymousLabel??s.studentId??s.id}),d>0&&e.jsxs("span",{className:"px-1.5 py-0.2 rounded text-3xs font-bold bg-rose-100 text-rose-700 dark:bg-rose-950/50 dark:text-rose-300 shrink-0",title:t?`监考异常事件 ${d} 次`:`${d} proctor violations`,children:["⚠️ ",d]})]}),e.jsxs("span",{className:"text-2xs text-muted",children:[s.status," · ",s.score??"—","/",s.maxScore??"—",s.needsManualReview&&e.jsx("span",{className:"ml-1 text-amber-700 dark:text-amber-300",children:t?"待批改":"pending"})]})]})},s.id)})})]}),e.jsxs("section",{"aria-labelledby":"grade-heading",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h2",{id:"grade-heading",className:"text-xs font-bold text-main",children:t?"逐题批改":"Grade items"}),x&&Number(x.attempt.proctor?.summary?.total??0)>0&&e.jsxs("div",{className:"px-2 py-0.5 rounded-lg border border-rose-200 bg-rose-50 text-rose-700 dark:bg-rose-950/40 dark:text-rose-300 dark:border-rose-800 text-2xs font-semibold",children:["⚠️ ",t?"监考异常":"Proctor alert",":",t?"切屏":"tab switch"," ",x.attempt.proctor?.summary?.visibility_hidden??0," · ",t?"失焦":"blur"," ",x.attempt.proctor?.summary?.blur??0," · ",t?"退出全屏":"exit fullscreen"," ",x.attempt.proctor?.summary?.fullscreen_exit??0]})]}),x?e.jsx("ul",{className:"space-y-3",children:x.items.map((s,r)=>e.jsxs("li",{"data-testid":`grading-item-${s.itemId}`,className:"border border-theme rounded-xl p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-2xs font-bold text-muted",children:["#",r+1]}),e.jsx("span",{className:"text-xs font-semibold text-main flex-1 min-w-0 line-clamp-2",children:s.stem}),e.jsxs("span",{className:"text-2xs text-muted",children:[s.score??"—","/",s.maxScore]}),s.manualOverride&&e.jsxs("span",{className:"text-2xs text-indigo-600 inline-flex items-center gap-0.5",children:[e.jsx(ie,{size:11}),t?"已人工批改":"manual"]})]}),e.jsx("p",{className:"text-xs text-main bg-surface-secondary rounded-lg px-2 py-1.5 whitespace-pre-wrap break-words",children:je(s.answer)}),s.needsManualReview&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("button",{type:"button",onClick:()=>void Q(s),disabled:L===s.itemId,className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary disabled:opacity-50 cursor-pointer",children:[L===s.itemId?e.jsx(T,{size:11,className:"animate-spin"}):e.jsx(oe,{size:11}),t?"AI 建议":"AI suggestion"]}),I[s.itemId]&&e.jsxs("div",{className:"text-2xs text-muted bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-900 rounded-lg px-2 py-1.5 space-y-1",children:[e.jsxs("p",{className:"text-main",children:[t?"建议分":"Suggested"," ",I[s.itemId].suggestedScore,"/",s.maxScore,I[s.itemId].confidence!==null&&" · "+(t?"置信度":"confidence")+" "+Math.round(I[s.itemId].confidence*100)+"%",p.has(s.itemId)&&" · "+(t?"已填入,待保存":"applied, pending save")]}),e.jsx("p",{className:"whitespace-pre-wrap break-words",children:I[s.itemId].rationale}),e.jsx("button",{type:"button",onClick:()=>H(s),className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-indigo-600 text-white text-2xs font-bold hover:bg-indigo-700 cursor-pointer",children:t?"采纳并填入分数":"Apply to score"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[100px_1fr_auto] gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:`score-${s.itemId}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"得分":"Score"}),e.jsx("input",{id:`score-${s.itemId}`,type:"number",min:0,max:s.maxScore,step:.5,value:v[s.itemId]??"",onChange:d=>u(B=>({...B,[s.itemId]:d.target.value})),className:se})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:`feedback-${s.itemId}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"评语(可选)":"Feedback (optional)"}),e.jsx("input",{id:`feedback-${s.itemId}`,type:"text",value:w[s.itemId]??"",onChange:d=>C(B=>({...B,[s.itemId]:d.target.value})),className:se})]}),e.jsxs("button",{type:"button",onClick:()=>void J(s),disabled:j===s.itemId,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[j===s.itemId&&e.jsx(T,{size:13,className:"animate-spin"}),t?"保存评分":"Save"]})]})]},s.itemId))}):e.jsx("p",{className:"text-xs text-muted",children:t?"从左侧选择一份作答。":"Pick an attempt on the left."})]})]})]})}function Ne(l){return{id:l.id,kind:l.kind,title:l.title,description:l.description,status:l.status,itemCount:l.itemCount,totalScore:l.totalScore,settings:l.settings,createdAt:l.createdAt,updatedAt:l.updatedAt}}function ke(l){return{attemptCount:l.attemptCount,submittedCount:l.submittedCount,gradedCount:l.gradedCount,needsManualReviewCount:l.needsManualReviewCount,averageScore:l.averageScore,averagePercent:l.averagePercent,maxScore:l.maxScore,items:l.items.map(i=>({itemId:i.itemId,type:i.type,stem:i.stem,maxScore:i.maxScore,answered:i.answered,graded:i.graded,correct:i.correct,correctRate:i.correctRate,avgScore:i.avgScore,distribution:i.distribution}))}}function Se({assignment:l,lang:i,onBack:c}){const t=i==="zh",[h,f]=n.useState(null),[b,y]=n.useState(!1),[x,o]=n.useState(null),v=n.useCallback(async()=>{y(!0),o(null);try{f(await k.stats(l.id))}catch(u){o(u instanceof U?u.message:String(u?.message??u))}finally{y(!1)}},[l.id]);return n.useEffect(()=>{v()},[v]),e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface text-muted hover:text-main cursor-pointer","aria-label":t?"返回试卷":"Back to assessment",children:e.jsx(X,{size:15})}),e.jsx("div",{className:"min-w-0 flex-1",children:e.jsxs("h1",{className:"text-sm font-bold text-main truncate",children:[t?"统计":"Statistics"," · ",l.className??l.classId]})}),e.jsxs("a",{href:k.exportCsvUrl(l.id),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main hover:bg-surface-secondary",children:[e.jsx(de,{size:13}),t?"导出 CSV":"Export CSV"]}),e.jsxs("button",{type:"button",onClick:()=>void v(),disabled:b,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:b?"animate-spin":""}),t?"刷新":"Refresh"]})]}),x&&e.jsx("p",{role:"alert",className:"mx-5 mt-3 px-3 py-2 rounded-xl border border-rose-200 bg-rose-50 text-rose-700 text-xs",children:x}),e.jsx("div",{className:"flex-1 overflow-y-auto p-5 space-y-4",children:h?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[[{label:t?"作答数":"Attempts",value:h.attemptCount},{label:t?"已交卷":"Submitted",value:h.submittedCount},{label:t?"待人工批改":"Pending review",value:h.needsManualReviewCount},{label:t?"平均分":"Average",value:h.averageScore===null?"—":`${h.averageScore}${h.averagePercent!==null?` (${h.averagePercent}%)`:""}`}].map(u=>e.jsxs("div",{className:"border border-theme rounded-xl px-3 py-2 bg-surface-secondary/40",children:[e.jsx("p",{className:"text-2xs text-muted",children:u.label}),e.jsx("p",{className:"text-sm font-bold text-main",children:u.value})]},u.label)),e.jsx(ae,{slot:"assessment.stats.card",slotProps:{assignmentId:l.id,stats:ke(h),lang:i},lang:i})]}),e.jsxs("table",{"data-testid":"stats-table",className:"w-full text-xs border border-theme rounded-xl overflow-hidden",children:[e.jsx("caption",{className:"sr-only",children:t?"逐题统计":"Per-item statistics"}),e.jsx("thead",{className:"bg-surface-secondary text-muted",children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",className:"text-left px-3 py-2 font-semibold",children:"#"}),e.jsx("th",{scope:"col",className:"text-left px-3 py-2 font-semibold",children:t?"题干":"Stem"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"作答":"Answered"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"正确率":"Correct rate"}),e.jsx("th",{scope:"col",className:"text-right px-3 py-2 font-semibold",children:t?"均分":"Avg score"})]})}),e.jsx("tbody",{children:h.items.map((u,w)=>e.jsxs("tr",{className:"border-t border-theme",children:[e.jsx("td",{className:"px-3 py-2 text-muted",children:w+1}),e.jsx("td",{className:"px-3 py-2 text-main max-w-[320px] truncate",title:u.stem,children:u.stem}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.answered}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.correctRate===null?"—":`${u.correctRate}%`}),e.jsx("td",{className:"px-3 py-2 text-right text-main",children:u.avgScore===null?"—":`${u.avgScore}/${u.maxScore}`})]},u.itemId))})]}),e.jsx("p",{className:"text-2xs text-muted",children:t?"待人工批改的题不计入正确率与均分;匿名问卷的导出不含身份信息。":"Items awaiting manual review are excluded from correct-rate and averages. Anonymous exports contain no identity."})]}):e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),t?"正在统计…":"Computing…"]})})]})}const q="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function we({assessmentId:l,lang:i,onBack:c}){const t=i==="zh",f=re()?.classes??[],[b,y]=n.useState(null),[x,o]=n.useState([]),[v,u]=n.useState([]),[w,C]=n.useState(!0),[A,g]=n.useState(null),[j,S]=n.useState(null),[$,a]=n.useState(null),[N,P]=n.useState(null),[I,E]=n.useState(null),[L,m]=n.useState(null),p=b?.status==="draft",M=n.useMemo(()=>(K.subscribe(()=>{}),K.list().filter(s=>s.supports.includes(b?.kind??"quiz"))),[b?.kind]),F=n.useCallback(async()=>{C(!0),S(null);try{const s=await k.get(l);y(s),o(s.items.map(d=>({id:d.id,type:d.type,stem:d.stem,config:d.config??{},answerKey:d.answerKey??null,maxScore:d.maxScore})));const r=await k.getAssignments(l).catch(()=>({items:[]}));u(r.items)}catch(s){S(s instanceof U?s.message:String(s?.message??s))}finally{C(!1)}},[l]);n.useEffect(()=>{F()},[F]);const _=async s=>{g("settings"),S(null);try{const r=await k.update(l,{settings:s});y(r),a(t?"设置已保存":"Settings saved")}catch(r){S(r?.message??String(r))}finally{g(null)}},Q=async()=>{g("items"),S(null);try{const s=await k.replaceItems(l,x.map((r,d)=>({id:r.id,type:r.type,stem:r.stem,config:r.config,answerKey:r.answerKey,maxScore:r.maxScore,sortOrder:d})));y(s),o(s.items.map(r=>({id:r.id,type:r.type,stem:r.stem,config:r.config??{},answerKey:r.answerKey??null,maxScore:r.maxScore}))),a(t?"题目已保存":"Items saved")}catch(s){S(s?.message??String(s))}finally{g(null)}},H=s=>{const r=K.get(s);o(d=>[...d,{id:`new-${Date.now()}-${d.length}`,type:s,stem:"",config:r?.createDefaultConfig?.()??{},answerKey:r?.createDefaultAnswerKey?.()??null,maxScore:5}])},J=async()=>{try{const s=await k.listBank();m(s.items)}catch(s){S(s?.message??String(s))}};return w?e.jsxs("div",{className:"flex-1 flex items-center justify-center gap-2 py-16 text-sm text-muted",children:[e.jsx(T,{size:16,className:"animate-spin"}),t?"正在加载试卷…":"Loading assessment…"]}):b?N?e.jsx(ve,{assignment:N,lang:i,onBack:()=>{P(null),F()}}):I?e.jsx(Se,{assignment:I,lang:i,onBack:()=>E(null)}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-3 border-b border-theme bg-surface-secondary/70 flex flex-wrap items-center gap-3 shrink-0",children:[e.jsx("button",{type:"button",onClick:c,className:"p-1.5 rounded-lg border border-theme bg-surface hover:bg-surface-secondary text-muted hover:text-main cursor-pointer","aria-label":t?"返回测评列表":"Back to assessment list",children:e.jsx(X,{size:15})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h1",{className:"text-sm font-bold text-main truncate",children:b.title}),e.jsxs("p",{className:"text-2xs text-muted",children:[t?"类型":"Kind",":",b.kind," · ",t?"状态":"Status",":",b.status," · ",x.length," ",t?"题":"items"," · ",t?"满分":"total"," ",x.reduce((s,r)=>s+r.maxScore,0)]})]}),p&&e.jsxs("button",{type:"button",onClick:()=>void Q(),disabled:A!==null,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[A==="items"?e.jsx(T,{size:13,className:"animate-spin"}):e.jsx(ce,{size:13}),t?"保存题目":"Save items"]})]}),(j||$)&&e.jsx("div",{role:j?"alert":"status",className:`mx-5 mt-3 px-3 py-2 rounded-xl border text-xs ${j?"border-rose-200 bg-rose-50 text-rose-700":"border-emerald-200 bg-emerald-50 text-emerald-700"}`,children:j??$}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-5 space-y-5",children:[e.jsxs("section",{"aria-labelledby":"settings-heading",className:"border border-theme rounded-xl p-4",children:[e.jsxs("h2",{id:"settings-heading",className:"text-xs font-bold text-main flex items-center gap-1.5 mb-3",children:[e.jsx(xe,{size:13}),t?"测评设置":"Settings",!p&&e.jsxs("span",{className:"text-2xs font-normal text-muted",children:["(",t?"已发布,只读":"published, read-only",")"]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-attempts",className:"block text-2xs font-semibold text-muted mb-1",children:t?"允许作答次数":"Max attempts"}),e.jsx("input",{id:"set-attempts",type:"number",min:1,max:10,value:b.settings.maxAttempts,disabled:!p||b.kind!=="quiz",onChange:s=>void _({maxAttempts:Number(s.target.value)||1}),className:q})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-policy",className:"block text-2xs font-semibold text-muted mb-1",children:t?"多次作答取哪次":"Score policy"}),e.jsxs("select",{id:"set-policy",value:b.settings.scorePolicy,disabled:!p||b.kind!=="quiz",onChange:s=>void _({scorePolicy:s.target.value}),className:q,children:[e.jsx("option",{value:"last",children:t?"最后一次":"Last"}),e.jsx("option",{value:"first",children:t?"第一次":"First"}),e.jsx("option",{value:"highest",children:t?"最高分":"Highest"}),e.jsx("option",{value:"average",children:t?"平均分":"Average"})]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"set-visibility",className:"block text-2xs font-semibold text-muted mb-1",children:t?"结果可见性":"Result visibility"}),e.jsxs("select",{id:"set-visibility",value:b.settings.resultVisibility,disabled:!p||b.kind==="survey",onChange:s=>void _({resultVisibility:s.target.value}),className:q,children:[e.jsx("option",{value:"immediate",children:t?"交卷即显示":"Immediately"}),e.jsx("option",{value:"after_release",children:t?"教师发布成绩后":"After release"}),e.jsx("option",{value:"score_only",children:t?"只显示分数":"Score only"})]})]})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-4",children:[{key:"singleAttempt",zh:"严格单次作答(禁止重考)",en:"Single attempt only",disabled:!p},{key:"shuffleItems",zh:"题目乱序",en:"Shuffle items",disabled:!p},{key:"shuffleOptions",zh:"选项乱序",en:"Shuffle options",disabled:!p},{key:"strictProctor",zh:"严格监考(切屏/失焦/防复制)",en:"Strict proctoring",disabled:!p},{key:"partialCredit",zh:"多选少选给部分分",en:"Partial credit for multi-choice",disabled:!p},{key:"caseSensitive",zh:"填空题区分大小写",en:"Case-sensitive blanks",disabled:!p},{key:"showItemAnalysis",zh:"允许查看逐题解析",en:"Show item analysis",disabled:!p||b.kind==="survey"},{key:"anonymous",zh:"匿名问卷",en:"Anonymous survey",disabled:!p||b.kind!=="survey"}].map(s=>e.jsxs("label",{className:"inline-flex items-center gap-1.5 text-xs text-main",children:[e.jsx("input",{type:"checkbox",checked:!!b.settings[s.key],disabled:s.disabled||!p,onChange:r=>void _({[s.key]:r.target.checked}),className:"accent-indigo-600"}),s[t?"zh":"en"]]},s.key))})]}),e.jsxs("section",{"aria-labelledby":"items-heading",className:"border border-theme rounded-xl p-4 space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("h2",{id:"items-heading",className:"text-xs font-bold text-main",children:[t?"题目列表":"Items","(",x.length,")"]}),p&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[M.map(s=>e.jsxs("button",{type:"button",onClick:()=>H(s.type),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[e.jsx(V,{size:11}),s.label[t?"zh":"en"]]},s.type)),e.jsxs("button",{type:"button",onClick:()=>void J(),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[e.jsx(ne,{size:11}),t?"从题库添加":"From bank"]})]})]}),x.length===0?e.jsx("p",{className:"text-xs text-muted py-6 text-center",children:t?"还没有题目。用上方按钮添加第一道题。":"No items yet — add your first question above."}):e.jsx("ol",{className:"space-y-3",children:x.map((s,r)=>{const d=K.get(s.type),B=d?.Editor;return e.jsxs("li",{"data-testid":`item-row-${r}`,className:"border border-theme rounded-xl p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-2xs font-bold text-muted",children:["#",r+1]}),e.jsx("span",{className:"px-2 py-0.5 rounded-full bg-surface-secondary border border-theme text-2xs font-semibold text-main",children:d?.label[t?"zh":"en"]??s.type}),e.jsx("label",{htmlFor:`item-score-${s.id}`,className:"ml-auto text-2xs text-muted",children:t?"分值":"Score"}),e.jsx("input",{id:`item-score-${s.id}`,type:"number",min:1,value:s.maxScore,disabled:!p,onChange:D=>o(z=>z.map((R,O)=>O===r?{...R,maxScore:Number(D.target.value)||1}:R)),className:"w-16 px-2 py-1 border border-theme rounded-lg text-xs bg-surface text-main"}),p&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",disabled:r===0,onClick:()=>o(D=>{const z=[...D];return[z[r-1],z[r]]=[z[r],z[r-1]],z}),"aria-label":t?`上移第 ${r+1} 题`:`Move item ${r+1} up`,className:"p-1 rounded-md text-muted hover:text-main hover:bg-surface-secondary disabled:opacity-30 cursor-pointer",children:e.jsx(me,{size:12})}),e.jsx("button",{type:"button",disabled:r===x.length-1,onClick:()=>o(D=>{const z=[...D];return[z[r+1],z[r]]=[z[r],z[r+1]],z}),"aria-label":t?`下移第 ${r+1} 题`:`Move item ${r+1} down`,className:"p-1 rounded-md text-muted hover:text-main hover:bg-surface-secondary disabled:opacity-30 cursor-pointer",children:e.jsx(ue,{size:12})}),e.jsx("button",{type:"button",onClick:()=>o(D=>D.filter((z,R)=>R!==r)),"aria-label":t?`删除第 ${r+1} 题`:`Delete item ${r+1}`,className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer",children:e.jsx(ee,{size:12})})]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:`item-stem-${s.id}`,className:"block text-2xs font-semibold text-muted mb-1",children:t?"题干":"Stem"}),e.jsx("textarea",{id:`item-stem-${s.id}`,rows:2,value:s.stem,disabled:!p,onChange:D=>o(z=>z.map((R,O)=>O===r?{...R,stem:D.target.value}:R)),className:`${q} resize-none`})]}),B?e.jsx(B,{config:s.config,answerKey:s.answerKey,lang:i,disabled:!p,onChange:({config:D,answerKey:z})=>o(R=>R.map((O,le)=>le===r?{...O,config:D,answerKey:z}:O))}):e.jsx("p",{className:"text-2xs text-amber-700 dark:text-amber-300",children:t?`题型「${s.type}」没有注册出题编辑器(可能来自未启用/已卸载的插件)。`:`No editor registered for "${s.type}" (plugin missing or disabled).`})]},s.id)})})]}),e.jsx(Ce,{lang:i,detail:b,classes:f,assignments:v,disabled:!p,onPublished:async()=>{await F()},onGrading:P,onStats:E,onError:S})]}),L&&e.jsx(ze,{lang:i,items:L,allowedTypes:M.map(s=>s.type),onClose:()=>m(null),onPick:s=>{o(r=>[...r,{id:`new-${Date.now()}-${r.length}`,type:s.type,stem:s.stem,config:s.config??{},answerKey:s.answerKey??null,maxScore:5}]),m(null)}})]}):e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-3 py-16",children:[e.jsx("p",{role:"alert",className:"text-sm text-rose-600",children:j??(t?"加载失败":"Failed to load")}),e.jsx("button",{type:"button",onClick:c,className:"text-xs font-semibold text-indigo-600 underline cursor-pointer",children:t?"返回列表":"Back to list"})]})}function Ce({lang:l,detail:i,classes:c,assignments:t,disabled:h,onPublished:f,onGrading:b,onStats:y,onError:x}){const o=l==="zh",[v,u]=n.useState(""),[w,C]=n.useState(""),[A,g]=n.useState(""),[j,S]=n.useState(!1),$=async()=>{if(!v){x(o?"请选择班级":"Pick a class first");return}S(!0);try{await k.publish(i.id,{classId:v,durationSec:w?Number(w)*60:null,closesAt:A?new Date(A).getTime():null}),await f()}catch(a){x(a?.message??String(a))}finally{S(!1)}};return e.jsxs("section",{"aria-labelledby":"publish-heading",className:"border border-theme rounded-xl p-4 space-y-3",children:[e.jsxs("h2",{id:"publish-heading",className:"text-xs font-bold text-main flex items-center gap-1.5",children:[e.jsx(be,{size:13}),o?"发布到班级":"Publish to a class"]}),h?e.jsx("p",{className:"text-2xs text-muted",children:o?"试卷已发布,内容只读。需要改题请新建一份试卷。":"Published papers are read-only. Create a new one to change items."}):e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[1.2fr_1fr_1fr_auto] gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-class",className:"block text-2xs font-semibold text-muted mb-1",children:o?"班级":"Class"}),e.jsxs("select",{id:"pub-class",value:v,onChange:a=>u(a.target.value),className:q,children:[e.jsx("option",{value:"",children:o?"请选择班级":"Select a class"}),c.map(a=>e.jsx("option",{value:a.id,children:a.name},a.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-duration",className:"block text-2xs font-semibold text-muted mb-1",children:o?"限时(分钟,可选)":"Time limit (min)"}),e.jsx("input",{id:"pub-duration",type:"number",min:1,value:w,onChange:a=>C(a.target.value),className:q})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"pub-closes",className:"block text-2xs font-semibold text-muted mb-1",children:o?"截止时间(可选)":"Closes at"}),e.jsx("input",{id:"pub-closes",type:"datetime-local",value:A,onChange:a=>g(a.target.value),className:q})]}),e.jsxs("button",{type:"button",onClick:()=>void $(),disabled:j,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-emerald-600 text-white text-xs font-bold hover:bg-emerald-700 disabled:opacity-50 cursor-pointer",children:[j&&e.jsx(T,{size:13,className:"animate-spin"}),o?"发布":"Publish"]})]}),t.length>0&&e.jsx("ul",{"data-testid":"assignment-list",className:"space-y-2 pt-1",children:t.map(a=>e.jsxs("li",{"data-testid":`assignment-row-${a.id}`,className:"flex flex-wrap items-center gap-2 border border-theme rounded-xl px-3 py-2",children:[e.jsx(pe,{size:13,className:"text-muted"}),e.jsx("span",{className:"text-xs font-semibold text-main",children:a.className??a.classId}),e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-semibold border ${a.status==="open"?"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800":"bg-surface-secondary text-muted border-theme"}`,children:a.status==="open"?o?"进行中":"Open":o?"已关闭":"Closed"}),e.jsxs("span",{className:"text-2xs text-muted",children:[o?"已交卷":"Submitted"," ",a.submittedCount,"/",a.attemptCount," ·"," ",o?"待批改":"Pending"," ",a.pendingReviewCount]}),a.scoreReleased&&e.jsx("span",{className:"text-2xs text-indigo-600",children:o?"成绩已发布":"Scores released"}),e.jsxs("span",{className:"ml-auto flex items-center gap-1.5",children:[e.jsxs("a",{href:k.exportCsvUrl(a.id),className:"inline-flex items-center gap-1 px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary",children:[e.jsx(he,{size:11}),"CSV"]}),e.jsx("button",{type:"button",onClick:()=>y(a),className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"统计":"Stats"}),e.jsx("button",{type:"button",onClick:()=>b(a),className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"批改":"Grade"}),a.scoreReleased?e.jsx("button",{type:"button",onClick:async()=>{try{await k.syncGradebook(a.id),await f()}catch(N){x(N?.message??String(N))}},title:o?"将本场成绩同步至系统成绩单":"Sync scores to gradebook",className:"px-2 py-1 rounded-lg border border-indigo-200 text-indigo-700 bg-indigo-50/50 hover:bg-indigo-100 dark:border-indigo-800 dark:text-indigo-300 dark:bg-indigo-950/40 text-2xs font-semibold cursor-pointer",children:o?"同步成绩单":"Sync Grades"}):e.jsx("button",{type:"button",onClick:async()=>{try{await k.releaseScores(a.id),await f()}catch(N){x(N?.message??String(N))}},title:o?"发布成绩并自动同步至成绩单":"Release scores and sync to gradebook",className:"px-2 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:o?"发布成绩":"Release"}),a.status==="open"&&e.jsx("button",{type:"button",onClick:async()=>{try{await k.closeAssignment(a.id),await f()}catch(N){x(N?.message??String(N))}},className:"px-2 py-1 rounded-lg border border-amber-300 text-2xs font-semibold text-amber-700 hover:bg-amber-50 cursor-pointer",children:o?"关闭":"Close"})]})]},a.id))})]})}function ze({lang:l,items:i,allowedTypes:c,onClose:t,onPick:h}){const f=l==="zh",b=i.filter(y=>c.includes(y.type));return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"bank-picker-title",className:"w-full max-w-lg max-h-[80vh] flex flex-col bg-surface border border-theme rounded-2xl shadow-2xl",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-theme flex items-center justify-between",children:[e.jsx("h2",{id:"bank-picker-title",className:"text-sm font-bold text-main",children:f?"从题库添加":"Add from question bank"}),e.jsx("button",{type:"button",onClick:t,className:"text-xs font-semibold text-muted hover:text-main cursor-pointer",children:f?"关闭":"Close"})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-2",children:b.length===0?e.jsx("p",{className:"text-xs text-muted py-6 text-center",children:f?"题库里还没有可用于本测评类型的题目。":"No bank items usable for this assessment kind."}):b.map(y=>e.jsxs("button",{type:"button",onClick:()=>h(y),className:"w-full text-left border border-theme rounded-xl px-3 py-2 hover:border-indigo-300 hover:bg-surface-secondary cursor-pointer",children:[e.jsx("p",{className:"text-xs font-semibold text-main line-clamp-2",children:y.stem}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:y.type})]},y.id))})]})})}const W="w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500";function Ae({lang:l}){const i=l==="zh",[c,t]=n.useState(null),[h,f]=n.useState(null),[b,y]=n.useState(!1),[x,o]=n.useState("single_choice"),[v,u]=n.useState(""),[w,C]=n.useState({}),[A,g]=n.useState(null),[j,S]=n.useState("private"),[$,a]=n.useState(!1),N=K.list(),I=K.get(x)?.Editor,E=n.useCallback(async()=>{y(!0),f(null);try{const m=await k.listBank();t(m.items)}catch(m){f(m instanceof U?m.message:String(m?.message??m))}finally{y(!1)}},[]);n.useEffect(()=>{E()},[E]),n.useEffect(()=>{const m=K.get(x);C(m?.createDefaultConfig?.()??{}),g(m?.createDefaultAnswerKey?.()??null)},[x]);const L=async m=>{if(m.preventDefault(),!v.trim()){f(i?"题干不能为空":"Stem is required");return}a(!0),f(null);try{await k.createBankItem({type:x,stem:v.trim(),config:w,answerKey:A,visibility:j}),u(""),await E()}catch(p){f(p?.message??String(p))}finally{a(!1)}};return e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-5",children:[e.jsxs("section",{"aria-labelledby":"bank-create-heading",className:"border border-theme rounded-xl p-4 max-w-3xl mx-auto",children:[e.jsxs("h2",{id:"bank-create-heading",className:"text-xs font-bold text-main flex items-center gap-1.5 mb-3",children:[e.jsx(V,{size:13}),i?"新增题库题目":"New bank item"]}),e.jsxs("form",{onSubmit:L,className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-type",className:"block text-2xs font-semibold text-muted mb-1",children:i?"题型":"Type"}),e.jsx("select",{id:"bank-type",value:x,onChange:m=>o(m.target.value),className:W,children:N.map(m=>e.jsx("option",{value:m.type,children:m.label[i?"zh":"en"]},m.type))})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-stem",className:"block text-2xs font-semibold text-muted mb-1",children:i?"题干":"Stem"}),e.jsx("textarea",{id:"bank-stem",rows:2,value:v,onChange:m=>u(m.target.value),className:`${W} resize-none`})]}),I&&e.jsx(I,{config:w,answerKey:A,lang:l,onChange:({config:m,answerKey:p})=>{C(m),g(p)}}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"bank-visibility",className:"block text-2xs font-semibold text-muted mb-1",children:i?"可见范围":"Visibility"}),e.jsxs("select",{id:"bank-visibility",value:j,onChange:m=>S(m.target.value==="school"?"school":"private"),className:W,children:[e.jsx("option",{value:"private",children:i?"仅自己":"Private"}),e.jsx("option",{value:"school",children:i?"同校教师可见":"Teachers on this instance"})]})]}),h&&e.jsx("p",{role:"alert",className:"text-xs text-rose-600",children:h}),e.jsxs("button",{type:"submit",disabled:$,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[$&&e.jsx(T,{size:13,className:"animate-spin"}),i?"存入题库":"Save to bank"]})]})]}),e.jsxs("section",{"aria-labelledby":"bank-list-heading",className:"max-w-3xl mx-auto",children:[e.jsxs("h2",{id:"bank-list-heading",className:"text-xs font-bold text-main mb-2 flex items-center gap-1.5",children:[e.jsx(ne,{size:13}),i?"题库题目":"Bank items","(",c?.length??0,")"]}),c===null&&b?e.jsxs("p",{className:"text-xs text-muted flex items-center gap-2",children:[e.jsx(T,{size:13,className:"animate-spin"}),i?"加载中…":"Loading…"]}):(c?.length??0)===0?e.jsx("p",{className:"text-xs text-muted",children:i?"题库还是空的。":"The bank is empty."}):e.jsx("ul",{"data-testid":"bank-list",className:"space-y-2",children:c.map(m=>e.jsxs("li",{"data-testid":`bank-row-${m.id}`,className:"flex items-start gap-2 border border-theme rounded-xl px-3 py-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-xs font-semibold text-main line-clamp-2",children:m.stem}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:K.get(m.type)?.label[i?"zh":"en"]??m.type})]}),e.jsx("button",{type:"button",onClick:async()=>{if(window.confirm(i?"从题库删除该题?":"Delete this bank item?"))try{await k.removeBankItem(m.id),await E()}catch(p){f(p?.message??String(p))}},"aria-label":i?`删除题库题目:${m.stem.slice(0,20)}`:"Delete bank item",className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer shrink-0",children:e.jsx(ee,{size:13})})]},m.id))})]})]})}const G={quiz:{zh:"测试",en:"Quiz",cls:"bg-indigo-50 text-indigo-700 border-indigo-200 dark:bg-indigo-950/40 dark:text-indigo-300 dark:border-indigo-800"},exam:{zh:"考试",en:"Exam",cls:"bg-rose-50 text-rose-700 border-rose-200 dark:bg-rose-950/40 dark:text-rose-300 dark:border-rose-800"},survey:{zh:"问卷",en:"Survey",cls:"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800"}},te={draft:{zh:"草稿",en:"Draft",cls:"bg-surface-secondary text-muted border-theme"},published:{zh:"已发布",en:"Published",cls:"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-300 dark:border-emerald-800"},closed:{zh:"已关闭",en:"Closed",cls:"bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-950/40 dark:text-amber-300 dark:border-amber-800"},archived:{zh:"已归档",en:"Archived",cls:"bg-surface-secondary text-muted border-theme"}};function Re(){const i=re()?.lang==="en"?"en":"zh",c=i==="zh",[t,h]=n.useState("papers"),[f,b]=n.useState(null),[y,x]=n.useState(!1),[o,v]=n.useState(null),[u,w]=n.useState(null),[C,A]=n.useState("all"),[g,j]=n.useState(!1),S=n.useCallback(async()=>{x(!0),v(null);try{const a=await k.list(C==="all"?{}:{kind:C});b(a.items)}catch(a){v(a instanceof U?a.message:String(a?.message??a))}finally{x(!1)}},[C]);n.useEffect(()=>{t==="papers"&&u===null&&S()},[t,u,S]);const $=n.useMemo(()=>[...f??[]].sort((N,P)=>P.updatedAt-N.updatedAt),[f]);return u?e.jsx(we,{assessmentId:u,lang:i,onBack:()=>{w(null),S()}}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-surface border border-theme rounded-2xl shadow-xl overflow-hidden",children:[e.jsxs("div",{className:"px-6 py-4 border-b border-theme bg-surface-secondary/70 flex flex-col lg:flex-row lg:items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("h1",{className:"text-base font-bold text-main flex items-center gap-2",children:[e.jsx(Z,{size:18,className:"text-indigo-500"}),c?"测评中心":"Assessment Center"]}),e.jsx("p",{className:"text-xs text-muted mt-0.5",children:c?"组卷、发布到班级、批改与统计。测试 / 考试 / 问卷共用同一套题目与判分模型。":"Build papers, publish to classes, grade and analyse. Quizzes, exams and surveys share one item model."})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("div",{className:"inline-flex p-1 bg-surface-secondary border border-theme rounded-xl text-xs font-semibold",children:[{id:"papers",label:c?"试卷":"Papers",icon:Z},{id:"bank",label:c?"题库":"Question bank",icon:ge}].map(a=>{const N=a.icon,P=t===a.id;return e.jsxs("button",{type:"button",onClick:()=>h(a.id),"aria-pressed":P,className:`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg transition-colors cursor-pointer ${P?"bg-surface text-main shadow-3xs font-bold":"text-muted hover:text-main"}`,children:[e.jsx(N,{size:13}),a.label]},a.id)})}),e.jsxs("button",{type:"button",onClick:()=>void S(),disabled:y||t!=="papers",className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl border border-theme bg-surface hover:bg-surface-secondary text-xs font-semibold text-main disabled:opacity-50 cursor-pointer",children:[e.jsx(Y,{size:13,className:y?"animate-spin":""}),c?"刷新":"Refresh"]}),t==="papers"&&e.jsxs("button",{type:"button",onClick:()=>j(!0),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 cursor-pointer",children:[e.jsx(V,{size:13}),c?"新建测评":"New assessment"]})]})]}),o&&e.jsxs("div",{role:"alert",className:"mx-6 mt-4 px-3 py-2 rounded-xl border border-rose-200 bg-rose-50 text-rose-700 text-xs flex items-center gap-2",children:[e.jsx(fe,{size:14}),o]}),t==="bank"?e.jsx(Ae,{lang:i}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"px-6 py-3 border-b border-theme flex flex-wrap items-center gap-2 shrink-0",children:[e.jsx("span",{className:"text-xs font-semibold text-muted",children:c?"类型筛选":"Filter by kind"}),["all","quiz","exam","survey"].map(a=>e.jsx("button",{type:"button",onClick:()=>A(a),"aria-pressed":C===a,className:`px-2.5 py-1 rounded-full text-xs font-semibold border cursor-pointer ${C===a?"bg-indigo-600 text-white border-indigo-600":"bg-surface text-muted border-theme hover:text-main"}`,children:a==="all"?c?"全部":"All":G[a]?.[c?"zh":"en"]??a},a))]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-6",children:f===null&&y?e.jsxs("div",{className:"flex items-center justify-center gap-2 py-16 text-sm text-muted",children:[e.jsx(T,{size:16,className:"animate-spin"}),c?"正在加载试卷…":"Loading papers…"]}):$.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-3 py-16 text-center",children:[e.jsx(Z,{size:40,className:"text-muted opacity-40"}),e.jsx("p",{className:"text-sm font-semibold text-main",children:c?"还没有任何测评":"No assessments yet"}),e.jsx("p",{className:"text-xs text-muted max-w-sm",children:c?"新建一份测试、考试或问卷,组卷后发布到班级,学生就能在「我的测评」里作答。":"Create a quiz, exam or survey, add questions, then publish it to a class."}),e.jsxs("button",{type:"button",onClick:()=>j(!0),className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 cursor-pointer",children:[e.jsx(V,{size:13}),c?"新建测评":"New assessment"]})]}):e.jsx("ul",{"data-testid":"assessment-list",className:"grid grid-cols-1 xl:grid-cols-2 gap-3 max-w-[1400px] mx-auto",children:$.map(a=>{const N=G[a.kind]??G.quiz,P=te[a.status]??te.draft;return e.jsxs("li",{"data-testid":`assessment-row-${a.id}`,className:"bg-surface border border-theme rounded-xl p-4 flex flex-col gap-2.5 hover:border-indigo-300 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"font-bold text-sm text-main truncate",title:a.title,children:a.title}),a.description&&e.jsx("p",{className:"text-xs text-muted mt-0.5 line-clamp-2",children:a.description})]}),e.jsxs("div",{className:"flex flex-col items-end gap-1 shrink-0",children:[e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-bold border ${N.cls}`,children:N[c?"zh":"en"]}),e.jsx("span",{className:`px-2 py-0.5 rounded-full text-2xs font-semibold border ${P.cls}`,children:P[c?"zh":"en"]})]})]}),e.jsxs("div",{className:"flex items-center gap-3 text-2xs text-muted flex-wrap",children:[e.jsxs("span",{children:[a.itemCount," ",c?"题":"items"]}),e.jsxs("span",{children:[c?"满分":"Total"," ",a.totalScore]}),a.settings.anonymous&&e.jsxs("span",{children:["🔒 ",c?"匿名":"Anonymous"]}),a.settings.maxAttempts>1&&e.jsx("span",{children:c?`可作答 ${a.settings.maxAttempts} 次`:`${a.settings.maxAttempts} attempts`}),e.jsxs("span",{className:"ml-auto flex items-center gap-2",children:[a.status==="draft"&&e.jsx("button",{type:"button",onClick:async()=>{if(window.confirm(c?`删除「${a.title}」?`:`Delete "${a.title}"?`))try{await k.remove(a.id),S()}catch(I){v(I?.message??String(I))}},"aria-label":c?`删除 ${a.title}`:`Delete ${a.title}`,className:"p-1 rounded-md text-muted hover:text-rose-500 hover:bg-rose-500/10 cursor-pointer",children:e.jsx(ee,{size:13})}),e.jsxs("button",{type:"button",onClick:()=>w(a.id),className:"inline-flex items-center gap-1 px-2.5 py-1 rounded-lg border border-theme text-2xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:[a.status==="draft"?c?"继续编辑":"Edit":c?"查看与批改":"Open",e.jsx(ye,{size:12})]})]})]}),e.jsx(ae,{slot:"assessment.list.card",slotProps:{assessment:Ne(a),viewer:"teacher",lang:i},lang:i})]},a.id)})})})]}),g&&e.jsx(Ie,{lang:i,onClose:()=>j(!1),onCreated:a=>{j(!1),w(a)}})]})}function Ie({lang:l,onClose:i,onCreated:c}){const t=l==="zh",[h,f]=n.useState("quiz"),[b,y]=n.useState(""),[x,o]=n.useState(""),[v,u]=n.useState(!1),[w,C]=n.useState(null),A=async g=>{if(g.preventDefault(),!b.trim()){C(t?"请填写标题":"Title is required");return}u(!0),C(null);try{const j=await k.create({kind:h,title:b.trim(),description:x.trim()||null});c(j.id)}catch(j){C(j?.message??String(j))}finally{u(!1)}};return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-labelledby":"create-assessment-title",className:"w-full max-w-md bg-surface border border-theme rounded-2xl shadow-2xl p-5 space-y-4",children:[e.jsx("h2",{id:"create-assessment-title",className:"text-sm font-bold text-main",children:t?"新建测评":"New assessment"}),e.jsxs("form",{onSubmit:A,className:"space-y-3",children:[e.jsxs("fieldset",{children:[e.jsx("legend",{className:"text-xs font-semibold text-muted mb-1",children:t?"类型":"Kind"}),e.jsx("div",{className:"grid grid-cols-3 gap-2",children:["quiz","exam","survey"].map(g=>e.jsxs("label",{className:`flex flex-col items-center gap-1 px-2 py-2 rounded-xl border text-xs cursor-pointer ${h===g?"border-indigo-500 bg-indigo-50 text-indigo-700 dark:bg-indigo-950/40 dark:text-indigo-300":"border-theme text-muted hover:text-main"}`,children:[e.jsx("input",{type:"radio",name:"assessment-kind",value:g,checked:h===g,onChange:()=>f(g),className:"sr-only"}),e.jsx("span",{className:"font-bold",children:G[g][t?"zh":"en"]}),e.jsx("span",{className:"text-2xs text-center leading-snug",children:g==="quiz"?t?"计分,可多次作答":"Scored, retakes allowed":g==="exam"?t?"一次作答,发布成绩后可见":"Single attempt, released later":t?"不计分,可匿名":"Not scored, can be anonymous"})]},g))})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"assessment-title",className:"block text-xs font-semibold text-muted mb-1",children:t?"标题":"Title"}),e.jsx("input",{id:"assessment-title",value:b,onChange:g=>y(g.target.value),className:"w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500",placeholder:t?"例如:第三单元小测":"e.g. Unit 3 quiz"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"assessment-description",className:"block text-xs font-semibold text-muted mb-1",children:t?"说明(可选)":"Description (optional)"}),e.jsx("textarea",{id:"assessment-description",value:x,onChange:g=>o(g.target.value),rows:2,className:"w-full px-2.5 py-1.5 border border-theme rounded-lg text-xs bg-surface text-main focus:outline-none focus:ring-1 focus:ring-indigo-500 resize-none"})]}),w&&e.jsx("p",{role:"alert",className:"text-xs text-rose-600",children:w}),e.jsxs("div",{className:"flex justify-end gap-2 pt-1",children:[e.jsx("button",{type:"button",onClick:i,className:"px-3 py-1.5 rounded-xl border border-theme text-xs font-semibold text-main hover:bg-surface-secondary cursor-pointer",children:t?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:v,className:"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-600 text-white text-xs font-bold hover:bg-indigo-700 disabled:opacity-50 cursor-pointer",children:[v&&e.jsx(T,{size:13,className:"animate-spin"}),t?"创建并开始组卷":"Create & build"]})]})]})]})})}export{Re as AssessmentCenter};
@@ -1 +1 @@
1
- import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as g}from"./index-2676X8YB.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-icons-CXrZ3R2V.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function z({batchPicker:l,setBatchPicker:o,batchPickerLesson:t,setBatchPickerLesson:a,batchPickerDate:i,setBatchPickerDate:n,batchPickerTargetClass:d,setBatchPickerTargetClass:c,lessons:x,classes:u,expandedClassId:m,confirmBatchPicker:h,lang:r}){return l?e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50",children:e.jsxs(g.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-md flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between bg-gray-50/80",children:[e.jsx("h2",{className:"font-bold text-gray-800 text-base",children:l==="schedule"?r==="zh"?"批量排课":"Batch Schedule":l==="lockedLesson"?r==="zh"?"批量设置锁定课程":"Batch Lock Lesson":r==="zh"?"批量转班":"Batch Transfer"}),e.jsx("button",{onClick:()=>o(null),className:"text-gray-400 hover:text-gray-600 text-lg font-bold p-1 hover:bg-gray-200 rounded",children:"×"})]}),e.jsxs("div",{className:"p-5 space-y-4",children:[(l==="schedule"||l==="lockedLesson")&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"选择课程":"Select Lesson"}),e.jsxs("select",{value:t,onChange:s=>a(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500",children:[e.jsx("option",{value:"",children:r==="zh"?"— 请选择 —":"— Select —"}),x.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))]})]}),l==="schedule"&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"上课日期":"Schedule Date"}),e.jsx("input",{type:"date",value:i,onChange:s=>n(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"})]}),l==="transfer"&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"选择目标班级":"Select Target Class"}),e.jsxs("select",{value:d,onChange:s=>c(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500",children:[e.jsx("option",{value:"",children:r==="zh"?"— 请选择 —":"— Select —"}),u.filter(s=>s.id!==m).map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 flex justify-end gap-2",children:[e.jsx("button",{onClick:()=>o(null),className:"px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-100 cursor-pointer",children:r==="zh"?"取消":"Cancel"}),e.jsx("button",{onClick:h,className:"px-4 py-2 text-sm rounded-lg bg-indigo-600 text-white hover:bg-indigo-700 cursor-pointer",children:r==="zh"?"确认":"Confirm"})]})]})}):null}export{z as BatchPickerModal};
1
+ import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as g}from"./index-BzXADCXZ.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-icons-CXrZ3R2V.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function z({batchPicker:l,setBatchPicker:o,batchPickerLesson:t,setBatchPickerLesson:a,batchPickerDate:i,setBatchPickerDate:n,batchPickerTargetClass:d,setBatchPickerTargetClass:c,lessons:x,classes:u,expandedClassId:m,confirmBatchPicker:h,lang:r}){return l?e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50",children:e.jsxs(g.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-md flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between bg-gray-50/80",children:[e.jsx("h2",{className:"font-bold text-gray-800 text-base",children:l==="schedule"?r==="zh"?"批量排课":"Batch Schedule":l==="lockedLesson"?r==="zh"?"批量设置锁定课程":"Batch Lock Lesson":r==="zh"?"批量转班":"Batch Transfer"}),e.jsx("button",{onClick:()=>o(null),className:"text-gray-400 hover:text-gray-600 text-lg font-bold p-1 hover:bg-gray-200 rounded",children:"×"})]}),e.jsxs("div",{className:"p-5 space-y-4",children:[(l==="schedule"||l==="lockedLesson")&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"选择课程":"Select Lesson"}),e.jsxs("select",{value:t,onChange:s=>a(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500",children:[e.jsx("option",{value:"",children:r==="zh"?"— 请选择 —":"— Select —"}),x.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))]})]}),l==="schedule"&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"上课日期":"Schedule Date"}),e.jsx("input",{type:"date",value:i,onChange:s=>n(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"})]}),l==="transfer"&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:r==="zh"?"选择目标班级":"Select Target Class"}),e.jsxs("select",{value:d,onChange:s=>c(s.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500",children:[e.jsx("option",{value:"",children:r==="zh"?"— 请选择 —":"— Select —"}),u.filter(s=>s.id!==m).map(s=>e.jsx("option",{value:s.id,children:s.name},s.id))]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 flex justify-end gap-2",children:[e.jsx("button",{onClick:()=>o(null),className:"px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-100 cursor-pointer",children:r==="zh"?"取消":"Cancel"}),e.jsx("button",{onClick:h,className:"px-4 py-2 text-sm rounded-lg bg-indigo-600 text-white hover:bg-indigo-700 cursor-pointer",children:r==="zh"?"确认":"Confirm"})]})]})}):null}export{z as BatchPickerModal};