openlearn-next 0.7.9 → 0.7.12

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 (56) hide show
  1. package/README.md +13 -4
  2. package/cli-data.mjs +1 -1
  3. package/dist/assets/{ActivityWorkspaceWidget-DbspLRxB.js → ActivityWorkspaceWidget-TtBuNORs.js} +1 -1
  4. package/dist/assets/AdminDirectoryView-D03WOMc-.js +5 -0
  5. package/dist/assets/{AssessmentCenter-DbJAcTvr.js → AssessmentCenter-MUvoJySb.js} +1 -1
  6. package/dist/assets/{AssignmentFilePreview-DEVTb4YJ.js → AssignmentFilePreview-dVhnTYmq.js} +1 -1
  7. package/dist/assets/{BatchPickerModal-czw6eA6e.js → BatchPickerModal-QALdhrX6.js} +1 -1
  8. package/dist/assets/{ClassesView-B1F0tTtB.js → ClassesView-CKwlRz-A.js} +5 -5
  9. package/dist/assets/{ClassroomCountdownWidget-C9pv3GLy.js → ClassroomCountdownWidget-DyWyForY.js} +1 -1
  10. package/dist/assets/{CloudDriveModal-goDB6dlC.js → CloudDriveModal-C8UAn3MO.js} +1 -1
  11. package/dist/assets/{ComputerLabView-Csqiqvw2.js → ComputerLabView-E5b3XTkk.js} +1 -1
  12. package/dist/assets/{CourseManagement-BD-4z2OZ.js → CourseManagement-3jSlq7lV.js} +1 -1
  13. package/dist/assets/{CourseWizardModal-NXwhuph_.js → CourseWizardModal-BAkW5VJX.js} +1 -1
  14. package/dist/assets/{CoursewareHubPanel-BuKp0mmW.js → CoursewareHubPanel-BkjcusjZ.js} +1 -1
  15. package/dist/assets/{Dashboard-CFDWNYSw.js → Dashboard-Ha2fZAqD.js} +2 -2
  16. package/dist/assets/{ExportWeightModal-dBxYVUP4.js → ExportWeightModal-D2Y13384.js} +1 -1
  17. package/dist/assets/{HelpTour-D3QcGDUz.js → HelpTour-DBq2otcV.js} +1 -1
  18. package/dist/assets/{HelpView-DSZC-1F0.js → HelpView-BVLRnMxl.js} +4 -4
  19. package/dist/assets/{ImportLessonsModal-m_s44eus.js → ImportLessonsModal-CQlq4b81.js} +1 -1
  20. package/dist/assets/ImportModal-Ct0I5cAL.js +3 -0
  21. package/dist/assets/{InteractiveCoursewareViewer-C7faFOFD.js → InteractiveCoursewareViewer-DGKh1gO8.js} +1 -1
  22. package/dist/assets/InteractiveWhiteboard-BbZlYpRu.js +65 -0
  23. package/dist/assets/{LazyCourseware-DNn0O8lA.js → LazyCourseware-zONqinCM.js} +2 -2
  24. package/dist/assets/{LazyWhiteboard-BxpydfnE.js → LazyWhiteboard-BV98LEZ8.js} +2 -2
  25. package/dist/assets/{LessonEditorView-CMCgnrJD.js → LessonEditorView-LXRkKxdY.js} +1 -1
  26. package/dist/assets/LiveClassroomView-TaHtHWkY.js +63 -0
  27. package/dist/assets/{NotificationDetailModal-BMrt09PY.js → NotificationDetailModal-BF_-pn0c.js} +1 -1
  28. package/dist/assets/{PluginView-B6gCF1ZB.js → PluginView-sVMPXae9.js} +1 -1
  29. package/dist/assets/{ProcessLogsModal-DmsOrZnV.js → ProcessLogsModal-D97xLgnL.js} +1 -1
  30. package/dist/assets/{QuizGeneratorModal-BNW6tZ78.js → QuizGeneratorModal-CNY8ISjR.js} +1 -1
  31. package/dist/assets/{StudentAssignmentEvalPanel-DMwBSOXf.js → StudentAssignmentEvalPanel-CUmM5DbT.js} +1 -1
  32. package/dist/assets/{StudentAssignmentView-cQpPme4_.js → StudentAssignmentView-B-1MtwKj.js} +1 -1
  33. package/dist/assets/{StudentLessonView-CpGgYV-b.js → StudentLessonView-CqrcvVND.js} +1 -1
  34. package/dist/assets/{StudentView-BfXi6-NQ.js → StudentView-Bi9kgSrN.js} +2 -2
  35. package/dist/assets/{SystemResourceLibraryModal-d4vfqM_9.js → SystemResourceLibraryModal-DDALKrJC.js} +1 -1
  36. package/dist/assets/{TeacherView-DSJCvFE-.js → TeacherView-C5JmoKHk.js} +2 -2
  37. package/dist/assets/{TimetableView-D9Rhnvfj.js → TimetableView-BOLB-kZC.js} +4 -4
  38. package/dist/assets/index-Bc9003lB.js +131 -0
  39. package/dist/assets/index-D4aq9poS.css +1 -0
  40. package/dist/assets/pluginParsers-DD3QL1Xl.js +1 -0
  41. package/dist/assets/{student-workspace-DO1mSl_I.js → student-workspace-C4UgD58C.js} +1 -1
  42. package/dist/assets/{vendor-icons-DLOPlM4i.js → vendor-icons-CaXLq01o.js} +1 -1
  43. package/dist/env-validation.cjs +14 -6
  44. package/dist/index.html +3 -3
  45. package/dist/server.cjs +1310 -778
  46. package/migrations/045_ai_providers_owner_and_scope.sql +20 -0
  47. package/migrations/README.md +1 -0
  48. package/migrations/schema-golden.json +13 -3
  49. package/package.json +5 -3
  50. package/dist/assets/AdminDirectoryView-C2ZFIwHx.js +0 -5
  51. package/dist/assets/ImportModal-h5ShIMzO.js +0 -2
  52. package/dist/assets/InteractiveWhiteboard-10fno-bJ.js +0 -65
  53. package/dist/assets/LiveClassroomView-BA0us3bY.js +0 -61
  54. package/dist/assets/index-DCnGJbif.css +0 -1
  55. package/dist/assets/index-DuxQtTr9.js +0 -131
  56. package/dist/assets/pluginParsers-HRw6CVog.js +0 -1
