openlearn-next 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/assets/{ActivityWorkspaceWidget-5PzyxF6a.js → ActivityWorkspaceWidget-CMN8elwQ.js} +1 -1
  2. package/dist/assets/{AdminDirectoryView-BCtmQTEK.js → AdminDirectoryView-Dlz7q-xf.js} +1 -1
  3. package/dist/assets/{AssessmentCenter-B43ojHG-.js → AssessmentCenter-CaoAI9Ke.js} +1 -1
  4. package/dist/assets/{BatchPickerModal-CbmjInp7.js → BatchPickerModal-CzutdtIz.js} +1 -1
  5. package/dist/assets/{ClassesView-DEnMaDOt.js → ClassesView-RkFPpWRu.js} +1 -1
  6. package/dist/assets/{ClassroomCountdownWidget-CHq4983w.js → ClassroomCountdownWidget-gs42lIGW.js} +1 -1
  7. package/dist/assets/{CloudDriveModal-D2t3Uyzr.js → CloudDriveModal-C6JtK08M.js} +1 -1
  8. package/dist/assets/{ComputerLabView-YtnoT5Rb.js → ComputerLabView-Dr-g8FrU.js} +1 -1
  9. package/dist/assets/{CourseManagement-DOXyJ_j-.js → CourseManagement-DNeaJcT9.js} +1 -1
  10. package/dist/assets/{CourseWizardModal-Dbi6Caw2.js → CourseWizardModal-vw876VJr.js} +1 -1
  11. package/dist/assets/{Dashboard-2rLu_ZBy.js → Dashboard-C1iYnfCh.js} +1 -1
  12. package/dist/assets/{ExportWeightModal-BrmAh6VX.js → ExportWeightModal-CTZ-O_wi.js} +1 -1
  13. package/dist/assets/{HelpView-CVBrKDrd.js → HelpView-wyKldm_R.js} +1 -1
  14. package/dist/assets/{ImportLessonsModal-PhHtX31R.js → ImportLessonsModal-C09Z-qtx.js} +1 -1
  15. package/dist/assets/{InteractiveCoursewareViewer-Vi6lLz7a.js → InteractiveCoursewareViewer-V97euiJF.js} +1 -1
  16. package/dist/assets/{InteractiveWhiteboard-lTzeayX5.js → InteractiveWhiteboard-COLMh_-w.js} +1 -1
  17. package/dist/assets/{LazyCourseware-KIt0rGtW.js → LazyCourseware-0iFYlRGj.js} +2 -2
  18. package/dist/assets/{LazyWhiteboard-CCN3pYcW.js → LazyWhiteboard-CcoBIx6V.js} +2 -2
  19. package/dist/assets/{LessonEditorView-D_GVhHuM.js → LessonEditorView-BWmtKwmP.js} +1 -1
  20. package/dist/assets/{LiveClassroomView-BRsZ6QEq.js → LiveClassroomView-CaS1DzSS.js} +1 -1
  21. package/dist/assets/{NotificationDetailModal-tY5rxYCN.js → NotificationDetailModal-4MdNF4tw.js} +1 -1
  22. package/dist/assets/{PluginView-CedpAW6d.js → PluginView-BqTbAp30.js} +1 -1
  23. package/dist/assets/{QuizGeneratorModal-bUA002kP.js → QuizGeneratorModal-xTq22vDq.js} +1 -1
  24. package/dist/assets/{StudentAssignmentView-BhAz6Hfk.js → StudentAssignmentView-Cy_JdPYB.js} +1 -1
  25. package/dist/assets/{StudentLessonView-DC1yX4kG.js → StudentLessonView-B3fKejCU.js} +1 -1
  26. package/dist/assets/{StudentView-PHKxIV9T.js → StudentView-CpJsG7FT.js} +2 -2
  27. package/dist/assets/{SystemResourceLibraryModal-DgXYe6_x.js → SystemResourceLibraryModal-YZ85mv_v.js} +1 -1
  28. package/dist/assets/{TeacherView-DscJtOJ9.js → TeacherView-B3zhzd5g.js} +2 -2
  29. package/dist/assets/{TimetableView-D2ozoj_D.js → TimetableView-D_4XmrRN.js} +1 -1
  30. package/dist/assets/{index-2676X8YB.js → index-BzXADCXZ.js} +5 -5
  31. package/dist/assets/{pluginParsers-e4PSm2Iy.js → pluginParsers-PzgFzxS9.js} +1 -1
  32. package/dist/cli-migrator.cjs +18 -1
  33. package/dist/index.html +1 -1
  34. package/dist/server.cjs +339 -249
  35. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import{r as i,j as e,R as Et}from"./vendor-react-Kv_JATwr.js";import{B as Ks,E as me,s as Na,F as ps,G as va,H as wa,I as ka,i as Wt,J as nt,K as xt,L as za,b as Sa,e as Ca,N as Br,O as $a,x as Aa,Q as Ea,y as Ta,R as Pa,T as St,U as _a}from"./index-2676X8YB.js";import{L as Ra}from"./LazyWhiteboard-CCN3pYcW.js";import{R as Pe,k as ft,aZ as Ia,C as fs,a3 as La,w as yt,E as tn,U as $e,ax as Xs,a6 as Ut,ap as qt,ae as er,N as ut,bd as Ma,a5 as Oe,X as we,B as Rt,o as Ce,ay as sn,y as bt,be as rn,bf as Vt,bg as bs,bh as Oa,$ as De,bi as nn,D as gs,b7 as tr,n as an,f as ms,z as ve,bj as on,p as Js,ad as Jt,a2 as ln,bk as Da,bl as Fa,bm as us,ac as et,ak as Tt,bn as cn,bo as Ba,T as Ie,q as qe,aA as dn,bp as Ga,bq as js,br as Ha,i as ys,bs as Wa,ab as It,K as Ua,a9 as gt,af as Yt,bt as qa,h as Va,aU as Kt,e as xn,bu as mn,W as sr,Q as rr,a4 as Ht,bv as Ka,G as nr,bw as Ja,A as Ns,bx as un,by as ar,a$ as Lt,t as or,c as jt,_ as vs,bz as hn,bA as Ya,bB as Pt,aG as Gr,b2 as Qa,bC as ds,L as Za,u as Qt,O as ir,s as pn,bD as Xa,aj as fn,aM as eo,aF as lr,V as bn,bE as gn,bF as cr,bG as to,bH as jn,bI as yn,r as so,bJ as ro,bK as no,b as Ys,as as ao,bL as oo,bM as Hr,bN as Bs,S as Wr,aT as io,bO as Ur,bP as lo,az as co,bQ as xo}from"./vendor-icons-CXrZ3R2V.js";import{C as mo,T as uo}from"./ClassroomCountdownWidget-CHq4983w.js";import{a as Nn,P as ho,h as po,g as fo,A as bo,C as go,X as jo,Y as yo,b as No,T as vo,e as wo}from"./vendor-charts-SrpBsvM3.js";import{r as dr,f as vn,D as wn,s as kn}from"./timeline-duration-BgdJCSrW.js";import{f as ko,t as zo}from"./teaching-modes-client-BeVaDdJ-.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";const qr=Ks;function zn({lessonId:t,lang:n,addToast:a}){const[o,d]=i.useState(!1),[r,l]=i.useState(!1),[s,h]=i.useState([]),[c,u]=i.useState(60),[m,p]=i.useState(40),[w,f]=i.useState({}),[N,b]=i.useState({}),[$,P]=i.useState({}),[y,k]=i.useState({}),[g,A]=i.useState({}),[U,W]=i.useState({}),T=n==="zh",Q=async(j=!1)=>{j?l(!0):d(!0);try{const ee=await(await fetch(`/api/lessons/${t}/eval-grades`)).json();if(Array.isArray(ee)){h(ee);const R={},O={},L={},X={};ee.forEach(K=>{K.grade?(R[K.id]=K.grade.teacher_score,O[K.id]=K.grade.teacher_comment,L[K.id]=Math.round(K.grade.teacher_weight*100),X[K.id]=Math.round(K.grade.peer_weight*100)):(R[K.id]=w[K.id]!==void 0?w[K.id]:80,O[K.id]=N[K.id]!==void 0?N[K.id]:"",L[K.id]=$[K.id]!==void 0?$[K.id]:c,X[K.id]=y[K.id]!==void 0?y[K.id]:m)}),f(K=>({...R,...K})),b(K=>({...O,...K})),P(K=>({...L,...K})),k(K=>({...X,...K}))}else throw new Error("Invalid submissions data format")}catch(q){console.error("Error fetching submissions grades:",q),a(T?"数据加载失败":"Failed to Load Data",T?"请检查网络连接或刷新页面。":"Please check your connection and try again.","warning")}finally{d(!1),l(!1)}};i.useEffect(()=>{t&&Q()},[t]),i.useEffect(()=>{const j=ps();if(!j||!t)return;const q=ee=>{(!ee?.lessonId||ee.lessonId===t)&&Q()};return j.on("assignment-submitted-toast",q),()=>{typeof j.off=="function"&&j.off("assignment-submitted-toast",q)}},[t]);const V=j=>{u(j),p(100-j),P(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=j)}),ee}),k(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=100-j)}),ee})},le=(j,q)=>{P(ee=>({...ee,[j]:q})),k(ee=>({...ee,[j]:100-q}))},F=async(j,q)=>{const ee=w[j],R=N[j]||"",O=($[j]??c)/100,L=(y[j]??m)/100;if(ee===void 0||isNaN(ee)||ee<0||ee>100){a(T?"评分无效":"Invalid Score",T?"教师评分必须在 0 到 100 之间!":"Teacher score must be between 0 and 100!","warning");return}if(q==="confirmed"){const X=T?"确认同步后,最终得分将直接同步写入宿主学期成绩库,此后该学生的作业成绩将锁定不可修改。是否确认?":"Once confirmed, the final score will be synced to the host semester reports and locked. Proceed?";if(!window.confirm(X))return}W(X=>({...X,[j]:q}));try{const K=await(await fetch("/api/commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({commandType:"assignment.grade",payload:{submissionId:j,teacherScore:Number(ee),teacherComment:R,teacherWeight:O,peerWeight:L,status:q}})})).json();if(K.success)a(q==="confirmed"?T?"平时成绩同步成功":"Semester Grade Synced":T?"平时成绩草稿已保存":"Grade Draft Saved",q==="confirmed"?T?`已将平时成绩 ${K.result.calculatedFinalScore} 分同步至学期报告!`:`Successfully synced grade ${K.result.calculatedFinalScore}!`:T?"成功保存了教师打分与评语草稿。":"Successfully saved score and comment draft.","success"),Q(!0);else throw new Error(K.error||"Failed to submit grade")}catch(X){a(T?"操作失败":"Operation Failed",X.message,"warning")}finally{W(X=>({...X,[j]:null}))}},D=j=>{A(q=>({...q,[j]:!q[j]}))};return o?e.jsxs("div",{className:"flex-grow flex flex-col items-center justify-center py-12 text-gray-500",children:[e.jsx(Pe,{className:"animate-spin text-indigo-500 mb-2",size:32}),e.jsx("p",{className:"text-xs",children:T?"正在读取学生作业与成绩状态...":"Loading student submissions and grades..."})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 w-full relative rounded-xl overflow-hidden border border-slate-200 shadow-md bg-white p-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center pb-4 border-b border-slate-100 mb-4 gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("h3",{className:"text-sm font-bold text-slate-800 flex items-center gap-1.5 select-none",children:[e.jsx(ft,{size:16,className:"text-indigo-655"}),T?"学生作业成绩评定与折算系统":"Student Assignment Grading & Sync"]}),e.jsxs("span",{className:"text-xs bg-indigo-50 text-indigo-750 px-2 py-0.5 rounded-full border border-indigo-100 font-bold",children:[s.length," ",T?"个提交":"submissions"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{slot:"assignment.grade.toolbar.action",slotProps:{lessonId:t,submissions:s,refresh:()=>Q(!0),lang:n}}),e.jsx("button",{onClick:()=>Q(!0),disabled:r,className:"p-1.5 bg-white hover:bg-slate-55 border border-slate-200 rounded-lg text-slate-600 transition-colors flex items-center justify-center cursor-pointer shadow-4xs",title:T?"刷新数据":"Refresh",children:e.jsx(Pe,{size:12,className:r?"animate-spin":""})})]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-200 rounded-xl p-4 mb-5 shrink-0 flex flex-col md:flex-row md:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsx(Ia,{className:"text-indigo-500 shrink-0 mt-0.5",size:16}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-bold text-slate-700",children:T?"全局默认折算权重设置":"Default Grading Weights Configuration"}),e.jsx("p",{className:"text-xs text-subtle mt-0.5 font-medium",children:T?"调整权重分配,所有尚未锁定成绩的学生将自动应用此默认权重比例。":"Setting global default weights. Changes will automatically apply to non-confirmed grades."})]})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0 bg-white px-3.5 py-2 rounded-lg border border-slate-200 shadow-3xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"教师评分:":"Teacher:"}),e.jsx("input",{type:"range","aria-label":T?"教师评分权重":"Teacher weight",min:"0",max:"100",step:"5",value:c,onChange:j=>V(Number(j.target.value)),className:"w-20 accent-indigo-650 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-bold text-indigo-700 w-8 text-right",children:[c,"%"]})]}),e.jsx("div",{className:"h-4 w-[1px] bg-slate-200"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"学生互评:":"Peer Review:"}),e.jsxs("span",{className:"text-xs font-bold text-slate-700 w-8",children:[m,"%"]})]})]}),e.jsx(me,{slot:"assignment.grade.rubric.addon",slotProps:{lessonId:t,defaultTeacherWeight:c,defaultPeerWeight:m,onTeacherWeightChange:V,lang:n}})]}),e.jsx("div",{className:"flex-grow flex-1 overflow-y-auto space-y-4 pr-1 scrollbar-thin",children:s.length===0?e.jsxs("div",{className:"h-full flex flex-col items-center justify-center py-12 text-slate-400 gap-2",children:[e.jsx(fs,{size:32,className:"text-slate-350"}),e.jsx("p",{className:"text-xs",children:T?"本节课目前没有任何学生提交作业。":"No students have submitted assignments yet for this lesson."})]}):s.map(j=>{const q=w[j.id]!==void 0?w[j.id]:80,ee=N[j.id]||"",R=$[j.id]??c,O=y[j.id]??m,L=j.grade?.status==="confirmed",X=Math.round(q*(R/100)+j.peerAverageScore*(O/100));return e.jsxs("div",{className:`bg-white border rounded-xl shadow-3xs overflow-hidden transition-all ${L?"border-emerald-200 bg-emerald-50/5":"border-slate-200"}`,children:[e.jsxs("div",{className:"px-4 py-3 bg-slate-50/50 border-b border-slate-100 flex flex-col md:flex-row md:items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-indigo-50 border border-indigo-100 flex items-center justify-center text-indigo-700 font-bold text-xs select-none",children:j.studentName?.charAt(0)||"S"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-bold text-slate-800",children:j.studentName}),e.jsxs("div",{className:"text-xs text-slate-400 font-mono mt-0.5 flex items-center gap-1.5",children:[e.jsxs("span",{children:["V",j.version]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:new Date(j.updatedAt).toLocaleString()})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[L?e.jsxs("span",{className:"bg-emerald-55 text-emerald-700 text-xs font-black px-2.5 py-1 rounded-full border border-emerald-150 flex items-center gap-1 shadow-3xs select-none",children:[e.jsx(La,{size:12}),T?"成绩已同步":"Synced to Reports"]}):e.jsx("span",{className:"bg-amber-50 text-amber-805 text-xs font-bold px-2 py-0.5 rounded-full border border-amber-200/60 select-none",children:j.grade?T?"草稿状态":"Draft":T?"未评定":"Ungraded"}),(()=>{const K=Na(j.filePath);return K?e.jsxs("a",{href:K,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-indigo-600 hover:text-indigo-850 font-medium hover:underline flex items-center gap-1 bg-white border border-slate-200 px-2 py-1 rounded-lg shadow-4xs",title:j.filePath,children:[e.jsx(yt,{size:11}),T?"查看作业":"View File",e.jsx(tn,{size:8})]}):null})()]})]}),e.jsxs("div",{className:"p-4 grid grid-cols-1 lg:grid-cols-12 gap-5",children:[e.jsxs("div",{className:"lg:col-span-5 flex flex-col gap-2.5 border-r border-slate-100 pr-0 lg:pr-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-xs font-bold text-slate-650 flex items-center gap-1 select-none",children:[e.jsx($e,{size:13,className:"text-slate-400"}),T?"学生互评详情":"Peer Review Details"]}),e.jsxs("span",{className:"text-xs font-bold text-slate-500 bg-slate-100 px-2 py-0.5 rounded-md",children:[T?"互评人数:":"Reviews:"," ",j.peerReviews.length]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-100 rounded-xl p-3 flex items-center gap-3",children:[e.jsxs("div",{className:"bg-white border border-slate-200 w-12 h-12 rounded-lg flex flex-col items-center justify-center shrink-0 shadow-3xs",children:[e.jsx("span",{className:"text-xs text-slate-405 select-none font-bold",children:T?"均分":"Avg"}),e.jsx("span",{className:"text-sm font-extrabold text-slate-700 leading-none mt-0.5",children:j.peerAverageScore})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs text-slate-450 leading-normal font-medium",children:j.peerReviews.length>0?T?"根据同学互评分数得出的平均值。":"Average score computed from classmate evaluations.":T?"暂无同学对此作业给出评分。":"No classmate peer reviews received yet."}),j.peerReviews.length>0&&e.jsx("button",{onClick:()=>D(j.id),className:"text-xs text-indigo-650 hover:text-indigo-800 font-bold mt-1.5 flex items-center gap-0.5 cursor-pointer outline-none",children:g[j.id]?e.jsxs(e.Fragment,{children:[T?"收起互评详情":"Hide Details"," ",e.jsx(Xs,{size:12})]}):e.jsxs(e.Fragment,{children:[T?"展开互评详情":"Show Details"," ",e.jsx(Ut,{size:12})]})})]})]}),g[j.id]&&j.peerReviews.length>0&&e.jsx("div",{className:"mt-2 space-y-2 border-t border-slate-100 pt-2.5 max-h-40 overflow-y-auto scrollbar-thin",children:j.peerReviews.map(K=>e.jsxs("div",{className:"bg-white border border-slate-200 rounded-lg p-2.5 text-xs text-left shadow-4xs",children:[e.jsxs("div",{className:"flex justify-between items-center font-bold text-slate-700",children:[e.jsxs("span",{className:"flex items-center gap-1 font-semibold text-slate-655",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-slate-300"}),K.reviewer_name]}),e.jsxs("span",{className:"text-indigo-650 bg-indigo-50 border border-indigo-100 rounded px-1.5 py-0.5 text-xs",children:[K.score," ",T?"分":"pts"]})]}),K.comment&&e.jsxs("p",{className:"text-xs text-slate-550 mt-1 italic pl-2.5 border-l-2 border-slate-100 font-medium",children:['"',K.comment,'"']})]},K.id))})]}),e.jsxs("div",{className:"lg:col-span-7 flex flex-col gap-3 justify-between",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-650 mb-1 select-none",children:T?"教师平时分评分 (0-100)":"Teacher Score (0-100)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{id:`teacher_score_input_${j.id}`,type:"number",min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Math.min(100,Math.max(0,Number(K.target.value)))})),className:"bg-white border border-slate-250 rounded-lg text-xs font-bold text-slate-700 px-3 py-1.5 focus:ring-1 focus:ring-indigo-500 outline-none w-20 shadow-4xs disabled:opacity-50 disabled:bg-slate-50"}),e.jsx("input",{type:"range","aria-label":T?`${j.studentName||"学生"} 的得分`:`Score for ${j.studentName||"student"}`,min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Number(K.target.value)})),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-1",children:[e.jsx("label",{className:"block text-xs font-bold text-slate-600 select-none",children:T?"打分占比 (教师权重)":"Teacher Score Weight"}),e.jsx("span",{className:"text-xs font-bold text-slate-400",children:T?`学生互评: ${O}%`:`Peer: ${O}%`})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{id:`teacher_weight_input_${j.id}`,type:"range",min:"0",max:"100",step:"5",disabled:L,value:R,onChange:K=>le(j.id,Number(K.target.value)),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-extrabold text-indigo-750 w-9 text-right",children:[R,"%"]})]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-655 mb-1 select-none",children:T?"教师评价评语":"Teacher Comments & Feedback"}),e.jsx("textarea",{id:`teacher_comment_input_${j.id}`,disabled:L,value:ee,placeholder:T?"在此输入对学生作业作品的改进指导意见及评语。":"Enter guiding feedback for this student.",onChange:K=>b(H=>({...H,[j.id]:K.target.value})),rows:2,className:"w-full bg-white border border-slate-250 rounded-lg text-xs p-2 focus:ring-1 focus:ring-indigo-500 outline-none shadow-4xs disabled:opacity-50 disabled:bg-slate-50 resize-none font-medium text-slate-700"})]}),e.jsx(me,{slot:"assignment.grade.item.addon",slotProps:{submission:j,studentId:j.student_id,lessonId:t,score:q,comment:ee,isConfirmed:L,onScoreChange:K=>f(H=>({...H,[j.id]:K})),onCommentChange:K=>b(H=>({...H,[j.id]:K})),lang:n}}),e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between gap-4 pt-2 border-t border-slate-100 mt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:`p-1.5 rounded-lg border flex items-center justify-center shrink-0 ${L?"bg-emerald-50 text-emerald-600 border-emerald-100":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:e.jsx(qt,{size:14})}),e.jsxs("div",{className:"text-xs text-slate-500 font-medium",children:[e.jsxs("div",{children:[T?"平时总分计算公式":"Calculated Final Grade",":"]}),e.jsxs("div",{className:"font-bold text-slate-700 mt-0.5 animate-formula",children:[R,"% × ",e.jsx("span",{className:"text-indigo-650 font-bold",children:q}),j.peerReviews.length>0&&` + ${O}% × ${j.peerAverageScore}`," = ",e.jsx("span",{className:L?"text-emerald-700 font-black text-xs":"text-indigo-700 font-black text-xs",children:L&&j.grade?.calculated_final_score||X}),T?"分":" pts"]})]})]}),!L&&e.jsxs("div",{className:"flex gap-2 justify-end shrink-0",children:[e.jsxs("button",{id:`teacher_draft_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"draft"),className:"px-3 py-1.5 bg-white border border-slate-350 rounded-lg text-xs font-bold text-slate-700 hover:bg-slate-55 flex items-center gap-1.5 shadow-4xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(er,{size:12}),U[j.id]==="draft"?T?"保存中...":"Saving...":T?"暂存草稿":"Save Draft"]}),e.jsxs("button",{id:`teacher_confirm_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"confirmed"),className:"px-3.5 py-1.5 bg-indigo-600 border border-indigo-700 rounded-lg text-xs font-bold text-white hover:bg-indigo-700 flex items-center gap-1.5 shadow-3xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(ut,{size:12}),U[j.id]==="confirmed"?T?"同步中...":"Syncing...":T?"确认并同步":"Confirm & Sync"]})]})]})]})]})]},j.id)})})]})}function So({isOpen:t,onClose:n,lessonId:a,lessonTitle:o,lang:d="zh"}){const{data:r,health:l,lastSyncedAt:s}=va(a,{enabled:t});return t?e.jsx(wa,{lessonId:a,lessonTitle:o,data:r,lang:d,health:l,lastSyncedAt:s,onClose:n}):null}function Co({lessonId:t,lessonTitle:n,lang:a}){const o=new URLSearchParams({mode:"stage_display",lessonId:t});n&&o.set("title",n),a&&o.set("lang",a);const{pathname:d,origin:r}=window.location;return`${r}${d}?${o.toString()}#/stage_display`}function $o(){const t=i.useRef(null),[n,a]=i.useState(!1),[o,d]=i.useState(!1);i.useEffect(()=>()=>{t.current=null},[]),i.useEffect(()=>{const h=setInterval(()=>{const c=t.current;c&&c.closed&&(t.current=null)},3e3);return()=>clearInterval(h)},[]);const r=i.useCallback(h=>{const c=t.current;if(c&&!c.closed){c.focus();return}let u;try{u=window.open(Co(h),"openlearn-stage-display","width=1280,height=720,menubar=no,toolbar=no,location=no")}catch(m){console.warn("[StageDisplay] window.open threw:",m),u=null}if(!u){d(!0),a(!0);return}t.current=u,d(!1),a(!1),u.focus?.()},[]),l=i.useCallback(()=>a(!1),[]),s=i.useCallback(()=>d(!1),[]);return{fallbackOpen:n,blocked:o,openStageWindow:r,closeFallback:l,clearBlockedHint:s}}const Gs={CLEAR:{emoji:"💡",zh:"理解",en:"Clear",color:"#10b981"},CONFUSED:{emoji:"❓",zh:"困惑",en:"Confused",color:"#f59e0b"},TOO_FAST:{emoji:"🐇",zh:"慢一点",en:"Slow down",color:"#f43f5e"},SLOW:{emoji:"🐢",zh:"快一点",en:"Speed up",color:"#6366f1"}},Ao=["CLEAR","CONFUSED","TOO_FAST","SLOW"];function Eo({lessonId:t,lang:n,signals:a,onlineCount:o=0,onClose:d,activeSegmentTitle:r}){const l=n==="zh",[s,h]=i.useState(a);i.useEffect(()=>{const f=ps();if(!f)return;const N=b=>{b?.lessonId===t&&b?.summary&&h(b.summary)};return f.on("classroom:pacing_updated",N),()=>{typeof f.off=="function"&&f.off("classroom:pacing_updated",N)}},[t]);const c=Ao.map(f=>({key:f,count:Number(s[f]??0)})),u=c.reduce((f,N)=>f+N.count,0);Number(s.CONFUSED??0)+Number(s.TOO_FAST??0)+Number(s.SLOW??0);const m=u>0?Math.round(Number(s.CLEAR??0)/u*100):null,p=i.useCallback(()=>u===0?{text:l?"暂无学生反馈,等待中…":"No feedback yet",tone:"text-muted"}:Number(s.CONFUSED??0)>=Math.max(2,u*.3)?{text:l?"⚠ 较多学生困惑,建议放慢并重新讲解当前环节":"⚠ Many students are confused — slow down and re-explain",tone:"text-amber-600"}:Number(s.TOO_FAST??0)>=Math.max(2,u*.3)?{text:l?"🐇 较多学生希望放慢节奏":"🐇 Many students want you to slow down",tone:"text-rose-600"}:Number(s.SLOW??0)>=Math.max(2,u*.3)?{text:l?"🐢 较多学生希望加快节奏":"🐢 Many students want you to speed up",tone:"text-indigo-600"}:{text:l?"✓ 节奏反馈健康,可按当前节奏继续":"✓ Pace is healthy — carry on",tone:"text-emerald-700 dark:text-emerald-400"},[s,u,l]),w=c.filter(f=>f.count>0).map(f=>({name:Gs[f.key][l?"zh":"en"],value:f.count,color:Gs[f.key].color}));return e.jsx("div",{className:"fixed inset-0 z-[90] flex items-center justify-center bg-slate-900/60 backdrop-blur-2xs",onPointerDown:d,children:e.jsxs("div",{className:"bg-surface border border-theme rounded-2xl shadow-2xl w-[560px] max-w-[92vw] max-h-[86vh] overflow-y-auto p-5 font-sans text-main",onPointerDown:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"p-2 bg-primary-theme/10 text-primary-theme rounded-xl",children:e.jsx(Ma,{size:18})}),e.jsxs("div",{children:[e.jsxs("h2",{className:"text-sm font-black text-main flex items-center gap-1.5",children:[l?"课堂反馈情绪仪表盘":"Classroom Feedback Dashboard",e.jsxs("span",{className:"flex items-center gap-1 text-2xs font-bold text-emerald-700 dark:text-emerald-400 bg-emerald-500/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(Oe,{size:10})," ",l?"实时":"LIVE"]})]}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:r?l?`当前教学环节: ${r} · 去重实时聚合`:`Active Segment: ${r} · Real-time`:l?"按环节去重 · 实时节奏反馈聚合":"Deduplicated real-time pacing feedback"})]})]}),e.jsx("button",{onClick:d,className:"p-1.5 rounded-lg hover:bg-surface-secondary text-muted cursor-pointer",title:l?"关闭":"Close",children:e.jsx(we,{size:16})})]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-center",children:[e.jsxs("div",{className:"w-[200px] h-[200px] relative shrink-0",children:[u>0?e.jsx(Nn,{width:"100%",height:"100%",children:e.jsx(ho,{children:e.jsx(po,{data:w,dataKey:"value",nameKey:"name",innerRadius:52,outerRadius:85,paddingAngle:3,strokeWidth:0,isAnimationActive:!1,children:w.map((f,N)=>e.jsx(fo,{fill:f.color},N))})})}):e.jsx("div",{className:"w-full h-full flex items-center justify-center text-3xl opacity-30",children:"📊"}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[e.jsxs("span",{className:"text-2xs text-muted flex items-center gap-1",children:[e.jsx($e,{size:10})," ",o," ",l?"在线":"online"]}),e.jsx("span",{className:`text-xl font-black ${m===null?"text-muted":m>=60?"text-emerald-700 dark:text-emerald-400":m>=30?"text-amber-700 dark:text-amber-400":"text-rose-700 dark:text-rose-400"}`,children:m===null?"—":`${m}%`}),e.jsx("span",{className:"text-2xs text-muted",children:l?"理解占比":"clear ratio"})]})]}),e.jsxs("div",{className:"flex-1 w-full flex flex-col gap-2.5",children:[c.map(({key:f,count:N})=>{const b=Gs[f],$=u>0?Math.round(N/u*100):0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-xs mb-0.5",children:[e.jsxs("span",{className:"font-bold text-main",children:[b.emoji," ",l?b.zh:b.en]}),e.jsxs("span",{className:"text-muted font-mono",children:[N," · ",$,"%"]})]}),e.jsx("div",{className:"h-2.5 bg-surface-secondary rounded-full overflow-hidden border border-theme/50",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${$}%`,background:b.color}})})]},f)}),e.jsx("div",{className:`mt-1 text-xs font-bold ${p().tone}`,children:p().text}),e.jsx(me,{slot:"classroom.barometer.metric",slotProps:{lessonId:t,signals:s,total:u,health:m,lang:n}})]})]})]})})}function To({progressHistory:t,lang:n="zh",compact:a=!1}){const o=i.useMemo(()=>({title:n==="zh"?"课程学习进度趋势":"Learning Progress Trend",badge:n==="zh"?"历史趋势":"History",subtitle:n==="zh"?"按课程追踪学习完成度与进度变化曲线":"Track lesson completion progress over time",emptyTitle:n==="zh"?"暂无学习进度记录":"No Progress Records Yet",emptyDesc:n==="zh"?"当学生被分配课程并开始学习后,进度趋势将在此展示。":"Progress trends will appear here once lessons are assigned and started.",tooltipLesson:n==="zh"?"课程":"Lesson",tooltipProgress:n==="zh"?"完成进度":"Progress",tooltipDate:n==="zh"?"分配时间":"Assigned",tooltipStatus:n==="zh"?"状态":"Status",completed:n==="zh"?"已完成":"Completed",inProgress:n==="zh"?"进行中":"In Progress",statAvg:n==="zh"?"平均进度":"Avg Progress",statCompleted:n==="zh"?"已完成":"Completed",statTotal:n==="zh"?"总课程数":"Total Lessons"}),[n]),{chartData:d,stats:r}=i.useMemo(()=>{if(!t||t.length===0)return{chartData:[],stats:{avg:0,completed:0,total:0}};const s=new Map;for(const p of t){const w=s.get(p.lesson_id);(!w||p.assigned_at>w.assigned_at)&&s.set(p.lesson_id,p)}const c=Array.from(s.values()).sort((p,w)=>p.assigned_at-w.assigned_at).map(p=>{const w=new Date(p.assigned_at),f=n==="zh"?`${w.getMonth()+1}月${w.getDate()}日`:w.toLocaleDateString("en-US",{month:"short",day:"numeric"});return{label:p.lesson_title.length>8?p.lesson_title.slice(0,8)+"…":p.lesson_title,lessonTitle:p.lesson_title,progressPercent:Math.max(0,Math.min(100,Math.round(p.progress_percent))),completed:p.completed===1,dateLabel:f,timestamp:p.assigned_at}}),u=c.reduce((p,w)=>p+w.progressPercent,0),m=c.filter(p=>p.completed).length;return{chartData:c,stats:{avg:c.length>0?Math.round(u/c.length):0,completed:m,total:c.length}}},[t,n]);if(d.length===0)return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-empty",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-2",children:[e.jsx(Oe,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title})]}),e.jsxs("div",{className:"rounded-xl border border-dashed border-border/60 p-4 text-center",children:[e.jsx(fs,{size:24,className:"mx-auto text-muted mb-1.5"}),e.jsx("p",{className:"text-[11px] font-semibold text-muted",children:o.emptyTitle}),e.jsx("p",{className:"text-[10px] text-muted mt-0.5",children:o.emptyDesc})]})]});const l=a?180:220;return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-chart",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Oe,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title}),e.jsx("span",{className:"text-[10px] font-mono font-bold px-1.5 py-0.5 rounded-md bg-primary-theme/10 text-primary-theme border border-primary-theme/20",children:o.badge})]})}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 mb-2.5",children:[e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statAvg}),e.jsxs("div",{className:"text-sm font-extrabold text-foreground font-mono",children:[r.avg,"%"]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statCompleted}),e.jsxs("div",{className:"text-sm font-extrabold text-emerald-600 dark:text-emerald-400 font-mono",children:[r.completed,"/",r.total]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statTotal}),e.jsx("div",{className:"text-sm font-extrabold text-foreground font-mono",children:r.total})]})]}),e.jsx("div",{style:{width:"100%",height:l},children:e.jsx(Nn,{width:"100%",height:"100%",children:e.jsxs(bo,{data:d,margin:{top:10,right:10,left:-25,bottom:5},children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"progressGradientFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#6366f1",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#6366f1",stopOpacity:.02})]}),e.jsxs("linearGradient",{id:"progressStrokeGrad",x1:"0",y1:"0",x2:"1",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"#6366f1"}),e.jsx("stop",{offset:"50%",stopColor:"#818cf8"}),e.jsx("stop",{offset:"100%",stopColor:"#a78bfa"})]})]}),e.jsx(go,{strokeDasharray:"3 3",vertical:!1,stroke:"#e2e8f0",opacity:.5}),e.jsx(jo,{dataKey:"label",tick:{fontSize:10,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,interval:d.length>8?Math.floor(d.length/6):0}),e.jsx(yo,{domain:[0,100],ticks:[0,25,50,75,100],tick:{fontSize:10,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,tickFormatter:s=>`${s}%`}),e.jsx(No,{y:100,stroke:"#10b981",strokeDasharray:"4 4",strokeWidth:1,label:{value:n==="zh"?"完成 100%":"100% Complete",fill:"#059669",fontSize:9,fontWeight:700,position:"insideTopRight"}}),e.jsx(vo,{content:({active:s,payload:h})=>{if(!s||!h||!h.length)return null;const c=h[0].payload;return e.jsxs("div",{className:"bg-slate-900 text-white rounded-xl p-2.5 shadow-xl border border-slate-700/80 text-xs min-w-[180px] z-50",children:[e.jsxs("div",{className:"flex items-center gap-1.5 pb-1.5 border-b border-slate-800",children:[e.jsx(Rt,{size:12,className:"text-indigo-300"}),e.jsx("span",{className:"font-bold text-indigo-300 truncate max-w-[150px]",children:c.lessonTitle})]}),e.jsxs("div",{className:"pt-1.5 space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipProgress,":"]}),e.jsxs("span",{className:"font-extrabold text-emerald-400 font-mono",children:[c.progressPercent,"%"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipDate,":"]}),e.jsx("span",{className:"text-slate-200 font-mono text-[11px]",children:c.dateLabel})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipStatus,":"]}),e.jsxs("span",{className:`flex items-center gap-1 font-semibold ${c.completed?"text-emerald-400":"text-amber-400"}`,children:[e.jsx(Ce,{size:11}),c.completed?o.completed:o.inProgress]})]})]})]})}}),e.jsx(wo,{type:"monotone",dataKey:"progressPercent",name:n==="zh"?"完成进度":"Progress",stroke:"url(#progressStrokeGrad)",strokeWidth:2.5,fill:"url(#progressGradientFill)",dot:{r:3.5,fill:"#6366f1",stroke:"#ffffff",strokeWidth:2},activeDot:{r:6,stroke:"#a78bfa",strokeWidth:2,fill:"#ffffff"},animationDuration:600})]})})})]})}function xr({isOpen:t,onClose:n,student:a,lessonId:o,classId:d,lang:r="zh",addToast:l,onInspectSandbox:s,onCastStudentScreen:h,onAwardPoints:c,progressHistory:u}){const[m,p]=i.useState(!1),[w,f]=i.useState([]),[N,b]=i.useState("overview"),$=ka(H=>H.version);i.useEffect(()=>{t&&b("overview")},[t,a?.id]),i.useEffect(()=>{if(u!==void 0)return;if(!t||!a?.id){f([]);return}let H=!0;return(async()=>{try{const te=await fetch(`/api/students/${a.id}/progress`);if(te.ok){const de=await te.json();H&&Array.isArray(de)&&f(de)}}catch{}})(),()=>{H=!1}},[t,a?.id,u,$]);const P=u!==void 0?u:w,y=a?.competencyScores,k=i.useMemo(()=>[{key:"logic",label:r==="zh"?"算法逻辑":"Logic"},{key:"engineering",label:r==="zh"?"代码工程":"Engineering"},{key:"creativity",label:r==="zh"?"创新思维":"Creativity"},{key:"collaboration",label:r==="zh"?"团队协作":"Collaboration"},{key:"focus",label:r==="zh"?"课堂专注":"Focus"}],[r]),g=i.useMemo(()=>k.map(H=>{const re=y?.[H.key],te=typeof re=="number"&&Number.isFinite(re);return{key:H.key,label:H.label,score:te?Math.max(0,Math.min(100,Math.round(re))):0,available:te}}),[y,k]),A=g.some(H=>H.available),U=g.filter(H=>!H.available).map(H=>H.label),W=i.useMemo(()=>{const H=r==="zh",re=a?.name??(r==="zh"?"该学生":"This student"),te=g.filter(B=>B.available);if(te.length===0)return H?`${re}本节暂无可用的维度数据(未参与随堂测/课件互动),无法生成掌握度评语。建议下节课关注其参与情况。`:`${re} has no competency data for this session (no quiz/courseware interaction).`;const de=Math.round(te.reduce((B,se)=>B+se.score,0)/te.length),G=te.reduce((B,se)=>se.score>B.score?se:B),S=te.reduce((B,se)=>se.score<B.score?se:B),M=g.filter(B=>!B.available).map(B=>B.label);return(H?[`本节已采集维度:${te.map(B=>`${B.label} ${B.score}`).join("、")},平均 ${de}。`,`相对优势为${G.label}(${G.score}),相对薄弱为${S.label}(${S.score})。`,M.length>0?`未采集维度:${M.join("、")}。`:""]:[`Collected: ${te.map(B=>`${B.label} ${B.score}`).join(", ")}; average ${de}.`,`Strongest ${G.label} (${G.score}), weakest ${S.label} (${S.score}).`,M.length>0?`Missing: ${M.join(", ")}.`:""]).filter(Boolean).join(" ")},[g,r,a]),T=i.useMemo(()=>{const H=r==="zh",re=g.filter(de=>de.available);if(re.length===0)return H?"数据不足,暂不生成建议":"Insufficient data";const te=re.reduce((de,G)=>de+G.score,0)/re.length;return te>=85?H?"建议进入算法创新挑战营":"Recommended for Advanced Camp":te>=70?H?"建议保持当前节奏并补强薄弱维度":"Keep pace, strengthen weak areas":H?"建议课后补充基础微练习":"Suggest remedial practice"},[g,r]),Q=i.useMemo(()=>{const H=g.filter(te=>te.available);if(H.length===0)return"—";const re=H.reduce((te,de)=>te+de.score,0)/H.length;return re>=90?"A+":re>=80?"A":re>=70?"B+":re>=60?"B":"C"},[g]),V=i.useMemo(()=>{const de=(B,se)=>{const v=-Math.PI/2+2*Math.PI/5*se;return{x:100+B*Math.cos(v),y:100+B*Math.sin(v)}},G=[1,.66,.33].map(B=>{const se=75*B;return Array.from({length:5},(_,Z)=>{const{x:ie,y:xe}=de(se,Z);return`${ie.toFixed(1)},${xe.toFixed(1)}`}).join(" ")}),S=Array.from({length:5},(B,se)=>{const{x:v,y:_}=de(75,se);return{x1:100,y1:100,x2:v,y2:_}}),M=g.map((B,se)=>{const v=75*Math.min(Math.max(B.score/100,.1),1);return de(v,se)}),I=M.map(B=>`${B.x.toFixed(1)},${B.y.toFixed(1)}`).join(" ");return{gridLevels:G,axes:S,dataPoints:M,dataPolygonString:I}},[g]);if(!t||!a)return null;const le=a.points??0,F=a.deltaPoints??4,D=a.focusPercentage,j=a.accuracyPercentage,q=a.helpCount??3,ee=a.role||a.student_number||"",R=a.group_name||"",O=a.student_number||a.id.slice(-6),L=a.timeline??[],X=async(H,re)=>{p(!0);try{c?c(a.id,H,re):await fetch(`/api/students/${a.id}/points`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({delta:H,dimension:"attribution",reason:re,classId:d,lessonId:o})}),l?.(r==="zh"?"成长积分已发放":"Points Awarded",r==="zh"?`已为学生 [${a.name}] ${H>=0?"+":""}${H} 分(${re})`:`Awarded ${H} pts to [${a.name}]`,"success")}catch(te){const de=te instanceof Error?te.message:String(te);l?.("Error",de,"error")}finally{p(!1)}},K=()=>{const H=`# 学生个人全景学情与成长档案 (${a.name})
1
+ import{r as i,j as e,R as Et}from"./vendor-react-Kv_JATwr.js";import{B as Ks,E as me,s as Na,F as ps,G as va,H as wa,I as ka,i as Wt,J as nt,K as xt,L as za,b as Sa,e as Ca,N as Br,O as $a,x as Aa,Q as Ea,y as Ta,R as Pa,T as St,U as _a}from"./index-BzXADCXZ.js";import{L as Ra}from"./LazyWhiteboard-CcoBIx6V.js";import{R as Pe,k as ft,aZ as Ia,C as fs,a3 as La,w as yt,E as tn,U as $e,ax as Xs,a6 as Ut,ap as qt,ae as er,N as ut,bd as Ma,a5 as Oe,X as we,B as Rt,o as Ce,ay as sn,y as bt,be as rn,bf as Vt,bg as bs,bh as Oa,$ as De,bi as nn,D as gs,b7 as tr,n as an,f as ms,z as ve,bj as on,p as Js,ad as Jt,a2 as ln,bk as Da,bl as Fa,bm as us,ac as et,ak as Tt,bn as cn,bo as Ba,T as Ie,q as qe,aA as dn,bp as Ga,bq as js,br as Ha,i as ys,bs as Wa,ab as It,K as Ua,a9 as gt,af as Yt,bt as qa,h as Va,aU as Kt,e as xn,bu as mn,W as sr,Q as rr,a4 as Ht,bv as Ka,G as nr,bw as Ja,A as Ns,bx as un,by as ar,a$ as Lt,t as or,c as jt,_ as vs,bz as hn,bA as Ya,bB as Pt,aG as Gr,b2 as Qa,bC as ds,L as Za,u as Qt,O as ir,s as pn,bD as Xa,aj as fn,aM as eo,aF as lr,V as bn,bE as gn,bF as cr,bG as to,bH as jn,bI as yn,r as so,bJ as ro,bK as no,b as Ys,as as ao,bL as oo,bM as Hr,bN as Bs,S as Wr,aT as io,bO as Ur,bP as lo,az as co,bQ as xo}from"./vendor-icons-CXrZ3R2V.js";import{C as mo,T as uo}from"./ClassroomCountdownWidget-gs42lIGW.js";import{a as Nn,P as ho,h as po,g as fo,A as bo,C as go,X as jo,Y as yo,b as No,T as vo,e as wo}from"./vendor-charts-SrpBsvM3.js";import{r as dr,f as vn,D as wn,s as kn}from"./timeline-duration-BgdJCSrW.js";import{f as ko,t as zo}from"./teaching-modes-client-BeVaDdJ-.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";const qr=Ks;function zn({lessonId:t,lang:n,addToast:a}){const[o,d]=i.useState(!1),[r,l]=i.useState(!1),[s,h]=i.useState([]),[c,u]=i.useState(60),[m,p]=i.useState(40),[w,f]=i.useState({}),[N,b]=i.useState({}),[$,P]=i.useState({}),[y,k]=i.useState({}),[g,A]=i.useState({}),[U,W]=i.useState({}),T=n==="zh",Q=async(j=!1)=>{j?l(!0):d(!0);try{const ee=await(await fetch(`/api/lessons/${t}/eval-grades`)).json();if(Array.isArray(ee)){h(ee);const R={},O={},L={},X={};ee.forEach(K=>{K.grade?(R[K.id]=K.grade.teacher_score,O[K.id]=K.grade.teacher_comment,L[K.id]=Math.round(K.grade.teacher_weight*100),X[K.id]=Math.round(K.grade.peer_weight*100)):(R[K.id]=w[K.id]!==void 0?w[K.id]:80,O[K.id]=N[K.id]!==void 0?N[K.id]:"",L[K.id]=$[K.id]!==void 0?$[K.id]:c,X[K.id]=y[K.id]!==void 0?y[K.id]:m)}),f(K=>({...R,...K})),b(K=>({...O,...K})),P(K=>({...L,...K})),k(K=>({...X,...K}))}else throw new Error("Invalid submissions data format")}catch(q){console.error("Error fetching submissions grades:",q),a(T?"数据加载失败":"Failed to Load Data",T?"请检查网络连接或刷新页面。":"Please check your connection and try again.","warning")}finally{d(!1),l(!1)}};i.useEffect(()=>{t&&Q()},[t]),i.useEffect(()=>{const j=ps();if(!j||!t)return;const q=ee=>{(!ee?.lessonId||ee.lessonId===t)&&Q()};return j.on("assignment-submitted-toast",q),()=>{typeof j.off=="function"&&j.off("assignment-submitted-toast",q)}},[t]);const V=j=>{u(j),p(100-j),P(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=j)}),ee}),k(q=>{const ee={...q};return s.forEach(R=>{(!R.grade||R.grade.status!=="confirmed")&&(ee[R.id]=100-j)}),ee})},le=(j,q)=>{P(ee=>({...ee,[j]:q})),k(ee=>({...ee,[j]:100-q}))},F=async(j,q)=>{const ee=w[j],R=N[j]||"",O=($[j]??c)/100,L=(y[j]??m)/100;if(ee===void 0||isNaN(ee)||ee<0||ee>100){a(T?"评分无效":"Invalid Score",T?"教师评分必须在 0 到 100 之间!":"Teacher score must be between 0 and 100!","warning");return}if(q==="confirmed"){const X=T?"确认同步后,最终得分将直接同步写入宿主学期成绩库,此后该学生的作业成绩将锁定不可修改。是否确认?":"Once confirmed, the final score will be synced to the host semester reports and locked. Proceed?";if(!window.confirm(X))return}W(X=>({...X,[j]:q}));try{const K=await(await fetch("/api/commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({commandType:"assignment.grade",payload:{submissionId:j,teacherScore:Number(ee),teacherComment:R,teacherWeight:O,peerWeight:L,status:q}})})).json();if(K.success)a(q==="confirmed"?T?"平时成绩同步成功":"Semester Grade Synced":T?"平时成绩草稿已保存":"Grade Draft Saved",q==="confirmed"?T?`已将平时成绩 ${K.result.calculatedFinalScore} 分同步至学期报告!`:`Successfully synced grade ${K.result.calculatedFinalScore}!`:T?"成功保存了教师打分与评语草稿。":"Successfully saved score and comment draft.","success"),Q(!0);else throw new Error(K.error||"Failed to submit grade")}catch(X){a(T?"操作失败":"Operation Failed",X.message,"warning")}finally{W(X=>({...X,[j]:null}))}},D=j=>{A(q=>({...q,[j]:!q[j]}))};return o?e.jsxs("div",{className:"flex-grow flex flex-col items-center justify-center py-12 text-gray-500",children:[e.jsx(Pe,{className:"animate-spin text-indigo-500 mb-2",size:32}),e.jsx("p",{className:"text-xs",children:T?"正在读取学生作业与成绩状态...":"Loading student submissions and grades..."})]}):e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 w-full relative rounded-xl overflow-hidden border border-slate-200 shadow-md bg-white p-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center pb-4 border-b border-slate-100 mb-4 gap-3 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("h3",{className:"text-sm font-bold text-slate-800 flex items-center gap-1.5 select-none",children:[e.jsx(ft,{size:16,className:"text-indigo-655"}),T?"学生作业成绩评定与折算系统":"Student Assignment Grading & Sync"]}),e.jsxs("span",{className:"text-xs bg-indigo-50 text-indigo-750 px-2 py-0.5 rounded-full border border-indigo-100 font-bold",children:[s.length," ",T?"个提交":"submissions"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(me,{slot:"assignment.grade.toolbar.action",slotProps:{lessonId:t,submissions:s,refresh:()=>Q(!0),lang:n}}),e.jsx("button",{onClick:()=>Q(!0),disabled:r,className:"p-1.5 bg-white hover:bg-slate-55 border border-slate-200 rounded-lg text-slate-600 transition-colors flex items-center justify-center cursor-pointer shadow-4xs",title:T?"刷新数据":"Refresh",children:e.jsx(Pe,{size:12,className:r?"animate-spin":""})})]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-200 rounded-xl p-4 mb-5 shrink-0 flex flex-col md:flex-row md:items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-2.5",children:[e.jsx(Ia,{className:"text-indigo-500 shrink-0 mt-0.5",size:16}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-bold text-slate-700",children:T?"全局默认折算权重设置":"Default Grading Weights Configuration"}),e.jsx("p",{className:"text-xs text-subtle mt-0.5 font-medium",children:T?"调整权重分配,所有尚未锁定成绩的学生将自动应用此默认权重比例。":"Setting global default weights. Changes will automatically apply to non-confirmed grades."})]})]}),e.jsxs("div",{className:"flex items-center gap-4 shrink-0 bg-white px-3.5 py-2 rounded-lg border border-slate-200 shadow-3xs",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"教师评分:":"Teacher:"}),e.jsx("input",{type:"range","aria-label":T?"教师评分权重":"Teacher weight",min:"0",max:"100",step:"5",value:c,onChange:j=>V(Number(j.target.value)),className:"w-20 accent-indigo-650 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-bold text-indigo-700 w-8 text-right",children:[c,"%"]})]}),e.jsx("div",{className:"h-4 w-[1px] bg-slate-200"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-bold text-slate-500",children:T?"学生互评:":"Peer Review:"}),e.jsxs("span",{className:"text-xs font-bold text-slate-700 w-8",children:[m,"%"]})]})]}),e.jsx(me,{slot:"assignment.grade.rubric.addon",slotProps:{lessonId:t,defaultTeacherWeight:c,defaultPeerWeight:m,onTeacherWeightChange:V,lang:n}})]}),e.jsx("div",{className:"flex-grow flex-1 overflow-y-auto space-y-4 pr-1 scrollbar-thin",children:s.length===0?e.jsxs("div",{className:"h-full flex flex-col items-center justify-center py-12 text-slate-400 gap-2",children:[e.jsx(fs,{size:32,className:"text-slate-350"}),e.jsx("p",{className:"text-xs",children:T?"本节课目前没有任何学生提交作业。":"No students have submitted assignments yet for this lesson."})]}):s.map(j=>{const q=w[j.id]!==void 0?w[j.id]:80,ee=N[j.id]||"",R=$[j.id]??c,O=y[j.id]??m,L=j.grade?.status==="confirmed",X=Math.round(q*(R/100)+j.peerAverageScore*(O/100));return e.jsxs("div",{className:`bg-white border rounded-xl shadow-3xs overflow-hidden transition-all ${L?"border-emerald-200 bg-emerald-50/5":"border-slate-200"}`,children:[e.jsxs("div",{className:"px-4 py-3 bg-slate-50/50 border-b border-slate-100 flex flex-col md:flex-row md:items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:"w-8 h-8 rounded-full bg-indigo-50 border border-indigo-100 flex items-center justify-center text-indigo-700 font-bold text-xs select-none",children:j.studentName?.charAt(0)||"S"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-bold text-slate-800",children:j.studentName}),e.jsxs("div",{className:"text-xs text-slate-400 font-mono mt-0.5 flex items-center gap-1.5",children:[e.jsxs("span",{children:["V",j.version]}),e.jsx("span",{children:"•"}),e.jsx("span",{children:new Date(j.updatedAt).toLocaleString()})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[L?e.jsxs("span",{className:"bg-emerald-55 text-emerald-700 text-xs font-black px-2.5 py-1 rounded-full border border-emerald-150 flex items-center gap-1 shadow-3xs select-none",children:[e.jsx(La,{size:12}),T?"成绩已同步":"Synced to Reports"]}):e.jsx("span",{className:"bg-amber-50 text-amber-805 text-xs font-bold px-2 py-0.5 rounded-full border border-amber-200/60 select-none",children:j.grade?T?"草稿状态":"Draft":T?"未评定":"Ungraded"}),(()=>{const K=Na(j.filePath);return K?e.jsxs("a",{href:K,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-indigo-600 hover:text-indigo-850 font-medium hover:underline flex items-center gap-1 bg-white border border-slate-200 px-2 py-1 rounded-lg shadow-4xs",title:j.filePath,children:[e.jsx(yt,{size:11}),T?"查看作业":"View File",e.jsx(tn,{size:8})]}):null})()]})]}),e.jsxs("div",{className:"p-4 grid grid-cols-1 lg:grid-cols-12 gap-5",children:[e.jsxs("div",{className:"lg:col-span-5 flex flex-col gap-2.5 border-r border-slate-100 pr-0 lg:pr-5 text-left",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("span",{className:"text-xs font-bold text-slate-650 flex items-center gap-1 select-none",children:[e.jsx($e,{size:13,className:"text-slate-400"}),T?"学生互评详情":"Peer Review Details"]}),e.jsxs("span",{className:"text-xs font-bold text-slate-500 bg-slate-100 px-2 py-0.5 rounded-md",children:[T?"互评人数:":"Reviews:"," ",j.peerReviews.length]})]}),e.jsxs("div",{className:"bg-slate-50 border border-slate-100 rounded-xl p-3 flex items-center gap-3",children:[e.jsxs("div",{className:"bg-white border border-slate-200 w-12 h-12 rounded-lg flex flex-col items-center justify-center shrink-0 shadow-3xs",children:[e.jsx("span",{className:"text-xs text-slate-405 select-none font-bold",children:T?"均分":"Avg"}),e.jsx("span",{className:"text-sm font-extrabold text-slate-700 leading-none mt-0.5",children:j.peerAverageScore})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs text-slate-450 leading-normal font-medium",children:j.peerReviews.length>0?T?"根据同学互评分数得出的平均值。":"Average score computed from classmate evaluations.":T?"暂无同学对此作业给出评分。":"No classmate peer reviews received yet."}),j.peerReviews.length>0&&e.jsx("button",{onClick:()=>D(j.id),className:"text-xs text-indigo-650 hover:text-indigo-800 font-bold mt-1.5 flex items-center gap-0.5 cursor-pointer outline-none",children:g[j.id]?e.jsxs(e.Fragment,{children:[T?"收起互评详情":"Hide Details"," ",e.jsx(Xs,{size:12})]}):e.jsxs(e.Fragment,{children:[T?"展开互评详情":"Show Details"," ",e.jsx(Ut,{size:12})]})})]})]}),g[j.id]&&j.peerReviews.length>0&&e.jsx("div",{className:"mt-2 space-y-2 border-t border-slate-100 pt-2.5 max-h-40 overflow-y-auto scrollbar-thin",children:j.peerReviews.map(K=>e.jsxs("div",{className:"bg-white border border-slate-200 rounded-lg p-2.5 text-xs text-left shadow-4xs",children:[e.jsxs("div",{className:"flex justify-between items-center font-bold text-slate-700",children:[e.jsxs("span",{className:"flex items-center gap-1 font-semibold text-slate-655",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-slate-300"}),K.reviewer_name]}),e.jsxs("span",{className:"text-indigo-650 bg-indigo-50 border border-indigo-100 rounded px-1.5 py-0.5 text-xs",children:[K.score," ",T?"分":"pts"]})]}),K.comment&&e.jsxs("p",{className:"text-xs text-slate-550 mt-1 italic pl-2.5 border-l-2 border-slate-100 font-medium",children:['"',K.comment,'"']})]},K.id))})]}),e.jsxs("div",{className:"lg:col-span-7 flex flex-col gap-3 justify-between",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-650 mb-1 select-none",children:T?"教师平时分评分 (0-100)":"Teacher Score (0-100)"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{id:`teacher_score_input_${j.id}`,type:"number",min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Math.min(100,Math.max(0,Number(K.target.value)))})),className:"bg-white border border-slate-250 rounded-lg text-xs font-bold text-slate-700 px-3 py-1.5 focus:ring-1 focus:ring-indigo-500 outline-none w-20 shadow-4xs disabled:opacity-50 disabled:bg-slate-50"}),e.jsx("input",{type:"range","aria-label":T?`${j.studentName||"学生"} 的得分`:`Score for ${j.studentName||"student"}`,min:"0",max:"100",disabled:L,value:q,onChange:K=>f(H=>({...H,[j.id]:Number(K.target.value)})),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-1",children:[e.jsx("label",{className:"block text-xs font-bold text-slate-600 select-none",children:T?"打分占比 (教师权重)":"Teacher Score Weight"}),e.jsx("span",{className:"text-xs font-bold text-slate-400",children:T?`学生互评: ${O}%`:`Peer: ${O}%`})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{id:`teacher_weight_input_${j.id}`,type:"range",min:"0",max:"100",step:"5",disabled:L,value:R,onChange:K=>le(j.id,Number(K.target.value)),className:"flex-1 accent-indigo-650 disabled:opacity-40 cursor-pointer"}),e.jsxs("span",{className:"text-xs font-extrabold text-indigo-750 w-9 text-right",children:[R,"%"]})]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-bold text-slate-655 mb-1 select-none",children:T?"教师评价评语":"Teacher Comments & Feedback"}),e.jsx("textarea",{id:`teacher_comment_input_${j.id}`,disabled:L,value:ee,placeholder:T?"在此输入对学生作业作品的改进指导意见及评语。":"Enter guiding feedback for this student.",onChange:K=>b(H=>({...H,[j.id]:K.target.value})),rows:2,className:"w-full bg-white border border-slate-250 rounded-lg text-xs p-2 focus:ring-1 focus:ring-indigo-500 outline-none shadow-4xs disabled:opacity-50 disabled:bg-slate-50 resize-none font-medium text-slate-700"})]}),e.jsx(me,{slot:"assignment.grade.item.addon",slotProps:{submission:j,studentId:j.student_id,lessonId:t,score:q,comment:ee,isConfirmed:L,onScoreChange:K=>f(H=>({...H,[j.id]:K})),onCommentChange:K=>b(H=>({...H,[j.id]:K})),lang:n}}),e.jsxs("div",{className:"flex flex-col md:flex-row md:items-center justify-between gap-4 pt-2 border-t border-slate-100 mt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:`p-1.5 rounded-lg border flex items-center justify-center shrink-0 ${L?"bg-emerald-50 text-emerald-600 border-emerald-100":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:e.jsx(qt,{size:14})}),e.jsxs("div",{className:"text-xs text-slate-500 font-medium",children:[e.jsxs("div",{children:[T?"平时总分计算公式":"Calculated Final Grade",":"]}),e.jsxs("div",{className:"font-bold text-slate-700 mt-0.5 animate-formula",children:[R,"% × ",e.jsx("span",{className:"text-indigo-650 font-bold",children:q}),j.peerReviews.length>0&&` + ${O}% × ${j.peerAverageScore}`," = ",e.jsx("span",{className:L?"text-emerald-700 font-black text-xs":"text-indigo-700 font-black text-xs",children:L&&j.grade?.calculated_final_score||X}),T?"分":" pts"]})]})]}),!L&&e.jsxs("div",{className:"flex gap-2 justify-end shrink-0",children:[e.jsxs("button",{id:`teacher_draft_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"draft"),className:"px-3 py-1.5 bg-white border border-slate-350 rounded-lg text-xs font-bold text-slate-700 hover:bg-slate-55 flex items-center gap-1.5 shadow-4xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(er,{size:12}),U[j.id]==="draft"?T?"保存中...":"Saving...":T?"暂存草稿":"Save Draft"]}),e.jsxs("button",{id:`teacher_confirm_btn_${j.id}`,type:"button",disabled:!!U[j.id],onClick:()=>F(j.id,"confirmed"),className:"px-3.5 py-1.5 bg-indigo-600 border border-indigo-700 rounded-lg text-xs font-bold text-white hover:bg-indigo-700 flex items-center gap-1.5 shadow-3xs cursor-pointer select-none disabled:opacity-50",children:[e.jsx(ut,{size:12}),U[j.id]==="confirmed"?T?"同步中...":"Syncing...":T?"确认并同步":"Confirm & Sync"]})]})]})]})]})]},j.id)})})]})}function So({isOpen:t,onClose:n,lessonId:a,lessonTitle:o,lang:d="zh"}){const{data:r,health:l,lastSyncedAt:s}=va(a,{enabled:t});return t?e.jsx(wa,{lessonId:a,lessonTitle:o,data:r,lang:d,health:l,lastSyncedAt:s,onClose:n}):null}function Co({lessonId:t,lessonTitle:n,lang:a}){const o=new URLSearchParams({mode:"stage_display",lessonId:t});n&&o.set("title",n),a&&o.set("lang",a);const{pathname:d,origin:r}=window.location;return`${r}${d}?${o.toString()}#/stage_display`}function $o(){const t=i.useRef(null),[n,a]=i.useState(!1),[o,d]=i.useState(!1);i.useEffect(()=>()=>{t.current=null},[]),i.useEffect(()=>{const h=setInterval(()=>{const c=t.current;c&&c.closed&&(t.current=null)},3e3);return()=>clearInterval(h)},[]);const r=i.useCallback(h=>{const c=t.current;if(c&&!c.closed){c.focus();return}let u;try{u=window.open(Co(h),"openlearn-stage-display","width=1280,height=720,menubar=no,toolbar=no,location=no")}catch(m){console.warn("[StageDisplay] window.open threw:",m),u=null}if(!u){d(!0),a(!0);return}t.current=u,d(!1),a(!1),u.focus?.()},[]),l=i.useCallback(()=>a(!1),[]),s=i.useCallback(()=>d(!1),[]);return{fallbackOpen:n,blocked:o,openStageWindow:r,closeFallback:l,clearBlockedHint:s}}const Gs={CLEAR:{emoji:"💡",zh:"理解",en:"Clear",color:"#10b981"},CONFUSED:{emoji:"❓",zh:"困惑",en:"Confused",color:"#f59e0b"},TOO_FAST:{emoji:"🐇",zh:"慢一点",en:"Slow down",color:"#f43f5e"},SLOW:{emoji:"🐢",zh:"快一点",en:"Speed up",color:"#6366f1"}},Ao=["CLEAR","CONFUSED","TOO_FAST","SLOW"];function Eo({lessonId:t,lang:n,signals:a,onlineCount:o=0,onClose:d,activeSegmentTitle:r}){const l=n==="zh",[s,h]=i.useState(a);i.useEffect(()=>{const f=ps();if(!f)return;const N=b=>{b?.lessonId===t&&b?.summary&&h(b.summary)};return f.on("classroom:pacing_updated",N),()=>{typeof f.off=="function"&&f.off("classroom:pacing_updated",N)}},[t]);const c=Ao.map(f=>({key:f,count:Number(s[f]??0)})),u=c.reduce((f,N)=>f+N.count,0);Number(s.CONFUSED??0)+Number(s.TOO_FAST??0)+Number(s.SLOW??0);const m=u>0?Math.round(Number(s.CLEAR??0)/u*100):null,p=i.useCallback(()=>u===0?{text:l?"暂无学生反馈,等待中…":"No feedback yet",tone:"text-muted"}:Number(s.CONFUSED??0)>=Math.max(2,u*.3)?{text:l?"⚠ 较多学生困惑,建议放慢并重新讲解当前环节":"⚠ Many students are confused — slow down and re-explain",tone:"text-amber-600"}:Number(s.TOO_FAST??0)>=Math.max(2,u*.3)?{text:l?"🐇 较多学生希望放慢节奏":"🐇 Many students want you to slow down",tone:"text-rose-600"}:Number(s.SLOW??0)>=Math.max(2,u*.3)?{text:l?"🐢 较多学生希望加快节奏":"🐢 Many students want you to speed up",tone:"text-indigo-600"}:{text:l?"✓ 节奏反馈健康,可按当前节奏继续":"✓ Pace is healthy — carry on",tone:"text-emerald-700 dark:text-emerald-400"},[s,u,l]),w=c.filter(f=>f.count>0).map(f=>({name:Gs[f.key][l?"zh":"en"],value:f.count,color:Gs[f.key].color}));return e.jsx("div",{className:"fixed inset-0 z-[90] flex items-center justify-center bg-slate-900/60 backdrop-blur-2xs",onPointerDown:d,children:e.jsxs("div",{className:"bg-surface border border-theme rounded-2xl shadow-2xl w-[560px] max-w-[92vw] max-h-[86vh] overflow-y-auto p-5 font-sans text-main",onPointerDown:f=>f.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"p-2 bg-primary-theme/10 text-primary-theme rounded-xl",children:e.jsx(Ma,{size:18})}),e.jsxs("div",{children:[e.jsxs("h2",{className:"text-sm font-black text-main flex items-center gap-1.5",children:[l?"课堂反馈情绪仪表盘":"Classroom Feedback Dashboard",e.jsxs("span",{className:"flex items-center gap-1 text-2xs font-bold text-emerald-700 dark:text-emerald-400 bg-emerald-500/10 px-1.5 py-0.5 rounded-full",children:[e.jsx(Oe,{size:10})," ",l?"实时":"LIVE"]})]}),e.jsx("p",{className:"text-2xs text-muted mt-0.5",children:r?l?`当前教学环节: ${r} · 去重实时聚合`:`Active Segment: ${r} · Real-time`:l?"按环节去重 · 实时节奏反馈聚合":"Deduplicated real-time pacing feedback"})]})]}),e.jsx("button",{onClick:d,className:"p-1.5 rounded-lg hover:bg-surface-secondary text-muted cursor-pointer",title:l?"关闭":"Close",children:e.jsx(we,{size:16})})]}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-4 items-center",children:[e.jsxs("div",{className:"w-[200px] h-[200px] relative shrink-0",children:[u>0?e.jsx(Nn,{width:"100%",height:"100%",children:e.jsx(ho,{children:e.jsx(po,{data:w,dataKey:"value",nameKey:"name",innerRadius:52,outerRadius:85,paddingAngle:3,strokeWidth:0,isAnimationActive:!1,children:w.map((f,N)=>e.jsx(fo,{fill:f.color},N))})})}):e.jsx("div",{className:"w-full h-full flex items-center justify-center text-3xl opacity-30",children:"📊"}),e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[e.jsxs("span",{className:"text-2xs text-muted flex items-center gap-1",children:[e.jsx($e,{size:10})," ",o," ",l?"在线":"online"]}),e.jsx("span",{className:`text-xl font-black ${m===null?"text-muted":m>=60?"text-emerald-700 dark:text-emerald-400":m>=30?"text-amber-700 dark:text-amber-400":"text-rose-700 dark:text-rose-400"}`,children:m===null?"—":`${m}%`}),e.jsx("span",{className:"text-2xs text-muted",children:l?"理解占比":"clear ratio"})]})]}),e.jsxs("div",{className:"flex-1 w-full flex flex-col gap-2.5",children:[c.map(({key:f,count:N})=>{const b=Gs[f],$=u>0?Math.round(N/u*100):0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-xs mb-0.5",children:[e.jsxs("span",{className:"font-bold text-main",children:[b.emoji," ",l?b.zh:b.en]}),e.jsxs("span",{className:"text-muted font-mono",children:[N," · ",$,"%"]})]}),e.jsx("div",{className:"h-2.5 bg-surface-secondary rounded-full overflow-hidden border border-theme/50",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${$}%`,background:b.color}})})]},f)}),e.jsx("div",{className:`mt-1 text-xs font-bold ${p().tone}`,children:p().text}),e.jsx(me,{slot:"classroom.barometer.metric",slotProps:{lessonId:t,signals:s,total:u,health:m,lang:n}})]})]})]})})}function To({progressHistory:t,lang:n="zh",compact:a=!1}){const o=i.useMemo(()=>({title:n==="zh"?"课程学习进度趋势":"Learning Progress Trend",badge:n==="zh"?"历史趋势":"History",subtitle:n==="zh"?"按课程追踪学习完成度与进度变化曲线":"Track lesson completion progress over time",emptyTitle:n==="zh"?"暂无学习进度记录":"No Progress Records Yet",emptyDesc:n==="zh"?"当学生被分配课程并开始学习后,进度趋势将在此展示。":"Progress trends will appear here once lessons are assigned and started.",tooltipLesson:n==="zh"?"课程":"Lesson",tooltipProgress:n==="zh"?"完成进度":"Progress",tooltipDate:n==="zh"?"分配时间":"Assigned",tooltipStatus:n==="zh"?"状态":"Status",completed:n==="zh"?"已完成":"Completed",inProgress:n==="zh"?"进行中":"In Progress",statAvg:n==="zh"?"平均进度":"Avg Progress",statCompleted:n==="zh"?"已完成":"Completed",statTotal:n==="zh"?"总课程数":"Total Lessons"}),[n]),{chartData:d,stats:r}=i.useMemo(()=>{if(!t||t.length===0)return{chartData:[],stats:{avg:0,completed:0,total:0}};const s=new Map;for(const p of t){const w=s.get(p.lesson_id);(!w||p.assigned_at>w.assigned_at)&&s.set(p.lesson_id,p)}const c=Array.from(s.values()).sort((p,w)=>p.assigned_at-w.assigned_at).map(p=>{const w=new Date(p.assigned_at),f=n==="zh"?`${w.getMonth()+1}月${w.getDate()}日`:w.toLocaleDateString("en-US",{month:"short",day:"numeric"});return{label:p.lesson_title.length>8?p.lesson_title.slice(0,8)+"…":p.lesson_title,lessonTitle:p.lesson_title,progressPercent:Math.max(0,Math.min(100,Math.round(p.progress_percent))),completed:p.completed===1,dateLabel:f,timestamp:p.assigned_at}}),u=c.reduce((p,w)=>p+w.progressPercent,0),m=c.filter(p=>p.completed).length;return{chartData:c,stats:{avg:c.length>0?Math.round(u/c.length):0,completed:m,total:c.length}}},[t,n]);if(d.length===0)return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-empty",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-2",children:[e.jsx(Oe,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title})]}),e.jsxs("div",{className:"rounded-xl border border-dashed border-border/60 p-4 text-center",children:[e.jsx(fs,{size:24,className:"mx-auto text-muted mb-1.5"}),e.jsx("p",{className:"text-[11px] font-semibold text-muted",children:o.emptyTitle}),e.jsx("p",{className:"text-[10px] text-muted mt-0.5",children:o.emptyDesc})]})]});const l=a?180:220;return e.jsxs("div",{className:"bg-surface rounded-xl border border-border/80 p-3.5 shadow-3xs","data-testid":"learning-progress-trend-chart",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(Oe,{size:15,className:"text-primary-theme"}),e.jsx("h4",{className:"text-xs font-bold text-foreground",children:o.title}),e.jsx("span",{className:"text-[10px] font-mono font-bold px-1.5 py-0.5 rounded-md bg-primary-theme/10 text-primary-theme border border-primary-theme/20",children:o.badge})]})}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 mb-2.5",children:[e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statAvg}),e.jsxs("div",{className:"text-sm font-extrabold text-foreground font-mono",children:[r.avg,"%"]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statCompleted}),e.jsxs("div",{className:"text-sm font-extrabold text-emerald-600 dark:text-emerald-400 font-mono",children:[r.completed,"/",r.total]})]}),e.jsxs("div",{className:"bg-surface-secondary/40 rounded-lg px-2 py-1.5 border border-border/50",children:[e.jsx("div",{className:"text-[10px] text-muted font-medium",children:o.statTotal}),e.jsx("div",{className:"text-sm font-extrabold text-foreground font-mono",children:r.total})]})]}),e.jsx("div",{style:{width:"100%",height:l},children:e.jsx(Nn,{width:"100%",height:"100%",children:e.jsxs(bo,{data:d,margin:{top:10,right:10,left:-25,bottom:5},children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"progressGradientFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#6366f1",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#6366f1",stopOpacity:.02})]}),e.jsxs("linearGradient",{id:"progressStrokeGrad",x1:"0",y1:"0",x2:"1",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"#6366f1"}),e.jsx("stop",{offset:"50%",stopColor:"#818cf8"}),e.jsx("stop",{offset:"100%",stopColor:"#a78bfa"})]})]}),e.jsx(go,{strokeDasharray:"3 3",vertical:!1,stroke:"#e2e8f0",opacity:.5}),e.jsx(jo,{dataKey:"label",tick:{fontSize:10,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,interval:d.length>8?Math.floor(d.length/6):0}),e.jsx(yo,{domain:[0,100],ticks:[0,25,50,75,100],tick:{fontSize:10,fill:"#64748b",fontWeight:600},axisLine:{stroke:"#e2e8f0"},tickLine:!1,tickFormatter:s=>`${s}%`}),e.jsx(No,{y:100,stroke:"#10b981",strokeDasharray:"4 4",strokeWidth:1,label:{value:n==="zh"?"完成 100%":"100% Complete",fill:"#059669",fontSize:9,fontWeight:700,position:"insideTopRight"}}),e.jsx(vo,{content:({active:s,payload:h})=>{if(!s||!h||!h.length)return null;const c=h[0].payload;return e.jsxs("div",{className:"bg-slate-900 text-white rounded-xl p-2.5 shadow-xl border border-slate-700/80 text-xs min-w-[180px] z-50",children:[e.jsxs("div",{className:"flex items-center gap-1.5 pb-1.5 border-b border-slate-800",children:[e.jsx(Rt,{size:12,className:"text-indigo-300"}),e.jsx("span",{className:"font-bold text-indigo-300 truncate max-w-[150px]",children:c.lessonTitle})]}),e.jsxs("div",{className:"pt-1.5 space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipProgress,":"]}),e.jsxs("span",{className:"font-extrabold text-emerald-400 font-mono",children:[c.progressPercent,"%"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipDate,":"]}),e.jsx("span",{className:"text-slate-200 font-mono text-[11px]",children:c.dateLabel})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-slate-300",children:[o.tooltipStatus,":"]}),e.jsxs("span",{className:`flex items-center gap-1 font-semibold ${c.completed?"text-emerald-400":"text-amber-400"}`,children:[e.jsx(Ce,{size:11}),c.completed?o.completed:o.inProgress]})]})]})]})}}),e.jsx(wo,{type:"monotone",dataKey:"progressPercent",name:n==="zh"?"完成进度":"Progress",stroke:"url(#progressStrokeGrad)",strokeWidth:2.5,fill:"url(#progressGradientFill)",dot:{r:3.5,fill:"#6366f1",stroke:"#ffffff",strokeWidth:2},activeDot:{r:6,stroke:"#a78bfa",strokeWidth:2,fill:"#ffffff"},animationDuration:600})]})})})]})}function xr({isOpen:t,onClose:n,student:a,lessonId:o,classId:d,lang:r="zh",addToast:l,onInspectSandbox:s,onCastStudentScreen:h,onAwardPoints:c,progressHistory:u}){const[m,p]=i.useState(!1),[w,f]=i.useState([]),[N,b]=i.useState("overview"),$=ka(H=>H.version);i.useEffect(()=>{t&&b("overview")},[t,a?.id]),i.useEffect(()=>{if(u!==void 0)return;if(!t||!a?.id){f([]);return}let H=!0;return(async()=>{try{const te=await fetch(`/api/students/${a.id}/progress`);if(te.ok){const de=await te.json();H&&Array.isArray(de)&&f(de)}}catch{}})(),()=>{H=!1}},[t,a?.id,u,$]);const P=u!==void 0?u:w,y=a?.competencyScores,k=i.useMemo(()=>[{key:"logic",label:r==="zh"?"算法逻辑":"Logic"},{key:"engineering",label:r==="zh"?"代码工程":"Engineering"},{key:"creativity",label:r==="zh"?"创新思维":"Creativity"},{key:"collaboration",label:r==="zh"?"团队协作":"Collaboration"},{key:"focus",label:r==="zh"?"课堂专注":"Focus"}],[r]),g=i.useMemo(()=>k.map(H=>{const re=y?.[H.key],te=typeof re=="number"&&Number.isFinite(re);return{key:H.key,label:H.label,score:te?Math.max(0,Math.min(100,Math.round(re))):0,available:te}}),[y,k]),A=g.some(H=>H.available),U=g.filter(H=>!H.available).map(H=>H.label),W=i.useMemo(()=>{const H=r==="zh",re=a?.name??(r==="zh"?"该学生":"This student"),te=g.filter(B=>B.available);if(te.length===0)return H?`${re}本节暂无可用的维度数据(未参与随堂测/课件互动),无法生成掌握度评语。建议下节课关注其参与情况。`:`${re} has no competency data for this session (no quiz/courseware interaction).`;const de=Math.round(te.reduce((B,se)=>B+se.score,0)/te.length),G=te.reduce((B,se)=>se.score>B.score?se:B),S=te.reduce((B,se)=>se.score<B.score?se:B),M=g.filter(B=>!B.available).map(B=>B.label);return(H?[`本节已采集维度:${te.map(B=>`${B.label} ${B.score}`).join("、")},平均 ${de}。`,`相对优势为${G.label}(${G.score}),相对薄弱为${S.label}(${S.score})。`,M.length>0?`未采集维度:${M.join("、")}。`:""]:[`Collected: ${te.map(B=>`${B.label} ${B.score}`).join(", ")}; average ${de}.`,`Strongest ${G.label} (${G.score}), weakest ${S.label} (${S.score}).`,M.length>0?`Missing: ${M.join(", ")}.`:""]).filter(Boolean).join(" ")},[g,r,a]),T=i.useMemo(()=>{const H=r==="zh",re=g.filter(de=>de.available);if(re.length===0)return H?"数据不足,暂不生成建议":"Insufficient data";const te=re.reduce((de,G)=>de+G.score,0)/re.length;return te>=85?H?"建议进入算法创新挑战营":"Recommended for Advanced Camp":te>=70?H?"建议保持当前节奏并补强薄弱维度":"Keep pace, strengthen weak areas":H?"建议课后补充基础微练习":"Suggest remedial practice"},[g,r]),Q=i.useMemo(()=>{const H=g.filter(te=>te.available);if(H.length===0)return"—";const re=H.reduce((te,de)=>te+de.score,0)/H.length;return re>=90?"A+":re>=80?"A":re>=70?"B+":re>=60?"B":"C"},[g]),V=i.useMemo(()=>{const de=(B,se)=>{const v=-Math.PI/2+2*Math.PI/5*se;return{x:100+B*Math.cos(v),y:100+B*Math.sin(v)}},G=[1,.66,.33].map(B=>{const se=75*B;return Array.from({length:5},(_,Z)=>{const{x:ie,y:xe}=de(se,Z);return`${ie.toFixed(1)},${xe.toFixed(1)}`}).join(" ")}),S=Array.from({length:5},(B,se)=>{const{x:v,y:_}=de(75,se);return{x1:100,y1:100,x2:v,y2:_}}),M=g.map((B,se)=>{const v=75*Math.min(Math.max(B.score/100,.1),1);return de(v,se)}),I=M.map(B=>`${B.x.toFixed(1)},${B.y.toFixed(1)}`).join(" ");return{gridLevels:G,axes:S,dataPoints:M,dataPolygonString:I}},[g]);if(!t||!a)return null;const le=a.points??0,F=a.deltaPoints??4,D=a.focusPercentage,j=a.accuracyPercentage,q=a.helpCount??3,ee=a.role||a.student_number||"",R=a.group_name||"",O=a.student_number||a.id.slice(-6),L=a.timeline??[],X=async(H,re)=>{p(!0);try{c?c(a.id,H,re):await fetch(`/api/students/${a.id}/points`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({delta:H,dimension:"attribution",reason:re,classId:d,lessonId:o})}),l?.(r==="zh"?"成长积分已发放":"Points Awarded",r==="zh"?`已为学生 [${a.name}] ${H>=0?"+":""}${H} 分(${re})`:`Awarded ${H} pts to [${a.name}]`,"success")}catch(te){const de=te instanceof Error?te.message:String(te);l?.("Error",de,"error")}finally{p(!1)}},K=()=>{const H=`# 学生个人全景学情与成长档案 (${a.name})
2
2
  - **学生姓名**: ${a.name}
3
3
  - **学号**: ${O}
4
4
  - **所属班级**: ${a.className||d||"默认班级"}
@@ -1 +1 @@
1
- import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as n}from"./index-2676X8YB.js";import{a2 as d,o,$ as l,aQ as i}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function y({notification:s,onClose:t,lang:r,onOpenWorkspace:a}){return s?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(n.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-xl flex flex-col overflow-hidden max-h-[85vh] font-sans",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(d,{className:"text-indigo-600 font-sans shrink-0",size:20}),e.jsx("h2",{className:"font-bold text-gray-800 text-base font-sans truncate",children:s.title})]}),e.jsx("button",{onClick:t,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors text-lg",children:"×"})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-4",children:[e.jsx("div",{className:"p-4 bg-indigo-50/50 rounded-xl border border-indigo-100 text-sm text-gray-700 leading-relaxed font-sans",children:s.message}),s.assignment&&e.jsxs("div",{className:"space-y-4 font-sans",children:[e.jsxs("div",{className:"border border-gray-150 rounded-xl p-4 bg-gray-50/50 space-y-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-xs text-gray-400 uppercase tracking-wider font-semibold font-sans",children:r==="zh"?"关联作业":"Associated Assignment"}),s.assignment.submission_status==="graded"&&e.jsx("span",{className:"bg-green-100 border border-green-200 text-green-800 text-xs font-bold px-2.5 py-1 rounded-full shadow-sm font-mono",children:r==="zh"?`得分:${s.assignment.score}%`:`Score: ${s.assignment.score}%`})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-base text-indigo-900 font-sans",children:s.assignment.title}),e.jsx("p",{className:"text-xs text-gray-500 mt-1 font-sans",children:s.assignment.class_name})]}),s.assignment.feedback&&e.jsxs("div",{className:"mt-3 bg-white p-3 rounded-lg border border-gray-150 space-y-1 font-sans",children:[e.jsxs("div",{className:"text-xs font-bold text-green-700 flex items-center justify-between gap-2 font-sans",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(o,{size:14,className:"font-sans"}),e.jsx("span",{children:r==="zh"?"教师评审意见与反馈":"Teacher Feedback & Recommendations"})]}),s.assignment.graded_at&&e.jsxs("div",{className:"text-xs text-gray-400 font-mono flex items-center gap-1 font-normal select-none",children:[e.jsx(l,{size:11,className:"text-neutral-400"}),e.jsx("span",{children:new Date(s.assignment.graded_at).toLocaleString(r==="zh"?"zh-CN":"en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})})]})]}),e.jsx("div",{className:"text-xs text-gray-600 italic bg-green-50/30 p-2 rounded border border-green-50 mt-1 leading-relaxed whitespace-pre-wrap font-sans",children:s.assignment.feedback})]})]}),s.assignment.submission_content&&e.jsxs("div",{className:"space-y-1.5 font-sans",children:[e.jsx("div",{className:"text-xs text-gray-400 font-bold uppercase tracking-wider font-sans",children:r==="zh"?"我提交的内容":"My Submission Content"}),e.jsx("div",{className:"bg-gray-900 text-gray-100 p-4 rounded-xl border border-gray-800 overflow-x-auto max-h-40 overflow-y-auto text-xs font-mono leading-relaxed whitespace-pre-wrap",children:s.assignment.submission_content})]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 bg-gray-50/85 flex justify-end gap-2.5 shrink-0 font-sans",children:[e.jsx("button",{type:"button",onClick:t,className:"px-4 py-2 text-xs font-semibold border border-gray-200 text-gray-700 bg-white rounded-lg hover:bg-gray-100 transition-colors cursor-pointer",children:r==="zh"?"关闭":"Close"}),s.assignment&&e.jsxs("button",{type:"button",onClick:()=>a(s.assignment),className:"px-4 py-2 text-xs font-bold bg-indigo-600 text-white border border-indigo-700 rounded-lg hover:bg-indigo-700 hover:shadow shadow-sm transition-all cursor-pointer flex items-center gap-1.5 font-sans",children:[e.jsx(i,{size:14,className:"font-sans"}),r==="zh"?"打开画布 / 查看详情":"Open Workspace Canvas"]})]})]})}):null}export{y as NotificationDetailModal};
1
+ import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as n}from"./index-BzXADCXZ.js";import{a2 as d,o,$ as l,aQ as i}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function y({notification:s,onClose:t,lang:r,onOpenWorkspace:a}){return s?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(n.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-xl flex flex-col overflow-hidden max-h-[85vh] font-sans",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(d,{className:"text-indigo-600 font-sans shrink-0",size:20}),e.jsx("h2",{className:"font-bold text-gray-800 text-base font-sans truncate",children:s.title})]}),e.jsx("button",{onClick:t,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors text-lg",children:"×"})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-4",children:[e.jsx("div",{className:"p-4 bg-indigo-50/50 rounded-xl border border-indigo-100 text-sm text-gray-700 leading-relaxed font-sans",children:s.message}),s.assignment&&e.jsxs("div",{className:"space-y-4 font-sans",children:[e.jsxs("div",{className:"border border-gray-150 rounded-xl p-4 bg-gray-50/50 space-y-3",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsx("span",{className:"text-xs text-gray-400 uppercase tracking-wider font-semibold font-sans",children:r==="zh"?"关联作业":"Associated Assignment"}),s.assignment.submission_status==="graded"&&e.jsx("span",{className:"bg-green-100 border border-green-200 text-green-800 text-xs font-bold px-2.5 py-1 rounded-full shadow-sm font-mono",children:r==="zh"?`得分:${s.assignment.score}%`:`Score: ${s.assignment.score}%`})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-bold text-base text-indigo-900 font-sans",children:s.assignment.title}),e.jsx("p",{className:"text-xs text-gray-500 mt-1 font-sans",children:s.assignment.class_name})]}),s.assignment.feedback&&e.jsxs("div",{className:"mt-3 bg-white p-3 rounded-lg border border-gray-150 space-y-1 font-sans",children:[e.jsxs("div",{className:"text-xs font-bold text-green-700 flex items-center justify-between gap-2 font-sans",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(o,{size:14,className:"font-sans"}),e.jsx("span",{children:r==="zh"?"教师评审意见与反馈":"Teacher Feedback & Recommendations"})]}),s.assignment.graded_at&&e.jsxs("div",{className:"text-xs text-gray-400 font-mono flex items-center gap-1 font-normal select-none",children:[e.jsx(l,{size:11,className:"text-neutral-400"}),e.jsx("span",{children:new Date(s.assignment.graded_at).toLocaleString(r==="zh"?"zh-CN":"en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})})]})]}),e.jsx("div",{className:"text-xs text-gray-600 italic bg-green-50/30 p-2 rounded border border-green-50 mt-1 leading-relaxed whitespace-pre-wrap font-sans",children:s.assignment.feedback})]})]}),s.assignment.submission_content&&e.jsxs("div",{className:"space-y-1.5 font-sans",children:[e.jsx("div",{className:"text-xs text-gray-400 font-bold uppercase tracking-wider font-sans",children:r==="zh"?"我提交的内容":"My Submission Content"}),e.jsx("div",{className:"bg-gray-900 text-gray-100 p-4 rounded-xl border border-gray-800 overflow-x-auto max-h-40 overflow-y-auto text-xs font-mono leading-relaxed whitespace-pre-wrap",children:s.assignment.submission_content})]})]})]}),e.jsxs("div",{className:"p-4 border-t border-gray-100 bg-gray-50/85 flex justify-end gap-2.5 shrink-0 font-sans",children:[e.jsx("button",{type:"button",onClick:t,className:"px-4 py-2 text-xs font-semibold border border-gray-200 text-gray-700 bg-white rounded-lg hover:bg-gray-100 transition-colors cursor-pointer",children:r==="zh"?"关闭":"Close"}),s.assignment&&e.jsxs("button",{type:"button",onClick:()=>a(s.assignment),className:"px-4 py-2 text-xs font-bold bg-indigo-600 text-white border border-indigo-700 rounded-lg hover:bg-indigo-700 hover:shadow shadow-sm transition-all cursor-pointer flex items-center gap-1.5 font-sans",children:[e.jsx(i,{size:14,className:"font-sans"}),r==="zh"?"打开画布 / 查看详情":"Open Workspace Canvas"]})]})]})}):null}export{y as NotificationDetailModal};
@@ -1,4 +1,4 @@
1
- import{r as K,j as e,c as Ee,g as ot,R as ve}from"./vendor-react-Kv_JATwr.js";import{c as ye,ao as lt,bg as dt,ac as Pe,T as _e,ak as ct,bS as ht,bw as Ue,X as ze,ae as ut,S as $e,z as Le,aT as ft,aA as mt,f as Ge,a3 as pt,ba as xt,U as gt,bT as Me,R as Ne,w as bt,bU as Be,a$ as yt,aX as vt,bV as wt,D as Oe,p as jt,E as et,o as Ce,b as Te,a8 as tt,ar as _t,P as st,ap as Ze,bp as kt,bW as Nt,as as zt}from"./vendor-icons-CXrZ3R2V.js";import{c as Ae}from"./vendor-pptx-Bzn6whfK.js";import{d as Ve,s as je,c as St}from"./index-2676X8YB.js";import{p as Ct}from"./pluginParsers-e4PSm2Iy.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-charts-SrpBsvM3.js";import"./vendor-motion-BFAPOs-b.js";function It({pluginId:R,lang:C}){const a=C==="zh",N=(v,j)=>a?v:j,[c,o]=K.useState(null),[h,n]=K.useState(!0),[f,p]=K.useState(!1),[k,b]=K.useState(null),[w,i]=K.useState(null),x=`/api/plugins/${encodeURIComponent(R)}/network-grants`,s=K.useCallback(async()=>{n(!0);try{const v=await fetch(x);if(v.status===403||v.status===404){p(!0);return}const j=await v.json().catch(()=>({}));if(!v.ok||j?.success===!1){p(!0);return}o({proposed:Array.isArray(j.proposed)?j.proposed:[],approved:Array.isArray(j.approved)?j.approved:[],rejected:Array.isArray(j.rejected)?j.rejected:[]}),p(!1)}catch{p(!0)}finally{n(!1)}},[x]);K.useEffect(()=>{s()},[s]);const d=K.useCallback(async v=>{b(v),i(null);try{const j=await fetch(x,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hosts:[v]})}),P=await j.json().catch(()=>({}));(!j.ok||P?.success!==!0)&&i(P?.error||N("批准失败","Approval failed"))}catch(j){i(j?.message||N("批准失败","Approval failed"))}finally{b(null),await s()}},[x,s,N]),l=K.useCallback(async v=>{b(v),i(null);try{const j=await fetch(`${x}?host=${encodeURIComponent(v)}`,{method:"DELETE"}),P=await j.json().catch(()=>({}));(!j.ok||P?.success!==!0)&&i(P?.error||N("撤销失败","Revoke failed"))}catch(j){i(j?.message||N("撤销失败","Revoke failed"))}finally{b(null),await s()}},[x,s,N]),g=c&&(c.approved.length>0||c.proposed.length>0||c.rejected.length>0);if(f||!h&&!g)return null;if(h)return e.jsxs("div",{className:"py-4 flex items-center gap-2 text-xs text-gray-400","data-testid":"network-grants-loading",children:[e.jsx(ye,{size:14,className:"animate-spin"}),N("正在读取出站域名授权…","Loading outbound grants…")]});const y=(c?.proposed??[]).filter(v=>!(c?.approved??[]).includes(v));return e.jsxs("div",{className:"pt-4 mt-2 border-t border-gray-100","data-testid":"network-grants-panel",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(lt,{size:15,className:"text-gray-500"}),e.jsx("h4",{className:"text-sm font-medium text-gray-700",children:N("出站网络域名","Outbound network hosts")}),e.jsxs("span",{className:"text-[10px] font-mono text-gray-400 bg-gray-50 border border-gray-200 rounded px-1.5 py-0.5",children:[c?.approved.length??0," ",N("已批准","approved")]})]}),e.jsx("p",{className:"text-xs text-gray-400 mb-3 leading-relaxed",children:N("清单声明的域名只是申请,只有「已批准」的才会被运行时放行。回环、私有与保留地址永远不会被批准。","Hosts declared in the manifest are requests only; the runtime allows just the approved ones. Loopback, private and reserved addresses are never granted.")}),w&&e.jsx("div",{className:"mb-2 text-xs text-rose-600 bg-rose-50 border border-rose-100 rounded-lg px-2.5 py-1.5",role:"alert",children:w}),e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"text-[11px] font-bold text-emerald-700 mb-1.5 flex items-center gap-1",children:[e.jsx(dt,{size:12}),N("已批准(运行时放行)","Approved (allowed at runtime)")]}),c&&c.approved.length>0?e.jsx("ul",{className:"space-y-1",children:c.approved.map(v=>e.jsxs("li",{className:"flex items-center justify-between gap-2 bg-emerald-50/60 border border-emerald-100 rounded-lg px-2.5 py-1.5",children:[e.jsx("code",{className:"text-xs text-emerald-900 font-mono truncate",children:v}),e.jsxs("button",{type:"button",onClick:()=>void l(v),disabled:k===v,"data-testid":`revoke-${v}`,className:"text-[11px] font-bold text-rose-600 hover:text-rose-700 flex items-center gap-1 disabled:opacity-40 cursor-pointer",children:[k===v?e.jsx(ye,{size:11,className:"animate-spin"}):e.jsx(Pe,{size:11}),N("撤销","Revoke")]})]},v))}):e.jsx("p",{className:"text-xs text-gray-400 italic","data-testid":"no-approved",children:N("尚未批准任何域名 —— 该插件无法发起出站请求。","No host approved yet — this plugin cannot make outbound requests.")})]}),y.length>0&&e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"text-[11px] font-bold text-amber-700 mb-1.5 flex items-center gap-1",children:[e.jsx(_e,{size:12}),N("清单申请中(未生效)","Requested by manifest (not active)")]}),e.jsx("ul",{className:"space-y-1",children:y.map(v=>e.jsxs("li",{className:"flex items-center justify-between gap-2 bg-amber-50/60 border border-amber-100 rounded-lg px-2.5 py-1.5",children:[e.jsx("code",{className:"text-xs text-amber-900 font-mono truncate",children:v}),e.jsxs("button",{type:"button",onClick:()=>void d(v),disabled:k===v,"data-testid":`approve-${v}`,className:"text-[11px] font-bold text-indigo-600 hover:text-indigo-700 flex items-center gap-1 disabled:opacity-40 cursor-pointer",children:[k===v?e.jsx(ye,{size:11,className:"animate-spin"}):e.jsx(ct,{size:11}),N("批准","Approve")]})]},v))})]}),c&&c.rejected.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"text-[11px] font-bold text-rose-700 mb-1.5 flex items-center gap-1",children:[e.jsx(ht,{size:12}),N("不可批准","Not approvable")]}),e.jsx("ul",{className:"space-y-1","data-testid":"rejected-hosts",children:c.rejected.map(v=>e.jsxs("li",{className:"text-xs text-gray-500 leading-relaxed",children:[e.jsx("code",{className:"font-mono text-rose-700 line-through",children:v.host}),v.reason?e.jsxs("span",{className:"ml-1.5 text-gray-400",children:["— ",v.reason]}):null]},`${v.host}-${v.reason??""}`))})]})]})}function Et({pluginId:R,pluginName:C,manifestStr:a,lang:N,onClose:c}){const[o,h]=K.useState(null),[n,f]=K.useState({}),[p,k]=K.useState(!0),[b,w]=K.useState(!1),[i,x]=K.useState(null),s=K.useCallback(async()=>{k(!0);try{const j=await fetch(`/api/plugins/${encodeURIComponent(R)}/config`);if(j.ok){const P=await j.json();if(P.success){h(P.result.schema),f(P.result.values);return}}}catch{}try{const P=JSON.parse(a).configuration?.properties??{};h(P);const E={};for(const[M,T]of Object.entries(P))E[M]=T.default;f(E)}catch{h({})}k(!1)},[R,a]);K.useEffect(()=>{s().finally(()=>k(!1))},[s]);const d=async()=>{w(!0),x(null);try{const P=await(await fetch(`/api/plugins/${encodeURIComponent(R)}/config`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})).json();P.success?x(N==="zh"?"✓ 已保存":"✓ Saved"):x(`✗ ${P.error}`)}catch(j){x(`✗ ${j.message}`)}w(!1)},l=(j,P)=>{f(E=>({...E,[j]:P})),x(null)},g=(j,P)=>N==="zh"?j:P,y=(j,P)=>{const E=n[j],M=P.description??"";switch(P.type){case"boolean":return e.jsxs("div",{className:"flex items-center justify-between py-2.5 border-b border-gray-100",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:M})]}),e.jsx("button",{type:"button",onClick:()=>l(j,!E),className:`relative w-10 h-5 rounded-full transition-colors ${E?"bg-indigo-600":"bg-gray-300"}`,children:e.jsx("span",{className:`absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-transform ${E?"translate-x-5":"translate-x-0.5"}`})})]},j);case"number":case"integer":return e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("input",{type:"number",step:P.type==="integer"?1:"any",min:P.minimum,max:P.maximum,value:E!=null?String(E):"",onChange:T=>{const G=T.target.value===""?void 0:Number(T.target.value);l(j,G)},className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none",placeholder:P.default!==void 0?String(P.default):""})]},j);default:return P.enum&&P.enum.length>0?e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("select",{value:String(E??P.default??""),onChange:T=>l(j,T.target.value),className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none bg-white",children:P.enum.map(T=>e.jsx("option",{value:String(T),children:String(T)},String(T)))})]},j):e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("input",{type:"text",value:E!=null?String(E):"",onChange:T=>l(j,T.target.value),className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none",placeholder:P.default!==void 0?String(P.default):""})]},j)}},v=o&&Object.keys(o).length>0;return e.jsx("div",{className:"fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4",onClick:c,children:e.jsxs("div",{className:"bg-white rounded-xl shadow-xl w-full max-w-md flex flex-col max-h-[85vh]",onClick:j=>j.stopPropagation(),children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ue,{size:18,className:"text-gray-500"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-gray-800 text-sm",children:g("插件设置","Plugin Settings")}),e.jsx("p",{className:"text-xs text-gray-400",children:C})]})]}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-gray-600 p-1",children:e.jsx(ze,{size:18})})]}),e.jsxs("div",{className:"p-4 flex-1 overflow-auto",children:[p?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ye,{size:24,className:"text-gray-400 animate-spin"})}):v?e.jsx("div",{className:"space-y-0.5",children:Object.entries(o).map(([j,P])=>y(j,P))}):e.jsxs("div",{className:"text-center py-8",children:[e.jsx(Ue,{size:32,className:"text-gray-300 mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-gray-400",children:g("此插件没有可配置项。","This plugin has no configurable settings.")}),e.jsx("p",{className:"text-xs text-gray-300 mt-1",children:g("在 manifest.configuration 中声明配置项即可在此处显示。","Declare settings in manifest.configuration to see them here.")})]}),e.jsx(It,{pluginId:R,lang:N})]}),v&&e.jsxs("div",{className:"p-4 border-t border-gray-100 flex items-center justify-between",children:[i&&e.jsx("span",{className:`text-xs ${i.startsWith("✓")?"text-green-600":"text-red-500"}`,children:i}),e.jsxs("div",{className:"flex gap-2 ml-auto",children:[e.jsx("button",{onClick:c,className:"px-4 py-2 text-xs font-medium text-gray-600 hover:bg-gray-50 rounded-lg transition-colors",children:g("取消","Cancel")}),e.jsxs("button",{onClick:d,disabled:b,className:"px-4 py-2 text-xs font-medium bg-indigo-600 text-white hover:bg-indigo-700 rounded-lg transition-colors flex items-center gap-1.5 disabled:opacity-50",children:[b?e.jsx(ye,{size:14,className:"animate-spin"}):e.jsx(ut,{size:14}),g("保存","Save")]})]})]})]})})}var Re={exports:{}};/*!
1
+ import{r as K,j as e,c as Ee,g as ot,R as ve}from"./vendor-react-Kv_JATwr.js";import{c as ye,ao as lt,bg as dt,ac as Pe,T as _e,ak as ct,bS as ht,bw as Ue,X as ze,ae as ut,S as $e,z as Le,aT as ft,aA as mt,f as Ge,a3 as pt,ba as xt,U as gt,bT as Me,R as Ne,w as bt,bU as Be,a$ as yt,aX as vt,bV as wt,D as Oe,p as jt,E as et,o as Ce,b as Te,a8 as tt,ar as _t,P as st,ap as Ze,bp as kt,bW as Nt,as as zt}from"./vendor-icons-CXrZ3R2V.js";import{c as Ae}from"./vendor-pptx-Bzn6whfK.js";import{d as Ve,s as je,c as St}from"./index-BzXADCXZ.js";import{p as Ct}from"./pluginParsers-PzgFzxS9.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-charts-SrpBsvM3.js";import"./vendor-motion-BFAPOs-b.js";function It({pluginId:R,lang:C}){const a=C==="zh",N=(v,j)=>a?v:j,[c,o]=K.useState(null),[h,n]=K.useState(!0),[f,p]=K.useState(!1),[k,b]=K.useState(null),[w,i]=K.useState(null),x=`/api/plugins/${encodeURIComponent(R)}/network-grants`,s=K.useCallback(async()=>{n(!0);try{const v=await fetch(x);if(v.status===403||v.status===404){p(!0);return}const j=await v.json().catch(()=>({}));if(!v.ok||j?.success===!1){p(!0);return}o({proposed:Array.isArray(j.proposed)?j.proposed:[],approved:Array.isArray(j.approved)?j.approved:[],rejected:Array.isArray(j.rejected)?j.rejected:[]}),p(!1)}catch{p(!0)}finally{n(!1)}},[x]);K.useEffect(()=>{s()},[s]);const d=K.useCallback(async v=>{b(v),i(null);try{const j=await fetch(x,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hosts:[v]})}),P=await j.json().catch(()=>({}));(!j.ok||P?.success!==!0)&&i(P?.error||N("批准失败","Approval failed"))}catch(j){i(j?.message||N("批准失败","Approval failed"))}finally{b(null),await s()}},[x,s,N]),l=K.useCallback(async v=>{b(v),i(null);try{const j=await fetch(`${x}?host=${encodeURIComponent(v)}`,{method:"DELETE"}),P=await j.json().catch(()=>({}));(!j.ok||P?.success!==!0)&&i(P?.error||N("撤销失败","Revoke failed"))}catch(j){i(j?.message||N("撤销失败","Revoke failed"))}finally{b(null),await s()}},[x,s,N]),g=c&&(c.approved.length>0||c.proposed.length>0||c.rejected.length>0);if(f||!h&&!g)return null;if(h)return e.jsxs("div",{className:"py-4 flex items-center gap-2 text-xs text-gray-400","data-testid":"network-grants-loading",children:[e.jsx(ye,{size:14,className:"animate-spin"}),N("正在读取出站域名授权…","Loading outbound grants…")]});const y=(c?.proposed??[]).filter(v=>!(c?.approved??[]).includes(v));return e.jsxs("div",{className:"pt-4 mt-2 border-t border-gray-100","data-testid":"network-grants-panel",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(lt,{size:15,className:"text-gray-500"}),e.jsx("h4",{className:"text-sm font-medium text-gray-700",children:N("出站网络域名","Outbound network hosts")}),e.jsxs("span",{className:"text-[10px] font-mono text-gray-400 bg-gray-50 border border-gray-200 rounded px-1.5 py-0.5",children:[c?.approved.length??0," ",N("已批准","approved")]})]}),e.jsx("p",{className:"text-xs text-gray-400 mb-3 leading-relaxed",children:N("清单声明的域名只是申请,只有「已批准」的才会被运行时放行。回环、私有与保留地址永远不会被批准。","Hosts declared in the manifest are requests only; the runtime allows just the approved ones. Loopback, private and reserved addresses are never granted.")}),w&&e.jsx("div",{className:"mb-2 text-xs text-rose-600 bg-rose-50 border border-rose-100 rounded-lg px-2.5 py-1.5",role:"alert",children:w}),e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"text-[11px] font-bold text-emerald-700 mb-1.5 flex items-center gap-1",children:[e.jsx(dt,{size:12}),N("已批准(运行时放行)","Approved (allowed at runtime)")]}),c&&c.approved.length>0?e.jsx("ul",{className:"space-y-1",children:c.approved.map(v=>e.jsxs("li",{className:"flex items-center justify-between gap-2 bg-emerald-50/60 border border-emerald-100 rounded-lg px-2.5 py-1.5",children:[e.jsx("code",{className:"text-xs text-emerald-900 font-mono truncate",children:v}),e.jsxs("button",{type:"button",onClick:()=>void l(v),disabled:k===v,"data-testid":`revoke-${v}`,className:"text-[11px] font-bold text-rose-600 hover:text-rose-700 flex items-center gap-1 disabled:opacity-40 cursor-pointer",children:[k===v?e.jsx(ye,{size:11,className:"animate-spin"}):e.jsx(Pe,{size:11}),N("撤销","Revoke")]})]},v))}):e.jsx("p",{className:"text-xs text-gray-400 italic","data-testid":"no-approved",children:N("尚未批准任何域名 —— 该插件无法发起出站请求。","No host approved yet — this plugin cannot make outbound requests.")})]}),y.length>0&&e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"text-[11px] font-bold text-amber-700 mb-1.5 flex items-center gap-1",children:[e.jsx(_e,{size:12}),N("清单申请中(未生效)","Requested by manifest (not active)")]}),e.jsx("ul",{className:"space-y-1",children:y.map(v=>e.jsxs("li",{className:"flex items-center justify-between gap-2 bg-amber-50/60 border border-amber-100 rounded-lg px-2.5 py-1.5",children:[e.jsx("code",{className:"text-xs text-amber-900 font-mono truncate",children:v}),e.jsxs("button",{type:"button",onClick:()=>void d(v),disabled:k===v,"data-testid":`approve-${v}`,className:"text-[11px] font-bold text-indigo-600 hover:text-indigo-700 flex items-center gap-1 disabled:opacity-40 cursor-pointer",children:[k===v?e.jsx(ye,{size:11,className:"animate-spin"}):e.jsx(ct,{size:11}),N("批准","Approve")]})]},v))})]}),c&&c.rejected.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"text-[11px] font-bold text-rose-700 mb-1.5 flex items-center gap-1",children:[e.jsx(ht,{size:12}),N("不可批准","Not approvable")]}),e.jsx("ul",{className:"space-y-1","data-testid":"rejected-hosts",children:c.rejected.map(v=>e.jsxs("li",{className:"text-xs text-gray-500 leading-relaxed",children:[e.jsx("code",{className:"font-mono text-rose-700 line-through",children:v.host}),v.reason?e.jsxs("span",{className:"ml-1.5 text-gray-400",children:["— ",v.reason]}):null]},`${v.host}-${v.reason??""}`))})]})]})}function Et({pluginId:R,pluginName:C,manifestStr:a,lang:N,onClose:c}){const[o,h]=K.useState(null),[n,f]=K.useState({}),[p,k]=K.useState(!0),[b,w]=K.useState(!1),[i,x]=K.useState(null),s=K.useCallback(async()=>{k(!0);try{const j=await fetch(`/api/plugins/${encodeURIComponent(R)}/config`);if(j.ok){const P=await j.json();if(P.success){h(P.result.schema),f(P.result.values);return}}}catch{}try{const P=JSON.parse(a).configuration?.properties??{};h(P);const E={};for(const[M,T]of Object.entries(P))E[M]=T.default;f(E)}catch{h({})}k(!1)},[R,a]);K.useEffect(()=>{s().finally(()=>k(!1))},[s]);const d=async()=>{w(!0),x(null);try{const P=await(await fetch(`/api/plugins/${encodeURIComponent(R)}/config`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})).json();P.success?x(N==="zh"?"✓ 已保存":"✓ Saved"):x(`✗ ${P.error}`)}catch(j){x(`✗ ${j.message}`)}w(!1)},l=(j,P)=>{f(E=>({...E,[j]:P})),x(null)},g=(j,P)=>N==="zh"?j:P,y=(j,P)=>{const E=n[j],M=P.description??"";switch(P.type){case"boolean":return e.jsxs("div",{className:"flex items-center justify-between py-2.5 border-b border-gray-100",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mt-0.5",children:M})]}),e.jsx("button",{type:"button",onClick:()=>l(j,!E),className:`relative w-10 h-5 rounded-full transition-colors ${E?"bg-indigo-600":"bg-gray-300"}`,children:e.jsx("span",{className:`absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-transform ${E?"translate-x-5":"translate-x-0.5"}`})})]},j);case"number":case"integer":return e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("input",{type:"number",step:P.type==="integer"?1:"any",min:P.minimum,max:P.maximum,value:E!=null?String(E):"",onChange:T=>{const G=T.target.value===""?void 0:Number(T.target.value);l(j,G)},className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none",placeholder:P.default!==void 0?String(P.default):""})]},j);default:return P.enum&&P.enum.length>0?e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("select",{value:String(E??P.default??""),onChange:T=>l(j,T.target.value),className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none bg-white",children:P.enum.map(T=>e.jsx("option",{value:String(T),children:String(T)},String(T)))})]},j):e.jsxs("div",{className:"py-2.5 border-b border-gray-100",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:j}),M&&e.jsx("p",{className:"text-xs text-gray-400 mb-1.5",children:M}),e.jsx("input",{type:"text",value:E!=null?String(E):"",onChange:T=>l(j,T.target.value),className:"w-full px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-200 focus:border-indigo-400 outline-none",placeholder:P.default!==void 0?String(P.default):""})]},j)}},v=o&&Object.keys(o).length>0;return e.jsx("div",{className:"fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4",onClick:c,children:e.jsxs("div",{className:"bg-white rounded-xl shadow-xl w-full max-w-md flex flex-col max-h-[85vh]",onClick:j=>j.stopPropagation(),children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ue,{size:18,className:"text-gray-500"}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-gray-800 text-sm",children:g("插件设置","Plugin Settings")}),e.jsx("p",{className:"text-xs text-gray-400",children:C})]})]}),e.jsx("button",{onClick:c,className:"text-gray-400 hover:text-gray-600 p-1",children:e.jsx(ze,{size:18})})]}),e.jsxs("div",{className:"p-4 flex-1 overflow-auto",children:[p?e.jsx("div",{className:"flex items-center justify-center py-12",children:e.jsx(ye,{size:24,className:"text-gray-400 animate-spin"})}):v?e.jsx("div",{className:"space-y-0.5",children:Object.entries(o).map(([j,P])=>y(j,P))}):e.jsxs("div",{className:"text-center py-8",children:[e.jsx(Ue,{size:32,className:"text-gray-300 mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-gray-400",children:g("此插件没有可配置项。","This plugin has no configurable settings.")}),e.jsx("p",{className:"text-xs text-gray-300 mt-1",children:g("在 manifest.configuration 中声明配置项即可在此处显示。","Declare settings in manifest.configuration to see them here.")})]}),e.jsx(It,{pluginId:R,lang:N})]}),v&&e.jsxs("div",{className:"p-4 border-t border-gray-100 flex items-center justify-between",children:[i&&e.jsx("span",{className:`text-xs ${i.startsWith("✓")?"text-green-600":"text-red-500"}`,children:i}),e.jsxs("div",{className:"flex gap-2 ml-auto",children:[e.jsx("button",{onClick:c,className:"px-4 py-2 text-xs font-medium text-gray-600 hover:bg-gray-50 rounded-lg transition-colors",children:g("取消","Cancel")}),e.jsxs("button",{onClick:d,disabled:b,className:"px-4 py-2 text-xs font-medium bg-indigo-600 text-white hover:bg-indigo-700 rounded-lg transition-colors flex items-center gap-1.5 disabled:opacity-50",children:[b?e.jsx(ye,{size:14,className:"animate-spin"}):e.jsx(ut,{size:14}),g("保存","Save")]})]})]})]})})}var Re={exports:{}};/*!
2
2
 
3
3
  JSZip v3.10.1 - A JavaScript class for generating and reading zip files
4
4
  <http://stuartk.com/jszip>
@@ -1 +1 @@
1
- import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as O}from"./index-2676X8YB.js";import{ar as w,c as C,o as k}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function E(z){const{isQuizGeneratorOpen:S,setIsQuizGeneratorOpen:x,lessons:g,quizGenMode:n,setQuizGenMode:u,quizGenSelectedLessonId:l,setQuizGenSelectedLessonId:Q,quizGenTopic:c,setQuizGenTopic:M,isGeneratingSuggestions:p,setIsGeneratingSuggestions:h,suggestedObjectives:b,setSuggestedObjectives:f,suggestedQuestions:r,setSuggestedQuestions:m,quizGenTimeLimit:j,setQuizGenTimeLimit:G,savingQuiz:y,setSavingQuiz:v,quizGeneratorClassId:o,fetchClassDashboard:N}=z;return e.jsx(e.Fragment,{children:S&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50 overflow-y-auto text-gray-850",children:e.jsxs(O.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-3xl flex flex-col overflow-hidden max-h-[90vh]",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(w,{className:"text-indigo-600 animate-pulse",size:20}),e.jsx("h2",{className:"font-bold text-gray-800 text-lg",children:"AI-Objective Quiz Generator"})]}),e.jsx("button",{onClick:()=>x(!1),className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors",children:"×"})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-6",children:[r.length===0&&e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"bg-indigo-50/80 p-4 rounded-xl border border-indigo-100 text-xs text-indigo-800 leading-relaxed font-sans",children:"Choose a lesson to scan. Our advanced AI model will run a deep semantic scan across the entire lesson curriculum content, discover your core learning objectives, and construct interactive multiple-choice questions aligning precisely with each of them."}),e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2",children:"Scan Core Selection Mode"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("button",{onClick:()=>u("scan_lesson"),className:`p-3 rounded-lg border text-left flex flex-col transition-all ${n==="scan_lesson"?"border-indigo-600 bg-indigo-50/40 ring-2 ring-indigo-100":"border-gray-200 hover:border-gray-300"}`,children:[e.jsx("span",{className:"font-semibold text-sm text-indigo-900",children:"Curriculum Lesson Scanning"}),e.jsx("span",{className:"text-xs text-gray-500 mt-1",children:"Examines real Markdown content inside virtual lesson modules."})]}),e.jsxs("button",{onClick:()=>u("topic"),className:`p-3 rounded-lg border text-left flex flex-col transition-all ${n==="topic"?"border-indigo-600 bg-indigo-50/40 ring-2 ring-indigo-100":"border-gray-200 hover:border-gray-300"}`,children:[e.jsx("span",{className:"font-semibold text-sm text-indigo-900",children:"Custom Keyword / Topic"}),e.jsx("span",{className:"text-xs text-gray-500 mt-1",children:"Provide a custom prompt keyword or objective manually."})]})]})]}),n==="scan_lesson"?e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2",children:"Select Lesson to Scan"}),g.length===0?e.jsx("div",{className:"text-gray-500 text-xs py-3 border rounded border-dashed text-center",children:"No lessons available. Please create a lesson first."}):e.jsxs("select",{value:l,onChange:s=>Q(s.target.value),className:"w-full p-2.5 bg-white border border-gray-200 rounded-lg text-sm text-gray-800 focus:border-indigo-500 focus:outline-none shadow-sm",children:[e.jsx("option",{value:"",children:"-- Choose a lesson --"}),g.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))]})]}):e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-505 uppercase tracking-wider mb-2",children:"Custom Topic Prompt"}),e.jsx("input",{type:"text",placeholder:"e.g. Introduction to React state, Cloud SQL setup...",value:c,onChange:s=>M(s.target.value),className:"w-full p-2.5 bg-white border border-gray-200 rounded-lg text-sm focus:border-indigo-500 focus:outline-none shadow-sm text-gray-800"})]}),e.jsx("div",{className:"pt-4 flex justify-end font-sans",children:e.jsx("button",{disabled:p||n==="scan_lesson"&&!l||n==="topic"&&!c.trim(),onClick:async()=>{h(!0);try{if(n==="scan_lesson"){const s=await fetch(`/api/classes/${o}/assignments/suggest`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({lessonId:l})});if(s.ok){const t=await s.json();f(t.learningObjectives||[]),m((t.questions||[]).map(i=>({...i,selected:!0})))}else alert("Error generating suggestions. Please make sure the selected lesson has content.")}else(await fetch(`/api/classes/${o}/assignments/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({topic:c})})).ok?(await N(o),x(!1)):alert("Error generating topic quiz.")}catch(s){console.error(s),alert(s.message)}finally{h(!1)}},className:"px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 text-white rounded-lg font-medium text-xs shadow transition flex items-center gap-2",children:p?e.jsxs(e.Fragment,{children:[e.jsx(C,{size:16,className:"animate-spin"}),e.jsx("span",{children:"AI Scanning Content..."})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{size:16}),e.jsx("span",{children:"Generate Key MCQ Quiz"})]})})})]}),r.length>0&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:"Identified Core Objectives"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:b.map((s,t)=>e.jsxs("span",{className:"px-2.5 py-1 bg-teal-50 text-teal-800 border border-teal-200 rounded-full text-xs font-semibold",children:["🎯 ",s]},t))})]}),e.jsxs("div",{className:"space-y-4 font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-500 uppercase tracking-wider font-semibold",children:"Suggested MCQ Questions"}),e.jsx("div",{className:"space-y-3",children:r.map((s,t)=>e.jsxs("div",{className:"p-4 rounded-xl border border-gray-150 bg-gray-50/50 hover:bg-gray-50 transition space-y-3 text-gray-800 text-gray-850",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-5 h-5 rounded-full bg-indigo-150 text-indigo-700 flex items-center justify-center text-xs font-bold shrink-0",children:t+1}),e.jsxs("span",{className:"text-xs font-semibold text-teal-700 bg-teal-50 px-2.5 py-0.5 rounded border border-teal-100",children:["objective: ",s.objective]})]}),e.jsx("input",{type:"checkbox",checked:!!s.selected,onChange:i=>{const a=[...r];a[t].selected=i.target.checked,m(a)},className:"w-4 h-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500"})]}),e.jsx("p",{className:"font-semibold text-gray-800 text-sm leading-relaxed",children:s.question}),e.jsx("div",{className:"grid grid-cols-2 gap-2 text-xs",children:s.options.map((i,a)=>{const d=i===s.correctAnswer;return e.jsxs("div",{className:`p-2 rounded border flex items-center justify-between ${d?"bg-green-50 border-green-200 text-green-955 font-semibold":"bg-white border-gray-100 text-gray-700"}`,children:[e.jsx("span",{children:i}),d&&e.jsx(k,{size:12,className:"text-green-600 shrink-0"})]},a)})})]},t))})]}),e.jsxs("div",{className:"pt-4 border-t border-gray-100 flex justify-between items-center font-sans",children:[e.jsx("button",{onClick:()=>{f([]),m([])},className:"px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg text-xs font-semibold transition",children:"Back / Scan New"}),e.jsxs("div",{className:"flex items-center gap-2 border border-indigo-150 bg-indigo-50/50 px-3 py-1.5 rounded-lg text-xs font-semibold text-indigo-900",children:[e.jsx("span",{children:"⏱️ Quiz Time Limit:"}),e.jsxs("select",{value:j,onChange:s=>G(Number(s.target.value)),className:"bg-transparent text-xs text-indigo-950 font-bold focus:outline-none cursor-pointer",children:[e.jsx("option",{className:"text-gray-800",value:0,children:"No Limit"}),e.jsx("option",{className:"text-gray-800",value:1,children:"1 Min"}),e.jsx("option",{className:"text-gray-800",value:2,children:"2 Mins"}),e.jsx("option",{className:"text-gray-800",value:5,children:"5 Mins"}),e.jsx("option",{className:"text-gray-800",value:10,children:"10 Mins"}),e.jsx("option",{className:"text-gray-800",value:15,children:"15 Mins"}),e.jsx("option",{className:"text-gray-800",value:20,children:"20 Mins"}),e.jsx("option",{className:"text-gray-800",value:30,children:"30 Mins"}),e.jsx("option",{className:"text-gray-800",value:45,children:"45 Mins"}),e.jsx("option",{className:"text-gray-800",value:60,children:"60 Mins"})]})]}),e.jsxs("button",{disabled:y||r.filter(s=>s.selected).length===0,onClick:async()=>{v(!0);try{const s=g.find(a=>a.id===l),t=s?s.title:c||"Custom Objective";(await fetch(`/api/classes/${o}/assignments/create-suggested-quiz`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:`MCQ Evaluation: ${t}`,description:"Automatic evaluation based on core learning objectives.",questions:r.filter(a=>a.selected).map(({selected:a,...d})=>d),learningObjectives:b,timeLimit:j})})).ok?(await N(o),x(!1)):alert("Failed to save suggested quiz.")}catch(s){console.error(s),alert(s.message)}finally{v(!1)}},className:"px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-medium text-xs shadow hover:shadow-md transition flex items-center gap-2",children:[y?e.jsx(C,{size:16,className:"animate-spin"}):e.jsx(k,{size:16}),e.jsx("span",{children:"Create Assessment Quiz"})]})]})]})]})]})})})}export{E as QuizGeneratorModal};
1
+ import{j as e}from"./vendor-react-Kv_JATwr.js";import{m as O}from"./index-BzXADCXZ.js";import{ar as w,c as C,o as k}from"./vendor-icons-CXrZ3R2V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function E(z){const{isQuizGeneratorOpen:S,setIsQuizGeneratorOpen:x,lessons:g,quizGenMode:n,setQuizGenMode:u,quizGenSelectedLessonId:l,setQuizGenSelectedLessonId:Q,quizGenTopic:c,setQuizGenTopic:M,isGeneratingSuggestions:p,setIsGeneratingSuggestions:h,suggestedObjectives:b,setSuggestedObjectives:f,suggestedQuestions:r,setSuggestedQuestions:m,quizGenTimeLimit:j,setQuizGenTimeLimit:G,savingQuiz:y,setSavingQuiz:v,quizGeneratorClassId:o,fetchClassDashboard:N}=z;return e.jsx(e.Fragment,{children:S&&e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50 overflow-y-auto text-gray-850",children:e.jsxs(O.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-3xl flex flex-col overflow-hidden max-h-[90vh]",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(w,{className:"text-indigo-600 animate-pulse",size:20}),e.jsx("h2",{className:"font-bold text-gray-800 text-lg",children:"AI-Objective Quiz Generator"})]}),e.jsx("button",{onClick:()=>x(!1),className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors",children:"×"})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-6",children:[r.length===0&&e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"bg-indigo-50/80 p-4 rounded-xl border border-indigo-100 text-xs text-indigo-800 leading-relaxed font-sans",children:"Choose a lesson to scan. Our advanced AI model will run a deep semantic scan across the entire lesson curriculum content, discover your core learning objectives, and construct interactive multiple-choice questions aligning precisely with each of them."}),e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2",children:"Scan Core Selection Mode"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("button",{onClick:()=>u("scan_lesson"),className:`p-3 rounded-lg border text-left flex flex-col transition-all ${n==="scan_lesson"?"border-indigo-600 bg-indigo-50/40 ring-2 ring-indigo-100":"border-gray-200 hover:border-gray-300"}`,children:[e.jsx("span",{className:"font-semibold text-sm text-indigo-900",children:"Curriculum Lesson Scanning"}),e.jsx("span",{className:"text-xs text-gray-500 mt-1",children:"Examines real Markdown content inside virtual lesson modules."})]}),e.jsxs("button",{onClick:()=>u("topic"),className:`p-3 rounded-lg border text-left flex flex-col transition-all ${n==="topic"?"border-indigo-600 bg-indigo-50/40 ring-2 ring-indigo-100":"border-gray-200 hover:border-gray-300"}`,children:[e.jsx("span",{className:"font-semibold text-sm text-indigo-900",children:"Custom Keyword / Topic"}),e.jsx("span",{className:"text-xs text-gray-500 mt-1",children:"Provide a custom prompt keyword or objective manually."})]})]})]}),n==="scan_lesson"?e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2",children:"Select Lesson to Scan"}),g.length===0?e.jsx("div",{className:"text-gray-500 text-xs py-3 border rounded border-dashed text-center",children:"No lessons available. Please create a lesson first."}):e.jsxs("select",{value:l,onChange:s=>Q(s.target.value),className:"w-full p-2.5 bg-white border border-gray-200 rounded-lg text-sm text-gray-800 focus:border-indigo-500 focus:outline-none shadow-sm",children:[e.jsx("option",{value:"",children:"-- Choose a lesson --"}),g.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))]})]}):e.jsxs("div",{className:"font-sans",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-505 uppercase tracking-wider mb-2",children:"Custom Topic Prompt"}),e.jsx("input",{type:"text",placeholder:"e.g. Introduction to React state, Cloud SQL setup...",value:c,onChange:s=>M(s.target.value),className:"w-full p-2.5 bg-white border border-gray-200 rounded-lg text-sm focus:border-indigo-500 focus:outline-none shadow-sm text-gray-800"})]}),e.jsx("div",{className:"pt-4 flex justify-end font-sans",children:e.jsx("button",{disabled:p||n==="scan_lesson"&&!l||n==="topic"&&!c.trim(),onClick:async()=>{h(!0);try{if(n==="scan_lesson"){const s=await fetch(`/api/classes/${o}/assignments/suggest`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({lessonId:l})});if(s.ok){const t=await s.json();f(t.learningObjectives||[]),m((t.questions||[]).map(i=>({...i,selected:!0})))}else alert("Error generating suggestions. Please make sure the selected lesson has content.")}else(await fetch(`/api/classes/${o}/assignments/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({topic:c})})).ok?(await N(o),x(!1)):alert("Error generating topic quiz.")}catch(s){console.error(s),alert(s.message)}finally{h(!1)}},className:"px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 disabled:opacity-50 text-white rounded-lg font-medium text-xs shadow transition flex items-center gap-2",children:p?e.jsxs(e.Fragment,{children:[e.jsx(C,{size:16,className:"animate-spin"}),e.jsx("span",{children:"AI Scanning Content..."})]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{size:16}),e.jsx("span",{children:"Generate Key MCQ Quiz"})]})})})]}),r.length>0&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-500 uppercase tracking-wider mb-2",children:"Identified Core Objectives"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:b.map((s,t)=>e.jsxs("span",{className:"px-2.5 py-1 bg-teal-50 text-teal-800 border border-teal-200 rounded-full text-xs font-semibold",children:["🎯 ",s]},t))})]}),e.jsxs("div",{className:"space-y-4 font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-500 uppercase tracking-wider font-semibold",children:"Suggested MCQ Questions"}),e.jsx("div",{className:"space-y-3",children:r.map((s,t)=>e.jsxs("div",{className:"p-4 rounded-xl border border-gray-150 bg-gray-50/50 hover:bg-gray-50 transition space-y-3 text-gray-800 text-gray-850",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-5 h-5 rounded-full bg-indigo-150 text-indigo-700 flex items-center justify-center text-xs font-bold shrink-0",children:t+1}),e.jsxs("span",{className:"text-xs font-semibold text-teal-700 bg-teal-50 px-2.5 py-0.5 rounded border border-teal-100",children:["objective: ",s.objective]})]}),e.jsx("input",{type:"checkbox",checked:!!s.selected,onChange:i=>{const a=[...r];a[t].selected=i.target.checked,m(a)},className:"w-4 h-4 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500"})]}),e.jsx("p",{className:"font-semibold text-gray-800 text-sm leading-relaxed",children:s.question}),e.jsx("div",{className:"grid grid-cols-2 gap-2 text-xs",children:s.options.map((i,a)=>{const d=i===s.correctAnswer;return e.jsxs("div",{className:`p-2 rounded border flex items-center justify-between ${d?"bg-green-50 border-green-200 text-green-955 font-semibold":"bg-white border-gray-100 text-gray-700"}`,children:[e.jsx("span",{children:i}),d&&e.jsx(k,{size:12,className:"text-green-600 shrink-0"})]},a)})})]},t))})]}),e.jsxs("div",{className:"pt-4 border-t border-gray-100 flex justify-between items-center font-sans",children:[e.jsx("button",{onClick:()=>{f([]),m([])},className:"px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg text-xs font-semibold transition",children:"Back / Scan New"}),e.jsxs("div",{className:"flex items-center gap-2 border border-indigo-150 bg-indigo-50/50 px-3 py-1.5 rounded-lg text-xs font-semibold text-indigo-900",children:[e.jsx("span",{children:"⏱️ Quiz Time Limit:"}),e.jsxs("select",{value:j,onChange:s=>G(Number(s.target.value)),className:"bg-transparent text-xs text-indigo-950 font-bold focus:outline-none cursor-pointer",children:[e.jsx("option",{className:"text-gray-800",value:0,children:"No Limit"}),e.jsx("option",{className:"text-gray-800",value:1,children:"1 Min"}),e.jsx("option",{className:"text-gray-800",value:2,children:"2 Mins"}),e.jsx("option",{className:"text-gray-800",value:5,children:"5 Mins"}),e.jsx("option",{className:"text-gray-800",value:10,children:"10 Mins"}),e.jsx("option",{className:"text-gray-800",value:15,children:"15 Mins"}),e.jsx("option",{className:"text-gray-800",value:20,children:"20 Mins"}),e.jsx("option",{className:"text-gray-800",value:30,children:"30 Mins"}),e.jsx("option",{className:"text-gray-800",value:45,children:"45 Mins"}),e.jsx("option",{className:"text-gray-800",value:60,children:"60 Mins"})]})]}),e.jsxs("button",{disabled:y||r.filter(s=>s.selected).length===0,onClick:async()=>{v(!0);try{const s=g.find(a=>a.id===l),t=s?s.title:c||"Custom Objective";(await fetch(`/api/classes/${o}/assignments/create-suggested-quiz`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:`MCQ Evaluation: ${t}`,description:"Automatic evaluation based on core learning objectives.",questions:r.filter(a=>a.selected).map(({selected:a,...d})=>d),learningObjectives:b,timeLimit:j})})).ok?(await N(o),x(!1)):alert("Failed to save suggested quiz.")}catch(s){console.error(s),alert(s.message)}finally{v(!1)}},className:"px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-medium text-xs shadow hover:shadow-md transition flex items-center gap-2",children:[y?e.jsx(C,{size:16,className:"animate-spin"}):e.jsx(k,{size:16}),e.jsx("span",{children:"Create Assessment Quiz"})]})]})]})]})]})})})}export{E as QuizGeneratorModal};
@@ -1 +1 @@
1
- import{j as e,r as N}from"./vendor-react-Kv_JATwr.js";import{E as z,h as T,M as q}from"./index-2676X8YB.js";import{f as _,ar as C,o as A,h as S,T as E,X as R}from"./vendor-icons-CXrZ3R2V.js";import{L as O}from"./LazyWhiteboard-CCN3pYcW.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function I(x){const{setStudentViewStatus:s,setSelectedAssignment:i,selectedAssignment:o}=x;return e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsxs("button",{onClick:()=>{s("dashboard"),i(null)},className:"flex items-center gap-2 text-indigo-600 hover:text-indigo-800 transition-colors font-medium text-sm",children:[e.jsx(_,{className:"rotate-180",size:16})," Back to Dashboard"]}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("h2",{className:"text-xl font-bold text-gray-800",children:["Assignment: ",o.title]}),e.jsx(z,{slot:"student.assignment.toolbar.action",slotProps:{assignment:o}})]})]})}function Q(x){const{selectedAssignment:s,quizStudentAnswers:i,setQuizStudentAnswers:o,submitQuizAssignment:d}=x,m=T.match(s?.content);if(m){const n=m.config,r={assignment:s,answers:i,setAnswers:t=>o?.(t),lang:"zh"};return e.jsxs("div",{className:"w-1/3 border-r border-gray-100 pr-4 overflow-y-auto hidden md:block",children:[e.jsx("div",{className:"flex justify-between items-center mb-4",children:e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-indigo-500 bg-indigo-50 border border-indigo-100 p-2.5 rounded-lg flex items-center gap-1.5 w-full",children:n.label})}),n.render(r),!s.submission_status&&e.jsx("div",{className:"mt-6 border-t border-gray-100 pt-4",children:e.jsx("button",{onClick:async()=>{if(n.validate){const t=n.validate(r);if(t){window.alert(t);return}}n.buildSubmission&&o?.(n.buildSubmission(r)),await d(!1)},className:"w-full py-2 bg-indigo-600 text-white rounded-lg shadow font-medium hover:bg-indigo-700 transition",children:"Submit"})})]})}return e.jsxs("div",{className:"w-1/3 border-r border-gray-100 pr-4 overflow-y-auto hidden md:block",children:[e.jsx("div",{className:"flex justify-between items-center mb-4",children:e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-400",children:s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?"Assessment":"Question"})}),s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"text-xs font-semibold uppercase tracking-wider text-teal-700 bg-teal-50 border border-teal-100 p-2.5 rounded-lg flex items-center gap-1.5 font-sans",children:[e.jsx(C,{size:12,className:"text-teal-600 animate-pulse"})," AI Interactive Evaluation"]}),e.jsx("p",{className:"text-xs text-gray-500 leading-relaxed font-sans",children:"This assessment was automatically mapped to the core learning objectives of your lesson by our tutoring assistant compiler."}),(()=>{try{const n=JSON.parse(s.content);return e.jsxs("div",{className:"space-y-2 font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider",children:"Lesson Learning Objectives:"}),e.jsx("ul",{className:"space-y-1.5",children:(n.learningObjectives||[]).map((r,t)=>e.jsxs("li",{className:"text-xs text-gray-755 flex items-start gap-1.5 font-medium leading-normal",children:[e.jsx("span",{className:"text-indigo-500 shrink-0 select-none",children:"🎯"}),e.jsx("span",{children:r})]},t))})]})}catch{return null}})()]}):e.jsx("div",{className:"prose prose-sm prose-indigo max-w-none mb-6",children:e.jsx(q,{children:s.content||""})}),!s.submission_status&&e.jsxs("div",{className:"mt-8 border-t border-gray-100 pt-6",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-400 mb-2",children:"Ready to submit?"}),e.jsx("p",{className:"text-xs text-gray-500 mb-4",children:s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?"Please answer all the interactive questions on the evaluation sheet, then click Submit.":"You can use the whiteboard to draw or answer, then click submit when finished."}),e.jsx("button",{onClick:async()=>{const n=s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"');if(n&&JSON.stringify(i),n)try{const r=JSON.parse(s.content),t=Object.keys(i).length;if(t<r.questions.length&&!window.confirm(`You have only answered ${t}/${r.questions.length} questions. Are you sure you want to submit your answers?`))return}catch{}await d(!1)},className:"w-full py-2 bg-indigo-600 text-white rounded-lg shadow font-medium hover:bg-indigo-700 transition",children:"Submit"})]}),s.submission_status==="graded"&&s.feedback&&e.jsxs("div",{className:"mt-6 bg-green-50 p-4 rounded-xl border border-green-100",children:[e.jsxs("div",{className:"font-semibold text-green-800 text-sm mb-1 flex items-center gap-1",children:[e.jsx(A,{size:16})," Grade: ",s.score,"%"]}),e.jsx("div",{className:"text-xs text-green-700 whitespace-pre-wrap leading-relaxed font-sans",children:s.feedback})]})]})}function W({assignmentId:x,timeLimitMinutes:s,onTimeUp:i,isSubmitted:o}){const[d,m]=N.useState(null);if(N.useEffect(()=>{if(o||!s||s<=0){m(null);return}const a=`quiz_timer_start_${x}`;let u=sessionStorage.getItem(a),g=u?parseInt(u,10):null;g||(g=Date.now(),sessionStorage.setItem(a,g.toString()));const l=s*60,c=()=>{const j=Math.floor((Date.now()-g)/1e3),h=l-j;h<=0?(m(0),i()):m(h)};c();const b=setInterval(c,1e3);return()=>clearInterval(b)},[x,s,o,i]),!s||s<=0)return null;if(o)return e.jsxs("div",{className:"flex items-center gap-2 font-sans text-xs bg-gray-100 text-gray-600 px-3 py-1.5 rounded-lg border border-gray-200",children:[e.jsx(S,{size:14}),e.jsxs("span",{children:["Time Limit: ",s," mins (Completed)"]})]});if(d===null)return null;const n=Math.floor(d/60),r=d%60,t=d<60;return e.jsxs("div",{className:`flex items-center gap-3 font-sans px-4 py-2.5 rounded-xl border transition-all ${t?"bg-red-50 text-red-700 border-red-200 animate-pulse font-bold":d<180?"bg-amber-50 text-amber-700 border-amber-200 font-semibold":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:[e.jsx(S,{size:16,className:t?"text-red-600 animate-pulse":"text-indigo-600"}),e.jsxs("div",{className:"flex-1 flex justify-between items-center text-xs gap-4",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:"Time Remaining:"}),e.jsxs("span",{className:"font-mono ml-1 text-sm bg-black/5 text-slate-800 px-1.5 py-0.5 rounded font-bold",children:[n.toString().padStart(2,"0"),":",r.toString().padStart(2,"0")]})]}),t&&e.jsxs("span",{className:"flex items-center gap-1 text-xs uppercase tracking-wider text-red-600 font-bold animate-pulse",children:[e.jsx(E,{size:12})," Time is almost up!"]})]})]})}function P(x){const{selectedAssignment:s,subAssignmentTab:i,setSubAssignmentTab:o,quizStudentAnswers:d,setQuizStudentAnswers:m,submitQuizAssignment:n,elements:r,activeRole:t,activeStudentId:a,fetchElements:u}=x;return e.jsx("div",{className:"flex-1 relative flex flex-col min-h-0",children:(()=>{const g=s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"');return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wider text-gray-500 pointer-events-none",children:g&&i==="quiz"?"Evaluation Sheet":"Live Canvas"}),g&&e.jsxs("div",{className:"flex bg-gray-100 p-0.5 rounded-lg border border-gray-200 text-xs",children:[e.jsx("button",{onClick:()=>o("quiz"),className:`px-2.5 py-0.5 rounded text-xs font-bold transition-all ${i==="quiz"?"bg-white text-indigo-700 shadow-sm":"text-gray-500 hover:text-gray-900"}`,children:"Interactive Test"}),e.jsx("button",{onClick:()=>o("whiteboard"),className:`px-2.5 py-0.5 rounded text-xs font-bold transition-all ${i==="whiteboard"?"bg-white text-indigo-700 shadow-sm":"text-gray-500 hover:text-gray-900"}`,children:"Sketch Whiteboard"})]})]}),s.submission_status&&e.jsx("div",{className:"text-xs uppercase font-bold text-gray-400 bg-gray-100 px-2 py-0.5 rounded",children:"Read Only"})]}),g&&i==="quiz"?e.jsx("div",{className:"flex-1 bg-gray-50/50 rounded-xl border border-gray-200 p-6 overflow-y-auto space-y-6",children:(()=>{try{const l=JSON.parse(s.content);return e.jsxs(e.Fragment,{children:[l.timeLimit>0&&e.jsx(W,{assignmentId:s.id,timeLimitMinutes:l.timeLimit,onTimeUp:()=>n(!0),isSubmitted:!!s.submission_status}),l.questions.map((c,b)=>{const j=d[b],h=!!s.submission_status,v=d[b]===c.correctAnswer;return e.jsxs("div",{className:"bg-white p-5 rounded-xl border border-gray-100 shadow-sm space-y-3 font-sans",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-6 h-6 rounded-full bg-indigo-50 text-indigo-700 flex items-center justify-center text-xs font-bold ring-1 ring-indigo-100",children:b+1}),e.jsxs("span",{className:"text-xs font-semibold text-teal-700 bg-teal-50 px-2.5 py-0.5 rounded-full border border-teal-100",children:["evaluates: ",c.objective]})]}),h&&e.jsx("span",{className:`text-xs font-bold px-2.5 py-0.5 rounded-full ${v?"bg-green-100 text-green-800":"bg-red-100 text-red-800"}`,children:v?"Correct ✓":`Incorrect (Correct Option: ${c.correctAnswer})`})]}),e.jsx("div",{className:"font-semibold text-gray-800 text-sm",children:c.question}),e.jsx("div",{className:"grid grid-cols-2 gap-3 text-xs pt-1",children:c.options.map((f,$)=>{const y=j===f,w=f===c.correctAnswer;let p="border-gray-200 hover:border-gray-300 bg-white text-gray-700 hover:bg-gray-50/50 cursor-pointer";return h?y?p=w?"border-green-600 bg-green-50 text-green-900 ring-2 ring-green-100":"border-red-600 bg-red-50 text-red-900 ring-2 ring-red-100":w?p="border-green-400 bg-green-50/20 text-green-900":p="border-gray-200 opacity-60 text-gray-400":y&&(p="border-indigo-600 bg-indigo-50/30 text-indigo-900 ring-2 ring-indigo-100 font-medium cursor-pointer"),e.jsxs("div",{onClick:()=>{h||m(k=>({...k,[b]:f}))},className:`p-3 rounded-xl border transition-all duration-150 flex items-center justify-between ${p}`,children:[e.jsx("span",{children:f}),y&&(h?w?e.jsx(A,{size:14,className:"text-green-600 shrink-0"}):e.jsx(R,{size:14,className:"text-red-600 shrink-0"}):e.jsx("div",{className:"w-2 h-2 rounded-full bg-indigo-600 shadow-sm shrink-0"}))]},$)})})]},b)})]})}catch{return e.jsx("div",{className:"text-xs text-red-500 font-sans",children:"Error parsing quiz structure."})}})()}):e.jsx("div",{className:`flex-1 min-h-0 flex flex-col ${s.submission_status?"opacity-90 pointer-events-none filter grayscale-[0.2]":""}`,children:e.jsx(O,{lessonId:`assignment-${s.id}-student-${a}`,elements:r,userRole:t,enableAutoAI:t==="student"&&!s.submission_status,onElementAdd:async(l,c)=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:l,data:c})}),u(`assignment-${s.id}-student-${a}`)},onElementUpdate:async(l,c)=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard/${l}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:c})}),u(`assignment-${s.id}-student-${a}`)},onElementDelete:async l=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard/${l}`,{method:"DELETE"}),u(`assignment-${s.id}-student-${a}`)},onClearBoard:async()=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard`,{method:"DELETE"}),u(`assignment-${s.id}-student-${a}`)},onRefresh:()=>u(`assignment-${s.id}-student-${a}`)})})]})})()})}function H(x){const{selectedAssignment:s,setStudentViewStatus:i,setSelectedAssignment:o,quizStudentAnswers:d,submitQuizAssignment:m,subAssignmentTab:n,setSubAssignmentTab:r,setQuizStudentAnswers:t,elements:a,activeRole:u,activeStudentId:g,fetchElements:l}=x;return e.jsxs("div",{className:"flex flex-col h-full space-y-4",children:[e.jsx(I,{setStudentViewStatus:i,setSelectedAssignment:o,selectedAssignment:s}),e.jsxs("div",{className:"flex-1 flex gap-6 min-h-0 bg-white border border-gray-200 rounded-xl p-4 shadow-sm",children:[e.jsx(Q,{selectedAssignment:s,quizStudentAnswers:d,setQuizStudentAnswers:t,submitQuizAssignment:m}),e.jsx(P,{selectedAssignment:s,subAssignmentTab:n,setSubAssignmentTab:r,quizStudentAnswers:d,setQuizStudentAnswers:t,submitQuizAssignment:m,elements:a,activeRole:u,activeStudentId:g,fetchElements:l})]})]})}export{H as StudentAssignmentView};
1
+ import{j as e,r as N}from"./vendor-react-Kv_JATwr.js";import{E as z,h as T,M as q}from"./index-BzXADCXZ.js";import{f as _,ar as C,o as A,h as S,T as E,X as R}from"./vendor-icons-CXrZ3R2V.js";import{L as O}from"./LazyWhiteboard-CcoBIx6V.js";import"./vendor-utils-aM7aYvPP.js";import"./vendor-pdf-C1Vh2Aqq.js";import"./vendor-motion-BFAPOs-b.js";import"./vendor-charts-SrpBsvM3.js";function I(x){const{setStudentViewStatus:s,setSelectedAssignment:i,selectedAssignment:o}=x;return e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsxs("button",{onClick:()=>{s("dashboard"),i(null)},className:"flex items-center gap-2 text-indigo-600 hover:text-indigo-800 transition-colors font-medium text-sm",children:[e.jsx(_,{className:"rotate-180",size:16})," Back to Dashboard"]}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("h2",{className:"text-xl font-bold text-gray-800",children:["Assignment: ",o.title]}),e.jsx(z,{slot:"student.assignment.toolbar.action",slotProps:{assignment:o}})]})]})}function Q(x){const{selectedAssignment:s,quizStudentAnswers:i,setQuizStudentAnswers:o,submitQuizAssignment:d}=x,m=T.match(s?.content);if(m){const n=m.config,r={assignment:s,answers:i,setAnswers:t=>o?.(t),lang:"zh"};return e.jsxs("div",{className:"w-1/3 border-r border-gray-100 pr-4 overflow-y-auto hidden md:block",children:[e.jsx("div",{className:"flex justify-between items-center mb-4",children:e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-indigo-500 bg-indigo-50 border border-indigo-100 p-2.5 rounded-lg flex items-center gap-1.5 w-full",children:n.label})}),n.render(r),!s.submission_status&&e.jsx("div",{className:"mt-6 border-t border-gray-100 pt-4",children:e.jsx("button",{onClick:async()=>{if(n.validate){const t=n.validate(r);if(t){window.alert(t);return}}n.buildSubmission&&o?.(n.buildSubmission(r)),await d(!1)},className:"w-full py-2 bg-indigo-600 text-white rounded-lg shadow font-medium hover:bg-indigo-700 transition",children:"Submit"})})]})}return e.jsxs("div",{className:"w-1/3 border-r border-gray-100 pr-4 overflow-y-auto hidden md:block",children:[e.jsx("div",{className:"flex justify-between items-center mb-4",children:e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-400",children:s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?"Assessment":"Question"})}),s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"text-xs font-semibold uppercase tracking-wider text-teal-700 bg-teal-50 border border-teal-100 p-2.5 rounded-lg flex items-center gap-1.5 font-sans",children:[e.jsx(C,{size:12,className:"text-teal-600 animate-pulse"})," AI Interactive Evaluation"]}),e.jsx("p",{className:"text-xs text-gray-500 leading-relaxed font-sans",children:"This assessment was automatically mapped to the core learning objectives of your lesson by our tutoring assistant compiler."}),(()=>{try{const n=JSON.parse(s.content);return e.jsxs("div",{className:"space-y-2 font-sans",children:[e.jsx("div",{className:"text-xs font-bold text-gray-400 uppercase tracking-wider",children:"Lesson Learning Objectives:"}),e.jsx("ul",{className:"space-y-1.5",children:(n.learningObjectives||[]).map((r,t)=>e.jsxs("li",{className:"text-xs text-gray-755 flex items-start gap-1.5 font-medium leading-normal",children:[e.jsx("span",{className:"text-indigo-500 shrink-0 select-none",children:"🎯"}),e.jsx("span",{children:r})]},t))})]})}catch{return null}})()]}):e.jsx("div",{className:"prose prose-sm prose-indigo max-w-none mb-6",children:e.jsx(q,{children:s.content||""})}),!s.submission_status&&e.jsxs("div",{className:"mt-8 border-t border-gray-100 pt-6",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-400 mb-2",children:"Ready to submit?"}),e.jsx("p",{className:"text-xs text-gray-500 mb-4",children:s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"')?"Please answer all the interactive questions on the evaluation sheet, then click Submit.":"You can use the whiteboard to draw or answer, then click submit when finished."}),e.jsx("button",{onClick:async()=>{const n=s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"');if(n&&JSON.stringify(i),n)try{const r=JSON.parse(s.content),t=Object.keys(i).length;if(t<r.questions.length&&!window.confirm(`You have only answered ${t}/${r.questions.length} questions. Are you sure you want to submit your answers?`))return}catch{}await d(!1)},className:"w-full py-2 bg-indigo-600 text-white rounded-lg shadow font-medium hover:bg-indigo-700 transition",children:"Submit"})]}),s.submission_status==="graded"&&s.feedback&&e.jsxs("div",{className:"mt-6 bg-green-50 p-4 rounded-xl border border-green-100",children:[e.jsxs("div",{className:"font-semibold text-green-800 text-sm mb-1 flex items-center gap-1",children:[e.jsx(A,{size:16})," Grade: ",s.score,"%"]}),e.jsx("div",{className:"text-xs text-green-700 whitespace-pre-wrap leading-relaxed font-sans",children:s.feedback})]})]})}function W({assignmentId:x,timeLimitMinutes:s,onTimeUp:i,isSubmitted:o}){const[d,m]=N.useState(null);if(N.useEffect(()=>{if(o||!s||s<=0){m(null);return}const a=`quiz_timer_start_${x}`;let u=sessionStorage.getItem(a),g=u?parseInt(u,10):null;g||(g=Date.now(),sessionStorage.setItem(a,g.toString()));const l=s*60,c=()=>{const j=Math.floor((Date.now()-g)/1e3),h=l-j;h<=0?(m(0),i()):m(h)};c();const b=setInterval(c,1e3);return()=>clearInterval(b)},[x,s,o,i]),!s||s<=0)return null;if(o)return e.jsxs("div",{className:"flex items-center gap-2 font-sans text-xs bg-gray-100 text-gray-600 px-3 py-1.5 rounded-lg border border-gray-200",children:[e.jsx(S,{size:14}),e.jsxs("span",{children:["Time Limit: ",s," mins (Completed)"]})]});if(d===null)return null;const n=Math.floor(d/60),r=d%60,t=d<60;return e.jsxs("div",{className:`flex items-center gap-3 font-sans px-4 py-2.5 rounded-xl border transition-all ${t?"bg-red-50 text-red-700 border-red-200 animate-pulse font-bold":d<180?"bg-amber-50 text-amber-700 border-amber-200 font-semibold":"bg-indigo-50 text-indigo-700 border-indigo-100"}`,children:[e.jsx(S,{size:16,className:t?"text-red-600 animate-pulse":"text-indigo-600"}),e.jsxs("div",{className:"flex-1 flex justify-between items-center text-xs gap-4",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-medium",children:"Time Remaining:"}),e.jsxs("span",{className:"font-mono ml-1 text-sm bg-black/5 text-slate-800 px-1.5 py-0.5 rounded font-bold",children:[n.toString().padStart(2,"0"),":",r.toString().padStart(2,"0")]})]}),t&&e.jsxs("span",{className:"flex items-center gap-1 text-xs uppercase tracking-wider text-red-600 font-bold animate-pulse",children:[e.jsx(E,{size:12})," Time is almost up!"]})]})]})}function P(x){const{selectedAssignment:s,subAssignmentTab:i,setSubAssignmentTab:o,quizStudentAnswers:d,setQuizStudentAnswers:m,submitQuizAssignment:n,elements:r,activeRole:t,activeStudentId:a,fetchElements:u}=x;return e.jsx("div",{className:"flex-1 relative flex flex-col min-h-0",children:(()=>{const g=s?.content&&s.content.startsWith('{"quizType":"mcq_learning_objectives"');return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-xs font-semibold uppercase tracking-wider text-gray-500 pointer-events-none",children:g&&i==="quiz"?"Evaluation Sheet":"Live Canvas"}),g&&e.jsxs("div",{className:"flex bg-gray-100 p-0.5 rounded-lg border border-gray-200 text-xs",children:[e.jsx("button",{onClick:()=>o("quiz"),className:`px-2.5 py-0.5 rounded text-xs font-bold transition-all ${i==="quiz"?"bg-white text-indigo-700 shadow-sm":"text-gray-500 hover:text-gray-900"}`,children:"Interactive Test"}),e.jsx("button",{onClick:()=>o("whiteboard"),className:`px-2.5 py-0.5 rounded text-xs font-bold transition-all ${i==="whiteboard"?"bg-white text-indigo-700 shadow-sm":"text-gray-500 hover:text-gray-900"}`,children:"Sketch Whiteboard"})]})]}),s.submission_status&&e.jsx("div",{className:"text-xs uppercase font-bold text-gray-400 bg-gray-100 px-2 py-0.5 rounded",children:"Read Only"})]}),g&&i==="quiz"?e.jsx("div",{className:"flex-1 bg-gray-50/50 rounded-xl border border-gray-200 p-6 overflow-y-auto space-y-6",children:(()=>{try{const l=JSON.parse(s.content);return e.jsxs(e.Fragment,{children:[l.timeLimit>0&&e.jsx(W,{assignmentId:s.id,timeLimitMinutes:l.timeLimit,onTimeUp:()=>n(!0),isSubmitted:!!s.submission_status}),l.questions.map((c,b)=>{const j=d[b],h=!!s.submission_status,v=d[b]===c.correctAnswer;return e.jsxs("div",{className:"bg-white p-5 rounded-xl border border-gray-100 shadow-sm space-y-3 font-sans",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-6 h-6 rounded-full bg-indigo-50 text-indigo-700 flex items-center justify-center text-xs font-bold ring-1 ring-indigo-100",children:b+1}),e.jsxs("span",{className:"text-xs font-semibold text-teal-700 bg-teal-50 px-2.5 py-0.5 rounded-full border border-teal-100",children:["evaluates: ",c.objective]})]}),h&&e.jsx("span",{className:`text-xs font-bold px-2.5 py-0.5 rounded-full ${v?"bg-green-100 text-green-800":"bg-red-100 text-red-800"}`,children:v?"Correct ✓":`Incorrect (Correct Option: ${c.correctAnswer})`})]}),e.jsx("div",{className:"font-semibold text-gray-800 text-sm",children:c.question}),e.jsx("div",{className:"grid grid-cols-2 gap-3 text-xs pt-1",children:c.options.map((f,$)=>{const y=j===f,w=f===c.correctAnswer;let p="border-gray-200 hover:border-gray-300 bg-white text-gray-700 hover:bg-gray-50/50 cursor-pointer";return h?y?p=w?"border-green-600 bg-green-50 text-green-900 ring-2 ring-green-100":"border-red-600 bg-red-50 text-red-900 ring-2 ring-red-100":w?p="border-green-400 bg-green-50/20 text-green-900":p="border-gray-200 opacity-60 text-gray-400":y&&(p="border-indigo-600 bg-indigo-50/30 text-indigo-900 ring-2 ring-indigo-100 font-medium cursor-pointer"),e.jsxs("div",{onClick:()=>{h||m(k=>({...k,[b]:f}))},className:`p-3 rounded-xl border transition-all duration-150 flex items-center justify-between ${p}`,children:[e.jsx("span",{children:f}),y&&(h?w?e.jsx(A,{size:14,className:"text-green-600 shrink-0"}):e.jsx(R,{size:14,className:"text-red-600 shrink-0"}):e.jsx("div",{className:"w-2 h-2 rounded-full bg-indigo-600 shadow-sm shrink-0"}))]},$)})})]},b)})]})}catch{return e.jsx("div",{className:"text-xs text-red-500 font-sans",children:"Error parsing quiz structure."})}})()}):e.jsx("div",{className:`flex-1 min-h-0 flex flex-col ${s.submission_status?"opacity-90 pointer-events-none filter grayscale-[0.2]":""}`,children:e.jsx(O,{lessonId:`assignment-${s.id}-student-${a}`,elements:r,userRole:t,enableAutoAI:t==="student"&&!s.submission_status,onElementAdd:async(l,c)=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:l,data:c})}),u(`assignment-${s.id}-student-${a}`)},onElementUpdate:async(l,c)=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard/${l}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:c})}),u(`assignment-${s.id}-student-${a}`)},onElementDelete:async l=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard/${l}`,{method:"DELETE"}),u(`assignment-${s.id}-student-${a}`)},onClearBoard:async()=>{await fetch(`/api/lessons/assignment-${s.id}-student-${a}/whiteboard`,{method:"DELETE"}),u(`assignment-${s.id}-student-${a}`)},onRefresh:()=>u(`assignment-${s.id}-student-${a}`)})})]})})()})}function H(x){const{selectedAssignment:s,setStudentViewStatus:i,setSelectedAssignment:o,quizStudentAnswers:d,submitQuizAssignment:m,subAssignmentTab:n,setSubAssignmentTab:r,setQuizStudentAnswers:t,elements:a,activeRole:u,activeStudentId:g,fetchElements:l}=x;return e.jsxs("div",{className:"flex flex-col h-full space-y-4",children:[e.jsx(I,{setStudentViewStatus:i,setSelectedAssignment:o,selectedAssignment:s}),e.jsxs("div",{className:"flex-1 flex gap-6 min-h-0 bg-white border border-gray-200 rounded-xl p-4 shadow-sm",children:[e.jsx(Q,{selectedAssignment:s,quizStudentAnswers:d,setQuizStudentAnswers:t,submitQuizAssignment:m}),e.jsx(P,{selectedAssignment:s,subAssignmentTab:n,setSubAssignmentTab:r,quizStudentAnswers:d,setQuizStudentAnswers:t,submitQuizAssignment:m,elements:a,activeRole:u,activeStudentId:g,fetchElements:l})]})]})}export{H as StudentAssignmentView};