@@ -1,2 +1,2 @@
1
- import{r as d,j as e,b as ze}from"./vendor-react-DHoBZpn2.js";import{l as Ce,E as xe}from"./index-DuxQtTr9.js";import{Q as he,a3 as ye,aC as ke,R as Re,J as Se,h as Ae,a4 as se,V as ve,b0 as Ee,U as Pe,b7 as $e,o as ie,n as q,aa as pe,ay as ce,az as de,r as be,ag as le,ad as fe,bV as Te,M as De}from"./vendor-icons-DLOPlM4i.js";import{a as Le,B as _e,C as Me,X as Fe,Y as Ve,T as Oe,f as Qe,g as Ie,i as Be}from"./vendor-charts-skggaP9D.js";const ge=["#F59E0B","#6366F1","#10B981","#3B82F6","#0EA5E9"];function Ke({lang:r="zh",lessonId:o,classId:w,lessons:N=[],classes:A=[],schedules:C=[],students:z=[],addToast:O,className:n="",compact:U=!1,allowSimulation:k=!1}){const[p,H]=d.useState(o||""),[y,Y]=d.useState("score"),[ne,W]=d.useState(!1),[G,Q]=d.useState(!1),[R,K]=d.useState([]),[F,V]=d.useState({totalParticipants:0,totalResponses:0,averageScore:0}),[re,P]=d.useState(null);d.useEffect(()=>{o&&o!==p&&H(o)},[o]),d.useEffect(()=>{if(!p&&N.length>0){const s=new Date().toISOString().split("T")[0],x=C.find(m=>m.scheduled_date===s);H(x?.lesson_id||N[0].id)}},[p,N,C]);const $=d.useCallback(async s=>{const x=s||p;if(x){W(!0);try{const m=w?`&classId=${encodeURIComponent(w)}`:"",u=await fetch(`/api/classroom/sessions/${encodeURIComponent(x)}/top-performers?limit=5${m}`);if(u.ok){const b=await u.json();b.success&&Array.isArray(b.topPerformers)&&b.topPerformers.length>0?(K(b.topPerformers),b.summary&&V(b.summary)):(K([]),V({totalParticipants:0,totalResponses:0,averageScore:0}))}}catch(m){console.warn("[TopPerformersWidget] fetch failed:",m)}finally{W(!1)}}},[p,w]);d.useEffect(()=>{p&&$(p)},[p,w,$]),d.useEffect(()=>{const s=u=>{if(P(Date.now()),!u||u.lessonId&&u.lessonId!==p)return;const b=u.studentId||u.id;Array.isArray(z)&&z.length>0&&!z.some(l=>l.id===b)||(K(l=>{const T=u.studentName||z.find(f=>f.id===b)?.name||`Student ${String(b).slice(-4)}`,L=Number(u.score)||0,_=u.isCorrect?1:0,D=l.findIndex(f=>f.studentId===b);let j;if(D>=0){const f=l[D],E=f.totalQuizzesAnswered+1,M=f.correctCount+_,I=f.cumulativeScore+L,oe=Math.round(M/E*100),ae={...f,cumulativeScore:I,totalQuizzesAnswered:E,correctCount:M,accuracy:oe,lastSubmittedAt:Date.now()};j=[...l],j[D]=ae}else{const f={rank:99,studentId:b,studentName:T,cumulativeScore:L,totalQuizzesAnswered:1,correctCount:_,accuracy:_?100:0,avgTimeSpentMs:u.time_spent_ms??null,lastSubmittedAt:Date.now()};j=[...l,f]}return j.sort((f,E)=>E.cumulativeScore-f.cumulativeScore||E.accuracy-f.accuracy||E.correctCount-f.correctCount),j.slice(0,5).map((f,E)=>({...f,rank:E+1}))}),V(l=>({...l,totalResponses:l.totalResponses+1})))};let x=null;const m=Ce(u=>{x?.(),u.on("whiteboard-quiz-answered",s),x=()=>{typeof u.off=="function"&&u.off("whiteboard-quiz-answered",s)}});return()=>{m(),x?.()}},[p,z]);const J=async()=>{if(p){Q(!0);try{(await fetch(`/api/classroom/sessions/${p}/simulate-quiz-responses`,{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&(O?.(r==="zh"?"🎯 实时答题模拟成功":"🎯 Quiz Simulation Success",r==="zh"?"已为 8 位学生生成随堂测验提交,实时成绩榜单已即时重排!":"Generated simulated live quiz submissions. Top performers updated!","success"),await $(p))}catch(s){console.error("Failed to simulate quiz responses:",s)}finally{Q(!1)}}},Z=s=>{O?.(r==="zh"?"🏆 表扬已送达":"🏆 Praise Sent",r==="zh"?`已向榜首学生 [${s.studentName}] 发送课堂「随堂之星」荣誉勋章与鼓励!`:`Sent "Quiz Star" honor medal to top performer [${s.studentName}]!`,"success")},ee=()=>{const s=["Rank","Student ID","Student Name","Cumulative Score","Answered","Correct","Accuracy %"],x=R.map(l=>[l.rank,l.studentId,l.studentName,l.cumulativeScore,l.totalQuizzesAnswered,l.correctCount,`${l.accuracy}%`]),m="data:text/csv;charset=utf-8,\uFEFF"+[s.join(","),...x.map(l=>l.join(","))].join(`
1
+ import{r as d,j as e,b as ze}from"./vendor-react-DHoBZpn2.js";import{l as Ce,E as xe}from"./index-Bc9003lB.js";import{Q as he,a3 as ye,aF as ke,R as Re,J as Se,h as Ae,a4 as se,V as ve,b2 as Ee,U as Pe,b9 as $e,o as ie,n as q,aa as pe,aB as ce,aC as de,r as be,ag as le,ad as fe,bV as Te,M as De}from"./vendor-icons-CaXLq01o.js";import{a as Le,B as _e,C as Me,X as Fe,Y as Ve,T as Oe,f as Qe,g as Ie,i as Be}from"./vendor-charts-skggaP9D.js";const ge=["#F59E0B","#6366F1","#10B981","#3B82F6","#0EA5E9"];function Ke({lang:r="zh",lessonId:o,classId:w,lessons:N=[],classes:A=[],schedules:C=[],students:z=[],addToast:O,className:n="",compact:U=!1,allowSimulation:k=!1}){const[p,H]=d.useState(o||""),[y,Y]=d.useState("score"),[ne,W]=d.useState(!1),[G,Q]=d.useState(!1),[R,K]=d.useState([]),[F,V]=d.useState({totalParticipants:0,totalResponses:0,averageScore:0}),[re,P]=d.useState(null);d.useEffect(()=>{o&&o!==p&&H(o)},[o]),d.useEffect(()=>{if(!p&&N.length>0){const s=new Date().toISOString().split("T")[0],x=C.find(m=>m.scheduled_date===s);H(x?.lesson_id||N[0].id)}},[p,N,C]);const $=d.useCallback(async s=>{const x=s||p;if(x){W(!0);try{const m=w?`&classId=${encodeURIComponent(w)}`:"",u=await fetch(`/api/classroom/sessions/${encodeURIComponent(x)}/top-performers?limit=5${m}`);if(u.ok){const b=await u.json();b.success&&Array.isArray(b.topPerformers)&&b.topPerformers.length>0?(K(b.topPerformers),b.summary&&V(b.summary)):(K([]),V({totalParticipants:0,totalResponses:0,averageScore:0}))}}catch(m){console.warn("[TopPerformersWidget] fetch failed:",m)}finally{W(!1)}}},[p,w]);d.useEffect(()=>{p&&$(p)},[p,w,$]),d.useEffect(()=>{const s=u=>{if(P(Date.now()),!u||u.lessonId&&u.lessonId!==p)return;const b=u.studentId||u.id;Array.isArray(z)&&z.length>0&&!z.some(l=>l.id===b)||(K(l=>{const T=u.studentName||z.find(f=>f.id===b)?.name||`Student ${String(b).slice(-4)}`,L=Number(u.score)||0,_=u.isCorrect?1:0,D=l.findIndex(f=>f.studentId===b);let j;if(D>=0){const f=l[D],E=f.totalQuizzesAnswered+1,M=f.correctCount+_,I=f.cumulativeScore+L,oe=Math.round(M/E*100),ae={...f,cumulativeScore:I,totalQuizzesAnswered:E,correctCount:M,accuracy:oe,lastSubmittedAt:Date.now()};j=[...l],j[D]=ae}else{const f={rank:99,studentId:b,studentName:T,cumulativeScore:L,totalQuizzesAnswered:1,correctCount:_,accuracy:_?100:0,avgTimeSpentMs:u.time_spent_ms??null,lastSubmittedAt:Date.now()};j=[...l,f]}return j.sort((f,E)=>E.cumulativeScore-f.cumulativeScore||E.accuracy-f.accuracy||E.correctCount-f.correctCount),j.slice(0,5).map((f,E)=>({...f,rank:E+1}))}),V(l=>({...l,totalResponses:l.totalResponses+1})))};let x=null;const m=Ce(u=>{x?.(),u.on("whiteboard-quiz-answered",s),x=()=>{typeof u.off=="function"&&u.off("whiteboard-quiz-answered",s)}});return()=>{m(),x?.()}},[p,z]);const J=async()=>{if(p){Q(!0);try{(await fetch(`/api/classroom/sessions/${p}/simulate-quiz-responses`,{method:"POST",headers:{"Content-Type":"application/json"}})).ok&&(O?.(r==="zh"?"🎯 实时答题模拟成功":"🎯 Quiz Simulation Success",r==="zh"?"已为 8 位学生生成随堂测验提交,实时成绩榜单已即时重排!":"Generated simulated live quiz submissions. Top performers updated!","success"),await $(p))}catch(s){console.error("Failed to simulate quiz responses:",s)}finally{Q(!1)}}},Z=s=>{O?.(r==="zh"?"🏆 表扬已送达":"🏆 Praise Sent",r==="zh"?`已向榜首学生 [${s.studentName}] 发送课堂「随堂之星」荣誉勋章与鼓励!`:`Sent "Quiz Star" honor medal to top performer [${s.studentName}]!`,"success")},ee=()=>{const s=["Rank","Student ID","Student Name","Cumulative Score","Answered","Correct","Accuracy %"],x=R.map(l=>[l.rank,l.studentId,l.studentName,l.cumulativeScore,l.totalQuizzesAnswered,l.correctCount,`${l.accuracy}%`]),m="data:text/csv;charset=utf-8,\uFEFF"+[s.join(","),...x.map(l=>l.join(","))].join(`
2
2
  `),u=encodeURI(m),b=document.createElement("a");b.setAttribute("href",u),b.setAttribute("download",`top_performers_quiz_${p||"class"}.csv`),document.body.appendChild(b),b.click(),document.body.removeChild(b),O?.(r==="zh"?"📥 导出成功":"📥 Exported",r==="zh"?"随堂测验 Top 5 榜单数据已导出为 CSV 文件。":"Top 5 performers exported to CSV.","info")},te=d.useMemo(()=>R.map(s=>{const x=s.studentName.length>8?`${s.studentName.slice(0,7)}…`:s.studentName;return{rank:s.rank,name:x,fullName:s.studentName,studentId:s.studentId,score:s.cumulativeScore,accuracy:s.accuracy,count:s.totalQuizzesAnswered,correctCount:s.correctCount,avgTimeSec:(s.avgTimeSpentMs/1e3).toFixed(1),chartValue:y==="score"?s.cumulativeScore:y==="accuracy"?s.accuracy:s.totalQuizzesAnswered}}),[R,y]),X=d.useMemo(()=>N.find(s=>s.id===p)?.title||p||"Classroom Session",[N,p]);return e.jsxs("div",{id:"top-performers-widget","data-testid":"top-performers-widget",className:`bg-surface border border-theme rounded-2xl p-5 shadow-sm transition-all relative flex flex-col gap-4 ${n}`,children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3 pb-3 border-b border-theme/60",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-10 h-10 rounded-xl bg-amber-500/10 text-amber-500 flex items-center justify-center font-bold shadow-xs",children:e.jsx(he,{size:20,className:"text-amber-500 animate-bounce"})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"text-base font-bold text-main tracking-tight",children:r==="zh"?"随堂测验优秀榜 (Top 5 Performers)":"Live Quiz Top 5 Performers"}),re&&e.jsxs("span",{className:"flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400 border border-emerald-200 dark:border-emerald-800 animate-pulse",children:[e.jsx(ye,{size:10,className:"animate-spin text-emerald-500"}),e.jsx("span",{children:r==="zh"?"实时作答同步中":"Live Sync"})]})]}),e.jsx("p",{className:"text-xs text-muted mt-0.5",children:r==="zh"?"基于课堂互动白板随堂测试累计得分与答题正确率智能聚合":"Aggregated from cumulative scores and accuracy in live quiz responses"})]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[N.length>0&&e.jsx("select",{value:p,onChange:s=>H(s.target.value),className:"bg-surface-secondary border border-theme text-xs rounded-lg px-2.5 py-1.5 text-main outline-none focus:ring-1 focus:ring-primary-theme cursor-pointer max-w-[160px] truncate",title:X,children:N.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))}),e.jsxs("div",{className:"bg-surface-secondary p-0.5 rounded-lg flex items-center border border-theme text-xs",children:[e.jsx("button",{onClick:()=>Y("score"),className:`px-2 py-1 rounded-md font-medium transition-all ${y==="score"?"bg-surface text-primary-theme shadow-xs font-bold":"text-muted hover:text-main"}`,title:r==="zh"?"按累计得分排序":"By Cumulative Score",children:r==="zh"?"累计得分":"Score"}),e.jsx("button",{onClick:()=>Y("accuracy"),className:`px-2 py-1 rounded-md font-medium transition-all ${y==="accuracy"?"bg-surface text-primary-theme shadow-xs font-bold":"text-muted hover:text-main"}`,title:r==="zh"?"按正确率排序":"By Accuracy",children:r==="zh"?"正确率":"Accuracy"}),e.jsx("button",{onClick:()=>Y("count"),className:`px-2 py-1 rounded-md font-medium transition-all ${y==="count"?"bg-surface text-primary-theme shadow-xs font-bold":"text-muted hover:text-main"}`,title:r==="zh"?"按答题题次排序":"By Quiz Count",children:r==="zh"?"题次":"Count"})]}),k&&e.jsxs("button",{onClick:J,disabled:G,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs font-bold bg-amber-50 text-amber-700 dark:bg-amber-950/40 dark:text-amber-400 border border-amber-200 dark:border-amber-800 hover:bg-amber-100 transition-colors cursor-pointer shadow-xs disabled:opacity-50",title:r==="zh"?"模拟学生实时答题":"Simulate Quiz Responses",children:[e.jsx(ke,{size:12,className:G?"animate-spin text-amber-600":"text-amber-600"}),e.jsx("span",{className:"hidden sm:inline",children:r==="zh"?"模拟答题":"Simulate"})]}),e.jsx("button",{onClick:()=>$(p),disabled:ne,className:"p-1.5 rounded-lg border border-theme bg-surface hover:bg-surface-secondary text-muted hover:text-main transition-colors cursor-pointer shadow-xs disabled:opacity-50",title:r==="zh"?"刷新榜单数据":"Refresh rankings",children:e.jsx(Re,{size:14,className:ne?"animate-spin text-primary-theme":""})}),e.jsx("button",{onClick:ee,disabled:R.length===0,className:"p-1.5 rounded-lg border border-theme bg-surface hover:bg-surface-secondary text-muted hover:text-main transition-colors cursor-pointer shadow-xs disabled:opacity-40",title:r==="zh"?"导出 Top 5 榜单 CSV":"Export CSV",children:e.jsx(Se,{size:14})})]})]}),R.length===0?e.jsxs("div",{className:"p-8 rounded-xl border border-dashed border-theme bg-surface-secondary/20 flex flex-col items-center justify-center text-center gap-2",children:[e.jsx(he,{size:28,className:"text-muted/60"}),e.jsx("p",{className:"text-sm font-semibold text-main",children:r==="zh"?"暂无随堂作答数据":"No Quiz Responses Yet"}),e.jsx("p",{className:"text-xs text-muted max-w-sm",children:r==="zh"?"学生开始作答随堂测验或白板互动题后,实时榜单与答题数据将自动刷新呈现。":"Rankings and visual distribution will appear here once students submit answers."})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-3",children:R.slice(0,3).map(s=>{const x=s.rank===1,m=s.rank===2;s.rank;const u=x?"border-amber-400/50 bg-amber-500/5":m?"border-indigo-400/40 bg-indigo-500/5":"border-emerald-400/40 bg-emerald-500/5",b=x?"bg-amber-500 text-white":m?"bg-indigo-500 text-white":"bg-emerald-500 text-white",l=x?"🥇":m?"🥈":"🥉";return e.jsxs("div",{"data-testid":"top-performers-item",className:`p-3.5 rounded-xl border ${u} flex flex-col justify-between gap-3 relative transition-all hover:shadow-sm`,children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:`w-8 h-8 rounded-lg flex items-center justify-center font-extrabold text-sm shadow-xs ${b}`,children:l}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-sm font-bold text-main leading-tight truncate max-w-[130px]",children:s.studentName}),e.jsxs("span",{className:"text-xs text-muted flex items-center gap-1 mt-0.5",children:[e.jsx(Ae,{size:11,className:"text-emerald-500"}),s.correctCount,"/",s.totalQuizzesAnswered," ",r==="zh"?"题全对":"correct"]})]})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("div",{className:"text-base font-extrabold text-main font-mono",children:[s.cumulativeScore," ",e.jsx("span",{className:"text-xs font-normal text-muted",children:r==="zh"?"分":"pts"})]}),e.jsxs("span",{className:"text-xs font-semibold px-1.5 py-0.2 rounded bg-surface border border-theme text-primary-theme",children:[s.accuracy,"% ",r==="zh"?"正确率":"acc"]})]})]}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted pt-2 border-t border-theme/40",children:[e.jsxs("span",{className:"flex items-center gap-1 font-mono",children:[e.jsx(se,{size:11})," ",s.avgTimeSpentMs?`${(s.avgTimeSpentMs/1e3).toFixed(1)}s`:"—"," ",r==="zh"?"均速":"avg"]}),x&&e.jsxs("button",{onClick:()=>Z(s),className:"flex items-center gap-1 text-xs font-semibold text-amber-600 hover:text-amber-700 dark:text-amber-400 hover:underline cursor-pointer",title:r==="zh"?"一键表扬榜首":"Praise top performer",children:[e.jsx(ve,{size:11})," ",r==="zh"?"一键表扬":"Praise"]})]})]},s.studentId)})}),e.jsxs("div",{className:"bg-surface-secondary/40 border border-theme rounded-xl p-4 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted px-1",children:[e.jsxs("span",{className:"font-semibold text-main flex items-center gap-1.5",children:[e.jsx(Ee,{size:14,className:"text-primary-theme"}),r==="zh"?`Top 5 答题得分可视化分布 (${y==="score"?"累计得分":y==="accuracy"?"正确率%":"答题数"})`:`Top 5 Visual Distribution (${y.toUpperCase()})`]}),e.jsx("span",{className:"text-xs text-muted font-mono",children:r==="zh"?`全班平均得分: ${F.averageScore} 分 | 参与人次: ${F.totalResponses}`:`Class Avg: ${F.averageScore} pts | Responses: ${F.totalResponses}`})]}),e.jsx("div",{"data-testid":"top-performers-chart",className:"w-full h-56 pt-2",children:e.jsx(Le,{width:"100%",height:"100%",children:e.jsxs(_e,{data:te,layout:"vertical",margin:{top:8,right:36,left:10,bottom:8},children:[e.jsx(Me,{strokeDasharray:"3 3",horizontal:!1,stroke:"currentColor",className:"text-theme/40"}),e.jsx(Fe,{type:"number",domain:[0,y==="accuracy"?100:"auto"],tick:{fontSize:12,fill:"currentColor"},className:"text-muted",unit:y==="accuracy"?"%":""}),e.jsx(Ve,{type:"category",dataKey:"name",tick:{fontSize:12,fill:"currentColor",fontWeight:600},className:"text-main",width:85}),e.jsx(Oe,{content:({active:s,payload:x})=>{if(s&&x&&x.length){const m=x[0].payload;return e.jsxs("div",{className:"bg-surface border border-theme p-3 rounded-xl shadow-lg text-xs flex flex-col gap-1.5 min-w-[180px] z-50",children:[e.jsx("div",{className:"flex items-center justify-between font-bold text-main border-b border-theme/60 pb-1",children:e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsxs("span",{className:"w-5 h-5 rounded-full bg-primary-theme/10 text-primary-theme flex items-center justify-center font-mono",children:["#",m.rank]}),m.fullName]})}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-2 gap-y-1 text-muted pt-1",children:[e.jsx("span",{children:r==="zh"?"累计得分:":"Total Score:"}),e.jsxs("span",{className:"font-bold text-main font-mono text-right",children:[m.score," 分"]}),e.jsx("span",{children:r==="zh"?"正确率:":"Accuracy:"}),e.jsxs("span",{className:"font-bold text-emerald-600 dark:text-emerald-400 font-mono text-right",children:[m.accuracy,"%"]}),e.jsx("span",{children:r==="zh"?"答对题次:":"Correct Count:"}),e.jsxs("span",{className:"font-mono text-right",children:[m.correctCount," / ",m.count," 题"]}),e.jsx("span",{children:r==="zh"?"平均答题速度:":"Avg Speed:"}),e.jsxs("span",{className:"font-mono text-right",children:[m.avgTimeSec," 秒"]})]})]})}return null}}),e.jsxs(Qe,{dataKey:"chartValue",radius:[0,6,6,0],barSize:22,children:[te.map((s,x)=>e.jsx(Ie,{fill:ge[x%ge.length]},`cell-${s.studentId}-${x}`)),e.jsx(Be,{dataKey:"chartValue",position:"right",formatter:s=>y==="accuracy"?`${s}%`:y==="score"?`${s}分`:`${s}题`,className:"fill-main text-xs font-bold font-mono"})]})]})})})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-2 text-xs text-muted pt-1",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(Pe,{size:12,className:"text-primary-theme"}),r==="zh"?"统计口径: 课中互动测验与答题器":"Scope: Live interactive quizzes & clickers"]}),e.jsx("span",{className:"hidden sm:inline text-theme",children:"•"}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx($e,{size:12,className:"text-amber-500"}),r==="zh"?"实时随堂竞赛积分制":"Gamified Live Quiz Points"]})]}),e.jsx("div",{className:"flex items-center gap-2",children:R.length>0&&e.jsx("span",{className:"text-xs text-muted font-medium",children:r==="zh"?`榜首: ${R[0].studentName} (${R[0].cumulativeScore}分)`:`Leader: ${R[0].studentName} (${R[0].cumulativeScore} pts)`})})]})]})}const we=[{id:"1m",label:"1 分钟快速提问",duration:60,icon:"⚡"},{id:"3m",label:"3 分钟温故知新",duration:180,icon:"📖"},{id:"5m",label:"5 分钟随堂小测",duration:300,icon:"📝"},{id:"10m",label:"10 分钟小组研讨",duration:600,icon:"👥"},{id:"15m",label:"15 分钟探究实验",duration:900,icon:"🔬"},{id:"25m",label:"25 分钟番茄专注",duration:1500,icon:"🍅"},{id:"45m",label:"45 分钟完整自习",duration:2700,icon:"⏱️"}],je=["📝 随堂小测","👥 小组研讨","🎯 专注练习","⚡ 限时答题","📖 课前预热","💬 自由提问"];function qe(){try{const r=window.AudioContext||window.webkitAudioContext;if(!r)return;const o=new r,w=o.currentTime,N=o.createOscillator(),A=o.createGain();N.type="sine",N.frequency.setValueAtTime(523.25,w),N.frequency.exponentialRampToValueAtTime(783.99,w+.25),A.gain.setValueAtTime(.3,w),A.gain.exponentialRampToValueAtTime(.001,w+.8),N.connect(A),A.connect(o.destination),N.start(w),N.stop(w+.8);const C=o.createOscillator(),z=o.createGain();C.type="triangle",C.frequency.setValueAtTime(659.25,w+.15),C.frequency.exponentialRampToValueAtTime(1046.5,w+.4),z.gain.setValueAtTime(.2,w+.15),z.gain.exponentialRampToValueAtTime(.001,w+1.2),C.connect(z),z.connect(o.destination),C.start(w+.15),C.stop(w+1.2)}catch{}}function Je({lessonId:r,lang:o="zh",compact:w=!1,variant:N="card",syncChannel:A,onlineStudentCount:C=0,onTimeRemainingChange:z,className:O=""}){const[n,U]=d.useState({lessonId:r,totalDuration:300,timeRemaining:300,isRunning:!1,isPaused:!1,label:o==="zh"?"📝 随堂小测":"📝 In-Class Quiz",endsAt:null,updatedAt:Date.now()}),[k,p]=d.useState(!0),[H,y]=d.useState(!1),[Y,ne]=d.useState("5"),[W,G]=d.useState(!1),[Q,R]=d.useState(""),[K,F]=d.useState(!1),[V,re]=d.useState([]),[P,$]=d.useState(!1),J=d.useRef(null),Z=d.useRef(null),ee=d.useRef(null),[te,X]=d.useState(null),s=d.useCallback(()=>{const t=ee.current??J.current;if(!t||typeof window>"u")return{};const i=t.getBoundingClientRect(),a=window.innerWidth||1024,c=window.innerHeight||768,h=6,g=8,v=Math.min(288,Math.max(200,a-g*2));let S=a-i.right;S=Math.max(g,Math.min(S,a-v-g));const B=Math.max(g,i.bottom+h),Ne=Math.max(180,c-B-g);return{top:B,right:S,width:v,maxHeight:Ne}},[]),x=d.useCallback(()=>{P||X(s()),$(t=>!t)},[P,s]);d.useEffect(()=>{if(!P){X(null);return}let t=0,i=!1;const a=()=>{if(i)return;i=!0;const g=()=>{i=!1,X(s())};typeof window.requestAnimationFrame=="function"?t=window.requestAnimationFrame(g):g()},c=g=>{const v=g.target;J.current?.contains(v)||Z.current?.contains(v)||$(!1)},h=g=>{g.key==="Escape"&&$(!1)};return document.addEventListener("mousedown",c),document.addEventListener("keydown",h),window.addEventListener("resize",a),window.addEventListener("scroll",a,!0),()=>{t&&typeof window.cancelAnimationFrame=="function"&&window.cancelAnimationFrame(t),document.removeEventListener("mousedown",c),document.removeEventListener("keydown",h),window.removeEventListener("resize",a),window.removeEventListener("scroll",a,!0)}},[P,s]);const m=d.useRef(null),u=d.useRef(n);u.current=n;const b=d.useCallback(async()=>{if(!r)return;const t=`openlearn_classroom_countdown_${r}`;try{const i=localStorage.getItem(t);if(i){const a=JSON.parse(i);if(a&&typeof a.timeRemaining=="number"){if(a.isRunning&&a.endsAt){const c=Date.now(),h=Math.max(0,Math.round((a.endsAt-c)/1e3));a.timeRemaining=h,h===0&&(a.isRunning=!1,a.isPaused=!1,a.endsAt=null)}U(a)}}}catch{}try{const i=await fetch(`/api/classroom/sessions/${r}/countdown`);if(i.ok){const a=await i.json();a.success&&a.countdown&&U(c=>{const h=a.countdown;return h.totalDuration>0||h.isRunning?h:c})}}catch{}},[r]);d.useEffect(()=>{b()},[b]);const l=d.useCallback(t=>{if(U(t),r)try{localStorage.setItem(`openlearn_classroom_countdown_${r}`,JSON.stringify(t))}catch{}z?.(t.timeRemaining,t.isRunning),A&&A.broadcastCountdown(t),r&&fetch(`/api/classroom/sessions/${r}/countdown`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:t.isRunning?"start":t.isPaused?"pause":"set",duration:t.totalDuration,label:t.label})}).catch(()=>{});try{window.dispatchEvent(new CustomEvent("openlearn:countdown:updated",{detail:t}))}catch{}},[r,z,A]);d.useEffect(()=>(n.isRunning&&n.endsAt?m.current=setInterval(()=>{const t=u.current;if(!t.isRunning||!t.endsAt)return;const i=Date.now(),a=Math.max(0,Math.round((t.endsAt-i)/1e3));if(a!==t.timeRemaining){const c={...t,timeRemaining:a,updatedAt:i};if(a<=0){c.isRunning=!1,c.isPaused=!1,c.endsAt=null,k&&qe();try{window.dispatchEvent(new CustomEvent("openlearn:countdown:expired",{detail:{lessonId:r,label:t.label,totalDuration:t.totalDuration}}))}catch{}}U(c),z?.(c.timeRemaining,c.isRunning),A?.broadcastCountdown(c);try{window.dispatchEvent(new CustomEvent("openlearn:countdown:tick",{detail:{timeRemaining:c.timeRemaining,totalDuration:c.totalDuration}}))}catch{}}},500):m.current&&(clearInterval(m.current),m.current=null),()=>{m.current&&clearInterval(m.current)}),[n.isRunning,n.endsAt,k,r,z,A]);const T=(t,i)=>{const a=Date.now(),c=t>0?t:n.totalDuration||300,h=i||n.label,g={lessonId:r,totalDuration:c,timeRemaining:c,isRunning:!0,isPaused:!1,label:h,endsAt:a+c*1e3,updatedAt:a};l(g);try{window.dispatchEvent(new CustomEvent("openlearn:countdown:started",{detail:g}))}catch{}},L=()=>{const t=Date.now(),i=u.current,a=i.endsAt?Math.max(0,Math.round((i.endsAt-t)/1e3)):i.timeRemaining,c={...i,timeRemaining:a,isRunning:!1,isPaused:!0,endsAt:null,updatedAt:t};l(c);try{window.dispatchEvent(new CustomEvent("openlearn:countdown:paused",{detail:c}))}catch{}},_=()=>{const t=Date.now(),i=u.current,a=i.timeRemaining>0?i.timeRemaining:i.totalDuration||300,c={...i,timeRemaining:a,isRunning:!0,isPaused:!1,endsAt:t+a*1e3,updatedAt:t};l(c);try{window.dispatchEvent(new CustomEvent("openlearn:countdown:resumed",{detail:c}))}catch{}},D=()=>{const t=Date.now(),i=u.current,a={...i,timeRemaining:i.totalDuration||300,isRunning:!1,isPaused:!1,endsAt:null,updatedAt:t};l(a);try{window.dispatchEvent(new CustomEvent("openlearn:countdown:reset",{detail:a}))}catch{}},j=t=>{const i=Date.now(),a=u.current,c=Math.max(0,a.timeRemaining+t),h=Math.max(a.totalDuration,c),g={...a,totalDuration:h,timeRemaining:c,endsAt:a.isRunning?i+c*1e3:null,updatedAt:i};l(g)};d.useEffect(()=>{const t={getState:()=>u.current,start:(v,S)=>T(v,S),pause:()=>L(),resume:()=>_(),reset:()=>D(),addTime:v=>j(v),registerPreset:v=>{re(S=>S.some(B=>B.id===v.id)?S:[...S,v])},getPresets:()=>[...we,...V]};window.__openlearn_countdown=t;const i=v=>{const{duration:S,label:B}=v.detail||{};T(S||300,B)},a=()=>L(),c=()=>_(),h=()=>D(),g=v=>{const{seconds:S}=v.detail||{};j(S||60)};return window.addEventListener("openlearn:countdown:trigger_start",i),window.addEventListener("openlearn:countdown:trigger_pause",a),window.addEventListener("openlearn:countdown:trigger_resume",c),window.addEventListener("openlearn:countdown:trigger_reset",h),window.addEventListener("openlearn:countdown:trigger_add_time",g),()=>{window.removeEventListener("openlearn:countdown:trigger_start",i),window.removeEventListener("openlearn:countdown:trigger_pause",a),window.removeEventListener("openlearn:countdown:trigger_resume",c),window.removeEventListener("openlearn:countdown:trigger_reset",h),window.removeEventListener("openlearn:countdown:trigger_add_time",g)}},[V]);const f=t=>{const i=Math.floor(t/60),a=t%60,c=h=>h.toString().padStart(2,"0");return`${c(i)}:${c(a)}`},E=n.totalDuration>0?Math.min(100,Math.max(0,n.timeRemaining/n.totalDuration*100)):0,M=n.timeRemaining>0&&n.timeRemaining<=60,I=n.timeRemaining>60&&n.timeRemaining<=180,oe=M?"text-rose-500":I?"text-amber-500":"text-primary-theme",ae=M?"bg-rose-500":I?"bg-amber-500":"bg-primary-theme",me=[...we,...V],ue=()=>H?e.jsxs("div",{id:"classroom-countdown-projector-modal",className:"fixed inset-0 z-50 bg-black/85 backdrop-blur-md flex flex-col items-center justify-center p-6 select-none animate-in fade-in duration-200",children:[e.jsxs("div",{className:"absolute top-6 right-6 flex items-center gap-3",children:[e.jsx("button",{type:"button",onClick:()=>p(!k),className:"p-2.5 rounded-xl bg-white/10 hover:bg-white/20 text-white transition-colors cursor-pointer",children:k?e.jsx(ce,{size:20}):e.jsx(de,{size:20})}),e.jsx("button",{type:"button",onClick:()=>y(!1),className:"p-2.5 rounded-xl bg-white/10 hover:bg-white/20 text-white transition-colors cursor-pointer",children:e.jsx(De,{size:20})})]}),e.jsxs("div",{className:"flex flex-col items-center gap-6 max-w-2xl w-full",children:[e.jsxs("div",{className:"flex items-center gap-2 px-4 py-1.5 rounded-full bg-white/10 border border-white/20 text-white text-sm font-bold",children:[e.jsx(ve,{size:16,className:"text-amber-300"}),e.jsx("span",{children:n.label}),e.jsx("span",{className:"text-xs text-white/60 ml-2",children:o==="zh"?`全班 ${C} 位学生正在同步`:`${C} students connected`})]}),e.jsx("div",{className:`text-8xl md:text-9xl font-black font-mono tracking-widest drop-shadow-2xl transition-all ${M?"text-rose-500 animate-pulse":I?"text-amber-400":"text-emerald-400"}`,children:f(n.timeRemaining)}),e.jsx("div",{className:"w-full h-3 bg-white/10 rounded-full overflow-hidden border border-white/20 shadow-inner",children:e.jsx("div",{className:`h-full transition-all duration-500 ${M?"bg-rose-500":I?"bg-amber-400":"bg-emerald-400"}`,style:{width:`${E}%`}})}),e.jsxs("div",{className:"flex items-center gap-4 mt-2",children:[n.isRunning?e.jsxs("button",{type:"button",onClick:L,className:"px-8 py-3 rounded-2xl bg-amber-700 hover:bg-amber-800 text-white font-bold text-lg transition-transform active:scale-95 shadow-xl flex items-center gap-2 cursor-pointer",children:[e.jsx(ie,{size:20}),e.jsx("span",{children:o==="zh"?"暂停":"Pause"})]}):n.isPaused?e.jsxs("button",{type:"button",onClick:_,className:"px-8 py-3 rounded-2xl bg-emerald-700 hover:bg-emerald-800 text-white font-bold text-lg transition-transform active:scale-95 shadow-xl flex items-center gap-2 cursor-pointer",children:[e.jsx(q,{size:20}),e.jsx("span",{children:o==="zh"?"继续":"Resume"})]}):e.jsxs("button",{type:"button",onClick:()=>T(n.totalDuration||300),className:"px-8 py-3 rounded-2xl bg-primary-theme hover:opacity-90 text-white font-bold text-lg transition-transform active:scale-95 shadow-xl flex items-center gap-2 cursor-pointer",children:[e.jsx(q,{size:20}),e.jsx("span",{children:o==="zh"?"开始":"Start"})]}),e.jsx("button",{type:"button",onClick:()=>j(60),className:"px-5 py-3 rounded-2xl bg-white/10 hover:bg-white/20 text-white font-bold text-base transition-colors cursor-pointer border border-white/20",children:"+1 分钟"}),e.jsx("button",{type:"button",onClick:()=>j(300),className:"px-5 py-3 rounded-2xl bg-white/10 hover:bg-white/20 text-white font-bold text-base transition-colors cursor-pointer border border-white/20",children:"+5 分钟"}),e.jsx("button",{type:"button",onClick:D,className:"p-3 rounded-2xl bg-white/10 hover:bg-white/20 text-white font-bold transition-colors cursor-pointer border border-white/20",title:"重置",children:e.jsx(le,{size:20})})]})]})]}):null;return N==="header"?e.jsxs("div",{ref:J,id:"classroom-countdown-header-container",className:`relative flex items-center shrink-0 ${O}`,children:[e.jsxs("div",{id:"classroom-countdown-header-pill",className:`h-7 sm:h-8 px-2 py-0.5 rounded-lg border text-xs font-semibold flex items-center gap-1.5 shadow-2xs select-none transition-all ${n.isRunning?"bg-primary-theme/10 border-primary-theme/40 text-primary-theme ring-1 ring-primary-theme/20":"bg-surface border-theme text-main hover:bg-surface-secondary"}`,children:[e.jsx(se,{size:13,className:`shrink-0 ${n.isRunning?"animate-spin text-primary-theme":"text-muted"}`,style:{animationDuration:"6s"}}),e.jsx("span",{className:"text-[11px] font-medium text-muted hidden xl:inline truncate max-w-[68px]",children:n.label}),e.jsx("span",{id:"classroom-countdown-digits",className:`font-mono font-black text-xs sm:text-sm tracking-wider ${M?"text-rose-500 animate-pulse":n.isRunning?"text-primary-theme font-extrabold":"text-main"}`,children:f(n.timeRemaining)}),e.jsxs("div",{className:"flex items-center gap-1 ml-0.5 border-l border-theme/60 pl-1.5",children:[n.isRunning?e.jsx("button",{type:"button",id:"classroom-countdown-pause-btn",onClick:L,className:"w-5 h-5 rounded-md bg-amber-700 text-white hover:bg-amber-800 flex items-center justify-center cursor-pointer transition-colors shadow-2xs",title:o==="zh"?"暂停倒计时":"Pause",children:e.jsx(ie,{size:10})}):n.isPaused?e.jsx("button",{type:"button",id:"classroom-countdown-resume-btn",onClick:_,className:"w-5 h-5 rounded-md bg-emerald-600 text-white hover:bg-emerald-700 flex items-center justify-center cursor-pointer transition-colors shadow-2xs",title:o==="zh"?"继续倒计时":"Resume",children:e.jsx(q,{size:10})}):e.jsx("button",{type:"button",id:"classroom-countdown-start-btn",onClick:()=>T(n.totalDuration||300),className:"w-5 h-5 rounded-md bg-primary-theme text-white hover:opacity-90 flex items-center justify-center cursor-pointer transition-colors shadow-2xs",title:o==="zh"?"开始倒计时":"Start",children:e.jsx(q,{size:10})}),e.jsx("button",{type:"button",onClick:()=>j(60),className:"px-1.5 h-5 rounded bg-surface-secondary hover:bg-primary-theme/15 hover:text-primary-theme border border-theme/60 text-[10px] font-bold text-muted transition-colors cursor-pointer",title:o==="zh"?"增加1分钟":"+1m",children:"+1m"}),e.jsx("button",{type:"button",ref:ee,id:"classroom-countdown-settings-toggle",onClick:x,"aria-expanded":P,"aria-haspopup":"dialog",className:`w-5 h-5 rounded flex items-center justify-center text-muted hover:text-main hover:bg-surface-secondary transition-colors cursor-pointer ${P?"bg-surface-secondary text-main":""}`,title:o==="zh"?"倒计时设置与大屏投放":"Settings & Projector",children:e.jsx(pe,{size:11,className:`transition-transform duration-200 ${P?"rotate-180":""}`})})]})]}),P&&ze.createPortal(e.jsxs("div",{ref:Z,id:"classroom-countdown-header-popover",role:"dialog","aria-label":o==="zh"?"课堂倒计时设置":"Countdown Settings",style:te??void 0,className:"fixed z-[9999] bg-surface border border-theme rounded-2xl shadow-xl p-3 flex flex-col gap-2.5 overflow-y-auto overflow-x-hidden animate-in fade-in slide-in-from-top-1 duration-150",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-theme/60 pb-2",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-xs font-bold text-main",children:[e.jsx(se,{size:13,className:"text-primary-theme"}),e.jsx("span",{children:o==="zh"?"课堂倒计时设置":"Countdown Settings"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>p(!k),className:`p-1 rounded-md text-xs transition-colors cursor-pointer border border-theme ${k?"text-primary-theme bg-surface":"text-muted bg-surface/50"}`,title:k?o==="zh"?"提示音已开启":"Sound On":o==="zh"?"提示音已静音":"Muted",children:k?e.jsx(ce,{size:12}):e.jsx(de,{size:12})}),e.jsx("button",{type:"button",onClick:()=>{y(!0),$(!1)},className:"p-1 rounded-md text-xs text-muted hover:text-main bg-surface hover:bg-surface-secondary transition-colors cursor-pointer border border-theme",title:o==="zh"?"大屏全屏投放":"Projector Mode",children:e.jsx(be,{size:12})})]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-1 text-[11px]",children:[e.jsx("span",{className:"text-muted font-medium",children:o==="zh"?"当前任务:":"Task:"}),e.jsx("div",{className:"flex items-center gap-1",children:e.jsx("select",{value:n.label,onChange:t=>l({...n,label:t.target.value}),className:"px-2 py-0.5 rounded-lg bg-surface border border-theme text-xs font-semibold text-main outline-none cursor-pointer",children:je.map(t=>e.jsx("option",{value:t,children:t},t))})})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("span",{className:"text-[10px] text-muted font-semibold uppercase tracking-wider",children:o==="zh"?"快捷预设":"Presets"}),e.jsx("div",{className:"grid grid-cols-3 gap-1",children:me.slice(0,6).map(t=>e.jsxs("button",{type:"button",onClick:()=>{T(t.duration,t.label),$(!1)},className:`px-1.5 py-1 rounded-lg text-[10px] font-bold transition-all cursor-pointer border flex items-center justify-center gap-1 ${n.totalDuration===t.duration&&n.isRunning?"bg-primary-theme text-white border-primary-theme shadow-2xs":"bg-surface hover:bg-surface-secondary text-main border-theme"}`,title:t.label,children:[e.jsx("span",{children:t.icon||"⏱️"}),e.jsxs("span",{children:[t.duration/60,"m"]})]},t.id))})]}),e.jsxs("div",{className:"flex items-center justify-between gap-1 pt-1.5 border-t border-theme/60",children:[e.jsxs("button",{type:"button",id:"classroom-countdown-header-reset-btn",onClick:D,className:"px-2 py-1 rounded-lg bg-surface hover:bg-surface-secondary border border-theme text-xs font-semibold text-muted hover:text-main transition-colors flex items-center gap-1 cursor-pointer",children:[e.jsx(le,{size:11}),e.jsx("span",{children:o==="zh"?"重置":"Reset"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>j(-60),disabled:n.timeRemaining<=60,className:"px-2 py-1 rounded-lg bg-surface hover:bg-surface-secondary border border-theme text-xs font-bold text-muted hover:text-main disabled:opacity-40 transition-colors cursor-pointer",children:"-1m"}),e.jsx("button",{type:"button",onClick:()=>j(60),className:"px-2 py-1 rounded-lg bg-surface hover:bg-surface-secondary border border-theme text-xs font-bold text-muted hover:text-main transition-colors cursor-pointer",children:"+1m"}),e.jsx("button",{type:"button",onClick:()=>j(300),className:"px-2 py-1 rounded-lg bg-surface hover:bg-surface-secondary border border-theme text-xs font-bold text-primary-theme hover:bg-primary-theme/10 transition-colors cursor-pointer",children:"+5m"})]})]})]}),document.body),ue()]}):e.jsxs("div",{id:"classroom-countdown-widget",className:`bg-surface-secondary border border-theme rounded-2xl p-3.5 flex flex-col gap-2.5 shadow-sm transition-all ${O}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1 select-none",children:[e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx("span",{className:"p-1 rounded-lg bg-primary-theme/10 text-primary-theme shrink-0",children:e.jsx(se,{size:13,className:n.isRunning?"animate-spin":"",style:{animationDuration:"6s"}})}),e.jsxs("div",{className:"flex flex-col min-w-0",children:[e.jsx("span",{className:"text-xs font-black uppercase tracking-wider text-main truncate flex items-center gap-1",children:o==="zh"?"课堂倒计时":"Classroom Countdown"}),e.jsxs("div",{className:"flex items-center gap-1 text-[10px] text-muted",children:[e.jsx(ye,{size:9,className:n.isRunning?"text-emerald-500 animate-pulse":"text-muted"}),e.jsx("span",{children:n.isRunning?o==="zh"?`实时广播中 (${C}人)`:`Broadcasting (${C})`:o==="zh"?"就绪":"Ready"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsx("button",{type:"button",onClick:()=>p(!k),className:`p-1 rounded-md text-xs transition-colors cursor-pointer border border-theme ${k?"text-primary-theme bg-surface":"text-muted bg-surface/50"}`,title:k?o==="zh"?"提示音已开启":"Sound On":o==="zh"?"提示音已静音":"Muted",children:k?e.jsx(ce,{size:12}):e.jsx(de,{size:12})}),e.jsx("button",{type:"button",onClick:()=>y(!0),className:"p-1 rounded-md text-xs text-muted hover:text-main bg-surface hover:bg-surface-secondary transition-colors cursor-pointer border border-theme",title:o==="zh"?"展台大屏全屏投放":"Projector Mode",children:e.jsx(be,{size:12})})]})]}),e.jsxs("div",{className:"relative",children:[K?e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("input",{type:"text",value:Q,onChange:t=>R(t.target.value),placeholder:"输入任务名称...",className:"flex-1 px-2 py-0.5 text-xs bg-surface border border-theme rounded-md text-main focus:outline-hidden focus:ring-1 focus:ring-primary-theme",autoFocus:!0}),e.jsx("button",{type:"button",onClick:()=>{Q.trim()&&l({...n,label:Q.trim()}),F(!1)},className:"p-1 rounded bg-primary-theme text-white text-xs cursor-pointer",children:e.jsx(fe,{size:11})})]}):e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsxs("button",{type:"button",onClick:()=>G(!W),className:"flex items-center gap-1 text-[11px] font-semibold text-muted hover:text-main px-1.5 py-0.5 rounded-md hover:bg-surface transition-colors cursor-pointer border border-transparent hover:border-theme truncate",title:"切换任务类型",children:[e.jsx(Te,{size:10,className:"shrink-0 text-primary-theme"}),e.jsx("span",{className:"truncate",children:n.label}),e.jsx(pe,{size:10,className:"shrink-0 opacity-60"})]}),e.jsx("button",{type:"button",onClick:()=>{R(n.label),F(!0)},className:"text-[10px] text-muted hover:text-primary-theme underline cursor-pointer shrink-0",children:o==="zh"?"自定义":"Custom"})]}),W&&e.jsx("div",{className:"absolute left-0 top-full mt-1 w-full bg-surface border border-theme rounded-xl shadow-lg p-1.5 z-30 flex flex-col gap-0.5",children:je.map(t=>e.jsxs("button",{type:"button",onClick:()=>{l({...n,label:t}),G(!1)},className:`text-left px-2 py-1 text-xs rounded-lg transition-colors cursor-pointer flex items-center justify-between ${n.label===t?"bg-primary-theme/10 text-primary-theme font-bold":"text-main hover:bg-surface-secondary"}`,children:[e.jsx("span",{children:t}),n.label===t&&e.jsx(fe,{size:10})]},t))})]}),e.jsxs("div",{className:"flex flex-col items-center justify-center p-3 bg-surface border border-theme rounded-xl relative overflow-hidden",children:[e.jsx("div",{className:"absolute top-0 left-0 right-0 h-1 bg-surface-secondary overflow-hidden",children:e.jsx("div",{className:`h-full transition-all duration-500 ${ae}`,style:{width:`${E}%`}})}),e.jsx("div",{id:"classroom-countdown-digits",className:`text-3xl font-black font-mono tracking-widest transition-colors ${M?"animate-pulse text-rose-500":oe}`,children:f(n.timeRemaining)}),e.jsx("span",{className:"text-[10px] font-semibold text-muted mt-0.5",children:n.timeRemaining===0?o==="zh"?"⏰ 时间到!建议点评总结":"⏰ Time is up!":`${o==="zh"?"总设时长":"Total"}: ${f(n.totalDuration)}`})]}),e.jsxs("div",{className:"flex items-center gap-1.5 w-full",children:[n.isRunning?e.jsxs("button",{type:"button",id:"classroom-countdown-pause-btn",onClick:L,className:"flex-1 py-1.5 px-3 rounded-xl bg-amber-700 hover:bg-amber-800 text-white text-xs font-bold transition-all shadow-sm flex items-center justify-center gap-1.5 cursor-pointer",children:[e.jsx(ie,{size:12}),e.jsx("span",{children:o==="zh"?"暂停计时":"Pause"})]}):n.isPaused?e.jsxs("button",{type:"button",id:"classroom-countdown-resume-btn",onClick:_,className:"flex-1 py-1.5 px-3 rounded-xl bg-emerald-600 hover:bg-emerald-700 text-white text-xs font-bold transition-all shadow-sm flex items-center justify-center gap-1.5 cursor-pointer",children:[e.jsx(q,{size:12}),e.jsx("span",{children:o==="zh"?"继续计时":"Resume"})]}):e.jsxs("button",{type:"button",id:"classroom-countdown-start-btn",onClick:()=>T(n.totalDuration||300),className:"flex-1 py-1.5 px-3 rounded-xl bg-primary-theme hover:opacity-90 text-white text-xs font-bold transition-all shadow-sm flex items-center justify-center gap-1.5 cursor-pointer",children:[e.jsx(q,{size:12}),e.jsx("span",{children:o==="zh"?"开始倒计时":"Start"})]}),e.jsxs("button",{type:"button",id:"classroom-countdown-reset-btn",onClick:D,className:"p-1.5 px-2.5 rounded-xl bg-surface hover:bg-surface-secondary border border-theme text-xs font-bold text-muted hover:text-main transition-colors flex items-center justify-center gap-1 cursor-pointer",title:o==="zh"?"重置计时":"Reset",children:[e.jsx(le,{size:12}),e.jsx("span",{className:"sr-only",children:"重置"})]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-1 pt-1 border-t border-theme/60",children:[e.jsx("span",{className:"text-[10px] text-muted font-medium",children:o==="zh"?"快速调整:":"Adjust:"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>j(-60),disabled:n.timeRemaining<=60,className:"px-1.5 py-0.5 rounded-md bg-surface hover:bg-surface-secondary border border-theme text-[11px] font-bold text-muted hover:text-main disabled:opacity-40 transition-colors cursor-pointer",title:"减去1分钟",children:"-1m"}),e.jsx("button",{type:"button",onClick:()=>j(60),className:"px-1.5 py-0.5 rounded-md bg-surface hover:bg-surface-secondary border border-theme text-[11px] font-bold text-muted hover:text-main transition-colors cursor-pointer",title:"增加1分钟",children:"+1m"}),e.jsx("button",{type:"button",onClick:()=>j(300),className:"px-1.5 py-0.5 rounded-md bg-surface hover:bg-surface-secondary border border-theme text-[11px] font-bold text-primary-theme hover:bg-primary-theme/10 transition-colors cursor-pointer",title:"增加5分钟",children:"+5m"})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 pt-1",children:[e.jsx("span",{className:"text-[10px] text-muted font-semibold uppercase tracking-wider",children:o==="zh"?"预设时长":"Presets"}),e.jsx("div",{className:"flex flex-wrap gap-1",children:me.map(t=>e.jsxs("button",{type:"button",onClick:()=>T(t.duration,t.label),className:`px-1.5 py-0.5 rounded-lg text-[10px] font-bold transition-all cursor-pointer border ${n.totalDuration===t.duration&&n.isRunning?"bg-primary-theme text-white border-primary-theme":"bg-surface hover:bg-surface-secondary text-main border-theme"}`,title:t.label,children:[e.jsx("span",{children:t.icon||"⏱️"})," ",t.duration/60,"m"]},t.id))})]}),e.jsx(xe,{slot:"classroom.countdown.action",slotProps:{countdown:n,onStart:T,onPause:L,onReset:D,onAddTime:j,lang:o}}),e.jsx(xe,{slot:"classroom.countdown.widget",slotProps:{countdown:n,lang:o}}),ue()]})}export{Je as C,Ke as T};
@@ -1 +1 @@
1
- import{j as e}from"./vendor-react-DHoBZpn2.js";import{L as o}from"./LazyCourseware-DNn0O8lA.js";import{aY as a,k as x,X as c,z as d}from"./vendor-icons-DLOPlM4i.js";import{M as m}from"./index-DuxQtTr9.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function g({vfsNodes:r,currentVfsParent:n,setCurrentVfsParent:t,cloudDrivePreviewNode:l,setCloudDrivePreviewNode:i}){return e.jsxs("div",{className:"flex-1 flex overflow-hidden min-h-0",children:[e.jsxs("div",{className:"w-64 border-r border-gray-100 flex flex-col bg-gray-50 shrink-0",children:[e.jsx("div",{className:"p-3 border-b border-gray-200 flex items-center gap-2",children:e.jsxs("button",{onClick:()=>{t(null),i(null)},className:`text-sm font-medium w-full text-left flex items-center gap-2 p-2 rounded cursor-pointer ${n===null?"bg-indigo-100 text-indigo-800 font-bold":"text-gray-600 hover:bg-gray-200"}`,children:[e.jsx(a,{size:16})," Data Root"]})}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-2",children:[n&&e.jsxs("button",{onClick:()=>t(null),className:"flex items-center gap-2 p-2 text-xs text-indigo-600 w-full hover:bg-gray-200 rounded mb-2 font-medium cursor-pointer",children:[e.jsx(x,{className:"rotate-180",size:14})," Back to Root"]}),e.jsx("div",{className:"text-xs uppercase font-semibold text-gray-400 px-2 py-1 mb-1",children:"Current Path Nodes"}),r.filter(s=>s.type==="dir").map(s=>e.jsxs("button",{onClick:()=>{t(s.id),i(null)},className:"w-full text-left p-2 rounded text-sm text-gray-700 hover:bg-gray-200 flex items-center gap-2 group mb-1 cursor-pointer",children:[e.jsx(a,{size:14,className:"text-indigo-400 group-hover:text-indigo-600"}),e.jsx("span",{className:"truncate",children:s.name})]},s.id))]})]}),e.jsx("div",{className:"flex-1 flex flex-col bg-white overflow-hidden min-w-0",children:l?e.jsxs("div",{className:"flex-1 flex flex-col h-full min-h-0",children:[e.jsxs("div",{className:"p-3 border-b border-gray-100 bg-gray-50 flex items-center gap-2 shrink-0",children:[e.jsx("button",{onClick:()=>i(null),className:"text-gray-500 hover:text-gray-700 cursor-pointer",children:e.jsx(c,{size:16})}),e.jsxs("span",{className:"text-sm font-medium text-gray-700",children:["Previewing: ",l.name]})]}),l.name.endsWith(".html")||l.name.endsWith(".htm")||l.content?.includes("<html")?e.jsx("div",{className:"flex-1 relative bg-gray-50",children:e.jsx(o,{coursewareId:l.id})}):e.jsx("div",{className:"flex-1 overflow-y-auto p-6 bg-white prose prose-sm max-w-none",children:e.jsx(m,{children:l.content})})]}):e.jsx("div",{className:"flex-1 p-6 overflow-y-auto",children:e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:[r.length===0&&e.jsx("div",{className:"col-span-full h-32 flex items-center justify-center text-sm text-gray-400 italic",children:"This directory is empty."}),r.map(s=>e.jsxs("div",{onClick:()=>{s.type==="dir"?t(s.id):i({id:s.id,name:s.name,content:s.content||"*(Empty file)*"})},className:"border border-gray-200 hover:border-indigo-300 hover:shadow-md cursor-pointer rounded-xl p-4 flex flex-col gap-3 transition-all bg-white",children:[e.jsx("div",{className:"p-3 rounded-xl w-12 h-12 flex items-center justify-center shrink-0 shadow-sm bg-gray-50 border border-gray-100",children:s.type==="dir"?e.jsx(a,{size:24,className:"text-indigo-500"}):e.jsx(d,{size:24,className:"text-gray-500"})}),e.jsx("div",{className:"text-sm font-medium text-gray-800 break-words",children:s.name})]},s.id))]})})})]})}function v(r){return r.isOpen?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("div",{className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-5xl h-[85vh] 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 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(a,{size:20,className:"text-indigo-600"}),e.jsx("h2",{className:"font-semibold text-gray-800 text-lg",children:"Cloud Course Resource Browser"})]}),e.jsx("button",{onClick:r.onClose,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors cursor-pointer",children:"×"})]}),e.jsx(g,{...r})]})}):null}export{v as CloudDriveModal,g as CloudDrivePanel};
1
+ import{j as e}from"./vendor-react-DHoBZpn2.js";import{L as o}from"./LazyCourseware-zONqinCM.js";import{a$ as a,k as x,X as c,z as d}from"./vendor-icons-CaXLq01o.js";import{M as m}from"./index-Bc9003lB.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function g({vfsNodes:r,currentVfsParent:n,setCurrentVfsParent:t,cloudDrivePreviewNode:l,setCloudDrivePreviewNode:i}){return e.jsxs("div",{className:"flex-1 flex overflow-hidden min-h-0",children:[e.jsxs("div",{className:"w-64 border-r border-gray-100 flex flex-col bg-gray-50 shrink-0",children:[e.jsx("div",{className:"p-3 border-b border-gray-200 flex items-center gap-2",children:e.jsxs("button",{onClick:()=>{t(null),i(null)},className:`text-sm font-medium w-full text-left flex items-center gap-2 p-2 rounded cursor-pointer ${n===null?"bg-indigo-100 text-indigo-800 font-bold":"text-gray-600 hover:bg-gray-200"}`,children:[e.jsx(a,{size:16})," Data Root"]})}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-2",children:[n&&e.jsxs("button",{onClick:()=>t(null),className:"flex items-center gap-2 p-2 text-xs text-indigo-600 w-full hover:bg-gray-200 rounded mb-2 font-medium cursor-pointer",children:[e.jsx(x,{className:"rotate-180",size:14})," Back to Root"]}),e.jsx("div",{className:"text-xs uppercase font-semibold text-gray-400 px-2 py-1 mb-1",children:"Current Path Nodes"}),r.filter(s=>s.type==="dir").map(s=>e.jsxs("button",{onClick:()=>{t(s.id),i(null)},className:"w-full text-left p-2 rounded text-sm text-gray-700 hover:bg-gray-200 flex items-center gap-2 group mb-1 cursor-pointer",children:[e.jsx(a,{size:14,className:"text-indigo-400 group-hover:text-indigo-600"}),e.jsx("span",{className:"truncate",children:s.name})]},s.id))]})]}),e.jsx("div",{className:"flex-1 flex flex-col bg-white overflow-hidden min-w-0",children:l?e.jsxs("div",{className:"flex-1 flex flex-col h-full min-h-0",children:[e.jsxs("div",{className:"p-3 border-b border-gray-100 bg-gray-50 flex items-center gap-2 shrink-0",children:[e.jsx("button",{onClick:()=>i(null),className:"text-gray-500 hover:text-gray-700 cursor-pointer",children:e.jsx(c,{size:16})}),e.jsxs("span",{className:"text-sm font-medium text-gray-700",children:["Previewing: ",l.name]})]}),l.name.endsWith(".html")||l.name.endsWith(".htm")||l.content?.includes("<html")?e.jsx("div",{className:"flex-1 relative bg-gray-50",children:e.jsx(o,{coursewareId:l.id})}):e.jsx("div",{className:"flex-1 overflow-y-auto p-6 bg-white prose prose-sm max-w-none",children:e.jsx(m,{children:l.content})})]}):e.jsx("div",{className:"flex-1 p-6 overflow-y-auto",children:e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:[r.length===0&&e.jsx("div",{className:"col-span-full h-32 flex items-center justify-center text-sm text-gray-400 italic",children:"This directory is empty."}),r.map(s=>e.jsxs("div",{onClick:()=>{s.type==="dir"?t(s.id):i({id:s.id,name:s.name,content:s.content||"*(Empty file)*"})},className:"border border-gray-200 hover:border-indigo-300 hover:shadow-md cursor-pointer rounded-xl p-4 flex flex-col gap-3 transition-all bg-white",children:[e.jsx("div",{className:"p-3 rounded-xl w-12 h-12 flex items-center justify-center shrink-0 shadow-sm bg-gray-50 border border-gray-100",children:s.type==="dir"?e.jsx(a,{size:24,className:"text-indigo-500"}):e.jsx(d,{size:24,className:"text-gray-500"})}),e.jsx("div",{className:"text-sm font-medium text-gray-800 break-words",children:s.name})]},s.id))]})})})]})}function v(r){return r.isOpen?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("div",{className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-5xl h-[85vh] 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 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(a,{size:20,className:"text-indigo-600"}),e.jsx("h2",{className:"font-semibold text-gray-800 text-lg",children:"Cloud Course Resource Browser"})]}),e.jsx("button",{onClick:r.onClose,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors cursor-pointer",children:"×"})]}),e.jsx(g,{...r})]})}):null}export{v as CloudDriveModal,g as CloudDrivePanel};
@@ -1 +1 @@
1
- import{r as l,j as e}from"./vendor-react-DHoBZpn2.js";import{a0 as Ae,E as M,c as Te}from"./index-DuxQtTr9.js";import{ap as fe,an as Le,bv as J,bu as Pe,af as Me,X as te,a0 as Re,ad as be,U as je,V as Oe,ag as Fe,c as ye,ah as Ue,C as Be,a2 as Je}from"./vendor-icons-DLOPlM4i.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function qe({computerLabs:h,onRefresh:y,lang:n,classes:b}){const[q,w]=l.useState(!1),[R,V]=l.useState(null),[G,H]=l.useState(""),[N,K]=l.useState(5),[S,Y]=l.useState(6),[O,p]=l.useState(""),[se,ae]=l.useState(!1),ne="openlearn_computer_lab_selected",X="openlearn_computer_lab_selected_class",[A,re]=l.useState(()=>{try{const t=localStorage.getItem(ne);if(t&&h.some(s=>s.id===t))return t}catch{}return h.length>0?h[0].id:null}),o=h.find(t=>t.id===(A||h[0]?.id)),[ve,ie]=l.useState([]),[d,F]=l.useState(()=>{const t=o??h[0];if(!t)return null;const s=b||[];try{const a=localStorage.getItem(X),i=a?s.find(c=>c.id===a):void 0;if(i&&i.lab_id===t.id)return i.id}catch{}const r=s.find(a=>a.lab_id===t.id);return r?r.id:null}),[E,oe]=l.useState([]),[g,C]=l.useState([]),[le,de]=l.useState(!1),[Q,ce]=l.useState(!1),[xe,W]=l.useState(""),[Z,k]=l.useState(!1),[f,v]=l.useState(null),[we,$]=l.useState(null),[x,T]=l.useState(null),[I,L]=l.useState(null);l.useEffect(()=>{b&&b.length>0?ie(b):fetch("/api/classes?pageSize=all").then(t=>t.ok?t.json():{data:[]}).then(t=>{const s=Ae(t);(s.length>0||Array.isArray(t?.data))&&ie(s)}).catch(t=>console.error("Failed to fetch classes in ComputerLabManager:",t))},[b]);const _=b&&b.length>0?b:ve,ue=l.useMemo(()=>o?_.filter(t=>t.lab_id===o.id):[],[_,o]);l.useEffect(()=>{if(!o)return;if(d){_.find(s=>s.id===d);return}try{const s=localStorage.getItem(X),r=s?_.find(a=>a.id===s):void 0;if(r&&r.lab_id===o.id){F(r.id);return}}catch{}const t=_.find(s=>s.lab_id===o.id);t&&F(t.id)},[o?.id,_]),l.useEffect(()=>{try{A&&localStorage.setItem(ne,A)}catch{}},[A]),l.useEffect(()=>{try{d&&localStorage.setItem(X,d)}catch{}},[d]);const me=l.useCallback(async(t,s)=>{de(!0),p(""),v(null),$(null);try{const[r,a]=await Promise.all([fetch(`/api/classes/${t}/seats`),fetch(`/api/classes/${t}/students`)]);let i=[];if(a.ok&&(i=await a.json(),oe(i)),r.ok){const u=(await r.json()).seats||[],D=new Map(i.map(j=>[j.id,j])),U=u.map(j=>{const B=D.get(j.student_id);return{...j,student_name:j.student_name||B?.name||"",student_number:j.student_number||B?.student_number||""}});C(U)}k(!1)}catch(r){console.error("Error loading seating:",r),p(r.message||"Failed to load class seating data")}finally{de(!1)}},[]);l.useEffect(()=>{d?me(d,o?.id):(oe([]),C([]),k(!1),v(null),$(null))},[d,me]);const ee=l.useMemo(()=>{const t=new Map;for(const s of g)t.set(`${s.row_idx}_${s.col_idx}`,s);return t},[g]),he=l.useMemo(()=>new Set(g.map(t=>t.student_id)),[g]),z=l.useMemo(()=>E.filter(t=>!he.has(t.id)).sort((t,s)=>String(t.student_number??t.name??"").localeCompare(String(s.student_number??s.name??""),"zh-Hans-CN",{numeric:!0})),[E,he]),pe=(t,s,r)=>{const a=g.find(u=>u.row_idx===s.row&&u.col_idx===s.col),i=!!r&&!!a&&a.student_id!==t.id;let c=g.filter(u=>!(u.row_idx===s.row&&u.col_idx===s.col)&&u.student_id!==t.id);i&&r&&(c=c.filter(u=>!(u.row_idx===r.row&&u.col_idx===r.col)),c=[...c,{...a,row_idx:r.row,col_idx:r.col}]),c=[...c,{student_id:t.id,row_idx:s.row,col_idx:s.col,student_name:t.name,student_number:t.student_number}],C(c),k(!0)},Ne=(t,s)=>{if(!d||!o)return;const r=ee.get(`${t}_${s}`);if(f){pe(f,{row:t,col:s},we),v(null),$(null);return}if(r){const a=E.find(i=>i.id===r.student_id)||{id:r.student_id,name:r.student_name||"Student",student_number:r.student_number||""};v(a),$({row:t,col:s})}},Se=(t,s,r)=>{t.stopPropagation(),C(a=>a.filter(i=>!(i.row_idx===s&&i.col_idx===r))),k(!0)},_e=()=>{if(!o||z.length===0)return;const t=[];for(let a=0;a<o.rows;a++)for(let i=0;i<o.cols;i++)ee.has(`${a}_${i}`)||t.push([a,i]);if(t.length===0)return;const r=z.slice(0,t.length).map((a,i)=>{const[c,u]=t[i];return{student_id:a.id,row_idx:c,col_idx:u,student_name:a.name,student_number:a.student_number}});C(a=>[...a,...r]),k(!0),v(null)},ze=()=>{g.length!==0&&confirm(n==="zh"?"确定要清空当前班级在该机房的所有机位排座吗?":"Are you sure you want to clear all seat assignments for this class in this lab?")&&(C([]),k(!0),v(null))},Ce=async()=>{if(!(!d||!o))try{ce(!0),p(""),W("");const t=await fetch(`/api/classes/${d}/seats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({lab_id:o.id,seats:g.map(s=>({student_id:s.student_id,row_idx:s.row_idx,col_idx:s.col_idx}))})});if(t.ok)k(!1),W(n==="zh"?"统一机房排座已成功持久化至系统 student_seats 数据表!":"Seating assignments saved to system student_seats table successfully!"),y(),setTimeout(()=>W(""),4e3);else{const s=await t.json();p(s.error||"Failed to save seats")}}catch(t){p(t.message||"Network error saving seats")}finally{ce(!1)}},ke=()=>{H(""),K(5),Y(6),p(""),V(null),w(!0)},$e=t=>{H(t.room_number),K(t.rows),Y(t.cols),p(""),V(t.id),w(!0)},Ee=async t=>{if(t.preventDefault(),!G.trim()){p(n==="zh"?"请输入机房编号/名称":"Please enter room name or number");return}if(N<=0||N>15){p(n==="zh"?"行数应在 1 至 15 之间":"Rows should be between 1 and 15");return}if(S<=0||S>15){p(n==="zh"?"列数应在 1 至 15 之间":"Columns should be between 1 and 15");return}try{ae(!0),p("");const s=R?`/api/labs/${R}`:"/api/labs",a=await fetch(s,{method:R?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({room_number:G.trim(),rows:N,cols:S})});if(a.ok)y(),w(!1),V(null);else{const i=await a.json();p(i.error||"Server error saving lab")}}catch(s){p(s.message||"Network error")}finally{ae(!1)}},De=async t=>{if(confirm(n==="zh"?"确定要删除该机房吗?删除后对应的座位分配也会被重置。":"Are you sure you want to delete this lab? Seat mappings will be cleared."))try{(await fetch(`/api/labs/${t}`,{method:"DELETE"})).ok&&(y(),A===t&&re(null))}catch(s){console.error(s)}};return e.jsxs("div",{className:"flex-1 flex flex-col h-full overflow-hidden",id:"lab_manager_root",children:[e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between pb-4 border-b border-gray-200 gap-4 shrink-0",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-xl font-bold text-gray-800 flex items-center gap-2",children:[e.jsx(fe,{className:"text-indigo-600",size:24}),n==="zh"?"统一机房座位管理":"Unified Computer Lab Seating"]}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:n==="zh"?"维护物理机房规格及其行列排列规则,并直接根据班级信息读取并编排系统中已存的统一机房座位数据(student_seats 表)。":"Maintain physical lab layouts and manage unified student seat allocations directly synced with existing system data tables."})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("button",{onClick:ke,className:"bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-xl text-xs font-semibold flex items-center gap-1.5 shadow-sm transition-all focus:ring-2 focus:ring-indigo-500 cursor-pointer",children:[e.jsx(Le,{size:14}),n==="zh"?"新增机房规则":"New Lab Config"]}),e.jsx(M,{slot:"computer_lab.toolbar.action",slotProps:{activeLab:o,computerLabs:h,onRefresh:y,lang:n}})]})]}),e.jsxs("div",{className:"flex-1 min-h-0 grid grid-cols-1 lg:grid-cols-12 gap-6 pt-5 overflow-hidden",children:[e.jsxs("div",{className:"lg:col-span-4 flex flex-col min-h-0 bg-white border border-gray-200 rounded-2xl shadow-xs overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 bg-gray-50 flex justify-between items-center shrink-0",children:[e.jsx("span",{className:"text-xs font-bold text-gray-700 uppercase tracking-wider block",children:n==="zh"?"机房列表":"Computer Labs"}),e.jsx("span",{className:"bg-gray-200 text-gray-700 font-bold px-2 py-0.5 rounded-full text-xs",children:h.length})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-3",children:h.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center p-8 text-center text-gray-400 h-full",children:[e.jsx(fe,{size:40,className:"mb-2 opacity-30"}),e.jsx("p",{className:"text-xs font-medium",children:n==="zh"?"暂无机房编号规则":"No Computer Labs configured yet."}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:n==="zh"?"点击右上角按钮添加首个机房规格。":"Click the button above to add your first computer room."})]}):h.map(t=>{const s=o?.id===t.id,r=_.filter(a=>a.lab_id===t.id);return e.jsxs("div",{onClick:()=>{re(t.id),w(!1)},className:`p-3 rounded-xl border transition-all cursor-pointer flex flex-col gap-2 group ${s?"border-indigo-300 bg-indigo-50/60 shadow-xs ring-1 ring-indigo-200":"border-gray-150 hover:border-gray-300 hover:bg-gray-50"}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${s?"bg-indigo-600 text-white":"bg-gray-100 text-gray-500 group-hover:bg-gray-200"}`,children:e.jsx(J,{size:16})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-bold text-gray-800 flex items-center gap-1.5",children:t.room_number}),e.jsxs("div",{className:"text-xs text-gray-400 font-mono mt-0.5",children:[t.rows," ",n==="zh"?"行":"Rows"," × ",t.cols," ",n==="zh"?"列":"Cols",e.jsx("span",{className:"mx-1.5",children:"•"}),t.rows*t.cols," ",n==="zh"?"个机位":"Seats"]})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity",children:[e.jsx("button",{onClick:a=>{a.stopPropagation(),$e(t)},className:"p-1 text-gray-500 hover:text-indigo-600 hover:bg-white rounded transition-colors",title:n==="zh"?"编辑规则":"Edit Rule",children:e.jsx(Pe,{size:13})}),e.jsx("button",{onClick:a=>{a.stopPropagation(),De(t.id)},className:"p-1 text-gray-500 hover:text-rose-600 hover:bg-white rounded transition-colors",title:n==="zh"?"删除机房间":"Delete Lab",children:e.jsx(Me,{size:14})})]})]}),r.length>0&&e.jsxs("div",{className:"flex items-center gap-1 flex-wrap pt-1 border-t border-gray-100/80",children:[e.jsx("span",{className:"text-[10px] text-gray-400 font-medium",children:n==="zh"?"绑定班级:":"Bound:"}),r.map(a=>e.jsx("span",{className:"text-[10px] font-semibold bg-indigo-100/70 text-indigo-700 px-1.5 py-0.5 rounded-md",children:a.name},a.id))]})]},t.id)})})]}),e.jsx("div",{className:"lg:col-span-8 flex flex-col min-h-0 bg-white border border-gray-200 rounded-2xl shadow-xs overflow-hidden",children:q?e.jsxs("form",{onSubmit:Ee,className:"flex-1 flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 bg-gray-50 font-bold text-xs text-gray-700 uppercase tracking-wider shrink-0 flex items-center justify-between",children:[e.jsx("span",{children:R?n==="zh"?"编辑机房规则":"Edit Lab Seating":n==="zh"?"创建全新上机机房":"Create Computer Lab"}),e.jsx("button",{type:"button",onClick:()=>w(!1),className:"text-gray-400 hover:text-gray-600",children:e.jsx(te,{size:16})})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-4",children:[O&&e.jsxs("div",{className:"p-3 bg-red-50 border border-red-200 text-red-700 text-xs rounded-xl flex items-center gap-1.5",children:[e.jsx(Re,{size:14}),e.jsx("span",{children:O})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"机房编号 / 场所名称 *":"Lab Name / Number *"}),e.jsx("input",{type:"text",value:G,onChange:t=>H(t.target.value),placeholder:n==="zh"?"例如:305综合机房、软创中心、Lab A":"e.g. Lab 404, Software Sandbox, Suite C",className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",maxLength:32,required:!0})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"排列行数 (Rows) *":"Rows Direction *"}),e.jsx("input",{type:"number",value:N,onChange:t=>K(Math.max(1,parseInt(t.target.value)||1)),min:1,max:15,className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",required:!0}),e.jsx("span",{className:"text-xs text-gray-400 block mt-0.5",children:n==="zh"?"上下方向机位数 (最大15行)":"Horizontal sets count (Max 15)"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"排列列数 (Columns) *":"Columns Direction *"}),e.jsx("input",{type:"number",value:S,onChange:t=>Y(Math.max(1,parseInt(t.target.value)||1)),min:1,max:15,className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",required:!0}),e.jsx("span",{className:"text-xs text-gray-400 block mt-0.5",children:n==="zh"?"左右方向机位数 (最大15列)":"Vertical sets count (Max 15)"})]})]}),e.jsxs("div",{className:"border border-dashed border-gray-200 bg-gray-50/50 p-4 rounded-xl",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider block mb-2",children:n==="zh"?"布局网格缩略结构":"Layout Aspect Schema"}),e.jsxs("div",{className:"flex flex-col gap-1 items-center justify-center p-3 bg-white rounded-lg border border-gray-100 min-h-[120px]",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[Array.from({length:Math.min(N,6)}).map((t,s)=>e.jsxs("div",{className:"flex gap-1 justify-center",children:[Array.from({length:Math.min(S,8)}).map((r,a)=>e.jsx("div",{className:"w-4 h-4 rounded bg-indigo-100 border border-indigo-200 shrink-0"},a)),S>8&&e.jsx("div",{className:"w-4 text-xs text-gray-400 flex items-center justify-center",children:"..."})]},s)),N>6&&e.jsx("div",{className:"text-xs text-center text-gray-400 mt-1",children:"..."})]}),e.jsxs("span",{className:"text-xs text-gray-450 mt-3 font-medium",children:["配置容量:",N," × ",S," = ",N*S," 座位"]})]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 shrink-0 flex items-center justify-end gap-2 bg-gray-50",children:[e.jsx("button",{type:"button",onClick:()=>w(!1),className:"px-4 py-2 text-xs font-semibold text-gray-500 hover:text-gray-700 bg-white hover:bg-gray-100 border border-gray-200 rounded-xl transition-all cursor-pointer",children:n==="zh"?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:se,className:"px-4 py-2 text-xs font-bold text-white bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 rounded-xl flex items-center gap-1 shadow-sm transition-all cursor-pointer",children:[e.jsx(be,{size:14}),e.jsx("span",{children:se?n==="zh"?"提交中...":"Saving...":n==="zh"?"提交保存":"Save Config"})]})]})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-3 border-b border-gray-100 bg-gray-50 flex flex-wrap items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs font-bold text-gray-700 uppercase tracking-wider flex items-center gap-1.5",children:[e.jsx(je,{size:14,className:"text-indigo-600"}),n==="zh"?"班级机位联动:":"Class Seating Link:"]}),e.jsxs("select",{value:d||"",onChange:t=>F(t.target.value?t.target.value:null),className:"text-xs font-semibold bg-white border border-gray-300 rounded-lg px-2.5 py-1.5 text-gray-700 focus:outline-none focus:ring-1 focus:ring-indigo-500 cursor-pointer shadow-2xs",children:[e.jsx("option",{value:"",children:n==="zh"?"📐 物理规格总览 (无班级)":"📐 Physical Blueprint (No Class)"}),_.map(t=>{const s=t.lab_id===o?.id;return e.jsxs("option",{value:t.id,children:[t.name," ",s?n==="zh"?"★ 已绑定此机房":"★ Bound":""]},t.id)})]})]}),d&&o&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:_e,disabled:z.length===0,className:"px-2.5 py-1.5 text-xs font-semibold bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 rounded-lg flex items-center gap-1 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",title:n==="zh"?"将未排座学生按学号依次填入空闲机位":"Auto assign unplaced students",children:[e.jsx(Oe,{size:13}),e.jsx("span",{children:n==="zh"?"一键排座":"Auto Fill"})]}),e.jsxs("button",{type:"button",onClick:ze,disabled:g.length===0,className:"px-2.5 py-1.5 text-xs font-semibold bg-gray-100 hover:bg-rose-50 text-gray-600 hover:text-rose-600 border border-gray-200 rounded-lg flex items-center gap-1 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",title:n==="zh"?"清空当前班级排座":"Clear Seating",children:[e.jsx(Fe,{size:13}),e.jsx("span",{children:n==="zh"?"清空":"Clear"})]}),e.jsxs("button",{type:"button",onClick:Ce,disabled:Q||!Z&&!o,className:`px-3 py-1.5 text-xs font-bold rounded-lg flex items-center gap-1.5 shadow-xs transition-all cursor-pointer ${Z?"bg-emerald-600 hover:bg-emerald-700 text-white animate-pulse":"bg-indigo-600 hover:bg-indigo-700 text-white disabled:opacity-60 disabled:cursor-not-allowed"}`,children:[Q?e.jsx(ye,{size:13,className:"animate-spin"}):e.jsx(Ue,{size:13}),e.jsx("span",{children:Q?n==="zh"?"保存中...":"Saving...":Z?n==="zh"?"保存排座 (已修改)":"Save (Modified)":n==="zh"?"已保存":"Saved"})]}),e.jsx(M,{slot:"computer_lab.seating.toolbar",slotProps:{labId:o.id,classId:d,assignedSeats:g,setAssignedSeats:C,lang:n}})]})]}),xe&&e.jsxs("div",{className:"bg-emerald-50 border-b border-emerald-200 text-emerald-800 text-xs px-4 py-2 flex items-center gap-1.5 animate-fadeIn",children:[e.jsx(be,{size:14,className:"text-emerald-600 shrink-0"}),e.jsx("span",{className:"font-medium",children:xe})]}),O&&e.jsxs("div",{className:"bg-red-50 border-b border-red-200 text-red-700 text-xs px-4 py-2 flex items-center gap-1.5",children:[e.jsx(Be,{size:14,className:"text-red-500 shrink-0"}),e.jsx("span",{children:O})]}),o?e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-slate-950 text-white overflow-hidden relative",children:[e.jsx("div",{className:"py-2.5 flex justify-center shrink-0 border-b border-slate-900 bg-slate-950/80 backdrop-blur-xs z-10",children:e.jsx("div",{className:"w-56 bg-slate-900 border border-slate-700 py-1 rounded text-center text-xs font-bold text-slate-300 uppercase tracking-widest select-none shadow-sm flex items-center justify-center gap-1.5",children:e.jsxs("span",{children:["📽️ ",n==="zh"?"讲台 / 教师主荧幕":"Classroom Stage / Screen"]})})}),e.jsx("div",{className:"flex-1 overflow-auto p-4 flex flex-col items-center",children:le?e.jsxs("div",{className:"flex flex-col items-center justify-center h-48 gap-2 text-slate-400",children:[e.jsx(ye,{size:24,className:"animate-spin text-indigo-400"}),e.jsx("span",{className:"text-xs",children:n==="zh"?"正在读取统一机房座位数据...":"Loading lab seating data..."})]}):e.jsx("div",{className:"flex flex-col gap-2.5 py-2 max-w-full",children:Array.from({length:o.rows}).map((t,s)=>e.jsxs("div",{className:"flex gap-2.5 justify-center items-center",children:[e.jsxs("span",{className:"text-xs font-bold font-mono text-slate-500 w-6 text-right select-none pr-0.5",children:["R",s+1]}),Array.from({length:o.cols}).map((r,a)=>{const i=ee.get(`${s}_${a}`),c=!!i,u=f&&(!c||i.student_id!==f.id),D=!!x?.from&&x.from.row===s&&x.from.col===a,U=!!x&&!!I&&I.row===s&&I.col===a&&!D,j=U&&c&&x?.type==="seat"&&i.student_id!==x.studentId,B=U&&(!c||x?.type==="pool");return e.jsx("div",{"data-seat-id":`${s}_${a}`,onClick:()=>Ne(s,a),draggable:!!d&&c,onDragStart:m=>{!d||!i||(T({type:"seat",studentId:i.student_id,from:{row:s,col:a}}),m.dataTransfer.setData("text/plain",JSON.stringify({type:"seat",studentId:i.student_id,from:{row:s,col:a}})),m.dataTransfer.effectAllowed="move")},onDragEnd:()=>{T(null),L(null)},onDragOver:m=>{!x||D||(m.preventDefault(),m.dataTransfer.dropEffect="move",L({row:s,col:a}))},onDragLeave:()=>{L(m=>m&&m.row===s&&m.col===a?null:m)},onDrop:m=>{if(m.preventDefault(),x&&!D){const ge=x.type==="pool"?z.find(P=>P.id===x.studentId)||E.find(P=>P.id===x.studentId):E.find(P=>P.id===x.studentId);ge&&(pe(ge,{row:s,col:a},x.from),v(null),$(null))}T(null),L(null)},className:`group relative rounded-xl flex flex-col items-center justify-center transition-all select-none shadow-sm ${d&&c?"cursor-grab":"cursor-pointer"} ${d?"w-20 h-14":"w-11 h-11"} ${c?"bg-slate-850 border border-indigo-500/70 hover:border-indigo-400 shadow-indigo-950/50":u?"bg-indigo-950/40 border border-dashed border-indigo-400 hover:bg-indigo-900/50 ring-1 ring-indigo-400/50 animate-pulse":"bg-slate-900 border border-slate-800 hover:border-slate-700 hover:bg-slate-850"}${j?" ring-2 ring-amber-400 border-amber-400 bg-amber-950/40":""}${B&&!j?" ring-2 ring-emerald-400 border-emerald-400 bg-emerald-950/40":""}${D?" opacity-40":""}`,children:c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"w-full h-full p-1.5 flex flex-col justify-between items-center text-center",children:[e.jsxs("div",{className:"flex items-center justify-between w-full px-0.5",children:[e.jsxs("span",{className:"text-[10px] font-mono text-indigo-300/80",children:[s+1,"-",a+1]}),d&&e.jsx("button",{type:"button",onClick:m=>Se(m,s,a),className:"opacity-0 group-hover:opacity-100 text-slate-400 hover:text-rose-400 p-0.5 rounded transition-opacity",title:n==="zh"?"移出此座位":"Unseat student",children:e.jsx(te,{size:11})})]}),e.jsx("div",{className:"font-bold text-xs text-white truncate max-w-[70px] leading-tight",children:i.student_name||"Student"}),e.jsx("div",{className:"text-[9px] font-mono text-slate-400 truncate max-w-[70px]",children:i.student_number||`ID:${i.student_id.slice(-4)}`}),e.jsx("div",{className:"w-full min-w-0",onClick:m=>m.stopPropagation(),children:e.jsx(M,{slot:"computer_lab.seat.overlay",slotProps:{labId:o.id,row:s,col:a,seat:i,isOccupied:!0}})})]}),e.jsxs("div",{className:"absolute bottom-16 bg-slate-900 text-white text-xs rounded-lg px-2.5 py-1.5 hidden group-hover:block whitespace-nowrap z-30 font-sans border border-indigo-700 shadow-2xl pointer-events-none",children:[e.jsx("div",{className:"font-bold text-indigo-300",children:i.student_name}),e.jsxs("div",{className:"text-[10px] text-slate-400 font-mono",children:[n==="zh"?"学号:":"No: ",i.student_number||i.student_id]}),e.jsx("div",{className:"text-[10px] text-slate-300 mt-0.5",children:n==="zh"?`第 ${s+1} 排,第 ${a+1} 列`:`Row ${s+1}, Col ${a+1}`})]})]}):e.jsxs(e.Fragment,{children:[e.jsx(J,{size:d?14:15,className:u?"text-indigo-400 animate-bounce":"text-slate-600 opacity-60"}),e.jsxs("span",{className:"text-[10px] font-mono text-slate-500 mt-0.5",children:[s+1,"-",a+1]}),e.jsx("div",{className:"absolute bottom-12 bg-slate-900 text-white text-xs rounded px-2 py-1 hidden group-hover:block whitespace-nowrap z-30 font-sans border border-slate-700 shadow-xl pointer-events-none",children:f?n==="zh"?`点击安排 [${f.name}] 到第 ${s+1} 排第 ${a+1} 列`:`Place [${f.name}] here`:n==="zh"?`第 ${s+1} 排第 ${a+1} 列 (空闲)`:`Row ${s+1} / Column ${a+1} (Empty)`})]})},a)})]},s))})}),d&&o&&!le&&e.jsx("div",{className:"shrink-0 px-4 pb-2",children:e.jsx(M,{slot:"computer_lab.seating.sidebar",slotProps:{labId:o.id,classId:d,assignedSeats:g,unassignedStudents:z}})}),d?e.jsxs("div",{className:"border-t border-slate-900 bg-slate-900/90 p-3 shrink-0 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"font-bold text-slate-300 flex items-center gap-1.5",children:[e.jsx(je,{size:13,className:"text-indigo-400"}),n==="zh"?"待排座学生池:":"Unassigned Students Pool:"]}),e.jsxs("span",{className:"text-[11px] font-mono text-slate-400",children:[z.length," ",n==="zh"?"人未排":"unplaced"," / ",E.length," ",n==="zh"?"人总计":"total"]}),f&&e.jsxs("span",{className:"bg-indigo-900/80 text-indigo-300 border border-indigo-700 text-[11px] px-2 py-0.5 rounded-full flex items-center gap-1 animate-pulse",children:[e.jsx("span",{children:n==="zh"?`当前选择: ${f.name} (点击上方空位落座)`:`Selected: ${f.name} (click empty seat)`}),e.jsx("button",{type:"button",onClick:()=>{v(null),$(null)},className:"hover:text-white",children:e.jsx(te,{size:10})})]})]}),e.jsxs("div",{className:"text-[11px] font-mono text-slate-400",children:[n==="zh"?"机房已占:":"Occupied: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:g.length})," /"," ",o.rows*o.cols]})]}),z.length===0?e.jsxs("div",{className:"text-xs text-slate-500 py-1 italic flex items-center gap-1",children:[e.jsx(Je,{size:13,className:"text-emerald-400"}),e.jsx("span",{children:n==="zh"?"当前班级全部学生均已成功分配机位!":"All students in this class have been assigned seats!"})]}):e.jsx("div",{className:"flex items-center gap-1.5 overflow-x-auto py-1 max-h-16 pr-2",children:z.map(t=>{const s=f?.id===t.id,r=x?.type==="pool"&&x.studentId===t.id;return e.jsxs("div",{className:"shrink-0 flex items-center gap-1","data-unassigned-id":t.id,children:[e.jsxs("button",{type:"button",draggable:!0,onDragStart:a=>{T({type:"pool",studentId:t.id}),a.dataTransfer.setData("text/plain",JSON.stringify({type:"pool",studentId:t.id})),a.dataTransfer.effectAllowed="move"},onDragEnd:()=>{T(null),L(null)},onClick:()=>{v(s?null:t),$(null)},className:`px-2.5 py-1 rounded-lg text-xs font-medium border transition-all cursor-grab active:cursor-grabbing flex items-center gap-1.5 ${s?"bg-indigo-600 text-white border-indigo-400 ring-2 ring-indigo-400/50 shadow-md":"bg-slate-800 text-slate-300 border-slate-700 hover:border-indigo-500 hover:bg-slate-750"}${r?" opacity-40":""}`,children:[e.jsx("span",{children:t.name}),t.student_number&&e.jsx("span",{className:"text-[10px] font-mono text-slate-400",children:t.student_number})]}),e.jsx(M,{slot:"computer_lab.unassigned.item",slotProps:{student:t,classId:d,labId:o?.id}})]},t.id)})})]}):e.jsxs("div",{className:"border-t border-slate-900 bg-slate-900/60 p-3 shrink-0 flex items-center justify-between text-xs text-slate-400 select-none",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"w-3.5 h-3.5 rounded bg-slate-800 border border-slate-700 flex items-center justify-center p-0.5",children:e.jsx(J,{size:10,className:"text-indigo-400 opacity-60"})}),e.jsx("span",{children:n==="zh"?"标准上机终端":"Console Terminals"})]}),ue.length>0&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-slate-500",children:n==="zh"?"已绑定班级:":"Bound Classes:"}),ue.map(t=>e.jsx("button",{type:"button",onClick:()=>F(t.id),className:"text-indigo-400 hover:text-indigo-300 underline font-semibold text-xs cursor-pointer ml-1",children:t.name},t.id))]})]}),e.jsxs("div",{className:"font-mono text-slate-500",children:[n==="zh"?"总行数:":"Rows: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:o.rows})," |",n==="zh"?" 总列数:":" Columns: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:o.cols})," |",n==="zh"?" 配置席位:":" Total: ",e.jsx("span",{className:"text-white font-bold",children:o.rows*o.cols})]})]})]}):e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center text-center p-8 text-gray-400 h-full",children:[e.jsx(J,{size:48,className:"opacity-20 mb-3"}),e.jsx("p",{className:"text-xs font-medium",children:n==="zh"?"请选择一个机房以预览其座位图":"Please select a lab config to preview details."})]})]})})]})]})}function We(h={}){const y=Te(),n=h.computerLabs??y?.computerLabs??[],b=h.onRefresh??y?.fetchLabs??(async()=>{}),q=h.lang??y?.lang??"zh",w=h.classes??y?.classes??[];return e.jsx(qe,{computerLabs:n,onRefresh:b,lang:q,classes:w})}export{We as ComputerLabView};
1
+ import{r as l,j as e}from"./vendor-react-DHoBZpn2.js";import{a0 as Ae,E as M,c as Te}from"./index-Bc9003lB.js";import{ap as fe,an as Le,bv as J,bu as Pe,af as Me,X as te,a0 as Re,ad as be,U as je,V as Oe,ag as Fe,c as ye,ah as Ue,C as Be,a2 as Je}from"./vendor-icons-CaXLq01o.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function qe({computerLabs:h,onRefresh:y,lang:n,classes:b}){const[q,w]=l.useState(!1),[R,V]=l.useState(null),[G,H]=l.useState(""),[N,K]=l.useState(5),[S,Y]=l.useState(6),[O,p]=l.useState(""),[se,ae]=l.useState(!1),ne="openlearn_computer_lab_selected",X="openlearn_computer_lab_selected_class",[A,re]=l.useState(()=>{try{const t=localStorage.getItem(ne);if(t&&h.some(s=>s.id===t))return t}catch{}return h.length>0?h[0].id:null}),o=h.find(t=>t.id===(A||h[0]?.id)),[ve,ie]=l.useState([]),[d,F]=l.useState(()=>{const t=o??h[0];if(!t)return null;const s=b||[];try{const a=localStorage.getItem(X),i=a?s.find(c=>c.id===a):void 0;if(i&&i.lab_id===t.id)return i.id}catch{}const r=s.find(a=>a.lab_id===t.id);return r?r.id:null}),[E,oe]=l.useState([]),[g,C]=l.useState([]),[le,de]=l.useState(!1),[Q,ce]=l.useState(!1),[xe,W]=l.useState(""),[Z,k]=l.useState(!1),[f,v]=l.useState(null),[we,$]=l.useState(null),[x,T]=l.useState(null),[I,L]=l.useState(null);l.useEffect(()=>{b&&b.length>0?ie(b):fetch("/api/classes?pageSize=all").then(t=>t.ok?t.json():{data:[]}).then(t=>{const s=Ae(t);(s.length>0||Array.isArray(t?.data))&&ie(s)}).catch(t=>console.error("Failed to fetch classes in ComputerLabManager:",t))},[b]);const _=b&&b.length>0?b:ve,ue=l.useMemo(()=>o?_.filter(t=>t.lab_id===o.id):[],[_,o]);l.useEffect(()=>{if(!o)return;if(d){_.find(s=>s.id===d);return}try{const s=localStorage.getItem(X),r=s?_.find(a=>a.id===s):void 0;if(r&&r.lab_id===o.id){F(r.id);return}}catch{}const t=_.find(s=>s.lab_id===o.id);t&&F(t.id)},[o?.id,_]),l.useEffect(()=>{try{A&&localStorage.setItem(ne,A)}catch{}},[A]),l.useEffect(()=>{try{d&&localStorage.setItem(X,d)}catch{}},[d]);const me=l.useCallback(async(t,s)=>{de(!0),p(""),v(null),$(null);try{const[r,a]=await Promise.all([fetch(`/api/classes/${t}/seats`),fetch(`/api/classes/${t}/students`)]);let i=[];if(a.ok&&(i=await a.json(),oe(i)),r.ok){const u=(await r.json()).seats||[],D=new Map(i.map(j=>[j.id,j])),U=u.map(j=>{const B=D.get(j.student_id);return{...j,student_name:j.student_name||B?.name||"",student_number:j.student_number||B?.student_number||""}});C(U)}k(!1)}catch(r){console.error("Error loading seating:",r),p(r.message||"Failed to load class seating data")}finally{de(!1)}},[]);l.useEffect(()=>{d?me(d,o?.id):(oe([]),C([]),k(!1),v(null),$(null))},[d,me]);const ee=l.useMemo(()=>{const t=new Map;for(const s of g)t.set(`${s.row_idx}_${s.col_idx}`,s);return t},[g]),he=l.useMemo(()=>new Set(g.map(t=>t.student_id)),[g]),z=l.useMemo(()=>E.filter(t=>!he.has(t.id)).sort((t,s)=>String(t.student_number??t.name??"").localeCompare(String(s.student_number??s.name??""),"zh-Hans-CN",{numeric:!0})),[E,he]),pe=(t,s,r)=>{const a=g.find(u=>u.row_idx===s.row&&u.col_idx===s.col),i=!!r&&!!a&&a.student_id!==t.id;let c=g.filter(u=>!(u.row_idx===s.row&&u.col_idx===s.col)&&u.student_id!==t.id);i&&r&&(c=c.filter(u=>!(u.row_idx===r.row&&u.col_idx===r.col)),c=[...c,{...a,row_idx:r.row,col_idx:r.col}]),c=[...c,{student_id:t.id,row_idx:s.row,col_idx:s.col,student_name:t.name,student_number:t.student_number}],C(c),k(!0)},Ne=(t,s)=>{if(!d||!o)return;const r=ee.get(`${t}_${s}`);if(f){pe(f,{row:t,col:s},we),v(null),$(null);return}if(r){const a=E.find(i=>i.id===r.student_id)||{id:r.student_id,name:r.student_name||"Student",student_number:r.student_number||""};v(a),$({row:t,col:s})}},Se=(t,s,r)=>{t.stopPropagation(),C(a=>a.filter(i=>!(i.row_idx===s&&i.col_idx===r))),k(!0)},_e=()=>{if(!o||z.length===0)return;const t=[];for(let a=0;a<o.rows;a++)for(let i=0;i<o.cols;i++)ee.has(`${a}_${i}`)||t.push([a,i]);if(t.length===0)return;const r=z.slice(0,t.length).map((a,i)=>{const[c,u]=t[i];return{student_id:a.id,row_idx:c,col_idx:u,student_name:a.name,student_number:a.student_number}});C(a=>[...a,...r]),k(!0),v(null)},ze=()=>{g.length!==0&&confirm(n==="zh"?"确定要清空当前班级在该机房的所有机位排座吗?":"Are you sure you want to clear all seat assignments for this class in this lab?")&&(C([]),k(!0),v(null))},Ce=async()=>{if(!(!d||!o))try{ce(!0),p(""),W("");const t=await fetch(`/api/classes/${d}/seats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({lab_id:o.id,seats:g.map(s=>({student_id:s.student_id,row_idx:s.row_idx,col_idx:s.col_idx}))})});if(t.ok)k(!1),W(n==="zh"?"统一机房排座已成功持久化至系统 student_seats 数据表!":"Seating assignments saved to system student_seats table successfully!"),y(),setTimeout(()=>W(""),4e3);else{const s=await t.json();p(s.error||"Failed to save seats")}}catch(t){p(t.message||"Network error saving seats")}finally{ce(!1)}},ke=()=>{H(""),K(5),Y(6),p(""),V(null),w(!0)},$e=t=>{H(t.room_number),K(t.rows),Y(t.cols),p(""),V(t.id),w(!0)},Ee=async t=>{if(t.preventDefault(),!G.trim()){p(n==="zh"?"请输入机房编号/名称":"Please enter room name or number");return}if(N<=0||N>15){p(n==="zh"?"行数应在 1 至 15 之间":"Rows should be between 1 and 15");return}if(S<=0||S>15){p(n==="zh"?"列数应在 1 至 15 之间":"Columns should be between 1 and 15");return}try{ae(!0),p("");const s=R?`/api/labs/${R}`:"/api/labs",a=await fetch(s,{method:R?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({room_number:G.trim(),rows:N,cols:S})});if(a.ok)y(),w(!1),V(null);else{const i=await a.json();p(i.error||"Server error saving lab")}}catch(s){p(s.message||"Network error")}finally{ae(!1)}},De=async t=>{if(confirm(n==="zh"?"确定要删除该机房吗?删除后对应的座位分配也会被重置。":"Are you sure you want to delete this lab? Seat mappings will be cleared."))try{(await fetch(`/api/labs/${t}`,{method:"DELETE"})).ok&&(y(),A===t&&re(null))}catch(s){console.error(s)}};return e.jsxs("div",{className:"flex-1 flex flex-col h-full overflow-hidden",id:"lab_manager_root",children:[e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between pb-4 border-b border-gray-200 gap-4 shrink-0",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-xl font-bold text-gray-800 flex items-center gap-2",children:[e.jsx(fe,{className:"text-indigo-600",size:24}),n==="zh"?"统一机房座位管理":"Unified Computer Lab Seating"]}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:n==="zh"?"维护物理机房规格及其行列排列规则,并直接根据班级信息读取并编排系统中已存的统一机房座位数据(student_seats 表)。":"Maintain physical lab layouts and manage unified student seat allocations directly synced with existing system data tables."})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("button",{onClick:ke,className:"bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-xl text-xs font-semibold flex items-center gap-1.5 shadow-sm transition-all focus:ring-2 focus:ring-indigo-500 cursor-pointer",children:[e.jsx(Le,{size:14}),n==="zh"?"新增机房规则":"New Lab Config"]}),e.jsx(M,{slot:"computer_lab.toolbar.action",slotProps:{activeLab:o,computerLabs:h,onRefresh:y,lang:n}})]})]}),e.jsxs("div",{className:"flex-1 min-h-0 grid grid-cols-1 lg:grid-cols-12 gap-6 pt-5 overflow-hidden",children:[e.jsxs("div",{className:"lg:col-span-4 flex flex-col min-h-0 bg-white border border-gray-200 rounded-2xl shadow-xs overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 bg-gray-50 flex justify-between items-center shrink-0",children:[e.jsx("span",{className:"text-xs font-bold text-gray-700 uppercase tracking-wider block",children:n==="zh"?"机房列表":"Computer Labs"}),e.jsx("span",{className:"bg-gray-200 text-gray-700 font-bold px-2 py-0.5 rounded-full text-xs",children:h.length})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-3",children:h.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center p-8 text-center text-gray-400 h-full",children:[e.jsx(fe,{size:40,className:"mb-2 opacity-30"}),e.jsx("p",{className:"text-xs font-medium",children:n==="zh"?"暂无机房编号规则":"No Computer Labs configured yet."}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:n==="zh"?"点击右上角按钮添加首个机房规格。":"Click the button above to add your first computer room."})]}):h.map(t=>{const s=o?.id===t.id,r=_.filter(a=>a.lab_id===t.id);return e.jsxs("div",{onClick:()=>{re(t.id),w(!1)},className:`p-3 rounded-xl border transition-all cursor-pointer flex flex-col gap-2 group ${s?"border-indigo-300 bg-indigo-50/60 shadow-xs ring-1 ring-indigo-200":"border-gray-150 hover:border-gray-300 hover:bg-gray-50"}`,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${s?"bg-indigo-600 text-white":"bg-gray-100 text-gray-500 group-hover:bg-gray-200"}`,children:e.jsx(J,{size:16})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-bold text-gray-800 flex items-center gap-1.5",children:t.room_number}),e.jsxs("div",{className:"text-xs text-gray-400 font-mono mt-0.5",children:[t.rows," ",n==="zh"?"行":"Rows"," × ",t.cols," ",n==="zh"?"列":"Cols",e.jsx("span",{className:"mx-1.5",children:"•"}),t.rows*t.cols," ",n==="zh"?"个机位":"Seats"]})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity",children:[e.jsx("button",{onClick:a=>{a.stopPropagation(),$e(t)},className:"p-1 text-gray-500 hover:text-indigo-600 hover:bg-white rounded transition-colors",title:n==="zh"?"编辑规则":"Edit Rule",children:e.jsx(Pe,{size:13})}),e.jsx("button",{onClick:a=>{a.stopPropagation(),De(t.id)},className:"p-1 text-gray-500 hover:text-rose-600 hover:bg-white rounded transition-colors",title:n==="zh"?"删除机房间":"Delete Lab",children:e.jsx(Me,{size:14})})]})]}),r.length>0&&e.jsxs("div",{className:"flex items-center gap-1 flex-wrap pt-1 border-t border-gray-100/80",children:[e.jsx("span",{className:"text-[10px] text-gray-400 font-medium",children:n==="zh"?"绑定班级:":"Bound:"}),r.map(a=>e.jsx("span",{className:"text-[10px] font-semibold bg-indigo-100/70 text-indigo-700 px-1.5 py-0.5 rounded-md",children:a.name},a.id))]})]},t.id)})})]}),e.jsx("div",{className:"lg:col-span-8 flex flex-col min-h-0 bg-white border border-gray-200 rounded-2xl shadow-xs overflow-hidden",children:q?e.jsxs("form",{onSubmit:Ee,className:"flex-1 flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 bg-gray-50 font-bold text-xs text-gray-700 uppercase tracking-wider shrink-0 flex items-center justify-between",children:[e.jsx("span",{children:R?n==="zh"?"编辑机房规则":"Edit Lab Seating":n==="zh"?"创建全新上机机房":"Create Computer Lab"}),e.jsx("button",{type:"button",onClick:()=>w(!1),className:"text-gray-400 hover:text-gray-600",children:e.jsx(te,{size:16})})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-4",children:[O&&e.jsxs("div",{className:"p-3 bg-red-50 border border-red-200 text-red-700 text-xs rounded-xl flex items-center gap-1.5",children:[e.jsx(Re,{size:14}),e.jsx("span",{children:O})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"机房编号 / 场所名称 *":"Lab Name / Number *"}),e.jsx("input",{type:"text",value:G,onChange:t=>H(t.target.value),placeholder:n==="zh"?"例如:305综合机房、软创中心、Lab A":"e.g. Lab 404, Software Sandbox, Suite C",className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",maxLength:32,required:!0})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"排列行数 (Rows) *":"Rows Direction *"}),e.jsx("input",{type:"number",value:N,onChange:t=>K(Math.max(1,parseInt(t.target.value)||1)),min:1,max:15,className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",required:!0}),e.jsx("span",{className:"text-xs text-gray-400 block mt-0.5",children:n==="zh"?"上下方向机位数 (最大15行)":"Horizontal sets count (Max 15)"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wide",children:n==="zh"?"排列列数 (Columns) *":"Columns Direction *"}),e.jsx("input",{type:"number",value:S,onChange:t=>Y(Math.max(1,parseInt(t.target.value)||1)),min:1,max:15,className:"w-full text-xs p-2.5 border border-gray-300 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 rounded-xl mt-1.5",required:!0}),e.jsx("span",{className:"text-xs text-gray-400 block mt-0.5",children:n==="zh"?"左右方向机位数 (最大15列)":"Vertical sets count (Max 15)"})]})]}),e.jsxs("div",{className:"border border-dashed border-gray-200 bg-gray-50/50 p-4 rounded-xl",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider block mb-2",children:n==="zh"?"布局网格缩略结构":"Layout Aspect Schema"}),e.jsxs("div",{className:"flex flex-col gap-1 items-center justify-center p-3 bg-white rounded-lg border border-gray-100 min-h-[120px]",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[Array.from({length:Math.min(N,6)}).map((t,s)=>e.jsxs("div",{className:"flex gap-1 justify-center",children:[Array.from({length:Math.min(S,8)}).map((r,a)=>e.jsx("div",{className:"w-4 h-4 rounded bg-indigo-100 border border-indigo-200 shrink-0"},a)),S>8&&e.jsx("div",{className:"w-4 text-xs text-gray-400 flex items-center justify-center",children:"..."})]},s)),N>6&&e.jsx("div",{className:"text-xs text-center text-gray-400 mt-1",children:"..."})]}),e.jsxs("span",{className:"text-xs text-gray-450 mt-3 font-medium",children:["配置容量:",N," × ",S," = ",N*S," 座位"]})]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 shrink-0 flex items-center justify-end gap-2 bg-gray-50",children:[e.jsx("button",{type:"button",onClick:()=>w(!1),className:"px-4 py-2 text-xs font-semibold text-gray-500 hover:text-gray-700 bg-white hover:bg-gray-100 border border-gray-200 rounded-xl transition-all cursor-pointer",children:n==="zh"?"取消":"Cancel"}),e.jsxs("button",{type:"submit",disabled:se,className:"px-4 py-2 text-xs font-bold text-white bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 rounded-xl flex items-center gap-1 shadow-sm transition-all cursor-pointer",children:[e.jsx(be,{size:14}),e.jsx("span",{children:se?n==="zh"?"提交中...":"Saving...":n==="zh"?"提交保存":"Save Config"})]})]})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-3 border-b border-gray-100 bg-gray-50 flex flex-wrap items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs font-bold text-gray-700 uppercase tracking-wider flex items-center gap-1.5",children:[e.jsx(je,{size:14,className:"text-indigo-600"}),n==="zh"?"班级机位联动:":"Class Seating Link:"]}),e.jsxs("select",{value:d||"",onChange:t=>F(t.target.value?t.target.value:null),className:"text-xs font-semibold bg-white border border-gray-300 rounded-lg px-2.5 py-1.5 text-gray-700 focus:outline-none focus:ring-1 focus:ring-indigo-500 cursor-pointer shadow-2xs",children:[e.jsx("option",{value:"",children:n==="zh"?"📐 物理规格总览 (无班级)":"📐 Physical Blueprint (No Class)"}),_.map(t=>{const s=t.lab_id===o?.id;return e.jsxs("option",{value:t.id,children:[t.name," ",s?n==="zh"?"★ 已绑定此机房":"★ Bound":""]},t.id)})]})]}),d&&o&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:_e,disabled:z.length===0,className:"px-2.5 py-1.5 text-xs font-semibold bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 rounded-lg flex items-center gap-1 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",title:n==="zh"?"将未排座学生按学号依次填入空闲机位":"Auto assign unplaced students",children:[e.jsx(Oe,{size:13}),e.jsx("span",{children:n==="zh"?"一键排座":"Auto Fill"})]}),e.jsxs("button",{type:"button",onClick:ze,disabled:g.length===0,className:"px-2.5 py-1.5 text-xs font-semibold bg-gray-100 hover:bg-rose-50 text-gray-600 hover:text-rose-600 border border-gray-200 rounded-lg flex items-center gap-1 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed",title:n==="zh"?"清空当前班级排座":"Clear Seating",children:[e.jsx(Fe,{size:13}),e.jsx("span",{children:n==="zh"?"清空":"Clear"})]}),e.jsxs("button",{type:"button",onClick:Ce,disabled:Q||!Z&&!o,className:`px-3 py-1.5 text-xs font-bold rounded-lg flex items-center gap-1.5 shadow-xs transition-all cursor-pointer ${Z?"bg-emerald-600 hover:bg-emerald-700 text-white animate-pulse":"bg-indigo-600 hover:bg-indigo-700 text-white disabled:opacity-60 disabled:cursor-not-allowed"}`,children:[Q?e.jsx(ye,{size:13,className:"animate-spin"}):e.jsx(Ue,{size:13}),e.jsx("span",{children:Q?n==="zh"?"保存中...":"Saving...":Z?n==="zh"?"保存排座 (已修改)":"Save (Modified)":n==="zh"?"已保存":"Saved"})]}),e.jsx(M,{slot:"computer_lab.seating.toolbar",slotProps:{labId:o.id,classId:d,assignedSeats:g,setAssignedSeats:C,lang:n}})]})]}),xe&&e.jsxs("div",{className:"bg-emerald-50 border-b border-emerald-200 text-emerald-800 text-xs px-4 py-2 flex items-center gap-1.5 animate-fadeIn",children:[e.jsx(be,{size:14,className:"text-emerald-600 shrink-0"}),e.jsx("span",{className:"font-medium",children:xe})]}),O&&e.jsxs("div",{className:"bg-red-50 border-b border-red-200 text-red-700 text-xs px-4 py-2 flex items-center gap-1.5",children:[e.jsx(Be,{size:14,className:"text-red-500 shrink-0"}),e.jsx("span",{children:O})]}),o?e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-slate-950 text-white overflow-hidden relative",children:[e.jsx("div",{className:"py-2.5 flex justify-center shrink-0 border-b border-slate-900 bg-slate-950/80 backdrop-blur-xs z-10",children:e.jsx("div",{className:"w-56 bg-slate-900 border border-slate-700 py-1 rounded text-center text-xs font-bold text-slate-300 uppercase tracking-widest select-none shadow-sm flex items-center justify-center gap-1.5",children:e.jsxs("span",{children:["📽️ ",n==="zh"?"讲台 / 教师主荧幕":"Classroom Stage / Screen"]})})}),e.jsx("div",{className:"flex-1 overflow-auto p-4 flex flex-col items-center",children:le?e.jsxs("div",{className:"flex flex-col items-center justify-center h-48 gap-2 text-slate-400",children:[e.jsx(ye,{size:24,className:"animate-spin text-indigo-400"}),e.jsx("span",{className:"text-xs",children:n==="zh"?"正在读取统一机房座位数据...":"Loading lab seating data..."})]}):e.jsx("div",{className:"flex flex-col gap-2.5 py-2 max-w-full",children:Array.from({length:o.rows}).map((t,s)=>e.jsxs("div",{className:"flex gap-2.5 justify-center items-center",children:[e.jsxs("span",{className:"text-xs font-bold font-mono text-slate-500 w-6 text-right select-none pr-0.5",children:["R",s+1]}),Array.from({length:o.cols}).map((r,a)=>{const i=ee.get(`${s}_${a}`),c=!!i,u=f&&(!c||i.student_id!==f.id),D=!!x?.from&&x.from.row===s&&x.from.col===a,U=!!x&&!!I&&I.row===s&&I.col===a&&!D,j=U&&c&&x?.type==="seat"&&i.student_id!==x.studentId,B=U&&(!c||x?.type==="pool");return e.jsx("div",{"data-seat-id":`${s}_${a}`,onClick:()=>Ne(s,a),draggable:!!d&&c,onDragStart:m=>{!d||!i||(T({type:"seat",studentId:i.student_id,from:{row:s,col:a}}),m.dataTransfer.setData("text/plain",JSON.stringify({type:"seat",studentId:i.student_id,from:{row:s,col:a}})),m.dataTransfer.effectAllowed="move")},onDragEnd:()=>{T(null),L(null)},onDragOver:m=>{!x||D||(m.preventDefault(),m.dataTransfer.dropEffect="move",L({row:s,col:a}))},onDragLeave:()=>{L(m=>m&&m.row===s&&m.col===a?null:m)},onDrop:m=>{if(m.preventDefault(),x&&!D){const ge=x.type==="pool"?z.find(P=>P.id===x.studentId)||E.find(P=>P.id===x.studentId):E.find(P=>P.id===x.studentId);ge&&(pe(ge,{row:s,col:a},x.from),v(null),$(null))}T(null),L(null)},className:`group relative rounded-xl flex flex-col items-center justify-center transition-all select-none shadow-sm ${d&&c?"cursor-grab":"cursor-pointer"} ${d?"w-20 h-14":"w-11 h-11"} ${c?"bg-slate-850 border border-indigo-500/70 hover:border-indigo-400 shadow-indigo-950/50":u?"bg-indigo-950/40 border border-dashed border-indigo-400 hover:bg-indigo-900/50 ring-1 ring-indigo-400/50 animate-pulse":"bg-slate-900 border border-slate-800 hover:border-slate-700 hover:bg-slate-850"}${j?" ring-2 ring-amber-400 border-amber-400 bg-amber-950/40":""}${B&&!j?" ring-2 ring-emerald-400 border-emerald-400 bg-emerald-950/40":""}${D?" opacity-40":""}`,children:c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"w-full h-full p-1.5 flex flex-col justify-between items-center text-center",children:[e.jsxs("div",{className:"flex items-center justify-between w-full px-0.5",children:[e.jsxs("span",{className:"text-[10px] font-mono text-indigo-300/80",children:[s+1,"-",a+1]}),d&&e.jsx("button",{type:"button",onClick:m=>Se(m,s,a),className:"opacity-0 group-hover:opacity-100 text-slate-400 hover:text-rose-400 p-0.5 rounded transition-opacity",title:n==="zh"?"移出此座位":"Unseat student",children:e.jsx(te,{size:11})})]}),e.jsx("div",{className:"font-bold text-xs text-white truncate max-w-[70px] leading-tight",children:i.student_name||"Student"}),e.jsx("div",{className:"text-[9px] font-mono text-slate-400 truncate max-w-[70px]",children:i.student_number||`ID:${i.student_id.slice(-4)}`}),e.jsx("div",{className:"w-full min-w-0",onClick:m=>m.stopPropagation(),children:e.jsx(M,{slot:"computer_lab.seat.overlay",slotProps:{labId:o.id,row:s,col:a,seat:i,isOccupied:!0}})})]}),e.jsxs("div",{className:"absolute bottom-16 bg-slate-900 text-white text-xs rounded-lg px-2.5 py-1.5 hidden group-hover:block whitespace-nowrap z-30 font-sans border border-indigo-700 shadow-2xl pointer-events-none",children:[e.jsx("div",{className:"font-bold text-indigo-300",children:i.student_name}),e.jsxs("div",{className:"text-[10px] text-slate-400 font-mono",children:[n==="zh"?"学号:":"No: ",i.student_number||i.student_id]}),e.jsx("div",{className:"text-[10px] text-slate-300 mt-0.5",children:n==="zh"?`第 ${s+1} 排,第 ${a+1} 列`:`Row ${s+1}, Col ${a+1}`})]})]}):e.jsxs(e.Fragment,{children:[e.jsx(J,{size:d?14:15,className:u?"text-indigo-400 animate-bounce":"text-slate-600 opacity-60"}),e.jsxs("span",{className:"text-[10px] font-mono text-slate-500 mt-0.5",children:[s+1,"-",a+1]}),e.jsx("div",{className:"absolute bottom-12 bg-slate-900 text-white text-xs rounded px-2 py-1 hidden group-hover:block whitespace-nowrap z-30 font-sans border border-slate-700 shadow-xl pointer-events-none",children:f?n==="zh"?`点击安排 [${f.name}] 到第 ${s+1} 排第 ${a+1} 列`:`Place [${f.name}] here`:n==="zh"?`第 ${s+1} 排第 ${a+1} 列 (空闲)`:`Row ${s+1} / Column ${a+1} (Empty)`})]})},a)})]},s))})}),d&&o&&!le&&e.jsx("div",{className:"shrink-0 px-4 pb-2",children:e.jsx(M,{slot:"computer_lab.seating.sidebar",slotProps:{labId:o.id,classId:d,assignedSeats:g,unassignedStudents:z}})}),d?e.jsxs("div",{className:"border-t border-slate-900 bg-slate-900/90 p-3 shrink-0 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"font-bold text-slate-300 flex items-center gap-1.5",children:[e.jsx(je,{size:13,className:"text-indigo-400"}),n==="zh"?"待排座学生池:":"Unassigned Students Pool:"]}),e.jsxs("span",{className:"text-[11px] font-mono text-slate-400",children:[z.length," ",n==="zh"?"人未排":"unplaced"," / ",E.length," ",n==="zh"?"人总计":"total"]}),f&&e.jsxs("span",{className:"bg-indigo-900/80 text-indigo-300 border border-indigo-700 text-[11px] px-2 py-0.5 rounded-full flex items-center gap-1 animate-pulse",children:[e.jsx("span",{children:n==="zh"?`当前选择: ${f.name} (点击上方空位落座)`:`Selected: ${f.name} (click empty seat)`}),e.jsx("button",{type:"button",onClick:()=>{v(null),$(null)},className:"hover:text-white",children:e.jsx(te,{size:10})})]})]}),e.jsxs("div",{className:"text-[11px] font-mono text-slate-400",children:[n==="zh"?"机房已占:":"Occupied: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:g.length})," /"," ",o.rows*o.cols]})]}),z.length===0?e.jsxs("div",{className:"text-xs text-slate-500 py-1 italic flex items-center gap-1",children:[e.jsx(Je,{size:13,className:"text-emerald-400"}),e.jsx("span",{children:n==="zh"?"当前班级全部学生均已成功分配机位!":"All students in this class have been assigned seats!"})]}):e.jsx("div",{className:"flex items-center gap-1.5 overflow-x-auto py-1 max-h-16 pr-2",children:z.map(t=>{const s=f?.id===t.id,r=x?.type==="pool"&&x.studentId===t.id;return e.jsxs("div",{className:"shrink-0 flex items-center gap-1","data-unassigned-id":t.id,children:[e.jsxs("button",{type:"button",draggable:!0,onDragStart:a=>{T({type:"pool",studentId:t.id}),a.dataTransfer.setData("text/plain",JSON.stringify({type:"pool",studentId:t.id})),a.dataTransfer.effectAllowed="move"},onDragEnd:()=>{T(null),L(null)},onClick:()=>{v(s?null:t),$(null)},className:`px-2.5 py-1 rounded-lg text-xs font-medium border transition-all cursor-grab active:cursor-grabbing flex items-center gap-1.5 ${s?"bg-indigo-600 text-white border-indigo-400 ring-2 ring-indigo-400/50 shadow-md":"bg-slate-800 text-slate-300 border-slate-700 hover:border-indigo-500 hover:bg-slate-750"}${r?" opacity-40":""}`,children:[e.jsx("span",{children:t.name}),t.student_number&&e.jsx("span",{className:"text-[10px] font-mono text-slate-400",children:t.student_number})]}),e.jsx(M,{slot:"computer_lab.unassigned.item",slotProps:{student:t,classId:d,labId:o?.id}})]},t.id)})})]}):e.jsxs("div",{className:"border-t border-slate-900 bg-slate-900/60 p-3 shrink-0 flex items-center justify-between text-xs text-slate-400 select-none",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"w-3.5 h-3.5 rounded bg-slate-800 border border-slate-700 flex items-center justify-center p-0.5",children:e.jsx(J,{size:10,className:"text-indigo-400 opacity-60"})}),e.jsx("span",{children:n==="zh"?"标准上机终端":"Console Terminals"})]}),ue.length>0&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-slate-500",children:n==="zh"?"已绑定班级:":"Bound Classes:"}),ue.map(t=>e.jsx("button",{type:"button",onClick:()=>F(t.id),className:"text-indigo-400 hover:text-indigo-300 underline font-semibold text-xs cursor-pointer ml-1",children:t.name},t.id))]})]}),e.jsxs("div",{className:"font-mono text-slate-500",children:[n==="zh"?"总行数:":"Rows: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:o.rows})," |",n==="zh"?" 总列数:":" Columns: ",e.jsx("span",{className:"text-indigo-400 font-bold",children:o.cols})," |",n==="zh"?" 配置席位:":" Total: ",e.jsx("span",{className:"text-white font-bold",children:o.rows*o.cols})]})]})]}):e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center text-center p-8 text-gray-400 h-full",children:[e.jsx(J,{size:48,className:"opacity-20 mb-3"}),e.jsx("p",{className:"text-xs font-medium",children:n==="zh"?"请选择一个机房以预览其座位图":"Please select a lab config to preview details."})]})]})})]})]})}function We(h={}){const y=Te(),n=h.computerLabs??y?.computerLabs??[],b=h.onRefresh??y?.fetchLabs??(async()=>{}),q=h.lang??y?.lang??"zh",w=h.classes??y?.classes??[];return e.jsx(qe,{computerLabs:n,onRefresh:b,lang:q,classes:w})}export{We as ComputerLabView};
@@ -1 +1 @@
1
- import{r as n,j as e}from"./vendor-react-DHoBZpn2.js";import{b as ae,E as f}from"./index-DuxQtTr9.js";import{B as j,ac as ie,aW as ne,an as I,a$ as T,X as oe,a2 as le,U as O,c0 as de,c1 as ce,x as xe,y as me,ai as ge,c as N,bd as he,af as P,T as ue}from"./vendor-icons-DLOPlM4i.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function pe(s){if(typeof s!="string")return"";let a=s;return a=a.replace(/<(think|thinking|reasoning|analysis)(?:\s+[^>]*)?>[\s\S]*?<\/\1>/gi,""),a=a.replace(/<(think|thinking|reasoning|analysis)(?:\s+[^>]*)?>[\s\S]*$/gi,""),a=a.replace(/```(?:think|thinking|reasoning|analysis)[\s\S]*?```/gi,""),a=a.replace(/^```(?:json|markdown|md)?\s*/i,"").replace(/```\s*$/i,""),a.trim()}function be(s,a=160){if(!s||typeof s!="string")return"";let r=pe(s);return r?(r=r.replace(/```[\s\S]*?```/g," "),r=r.replace(/!\[.*?\]\(.*?\)/g,""),r=r.replace(/\[(.*?)\]\(.*?\)/g,"$1"),r=r.replace(/^#+\s+/gm,""),r=r.replace(/^\s*[-*+]\s+/gm,""),r=r.replace(/^\s*\d+\.\s+/gm,""),r=r.replace(/^\s*>\s+/gm,""),r=r.replace(/\*\*([^*]+)\*\*/g,"$1"),r=r.replace(/\*([^*]+)\*/g,"$1"),r=r.replace(/__([^_]+)__/g,"$1"),r=r.replace(/_([^_]+)_/g,"$1"),r=r.replace(/~~(.*?)~~/g,"$1"),r=r.replace(/`([^`]+)`/g,"$1"),r=r.replace(/\s+/g," ").trim(),r.length<=a?r:r.slice(0,a).trimEnd()+"..."):""}function Se(){const{lang:s,session:a,lessons:r,lessonsSearchQuery:h,setLessonsSearchQuery:u,lessonsSortOrder:A,setLessonsSortOrder:F,filteredAndSortedLessons:p,isImportLessonsOpen:ye,setIsImportLessonsOpen:M,isCourseWizardOpen:fe,setIsCourseWizardOpen:R,onViewCourse:v,onDeleteCourse:W,onCopyCourse:U,filterEnrollment:C,setFilterEnrollment:B,filterHasContent:w,setFilterHasContent:H,filterThisMonth:z,setFilterThisMonth:Q,copyingLessonId:V,fetchLessons:X,downloadCourseTemplate:Z,exportCoursePackage:J}=ae(),q=()=>M(!0),k=()=>R(!0),i=a,G=i?.username==="admin"||i?.userId==="usr_admin"||i?.role==="administrator"||i?.subRole==="administrator",[b,K]=n.useState(!1),[o,y]=n.useState(null),[l,d]=n.useState(null),[S,L]=n.useState(!1),[Y,$]=n.useState(!1),[x,_]=n.useState(null),[D,E]=n.useState(null),ee=async t=>{E(t.id);try{await J(t.id)}finally{E(null)}},se=t=>{navigator.clipboard.writeText(t).then(()=>{_(t),setTimeout(()=>_(null),1500)})},te=async t=>{y(t),d(null),$(!0);try{const m=await fetch(`/api/lessons/${t.id}/stats`);if(m.ok){const c=await m.json();d(c)}}catch{d({whiteboardCount:0,scheduleCount:0,enrollmentCount:0,assignmentCount:0})}finally{$(!1)}},re=async()=>{if(o){L(!0);try{await W(o.id),y(null),d(null)}finally{L(!1)}}};return e.jsxs("div",{className:"flex-1 flex flex-col gap-6 h-full overflow-y-auto",children:[e.jsxs("div",{className:"flex-1 bg-white border border-gray-200 rounded-xl shadow-sm flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between shrink-0",children:[e.jsxs("h3",{className:"font-medium text-gray-700 flex items-center gap-2",children:[e.jsx(j,{size:16,className:"text-gray-400"}),s==="zh"?"课程与教学环节管理 (SQLite)":"Courses & Lessons Management"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{id:"import-lessons-csv-btn",onClick:q,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 font-semibold rounded-lg shadow-3xs transition-all hover:shadow-xs hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(ie,{size:14}),s==="zh"?"批量导入课程":"Import Lessons"]}),e.jsxs("button",{id:"download-course-template-btn",onClick:()=>void Z(),title:s==="zh"?"下载自包含的课程模板(教学环节 + 全部预设组件 + PDF/PPTX 课件附件)":"Download a self-contained course template (segments + every preset component + PDF/PPTX assets)",className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-emerald-50 hover:bg-emerald-100 text-emerald-700 border border-emerald-200 font-semibold rounded-lg shadow-3xs transition-all hover:shadow-xs hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(ne,{size:14}),s==="zh"?"下载课程模板":"Course Template"]}),e.jsxs("button",{id:"add-course-wizard-btn",onClick:k,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-lg shadow-sm transition-all hover:shadow-md hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(I,{size:14}),s==="zh"?"手动添加课程 (向导)":"Add Course Wizard"]}),e.jsx(f,{slot:"course.list.toolbar.action",slotProps:{lang:s,onRefresh:X}})]})]}),r.length>0&&e.jsxs("div",{className:"px-5 py-3.5 border-b border-gray-100 bg-gray-50/50 flex flex-col sm:flex-row items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3 w-full sm:w-auto",children:[e.jsxs("div",{className:"relative w-full sm:w-64",children:[e.jsx("span",{className:"absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-gray-400",children:e.jsx(T,{size:14})}),e.jsx("input",{type:"text",placeholder:"Search courses by title...",value:h,onChange:t=>u(t.target.value),className:"w-full pl-9 pr-8 py-1.5 text-xs bg-white border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 shadow-sm"}),h&&e.jsx("button",{onClick:()=>u(""),className:"absolute inset-y-0 right-0 flex items-center pr-2.5 text-gray-400 hover:text-gray-600",children:e.jsx(oe,{size:12,className:"bg-gray-100 hover:bg-gray-200 rounded-full p-0.5"})})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs font-bold text-subtle uppercase tracking-wider",children:s==="zh"?"排序方式:":"Sort by:"}),e.jsxs("select",{"aria-label":s==="zh"?"课程排序方式":"Course sort order",value:A,onChange:t=>F(t.target.value),className:"bg-white border border-gray-200 text-xs text-gray-755 font-bold px-2.5 py-1.5 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-sm",id:"courses-sort-select",children:[e.jsx("option",{value:"recent",children:s==="zh"?"最新创建":"Most Recent"}),e.jsx("option",{value:"alphabetical",children:s==="zh"?"按名称 (A-Z)":"Alphabetical (A-Z)"}),e.jsx("option",{value:"enrollment",children:s==="zh"?"学生选课人次":"Student Enrollment Count"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("button",{onClick:()=>K(!b),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${b?"bg-indigo-600 text-white border-indigo-600 shadow-2xs":"bg-white text-gray-600 border-gray-200 hover:border-gray-300"}`,title:s==="zh"?"只看我创建的课程":"Only show courses created by me",children:[e.jsx(le,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"我的备课":"My Courses"]}),e.jsxs("button",{onClick:()=>B(!C),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${C?"bg-emerald-50 text-emerald-700 border-emerald-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:[e.jsx(O,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"有人选":"Enrolled"]}),e.jsxs("button",{onClick:()=>H(!w),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${w?"bg-indigo-50 text-indigo-700 border-indigo-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:[e.jsx(j,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"有内容":"Has Content"]}),e.jsx("button",{onClick:()=>Q(!z),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${z?"bg-amber-50 text-amber-700 border-amber-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:s==="zh"?"本月":"This Month"})]}),e.jsxs("div",{className:"text-xs font-semibold text-gray-500",children:["Found ",e.jsx("span",{className:"text-indigo-650 font-bold",children:p.length})," of"," ",e.jsx("span",{className:"text-gray-700 font-bold",children:r.length})," course",r.length===1?"":"s"]})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:r.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 min-h-[300px]",children:[e.jsx(j,{size:48,className:"mb-4 opacity-30 text-indigo-500"}),e.jsx("h3",{className:"text-lg font-bold text-gray-800",children:s==="zh"?"暂无可用课程":"No Courses Available"}),e.jsx("p",{className:"mt-2 text-sm text-gray-500 text-center max-w-xs",children:s==="zh"?"系统中暂未部署任何课程。请通过下方按钮启动添加向导指南。":"There are no courses active in the system yet. Build your first curriculum!"}),e.jsxs("button",{id:"empty-add-course-btn",onClick:k,className:"mt-5 flex items-center gap-2 px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white font-bold rounded-xl shadow-md transition-all cursor-pointer",children:[e.jsx(I,{size:16}),s==="zh"?"使用向导指南来创建新课程":"Create Course via Wizard"]})]}):p.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-full py-12 text-gray-450 text-center",children:[e.jsx(T,{size:44,className:"mb-3 opacity-30 text-gray-450"}),e.jsxs("h4",{className:"font-semibold text-gray-700 text-sm",children:['No Courses Match "',h,'"']}),e.jsx("p",{className:"text-xs text-gray-500 mt-1 max-w-xs",children:"Double-check the spelling or try searching for another curriculum keyword."}),e.jsx("button",{onClick:()=>u(""),className:"mt-3 text-xs bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 font-semibold px-3 py-1.5 rounded-lg transition-colors",children:"Clear Search Filter"})]}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:p.filter(t=>b?!t.creator_id||t.creator_id===i?.userId||t.creator_id===i?.username:!0).map(t=>{const m=V===t.id,c=!t.creator_id||t.creator_id===i?.userId||t.creator_id===i?.username,g=G||c;return e.jsxs("div",{className:`border border-gray-200 hover:border-indigo-300 rounded-xl p-4 flex flex-col bg-gray-50/50 hover:shadow-md transition-all ${m?"opacity-60 pointer-events-none":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2 gap-2",children:[e.jsx("div",{className:"font-semibold text-gray-800 text-lg truncate cursor-pointer hover:text-indigo-600 transition-colors",title:t.title,onClick:()=>v(t.id),children:t.title}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx(f,{slot:"course.card.badge",slotProps:{course:t}}),t.creator_name?e.jsxs("span",{className:`text-xs font-medium px-1.5 py-0.5 rounded border flex items-center gap-0.5 ${c?"bg-indigo-50 text-indigo-700 border-indigo-200 font-semibold":"bg-slate-100 text-slate-600 border-slate-200"}`,title:s==="zh"?`创建教师: ${t.creator_name}`:`Created by: ${t.creator_name}`,children:[c?"👑 ":"👤 ",t.creator_name]}):null,e.jsxs("span",{className:"inline-flex items-center gap-1 bg-indigo-50 text-indigo-700 px-1.5 py-0.5 border border-indigo-100 rounded text-xs font-bold",children:[e.jsx(O,{size:10,className:"text-indigo-500"}),t.enrollment_count||0]})]})]}),e.jsx("div",{className:"text-sm text-gray-500 line-clamp-3 mb-4 flex-1 leading-relaxed",children:be(t.content)||e.jsx("span",{className:"italic text-gray-400",children:s==="zh"?"暂无课程大纲与简介":"No outline or summary available."})}),e.jsxs("div",{className:"flex justify-between items-center mt-auto",children:[e.jsxs("button",{onClick:()=>se(t.id),className:`flex items-center gap-1 text-xs rounded px-1.5 py-0.5 transition-all cursor-pointer ${x===t.id?"text-emerald-700 bg-emerald-50 border border-emerald-200":"text-subtle hover:text-indigo-600 hover:bg-indigo-50 border border-transparent"}`,title:x===t.id?s==="zh"?"已复制!":"Copied!":s==="zh"?"复制课程 ID":"Copy Course ID",children:[x===t.id?e.jsx(de,{size:12}):e.jsx(ce,{size:12}),e.jsx("span",{className:"font-mono",children:x===t.id?s==="zh"?"已复制!":"Copied!":`${t.id.substring(0,8)}…`})]}),e.jsxs("div",{className:"flex items-center gap-0.5",children:[e.jsx("button",{onClick:()=>v(t.id),className:"p-1.5 text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 rounded transition-colors cursor-pointer",title:g?s==="zh"?"查看与编辑":"View & Edit":s==="zh"?"查看只读 (他人课程)":"View Read-Only",children:g?e.jsx(xe,{size:15}):e.jsx(me,{size:15})}),e.jsx("button",{onClick:()=>U(t.id),className:"p-1.5 text-gray-400 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors cursor-pointer",title:s==="zh"?"克隆为我的备课":"Clone Course",children:e.jsx(ge,{size:14})}),g&&e.jsx("button",{onClick:()=>void ee(t),disabled:D===t.id,className:"p-1.5 text-gray-400 hover:text-sky-600 hover:bg-sky-50 rounded transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-wait",title:s==="zh"?"导出为课程包(教学环节 + 白板元素 + 内联附件,可拖回导入框)":"Export as course package (segments + whiteboard elements + embedded assets)",children:D===t.id?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(he,{size:14})}),g?e.jsx("button",{onClick:()=>te(t),className:"p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors cursor-pointer",title:s==="zh"?"删除课程":"Delete Course",children:e.jsx(P,{size:14})}):e.jsx("span",{className:"p-1.5 text-gray-300 cursor-not-allowed",title:s==="zh"?"仅创建教师或管理员可删除":"Only creator or admin can delete",children:e.jsx(P,{size:14})}),e.jsx(f,{slot:"course.card.action",slotProps:{course:t,lang:s}})]})]})]},t.id)})})})]}),o&&e.jsx("div",{className:"fixed inset-0 bg-black/40 backdrop-blur-[2px] flex items-center justify-center z-[9999] p-4",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-2xl max-w-md w-full border border-gray-100 overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-4 border-b border-gray-100 bg-red-50 flex items-center gap-2",children:[e.jsx(ue,{size:18,className:"text-red-600"}),e.jsx("h3",{className:"font-bold text-red-800 text-sm",children:s==="zh"?"确认删除课程":"Confirm Course Deletion"})]}),e.jsxs("div",{className:"p-5 space-y-3",children:[e.jsx("p",{className:"text-sm text-gray-700",children:s==="zh"?e.jsxs(e.Fragment,{children:["确定要删除课程 ",e.jsx("span",{className:"font-bold text-red-600",children:o.title})," 吗?"]}):e.jsxs(e.Fragment,{children:["Are you sure you want to delete ",e.jsx("span",{className:"font-bold text-red-600",children:o.title}),"?"]})}),e.jsx("p",{className:"text-xs text-red-600 font-medium",children:s==="zh"?"此操作不可撤销,将删除课程的所有关联数据。":"This action is irreversible and will delete all associated data."}),Y?e.jsxs("div",{className:"flex items-center gap-2 text-xs text-gray-500 py-2",children:[e.jsx(N,{size:14,className:"animate-spin"}),s==="zh"?"正在统计关联数据...":"Counting related data..."]}):l?e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3 space-y-1.5 text-xs",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"白板元素":"Whiteboard Elements"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.whiteboardCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"排课记录":"Schedules"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.scheduleCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"选课学生":"Enrollments"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.enrollmentCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"作业任务":"Assignments"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.assignmentCount})]})]}):null]}),e.jsxs("div",{className:"px-5 py-3 border-t border-gray-100 bg-gray-50 flex justify-end gap-2",children:[e.jsx("button",{onClick:()=>{y(null),d(null)},className:"px-4 py-2 text-xs font-medium text-gray-600 hover:bg-gray-100 border border-gray-200 rounded-lg transition-colors cursor-pointer",children:s==="zh"?"取消":"Cancel"}),e.jsxs("button",{onClick:re,disabled:S,className:"px-4 py-2 text-xs font-bold text-white bg-red-600 hover:bg-red-700 rounded-lg transition-colors cursor-pointer disabled:opacity-50 flex items-center gap-1.5",children:[S&&e.jsx(N,{size:12,className:"animate-spin"}),s==="zh"?"确认删除":"Confirm Delete"]})]})]})})]})}export{Se as CourseManagement};
1
+ import{r as n,j as e}from"./vendor-react-DHoBZpn2.js";import{b as ae,E as f}from"./index-Bc9003lB.js";import{B as j,ac as ie,aZ as ne,an as I,b1 as T,X as oe,a2 as le,U as O,c0 as de,c1 as ce,x as xe,y as me,ai as ge,c as N,be as he,af as P,T as ue}from"./vendor-icons-CaXLq01o.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";function pe(s){if(typeof s!="string")return"";let a=s;return a=a.replace(/<(think|thinking|reasoning|analysis)(?:\s+[^>]*)?>[\s\S]*?<\/\1>/gi,""),a=a.replace(/<(think|thinking|reasoning|analysis)(?:\s+[^>]*)?>[\s\S]*$/gi,""),a=a.replace(/```(?:think|thinking|reasoning|analysis)[\s\S]*?```/gi,""),a=a.replace(/^```(?:json|markdown|md)?\s*/i,"").replace(/```\s*$/i,""),a.trim()}function be(s,a=160){if(!s||typeof s!="string")return"";let r=pe(s);return r?(r=r.replace(/```[\s\S]*?```/g," "),r=r.replace(/!\[.*?\]\(.*?\)/g,""),r=r.replace(/\[(.*?)\]\(.*?\)/g,"$1"),r=r.replace(/^#+\s+/gm,""),r=r.replace(/^\s*[-*+]\s+/gm,""),r=r.replace(/^\s*\d+\.\s+/gm,""),r=r.replace(/^\s*>\s+/gm,""),r=r.replace(/\*\*([^*]+)\*\*/g,"$1"),r=r.replace(/\*([^*]+)\*/g,"$1"),r=r.replace(/__([^_]+)__/g,"$1"),r=r.replace(/_([^_]+)_/g,"$1"),r=r.replace(/~~(.*?)~~/g,"$1"),r=r.replace(/`([^`]+)`/g,"$1"),r=r.replace(/\s+/g," ").trim(),r.length<=a?r:r.slice(0,a).trimEnd()+"..."):""}function Se(){const{lang:s,session:a,lessons:r,lessonsSearchQuery:h,setLessonsSearchQuery:u,lessonsSortOrder:A,setLessonsSortOrder:F,filteredAndSortedLessons:p,isImportLessonsOpen:ye,setIsImportLessonsOpen:M,isCourseWizardOpen:fe,setIsCourseWizardOpen:R,onViewCourse:v,onDeleteCourse:W,onCopyCourse:U,filterEnrollment:C,setFilterEnrollment:B,filterHasContent:w,setFilterHasContent:H,filterThisMonth:z,setFilterThisMonth:Q,copyingLessonId:V,fetchLessons:X,downloadCourseTemplate:Z,exportCoursePackage:J}=ae(),q=()=>M(!0),k=()=>R(!0),i=a,G=i?.username==="admin"||i?.userId==="usr_admin"||i?.role==="administrator"||i?.subRole==="administrator",[b,K]=n.useState(!1),[o,y]=n.useState(null),[l,d]=n.useState(null),[S,L]=n.useState(!1),[Y,_]=n.useState(!1),[x,$]=n.useState(null),[D,E]=n.useState(null),ee=async t=>{E(t.id);try{await J(t.id)}finally{E(null)}},se=t=>{navigator.clipboard.writeText(t).then(()=>{$(t),setTimeout(()=>$(null),1500)})},te=async t=>{y(t),d(null),_(!0);try{const m=await fetch(`/api/lessons/${t.id}/stats`);if(m.ok){const c=await m.json();d(c)}}catch{d({whiteboardCount:0,scheduleCount:0,enrollmentCount:0,assignmentCount:0})}finally{_(!1)}},re=async()=>{if(o){L(!0);try{await W(o.id),y(null),d(null)}finally{L(!1)}}};return e.jsxs("div",{className:"flex-1 flex flex-col gap-6 h-full overflow-y-auto",children:[e.jsxs("div",{className:"flex-1 bg-white border border-gray-200 rounded-xl shadow-sm flex flex-col min-h-0",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between shrink-0",children:[e.jsxs("h3",{className:"font-medium text-gray-700 flex items-center gap-2",children:[e.jsx(j,{size:16,className:"text-gray-400"}),s==="zh"?"课程与教学环节管理 (SQLite)":"Courses & Lessons Management"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{id:"import-lessons-csv-btn",onClick:q,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 font-semibold rounded-lg shadow-3xs transition-all hover:shadow-xs hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(ie,{size:14}),s==="zh"?"批量导入课程":"Import Lessons"]}),e.jsxs("button",{id:"download-course-template-btn",onClick:()=>void Z(),title:s==="zh"?"下载自包含的课程模板(教学环节 + 全部预设组件 + PDF/PPTX 课件附件)":"Download a self-contained course template (segments + every preset component + PDF/PPTX assets)",className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-emerald-50 hover:bg-emerald-100 text-emerald-700 border border-emerald-200 font-semibold rounded-lg shadow-3xs transition-all hover:shadow-xs hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(ne,{size:14}),s==="zh"?"下载课程模板":"Course Template"]}),e.jsxs("button",{id:"add-course-wizard-btn",onClick:k,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-lg shadow-sm transition-all hover:shadow-md hover:-translate-y-0.5 cursor-pointer",children:[e.jsx(I,{size:14}),s==="zh"?"手动添加课程 (向导)":"Add Course Wizard"]}),e.jsx(f,{slot:"course.list.toolbar.action",slotProps:{lang:s,onRefresh:X}})]})]}),r.length>0&&e.jsxs("div",{className:"px-5 py-3.5 border-b border-gray-100 bg-gray-50/50 flex flex-col sm:flex-row items-center justify-between gap-3 shrink-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3 w-full sm:w-auto",children:[e.jsxs("div",{className:"relative w-full sm:w-64",children:[e.jsx("span",{className:"absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-gray-400",children:e.jsx(T,{size:14})}),e.jsx("input",{type:"text",placeholder:"Search courses by title...",value:h,onChange:t=>u(t.target.value),className:"w-full pl-9 pr-8 py-1.5 text-xs bg-white border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 shadow-sm"}),h&&e.jsx("button",{onClick:()=>u(""),className:"absolute inset-y-0 right-0 flex items-center pr-2.5 text-gray-400 hover:text-gray-600",children:e.jsx(oe,{size:12,className:"bg-gray-100 hover:bg-gray-200 rounded-full p-0.5"})})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs font-bold text-subtle uppercase tracking-wider",children:s==="zh"?"排序方式:":"Sort by:"}),e.jsxs("select",{"aria-label":s==="zh"?"课程排序方式":"Course sort order",value:A,onChange:t=>F(t.target.value),className:"bg-white border border-gray-200 text-xs text-gray-755 font-bold px-2.5 py-1.5 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-sm",id:"courses-sort-select",children:[e.jsx("option",{value:"recent",children:s==="zh"?"最新创建":"Most Recent"}),e.jsx("option",{value:"alphabetical",children:s==="zh"?"按名称 (A-Z)":"Alphabetical (A-Z)"}),e.jsx("option",{value:"enrollment",children:s==="zh"?"学生选课人次":"Student Enrollment Count"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("button",{onClick:()=>K(!b),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${b?"bg-indigo-600 text-white border-indigo-600 shadow-2xs":"bg-white text-gray-600 border-gray-200 hover:border-gray-300"}`,title:s==="zh"?"只看我创建的课程":"Only show courses created by me",children:[e.jsx(le,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"我的备课":"My Courses"]}),e.jsxs("button",{onClick:()=>B(!C),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${C?"bg-emerald-50 text-emerald-700 border-emerald-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:[e.jsx(O,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"有人选":"Enrolled"]}),e.jsxs("button",{onClick:()=>H(!w),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${w?"bg-indigo-50 text-indigo-700 border-indigo-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:[e.jsx(j,{size:11,className:"inline mr-0.5 -mt-0.5"}),s==="zh"?"有内容":"Has Content"]}),e.jsx("button",{onClick:()=>Q(!z),className:`px-2 py-1 text-xs font-bold rounded-md border transition-all cursor-pointer ${z?"bg-amber-50 text-amber-700 border-amber-200":"bg-white text-gray-500 border-gray-200 hover:border-gray-300"}`,children:s==="zh"?"本月":"This Month"})]}),e.jsxs("div",{className:"text-xs font-semibold text-gray-500",children:["Found ",e.jsx("span",{className:"text-indigo-650 font-bold",children:p.length})," of"," ",e.jsx("span",{className:"text-gray-700 font-bold",children:r.length})," course",r.length===1?"":"s"]})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:r.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 min-h-[300px]",children:[e.jsx(j,{size:48,className:"mb-4 opacity-30 text-indigo-500"}),e.jsx("h3",{className:"text-lg font-bold text-gray-800",children:s==="zh"?"暂无可用课程":"No Courses Available"}),e.jsx("p",{className:"mt-2 text-sm text-gray-500 text-center max-w-xs",children:s==="zh"?"系统中暂未部署任何课程。请通过下方按钮启动添加向导指南。":"There are no courses active in the system yet. Build your first curriculum!"}),e.jsxs("button",{id:"empty-add-course-btn",onClick:k,className:"mt-5 flex items-center gap-2 px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white font-bold rounded-xl shadow-md transition-all cursor-pointer",children:[e.jsx(I,{size:16}),s==="zh"?"使用向导指南来创建新课程":"Create Course via Wizard"]})]}):p.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-full py-12 text-gray-450 text-center",children:[e.jsx(T,{size:44,className:"mb-3 opacity-30 text-gray-450"}),e.jsxs("h4",{className:"font-semibold text-gray-700 text-sm",children:['No Courses Match "',h,'"']}),e.jsx("p",{className:"text-xs text-gray-500 mt-1 max-w-xs",children:"Double-check the spelling or try searching for another curriculum keyword."}),e.jsx("button",{onClick:()=>u(""),className:"mt-3 text-xs bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 font-semibold px-3 py-1.5 rounded-lg transition-colors",children:"Clear Search Filter"})]}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:p.filter(t=>b?!t.creator_id||t.creator_id===i?.userId||t.creator_id===i?.username:!0).map(t=>{const m=V===t.id,c=!t.creator_id||t.creator_id===i?.userId||t.creator_id===i?.username,g=G||c;return e.jsxs("div",{className:`border border-gray-200 hover:border-indigo-300 rounded-xl p-4 flex flex-col bg-gray-50/50 hover:shadow-md transition-all ${m?"opacity-60 pointer-events-none":""}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2 gap-2",children:[e.jsx("div",{className:"font-semibold text-gray-800 text-lg truncate cursor-pointer hover:text-indigo-600 transition-colors",title:t.title,onClick:()=>v(t.id),children:t.title}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx(f,{slot:"course.card.badge",slotProps:{course:t}}),t.creator_name?e.jsxs("span",{className:`text-xs font-medium px-1.5 py-0.5 rounded border flex items-center gap-0.5 ${c?"bg-indigo-50 text-indigo-700 border-indigo-200 font-semibold":"bg-slate-100 text-slate-600 border-slate-200"}`,title:s==="zh"?`创建教师: ${t.creator_name}`:`Created by: ${t.creator_name}`,children:[c?"👑 ":"👤 ",t.creator_name]}):null,e.jsxs("span",{className:"inline-flex items-center gap-1 bg-indigo-50 text-indigo-700 px-1.5 py-0.5 border border-indigo-100 rounded text-xs font-bold",children:[e.jsx(O,{size:10,className:"text-indigo-500"}),t.enrollment_count||0]})]})]}),e.jsx("div",{className:"text-sm text-gray-500 line-clamp-3 mb-4 flex-1 leading-relaxed",children:be(t.content)||e.jsx("span",{className:"italic text-gray-400",children:s==="zh"?"暂无课程大纲与简介":"No outline or summary available."})}),e.jsxs("div",{className:"flex justify-between items-center mt-auto",children:[e.jsxs("button",{onClick:()=>se(t.id),className:`flex items-center gap-1 text-xs rounded px-1.5 py-0.5 transition-all cursor-pointer ${x===t.id?"text-emerald-700 bg-emerald-50 border border-emerald-200":"text-subtle hover:text-indigo-600 hover:bg-indigo-50 border border-transparent"}`,title:x===t.id?s==="zh"?"已复制!":"Copied!":s==="zh"?"复制课程 ID":"Copy Course ID",children:[x===t.id?e.jsx(de,{size:12}):e.jsx(ce,{size:12}),e.jsx("span",{className:"font-mono",children:x===t.id?s==="zh"?"已复制!":"Copied!":`${t.id.substring(0,8)}…`})]}),e.jsxs("div",{className:"flex items-center gap-0.5",children:[e.jsx("button",{onClick:()=>v(t.id),className:"p-1.5 text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 rounded transition-colors cursor-pointer",title:g?s==="zh"?"查看与编辑":"View & Edit":s==="zh"?"查看只读 (他人课程)":"View Read-Only",children:g?e.jsx(xe,{size:15}):e.jsx(me,{size:15})}),e.jsx("button",{onClick:()=>U(t.id),className:"p-1.5 text-gray-400 hover:text-emerald-600 hover:bg-emerald-50 rounded transition-colors cursor-pointer",title:s==="zh"?"克隆为我的备课":"Clone Course",children:e.jsx(ge,{size:14})}),g&&e.jsx("button",{onClick:()=>void ee(t),disabled:D===t.id,className:"p-1.5 text-gray-400 hover:text-sky-600 hover:bg-sky-50 rounded transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-wait",title:s==="zh"?"导出为课程包(教学环节 + 白板元素 + 内联附件,可拖回导入框)":"Export as course package (segments + whiteboard elements + embedded assets)",children:D===t.id?e.jsx(N,{size:14,className:"animate-spin"}):e.jsx(he,{size:14})}),g?e.jsx("button",{onClick:()=>te(t),className:"p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors cursor-pointer",title:s==="zh"?"删除课程":"Delete Course",children:e.jsx(P,{size:14})}):e.jsx("span",{className:"p-1.5 text-gray-300 cursor-not-allowed",title:s==="zh"?"仅创建教师或管理员可删除":"Only creator or admin can delete",children:e.jsx(P,{size:14})}),e.jsx(f,{slot:"course.card.action",slotProps:{course:t,lang:s}})]})]})]},t.id)})})})]}),o&&e.jsx("div",{className:"fixed inset-0 bg-black/40 backdrop-blur-[2px] flex items-center justify-center z-[9999] p-4",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-2xl max-w-md w-full border border-gray-100 overflow-hidden",children:[e.jsxs("div",{className:"px-5 py-4 border-b border-gray-100 bg-red-50 flex items-center gap-2",children:[e.jsx(ue,{size:18,className:"text-red-600"}),e.jsx("h3",{className:"font-bold text-red-800 text-sm",children:s==="zh"?"确认删除课程":"Confirm Course Deletion"})]}),e.jsxs("div",{className:"p-5 space-y-3",children:[e.jsx("p",{className:"text-sm text-gray-700",children:s==="zh"?e.jsxs(e.Fragment,{children:["确定要删除课程 ",e.jsx("span",{className:"font-bold text-red-600",children:o.title})," 吗?"]}):e.jsxs(e.Fragment,{children:["Are you sure you want to delete ",e.jsx("span",{className:"font-bold text-red-600",children:o.title}),"?"]})}),e.jsx("p",{className:"text-xs text-red-600 font-medium",children:s==="zh"?"此操作不可撤销,将删除课程的所有关联数据。":"This action is irreversible and will delete all associated data."}),Y?e.jsxs("div",{className:"flex items-center gap-2 text-xs text-gray-500 py-2",children:[e.jsx(N,{size:14,className:"animate-spin"}),s==="zh"?"正在统计关联数据...":"Counting related data..."]}):l?e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3 space-y-1.5 text-xs",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"白板元素":"Whiteboard Elements"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.whiteboardCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"排课记录":"Schedules"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.scheduleCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"选课学生":"Enrollments"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.enrollmentCount})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-gray-600",children:s==="zh"?"作业任务":"Assignments"}),e.jsx("span",{className:"font-bold text-gray-800",children:l.assignmentCount})]})]}):null]}),e.jsxs("div",{className:"px-5 py-3 border-t border-gray-100 bg-gray-50 flex justify-end gap-2",children:[e.jsx("button",{onClick:()=>{y(null),d(null)},className:"px-4 py-2 text-xs font-medium text-gray-600 hover:bg-gray-100 border border-gray-200 rounded-lg transition-colors cursor-pointer",children:s==="zh"?"取消":"Cancel"}),e.jsxs("button",{onClick:re,disabled:S,className:"px-4 py-2 text-xs font-bold text-white bg-red-600 hover:bg-red-700 rounded-lg transition-colors cursor-pointer disabled:opacity-50 flex items-center gap-1.5",children:[S&&e.jsx(N,{size:12,className:"animate-spin"}),s==="zh"?"确认删除":"Confirm Delete"]})]})]})})]})}export{Se as CourseManagement};
@@ -1,3 +1,3 @@
1
- import{j as e,r as y}from"./vendor-react-DHoBZpn2.js";import{m as I,E,M as L}from"./index-DuxQtTr9.js";import{B as f,V as j,u as M,an as O,c as v,h as R,as as z,k as $}from"./vendor-icons-DLOPlM4i.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";const w={1:{zh:"内容选题",en:"Background"},2:{zh:"课堂脉络",en:"Timeslots"},3:{zh:"编写大纲",en:"Syllabus"},4:{zh:"总览部署",en:"Deploy"}};function Q(N){const{isCourseWizardOpen:k,setIsCourseWizardOpen:C,lang:t,wizardStep:i,setWizardStep:m,wizardIsSubmitting:x,wizardCourseTitle:g,setWizardCourseTitle:S,wizardCourseDescription:h,setWizardCourseDescription:A,wizardCourseCategory:o,setWizardCourseCategory:P,wizardCourseTimeline:a,setWizardCourseTimeline:c,wizardCourseContent:p,setWizardCourseContent:D,addToast:b,wizardIsGeneratingOutline:u,handleGenerateOutline:T,handleDeployWizardCourse:W}=N;return e.jsx(e.Fragment,{children:k&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/50 backdrop-blur-sm flex items-center justify-center p-4 md:p-6 z-50 overflow-y-auto text-gray-850",children:e.jsxs(I.div,{initial:{opacity:0,y:15,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:10,scale:.98},className:"bg-white border text-gray-900 border-gray-250 rounded-2xl shadow-2xl w-full max-w-4xl flex flex-col overflow-hidden max-h-[92vh] font-sans text-left",children:[e.jsxs("div",{className:"p-4 md:p-5 border-b border-gray-100 flex items-center justify-between bg-slate-50 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-indigo-50 border border-indigo-100 rounded-lg text-indigo-650",children:e.jsx(f,{size:20,className:"animate-pulse"})}),e.jsxs("div",{children:[e.jsx("h2",{className:"font-bold text-gray-850 text-base md:text-lg",children:t==="zh"?"⭐ 互动课程发布与时间轴向导":"⭐ Course Design Guide & Wizard"}),e.jsx("p",{className:"text-xs text-gray-500 mt-0.5",children:t==="zh"?"遵循系统设计法,逐步构建您的学科专属教案与课堂时间轴流程。":"Follow best practices to define curriculum content, timeline segments, and deploy."})]})]}),e.jsx("button",{onClick:()=>C(!1),className:"text-gray-400 hover:text-gray-650 font-bold p-1 rounded-lg hover:bg-gray-150 transition-all text-xl leading-none",children:"×"})]}),e.jsx("div",{className:"px-6 py-4.5 border-b border-gray-50 bg-slate-50/50 flex items-center justify-between gap-2 shrink-0 select-none",children:[{step:1,zh:"1内容选题",en:"1 Background"},{step:2,zh:"2课堂脉络",en:"2 Timeslots"},{step:3,zh:"3编写大纲",en:"3 Syllabus"},{step:4,zh:"4总览部署",en:"4 Deploy"}].map((r,n)=>{const l=i===r.step,s=i>r.step;return e.jsxs(y.Fragment,{children:[e.jsxs("div",{onClick:()=>!x&&m(r.step),className:`flex items-center gap-2 cursor-pointer transition-all ${l?"text-indigo-650 font-boldScale":s?"text-emerald-600 font-medium":"text-gray-400 hover:text-gray-600"}`,children:[e.jsx("div",{className:`w-5 h-5 rounded-full flex items-center justify-center text-xs border ${l?"bg-indigo-600 border-indigo-600 text-white shadow-xs font-bold":s?"bg-emerald-50 border-emerald-500 text-emerald-600 font-bold":"bg-white border-gray-250 text-gray-500"}`,children:s?"✓":r.step}),e.jsx("span",{className:"text-xs font-semibold hidden sm:inline",children:t==="zh"?r.zh:r.en})]}),n<3&&e.jsx("div",{className:`flex-1 h-0.5 max-w-[40px] md:max-w-none transition-all ${i>r.step?"bg-emerald-500":"bg-gray-200"}`})]},r.step)})}),e.jsxs("div",{className:"flex-grow overflow-y-auto p-5 md:p-6 space-y-5",children:[i===1&&e.jsxs("div",{className:"space-y-4 animate-in fade-in duration-200 text-left",children:[e.jsxs("div",{className:"bg-indigo-50/70 py-3.5 px-4.5 rounded-xl border border-indigo-100 text-xs text-indigo-750 font-sans leading-relaxed flex items-start gap-2",children:[e.jsx(j,{size:16,className:"text-indigo-500 shrink-0 mt-0.5 animate-bounce"}),e.jsxs("div",{children:[e.jsx("strong",{children:t==="zh"?"设计理念:":"Instructional ConceptTip:"}),e.jsx("p",{className:"mt-0.5",children:t==="zh"?"一个高品质的课程往往始于明确的选题背景。选择适当的学科科目分类,系统不仅会按您的选择在后续步骤推荐量身定做的教案摸板,还可以一键预装适合该学科的课堂互动时间轴模板。":"Selecting a clear title and specific subject category helps pre-populate customized Markdown content outlines and specialized scheduling presets."})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6 font-sans",children:[e.jsxs("div",{className:"md:col-span-2 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"📍 课程/课件名称 *":"📍 Course Title *"}),e.jsx("input",{type:"text",required:!0,value:g,onChange:r=>S(r.target.value),placeholder:t==="zh"?"例:西方哲学:康德的三大批判、Python编程入门、高中物理电路并联原理":"e.g. Introduction to regressions, Western Philosophies, Lever Principles",className:"w-full px-4 py-3 border border-gray-250 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 text-sm shadow-xs"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"🎯 课程设计简介与要点说明 (Objectives)":"🎯 Description & Lesson Objectives"}),e.jsx("textarea",{rows:4,value:h,onChange:r=>A(r.target.value),placeholder:t==="zh"?"在此处编写您的授课背景、面向学段及最关键的 2-3 个核心教学总目标。":"Write a short description stating learning outcomes and student prerequisite goals.",className:"w-full p-4 border border-gray-255 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 text-sm shadow-xs resize-none"})]})]}),e.jsxs("div",{className:"col-span-1 border-l border-gray-100 md:pl-6 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-2",children:t==="zh"?"🎨 学部科目分类":"🎨 Subject Category"}),e.jsxs("select",{value:o,onChange:r=>{P(r.target.value)},className:"w-full bg-white border border-gray-250 text-gray-755 font-bold px-3 py-2.5 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-xs text-sm cursor-pointer",children:[e.jsx("option",{value:"Mathematics",children:t==="zh"?"📐 基础数学与几何":"📐 Mathematics"}),e.jsx("option",{value:"ComputerScience",children:t==="zh"?"💻 计算机软件与人工智能":"💻 Computer Science"}),e.jsx("option",{value:"Literature",children:t==="zh"?"✍️ 语言文字与阅读理解":"✍️ Literature & Writing"}),e.jsx("option",{value:"Physics",children:t==="zh"?"⚡ 物理实验与自然探索":"⚡ Physics & Science"}),e.jsx("option",{value:"History",children:t==="zh"?"🏛️ 历史脉络与人地分析":"🏛️ History & Humanities"}),e.jsx("option",{value:"Art",children:t==="zh"?"🎨 交互设计与先锋创意艺术":"🎨 Visual Arts & Design"}),e.jsx("option",{value:"Other",children:t==="zh"?"🔮 交叉素养与综合学习":"🔮 General & Other"})]})]}),e.jsxs("div",{className:"bg-slate-50 p-4 rounded-xl border border-gray-100 space-y-2 select-none text-left",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider block",children:t==="zh"?"科目时间轴专家建议":"SUBJECT HEURISTICS"}),e.jsxs("div",{className:"text-xs text-gray-600 leading-relaxed font-sans mt-1",children:[o==="Mathematics"&&(t==="zh"?"💡 数学:偏向理论推演。推荐 15分公式精讲 + 20分黑板实践互动 + 5分随堂检测。":"💡 Math recommends: 15m Core Lecture + 20m Practice + 5m Check."),o==="ComputerScience"&&(t==="zh"?"💡 计算机:偏重编码体验。推荐 15分白板代码推演 + 20分终端实验与分享 + 5分演示。":"💡 CS recommends: 15m Algorithms + 20m Interactive workshops + 5m Demo."),o==="Literature"&&(t==="zh"?"💡 语文文学:注重文本深度。推荐 10分范文研习 + 20分分组思辨 + 10分迁移练笔。":"💡 Lit recommends: 10m Reading Analysis + 20m Collaborative Discussions + 10m Writing."),o==="Physics"&&(t==="zh"?"💡 科学类:逻辑导向。推荐 10分虚拟视频实验 + 20分机理讲解 + 10分钟随堂答卷。":"💡 Science recommends: 10m virtual showcase + 20m principles + 10m evaluation."),o==="History"&&(t==="zh"?"💡 历史人文:情景引入。推荐 10分人文画卷重塑 + 20分史实论驳辩论 + 10分钟史料评析。":"💡 History recommends: 10m Context Mapping + 20m Interactive Debate + 10m Source Analysis."),o==="Art"&&(t==="zh"?"💡 视觉创意:自由度高。推荐 10分美术鉴赏 + 25分白板手绘画布互动体验 + 5分互评。":"💡 Art recommends: 10m Aesthetics + 25m real-time board drawing + 5m Peer Review."),o==="Other"&&(t==="zh"?"💡 其他科目:均分各小节时间,循序渐进,打造完整的教学循环闭环。":"💡 Generic: Divide evenly into sequential warm-up, core presentation and quiz.")]})]})]})]})]}),i===2&&e.jsxs("div",{className:"space-y-5 animate-in fade-in duration-200 text-left font-sans",children:[e.jsxs("div",{className:"bg-emerald-50/40 py-3.5 px-4.5 rounded-xl border border-emerald-100 text-xs text-emerald-850 leading-relaxed flex items-start gap-2 text-left",children:[e.jsx(M,{size:16,className:"text-emerald-555 shrink-0 mt-0.5 animate-pulse"}),e.jsxs("div",{children:[e.jsx("strong",{children:t==="zh"?"专家课堂时间轴预设:":"Dynamic Class Presets:"}),e.jsx("p",{className:"mt-0.5",children:t==="zh"?"好的教授节奏必须动静相宜。以下提供三种国际领先的精品课件时间节点设计,点击即可一键刷装配置。您也可以在下方自由增删和重新指定每个环节的长短!":"Curating temporal context maximizes classroom retention. Load from predefined templates or tweak the active steps on the dynamic table."})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"💡 点击应用典型课堂框架模板 (Quick Apply)":"💡 Click to Auto-Apply Structure Presets"}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[{id:"preset_standard",title:t==="zh"?"经典 5-15-15-5 讲授模式":"Traditional 5-15-15-5 Lecture Paradigm",desc:t==="zh"?"由浅入深:先通过场景导入,后精讲,接着在白板配合大屏进行演练。":"Perfect dynamic for most standard classes.",segments:[{id:"seg-preset-1",title:"Course Orientation / 课堂导入",type:"intro",duration:"5m",color:"bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100",notes:"Warm up topic"},{id:"seg-preset-2",title:"Subject Core Lecture / 核心理论精讲",type:"lecture",duration:"15m",color:"bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100",notes:"Main content slide"},{id:"seg-preset-3",title:"Interactive Lab Work / 随堂协同演练",type:"practice",duration:"15m",color:"bg-green-50 text-green-700 border-green-200 hover:bg-green-100",notes:"Exercises & questions"},{id:"seg-preset-4",title:"Wrap up / 课堂成果总结与答疑",type:"summary",duration:"5m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Check answer notes"}]},{id:"preset_seminar",title:t==="zh"?"主题讨论工作坊模式":"Active Discussion Workshop",desc:t==="zh"?"协同探究:教师5分钟破冰,学生13分钟小组演练,12分钟对决汇报,10分钟定级。":"Discussion and presentation heavy layout.",segments:[{id:"seg-preset-5",title:"Debate Scenario Brief / 讨论情境简述",type:"intro",duration:"5m",color:"bg-amber-50 text-amber-700 border-amber-200 hover:bg-amber-100",notes:"Define debate metrics"},{id:"seg-preset-6",title:"Cooperative Ideation / 精英白板协作设计",type:"practice",duration:"13m",color:"bg-green-50 text-green-700 border-green-200 hover:bg-green-100",notes:"Joint workspace analysis"},{id:"seg-preset-7",title:"Student Team Presentation / 各小组交互汇报",type:"lecture",duration:"12m",color:"bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100",notes:"Group screen sharing"},{id:"seg-preset-8",title:"Review & Grade Feedback / 教师深度对标点评",type:"summary",duration:"10m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Score reviews"}]},{id:"preset_flipped",title:t==="zh"?"翻转课堂高强度训练":"Targeted Problem-Solving Sprint",desc:t==="zh"?"应试/解惑突破:8分钟温习,14分钟重难盲点攻坚,13分钟专项题演习,5分钟固化。":"Perfect for exams and targeted training courses.",segments:[{id:"seg-preset-9",title:"Blind Spot Evaluation / 温史自学效果自测",type:"intro",duration:"8m",color:"bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100",notes:"Scan quiz"},{id:"seg-preset-10",title:"Advanced Principle Explores / 重难考点极限拆解",type:"lecture",duration:"14m",color:"bg-rose-50 text-rose-700 border-rose-200 hover:bg-rose-100",notes:"Analyse weak metrics"},{id:"seg-preset-11",title:"Mock Solving Battle / 核心精选题实操对抗",type:"practice",duration:"13m",color:"bg-emerald-50 text-emerald-700 border-emerald-200 hover:bg-emerald-100",notes:"Sprint workout"},{id:"seg-preset-12",title:"Anchor Recap / 知识网架构网节点固化",type:"summary",duration:"5m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Highlight checklist"}]}].map(r=>e.jsxs("button",{type:"button",onClick:()=>{c(r.segments),b(t==="zh"?"预设已刷装":"Preset Configured",t==="zh"?`已将《${r.title}》应用到您当前设计的课程中。`:`Assigned "${r.title}" timeslots.`,"success")},className:"bg-white border rounded-xl p-3 text-left transition-all hover:bg-indigo-50/20 hover:border-indigo-400 cursor-pointer active:scale-98",children:[e.jsx("div",{className:"font-bold text-gray-800 text-xs sm:text-sm",children:r.title}),e.jsx("div",{className:"text-xs text-gray-400 mt-1.5 leading-relaxed",children:r.desc})]},r.id))})]}),e.jsx("div",{className:"mt-1",children:e.jsx(E,{slot:"course.wizard.quick_apply",lang:t,slotProps:{lang:t,wizardCourseTitle:g,wizardCourseCategory:o,wizardCourseTimeline:a,setWizardCourseTimeline:c,addToast:b}})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2 select-none",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider",children:t==="zh"?"📌 流程时间卡编辑 (拖拽或直接对表格字段赋值)":"📌 Custom Timeslot Table (Edit fields directly)"}),e.jsxs("button",{type:"button",onClick:()=>{const r={id:`seg-w-custom-${Date.now()}`,title:t==="zh"?`自理授课阶段 ${a.length+1}`:`Interactive Step ${a.length+1}`,type:"practice",duration:"10m",color:"bg-slate-50 text-slate-700 border-slate-200 hover:bg-slate-100",notes:""};c([...a,r])},className:"flex items-center gap-1 text-xs font-bold text-indigo-600 hover:text-indigo-800 cursor-pointer",children:[e.jsx(O,{size:12})," ",t==="zh"?"增设阶段":"Append Phase"]})]}),e.jsx("div",{className:"space-y-2 border border-gray-150 rounded-xl p-3.5 bg-gray-50/50",children:a.map((r,n)=>e.jsxs("div",{className:"flex flex-col sm:flex-row items-center gap-3 bg-white border border-gray-200 rounded-lg p-2.5 shadow-xs",children:[e.jsxs("div",{className:"flex items-center gap-2 w-full sm:w-auto",children:[e.jsx("span",{className:"w-5 h-5 rounded-full bg-slate-100 flex items-center justify-center text-xs text-gray-500 font-bold shrink-0",children:n+1}),e.jsx("input",{type:"text",value:r.title,onChange:l=>{const s=[...a];s[n].title=l.target.value,c(s)},className:"font-bold text-xs text-gray-800 bg-transparent border-b border-transparent hover:border-gray-200 focus:border-indigo-500 py-0.5 px-1 focus:outline-none focus:bg-gray-50/50 rounded flex-1 sm:w-56",placeholder:"Phase Title"})]}),e.jsxs("div",{className:"flex items-center gap-2.5 w-full sm:w-auto justify-end sm:ml-auto",children:[e.jsxs("div",{className:"flex items-center gap-1 bg-slate-50 border border-gray-200 rounded px-2 py-0.5 shrink-0",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400",children:"时长:"}),e.jsx("input",{type:"text",value:r.duration,onChange:l=>{const s=[...a];s[n].duration=l.target.value,c(s)},className:"w-8 text-xs text-gray-800 font-extrabold bg-transparent text-center focus:outline-none"})]}),e.jsxs("select",{value:r.type,onChange:l=>{const s=l.target.value,d=[...a];d[n].type=s,s==="intro"?d[n].color="bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100":s==="lecture"?d[n].color="bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100":s==="practice"?d[n].color="bg-green-50 text-green-700 border-green-200 hover:bg-green-100":s==="summary"?d[n].color="bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100":d[n].color="bg-gray-50 text-gray-700 border-gray-205 hover:bg-gray-100",c(d)},className:"bg-slate-50 border border-gray-200 text-xs font-bold text-gray-600 rounded p-1 focus:outline-none cursor-pointer",children:[e.jsx("option",{value:"intro",children:t==="zh"?"温习 / 导入":"Warm-up / Intro"}),e.jsx("option",{value:"lecture",children:t==="zh"?"主体 / 精讲":"Core Lecture"}),e.jsx("option",{value:"practice",children:t==="zh"?"交互白板练习":"Practice Workshop"}),e.jsx("option",{value:"summary",children:t==="zh"?"总结 / 定级":"Wrap-up / Recap"})]}),e.jsx("button",{type:"button",onClick:()=>{if(a.length<=1){alert(t==="zh"?"请保留至少一个核心环节!":"At least one segment must exist.");return}const l=a.filter((s,d)=>d!==n);c(l)},className:"text-gray-400 hover:text-rose-600 font-bold p-1 cursor-pointer text-sm select-none",title:"Delete this segment",children:"×"})]})]},r.id))}),e.jsxs("div",{className:"mt-2 text-xs text-right text-gray-500 font-mono select-none",children:[t==="zh"?"📈 环节累加公式:":"📈 Dynamic aggregation formula: ",e.jsx("span",{className:"text-gray-800 font-semibold",children:a.map(r=>r.duration).join(" + ")})]})]})]}),i===3&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 animate-in fade-in duration-200 font-sans text-left",children:[e.jsxs("div",{className:"space-y-3 flex flex-col h-full min-h-[360px] text-left",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-2",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider select-none shrink-0",children:t==="zh"?"✏️ 使用 Markdown 语法编写课时材料":"✏️ Lesson Materials (Markdown)"}),e.jsxs("button",{type:"button",onClick:()=>void T(),disabled:u,className:"flex items-center gap-1 text-xs bg-indigo-50 border border-indigo-100 text-indigo-755 hover:bg-indigo-100 px-3 py-1 rounded-lg transition-colors font-bold cursor-pointer disabled:opacity-60 disabled:cursor-not-allowed",children:[u?e.jsx(v,{size:13,className:"text-indigo-500 animate-spin"}):e.jsx(j,{size:13,className:"text-indigo-500"}),u?t==="zh"?"AI 正在生成大纲...":"AI is writing your outline...":t==="zh"?"✨ AI 生成专家级教学大纲":"✨ AI-Generate Syllabus"]})]}),e.jsx("textarea",{rows:14,value:p,onChange:r=>D(r.target.value),placeholder:t==="zh"?`# 西方哲学三大经典原理
1
+ import{j as e,r as y}from"./vendor-react-DHoBZpn2.js";import{m as I,E,M as L}from"./index-Bc9003lB.js";import{B as f,V as j,u as M,an as O,c as v,h as R,as as z,k as $}from"./vendor-icons-CaXLq01o.js";import"./vendor-utils-BxOuk3id.js";import"./vendor-pdf-DVWGghIL.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-skggaP9D.js";const w={1:{zh:"内容选题",en:"Background"},2:{zh:"课堂脉络",en:"Timeslots"},3:{zh:"编写大纲",en:"Syllabus"},4:{zh:"总览部署",en:"Deploy"}};function Q(N){const{isCourseWizardOpen:k,setIsCourseWizardOpen:C,lang:t,wizardStep:i,setWizardStep:m,wizardIsSubmitting:x,wizardCourseTitle:g,setWizardCourseTitle:S,wizardCourseDescription:h,setWizardCourseDescription:A,wizardCourseCategory:o,setWizardCourseCategory:P,wizardCourseTimeline:a,setWizardCourseTimeline:c,wizardCourseContent:p,setWizardCourseContent:D,addToast:b,wizardIsGeneratingOutline:u,handleGenerateOutline:T,handleDeployWizardCourse:W}=N;return e.jsx(e.Fragment,{children:k&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/50 backdrop-blur-sm flex items-center justify-center p-4 md:p-6 z-50 overflow-y-auto text-gray-850",children:e.jsxs(I.div,{initial:{opacity:0,y:15,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:10,scale:.98},className:"bg-white border text-gray-900 border-gray-250 rounded-2xl shadow-2xl w-full max-w-4xl flex flex-col overflow-hidden max-h-[92vh] font-sans text-left",children:[e.jsxs("div",{className:"p-4 md:p-5 border-b border-gray-100 flex items-center justify-between bg-slate-50 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-indigo-50 border border-indigo-100 rounded-lg text-indigo-650",children:e.jsx(f,{size:20,className:"animate-pulse"})}),e.jsxs("div",{children:[e.jsx("h2",{className:"font-bold text-gray-850 text-base md:text-lg",children:t==="zh"?"⭐ 互动课程发布与时间轴向导":"⭐ Course Design Guide & Wizard"}),e.jsx("p",{className:"text-xs text-gray-500 mt-0.5",children:t==="zh"?"遵循系统设计法,逐步构建您的学科专属教案与课堂时间轴流程。":"Follow best practices to define curriculum content, timeline segments, and deploy."})]})]}),e.jsx("button",{onClick:()=>C(!1),className:"text-gray-400 hover:text-gray-650 font-bold p-1 rounded-lg hover:bg-gray-150 transition-all text-xl leading-none",children:"×"})]}),e.jsx("div",{className:"px-6 py-4.5 border-b border-gray-50 bg-slate-50/50 flex items-center justify-between gap-2 shrink-0 select-none",children:[{step:1,zh:"1内容选题",en:"1 Background"},{step:2,zh:"2课堂脉络",en:"2 Timeslots"},{step:3,zh:"3编写大纲",en:"3 Syllabus"},{step:4,zh:"4总览部署",en:"4 Deploy"}].map((r,n)=>{const l=i===r.step,s=i>r.step;return e.jsxs(y.Fragment,{children:[e.jsxs("div",{onClick:()=>!x&&m(r.step),className:`flex items-center gap-2 cursor-pointer transition-all ${l?"text-indigo-650 font-boldScale":s?"text-emerald-600 font-medium":"text-gray-400 hover:text-gray-600"}`,children:[e.jsx("div",{className:`w-5 h-5 rounded-full flex items-center justify-center text-xs border ${l?"bg-indigo-600 border-indigo-600 text-white shadow-xs font-bold":s?"bg-emerald-50 border-emerald-500 text-emerald-600 font-bold":"bg-white border-gray-250 text-gray-500"}`,children:s?"✓":r.step}),e.jsx("span",{className:"text-xs font-semibold hidden sm:inline",children:t==="zh"?r.zh:r.en})]}),n<3&&e.jsx("div",{className:`flex-1 h-0.5 max-w-[40px] md:max-w-none transition-all ${i>r.step?"bg-emerald-500":"bg-gray-200"}`})]},r.step)})}),e.jsxs("div",{className:"flex-grow overflow-y-auto p-5 md:p-6 space-y-5",children:[i===1&&e.jsxs("div",{className:"space-y-4 animate-in fade-in duration-200 text-left",children:[e.jsxs("div",{className:"bg-indigo-50/70 py-3.5 px-4.5 rounded-xl border border-indigo-100 text-xs text-indigo-750 font-sans leading-relaxed flex items-start gap-2",children:[e.jsx(j,{size:16,className:"text-indigo-500 shrink-0 mt-0.5 animate-bounce"}),e.jsxs("div",{children:[e.jsx("strong",{children:t==="zh"?"设计理念:":"Instructional ConceptTip:"}),e.jsx("p",{className:"mt-0.5",children:t==="zh"?"一个高品质的课程往往始于明确的选题背景。选择适当的学科科目分类,系统不仅会按您的选择在后续步骤推荐量身定做的教案摸板,还可以一键预装适合该学科的课堂互动时间轴模板。":"Selecting a clear title and specific subject category helps pre-populate customized Markdown content outlines and specialized scheduling presets."})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6 font-sans",children:[e.jsxs("div",{className:"md:col-span-2 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"📍 课程/课件名称 *":"📍 Course Title *"}),e.jsx("input",{type:"text",required:!0,value:g,onChange:r=>S(r.target.value),placeholder:t==="zh"?"例:西方哲学:康德的三大批判、Python编程入门、高中物理电路并联原理":"e.g. Introduction to regressions, Western Philosophies, Lever Principles",className:"w-full px-4 py-3 border border-gray-250 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 text-sm shadow-xs"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"🎯 课程设计简介与要点说明 (Objectives)":"🎯 Description & Lesson Objectives"}),e.jsx("textarea",{rows:4,value:h,onChange:r=>A(r.target.value),placeholder:t==="zh"?"在此处编写您的授课背景、面向学段及最关键的 2-3 个核心教学总目标。":"Write a short description stating learning outcomes and student prerequisite goals.",className:"w-full p-4 border border-gray-255 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 text-gray-800 text-sm shadow-xs resize-none"})]})]}),e.jsxs("div",{className:"col-span-1 border-l border-gray-100 md:pl-6 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-2",children:t==="zh"?"🎨 学部科目分类":"🎨 Subject Category"}),e.jsxs("select",{value:o,onChange:r=>{P(r.target.value)},className:"w-full bg-white border border-gray-250 text-gray-755 font-bold px-3 py-2.5 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-xs text-sm cursor-pointer",children:[e.jsx("option",{value:"Mathematics",children:t==="zh"?"📐 基础数学与几何":"📐 Mathematics"}),e.jsx("option",{value:"ComputerScience",children:t==="zh"?"💻 计算机软件与人工智能":"💻 Computer Science"}),e.jsx("option",{value:"Literature",children:t==="zh"?"✍️ 语言文字与阅读理解":"✍️ Literature & Writing"}),e.jsx("option",{value:"Physics",children:t==="zh"?"⚡ 物理实验与自然探索":"⚡ Physics & Science"}),e.jsx("option",{value:"History",children:t==="zh"?"🏛️ 历史脉络与人地分析":"🏛️ History & Humanities"}),e.jsx("option",{value:"Art",children:t==="zh"?"🎨 交互设计与先锋创意艺术":"🎨 Visual Arts & Design"}),e.jsx("option",{value:"Other",children:t==="zh"?"🔮 交叉素养与综合学习":"🔮 General & Other"})]})]}),e.jsxs("div",{className:"bg-slate-50 p-4 rounded-xl border border-gray-100 space-y-2 select-none text-left",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider block",children:t==="zh"?"科目时间轴专家建议":"SUBJECT HEURISTICS"}),e.jsxs("div",{className:"text-xs text-gray-600 leading-relaxed font-sans mt-1",children:[o==="Mathematics"&&(t==="zh"?"💡 数学:偏向理论推演。推荐 15分公式精讲 + 20分黑板实践互动 + 5分随堂检测。":"💡 Math recommends: 15m Core Lecture + 20m Practice + 5m Check."),o==="ComputerScience"&&(t==="zh"?"💡 计算机:偏重编码体验。推荐 15分白板代码推演 + 20分终端实验与分享 + 5分演示。":"💡 CS recommends: 15m Algorithms + 20m Interactive workshops + 5m Demo."),o==="Literature"&&(t==="zh"?"💡 语文文学:注重文本深度。推荐 10分范文研习 + 20分分组思辨 + 10分迁移练笔。":"💡 Lit recommends: 10m Reading Analysis + 20m Collaborative Discussions + 10m Writing."),o==="Physics"&&(t==="zh"?"💡 科学类:逻辑导向。推荐 10分虚拟视频实验 + 20分机理讲解 + 10分钟随堂答卷。":"💡 Science recommends: 10m virtual showcase + 20m principles + 10m evaluation."),o==="History"&&(t==="zh"?"💡 历史人文:情景引入。推荐 10分人文画卷重塑 + 20分史实论驳辩论 + 10分钟史料评析。":"💡 History recommends: 10m Context Mapping + 20m Interactive Debate + 10m Source Analysis."),o==="Art"&&(t==="zh"?"💡 视觉创意:自由度高。推荐 10分美术鉴赏 + 25分白板手绘画布互动体验 + 5分互评。":"💡 Art recommends: 10m Aesthetics + 25m real-time board drawing + 5m Peer Review."),o==="Other"&&(t==="zh"?"💡 其他科目:均分各小节时间,循序渐进,打造完整的教学循环闭环。":"💡 Generic: Divide evenly into sequential warm-up, core presentation and quiz.")]})]})]})]})]}),i===2&&e.jsxs("div",{className:"space-y-5 animate-in fade-in duration-200 text-left font-sans",children:[e.jsxs("div",{className:"bg-emerald-50/40 py-3.5 px-4.5 rounded-xl border border-emerald-100 text-xs text-emerald-850 leading-relaxed flex items-start gap-2 text-left",children:[e.jsx(M,{size:16,className:"text-emerald-555 shrink-0 mt-0.5 animate-pulse"}),e.jsxs("div",{children:[e.jsx("strong",{children:t==="zh"?"专家课堂时间轴预设:":"Dynamic Class Presets:"}),e.jsx("p",{className:"mt-0.5",children:t==="zh"?"好的教授节奏必须动静相宜。以下提供三种国际领先的精品课件时间节点设计,点击即可一键刷装配置。您也可以在下方自由增删和重新指定每个环节的长短!":"Curating temporal context maximizes classroom retention. Load from predefined templates or tweak the active steps on the dynamic table."})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:t==="zh"?"💡 点击应用典型课堂框架模板 (Quick Apply)":"💡 Click to Auto-Apply Structure Presets"}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-3",children:[{id:"preset_standard",title:t==="zh"?"经典 5-15-15-5 讲授模式":"Traditional 5-15-15-5 Lecture Paradigm",desc:t==="zh"?"由浅入深:先通过场景导入,后精讲,接着在白板配合大屏进行演练。":"Perfect dynamic for most standard classes.",segments:[{id:"seg-preset-1",title:"Course Orientation / 课堂导入",type:"intro",duration:"5m",color:"bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100",notes:"Warm up topic"},{id:"seg-preset-2",title:"Subject Core Lecture / 核心理论精讲",type:"lecture",duration:"15m",color:"bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100",notes:"Main content slide"},{id:"seg-preset-3",title:"Interactive Lab Work / 随堂协同演练",type:"practice",duration:"15m",color:"bg-green-50 text-green-700 border-green-200 hover:bg-green-100",notes:"Exercises & questions"},{id:"seg-preset-4",title:"Wrap up / 课堂成果总结与答疑",type:"summary",duration:"5m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Check answer notes"}]},{id:"preset_seminar",title:t==="zh"?"主题讨论工作坊模式":"Active Discussion Workshop",desc:t==="zh"?"协同探究:教师5分钟破冰,学生13分钟小组演练,12分钟对决汇报,10分钟定级。":"Discussion and presentation heavy layout.",segments:[{id:"seg-preset-5",title:"Debate Scenario Brief / 讨论情境简述",type:"intro",duration:"5m",color:"bg-amber-50 text-amber-700 border-amber-200 hover:bg-amber-100",notes:"Define debate metrics"},{id:"seg-preset-6",title:"Cooperative Ideation / 精英白板协作设计",type:"practice",duration:"13m",color:"bg-green-50 text-green-700 border-green-200 hover:bg-green-100",notes:"Joint workspace analysis"},{id:"seg-preset-7",title:"Student Team Presentation / 各小组交互汇报",type:"lecture",duration:"12m",color:"bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100",notes:"Group screen sharing"},{id:"seg-preset-8",title:"Review & Grade Feedback / 教师深度对标点评",type:"summary",duration:"10m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Score reviews"}]},{id:"preset_flipped",title:t==="zh"?"翻转课堂高强度训练":"Targeted Problem-Solving Sprint",desc:t==="zh"?"应试/解惑突破:8分钟温习,14分钟重难盲点攻坚,13分钟专项题演习,5分钟固化。":"Perfect for exams and targeted training courses.",segments:[{id:"seg-preset-9",title:"Blind Spot Evaluation / 温史自学效果自测",type:"intro",duration:"8m",color:"bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100",notes:"Scan quiz"},{id:"seg-preset-10",title:"Advanced Principle Explores / 重难考点极限拆解",type:"lecture",duration:"14m",color:"bg-rose-50 text-rose-700 border-rose-200 hover:bg-rose-100",notes:"Analyse weak metrics"},{id:"seg-preset-11",title:"Mock Solving Battle / 核心精选题实操对抗",type:"practice",duration:"13m",color:"bg-emerald-50 text-emerald-700 border-emerald-200 hover:bg-emerald-100",notes:"Sprint workout"},{id:"seg-preset-12",title:"Anchor Recap / 知识网架构网节点固化",type:"summary",duration:"5m",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",notes:"Highlight checklist"}]}].map(r=>e.jsxs("button",{type:"button",onClick:()=>{c(r.segments),b(t==="zh"?"预设已刷装":"Preset Configured",t==="zh"?`已将《${r.title}》应用到您当前设计的课程中。`:`Assigned "${r.title}" timeslots.`,"success")},className:"bg-white border rounded-xl p-3 text-left transition-all hover:bg-indigo-50/20 hover:border-indigo-400 cursor-pointer active:scale-98",children:[e.jsx("div",{className:"font-bold text-gray-800 text-xs sm:text-sm",children:r.title}),e.jsx("div",{className:"text-xs text-gray-400 mt-1.5 leading-relaxed",children:r.desc})]},r.id))})]}),e.jsx("div",{className:"mt-1",children:e.jsx(E,{slot:"course.wizard.quick_apply",lang:t,slotProps:{lang:t,wizardCourseTitle:g,wizardCourseCategory:o,wizardCourseTimeline:a,setWizardCourseTimeline:c,addToast:b}})}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2 select-none",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider",children:t==="zh"?"📌 流程时间卡编辑 (拖拽或直接对表格字段赋值)":"📌 Custom Timeslot Table (Edit fields directly)"}),e.jsxs("button",{type:"button",onClick:()=>{const r={id:`seg-w-custom-${Date.now()}`,title:t==="zh"?`自理授课阶段 ${a.length+1}`:`Interactive Step ${a.length+1}`,type:"practice",duration:"10m",color:"bg-slate-50 text-slate-700 border-slate-200 hover:bg-slate-100",notes:""};c([...a,r])},className:"flex items-center gap-1 text-xs font-bold text-indigo-600 hover:text-indigo-800 cursor-pointer",children:[e.jsx(O,{size:12})," ",t==="zh"?"增设阶段":"Append Phase"]})]}),e.jsx("div",{className:"space-y-2 border border-gray-150 rounded-xl p-3.5 bg-gray-50/50",children:a.map((r,n)=>e.jsxs("div",{className:"flex flex-col sm:flex-row items-center gap-3 bg-white border border-gray-200 rounded-lg p-2.5 shadow-xs",children:[e.jsxs("div",{className:"flex items-center gap-2 w-full sm:w-auto",children:[e.jsx("span",{className:"w-5 h-5 rounded-full bg-slate-100 flex items-center justify-center text-xs text-gray-500 font-bold shrink-0",children:n+1}),e.jsx("input",{type:"text",value:r.title,onChange:l=>{const s=[...a];s[n].title=l.target.value,c(s)},className:"font-bold text-xs text-gray-800 bg-transparent border-b border-transparent hover:border-gray-200 focus:border-indigo-500 py-0.5 px-1 focus:outline-none focus:bg-gray-50/50 rounded flex-1 sm:w-56",placeholder:"Phase Title"})]}),e.jsxs("div",{className:"flex items-center gap-2.5 w-full sm:w-auto justify-end sm:ml-auto",children:[e.jsxs("div",{className:"flex items-center gap-1 bg-slate-50 border border-gray-200 rounded px-2 py-0.5 shrink-0",children:[e.jsx("span",{className:"text-xs font-bold text-gray-400",children:"时长:"}),e.jsx("input",{type:"text",value:r.duration,onChange:l=>{const s=[...a];s[n].duration=l.target.value,c(s)},className:"w-8 text-xs text-gray-800 font-extrabold bg-transparent text-center focus:outline-none"})]}),e.jsxs("select",{value:r.type,onChange:l=>{const s=l.target.value,d=[...a];d[n].type=s,s==="intro"?d[n].color="bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100":s==="lecture"?d[n].color="bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100":s==="practice"?d[n].color="bg-green-50 text-green-700 border-green-200 hover:bg-green-100":s==="summary"?d[n].color="bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100":d[n].color="bg-gray-50 text-gray-700 border-gray-205 hover:bg-gray-100",c(d)},className:"bg-slate-50 border border-gray-200 text-xs font-bold text-gray-600 rounded p-1 focus:outline-none cursor-pointer",children:[e.jsx("option",{value:"intro",children:t==="zh"?"温习 / 导入":"Warm-up / Intro"}),e.jsx("option",{value:"lecture",children:t==="zh"?"主体 / 精讲":"Core Lecture"}),e.jsx("option",{value:"practice",children:t==="zh"?"交互白板练习":"Practice Workshop"}),e.jsx("option",{value:"summary",children:t==="zh"?"总结 / 定级":"Wrap-up / Recap"})]}),e.jsx("button",{type:"button",onClick:()=>{if(a.length<=1){alert(t==="zh"?"请保留至少一个核心环节!":"At least one segment must exist.");return}const l=a.filter((s,d)=>d!==n);c(l)},className:"text-gray-400 hover:text-rose-600 font-bold p-1 cursor-pointer text-sm select-none",title:"Delete this segment",children:"×"})]})]},r.id))}),e.jsxs("div",{className:"mt-2 text-xs text-right text-gray-500 font-mono select-none",children:[t==="zh"?"📈 环节累加公式:":"📈 Dynamic aggregation formula: ",e.jsx("span",{className:"text-gray-800 font-semibold",children:a.map(r=>r.duration).join(" + ")})]})]})]}),i===3&&e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 animate-in fade-in duration-200 font-sans text-left",children:[e.jsxs("div",{className:"space-y-3 flex flex-col h-full min-h-[360px] text-left",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-between gap-2",children:[e.jsx("label",{className:"block text-xs font-bold text-gray-500 uppercase tracking-wider select-none shrink-0",children:t==="zh"?"✏️ 使用 Markdown 语法编写课时材料":"✏️ Lesson Materials (Markdown)"}),e.jsxs("button",{type:"button",onClick:()=>void T(),disabled:u,className:"flex items-center gap-1 text-xs bg-indigo-50 border border-indigo-100 text-indigo-755 hover:bg-indigo-100 px-3 py-1 rounded-lg transition-colors font-bold cursor-pointer disabled:opacity-60 disabled:cursor-not-allowed",children:[u?e.jsx(v,{size:13,className:"text-indigo-500 animate-spin"}):e.jsx(j,{size:13,className:"text-indigo-500"}),u?t==="zh"?"AI 正在生成大纲...":"AI is writing your outline...":t==="zh"?"✨ AI 生成专家级教学大纲":"✨ AI-Generate Syllabus"]})]}),e.jsx("textarea",{rows:14,value:p,onChange:r=>D(r.target.value),placeholder:t==="zh"?`# 西方哲学三大经典原理
2
2
 
3
3
  在此输入您的具体内容讲解、白板图形绘制节点、以及课后实践任务大纲...`:"# Course curriculum content",className:"w-full flex-grow p-4 bg-slate-900 text-slate-100 border border-slate-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-indigo-500 font-mono text-xs shadow-inner leading-relaxed text-left"})]}),e.jsxs("div",{className:"space-y-3 flex flex-col h-full border border-gray-150 rounded-xl bg-slate-50/50 p-4 text-left",children:[e.jsxs("span",{className:"block text-xs font-bold text-gray-400 uppercase tracking-wider select-none shrink-0",children:["🖥️ ",t==="zh"?"大纲资料实时交互渲染":"Syllabus Live Context rendering"]}),e.jsx("div",{className:"flex-grow overflow-y-auto bg-white border border-gray-150 rounded-lg p-4 text-xs font-sans text-gray-700 max-h-[380px] overflow-x-hidden text-left select-text",children:p.trim()?e.jsx("div",{className:"markdown-body",children:e.jsx(L,{children:p})}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 italic py-16",children:[e.jsx(f,{size:32,className:"mb-2 opacity-20 text-indigo-500"}),e.jsx("span",{children:t==="zh"?"教案空无内容,等待输入或一键填充模板...":"Waiting for materials..."})]})})]})]}),i===4&&e.jsxs("div",{className:"space-y-6 animate-in fade-in duration-200 text-center font-sans max-w-xl mx-auto py-3",children:[e.jsx("div",{className:"inline-flex p-3 bg-emerald-50 border border-emerald-100 text-emerald-500 rounded-full",children:e.jsx(R,{size:36,className:"animate-pulse text-emerald-555"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-extrabold text-gray-800 text-base md:text-lg",children:t==="zh"?"🚀 互动课程已精心筹备成功!":"🚀 Materials Generated successfully!"}),e.jsx("p",{className:"text-xs text-gray-400 mt-1",children:t==="zh"?"设计与时间轴逻辑全部检验合格。请在下方核验新课卡片,确认无误一键部署入 SQLite 内核数据库。":"Curriculum parameters are ready to boot inside the Secure Host."})]}),e.jsxs("div",{className:"border border-indigo-200 rounded-2xl p-5 bg-linear-to-b from-indigo-50/20 to-white shadow-md text-left space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-indigo-50 pb-3 gap-2",children:[e.jsx("div",{className:"font-bold text-indigo-950 text-base sm:text-lg truncate",children:g||(t==="zh"?"未指定课程主题":"Blank Topic")}),e.jsx("span",{className:"inline-flex px-2 py-0.5 rounded text-xs font-extrabold bg-indigo-50 text-indigo-800 uppercase tracking-wide border border-indigo-150 shrink-0",children:o})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-gray-400 block tracking-wider text-xs font-bold",children:t==="zh"?"教研环节数":"TOTAL STEPS"}),e.jsxs("span",{className:"text-gray-800 font-extrabold text-sm block mt-1",children:[a.length," ",t==="zh"?"项教学环节":"slots"]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-gray-400 block tracking-wider text-xs font-bold",children:t==="zh"?"发布载体引擎":"STORAGE MEDIUM"}),e.jsxs("div",{className:"flex items-center gap-1 text-emerald-650 font-extrabold text-sm mt-1",children:[e.jsx(z,{size:11,className:"text-emerald-500"}),e.jsx("span",{children:"SQLite DB"})]})]})]}),e.jsx("div",{className:"bg-slate-50 border border-gray-150 p-3 rounded-lg text-xs text-gray-600 line-clamp-2 italic leading-relaxed text-left",children:h||(t==="zh"?"无科目描述内容":"No description written.")}),e.jsxs("div",{className:"space-y-1.5 select-none",children:[e.jsx("span",{className:"text-xs font-extrabold text-gray-400 uppercase tracking-wider block",children:t==="zh"?"教学时间轴环流预览":"TIMELINE PROGRESS OVERVIEW"}),e.jsx("div",{className:"flex items-center gap-1 w-full overflow-x-auto py-1",children:a.map((r,n)=>e.jsxs(y.Fragment,{children:[e.jsxs("div",{className:`px-2 py-1 text-xs font-bold rounded border truncate max-w-[120px] ${r.color.split(" ")[0]}`,children:[r.title.split(" / ")[0]," (",r.duration,")"]}),n<a.length-1&&e.jsx($,{size:11,className:"text-gray-300"})]},r.id))})]})]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-105 bg-slate-50 flex justify-between items-center shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs font-medium text-gray-500 select-none",children:[e.jsx("span",{className:"inline-flex items-center justify-center w-5 h-5 rounded-full bg-indigo-50 text-indigo-600 font-bold text-[11px] border border-indigo-200",children:i}),e.jsx("span",{children:t==="zh"?`第 ${i} 步 / 共 4 步 · ${w[i]?.zh||""}`:`Step ${i} of 4 · ${w[i]?.en||""}`})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[i>1&&e.jsx("button",{type:"button",onClick:()=>m(r=>r-1),disabled:x,className:"px-4 py-2 text-xs font-semibold border border-gray-200 text-gray-700 bg-white hover:bg-gray-50 rounded-lg transition-colors cursor-pointer select-none",children:t==="zh"?"上一步":"Back"}),i<4?e.jsx("button",{type:"button",onClick:()=>{if(i===1&&!g.trim()){alert(t==="zh"?"请输入课程课题名称!":"Please type course title to proceed.");return}m(r=>r+1)},className:"px-4.5 py-2 text-xs font-bold bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg shadow-sm flex items-center gap-1 cursor-pointer select-none",children:t==="zh"?"继续前进":"Continue"}):e.jsx("button",{type:"button",onClick:W,disabled:x,className:"px-5 py-2 text-xs font-bold bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg shadow-md flex items-center gap-1.5 cursor-pointer disabled:opacity-50 select-none animate-bounce",children:x?e.jsxs(e.Fragment,{children:[e.jsx(v,{size:13,className:"animate-spin"}),e.jsx("span",{children:t==="zh"?"写入底库中...":"Deploying..."})]}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:13}),e.jsx("span",{children:t==="zh"?"部署并激活新课程":"Deploy & Activate"})]})})]})]})]})})})}export{Q as CourseWizardModal,w as WIZARD_STEP_META};