openlearn-next 0.2.8 → 0.3.1
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.
- package/dist/assets/AdminDirectoryView-0XV86Ues.js +1 -0
- package/dist/assets/BatchPickerModal-of9a5EJz.js +1 -0
- package/dist/assets/ClassesView-CefnsjZ8.js +19 -0
- package/dist/assets/CloudDriveModal-DgVQLbO5.js +1 -0
- package/dist/assets/ComputerLabView-BId0ZarM.js +1 -0
- package/dist/assets/CourseManagement-Cxhc784Q.js +1 -0
- package/dist/assets/CourseWizardModal-Da6PKhnU.js +3 -0
- package/dist/assets/CoursewareHubPanel-LpUgjqbH.js +1 -0
- package/dist/assets/{Dashboard-DQ91dQio.js → Dashboard-LWbFbup4.js} +2 -2
- package/dist/assets/ExportWeightModal-Cyg1zMEd.js +1 -0
- package/dist/assets/HelpTour-CHPIK2ae.js +1 -0
- package/dist/assets/{HelpView-DLAKVpwf.js → HelpView-CvpgBpdr.js} +5 -5
- package/dist/assets/ImportLessonsModal-CfWIrW1K.js +1 -0
- package/dist/assets/ImportModal-BTfia0Ah.js +1 -0
- package/dist/assets/InteractiveCoursewareViewer-CS5BqfJZ.js +1 -0
- package/dist/assets/InteractiveWhiteboard-U23CsqGo.js +78 -0
- package/dist/assets/{LazyCourseware-g7b8EXR_.js → LazyCourseware-DXL9IxZO.js} +1 -1
- package/dist/assets/{LazyWhiteboard-B6rDWBFb.js → LazyWhiteboard-CtkzSFtN.js} +2 -2
- package/dist/assets/LessonEditorView-Bfxf4VVB.js +1 -0
- package/dist/assets/LiveClassroomView-DHzCM4qQ.js +1 -0
- package/dist/assets/NotificationDetailModal-BxrpnlWV.js +1 -0
- package/dist/assets/{PluginView-DCY4yi2h.js → PluginView-12qYzmnq.js} +3 -3
- package/dist/assets/{ProcessLogsModal-B-PY780w.js → ProcessLogsModal-01S7zsw0.js} +1 -1
- package/dist/assets/QuizGeneratorModal-DfZI40Ii.js +1 -0
- package/dist/assets/StudentAssignmentView-BP6zbHuM.js +1 -0
- package/dist/assets/StudentLessonView-DEpMzrH2.js +1 -0
- package/dist/assets/StudentPreviewModal-DCmai53s.js +1 -0
- package/dist/assets/StudentView-CcGlfW25.js +2 -0
- package/dist/assets/SystemResourceLibraryModal-BzHw1edT.js +1 -0
- package/dist/assets/TeacherView-Dw6mKwcv.js +2 -0
- package/dist/assets/{TimetableView-BMsjwi-s.js → TimetableView-DJgOlGSf.js} +3 -3
- package/dist/assets/index-B-YxO39A.css +1 -0
- package/dist/assets/index-C8sCKzmN.js +2 -0
- package/dist/assets/index-CYzNsYZB.js +193 -0
- package/dist/assets/{index.es-DZ6UeYE-.js → index.es-CfxBkm_z.js} +1 -1
- package/dist/assets/{vendor-charts-B7ViBL9w.js → vendor-charts-CRXa4AlU.js} +1 -1
- package/dist/assets/vendor-content-CYR4BTuT.js +3 -0
- package/dist/assets/{vendor-icons-_c3xpwjZ.js → vendor-icons-Dq6MhgH9.js} +1 -1
- package/dist/assets/{vendor-pdf-CVyNPGVr.js → vendor-pdf-Cp-cYteE.js} +2 -2
- package/dist/assets/{vendor-pptx-B0hlo0eh.js → vendor-pptx-B_NheIKl.js} +5 -5
- package/dist/assets/vendor-utils-BEhuP0Zq.js +1 -0
- package/dist/index.html +2 -2
- package/dist/server.cjs +1079 -699
- package/package.json +9 -6
- package/dist/assets/AdminDirectoryView-CD7tW4mc.js +0 -1
- package/dist/assets/BatchPickerModal-Bt8Qx0Av.js +0 -1
- package/dist/assets/ClassesView-B1B3wlkx.js +0 -19
- package/dist/assets/CloudDriveModal-BSZaWIex.js +0 -1
- package/dist/assets/ComputerLabView-B6-twB0u.js +0 -1
- package/dist/assets/CourseManagement-Bnezm9Vv.js +0 -1
- package/dist/assets/CourseWizardModal-BvfTvcQT.js +0 -3
- package/dist/assets/CoursewareHubPanel-Cb1mAqHS.js +0 -1
- package/dist/assets/ExportWeightModal-al1iIVxb.js +0 -1
- package/dist/assets/HelpTour-DwM9UBiA.js +0 -1
- package/dist/assets/ImportLessonsModal-DwhvqzY_.js +0 -1
- package/dist/assets/ImportModal-CmUt1YeX.js +0 -1
- package/dist/assets/InteractiveCoursewareViewer-DWnzq20c.js +0 -1
- package/dist/assets/InteractiveWhiteboard-CQ-4meYj.js +0 -102
- package/dist/assets/LessonEditorView-DixwX1Kw.js +0 -1
- package/dist/assets/LiveClassroomView-j93YOxSh.js +0 -1
- package/dist/assets/NotificationDetailModal-CQ9PIqkD.js +0 -1
- package/dist/assets/QuizGeneratorModal-BvTcmD68.js +0 -1
- package/dist/assets/StudentAssignmentView-4R0WxStx.js +0 -1
- package/dist/assets/StudentLessonView-DZ0i9-tX.js +0 -1
- package/dist/assets/StudentPreviewModal-CfsB1dPY.js +0 -1
- package/dist/assets/StudentView-D7GtUiYR.js +0 -2
- package/dist/assets/SystemResourceLibraryModal-Ilnthwpw.js +0 -1
- package/dist/assets/TeacherView-DjnjsQ_3.js +0 -2
- package/dist/assets/index-CATki2cp.css +0 -1
- package/dist/assets/index-D8x6bUeG.js +0 -150
- package/dist/assets/index-wdWIWwbg.js +0 -1
- package/dist/assets/vendor-content-V6uLfjnH.js +0 -3
- package/dist/assets/vendor-utils-4FcTwKPj.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./vendor-react-0Lg0vA-4.js";import{d,D as g,af as x,e as f,w as p}from"./vendor-icons-Dq6MhgH9.js";function u({show:c,onClose:r,lang:s,handleImportFile:a,importError:i,importSuccess:n,isImporting:m,downloadCSVTemplate:l}){return c?e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 font-sans text-gray-800",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-xl w-full max-w-lg flex flex-col p-6 relative",children:[e.jsx("button",{type:"button",onClick:r,className:"absolute top-4 right-4 text-gray-400 hover:text-gray-600 text-xl font-medium cursor-pointer",children:"×"}),e.jsxs("h3",{className:"text-base font-semibold text-gray-900 mb-1 flex items-center gap-2",children:[e.jsx(d,{size:18,className:"text-indigo-600"}),s==="zh"?"手动批量导入数据":"Manual Bulk Import"]}),e.jsx("p",{className:"text-xs text-gray-500 mb-4 font-sans text-left",children:s==="zh"?"支持导入 CSV 或 JSON 文件。CSV 文件需包含标题行,建议格式如下(支持中英文标题):":"Supports CSV or JSON files. CSV requires a header line with names like:"}),e.jsxs("div",{className:"bg-gray-50 p-3 rounded-lg border border-gray-100 text-[10px] font-mono text-gray-600 mb-4 whitespace-nowrap overflow-x-auto select-all text-left",children:["班级名称, 班级描述, 学生姓名, 学生邮箱",e.jsx("br",{}),"高一A班, 基础英语课程, 李明, liming@example.com",e.jsx("br",{}),"高一A班, 基础英语课程, 王华, wanghua@example.com"]}),e.jsxs("div",{className:"mb-4 flex flex-col gap-2 p-3 bg-indigo-50/50 border border-indigo-100 rounded-lg text-left select-none",children:[e.jsxs("span",{className:"text-xs font-semibold text-indigo-900 flex items-center gap-1",children:[e.jsx(g,{size:13,className:"text-indigo-600"}),s==="zh"?"下载导入数据模板文件:":"Download Import Templates:"]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 mt-1",children:[e.jsxs("button",{type:"button",onClick:()=>l("class"),className:"flex-1 flex items-center justify-center gap-1.5 text-xs px-2.5 py-2 bg-white border border-indigo-200 text-indigo-700 rounded-lg hover:bg-indigo-50 transition-colors shadow-sm font-medium cursor-pointer",children:[e.jsx(x,{size:12,className:"text-emerald-600"}),s==="zh"?"下载班级与学生模板":"Class & Students Template"]}),e.jsxs("button",{type:"button",onClick:()=>l("student"),className:"flex-1 flex items-center justify-center gap-1.5 text-xs px-2.5 py-2 bg-white border border-indigo-200 text-indigo-700 rounded-lg hover:bg-indigo-50 transition-colors shadow-sm font-medium cursor-pointer",children:[e.jsx(x,{size:12,className:"text-emerald-600"}),s==="zh"?"下载独立学生模板":"Independent Students Template"]})]})]}),e.jsxs("div",{onDragOver:t=>t.preventDefault(),onDrop:t=>{t.preventDefault(),!(!t.dataTransfer.files||t.dataTransfer.files.length===0)&&a(t.dataTransfer.files[0])},className:"border-2 border-dashed border-gray-300 rounded-xl p-8 text-center cursor-pointer hover:border-indigo-500 hover:bg-indigo-50/20 transition-all mb-4",onClick:()=>{const t=document.createElement("input");t.type="file",t.accept=".csv,.json",t.onchange=o=>{o.target.files?.[0]&&a(o.target.files[0])},t.click()},children:[e.jsx(d,{className:"mx-auto text-gray-400 mb-2",size:24}),e.jsx("p",{className:"text-xs font-semibold text-gray-700",children:s==="zh"?"点击选择文件 或 拖拽文件到这里":"Click to select file or drag it here"}),e.jsx("p",{className:"text-[10px] text-gray-400 mt-1",children:"CSV or JSON (max 5MB)"})]}),i&&e.jsxs("div",{className:"p-3 bg-red-50 border border-red-100 text-red-700 text-xs rounded-lg mb-4 flex items-start gap-2 max-h-32 overflow-y-auto",children:[e.jsx("span",{className:"font-bold shrink-0",children:"✕"}),e.jsx("span",{className:"font-sans text-left leading-tight break-all",children:i})]}),n&&e.jsxs("div",{className:"p-3 bg-green-50 border border-green-105 text-green-700 text-xs rounded-lg mb-4 flex items-start gap-2",children:[e.jsx(f,{size:14,className:"shrink-0 mt-0.5"}),e.jsx("span",{className:"font-sans text-left leading-tight",children:n})]}),m&&e.jsxs("div",{className:"flex items-center justify-center gap-2 text-indigo-600 text-xs py-2",children:[e.jsx(p,{size:16,className:"animate-spin"}),e.jsx("span",{children:s==="zh"?"正在分析数据并导入系统数据库...":"Validating data and transferring records..."})]}),e.jsx("div",{className:"flex justify-end gap-2 mt-2",children:e.jsx("button",{type:"button",onClick:r,className:"px-4 py-2 text-xs font-medium border border-gray-200 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer",children:s==="zh"?"关闭":"Close"})})]})}):null}export{u as ImportModal};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,j as e}from"./vendor-react-0Lg0vA-4.js";import{d,i as x,j as f}from"./index-CYzNsYZB.js";import{p as o,$ as h,ah as g,X as b}from"./vendor-icons-Dq6MhgH9.js";import"./vendor-pdf-Cp-cYteE.js";import"./vendor-utils-BEhuP0Zq.js";import"./vendor-motion-DjY2czvL.js";import"./vendor-pptx-B_NheIKl.js";import"./vendor-charts-CRXa4AlU.js";function k({coursewareId:l,onClose:n}){const[a,c]=t.useState(!1),s=t.useRef(null),{theme:i}=d(),u=()=>{x(i,f(i))};t.useEffect(()=>{const r=()=>{c(!!document.fullscreenElement&&document.fullscreenElement===s.current)};return document.addEventListener("fullscreenchange",r),()=>{document.removeEventListener("fullscreenchange",r)}},[]);const m=()=>{const r=s.current;r&&(document.fullscreenElement?document.exitFullscreen?document.exitFullscreen():document.webkitExitFullscreen&&document.webkitExitFullscreen():r.requestFullscreen?r.requestFullscreen():r.webkitRequestFullscreen&&r.webkitRequestFullscreen())};return l?e.jsxs("div",{ref:s,className:"flex flex-col h-full bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden relative",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-2 bg-gray-100 border-b border-gray-200 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2 select-none",children:[e.jsx(o,{size:16,className:"text-indigo-500"}),e.jsx("span",{className:"font-semibold text-sm text-gray-700",children:"Interactive Courseware"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:m,className:"p-1 hover:bg-gray-200 rounded-lg text-gray-500 transition-colors cursor-pointer",title:a?"退出全屏":"全屏播放",children:a?e.jsx(h,{size:16}):e.jsx(g,{size:16})}),n&&e.jsx("button",{onClick:n,className:"p-1 hover:bg-gray-200 rounded-lg text-gray-500 transition-colors cursor-pointer",children:e.jsx(b,{size:16})})]})]}),e.jsx("div",{className:"flex-1 relative bg-white",children:e.jsx("iframe",{src:`/api/courseware/${l}`,sandbox:"allow-scripts allow-forms allow-downloads",allowFullScreen:!0,className:"w-full h-full border-none",title:"Interactive Courseware",onLoad:u})})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-full text-gray-400 bg-gray-50 rounded-xl border border-dashed border-gray-300",children:[e.jsx(o,{size:48,className:"mb-4 text-gray-300 opacity-50"}),e.jsx("h3",{className:"text-lg font-medium text-gray-700",children:"No Courseware Selected"}),e.jsx("p",{className:"mt-2 text-sm text-center",children:"Please select a courseware from the list to view it interactively."})]})}export{k as InteractiveCoursewareViewer};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import{r as p,j as e,R as _t,b as Dr}from"./vendor-react-0Lg0vA-4.js";import{S as Mr,L as Tr,G as Ce,H as Pe,a as tt,R as Ot,C as Lt,T as Bt}from"./vendor-konva-CzxOmTv9.js";/* empty css */import{u as $r,M as Ft,E as ae,f as B,d as Er,e as Rr,F as Or,p as Lr,H as Ht,h as qe}from"./index-CYzNsYZB.js";import{w as st,f as yt,T as oe,aI as Yt,O as Br,v as Fr,W as wt,r as bt,ae as Ie,a9 as Je,z as Ar,B as Xr,aJ as gt,d as Wr,ah as ze,I as It,b8 as Jt,ac as qt,aV as Ut,aD as Gt,b9 as Kt,ba as Qt,s as _r,t as Hr,p as Yr,a_ as Ir,bb as Jr,R as qr,aZ as At,b as Ur,j as Xt,ag as rt,X as Zt,aE as Gr,bc as Kr,bd as Qr,be as Zr,$ as ft}from"./vendor-icons-Dq6MhgH9.js";import{t as Vr,v as F}from"./vendor-pptx-B_NheIKl.js";import"./vendor-pdf-Cp-cYteE.js";import"./vendor-utils-BEhuP0Zq.js";import"./vendor-motion-DjY2czvL.js";import"./vendor-charts-CRXa4AlU.js";class es{constructor(){this.frameTimes=[],this.lastTime=performance.now(),this.stats={fps:60,renderTimeMs:0,drawCount:0,visibleCount:0,totalCount:0,memoryUsageMb:0}}recordFrame(x,k,h,v){const T=performance.now(),f=T-this.lastTime;this.lastTime=T,f>0&&(this.frameTimes.push(1e3/f),this.frameTimes.length>30&&this.frameTimes.shift());const w=Math.round(this.frameTimes.reduce((N,P)=>N+P,0)/(this.frameTimes.length||1));let l=0;performance.memory&&(l=Math.round(performance.memory.usedJSHeapSize/(1024*1024)*10)/10),this.stats={fps:w,renderTimeMs:Math.round(x*100)/100,drawCount:k,visibleCount:h,totalCount:v,memoryUsageMb:l}}getStats(){return{...this.stats}}}new es;class ts{constructor(){this.currentTheme="light",this.lightTokens={primary:"#4f46e5",background:"#f8fafc",gridDot:"#cbd5e1",selectionBorder:"#6366f1",selectionHandle:"#4f46e5",textPrimary:"#1e293b",borderDefault:"#e2e8f0",guideLine:"#ec4899"},this.darkTokens={primary:"#6366f1",background:"#0b0f19",gridDot:"#334155",selectionBorder:"#818cf8",selectionHandle:"#6366f1",textPrimary:"#f8fafc",borderDefault:"#1e293b",guideLine:"#f472b6"},this.eyecareTokens={primary:"#2d6a4f",background:"#f2f7f4",gridDot:"#b7d5c5",selectionBorder:"#40916c",selectionHandle:"#2d6a4f",textPrimary:"#143526",borderDefault:"#cce0d6",guideLine:"#10b981"},this.chalkboardTokens={primary:"#4caf50",background:"#0e1713",gridDot:"#2d5242",selectionBorder:"#81c784",selectionHandle:"#4caf50",textPrimary:"#e8f5e9",borderDefault:"#1f382d",guideLine:"#66bb6a"},this.teachingTokens={primary:"#d97706",background:"#fffbeb",gridDot:"#fde68a",selectionBorder:"#f59e0b",selectionHandle:"#d97706",textPrimary:"#78350f",borderDefault:"#fef3c7",guideLine:"#ef4444"},this.customTokens=new Map,this.listeners=new Set}getTokens(){if(this.customTokens.has(this.currentTheme))return this.customTokens.get(this.currentTheme);switch(this.currentTheme){case"dark":return this.darkTokens;case"eyecare":return this.eyecareTokens;case"chalkboard":return this.chalkboardTokens;case"teaching":return this.teachingTokens;default:return this.lightTokens}}setTheme(x){this.currentTheme=x;const k=this.getTokens();this.listeners.forEach(h=>{try{h(k,x)}catch(v){console.error("[ThemeManager] Error in theme change listener:",v)}})}getTheme(){return this.currentTheme}registerCustomTokens(x,k){this.customTokens.set(x,k),this.currentTheme===x&&this.setTheme(x)}unregisterCustomTokens(x){this.customTokens.delete(x),this.currentTheme===x&&this.setTheme("light")}subscribe(x){return this.listeners.add(x),()=>{this.listeners.delete(x)}}}const Wt=new ts;function rs({pluginId:o,slot:x,widgetId:k,elementId:h,lessonId:v}){const f=$r(N=>N.extensionPoints).get(x)||[],w=f.find(N=>N.id===k)??f.find(N=>N.pluginId===o&&N.id===k),l=p.useRef(null);return p.useEffect(()=>{w&&l.current&&(l.current.innerHTML="",!w.component&&w.render&&Promise.resolve(w.render(l.current,{elementId:h,lessonId:v})).catch(console.error))},[w,o,k,h,v]),w?w.component?_t.createElement(w.component,{elementId:h,lessonId:v}):e.jsx("div",{ref:l,className:"w-full h-full min-h-0"}):e.jsxs("div",{className:"text-center py-6 text-xs text-gray-400 italic flex flex-col justify-center items-center h-full",children:[e.jsx(st,{size:16,className:"animate-spin mb-1"}),e.jsxs("span",{children:["组件 [",k,"] 正在加载或未启用..."]})]})}function ss({elementId:o,data:x,onElementUpdate:k,onPointerDown:h,onPointerMove:v,onPointerUp:T,onDelete:f}){const w=x.allStudents||[{id:"mock-s-1",name:"张明",email:"zhangming@edu-os.org"},{id:"mock-s-2",name:"李华",email:"lihua@edu-os.org"},{id:"mock-s-3",name:"王超",email:"wangchao@edu-os.org"},{id:"mock-s-4",name:"赵丽",email:"zhaoli@edu-os.org"},{id:"mock-s-5",name:"钱科",email:"qianke@edu-os.org"},{id:"mock-s-6",name:"孙雪",email:"sunxue@edu-os.org"}],[l,N]=p.useState(x.selectedStudent||null),[P,L]=p.useState(!1),[Z,j]=p.useState(""),Y=()=>{if(w.length===0||P)return;L(!0);let $=0;const X=16,u=setInterval(()=>{const C=Math.floor(Math.random()*w.length);if(j(w[C].name),$++,$>=X){clearInterval(u);const E=Math.floor(Math.random()*w.length),D=w[E];N(D),L(!1),k&&k(o,{...x,selectedStudent:D,pickedTime:new Date().toISOString(),status:"picked"})}},80)};return e.jsxs("div",{className:"w-full h-full bg-gradient-to-br from-indigo-950 via-slate-900 to-indigo-900 border border-indigo-500/50 rounded-xl shadow-2xl overflow-hidden flex flex-col font-sans select-none",style:{pointerEvents:"auto"},children:[e.jsxs("div",{className:"bg-indigo-950/80 text-indigo-200 px-3 py-2 flex justify-between items-center text-xs font-semibold border-b border-indigo-900/50 cursor-move select-none shrink-0",onPointerDown:h,onPointerMove:v,onPointerUp:T,children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-indigo-300",children:[e.jsx(yt,{size:13,className:"animate-pulse text-indigo-400"}),e.jsx("span",{children:"随机点名助手 (Picker Ext)"})]}),e.jsx("button",{onClick:f,onPointerDown:$=>$.stopPropagation(),className:"p-1 hover:bg-indigo-900/60 rounded text-indigo-400 hover:text-red-450 transition-colors cursor-pointer",title:"删除组件",children:e.jsx(oe,{size:13})})]}),e.jsxs("div",{className:"flex-1 p-3.5 flex flex-col justify-between min-h-0 text-white gap-2",children:[e.jsx("div",{className:"w-full flex-1 flex flex-col items-center justify-center p-2 rounded-lg bg-indigo-950/50 border border-indigo-900/30",children:P?e.jsxs("div",{className:"text-center space-y-2",children:[e.jsx("div",{className:"text-[10px] text-indigo-300 uppercase tracking-widest animate-pulse font-semibold",children:"检索班级学生中..."}),e.jsx("div",{className:"text-2xl font-extrabold text-amber-300 scale-105 tracking-wider font-sans",children:Z})]}):l?e.jsxs("div",{className:"text-center space-y-1.5",children:[e.jsxs("div",{className:"text-[9px] text-indigo-400 uppercase tracking-widest font-semibold flex items-center justify-center gap-1",children:[e.jsx(Yt,{size:11,className:"text-emerald-400 animate-bounce"}),e.jsx("span",{children:"抽中的幸运学生"})]}),e.jsx("div",{className:"text-2xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-amber-200 via-yellow-400 to-amber-300 tracking-wider",children:l.name}),e.jsx("div",{className:"text-[9px] text-indigo-300/70 font-mono overflow-hidden text-ellipsis max-w-full",children:l.email||"No Email Account"})]}):e.jsxs("div",{className:"text-center space-y-1",children:[e.jsx(Br,{size:28,className:"text-indigo-400/80 mx-auto animate-pulse"}),e.jsx("div",{className:"text-xs text-indigo-300 font-semibold",children:"随机抽取摇奖板"}),e.jsx("p",{className:"text-[9px] text-indigo-400/60 leading-tight",children:"将在白板上演示随机滚动,对课堂提问大有裨益"})]})}),e.jsxs("div",{className:"w-full shrink-0 flex flex-col items-center gap-1",onPointerDown:$=>$.stopPropagation(),children:[e.jsxs("button",{onClick:Y,disabled:P,className:"w-full py-1.5 bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-650 hover:to-purple-750 text-white font-bold text-[11px] uppercase tracking-wider rounded-lg shadow-md active:scale-97 disabled:opacity-50 transition-all flex items-center justify-center gap-1.5",children:[e.jsx(Fr,{size:12,className:P?"animate-spin":""}),e.jsx("span",{children:P?"滚轮运转中...":l?"重新随机点名":"开始随机点名"})]}),e.jsxs("div",{className:"text-[8.5px] text-indigo-400/60 text-center font-mono",children:["班级人数:",w.length," 人 • 内核总线热同步"]})]})]})]})}function ns({elementId:o,data:x,onElementUpdate:k,onPointerDown:h,onPointerMove:v,onPointerUp:T,onDelete:f}){const[w,l]=p.useState(x.code||"console.log('Hello from sandbox!');"),[N,P]=p.useState(""),L=()=>{P("Running in isolated Web Worker...");try{const j=`
|
|
2
|
+
const logs = [];
|
|
3
|
+
const originalLog = console.log;
|
|
4
|
+
console.log = (...args) => {
|
|
5
|
+
logs.push(args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
|
|
6
|
+
};
|
|
7
|
+
self.onmessage = function(e) {
|
|
8
|
+
try {
|
|
9
|
+
const fn = new Function(e.data);
|
|
10
|
+
const res = fn();
|
|
11
|
+
if (res !== undefined) logs.push('Return: ' + String(res));
|
|
12
|
+
self.postMessage({ success: true, logs: logs.join('\\n') });
|
|
13
|
+
} catch (err) {
|
|
14
|
+
self.postMessage({ success: false, error: err.message, logs: logs.join('\\n') });
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
`,Y=new Blob([j],{type:"application/javascript"}),$=URL.createObjectURL(Y),X=new Worker($),i=setTimeout(()=>{X.terminate(),URL.revokeObjectURL($),P("Execution timed out (3000ms limit). Worker terminated.")},3e3);X.onmessage=u=>{clearTimeout(i),X.terminate(),URL.revokeObjectURL($),u.data.success?P(u.data.logs||"Code executed successfully (no output)"):P((u.data.logs?u.data.logs+`
|
|
18
|
+
`:"")+"Error: "+u.data.error)},X.onerror=u=>{clearTimeout(i),X.terminate(),URL.revokeObjectURL($),P(`Worker Error: ${u.message}`)},X.postMessage(w)}catch(j){P(`Failed to spawn isolated worker: ${j.message}`)}},Z=()=>{k&&w!==x.code&&k(o,{...x,code:w})};return e.jsxs("div",{className:"w-full h-full bg-gray-900 border border-gray-700 rounded-lg shadow-xl overflow-hidden flex flex-col font-mono text-sm",style:{pointerEvents:"auto"},children:[e.jsxs("div",{className:"bg-gray-800 text-gray-300 px-3 py-1.5 flex justify-between items-center text-xs border-b border-gray-700 cursor-move select-none shrink-0",onPointerDown:h,onPointerMove:v,onPointerUp:T,children:[e.jsx("span",{className:"flex items-center gap-1",children:"JS Sandbox"}),e.jsxs("div",{className:"flex items-center gap-1.5",onPointerDown:j=>j.stopPropagation(),children:[e.jsx("button",{onClick:L,className:"bg-green-600 hover:bg-green-500 text-white px-2 py-0.5 rounded shadow text-[10px] cursor-pointer",children:"Run"}),e.jsx("button",{onClick:f,className:"p-0.5 hover:bg-gray-700 rounded text-gray-400 hover:text-red-500 transition-colors cursor-pointer",title:"删除组件",children:e.jsx(oe,{size:13})})]})]}),e.jsx("textarea",{value:w,onChange:j=>l(j.target.value),onBlur:Z,className:"w-full flex-1 min-h-0 bg-gray-900 text-green-400 p-3 focus:outline-none resize-none font-mono text-xs",placeholder:"// Write JS here",onPointerDown:j=>{j.stopPropagation()},onKeyDown:j=>{j.stopPropagation()}}),N&&e.jsx("div",{className:"bg-black text-gray-400 p-2 border-t border-gray-800 h-24 overflow-y-auto whitespace-pre-wrap text-[10px] shrink-0",children:N})]})}function os(o,x){const k=(o||"").trim();if(!k)return NaN;if(/[;={}\[\]'"`\\&|<>?!]|constructor|prototype|__proto__|window|document|fetch|eval|import|require|process/i.test(k))throw new Error("表达式包含不安全字符");const v=k.replace(/Math\./gi,"").toLowerCase(),T=[];let f=0;for(;f<v.length;){const i=v[f];if(/\s/.test(i)){f++;continue}if(/[0-9.]/.test(i)){let u="";for(;f<v.length&&/[0-9.]/.test(v[f]);)u+=v[f++];T.push(u);continue}if(/[a-z]/.test(i)){let u="";for(;f<v.length&&/[a-z]/.test(v[f]);)u+=v[f++];T.push(u);continue}if("+-*/^%()".includes(i)){T.push(i),f++;continue}throw new Error(`不支持的符号: ${i}`)}let w=0;const l=()=>T[w],N=i=>{const u=T[w++];if(i&&u!==i)throw new Error(`预期 '${i}',但得到 '${u}'`);return u},P=()=>L(),L=()=>{let i=Z();for(;l()==="+"||l()==="-";){const u=N(),C=Z();i=u==="+"?i+C:i-C}return i},Z=()=>{let i=j();for(;l()==="*"||l()==="/"||l()==="%";){const u=N(),C=j();u==="*"?i*=C:u==="/"?i=C===0?NaN:i/C:i%=C}return i},j=()=>{let i=Y();for(;l()==="^";){N();const u=j();i=Math.pow(i,u)}return i},Y=()=>l()==="-"?(N(),-Y()):l()==="+"?(N(),Y()):$(),$=()=>{const i=l();if(!i)throw new Error("意外的表达式结尾");if(i==="("){N("(");const C=P();return N(")"),C}if(/^[0-9.]+$/.test(i))return N(),parseFloat(i);if(i==="x")return N(),x;if(i==="pi")return N(),Math.PI;if(i==="e")return N(),Math.E;const u=N();if(l()==="("){N("(");const C=P();switch(N(")"),u){case"sin":return Math.sin(C);case"cos":return Math.cos(C);case"tan":return Math.tan(C);case"sqrt":return Math.sqrt(C);case"abs":return Math.abs(C);case"log":return Math.log(C);case"exp":return Math.exp(C);case"round":return Math.round(C);case"floor":return Math.floor(C);case"ceil":return Math.ceil(C);default:throw new Error(`未知的数学函数: ${u}`)}}throw new Error(`未知的数学标识符: ${i}`)},X=P();if(w<T.length)throw new Error(`多余语法: ${T.slice(w).join(" ")}`);return X}function is({elementId:o,data:x,onElementUpdate:k,onPointerDown:h,onPointerMove:v,onPointerUp:T,onDelete:f}){const[w,l]=p.useState(x.equation||"sin(x)"),[N,P]=p.useState(""),[L,Z]=p.useState(""),[j,Y]=p.useState({width:400,height:300}),$=p.useRef(null);p.useEffect(()=>{if(!$.current)return;const i=new ResizeObserver(u=>{for(const C of u)Y({width:C.contentRect.width||400,height:C.contentRect.height||300})});return i.observe($.current),()=>i.disconnect()},[]),p.useEffect(()=>{try{const i=[],u=j.width/2,C=j.height/2;for(let E=-10;E<=10;E+=.2){const D=E,W=os(w,D);if(typeof W!="number"||isNaN(W))continue;const he=u+D*20,$e=C-W*20;i.push(`${he},${$e}`)}P(i.join(" ")),Z("")}catch(i){Z(i.message)}},[w,j]);const X=()=>{k&&w!==x.equation&&k(o,{...x,equation:w})};return e.jsxs("div",{className:"w-full h-full bg-white border border-gray-300 rounded-lg shadow-xl overflow-hidden flex flex-col font-mono text-sm",style:{pointerEvents:"auto"},children:[e.jsxs("div",{className:"bg-gray-100 text-gray-700 px-3 py-1.5 flex justify-between items-center text-xs border-b border-gray-300 cursor-move select-none shrink-0",onPointerDown:h,onPointerMove:v,onPointerUp:T,children:[e.jsx("span",{className:"flex items-center gap-1 font-semibold text-gray-600",children:"Math Graph Sandbox"}),e.jsx("button",{onClick:f,onPointerDown:i=>i.stopPropagation(),className:"p-1 hover:bg-gray-200 rounded-full text-gray-500 hover:text-red-500 transition-colors cursor-pointer flex items-center justify-center",title:"删除组件",children:e.jsx(oe,{size:13})})]}),e.jsxs("div",{className:"p-3 border-b border-gray-200 flex-none flex flex-col gap-1",children:[e.jsx("span",{className:"text-gray-500 text-xs",children:"y = f(x)"}),e.jsx("input",{type:"text",value:w,onChange:i=>l(i.target.value),onBlur:X,className:"w-full border border-gray-300 rounded px-2 py-1 focus:outline-none focus:border-indigo-500 font-mono text-xs",placeholder:"e.g. Math.sin(x) * x",onPointerDown:i=>i.stopPropagation(),onKeyDown:i=>i.stopPropagation()}),L&&e.jsx("div",{className:"text-red-500 text-[10px] mt-1",children:L})]}),e.jsx("div",{className:"flex-1 relative overflow-hidden bg-white min-h-0",ref:$,children:e.jsxs("svg",{width:j.width,height:j.height,viewBox:`0 0 ${j.width} ${j.height}`,className:"absolute top-0 left-0",children:[e.jsx("line",{x1:j.width/2,y1:"0",x2:j.width/2,y2:j.height,stroke:"#e5e7eb",strokeWidth:"1"}),e.jsx("line",{x1:"0",y1:j.height/2,x2:j.width,y2:j.height/2,stroke:"#e5e7eb",strokeWidth:"1"}),N&&e.jsx("polyline",{points:N,fill:"none",stroke:"#6366f1",strokeWidth:"2",strokeLinejoin:"round"})]})})]})}function as({elementId:o,data:x,onElementUpdate:k,onPointerDown:h,onPointerMove:v,onPointerUp:T,onDelete:f,lessonId:w}){const[l,N]=p.useState(!1),P=async()=>{N(!0);try{await fetch("/api/commands",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({commandType:"hello.say",payload:{lessonId:w,username:"World",shout:!0}})})}catch(L){console.error("Failed to trigger hello.say command:",L)}finally{N(!1)}};return e.jsxs("div",{className:"w-full h-full bg-white border border-slate-200/80 rounded-xl shadow-lg overflow-hidden flex flex-col font-sans select-none",style:{pointerEvents:"auto"},children:[e.jsxs("div",{className:"bg-slate-50 text-slate-700 px-2 py-1.5 flex justify-between items-center text-[10px] font-semibold border-b border-slate-150 cursor-move select-none shrink-0",onPointerDown:h,onPointerMove:v,onPointerUp:T,children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-slate-650",children:[e.jsx(yt,{size:11,className:"text-amber-500 animate-pulse"}),e.jsx("span",{children:"Hello World 插件"})]}),e.jsx("button",{onClick:f,onPointerDown:L=>L.stopPropagation(),className:"p-1 hover:bg-slate-150 rounded text-slate-400 hover:text-red-500 transition-colors cursor-pointer",title:"删除组件",children:e.jsx(oe,{size:11})})]}),e.jsx("div",{className:"flex-1 p-2 flex items-center justify-center bg-slate-50/20",children:e.jsxs("button",{onClick:P,disabled:l,onPointerDown:L=>L.stopPropagation(),className:"w-full py-1 bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-650 hover:to-purple-750 text-white font-bold text-[10px] rounded-lg shadow-sm active:scale-95 transition-all flex items-center justify-center gap-1 cursor-pointer",children:[e.jsx(wt,{size:11,className:l?"animate-spin":""}),e.jsx("span",{children:l?"输出中...":"点击输出"})]})})]})}function ls({elementId:o,data:x,userRole:k="teacher",onElementUpdate:h}){const[v,T]=p.useState("ppt"),[f,w]=p.useState(x.markdown||`# Title Slide
|
|
19
|
+
---
|
|
20
|
+
## Slide 2`),[l,N]=p.useState(x.slideX||0),[P,L]=p.useState(!1),[Z,j]=p.useState(4),[Y,$]=p.useState(!1),X=p.useRef(null),i=k==="teacher",u=k==="student",C=x.fileUrl||"",E=x.fileType||"md",D=x.fileName||"",W=!!C,[he,$e]=p.useState(!1),Ee=p.useRef(null),be=p.useRef(null),A=p.useRef(null),G=!!x.isFullscreenSynced,le=!!x.isFullscreenForced,K=Y||u&&G&&le,we=f.split(/(?:\r?\n|^)---(?:\r?\n|$)/).map(g=>g.trim()).filter(g=>g.length>0),se=E==="md"?Math.max(1,we.length):x.slideCount||1;p.useEffect(()=>{E!=="md"&&v!=="ppt"&&T("ppt")},[E,v]),p.useEffect(()=>{x.slideX!==void 0&&x.slideX!==l&&N(x.slideX)},[x.slideX]),p.useEffect(()=>{x.markdown!==void 0&&x.markdown!==f&&w(x.markdown)},[x.markdown]),p.useEffect(()=>{if(E!=="pptx"||!C){A.current&&(A.current.destroy(),A.current=null);return}let g=!0;return fetch(C).then(y=>y.arrayBuffer()).then(async y=>{if(g&&(A.current&&(A.current.destroy(),A.current=null),be.current)){be.current.innerHTML="";try{const R=Vr(be.current,{mode:"slide"});A.current=R,await R.load(y),g&&(i&&h&&x.slideCount!==R.slideCount&&h(o,{...x,slideCount:R.slideCount}),R.renderSingleSlide(l))}catch(R){console.error("PPTX preview init failed",R)}}}).catch(y=>console.error("Fetch PPTX failed",y)),()=>{g=!1,A.current&&(A.current.destroy(),A.current=null)}},[C,E,K]),p.useEffect(()=>{if(E==="pptx"&&A.current)try{A.current.renderSingleSlide(l)}catch(g){console.error("PPTX renderSingleSlide failed",g)}},[l,E]),p.useEffect(()=>{if(!P||v!=="ppt"||E!=="md")return;const g=setInterval(()=>{N(y=>{const R=(y+1)%Math.max(1,we.length);return h&&h(o,{...x,slideX:R}),R})},Z*1e3);return()=>clearInterval(g)},[P,Z,we.length,v,E]),p.useEffect(()=>{const g=y=>{u&&G&&le||(y.key==="ArrowRight"||y.key===" "?(y.preventDefault(),je(l+1)):y.key==="ArrowLeft"?(y.preventDefault(),je(l-1)):y.key==="Escape"&&K&&(y.preventDefault(),ge(!1)))};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[l,K,u,G,le,se]);const je=g=>{if(u&&G&&le)return;const y=Math.min(Math.max(0,g),se-1);N(y),i&&h&&h(o,{...x,slideX:y})},Le=g=>{w(g),h&&h(o,{...x,markdown:g})},nt=async g=>{const y=g.target.files?.[0];if(!y)return;const R=y.name.split(".").pop()?.toLowerCase();if(R!=="pdf"&&R!=="pptx"){alert("仅支持上传 PDF 或 PPTX 格式的课件文件!");return}$e(!0);try{const ce=new FileReader;ce.onload=async ye=>{const me=(ye.target?.result).split(",")[1],Fe=await fetch("/api/upload",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filename:y.name,base64Data:me})});if(!Fe.ok)throw new Error("服务器上传文件失败");const I=await Fe.json();h&&(await h(o,{...x,fileUrl:I.url,fileName:y.name,fileType:I.type,slideX:0,slideCount:I.pageCount||1,isFullscreenSynced:x.isFullscreenSynced!==void 0?x.isFullscreenSynced:!0,isFullscreenForced:!1}),N(0))},ce.readAsDataURL(y)}catch(ce){console.error(ce),alert("课件文件上传失败,请重试")}finally{$e(!1)}},Ue=()=>{window.confirm("确定要清除已上传的课件并恢复为 Markdown 编辑模式吗?")&&h&&(h(o,{...x,fileUrl:"",fileName:"",fileType:"md",slideX:0,slideCount:0,isFullscreenForced:!1}),N(0))},ge=g=>{$(g),i&&h&&h(o,{...x,isFullscreenForced:g})},Be=g=>{h&&h(o,{...x,isFullscreenSynced:g,isFullscreenForced:g?Y:!1})},ot=[{name:"基础通用课件",desc:"标准的课件 structure",content:`# 物理学原理与探究
|
|
21
|
+
---
|
|
22
|
+
## 课程介绍
|
|
23
|
+
1. 经典力学基础
|
|
24
|
+
2. 能量守恒定律
|
|
25
|
+
3. 万有引力应用
|
|
26
|
+
---
|
|
27
|
+
## 科学探究要素
|
|
28
|
+
- 观察与提问
|
|
29
|
+
- 制定计划与设计实验
|
|
30
|
+
- 进行实验与收集证据
|
|
31
|
+
- 交流、评估及得出结论
|
|
32
|
+
---
|
|
33
|
+
## 物理课后思考一
|
|
34
|
+
> 牛顿第一定律是否可以在地球上直接通过实验完全验证?请结合摩擦力阐述。`},{name:"英语词汇互动",desc:"交互式英文闪卡",content:`# Topic: Smart Education
|
|
35
|
+
---
|
|
36
|
+
## Key Vocabulary
|
|
37
|
+
- **Orchestration**: Arrangement or cooperation of system systems.
|
|
38
|
+
- **Heuristic**: Practical method not guaranteed to be perfect.
|
|
39
|
+
- **Applet**: Lightweight interactive program.
|
|
40
|
+
---
|
|
41
|
+
## Reading Passage
|
|
42
|
+
Modern class orchestration allows instructors to dispatch customized applets directly onto the virtual desk interfaces of student endpoints instantly!
|
|
43
|
+
---
|
|
44
|
+
## Fill in the Blank
|
|
45
|
+
The teacher used the virtual whiteboard to ___ classroom active learning slides.
|
|
46
|
+
*(Answer: orchestrate)*`},{name:"微课探究文档",desc:"一页式大纲微课",content:`# 探究牛顿第三定律
|
|
47
|
+
在本节微课中,我们将探讨作用力与反作用力的核心性质。
|
|
48
|
+
|
|
49
|
+
## 概念要点
|
|
50
|
+
- 作用力与反作用力**大小相等**
|
|
51
|
+
- 作用力与反作用力**方向相反**
|
|
52
|
+
- 作用力与反作用力作用在**不同的物体上**
|
|
53
|
+
- 它们伴随发生,同时消失。
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 经典实验设计
|
|
58
|
+
1. 准备两个完全相同的弹簧测力计 A 与 B。
|
|
59
|
+
2. 将它们对拉,观察两者的示数变化。
|
|
60
|
+
3. 会发现:不管拉力如何变化,A 的读数总是等于 B 的读数。
|
|
61
|
+
|
|
62
|
+
## 问题思考
|
|
63
|
+
当马拉着车在水平路面上加速前进时,马拉车的力与车拉马的力,哪一个更大?`}],Ge=(()=>{const g=f.split(`
|
|
64
|
+
`),y=[];return g.forEach((R,ce)=>{const ye=R.match(/^(#{1,3})\s+(.*)$/);ye&&y.push({text:ye[2].trim(),level:ye[1].length,lineIndex:ce})}),y})();if(K&&typeof document<"u")return e.jsxs("div",{className:"w-full h-full flex flex-col items-center justify-center bg-slate-900/10 text-slate-400 font-sans p-4",children:[e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx(bt,{size:24,className:"text-indigo-500 animate-pulse"}),e.jsx("span",{className:"text-xs",children:"演示文稿正在全屏放映中"})]}),Dr.createPortal(e.jsxs("div",{className:"fixed inset-0 z-[99999] bg-neutral-950 flex flex-col items-center justify-center font-sans p-6",children:[e.jsxs("div",{className:"absolute top-4 left-4 right-4 flex items-center justify-between text-white/80 select-none z-[100001] px-4 py-2 bg-neutral-900/60 backdrop-blur-md rounded-xl border border-neutral-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-2.5 h-2.5 rounded-full bg-emerald-500 animate-pulse"}),e.jsxs("span",{className:"font-bold text-xs tracking-wider uppercase",children:[E==="md"?"Markdown Slides":`${E.toUpperCase()} Presentation`," ",u&&"(Synced)"]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-xs font-mono text-white/50",children:["Slide ",l+1," / ",se]}),i&&e.jsxs(e.Fragment,{children:[E==="md"&&e.jsx("button",{onClick:()=>L(g=>!g),className:`px-2.5 py-1 rounded-md text-[10px] uppercase font-bold tracking-wider transition-colors border cursor-pointer ${P?"bg-emerald-50 border-emerald-400 text-white animate-pulse":"bg-transparent border-neutral-700 text-neutral-400 hover:bg-neutral-850"}`,children:P?"Autoplay Live":"Autoplay"}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-white/70 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:G,onChange:g=>Be(g.target.checked),className:"rounded border-neutral-700 bg-neutral-800 text-indigo-500 focus:ring-0 focus:ring-offset-0 cursor-pointer"}),e.jsx("span",{children:"同步学生全屏"})]})]}),(!u||!le||!G||Y)&&e.jsx("button",{onClick:()=>ge(!1),className:"p-1 px-2.5 bg-red-600 text-white text-xs font-bold rounded-lg transition-colors cursor-pointer border-0 hover:bg-red-700",title:"退出放映",children:"退出放映 (Esc)"})]})]}),e.jsx("div",{className:"w-full flex-1 min-h-0 flex items-center justify-center relative",children:E==="pdf"?e.jsx("div",{className:"w-full h-full flex items-center justify-center p-2 bg-slate-100 max-w-[90vw] max-h-[82vh] aspect-video rounded-2xl overflow-hidden shadow-2xl border border-neutral-850",children:e.jsx("iframe",{src:`${C}#page=${l+1}&toolbar=0&navpanes=0`,className:"w-full h-full border-0 rounded-xl"},`${C}-fs-${l}`)}):E==="pptx"?e.jsx("div",{className:"w-full h-full flex items-center justify-center p-2 bg-slate-900/5 max-w-[90vw] max-h-[82vh] aspect-video rounded-2xl overflow-hidden shadow-2xl border border-neutral-850",children:e.jsx("div",{ref:be,className:"w-full h-full overflow-auto rounded-xl bg-white border border-slate-100 shadow-md flex items-center justify-center"})}):e.jsx("div",{className:"flex-1 w-full flex items-center justify-center max-w-[90vw] min-h-0",children:e.jsxs("div",{className:"w-full bg-white rounded-xl shadow-md border border-slate-100 flex flex-col overflow-y-auto p-6 md:p-8 aspect-video relative transition-all duration-300 hover:shadow-lg max-h-[82vh] max-w-none p-12 md:p-16 border-neutral-850 rounded-3xl shadow-2xl",children:[e.jsxs("div",{className:"flex justify-between items-center text-[10px] font-semibold text-slate-400 border-b border-slate-100 pb-2 mb-4 shrink-0",children:[e.jsx("span",{className:"tracking-wide uppercase text-indigo-650",children:"SMART CLASS SLIDE DECK"}),e.jsxs("span",{className:"font-mono",children:["SLIDE ",l+1," / ",se]})]}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto pr-1",children:e.jsx("div",{className:"markdown-body text-slate-800 leading-relaxed font-sans prose prose-neutral max-w-none text-xs",children:we[l]?e.jsx(Ft,{children:we[l]}):e.jsx("div",{className:"text-center text-slate-400 italic py-8",children:"幻灯片没有内容,请在“编辑文档”中添加。"})})}),e.jsxs("div",{className:"mt-4 pt-2 border-t border-slate-50 flex items-center justify-between text-[10px] text-slate-400 shrink-0 font-sans",children:[e.jsx("span",{children:"智慧互动教室白板演示系统"}),e.jsxs("span",{children:["Page ",l+1]})]})]})})}),!(u&&G&&le)&&e.jsxs("div",{className:"absolute bottom-6 bg-neutral-900/80 backdrop-blur-md px-6 py-2.5 rounded-full border border-neutral-800 shadow-2xl z-[100001]",children:[e.jsx("button",{disabled:l===0||u,onClick:()=>je(l-1),className:`p-1.5 rounded-full border transition-colors cursor-pointer ${l===0||u?"border-neutral-800 text-neutral-600 bg-neutral-950/20 cursor-not-allowed":"border-neutral-700 text-neutral-300 hover:bg-neutral-800"}`,title:"上一张 (ArrowLeft)",children:e.jsx(Ie,{size:18})}),e.jsxs("div",{className:"flex items-center gap-1.5 px-1 font-mono text-xs text-neutral-200",children:[e.jsx("span",{className:"font-bold text-white text-base",children:l+1}),e.jsx("span",{className:"text-neutral-600",children:"/"}),e.jsx("span",{children:se})]}),e.jsx("button",{disabled:l>=se-1||u,onClick:()=>je(l+1),className:`p-1.5 rounded-full border transition-colors cursor-pointer ${l>=se-1||u?"border-neutral-800 text-neutral-600 bg-neutral-950/20 cursor-not-allowed":"border-neutral-700 text-neutral-300 hover:bg-neutral-800"}`,title:"下一张 (ArrowRight)",children:e.jsx(Je,{size:18})})]})]}),document.body)]});const it=K?"fixed inset-0 z-[99999] bg-neutral-950 flex flex-col items-center justify-center font-sans p-6":"flex-1 flex flex-col items-center justify-between p-4 bg-slate-900/5 relative min-w-0";return e.jsxs("div",{className:"w-full h-full flex flex-col bg-slate-50 text-slate-800 overflow-hidden text-xs relative font-sans",children:[!K&&e.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5 bg-slate-100 border-b border-slate-200 shrink-0 select-none relative z-10",children:[e.jsx("div",{className:"flex items-center gap-1",children:E==="md"?e.jsxs(e.Fragment,{children:[e.jsxs("button",{onClick:()=>T("ppt"),className:`px-2 py-1 rounded flex items-center gap-1 font-medium transition-colors cursor-pointer ${v==="ppt"?"bg-indigo-600 text-white shadow-sm":"text-slate-600 hover:bg-slate-200"}`,title:"播放课件幻灯片 (PPT Mode)",children:[e.jsx(Ar,{size:11}),e.jsx("span",{children:"PPT 播放"})]}),e.jsxs("button",{onClick:()=>T("doc"),className:`px-2 py-1 rounded flex items-center gap-1 font-medium transition-colors cursor-pointer ${v==="doc"?"bg-indigo-600 text-white shadow-sm":"text-slate-600 hover:bg-slate-200"}`,title:"以精美文档形式阅读 (Markdown Document mode)",children:[e.jsx(Xr,{size:11}),e.jsx("span",{children:"文档阅读"})]}),e.jsxs("button",{onClick:()=>T("edit"),className:`px-2 py-1 rounded flex items-center gap-1 font-medium transition-colors cursor-pointer ${v==="edit"?"bg-indigo-600 text-white shadow-sm":"text-slate-600 hover:bg-slate-200"}`,title:"在线编辑 Markdown 内容",children:[e.jsx(gt,{size:11}),e.jsx("span",{children:"编辑文档"})]})]}):e.jsxs("div",{className:"flex items-center gap-1 bg-indigo-50 border border-indigo-200/50 text-indigo-700 px-2 py-0.5 rounded text-[10px] font-semibold",children:[e.jsx(bt,{size:10}),e.jsxs("span",{children:[E.toUpperCase()," 课件演示中"]})]})}),e.jsxs("div",{className:"flex items-center gap-3",children:[i&&e.jsx("div",{className:"flex items-center gap-1.5 border-r border-slate-200 pr-3",children:he?e.jsxs("div",{className:"flex items-center gap-1 text-[10px] text-slate-500 font-medium",children:[e.jsx(st,{size:10,className:"animate-spin"}),e.jsx("span",{children:"上传解析中..."})]}):W?e.jsxs("div",{className:"flex items-center gap-1.5 bg-slate-200/50 pl-2 pr-1.5 py-0.5 rounded border border-slate-300/30",children:[e.jsx("span",{className:"text-[10px] font-medium text-slate-600 max-w-[120px] truncate font-mono",title:D,children:D}),e.jsx("button",{onClick:Ue,className:"p-0.5 hover:bg-slate-300 rounded text-red-500 cursor-pointer border-0 bg-transparent",title:"清除并切换回 Markdown",children:e.jsx(oe,{size:10})})]}):e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>Ee.current?.click(),className:"px-2 py-1 rounded bg-indigo-50 border border-indigo-200 text-indigo-700 hover:bg-indigo-100 flex items-center gap-1 font-semibold text-[10px] cursor-pointer",title:"上传 PPTX 或 PDF 课件",children:[e.jsx(Wr,{size:10}),e.jsx("span",{children:"上传课件"})]}),e.jsx("input",{type:"file",ref:Ee,onChange:nt,accept:".pdf,.pptx",className:"hidden"})]})}),v==="ppt"&&E==="md"&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("button",{onClick:()=>L(g=>!g),className:`p-1 rounded flex items-center gap-1 font-semibold text-[10px] transition-colors border cursor-pointer ${P?"bg-emerald-50 border-emerald-300 text-emerald-700":"bg-white border-slate-200 text-slate-500 hover:bg-slate-50"}`,title:"开启/关闭幻灯片自动播放",children:[P?e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping"}):null,e.jsx("span",{children:P?"自动播放中":"自动播放"})]}),P&&e.jsxs("select",{value:Z,onChange:g=>j(Number(g.target.value)),className:"bg-white border border-slate-200 rounded px-1 text-[10px] py-0.5 text-slate-700 font-medium",children:[e.jsx("option",{value:2,children:"2秒"}),e.jsx("option",{value:4,children:"4秒"}),e.jsx("option",{value:6,children:"6秒"}),e.jsx("option",{value:10,children:"10秒"})]})]}),i&&v==="ppt"&&e.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-slate-500 font-medium cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:G,onChange:g=>Be(g.target.checked),className:"rounded border-slate-300 text-indigo-650 focus:ring-0 focus:ring-offset-0 cursor-pointer"}),e.jsx("span",{children:"同步学生全屏"})]}),v==="ppt"&&(!u||!(G&&le))&&e.jsx("button",{onClick:()=>ge(!0),className:"p-1 rounded-lg text-slate-655 hover:bg-slate-200 border border-slate-200 bg-white transition-colors cursor-pointer",title:"全屏放映",children:e.jsx(ze,{size:11})})]})]}),e.jsxs("div",{className:"flex-1 min-h-0 relative flex flex-row overflow-hidden",children:[v==="ppt"&&e.jsxs("div",{className:it,children:[K&&e.jsxs("div",{className:"absolute top-4 left-4 right-4 flex items-center justify-between text-white/80 select-none z-[100001] px-4 py-2 bg-neutral-900/60 backdrop-blur-md rounded-xl border border-neutral-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-2.5 h-2.5 rounded-full bg-emerald-500 animate-pulse"}),e.jsxs("span",{className:"font-bold text-xs tracking-wider uppercase",children:[E==="md"?"Markdown Slides":`${E.toUpperCase()} Presentation`," ",u&&"(Synced)"]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-xs font-mono text-white/50",children:["Slide ",l+1," / ",se]}),i&&e.jsxs(e.Fragment,{children:[E==="md"&&e.jsx("button",{onClick:()=>L(g=>!g),className:`px-2.5 py-1 rounded-md text-[10px] uppercase font-bold tracking-wider transition-colors border cursor-pointer ${P?"bg-emerald-50 border-emerald-400 text-white animate-pulse":"bg-transparent border-neutral-700 text-neutral-400 hover:bg-neutral-850"}`,children:P?"Autoplay Live":"Autoplay"}),e.jsxs("label",{className:"flex items-center gap-1.5 text-xs text-white/70 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:G,onChange:g=>Be(g.target.checked),className:"rounded border-neutral-700 bg-neutral-800 text-indigo-500 focus:ring-0 focus:ring-offset-0 cursor-pointer"}),e.jsx("span",{children:"同步学生全屏"})]}),e.jsx("button",{onClick:()=>ge(!1),className:"p-1 px-2.5 bg-red-655 text-white text-xs font-bold rounded-md transition-colors cursor-pointer border-0",title:"退出放映",children:"退出放映 (Esc)"})]})]})]}),e.jsx("div",{className:"w-full flex-1 min-h-0 flex items-center justify-center relative",children:E==="pdf"?e.jsx("div",{className:`w-full h-full flex items-center justify-center p-2 bg-slate-100 ${K?"max-w-5xl aspect-video rounded-2xl overflow-hidden shadow-2xl border border-neutral-850":""}`,children:e.jsx("iframe",{src:`${C}#page=${l+1}&toolbar=0&navpanes=0`,className:"w-full h-full border-0 rounded-xl"},`${C}-${K?"fs":"card"}-${l}`)}):E==="pptx"?e.jsx("div",{className:`w-full h-full flex items-center justify-center p-2 bg-slate-900/5 ${K?"max-w-5xl aspect-video rounded-2xl overflow-hidden shadow-2xl border border-neutral-850":""}`,children:e.jsx("div",{ref:be,className:"w-full h-full overflow-auto rounded-xl bg-white border border-slate-100 shadow-md flex items-center justify-center"})}):e.jsx("div",{className:"flex-1 w-full flex items-center justify-center max-w-2xl min-h-0",children:e.jsxs("div",{className:`w-full bg-white rounded-xl shadow-md border border-slate-100 flex flex-col overflow-y-auto p-6 md:p-8 aspect-video relative transition-all duration-300 hover:shadow-lg max-h-full ${K?"max-w-4xl p-12 md:p-16 border-neutral-850 rounded-3xl shadow-2xl":""}`,children:[e.jsxs("div",{className:"flex justify-between items-center text-[10px] font-semibold text-slate-400 border-b border-slate-100 pb-2 mb-4 shrink-0",children:[e.jsx("span",{className:"tracking-wide uppercase text-indigo-650",children:"SMART CLASS SLIDE DECK"}),e.jsxs("span",{className:"font-mono",children:["SLIDE ",l+1," / ",se]})]}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto pr-1",children:e.jsx("div",{className:"markdown-body text-slate-800 leading-relaxed font-sans prose prose-neutral max-w-none text-xs",children:we[l]?e.jsx(Ft,{children:we[l]}):e.jsx("div",{className:"text-center text-slate-400 italic py-8",children:"幻灯片没有内容,请在“编辑文档”中添加。"})})}),e.jsxs("div",{className:"mt-4 pt-2 border-t border-slate-50 flex items-center justify-between text-[10px] text-slate-400 shrink-0 font-sans",children:[e.jsx("span",{children:"智慧互动教室白板演示系统"}),e.jsxs("span",{children:["Page ",l+1]})]})]})})}),!(u&&G&&le)&&e.jsxs("div",{className:`mt-4 flex items-center justify-center gap-3 select-none shrink-0 ${K?"absolute bottom-6 bg-neutral-900/80 backdrop-blur-md px-6 py-2.5 rounded-full border border-neutral-800 shadow-2xl z-[100001]":"bg-white px-4 py-2 rounded-full border border-slate-200/80 shadow-md relative z-10"}`,children:[e.jsx("button",{disabled:l===0||u&&G&&le,onClick:()=>je(l-1),className:`p-1.5 rounded-full border transition-colors cursor-pointer ${l===0||u&&G&&le?K?"border-neutral-800 text-neutral-600 bg-neutral-950/20 cursor-not-allowed":"border-slate-100 bg-slate-50 text-slate-300 cursor-not-allowed":K?"border-neutral-700 text-neutral-300 hover:bg-neutral-800":"border-slate-205 text-slate-655 hover:bg-slate-50"}`,title:"上一张 (ArrowLeft)",children:e.jsx(Ie,{size:K?18:14})}),e.jsxs("div",{className:`flex items-center gap-1.5 px-1 font-mono text-xs ${K?"text-neutral-200":"text-slate-700"}`,children:[e.jsx("span",{className:`font-bold ${K?"text-white text-base":"text-slate-900"}`,children:l+1}),e.jsx("span",{className:K?"text-neutral-600":"text-slate-350",children:"/"}),e.jsx("span",{children:se})]}),e.jsx("button",{disabled:l>=se-1||u&&G&&le,onClick:()=>je(l+1),className:`p-1.5 rounded-full border transition-colors cursor-pointer ${l>=se-1||u&&G&&le?K?"border-neutral-800 text-neutral-600 bg-neutral-950/20 cursor-not-allowed":"border-slate-100 bg-slate-50 text-slate-300 cursor-not-allowed":K?"border-neutral-700 text-neutral-300 hover:bg-neutral-800":"border-slate-205 text-slate-655 hover:bg-slate-50"}`,title:"下一张 (ArrowRight)",children:e.jsx(Je,{size:K?18:14})})]})]}),v==="doc"&&E==="md"&&e.jsxs("div",{className:"flex-1 flex flex-row min-h-0 bg-white",children:[Ge.length>0&&e.jsxs("div",{className:"w-1/4 min-w-[120px] max-w-[200px] border-r border-slate-200 bg-slate-50/50 flex flex-col py-3 px-2 overflow-y-auto shrink-0 select-none",children:[e.jsxs("span",{className:"text-[10px] font-bold text-slate-400 uppercase tracking-widest px-2 mb-2 flex items-center gap-1",children:[e.jsx(It,{size:10}),"文档大纲"]}),e.jsx("div",{className:"flex flex-col gap-0.5",children:Ge.map((g,y)=>e.jsx("button",{onClick:()=>{const R=X.current?.querySelector(`[data-line-index="${g.lineIndex}"]`);R&&R.scrollIntoView({behavior:"smooth",block:"start"})},className:"text-left text-[11px] py-1 px-2 rounded hover:bg-slate-100 text-slate-600 hover:text-slate-900 truncate cursor-pointer font-medium whitespace-nowrap border-0 bg-transparent",style:{paddingLeft:`${Math.max(8,g.level*6)}px`},title:g.text,children:g.text},y))})]}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto p-6 md:p-8",ref:X,children:e.jsx("div",{className:"markdown-body prose prose-neutral max-w-none text-xs leading-relaxed text-slate-700",children:f.split(`
|
|
65
|
+
`).map((g,y)=>{const R=g.match(/^(#{1,3})\s+(.*)$/);if(R){const ce=R[1].length,ye=R[2].trim(),Ke=ce===1?"h1":ce===2?"h2":"h3",me=ce===1?"text-lg font-bold text-indigo-900 border-b pb-1 mt-4 mb-2":ce===2?"text-base font-bold text-slate-800 mt-3 mb-1.5":"text-sm font-semibold text-slate-700 mt-2 mb-1";return e.jsx(Ke,{"data-line-index":y,className:me,children:ye},y)}return g.trim()==="---"?e.jsx("hr",{className:"my-4 border-slate-200"},y):e.jsx("p",{className:"my-1.5 text-slate-600 antialiased leading-relaxed",children:g},y)})})})]}),v==="edit"&&E==="md"&&e.jsxs("div",{className:"flex-1 flex flex-col md:flex-row min-h-0 bg-white",children:[e.jsxs("div",{className:"w-full md:w-1/3 border-b md:border-b-0 md:border-r border-slate-100 bg-slate-50/40 p-3 flex flex-col overflow-y-auto shrink-0 select-none",children:[e.jsxs("span",{className:"text-[10px] font-bold text-slate-400 tracking-wider uppercase mb-2 flex items-center gap-1",children:[e.jsx(wt,{size:10,className:"text-indigo-650"}),"推荐课件及文档模板"]}),e.jsx("div",{className:"flex flex-col gap-2",children:ot.map((g,y)=>e.jsxs("button",{type:"button",onClick:()=>{window.confirm(`确定要加载模板 “${g.name}” 吗?这将会覆盖当前白板课件中的所有编辑内容。`)&&(Le(g.content),N(0))},className:"w-full text-left p-2.5 rounded-lg border border-slate-200 bg-white hover:border-indigo-300 hover:shadow-sm transition-all focus:outline-none cursor-pointer group",children:[e.jsx("div",{className:"font-bold text-[11px] text-slate-800 group-hover:text-indigo-700 whitespace-nowrap overflow-hidden text-ellipsis",children:g.name}),e.jsx("div",{className:"text-[9px] text-slate-400 mt-0.5",children:g.desc})]},y))}),e.jsxs("div",{className:"mt-4 p-2 bg-amber-50 rounded border border-amber-100 text-[10px] text-amber-700 font-sans leading-relaxed",children:[e.jsx("strong",{children:"💡 使用提示"}),e.jsx("br",{}),"在任意位置插入一行 ",e.jsx("code",{children:"---"})," 即可分割出一个新的幻灯片(PPT)页面。"]})]}),e.jsxs("div",{className:"flex-1 flex flex-col p-3 min-h-[200px]",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5 px-1",children:[e.jsx("span",{className:"font-bold text-slate-500 text-[10px] uppercase",children:"Markdown Source Code"}),e.jsx("span",{className:"text-[9px] text-slate-400",children:"实时自动同步到所有协同终端"})]}),e.jsx("textarea",{value:f,onChange:g=>Le(g.target.value),placeholder:"在此输入 Markdown 文档。使用 '---' 来作为 PPT 页面分页符...",className:"flex-1 w-full p-3 font-mono text-xs bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:bg-white transition-all resize-none leading-relaxed text-slate-800"})]})]})]})]})}const cs=({tool:o,setTool:x,setSelectedShapeId:k,highlighterColor:h,setHighlighterColor:v,onElementAdd:T,currentPage:f,activeSegmentId:w,lessonId:l,safeElements:N,selectedShapeId:P,showGrid:L,setShowGrid:Z,userRole:j="teacher",isSyncing:Y,setIsSyncing:$,handleClearBoard:X,handleResetBoard:i,handleElementDelete:u,setDialog:C,setDialogInput:E,onRefresh:D})=>e.jsxs("div",{className:"flex items-center justify-start gap-1.5 px-3 py-1.5 bg-surface border-b border-theme shrink-0 font-sans select-none text-main",children:[e.jsx("button",{onClick:()=>{x("cursor"),k(null)},className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="cursor"?"bg-primary-theme text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"选择工具 (Pointer / Selector)",children:e.jsx(Jt,{size:16})}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx("button",{onClick:()=>x("pen"),className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="pen"?"bg-primary-theme text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"画笔工具 (Pen)",children:e.jsx(qt,{size:16})}),e.jsx("button",{onClick:()=>x("highlighter"),className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="highlighter"?"bg-amber-500 text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"荧光高亮笔 (Highlighter)",children:e.jsx(Ut,{size:16})}),o==="highlighter"&&e.jsx("div",{className:"flex items-center gap-1 bg-surface-secondary p-1 rounded-xl border border-theme animate-in zoom-in-95 duration-150",children:[{hex:"#facc15",label:"Yellow"},{hex:"#4ade80",label:"Green"},{hex:"#f472b6",label:"Pink"},{hex:"#60a5fa",label:"Blue"}].map(W=>e.jsx("button",{onClick:()=>v(W.hex),className:`w-3.5 h-3.5 rounded-full border transition-all ${h===W.hex?"ring-2 ring-primary-theme scale-110 border-white":"border-transparent"}`,style:{backgroundColor:W.hex},title:W.label},W.hex))}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx("button",{onClick:()=>x("rect"),className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="rect"?"bg-primary-theme text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"矩形工具 (Rectangle)",children:e.jsx(Gt,{size:16})}),e.jsx("button",{onClick:()=>x("circle"),className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="circle"?"bg-primary-theme text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"圆形工具 (Circle)",children:e.jsx(Kt,{size:16})}),e.jsx("button",{onClick:()=>x("text"),className:`p-1.5 rounded-xl transition-all cursor-pointer ${o==="text"?"bg-primary-theme text-white shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"文本工具 (Text)",children:e.jsx(Qt,{size:16})}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:presentation",placement:"before"}),e.jsx("button",{onClick:()=>{E(`# Title Slide
|
|
66
|
+
---
|
|
67
|
+
## Slide 2`),C({type:"prompt",title:"添加演示文稿",message:"请输入演示文稿的 Markdown 内容 (使用 --- 拆分新幻灯片):",placeholder:`# Title Slide
|
|
68
|
+
---
|
|
69
|
+
## Slide 2`,onConfirm:async W=>{const he=W||`# Title Slide
|
|
70
|
+
---
|
|
71
|
+
## Slide 2`;$(!0);try{await T("presentation",{markdown:he,x:50,y:50,width:600,height:400,slideX:0,slideY:0,page:f,segmentId:w}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l})}finally{$(!1),C(null)}}})},className:"p-1.5 rounded-xl text-muted hover:bg-surface-secondary hover:text-main transition-all cursor-pointer",title:"插入演示幻灯片 (Presentation)",children:e.jsx(bt,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:presentation",placement:"after"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:code-sandbox",placement:"before"}),e.jsx("button",{onClick:async()=>{$(!0);try{await T("code-sandbox",{code:"console.log('Hello Sandbox!');",x:100,y:100,page:f,segmentId:w}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l})}finally{$(!1)}},className:"p-1.5 rounded-xl text-muted hover:bg-surface-secondary hover:text-main transition-all cursor-pointer",title:"插入代码沙箱 (Code Sandbox)",children:e.jsx(_r,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:code-sandbox",placement:"after"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:math-graph",placement:"before"}),e.jsx("button",{onClick:async()=>{$(!0);try{await T("math-graph",{equation:"Math.sin(x)",x:100,y:150,page:f,segmentId:w}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l})}finally{$(!1)}},className:"p-1.5 rounded-xl text-muted hover:bg-surface-secondary hover:text-main transition-all cursor-pointer",title:"插入数学函数图表 (Math Graph)",children:e.jsx(Hr,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:math-graph",placement:"after"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:courseware",placement:"before"}),e.jsx("button",{onClick:async()=>{$(!0);try{await T("html-applet",{code:`<!-- Interactive Web Courseware -->
|
|
72
|
+
<div style='padding:20px; text-align:center;'>
|
|
73
|
+
<h2>Interactive Web Courseware</h2>
|
|
74
|
+
<p>可在右侧属性栏中选择本地 ZIP/HTML 部署包。</p>
|
|
75
|
+
</div>`,x:100,y:150,page:f,segmentId:w}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l})}finally{$(!1)}},className:"p-1.5 rounded-xl text-muted hover:bg-surface-secondary hover:text-main transition-all cursor-pointer",title:"插入交互网页课件 (Interactive Courseware)",children:e.jsx(Yr,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:courseware",placement:"after"}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:rollcall",placement:"before"}),e.jsx("button",{onClick:async()=>{$(!0);try{await T("rollcall",{title:"随机点名助手",x:120,y:120,page:f,segmentId:w}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l})}finally{$(!1)}},className:"p-1.5 rounded-xl text-primary-theme hover:bg-primary-theme-light transition-all cursor-pointer flex items-center gap-1 text-xs font-semibold",title:"插入随机点名组件 (Roll Call)",children:e.jsx(Yt,{size:15})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:rollcall",placement:"after"}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx(ae,{slot:"classroom.tool"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:ai-tutor",placement:"before"}),e.jsx("button",{onClick:async()=>{$(!0);try{(await fetch(`/api/lessons/${l}/ai-tutor`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({elements:N.map(he=>({type:he.type,data:JSON.parse(he.data)}))})})).ok?(B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:l},timestamp:Date.now(),correlationId:l}),D&&D()):C({type:"alert",title:"AI 辅导提示",message:"无法获取 AI 授课助手的帮助,请稍后再试。",onConfirm:()=>C(null)})}finally{$(!1)}},className:"p-1.5 rounded-xl text-purple-600 hover:bg-purple-500/10 transition-all cursor-pointer",title:"请求 AI 助教建议 (Ask AI Tutor)",children:e.jsx(wt,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:ai-tutor",placement:"after"}),e.jsx("div",{className:"w-px h-4 bg-border-theme mx-0.5"}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:grid",placement:"before"}),e.jsx("button",{onClick:()=>Z(W=>!W),className:`p-1.5 rounded-xl transition-all cursor-pointer ${L?"text-primary-theme bg-primary-theme-light":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:L?"关闭网格背景":"开启网格背景",children:e.jsx(Ir,{size:16})}),e.jsx(ae,{slot:"anchor:whiteboard-toolbar:grid",placement:"after"}),P&&e.jsxs("button",{onClick:()=>{u(P),k(null)},className:"px-2 py-1 rounded-xl text-rose-500 bg-rose-500/10 hover:bg-rose-500/20 border border-rose-500/30 shadow-2xs font-semibold flex items-center gap-1 text-xs transition-all cursor-pointer",title:"删除选中图形",children:[e.jsx(oe,{size:13})," 删除"]}),j!=="student"?e.jsx("button",{onClick:X,className:"p-1.5 rounded-xl text-muted hover:text-rose-500 hover:bg-rose-500/10 transition-all cursor-pointer",title:"清空白板 (Clear Board)",children:e.jsx(Jr,{size:16})}):e.jsx("button",{onClick:i,className:"p-1.5 rounded-xl text-muted hover:text-amber-500 hover:bg-amber-500/10 transition-all cursor-pointer",title:"重置白板 (Reset Board)",children:e.jsx(qr,{size:16})}),Y&&e.jsx(st,{size:15,className:"text-primary-theme animate-spin ml-1"})]}),ds=({pages:o,currentPage:x,showPageDrawer:k,setShowPageDrawer:h,editingPageIdx:v,setEditingPageIdx:T,editingPageTitle:f,setEditingPageTitle:w,activeMenuPageIdx:l,setActiveMenuPageIdx:N,safeElements:P,handleSwitchPage:L,handleRenamePage:Z,handleDuplicatePage:j,handleMovePage:Y,handleDeletePage:$,handleAddPage:X})=>e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"absolute bottom-3 left-1/2 -translate-x-1/2 z-20 flex items-center gap-1.5 bg-surface/90 backdrop-blur-md px-3 py-1.5 rounded-full shadow-lg border border-theme font-sans select-none text-main",children:[e.jsxs("button",{onClick:()=>h(!k),className:`p-1.5 rounded-full transition-colors cursor-pointer flex items-center gap-1 text-xs font-medium ${k?"bg-primary-theme-light text-primary-theme":"text-muted hover:bg-surface-secondary hover:text-main"}`,title:"页面大纲与预览 (Pages Outline)",children:[e.jsx(At,{size:15}),e.jsxs("span",{className:"hidden sm:inline text-[11px] font-semibold",children:["大纲 (",o.length,")"]})]}),e.jsx("div",{className:"h-4 w-px bg-border-theme mx-0.5"}),e.jsx("button",{onClick:()=>L(Math.max(0,x-1)),className:"p-1 hover:bg-surface-secondary rounded-full text-muted hover:text-main disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer",disabled:x===0,title:"上一页",children:e.jsx(Ie,{size:16})}),e.jsx("div",{className:"flex items-center gap-1 max-w-[500px] overflow-x-auto no-scrollbar py-0.5",children:o.map((i,u)=>{const C=u===x,E=v===u;return e.jsxs("div",{className:"relative group flex items-center",children:[E?e.jsx("input",{type:"text",autoFocus:!0,value:f,onChange:D=>w(D.target.value),onKeyDown:D=>{D.key==="Enter"&&Z(u,f),D.key==="Escape"&&T(null)},onBlur:()=>Z(u,f),className:"px-2 py-0.5 text-xs font-bold bg-surface border border-primary-theme rounded-full outline-none w-28 text-main shadow-2xs"}):e.jsx("button",{onClick:()=>L(u),onDoubleClick:()=>{T(u),w(i.title)},className:`px-3 py-1 rounded-full text-xs font-bold transition-all cursor-pointer flex items-center gap-1 border ${C?"bg-primary-theme text-white border-primary-theme shadow-2xs":"text-muted hover:bg-surface-secondary hover:text-main border-transparent"}`,title:"双击重命名",children:e.jsx("span",{className:"truncate max-w-[120px]",children:i.title})}),e.jsx("button",{onClick:D=>{D.stopPropagation(),N(l===u?null:u)},className:`p-0.5 rounded-full hover:bg-black/10 transition-colors ml-[-4px] z-10 ${C?"text-white/80 hover:text-white":"text-muted hover:text-main"}`,title:"页面选项",children:e.jsx(Ur,{size:12})}),l===u&&e.jsxs("div",{className:"absolute bottom-full mb-2 left-1/2 -translate-x-1/2 bg-surface rounded-xl shadow-xl border border-theme py-1 w-36 z-50 text-xs font-normal text-main",onClick:D=>D.stopPropagation(),children:[e.jsxs("button",{onClick:()=>{T(u),w(i.title),N(null)},className:"w-full px-3 py-1.5 text-left text-main hover:bg-primary-theme-light hover:text-primary-theme flex items-center gap-2 cursor-pointer",children:[e.jsx(gt,{size:13})," 重命名"]}),e.jsxs("button",{onClick:()=>{j(u),N(null)},className:"w-full px-3 py-1.5 text-left text-main hover:bg-primary-theme-light hover:text-primary-theme flex items-center gap-2 cursor-pointer",children:[e.jsx(Xt,{size:13})," 复制页面"]}),u>0&&e.jsxs("button",{onClick:()=>{Y(u,"left"),N(null)},className:"w-full px-3 py-1.5 text-left text-main hover:bg-primary-theme-light hover:text-primary-theme flex items-center gap-2 cursor-pointer",children:[e.jsx(Ie,{size:13})," 向左移动"]}),u<o.length-1&&e.jsxs("button",{onClick:()=>{Y(u,"right"),N(null)},className:"w-full px-3 py-1.5 text-left text-main hover:bg-primary-theme-light hover:text-primary-theme flex items-center gap-2 cursor-pointer",children:[e.jsx(Je,{size:13})," 向右移动"]}),e.jsx("div",{className:"my-1 border-t border-theme"}),e.jsxs("button",{onClick:()=>{$(u),N(null)},className:"w-full px-3 py-1.5 text-left text-rose-500 hover:bg-rose-500/10 flex items-center gap-2 cursor-pointer disabled:opacity-30",disabled:o.length<=1,children:[e.jsx(oe,{size:13})," 删除页面"]})]})]},i.id||u)})}),e.jsx("button",{onClick:()=>X(),className:"p-1 hover:bg-primary-theme-light hover:text-primary-theme text-muted rounded-full transition-colors cursor-pointer ml-0.5",title:"新建白板页面",children:e.jsx(rt,{size:16})}),e.jsx("button",{onClick:()=>L(Math.min(o.length-1,x+1)),className:"p-1 hover:bg-surface-secondary rounded-full text-muted hover:text-main disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer",disabled:x>=o.length-1,title:"下一页",children:e.jsx(Je,{size:16})})]}),k&&e.jsx("div",{className:"absolute inset-0 bg-slate-950/40 backdrop-blur-xs z-30 flex flex-col justify-end pointer-events-auto font-sans",onClick:()=>h(!1),children:e.jsxs("div",{className:"bg-surface/95 backdrop-blur-xl border-t border-theme rounded-t-2xl shadow-2xl p-4 max-h-[70vh] flex flex-col w-full max-w-5xl mx-auto animate-in slide-in-from-bottom duration-200 text-main",onClick:i=>i.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between pb-3 border-b border-theme shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(At,{className:"w-5 h-5 text-primary-theme"}),e.jsx("h3",{className:"font-bold text-main text-sm",children:"白板页面大纲与预览"}),e.jsxs("span",{className:"px-2 py-0.5 bg-primary-theme-light text-primary-theme text-xs rounded-full font-semibold",children:["共 ",o.length," 页"]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>X(),className:"px-3 py-1.5 bg-primary-theme hover:bg-primary-theme-hover text-white rounded-lg text-xs font-semibold flex items-center gap-1.5 transition-colors cursor-pointer shadow-xs",children:[e.jsx(rt,{size:14})," 新建页面"]}),e.jsx("button",{onClick:()=>h(!1),className:"p-1.5 hover:bg-surface-secondary rounded-full text-muted hover:text-main transition-colors cursor-pointer",children:e.jsx(Zt,{size:16})})]})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 py-4 overflow-y-auto max-h-[50vh]",children:o.map((i,u)=>{const C=u===x,E=P.filter(D=>D.type!=="page_meta"&&(()=>{try{const W=JSON.parse(D.data);return(W.page??0)===u||W.pageId===i.id}catch{return u===0}})()).length;return e.jsxs("div",{onClick:()=>{L(u),h(!1)},className:`relative flex flex-col p-3 rounded-xl border-2 transition-all cursor-pointer group bg-surface ${C?"border-primary-theme bg-primary-theme-light/30 shadow-md ring-2 ring-[var(--color-primary)]/20":"border-theme hover:border-primary-theme hover:shadow-sm"}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("span",{className:`text-[11px] font-extrabold px-2 py-0.5 rounded-md ${C?"bg-primary-theme text-white":"bg-surface-secondary text-muted"}`,children:["P",u+1]}),C&&e.jsx("span",{className:"text-[10px] font-bold text-primary-theme bg-primary-theme-light px-1.5 py-0.5 rounded",children:"当前激活"})]}),e.jsxs("div",{className:"h-20 bg-surface-secondary border border-theme rounded-lg flex flex-col items-center justify-center mb-2 overflow-hidden relative",children:[e.jsx(It,{size:24,className:C?"text-primary-theme":"text-subtle"}),e.jsxs("span",{className:"text-[10px] text-muted font-medium mt-1",children:[E," 个组件/笔画"]})]}),e.jsx("div",{className:"font-bold text-xs text-main truncate mb-1",title:i.title,children:i.title}),e.jsxs("div",{className:"flex items-center justify-between pt-2 border-t border-theme text-muted text-[11px]",onClick:D=>D.stopPropagation(),children:[e.jsx("button",{onClick:()=>{T(u),w(i.title)},className:"hover:text-primary-theme p-1 rounded hover:bg-surface-secondary transition-colors",title:"重命名",children:e.jsx(gt,{size:13})}),e.jsx("button",{onClick:()=>j(u),className:"hover:text-primary-theme p-1 rounded hover:bg-surface-secondary transition-colors",title:"复制页面",children:e.jsx(Xt,{size:13})}),u>0&&e.jsx("button",{onClick:()=>Y(u,"left"),className:"hover:text-primary-theme p-1 rounded hover:bg-surface-secondary transition-colors",title:"向左移",children:e.jsx(Ie,{size:13})}),u<o.length-1&&e.jsx("button",{onClick:()=>Y(u,"right"),className:"hover:text-primary-theme p-1 rounded hover:bg-surface-secondary transition-colors",title:"向右移",children:e.jsx(Je,{size:13})}),e.jsx("button",{onClick:()=>$(u),className:"hover:text-rose-500 p-1 rounded hover:bg-rose-500/10 transition-colors disabled:opacity-30",disabled:o.length<=1,title:"删除页面",children:e.jsx(oe,{size:13})})]})]},i.id||u)})})]})})]}),us=({dialog:o,dialogInput:x,setDialogInput:k,setDialog:h})=>o?e.jsx("div",{className:"absolute inset-0 bg-neutral-900/40 backdrop-blur-[2px] flex items-center justify-center z-[9999] p-4 font-sans",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-2xl overflow-hidden max-w-sm w-full border border-gray-100 flex flex-col scale-100 pointer-events-auto",children:[e.jsxs("div",{className:"px-5 py-4 border-b border-gray-150/60 bg-gray-50 flex justify-between items-center shrink-0",children:[e.jsx("h3",{className:"font-bold text-gray-800 text-sm",children:o.title}),e.jsx("button",{onClick:()=>h(null),className:"text-gray-400 hover:text-gray-650 transition-colors text-xl font-light cursor-pointer",children:"×"})]}),e.jsxs("div",{className:"p-5 flex-1 min-h-0",children:[e.jsx("p",{className:"text-xs text-gray-600 leading-relaxed whitespace-pre-wrap mb-4 font-medium",children:o.message}),o.type==="prompt"&&e.jsx("textarea",{value:x,onChange:v=>k(v.target.value),placeholder:o.placeholder,className:"w-full h-32 p-3 border border-gray-300 rounded-lg text-xs font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-gray-50 focus:bg-white transition-all resize-none font-medium",onPointerDown:v=>v.stopPropagation()})]}),e.jsxs("div",{className:"px-5 py-3 border-t border-gray-100 bg-gray-50 flex justify-end gap-2 text-xs shrink-0",children:[o.type!=="alert"&&e.jsx("button",{onClick:()=>h(null),className:"px-4 py-2 text-gray-500 hover:bg-gray-100 rounded-lg transition-colors font-medium border border-gray-200 cursor-pointer",children:"取消"}),e.jsx("button",{onClick:async()=>{try{await o.onConfirm(x)}catch(v){console.error("Dialog action error:",v)}},className:"px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-semibold transition-all shadow-sm cursor-pointer",children:"确定"})]})]})}):null,xs=({showEntrySelector:o,setShowEntrySelector:x,zipUploadInfo:k,zipCandidates:h,handlePropsUpdate:v,fetchCoursewares:T})=>!o||!k?null:e.jsx("div",{className:"absolute inset-0 bg-neutral-900/40 backdrop-blur-[2px] flex items-center justify-center z-[9999] p-4 font-sans",children:e.jsxs("div",{className:"bg-white rounded-xl shadow-2xl overflow-hidden max-w-sm w-full border border-gray-100 flex flex-col scale-100 pointer-events-auto",children:[e.jsxs("div",{className:"px-5 py-4 border-b border-gray-150/60 bg-gray-50 flex justify-between items-center shrink-0",children:[e.jsx("h3",{className:"font-bold text-gray-800 text-sm",children:"选择课件入口页面"}),e.jsx("button",{onClick:()=>x(!1),className:"text-gray-400 hover:text-gray-650 transition-colors text-xl font-light cursor-pointer",children:"×"})]}),e.jsxs("div",{className:"p-5 flex-1 min-h-0 space-y-3",children:[e.jsx("p",{className:"text-xs text-gray-600 leading-relaxed font-medium",children:"ZIP压缩包中含有多个HTML文件,请选择一个作为课件入口:"}),e.jsx("div",{className:"max-h-60 overflow-y-auto border border-gray-200 rounded-lg p-2 bg-gray-50 space-y-1",children:h.map(f=>e.jsxs("button",{onClick:async()=>{try{const w=await fetch("/api/courseware/confirm",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({uuid:k.uuid,name:k.name,entry:f})});if(w.ok){const l=await w.json();v({coursewareUuid:l.uuid,resourceId:""}),x(!1),T()}}catch(w){console.error("Failed to confirm entry point:",w)}},className:"w-full text-left p-2 rounded hover:bg-indigo-50 hover:text-indigo-700 text-xs font-semibold font-mono truncate transition-all cursor-pointer",children:["📄 ",f]},f))})]}),e.jsx("div",{className:"px-5 py-3 border-t border-gray-100 bg-gray-50 flex justify-end gap-2 text-xs shrink-0",children:e.jsx("button",{onClick:()=>x(!1),className:"px-4 py-2 text-gray-500 hover:bg-gray-100 rounded-lg transition-colors font-medium border border-gray-200 cursor-pointer",children:"取消"})})]})});qe.register("quiz",({data:o})=>e.jsxs("div",{className:"max-w-2xl mx-auto space-y-6",children:[e.jsx("h3",{className:"text-xl font-bold text-gray-800",children:o.question}),e.jsx("div",{className:"flex flex-col gap-3",children:(o.options||[]).map((x,k)=>e.jsxs("button",{className:"px-5 py-4 text-left bg-gray-50 border-2 border-gray-200 rounded-xl text-base hover:bg-gray-100 transition-colors",children:[e.jsxs("span",{className:"font-bold text-indigo-600 mr-3",children:["ABCDEFGHIJKLMNOPQRSTUVWXYZ"[k],"."]}),x]},k))}),o.submissions&&Object.keys(o.submissions).length>0&&e.jsx("div",{className:"mt-4 p-4 bg-gray-50 rounded-xl",children:e.jsxs("p",{className:"text-sm font-semibold text-gray-600",children:["提交统计: ",Object.keys(o.submissions).length," 人已作答"]})})]}));qe.register("timer",({data:o})=>e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsxs("div",{className:"text-center",children:[e.jsxs("div",{className:"text-8xl font-mono font-bold text-orange-600 mb-4",children:[String(Math.floor((o.remaining??o.duration??60)/60)).padStart(2,"0"),":",String((o.remaining??o.duration??60)%60).padStart(2,"0")]}),e.jsx("p",{className:"text-lg text-gray-500",children:o.label||"计时器"})]})}));qe.register("assignment",({data:o})=>e.jsxs("div",{className:"max-w-2xl mx-auto space-y-6",children:[e.jsx("h3",{className:"text-xl font-bold text-gray-800",children:o.title}),e.jsx("p",{className:"text-gray-600 text-base whitespace-pre-wrap",children:o.description}),e.jsx("button",{className:"w-full bg-orange-600 hover:bg-orange-700 text-white font-medium py-3 rounded-xl transition-colors text-base shadow-sm cursor-pointer",children:"Upload File"})]}));qe.register("rollcall",({data:o})=>e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"text-6xl font-bold text-indigo-600 mb-4",children:o.selectedStudent||"点击点名"}),e.jsx("p",{className:"text-lg text-gray-500",children:"随机点名"})]})}));qe.register("html-applet",({data:o,lessonId:x})=>e.jsx(Ht,{data:o,lessonId:x,className:"w-full h-full rounded-xl border"}));const ps=[{id:"page-0",title:"P1 · 引入导入",order:0},{id:"page-1",title:"P2 · 核心讲解",order:1},{id:"page-2",title:"P3 · 互动练习",order:2}],Ts=p.forwardRef(({lessonId:o,elements:x,onElementAdd:k,onElementUpdate:h,onElementDelete:v,onClearBoard:T,onRefresh:f,enableAutoAI:w,activeSegmentId:l,onSegmentSync:N,userRole:P="teacher",isEditMode:L=!0},Z)=>{const j=Array.isArray(x)?x:[],Y=Er(r=>r.theme);p.useEffect(()=>{Wt.setTheme(Y)},[Y]);const $=Wt.getTokens(),X=Y==="dark"||Y==="chalkboard",[i,u]=p.useState("cursor"),[C,E]=p.useState("#facc15"),[D,W]=p.useState(0),[he,$e]=p.useState(!0),[Ee,be]=p.useState(!1),[A,G]=p.useState(ps),[le,K]=p.useState(!1),[we,se]=p.useState(null),[je,Le]=p.useState(""),[nt,Ue]=p.useState(null);p.useEffect(()=>{const r=j.find(t=>t.type==="page_meta");if(r)try{const t=JSON.parse(r.data);Array.isArray(t.pages)&&t.pages.length>0&&G(t.pages)}catch(t){console.error("Failed to parse whiteboard page_meta:",t)}},[x]);const ge=r=>{const t=j.find(s=>s.type==="page_meta");t&&h?h(t.id,{pages:r}):k&&k("page_meta",{pages:r}),te.current&&te.current.emit("whiteboard-update",{roomId:o,type:"page-meta-update",payload:{pages:r}})},Be=r=>{W(r),Ue(null),te.current&&te.current.emit("whiteboard-update",{roomId:o,type:"page-change",payload:{page:r}})},ot=r=>{const t=A.length,s={id:`page-${Date.now()}-${t}`,title:r||`P${t+1} · 备课页面`,order:t},a=[...A,s];G(a),W(t),ge(a),te.current&&te.current.emit("whiteboard-update",{roomId:o,type:"page-change",payload:{page:t}})},jt=(r,t)=>{if(!t.trim()){se(null);return}const s=A.map((a,d)=>d===r?{...a,title:t.trim()}:a);G(s),ge(s),se(null),Le("")},Ge=r=>{const t=A[r];if(!t)return;const s=r+1,a={id:`page-${Date.now()}-${s}`,title:`${t.title} (副本)`,order:s},d=[...A.slice(0,s),a,...A.slice(s).map(m=>({...m,order:m.order+1}))];G(d),W(s),ge(d),j.filter(m=>m.type!=="page_meta"&&(()=>{try{const z=JSON.parse(m.data);return(z.page??0)===r||z.pageId===t.id}catch{return r===0}})()).forEach(m=>{try{const z=JSON.parse(m.data);k&&k(m.type,{...z,page:s,pageId:a.id,x:(z.x??100)+20,y:(z.y??100)+20})}catch(z){console.error("Failed duplicating page element:",z)}})},it=r=>{if(A.length<=1){pe({title:"无法删除",message:"至少需要保留一个白板页面!",type:"alert"});return}const t=A[r],s=j.filter(d=>d.type!=="page_meta"&&(()=>{try{const c=JSON.parse(d.data);return(c.page??0)===r||c.pageId===t.id}catch{return r===0}})()),a=()=>{v&&s.forEach(m=>v(m.id));const d=A.filter((m,z)=>z!==r).map((m,z)=>({...m,order:z}));G(d);const c=Math.min(D,d.length-1);W(c),ge(d)};s.length>0?pe({title:"确认删除白板页面",message:`页面 [${t.title}] 包含 ${s.length} 个组件,删除页面将同时清理该页面的组件,是否确定删除?`,type:"confirm",onConfirm:a}):a()},g=(r,t)=>{const s=t==="left"?r-1:r+1;if(s<0||s>=A.length)return;const a=[...A],d=a[r];a[r]=a[s],a[s]=d,a.forEach((c,m)=>{c.order=m}),G(a),D===r?W(s):D===s&&W(r),ge(a)},[y,R]=p.useState(null),[ce,ye]=p.useState(!1),Ke=p.useRef(null),[me,Fe]=p.useState({width:0,height:0}),I=p.useRef(null),[Qe,J]=p.useState(!1),te=p.useRef(null),[Vt,vt]=p.useState({}),[hs,ms]=p.useState({}),[fs,bs]=p.useState({}),[gs,ys]=p.useState({}),[at,Re]=p.useState(null),[Ae,lt]=p.useState(null),ie=p.useRef(null),q=p.useRef(null),Se=p.useRef(null),[S,Nt]=p.useState(null),O=r=>{P==="teacher"&&Nt(r)},[Xe,er]=p.useState(null),ee=r=>{P==="teacher"&&er(r)},[kt,Ct]=p.useState(null),[De,ct]=p.useState(null),We=p.useRef(null),[tr,pe]=p.useState(null),[rr,Pt]=p.useState(""),[M,fe]=p.useState(null),[_e,dt]=p.useState({}),[He,ut]=p.useState({}),[sr,nr]=p.useState([]),[ws,zt]=p.useState(!1),[or,ir]=p.useState([]),[ar,lr]=p.useState([]),[cr,dr]=p.useState(null),[ur,St]=p.useState(!1),xt=async()=>{try{const r=await fetch("/api/courseware");if(r.ok){const t=await r.json();ir(t)}}catch(r){console.error("Error fetching coursewares:",r)}},pt=async()=>{try{zt(!0);const r=await fetch("/api/resources");if(r.ok){const t=await r.json();nr(t)}}catch(r){console.error("Error fetching system resources:",r)}finally{zt(!1)}};p.useEffect(()=>{if(S){const r=j.find(t=>t.id===S);if(r){r.type==="html-applet"&&(pt(),xt());try{fe(JSON.parse(r.data))}catch{fe({})}}else fe(null)}else fe(null)},[S,x]);const Me=async r=>{const t=j.find(m=>m.id===S);if(!t)return;let s={};try{s=JSON.parse(t.data)}catch{}const a={...s,...r},d=t.data,c=JSON.stringify(a);if(d!==c&&(dt(m=>{const z=m[t.id]?[...m[t.id]]:[];return z.length>=30&&z.shift(),z.push(d),{...m,[t.id]:z}}),ut(m=>({...m,[t.id]:[]}))),h){J(!0);try{await h(t.id,a),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f()}catch(m){console.error("更新属性失败:",m)}finally{J(!1)}}},xr=async()=>{if(!S)return;const r=j.find(c=>c.id===S);if(!r)return;const t=_e[S]||[];if(t.length===0)return;const s=t[t.length-1],a=t.slice(0,t.length-1),d=r.data;if(ut(c=>{const m=c[S]?[...c[S]]:[];return m.push(d),{...c,[S]:m}}),dt(c=>({...c,[S]:a})),h){J(!0);try{const c=JSON.parse(s);fe(c),await h(S,c),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f()}catch(c){console.error("撤销修改失败:",c)}finally{J(!1)}}},pr=async()=>{if(!S)return;const r=j.find(c=>c.id===S);if(!r)return;const t=He[S]||[];if(t.length===0)return;const s=t[t.length-1],a=t.slice(0,t.length-1),d=r.data;if(dt(c=>{const m=c[S]?[...c[S]]:[];return m.push(d),{...c,[S]:m}}),ut(c=>({...c,[S]:a})),h){J(!0);try{const c=JSON.parse(s);fe(c),await h(S,c),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f()}catch(c){console.error("重做修改失败:",c)}finally{J(!1)}}},V=(r,t)=>{fe(s=>s&&{...s,[r]:t})},de=(r,t)=>{Me({[r]:t})},Te=r=>{fe(t=>t&&{...t,...r}),Me(r)},Oe=(r,t)=>{const s=parseFloat(t);isNaN(s)||Me({[r]:s})},hr=(r,t)=>{fe(s=>{if(!s)return s;const a=[...s.options||[]];return a[r]=t,{...s,options:a}})},mr=(r,t)=>{if(!M)return;const s=[...M.options||[]];s[r]=t,Me({options:s})},fr=()=>{if(!M)return;const r=M.options||[],s="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[r.length]||`Option ${r.length+1}`,a=[...r,`选项 ${s}`];fe(d=>d&&{...d,options:a}),Me({options:a})},br=r=>{if(!M)return;const t=(M.options||[]).filter((s,a)=>a!==r);fe(s=>s&&{...s,options:t}),Me({options:t})};p.useEffect(()=>{const r=()=>{ee(null)};return window.addEventListener("click",r),()=>window.removeEventListener("click",r)},[]);const gr=r=>{try{const t=JSON.parse(r.data);if(r.type==="pen"&&t.points){let s=1/0,a=-1/0,d=1/0;for(let c=0;c<t.points.length;c+=2){const m=t.points[c],z=t.points[c+1];m<s&&(s=m),m>a&&(a=m),z<d&&(d=z)}return{x:(s+a)/2,y:d-36}}else if(r.type==="rectangle"||r.type==="shape"&&t.shape==="rect"){const s=t.x??0,a=t.y??0,d=t.width??0,c=t.height??0;return{x:s+d/2,y:(c<0?a+c:a)-36}}else if(r.type==="circle"||r.type==="shape"&&t.shape==="circle"){const s=t.x??0,a=t.y??0,d=t.radius??0;return{x:s,y:a-d-36}}else if(r.type==="text"){const s=t.x??0,a=t.y??0;return{x:s+40,y:a-36}}else if(t.x!==void 0&&t.y!==void 0)return{x:t.x+(t.width?t.width/2:150),y:t.y-36}}catch(t){console.error(t)}return null},ve=(r,t,s)=>{if(P!=="teacher")return;r.preventDefault();const a=s.x??0,d=s.y??0,c={id:t,currentX:a,currentY:d,startPointerX:r.clientX,startPointerY:r.clientY,data:s};ie.current=c,lt(c)},Ne=r=>{},ke=async r=>{},Ze=(r,t,s,a,d,c,m)=>{if(P!=="teacher")return;r.preventDefault(),r.stopPropagation();const z={id:t,corner:s,startX:r.clientX,startY:r.clientY,initialX:a,initialY:d,initialWidth:c,initialHeight:m},_={id:t,x:a,y:d,width:c,height:m};q.current=z,Se.current=_,Ct(z),ct(_)},Ve=r=>{},et=async r=>{};p.useEffect(()=>{if(!Ae)return;const r=s=>{if(!ie.current)return;const a=s.clientX-ie.current.startPointerX,d=s.clientY-ie.current.startPointerY,c=ie.current.data.x??0,m=ie.current.data.y??0;ie.current.currentX=c+a,ie.current.currentY=m+d,lt({...ie.current})},t=async s=>{if(!ie.current)return;const a=ie.current.currentX,d=ie.current.currentY,c=ie.current.id,m=ie.current.data;if(ie.current=null,lt(null),h){J(!0);try{await h(c,{...m,x:a,y:d}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}catch(z){console.error("Drag end update error:",z)}finally{J(!1)}}};return window.addEventListener("pointermove",r),window.addEventListener("pointerup",t),()=>{window.removeEventListener("pointermove",r),window.removeEventListener("pointerup",t)}},[Ae,h,o]),p.useEffect(()=>{if(!kt||!De)return;const r=s=>{if(!q.current||!Se.current)return;const a=s.clientX-q.current.startX,d=s.clientY-q.current.startY;let c=q.current.initialX,m=q.current.initialY,z=q.current.initialWidth,_=q.current.initialHeight;const U=150,ne=100,{corner:re}=q.current;if(re==="bottom-right")z=Math.max(U,q.current.initialWidth+a),_=Math.max(ne,q.current.initialHeight+d);else if(re==="bottom-left"){const n=q.current.initialWidth-a;n>=U&&(z=n,c=q.current.initialX+a),_=Math.max(ne,q.current.initialHeight+d)}else if(re==="top-right"){z=Math.max(U,q.current.initialWidth+a);const n=q.current.initialHeight-d;n>=ne&&(_=n,m=q.current.initialY+d)}else if(re==="top-left"){const n=q.current.initialWidth-a;n>=U&&(z=n,c=q.current.initialX+a);const b=q.current.initialHeight-d;b>=ne&&(_=b,m=q.current.initialY+d)}Se.current={id:q.current.id,x:c,y:m,width:z,height:_},ct({...Se.current})},t=async s=>{if(!q.current||!Se.current)return;const{id:a}=q.current,{x:d,y:c,width:m,height:z}=Se.current;q.current=null,Se.current=null,Ct(null),ct(null);const _=j.find(U=>U.id===a);if(_&&h)try{const U=JSON.parse(_.data);J(!0),await h(a,{...U,x:d,y:c,width:m,height:z}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}catch(U){console.error("Resize end update error:",U)}finally{J(!1)}};return window.addEventListener("pointermove",r),window.addEventListener("pointerup",t),()=>{window.removeEventListener("pointermove",r),window.removeEventListener("pointerup",t)}},[kt,De,x,h,o]);const ue=r=>{pe({type:"confirm",title:"删除组件",message:"您确定要从白板中删除这个组件或图形吗?该操作不可撤销。",onConfirm:async()=>{J(!0);try{v?await v(r):await fetch(`/api/lessons/${o}/whiteboard/${r}`,{method:"DELETE"}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f(),O(null)}catch(t){console.error("Delete element failed:",t)}finally{J(!1),pe(null)}}})},yr=()=>{pe({type:"confirm",title:"清空白板",message:"您确定要清空画布上的所有组件、图形和线条吗?此操作将永久清空白板且不可逆!",onConfirm:async()=>{J(!0);try{T?await T():await fetch(`/api/lessons/${o}/whiteboard`,{method:"DELETE"}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f(),O(null)}catch(r){console.error("Clear board failed:",r)}finally{J(!1),pe(null)}}})},wr=()=>{pe({type:"confirm",title:"重置白板",message:"您确定要将白板重置为开始上课的状态吗?您在白板上做的所有临时修改都将被重置。",onConfirm:async()=>{J(!0);try{await fetch(`/api/lessons/${o}/whiteboard/reset`,{method:"POST"}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f(),O(null)}catch(r){console.error("Reset board failed:",r)}finally{J(!1),pe(null)}}})};p.useEffect(()=>{const r=t=>{if((t.key==="Delete"||t.key==="Backspace")&&S){const s=t.target;s.tagName!=="INPUT"&&s.tagName!=="TEXTAREA"&&(ue(S),O(null))}};return window.addEventListener("keydown",r),()=>window.removeEventListener("keydown",r)},[S]);const Dt=()=>{We.current&&clearTimeout(We.current),w&&(We.current=setTimeout(async()=>{J(!0);try{(await fetch(`/api/lessons/${o}/ai-tutor`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({elements:j.map(t=>({type:t.type,data:JSON.parse(t.data)}))})})).ok&&(B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f())}catch(r){console.error(r)}finally{J(!1)}},6e4))};p.useEffect(()=>(Dt(),()=>{We.current&&clearTimeout(We.current)}),[x]),p.useEffect(()=>{const r=Rr();te.current=r,r.emit("join-room",o);const t=s=>{s.type==="temp-draw"?vt(a=>({...a,[s.userId]:s.payload})):s.type==="temp-end"?vt(a=>{const d={...a};return delete d[s.userId],d}):s.type==="refresh"?f&&f():s.type==="segment-change"?N&&s.payload?.segmentId&&N(s.payload.segmentId):s.type==="page-change"?typeof s.payload?.page=="number"&&W(s.payload.page):s.type==="page-meta-update"&&Array.isArray(s.payload?.pages)&&G(s.payload.pages)};return te.current.on("whiteboard-sync",t),()=>{te.current?.off("whiteboard-sync",t)}},[o,f,N]),p.useEffect(()=>{if(!I.current)return;const r=new ResizeObserver(s=>{for(let a of s)I.current&&Fe({width:I.current.offsetWidth,height:I.current.offsetHeight})});r.observe(I.current);const t=()=>{I.current&&Fe({width:I.current.offsetWidth,height:I.current.offsetHeight})};return t(),window.addEventListener("resize",t),()=>{r.disconnect(),window.removeEventListener("resize",t)}},[]);const jr=r=>{if(Dt(),ee(null),i==="cursor"){r.target===r.target.getStage()&&O(null);return}if(Qe)return;ye(!0);const t=r.target.getStage().getPointerPosition();if(i==="pen"){const s=X?"#f8fafc":"black";R({type:"pen",points:[t.x,t.y],color:s})}else if(i==="highlighter")R({type:"highlighter",points:[t.x,t.y],color:C});else if(i==="rect"){const s=X?"#818cf8":"blue";R({type:"rectangle",x:t.x,y:t.y,width:0,height:0,stroke:s})}else if(i==="circle"){const s=X?"#4ade80":"green";R({type:"circle",x:t.x,y:t.y,radius:0,stroke:s})}else if(i==="text"){const s=X?"#f8fafc":"black";R({type:"text",x:t.x,y:t.y,text:"Click to edit...",fontSize:16,color:s})}},vr=r=>{if(!ce||!y)return;const t=r.target.getStage().getPointerPosition();if(y.type==="pen"||y.type==="highlighter")R({...y,points:y.points.concat([t.x,t.y])});else if(y.type==="rectangle")R({...y,width:t.x-y.x,height:t.y-y.y});else if(y.type==="circle"){const s=Math.sqrt(Math.pow(t.x-y.x,2)+Math.pow(t.y-y.y,2));R({...y,radius:s})}},Nr=async()=>{if(!ce||!y)return;ye(!1);const r={...y,page:D,segmentId:l};R(null),J(!0);try{await k(r.type,r),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}finally{J(!1)}};p.useEffect(()=>{!te.current||!te.current.id||(y?te.current.emit("whiteboard-update",{roomId:o,type:"temp-draw",userId:te.current.id,payload:{...y,page:D,segmentId:l}}):te.current.emit("whiteboard-update",{roomId:o,type:"temp-end",userId:te.current.id}))},[y,o,D,l]),p.useEffect(()=>{l&&te.current&&te.current.emit("whiteboard-update",{roomId:o,type:"segment-change",payload:{segmentId:l}})},[l,o]);const Mt=r=>{if(!r)return null;const t=r.page??0,s=A[D];return!(r.pageId&&s?.id?r.pageId===s.id:t===D)||l&&r.segmentId&&r.segmentId!==l?null:r.type==="pen"?e.jsx(tt,{points:r.points,stroke:r.color,strokeWidth:4,tension:.5,lineCap:"round",lineJoin:"round"}):r.type==="highlighter"?e.jsx(tt,{points:r.points,stroke:r.color||"#facc15",strokeWidth:18,tension:.5,lineCap:"round",lineJoin:"round",opacity:.5}):r.type==="rectangle"?e.jsx(Ot,{x:r.x,y:r.y,width:r.width,height:r.height,stroke:r.stroke}):r.type==="circle"?e.jsx(Lt,{x:r.x,y:r.y,radius:r.radius,stroke:r.stroke}):r.type==="text"?e.jsx(Bt,{x:r.x,y:r.y,text:r.text,fontSize:r.fontSize,fill:r.color}):null},kr=()=>Mt(y?{...y,page:D,segmentId:l}:null),Cr=()=>Object.values(Vt).map((r,t)=>e.jsx(_t.Fragment,{children:Mt(r)},t)),Pr=r=>{try{const t=JSON.parse(r.data),s=Ae?.id===r.id,a=De?.id===r.id,d=a?De.x:s?Ae.currentX:t.x??0,c=a?De.y:s?Ae.currentY:t.y??0,m=n=>n==="plugin"?t.width||500:n==="hello-world"?160:n==="quiz"?300:n==="rollcall"?320:n==="assignment"?310:n==="html-applet"||n==="code-sandbox"||n==="math-graph"?400:n==="presentation"?600:300,z=n=>n==="plugin"?t.height||400:n==="hello-world"?64:n==="quiz"?280:n==="rollcall"?310:n==="assignment"?250:n==="html-applet"?300:n==="code-sandbox"?320:n==="math-graph"?350:n==="presentation"?400:300,_=a?De.width:t.width??m(r.type),U=a?De.height:t.isMinimized?32:t.height??z(r.type),ne=S===r.id,re=()=>ne?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"absolute -inset-1 border-2 border-indigo-500 rounded-lg pointer-events-none z-50 shadow-md animate-pulse duration-1000 animate-in fade-in"}),e.jsx("div",{className:"absolute -top-1.5 -left-1.5 w-3.5 h-3.5 bg-white border-2 border-indigo-600 rounded-full cursor-nwse-resize z-50 hover:bg-indigo-50 hover:scale-110 transition-transform shadow",onPointerDown:n=>Ze(n,r.id,"top-left",d,c,_,U),onPointerMove:Ve,onPointerUp:et}),e.jsx("div",{className:"absolute -top-1.5 -right-1.5 w-3.5 h-3.5 bg-white border-2 border-indigo-600 rounded-full cursor-nesw-resize z-50 hover:bg-indigo-50 hover:scale-110 transition-transform shadow",onPointerDown:n=>Ze(n,r.id,"top-right",d,c,_,U),onPointerMove:Ve,onPointerUp:et}),e.jsx("div",{className:"absolute -bottom-1.5 -left-1.5 w-3.5 h-3.5 bg-white border-2 border-indigo-600 rounded-full cursor-nesw-resize z-50 hover:bg-indigo-50 hover:scale-110 transition-transform shadow",onPointerDown:n=>Ze(n,r.id,"bottom-left",d,c,_,U),onPointerMove:Ve,onPointerUp:et}),e.jsx("div",{className:"absolute -bottom-1.5 -right-1.5 w-3.5 h-3.5 bg-white border-2 border-indigo-600 rounded-full cursor-nwse-resize z-50 hover:bg-indigo-50 hover:scale-110 transition-transform shadow",onPointerDown:n=>Ze(n,r.id,"bottom-right",d,c,_,U),onPointerMove:Ve,onPointerUp:et})]}):null;if(r.type==="plugin"){const n=P==="teacher",b=n?t.teacherWidgetId:t.studentWidgetId,H=n?"teacher.dashboard.widget":"student.view";return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:Q=>{O(r.id),Q.stopPropagation()},onContextMenu:Q=>{Q.preventDefault(),Q.stopPropagation();const xe=I.current?.getBoundingClientRect();xe&&ee({x:Q.clientX-xe.left,y:Q.clientY-xe.top,elementId:r.id})},className:"bg-white border border-gray-300 rounded-lg shadow-xl overflow-hidden flex flex-col font-sans text-sm relative",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsxs("div",{className:"bg-indigo-50 text-indigo-750 px-3 py-1.5 flex justify-between items-center text-xs font-semibold border-b border-indigo-150 cursor-move select-none shrink-0",onPointerDown:Q=>ve(Q,r.id,t),onPointerMove:Ne,onPointerUp:ke,children:[e.jsx("span",{children:t.title||"Plugin Component"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>Re(r.id),onPointerDown:Q=>Q.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-indigo-650 hover:text-indigo-900 transition-colors cursor-pointer flex items-center justify-center",title:"全屏",children:e.jsx(ze,{size:11})}),e.jsx("button",{onClick:()=>ue(r.id),onPointerDown:Q=>Q.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-indigo-600 hover:text-red-500 transition-colors cursor-pointer flex items-center justify-center",title:"删除组件",children:e.jsx(oe,{size:11})})]})]}),!t.isMinimized&&e.jsx("div",{className:"flex-grow bg-white overflow-auto relative min-h-0 p-2",children:e.jsx(rs,{pluginId:t.pluginId,slot:H,widgetId:b,elementId:r.id,lessonId:o})}),!t.isMinimized&&re()]})})},r.id)}if(r.type==="hello-world")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},className:"bg-transparent",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsx(as,{elementId:r.id,data:t,onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,onDelete:()=>ue(r.id),onElementUpdate:h,lessonId:o}),re()]})})},r.id);if(r.type==="rollcall")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"bg-transparent",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsx(ss,{elementId:r.id,data:t,onElementUpdate:h,onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,onDelete:()=>ue(r.id)}),re()]})})},r.id);if(r.type==="quiz")return null;if(r.type==="assignment")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"bg-white border border-gray-300 rounded-lg shadow-xl overflow-hidden flex flex-col font-sans text-sm relative select-none",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsxs("div",{className:"bg-orange-50 text-orange-700 px-3 py-1.5 flex justify-between items-center text-xs font-semibold border-b border-orange-100 cursor-move select-none shrink-0",onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,children:[e.jsx("span",{children:"Assignment Upload Task"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>Re(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-orange-600 hover:text-orange-900 transition-colors cursor-pointer flex items-center justify-center",title:"全屏",children:e.jsx(ze,{size:11})}),e.jsx("button",{onClick:async()=>{h&&(await h(r.id,{...t,isMinimized:!t.isMinimized}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))},onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-orange-655 hover:text-orange-900 transition-colors cursor-pointer flex items-center justify-center",title:t.isMinimized?"展开组件":"收起组件",children:t.isMinimized?e.jsx(ze,{size:11}):e.jsx(ft,{size:11})}),e.jsx("button",{onClick:()=>ue(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-orange-600 hover:text-red-500 transition-colors cursor-pointer flex items-center justify-center",title:"删除组件",children:e.jsx(oe,{size:11})})]})]}),!t.isMinimized&&e.jsxs("div",{className:"p-4 text-center flex-1 overflow-y-auto flex flex-col justify-center min-h-0",children:[e.jsx("p",{className:"font-semibold text-gray-800 mb-1 text-xs",children:t.title}),e.jsx("p",{className:"text-xs text-gray-500 mb-3 line-clamp-3",children:t.description}),e.jsx("button",{className:"w-full bg-orange-600 hover:bg-orange-700 text-white font-medium py-1.5 rounded transition-colors text-xs shadow-sm cursor-pointer",onClick:()=>{pe({type:"alert",title:"作业文件上传",message:`系统已经成功模拟拉起本地文件选择和上传流程!
|
|
76
|
+
已准备上传作业: ${t.title??"白板作业"}`,onConfirm:()=>pe(null)})},children:"Upload File"})]}),!t.isMinimized&&re()]})})},r.id);if(r.type==="html-applet")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"bg-white border border-gray-300 rounded-lg shadow-xl overflow-hidden flex flex-col font-sans text-sm relative",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsxs("div",{className:"bg-gray-100 text-gray-700 px-3 py-1.5 flex justify-between items-center text-xs font-semibold border-b border-gray-200 cursor-move select-none shrink-0",onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,children:[e.jsx("span",{children:t.title||"Interactive Courseware"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>Re(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-gray-600 hover:text-gray-900 transition-colors cursor-pointer flex items-center justify-center",title:"全屏",children:e.jsx(ze,{size:11})}),e.jsx("button",{onClick:async()=>{h&&(await h(r.id,{...t,isMinimized:!t.isMinimized}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))},onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-gray-650 hover:text-gray-900 transition-colors cursor-pointer flex items-center justify-center",title:t.isMinimized?"展开组件":"收起组件",children:t.isMinimized?e.jsx(ze,{size:11}):e.jsx(ft,{size:11})}),e.jsx("button",{onClick:()=>ue(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-gray-650 hover:text-red-500 transition-colors cursor-pointer flex items-center justify-center",title:"删除组件",children:e.jsx(oe,{size:11})})]})]}),!t.isMinimized&&e.jsx("div",{className:"flex-1 bg-white overflow-hidden relative min-h-0",children:e.jsx(Ht,{data:t,lessonId:o,className:"w-full h-full border-none"})}),!t.isMinimized&&re()]})})},r.id);if(r.type==="pen"){const n=S===r.id;return e.jsx(tt,{id:r.id,points:t.points,stroke:n?$.selectionBorder||"#3b82f6":t.color&&t.color!=="black"&&t.color!=="#000000"?t.color:X?"#f8fafc":t.color||"black",strokeWidth:n?6:4,tension:.5,lineCap:"round",lineJoin:"round",draggable:P==="teacher"&&i==="cursor",onClick:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onTap:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onDragEnd:async b=>{const H=b.target,Q=H.x(),xe=H.y();H.x(0),H.y(0);const ht=t.points.map((Ye,mt)=>mt%2===0?Ye+Q:Ye+xe);h&&(await h(r.id,{...t,points:ht}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))}},r.id)}if(r.type==="highlighter"){const n=S===r.id;return e.jsx(tt,{id:r.id,points:t.points,stroke:n?"#3b82f6":t.color||"#facc15",strokeWidth:n?24:18,tension:.5,lineCap:"round",lineJoin:"round",opacity:.5,draggable:P==="teacher"&&i==="cursor",onClick:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onTap:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onDragEnd:async b=>{const H=b.target,Q=H.x(),xe=H.y();H.x(0),H.y(0);const ht=t.points.map((Ye,mt)=>mt%2===0?Ye+Q:Ye+xe);h&&(await h(r.id,{...t,points:ht}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))}},r.id)}if(r.type==="rectangle"||r.type==="shape"&&t.shape==="rect"){const n=S===r.id;return e.jsx(Ot,{id:r.id,x:t.x,y:t.y,width:t.width,height:t.height,fill:t.fill||"transparent",stroke:n?"#3b82f6":t.stroke||"blue",strokeWidth:n?3:1,draggable:P==="teacher"&&i==="cursor",onClick:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onTap:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onDragEnd:async b=>{const H=b.target,Q=H.x(),xe=H.y();H.x(0),H.y(0),h&&(await h(r.id,{...t,x:t.x+Q,y:t.y+xe}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))}},r.id)}if(r.type==="circle"||r.type==="shape"&&t.shape==="circle"){const n=S===r.id;return e.jsx(Lt,{id:r.id,x:t.x,y:t.y,radius:t.radius,fill:t.fill||"transparent",stroke:n?"#3b82f6":t.stroke||"green",strokeWidth:n?3:1,draggable:P==="teacher"&&i==="cursor",onClick:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onTap:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onDragEnd:async b=>{const H=b.target,Q=H.x(),xe=H.y();H.x(0),H.y(0),h&&(await h(r.id,{...t,x:t.x+Q,y:t.y+xe}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))}},r.id)}if(r.type==="text"){const n=S===r.id;return e.jsx(Bt,{id:r.id,x:t.x,y:t.y,text:t.text,fontSize:t.fontSize||16,fill:n?$.selectionBorder||"#3b82f6":t.color&&t.color!=="black"&&t.color!=="#000000"?t.color:X?"#f8fafc":t.color||"black",fontStyle:n?"bold":"normal",draggable:P==="teacher"&&i==="cursor",onClick:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onTap:b=>{i==="cursor"&&(b.cancelBubble=!0,O(n?null:r.id))},onDragEnd:async b=>{const H=b.target,Q=H.x(),xe=H.y();H.x(0),H.y(0),h&&(await h(r.id,{...t,x:t.x+Q,y:t.y+xe}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))}},r.id)}if(r.type==="code-sandbox")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"relative rounded-lg shadow-xl",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsx(ns,{elementId:r.id,data:t,onElementUpdate:h?async(n,b)=>{await h(n,b),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}:void 0,onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,onDelete:()=>ue(r.id)}),re()]})})},r.id);if(r.type==="math-graph")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"relative rounded-lg shadow-xl",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsx(is,{elementId:r.id,data:t,onElementUpdate:h?async(n,b)=>{await h(n,b),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}:void 0,onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,onDelete:()=>ue(r.id)}),re()]})})},r.id);if(r.type==="presentation")return e.jsx(Ce,{children:e.jsx(Pe,{divProps:{style:{position:"absolute",top:`${c}px`,left:`${d}px`,pointerEvents:"none",zIndex:ne?20:10}},children:e.jsxs("div",{onPointerDown:n=>{O(r.id),n.stopPropagation()},onContextMenu:n=>{n.preventDefault(),n.stopPropagation();const b=I.current?.getBoundingClientRect();b&&ee({x:n.clientX-b.left,y:n.clientY-b.top,elementId:r.id})},className:"bg-white border border-gray-305 rounded-lg shadow-xl overflow-hidden flex flex-col font-sans text-sm relative select-none",style:{pointerEvents:"auto",width:`${_}px`,height:`${U}px`},children:[e.jsxs("div",{className:"bg-purple-100 text-purple-700 px-3 py-1.5 flex justify-between items-center text-xs font-semibold border-b border-purple-200 cursor-move shrink-0",onPointerDown:n=>ve(n,r.id,t),onPointerMove:Ne,onPointerUp:ke,children:[e.jsx("span",{children:"Interactive Presentation"}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>Re(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-purple-600 hover:text-purple-900 transition-colors cursor-pointer flex items-center justify-center",title:"全屏",children:e.jsx(ze,{size:11})}),e.jsx("button",{onClick:async()=>{h&&(await h(r.id,{...t,isMinimized:!t.isMinimized}),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}))},onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-purple-650 hover:text-purple-900 transition-colors cursor-pointer flex items-center justify-center",title:t.isMinimized?"展开组件":"收起组件",children:t.isMinimized?e.jsx(ze,{size:11}):e.jsx(ft,{size:11})}),e.jsx("button",{onClick:()=>ue(r.id),onPointerDown:n=>n.stopPropagation(),className:"p-1 hover:bg-slate-200/50 rounded-full text-purple-600 hover:text-red-500 transition-colors cursor-pointer flex items-center justify-center",title:"删除组件",children:e.jsx(oe,{size:11})})]})]}),!t.isMinimized&&e.jsx("div",{className:"flex-1 min-h-0 relative bg-white",style:{pointerEvents:"auto"},children:e.jsx(ls,{elementId:r.id,data:t,userRole:P,onElementUpdate:h?async(n,b)=>{await h(n,b),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o})}:void 0})}),!t.isMinimized&&re()]})})},r.id)}catch(t){console.error(t)}return null},Tt=r=>{r.preventDefault(),r.dataTransfer.dropEffect="copy",Ee||be(!0)},$t=r=>{r.preventDefault(),r.dataTransfer.dropEffect="copy",be(!0)},zr=r=>{r.preventDefault(),r.currentTarget.contains(r.relatedTarget)||be(!1)},Et=(r,t,s,a)=>{const d={x:s,y:a,page:D,segmentId:l};switch(r){case"code-sandbox":return{...d,code:t.code??"console.log('Hello Sandbox!');"};case"math-graph":return{...d,equation:t.equation??"Math.sin(x)"};case"presentation":return{...d,markdown:t.markdown??`# Title Slide
|
|
77
|
+
---
|
|
78
|
+
## Slide 2`,width:600,height:400,slideX:0,slideY:0};case"quiz":return{...d,question:t.question??"New Quiz",options:Array.isArray(t.options)?t.options:["A","B","C","D"]};case"html-applet":return{...d,title:t.title??"",code:t.code??"",coursewareUuid:t.coursewareUuid??void 0,resourceId:t.resourceId??void 0};case"assignment":return{...d,title:t.title??"New Assignment",description:t.description??""};case"hello-world":return d;case"rollcall":return{...d,allStudents:[]};default:return{...d,...t}}},Sr=async(r,t)=>{if(!I.current)return;const s=I.current.getBoundingClientRect(),a=Math.round(s.width/2),d=Math.round(s.height/2);J(!0);try{await k(r,Et(r,t,a,d)),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f()}catch(c){console.error("addElementAtCenter error",c)}finally{J(!1)}};p.useImperativeHandle(Z,()=>({addElementAtCenter:Sr}));const Rt=async r=>{r.preventDefault(),r.stopPropagation();try{let t=r.dataTransfer.getData("application/json");if(t||(t=r.dataTransfer.getData("text/plain")),t||(t=r.dataTransfer.getData("text")),t||(t=r.dataTransfer.getData("Text")),console.log("Whiteboard drop triggered. Payload:",t),!t)return;let s;try{s=JSON.parse(t)}catch(m){console.error("Failed to parse drop JSON payload:",m);return}if(typeof s!="object"||!s)return;if(!I.current){console.warn("containerRef.current is not loaded on drop");return}const a=I.current.getBoundingClientRect();let d=r.clientX-a.left,c=r.clientY-a.top;console.log(`Adding whiteboard element of type ${s.type} at (${d}, ${c})`),J(!0);try{await k(s.type,Et(s.type,s,d,c)),B.publish({id:F(),type:"whiteboard.element_updated",source:"whiteboard",payload:{lessonId:o},timestamp:Date.now(),correlationId:o}),f&&f()}finally{J(!1)}}catch(t){console.error("Drop error",t)}};return e.jsxs("div",{className:"flex-1 flex flex-row min-h-0 overflow-hidden bg-app",children:[e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 bg-app relative min-w-0",onDragOver:Tt,onDragEnter:$t,onDrop:Rt,children:[e.jsx(cs,{tool:i,setTool:u,setSelectedShapeId:O,highlighterColor:C,setHighlighterColor:E,onElementAdd:k,currentPage:D,activeSegmentId:l,lessonId:o,safeElements:j,selectedShapeId:S,showGrid:he,setShowGrid:$e,userRole:P,isSyncing:Qe,setIsSyncing:J,handleClearBoard:yr,handleResetBoard:wr,handleElementDelete:ue,setDialog:pe,setDialogInput:Pt,onRefresh:f}),e.jsxs("div",{ref:I,className:"flex-1 rounded-2xl border border-theme relative overflow-hidden w-full mb-14 shadow-inner transition-colors",style:{backgroundImage:he?`radial-gradient(${$.gridDot} 1.2px, transparent 1.2px)`:"none",backgroundSize:"24px 24px",backgroundColor:$.background},onDragOver:Tt,onDragEnter:$t,onDragLeave:zr,onDrop:async r=>{be(!1),await Rt(r)},children:[Ee&&e.jsxs("div",{className:"absolute inset-0 border-2 border-dashed border-indigo-500 bg-indigo-500/10 backdrop-blur-[2px] rounded-2xl flex flex-col items-center justify-center text-indigo-600 font-bold text-sm z-30 animate-in fade-in pointer-events-none",children:[e.jsx(rt,{size:32,className:"mb-2 text-indigo-600 animate-bounce"}),e.jsx("span",{children:"释放鼠标将组件放入当前白板页面"})]}),j.filter(r=>{if(r.type==="page_meta")return!1;try{const t=JSON.parse(r.data),s=t.page??0,a=A[D];return!(!(t.pageId&&a?.id?t.pageId===a.id:s===D)||l&&t.segmentId&&t.segmentId!==l)}catch{return D===0}}).length===0&&!at&&e.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none select-none text-muted p-6 z-0",children:[e.jsx("div",{className:"w-16 h-16 rounded-2xl bg-primary-theme-light border border-theme flex items-center justify-center mb-3 shadow-2xs",children:e.jsx(yt,{className:"w-7 h-7 text-primary-theme animate-pulse"})}),e.jsx("p",{className:"font-bold text-sm text-main mb-1",children:"交互式备课白板"}),e.jsx("p",{className:"text-xs text-muted max-w-sm text-center",children:"从左侧组件库拖拽组件至此处,或使用顶部工具栏插入画笔、几何图形与 AI 助教"})]}),e.jsxs("div",{className:"absolute inset-0 w-full h-full overflow-hidden",style:{pointerEvents:Ee?"none":"auto"},children:[me.width>0&&me.height>0&&(at?(()=>{const r=j.find(a=>a.id===at);if(!r)return Re(null),null;let t={};try{t=JSON.parse(r.data)}catch{}const s={quiz:"📝 随堂测验",timer:"⏱ 计时器",assignment:"📋 作业","code-sandbox":"💻 代码沙箱","html-applet":"🌐 交互课件",rollcall:"🎲 随机点名",presentation:"📽 演示文稿","math-graph":"📐 数学图形",text:"📝 文本"};return e.jsx(Or,{type:r.type,title:s[r.type]||r.type,data:t,containerSize:me,onClose:()=>Re(null),lessonId:o})})():e.jsx(Mr,{width:me.width,height:me.height,onMouseDown:jr,onMousemove:vr,onMouseup:Nr,onContextMenu:r=>{r.evt.preventDefault();const t=I.current?.getBoundingClientRect();if(t){const s=r.evt.clientX-t.left,a=r.evt.clientY-t.top,c=r.target.id();c?(O(c),ee({x:s,y:a,elementId:c})):ee({x:s,y:a})}},ref:Ke,className:"w-full h-full cursor-crosshair",children:e.jsxs(Tr,{children:[j.filter(r=>{if(r.type==="page_meta")return!1;try{const t=JSON.parse(r.data),s=t.page??0,a=A[D];return!(!(t.pageId&&a?.id?t.pageId===a.id:s===D)||l&&t.segmentId&&t.segmentId!==l)}catch{return D===0}}).map(Pr),kr(),Cr()]})})),S&&(()=>{const r=j.find(d=>d.id===S);if(!r)return null;const t=gr(r);if(!t)return null;const s=Math.max(10,Math.min(me.width-150,t.x-60)),a=Math.max(10,Math.min(me.height-50,t.y));return e.jsxs("div",{style:{left:`${s}px`,top:`${a}px`,pointerEvents:"auto"},className:"absolute bg-white text-gray-800 shadow-xl border border-red-200 rounded-lg py-1 px-2 flex items-center gap-1.5 z-30 animate-in fade-in slide-in-from-bottom-2 duration-150 animate-out fade-out duration-100",children:[e.jsx("span",{className:"text-xs font-semibold px-1 text-gray-500 capitalize select-none",children:r.type}),e.jsx("div",{className:"w-[1px] h-3 bg-gray-200"}),e.jsxs("button",{onClick:()=>{ue(S),O(null)},className:"flex items-center gap-1 text-xs text-red-600 hover:text-white hover:bg-red-600 px-2 py-0.5 rounded transition-all font-medium cursor-pointer",children:[e.jsx(oe,{size:12}),"删除"]})]})})(),Xe&&e.jsx("div",{style:{left:`${Xe.x}px`,top:`${Xe.y}px`,pointerEvents:"auto"},className:"absolute bg-surface rounded-lg shadow-2xl border border-theme py-1.5 w-44 z-40 font-sans text-sm animate-in fade-in zoom-in-95 duration-100 text-main",onClick:r=>r.stopPropagation(),onContextMenu:r=>r.preventDefault(),children:Xe.elementId?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"px-3 py-1 text-[11px] text-muted font-bold uppercase tracking-wider select-none",children:"组件选项"}),e.jsxs("button",{onClick:()=>{const r=Xe.elementId;r&&(ue(r),S===r&&O(null)),ee(null)},className:"w-full px-3 py-1.5 flex items-center gap-2 text-left text-rose-500 hover:bg-rose-500/10 transition-colors text-xs font-semibold cursor-pointer",children:[e.jsx(oe,{size:14}),"删除此组件"]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"px-3 py-1 text-[11px] text-muted font-bold uppercase tracking-wider select-none",children:"白板操作"}),e.jsxs("button",{onClick:()=>{u("cursor"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="cursor"?"text-primary-theme":"text-main"}`,children:[e.jsx(Jt,{size:14}),"选择工具 (Cursor)"]}),e.jsxs("button",{onClick:()=>{u("pen"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="pen"?"text-primary-theme":"text-main"}`,children:[e.jsx(qt,{size:14}),"画笔工具 (Pen)"]}),e.jsxs("button",{onClick:()=>{u("highlighter"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="highlighter"?"text-primary-theme":"text-main"}`,children:[e.jsx(Ut,{size:14}),"高亮荧光笔 (Highlighter)"]}),e.jsxs("button",{onClick:()=>{u("rect"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="rect"?"text-primary-theme":"text-main"}`,children:[e.jsx(Gt,{size:14}),"矩形工具 (Rectangle)"]}),e.jsxs("button",{onClick:()=>{u("circle"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="circle"?"text-primary-theme":"text-main"}`,children:[e.jsx(Kt,{size:14}),"圆形工具 (Circle)"]}),e.jsxs("button",{onClick:()=>{u("text"),ee(null)},className:`w-full px-3 py-1.5 flex items-center gap-2 text-left text-xs font-medium hover:bg-surface-secondary transition-colors cursor-pointer ${i==="text"?"text-primary-theme":"text-main"}`,children:[e.jsx(Qt,{size:14}),"文本工具 (Text)"]})]})})]})]}),e.jsx(ds,{pages:A,currentPage:D,showPageDrawer:le,setShowPageDrawer:K,editingPageIdx:we,setEditingPageIdx:se,editingPageTitle:je,setEditingPageTitle:Le,activeMenuPageIdx:nt,setActiveMenuPageIdx:Ue,safeElements:j,handleSwitchPage:Be,handleRenamePage:jt,handleDuplicatePage:Ge,handleMovePage:g,handleDeletePage:it,handleAddPage:ot}),e.jsx(us,{dialog:tr,dialogInput:rr,setDialogInput:Pt,setDialog:pe}),e.jsx(xs,{showEntrySelector:ur,setShowEntrySelector:St,zipUploadInfo:cr,zipCandidates:ar,handlePropsUpdate:Te,fetchCoursewares:xt})]}),L&&S&&M&&(()=>{const r=j.find(t=>t.id===S);return r?e.jsxs("div",{className:"w-80 h-full max-h-full bg-surface border-l border-theme flex flex-col font-sans text-xs select-none shadow-xl shrink-0 z-20 animate-in slide-in-from-right duration-200 text-main",onPointerDown:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"px-4 py-3 border-b border-theme bg-surface-secondary flex justify-between items-center shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Gr,{size:15,className:"text-muted animate-spin",style:{animationDuration:"6s"}}),e.jsx("span",{className:"font-bold text-main text-sm",children:"属性编辑器"})]}),e.jsxs("div",{className:"flex items-center gap-1.5 font-sans",children:[e.jsxs("button",{onClick:xr,disabled:(_e[S]||[]).length===0,className:`p-1 rounded-lg transition-all flex items-center justify-center gap-1 border border-transparent select-none cursor-pointer ${(_e[S]||[]).length===0?"text-subtle bg-transparent border-transparent opacity-40 cursor-not-allowed":"text-main bg-surface hover:bg-surface-secondary hover:border-theme active:bg-surface-secondary"}`,title:"撤销属性修改",children:[e.jsx(Kr,{size:13}),(_e[S]||[]).length>0&&e.jsx("span",{className:"text-[10px] font-bold text-muted",children:(_e[S]||[]).length})]}),e.jsxs("button",{onClick:pr,disabled:(He[S]||[]).length===0,className:`p-1 rounded-lg transition-all flex items-center justify-center gap-1 border border-transparent select-none cursor-pointer ${(He[S]||[]).length===0?"text-subtle bg-transparent border-transparent opacity-40 cursor-not-allowed":"text-main bg-surface hover:bg-surface-secondary hover:border-theme active:bg-surface-secondary"}`,title:"重做属性修改",children:[e.jsx(Qr,{size:13}),(He[S]||[]).length>0&&e.jsx("span",{className:"text-[10px] font-bold text-muted",children:(He[S]||[]).length})]}),e.jsx("div",{className:"h-4 w-px bg-border-theme mx-0.5 shrink-0"}),e.jsx("button",{onClick:()=>O(null),className:"text-muted hover:text-main hover:bg-surface-secondary p-1 rounded-full transition-all cursor-pointer",title:"关闭属性编辑器",children:e.jsx(Zt,{size:15})})]})]}),e.jsxs("div",{className:"flex-1 overflow-y-auto p-4 space-y-4",children:[e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-muted text-[10px] font-bold uppercase tracking-wider",children:"组件类型"}),e.jsx("span",{className:"px-2 py-0.5 bg-primary-theme-light text-primary-theme rounded text-[10px] font-bold uppercase tracking-wider",children:r.type})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-muted text-[10px] font-bold uppercase tracking-wider",children:"组件标识"}),e.jsx("span",{className:"font-mono text-muted text-[10px] truncate max-w-[155px]",title:r.id,children:r.id})]})]}),e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5 flex items-center gap-1.5",children:"物理定位 & 尺寸"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"X 坐标"}),e.jsx("input",{type:"number",value:Math.round(M.x??0),onChange:t=>V("x",parseFloat(t.target.value)||0),onBlur:t=>Oe("x",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"Y 坐标"}),e.jsx("input",{type:"number",value:Math.round(M.y??0),onChange:t=>V("y",parseFloat(t.target.value)||0),onBlur:t=>Oe("y",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]})]}),r.type!=="pen"&&r.type!=="circle"&&e.jsxs("div",{className:"grid grid-cols-2 gap-2 mt-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"宽度 (Width)"}),e.jsx("input",{type:"number",min:"50",value:Math.round(M.width??300),onChange:t=>V("width",parseFloat(t.target.value)||50),onBlur:t=>Oe("width",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"高度 (Height)"}),e.jsx("input",{type:"number",min:"50",value:Math.round(M.height??300),onChange:t=>V("height",parseFloat(t.target.value)||50),onBlur:t=>Oe("height",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]})]}),r.type==="circle"&&e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"半径 (Radius)"}),e.jsx("input",{type:"number",min:"5",value:Math.round(M.radius??50),onChange:t=>V("radius",parseFloat(t.target.value)||5),onBlur:t=>Oe("radius",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]})]}),(()=>{const t=Lr.get(r.type);return t?e.jsx(t,{elementId:r.id,elementType:r.type,data:M,updateData:Te,lessonId:o,onClose:()=>O(null)}):null})(),r.type==="quiz"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"随堂测验配置"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"测验题目 (Question)"}),e.jsx("textarea",{value:M.question||"",onChange:t=>V("question",t.target.value),onBlur:t=>de("question",t.target.value),className:"w-full h-20 p-2 border border-theme rounded-lg text-xs focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main resize-none font-medium leading-relaxed",placeholder:"编写问题描述..."})]}),(M.options||[]).length>0&&e.jsxs("div",{className:"bg-amber-500/10 border border-amber-500/30 rounded-lg p-2.5",children:[e.jsx("label",{className:"block text-[10px] text-amber-500 font-bold mb-1.5",children:"⚠️ 正确答案 (Correct Answer)"}),e.jsxs("select",{value:M.correctAnswer||"",onChange:t=>{V("correctAnswer",t.target.value),de("correctAnswer",t.target.value)},className:`w-full px-2 py-1.5 border rounded-lg text-xs font-medium focus:outline-none focus:ring-1 focus:ring-amber-500 cursor-pointer ${M.correctAnswer?"border-green-500/40 bg-green-500/10 text-green-600":"border-amber-500/40 bg-surface text-main"}`,children:[e.jsx("option",{value:"",children:"-- 请选择正确答案 --"}),(M.options||[]).map((t,s)=>e.jsx("option",{value:t,children:t},s))]}),!M.correctAnswer&&e.jsx("p",{className:"text-[9px] text-amber-500 mt-1",children:"未设置正确答案将无法自动判分"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold",children:"选项列表 (Options)"}),e.jsx("div",{className:"space-y-1.5 max-h-48 overflow-y-auto pr-1",children:(M.options||[]).map((t,s)=>{const d="ABCDEFGHIJKLMNOPQRSTUVWXYZ"[s]||s+1;return e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"font-bold text-main bg-surface-secondary rounded px-1.5 py-1 text-center shrink-0 min-w-[22px]",children:d}),e.jsx("input",{type:"text",value:t||"",onChange:c=>hr(s,c.target.value),onBlur:c=>mr(s,c.target.value),className:"flex-1 px-2 py-1 border border-theme rounded-lg text-xs font-medium bg-surface text-main"}),e.jsx("button",{onClick:()=>br(s),title:"删除选项",className:"text-muted hover:text-rose-500 hover:bg-rose-500/10 p-1 rounded-md shrink-0 transition-colors cursor-pointer",children:e.jsx(oe,{size:13})})]},s)})}),e.jsxs("button",{onClick:fr,className:"w-full mt-2 py-1 bg-surface-secondary hover:bg-surface-secondary text-main font-bold border border-theme rounded-lg flex items-center justify-center gap-1 transition-all text-[11px] cursor-pointer",children:[e.jsx(rt,{size:12})," 添加选项"]})]})]}),r.type==="assignment"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"作业选项配置"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"作业任务标题 (Title)"}),e.jsx("input",{type:"text",value:M.title||"",onChange:t=>V("title",t.target.value),onBlur:t=>de("title",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-semibold focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main",placeholder:"作业名..."})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"详细作业要求描述"}),e.jsx("textarea",{value:M.description||"",onChange:t=>V("description",t.target.value),onBlur:t=>de("description",t.target.value),className:"w-full h-24 p-2 border border-theme rounded-lg text-xs focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main resize-none font-medium leading-relaxed",placeholder:"请输入详细的作业指南..."})]})]}),(r.type==="code-sandbox"||r.type==="html-applet")&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsxs("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5 flex justify-between items-center",children:[e.jsx("span",{children:"动态运行代码定制"}),r.type==="html-applet"&&e.jsx("span",{className:"text-[10px] bg-primary-theme-light text-primary-theme px-1.5 py-0.5 rounded-full font-bold",children:"HTML Applet"})]}),r.type==="html-applet"&&e.jsxs("div",{className:"space-y-3 border-b border-theme pb-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-primary-theme font-bold mb-1",children:"选择 AI 互动课件 (ZIP/HTML):"}),e.jsxs("select",{value:M.coursewareUuid||"",onChange:t=>{const s=t.target.value;Te({coursewareUuid:s,resourceId:""})},className:"w-full text-xs p-2 bg-surface-secondary border border-theme hover:border-primary-theme rounded-lg text-main focus:outline-none focus:ring-1 focus:ring-primary-theme transition-all font-semibold",children:[e.jsx("option",{value:"",children:"-- 使用系统资源或自定义代码 --"}),or.map(t=>e.jsxs("option",{value:t.uuid,children:["📁 [互动课件] ",t.name]},t.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-bold mb-1",children:"选择已有的系统资源:"}),e.jsxs("select",{value:M.resourceId||"",onChange:t=>{const s=t.target.value;Te({resourceId:s,coursewareUuid:""})},className:"w-full text-xs p-2 bg-surface-secondary border border-theme hover:border-primary-theme rounded-lg text-main focus:outline-none focus:ring-1 focus:ring-primary-theme transition-all font-semibold",children:[e.jsx("option",{value:"",children:"-- 使用互动课件或自定义代码 --"}),sr.map(t=>e.jsxs("option",{value:t.id,children:["[",t.type==="folder"?"文件夹":"单HTML","] ",t.name]},t.id))]})]}),e.jsxs("div",{className:"bg-surface-secondary p-2.5 rounded-xl border border-theme text-[10px] text-muted space-y-2",children:[e.jsx("span",{className:"font-bold text-main block",children:"上传资源 (会自动保存到对应库):"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("label",{className:"col-span-2 flex flex-col items-center justify-center p-2 bg-indigo-50 hover:bg-indigo-100 border border-indigo-200 hover:border-indigo-300 rounded-lg cursor-pointer text-center transition-all",children:[e.jsx("span",{className:"font-bold text-indigo-700 text-[10px]",children:"✨ 上传 AI 互动课件 (.zip/.html)"}),e.jsx("input",{type:"file",accept:".zip,.html,.htm",className:"hidden",onChange:async t=>{const s=t.target.files?.[0];if(!s)return;const a=new FileReader;a.onload=async d=>{const c=d.target?.result;try{const m=await fetch("/api/courseware/upload",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.name.replace(/\.[^/.]+$/,""),filename:s.name,base64Data:c})});if(m.ok){const z=await m.json();z.need_select_entry?(lr(z.candidates),dr({uuid:z.uuid,name:z.name}),St(!0)):(Te({coursewareUuid:z.uuid,resourceId:""}),xt())}else{const z=await m.json();alert("上传失败: "+(z.error||m.statusText))}}catch(m){console.error("Courseware upload failed:",m)}},a.readAsDataURL(s)}})]}),e.jsxs("label",{className:"flex flex-col items-center justify-center p-2 bg-white hover:bg-slate-100 border border-slate-200 hover:border-slate-300 rounded-lg cursor-pointer text-center transition-all",children:[e.jsx("span",{className:"font-bold text-slate-600 text-[10px]",children:"📄 上传系统HTML文件"}),e.jsx("input",{type:"file",accept:".html,.htm",className:"hidden",onChange:async t=>{const s=t.target.files?.[0];if(!s)return;const a=new FileReader;a.onload=async d=>{const c=d.target?.result;try{const m=await fetch("/api/resources",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.name,type:"html",content:c})});if(m.ok){const z=await m.json();Te({resourceId:z.id,coursewareUuid:""}),pt()}}catch(m){console.error("Upload failed:",m)}},a.readAsText(s)}})]}),e.jsxs("label",{className:"flex flex-col items-center justify-center p-2 bg-white hover:bg-slate-100 border border-slate-200 hover:border-slate-300 rounded-lg cursor-pointer text-center transition-all",children:[e.jsx("span",{className:"font-bold text-slate-600 text-[10px]",children:"📁 上传系统文件夹"}),e.jsx("input",{type:"file",webkitdirectory:"",directory:"",multiple:!0,className:"hidden",onChange:async t=>{const s=t.target.files;if(!s||s.length===0)return;const a=[];let d="";for(let c=0;c<s.length;c++){const m=s[c],z=m.webkitRelativePath||m.name;d||(d=z.split("/")[0]||"uploaded_resource");const _=m.name.split(".").pop()?.toLowerCase(),U=["png","jpg","jpeg","gif","webp","ico"].includes(_||"");await new Promise(ne=>{const re=new FileReader;re.onload=n=>{const b=n.target?.result;a.push({path:z,content:b}),ne()},U?re.readAsDataURL(m):re.readAsText(m)})}try{const c=await fetch("/api/resources",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:d,type:"folder",content:JSON.stringify(a)})});if(c.ok){const m=await c.json();Te({resourceId:m.id,coursewareUuid:""}),pt()}}catch(c){console.error("Folder upload failed:",c)}}})]})]})]})]}),(!M.resourceId&&!M.coursewareUuid||r.type==="code-sandbox")&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-slate-400 font-semibold mb-1",children:"沙箱程序代码 (Source Code)"}),e.jsx("textarea",{value:M.code||"",onChange:t=>V("code",t.target.value),onBlur:t=>de("code",t.target.value),className:"w-full h-48 p-3 border border-slate-300 rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-indigo-500 bg-slate-900 text-slate-100 resize-none leading-relaxed",placeholder:"// 编写交互沙箱代码..."})]})]}),r.type==="math-graph"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"函数解析拟合"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"函数表达式 y = f(x)"}),e.jsx("input",{type:"text",value:M.equation||"",onChange:t=>V("equation",t.target.value),onBlur:t=>de("equation",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"}),e.jsxs("p",{className:"text-[10px] text-muted mt-1 leading-snug",children:["支持标准 JS 表达式。 示例:",e.jsx("br",{}),"• ",e.jsx("code",{className:"bg-surface-secondary px-1 rounded",children:"Math.sin(x)"})," 正负弦波形",e.jsx("br",{}),"• ",e.jsx("code",{className:"bg-surface-secondary px-1 rounded",children:"Math.cos(x) * x"})," 振幅衰减"]})]})]}),r.type==="presentation"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"幻灯片 Markdown 文案"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"Markdown 源代码"}),e.jsx("textarea",{value:M.markdown||"",onChange:t=>V("markdown",t.target.value),onBlur:t=>de("markdown",t.target.value),className:"w-full h-64 p-2.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme resize-none font-medium leading-relaxed bg-surface text-main",placeholder:"修改 Markdown 内容..."})]})]}),r.type==="text"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"文字属性管理"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"文本内容"}),e.jsx("input",{type:"text",value:M.text||"",onChange:t=>V("text",t.target.value),onBlur:t=>de("text",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-medium focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"文字大小 (FontSize)"}),e.jsx("input",{type:"number",min:"10",max:"100",value:M.fontSize||16,onChange:t=>V("fontSize",parseInt(t.target.value)||10),onBlur:t=>Oe("fontSize",t.target.value),className:"w-full px-2 py-1.5 border border-theme rounded-lg text-xs font-mono focus:outline-none focus:ring-1 focus:ring-primary-theme bg-surface text-main"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"文字填充颜色"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:M.color||"#000000",onChange:t=>V("color",t.target.value),onBlur:t=>de("color",t.target.value),className:"w-8 h-8 rounded border border-theme cursor-pointer shrink-0 bg-surface"}),e.jsx("span",{className:"font-mono text-[11px] text-muted",children:M.color||"#000000"})]})]})]}),(r.type==="rectangle"||r.type==="shape")&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"矩形样式配置"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"外边框颜色"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:M.stroke||"#000000",onChange:t=>V("stroke",t.target.value),onBlur:t=>de("stroke",t.target.value),className:"w-8 h-8 rounded border border-theme cursor-pointer shrink-0 bg-surface"}),e.jsx("span",{className:"font-mono text-[11px] text-muted",children:M.stroke||"#000000"})]})]})]}),r.type==="circle"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"圆形样式配置"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"外边框颜色"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:M.stroke||"#000000",onChange:t=>V("stroke",t.target.value),onBlur:t=>de("stroke",t.target.value),className:"w-8 h-8 rounded border border-theme cursor-pointer shrink-0 bg-surface"}),e.jsx("span",{className:"font-mono text-[11px] text-muted",children:M.stroke||"#000000"})]})]})]}),r.type==="pen"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"线条样式配置"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"折线颜色"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:M.color||"#000000",onChange:t=>V("color",t.target.value),onBlur:t=>de("color",t.target.value),className:"w-8 h-8 rounded border border-theme cursor-pointer shrink-0 bg-surface"}),e.jsx("span",{className:"font-mono text-[11px] text-muted",children:M.color||"#000000"})]})]})]}),r.type==="highlighter"&&e.jsxs("div",{className:"bg-surface p-3 rounded-xl border border-theme shadow-sm space-y-3",children:[e.jsx("h4",{className:"font-bold text-main text-xs border-b border-theme pb-1.5",children:"高亮荧光标记 (Highlighter)"}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] text-muted font-semibold mb-1",children:"荧光笔颜色"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"color",value:M.color||"#facc15",onChange:t=>V("color",t.target.value),onBlur:t=>de("color",t.target.value),className:"w-8 h-8 rounded border border-theme cursor-pointer shrink-0 bg-surface"}),e.jsx("span",{className:"font-mono text-[11px] text-muted",children:M.color||"#facc15"})]})]})]}),e.jsx("div",{className:"text-[10px] text-muted text-center select-none pt-2 font-medium",children:"提示:属性在失焦或修改时自动同步,多端可见。"})]}),e.jsxs("div",{className:"p-3 border-t border-slate-200 bg-white flex flex-col gap-2 shrink-0",children:[e.jsx("button",{onClick:()=>Me(M),disabled:Qe,className:"w-full py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-bold transition-all shadow-sm hover:shadow active:scale-[0.98] cursor-pointer flex items-center justify-center gap-1.5 text-xs",children:Qe?e.jsxs(e.Fragment,{children:[e.jsx(st,{size:13,className:"animate-spin"}),"正在广播同步..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Zr,{size:13}),"应用修改并强制同步"]})}),e.jsxs("button",{onClick:()=>{ue(S),O(null)},className:"w-full py-2 bg-red-50 hover:bg-red-105 text-red-650 rounded-lg font-semibold transition-all flex items-center justify-center gap-1.5 border border-red-200 cursor-pointer text-xs",children:[e.jsx(oe,{size:13}),"删除当前组件"]})]})]}):null})()]})});export{ps as DEFAULT_WHITEBOARD_PAGES,Ts as InteractiveWhiteboard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as a}from"./vendor-pdf-
|
|
1
|
+
import{_ as a}from"./vendor-pdf-Cp-cYteE.js";import{j as e,r as s}from"./vendor-react-0Lg0vA-4.js";const t=s.lazy(()=>a(()=>import("./index-C8sCKzmN.js"),[]).then(r=>({default:r.CoursewareViewer})));function n(r){return e.jsx(s.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(t,{...r})})}export{n as L};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-
|
|
2
|
-
import{_ as s}from"./vendor-pdf-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-B-YxO39A.css","assets/vendor-reveal-DcQQzuI9.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as s}from"./vendor-pdf-Cp-cYteE.js";import{r as t,j as e}from"./vendor-react-0Lg0vA-4.js";const i=t.lazy(()=>s(()=>import("./InteractiveWhiteboard-U23CsqGo.js"),__vite__mapDeps([0,1])).then(r=>({default:r.InteractiveWhiteboard}))),n=t.forwardRef((r,a)=>e.jsx(t.Suspense,{fallback:e.jsx("div",{className:"flex items-center justify-center h-full bg-gray-50",children:e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-500"})}),children:e.jsx(i,{ref:a,...r})}));export{n as L};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,r as C,R as ee}from"./vendor-react-0Lg0vA-4.js";import{C as E,P as te,b as re,a as se,c as Z}from"./index-CYzNsYZB.js";import{L as ae}from"./LazyWhiteboard-CtkzSFtN.js";import{ar as Q,ay as oe,al as ne,X as J,x as L,f as le,a9 as H,b as ie,a1 as ce,r as de,az as xe,O as he,o as F,aA as pe,aB as me,I as S,ag as ue,aj as be,T as fe,W as ge,w as ye,q as je,E as Ne,at as ve,j as we,ac as ze}from"./vendor-icons-Dq6MhgH9.js";import"./vendor-pdf-Cp-cYteE.js";import"./vendor-utils-BEhuP0Zq.js";import"./vendor-motion-DjY2czvL.js";import"./vendor-pptx-B_NheIKl.js";import"./vendor-charts-CRXa4AlU.js";function B({config:r,lang:o,onActivate:d,isFavorite:b=!1,onToggleFavorite:s}){const p=r.icon,x=E[r.color]||E.indigo;return e.jsxs("div",{draggable:!0,onDragStart:m=>{const c={type:r.type,...r.defaultData},y=JSON.stringify(c);m.dataTransfer.effectAllowed="copy",m.dataTransfer.setData("application/json",y),m.dataTransfer.setData("text/plain",y)},onClick:()=>d(r.type),title:o==="zh"?"点击编辑并添加到画板,或拖拽到画板":"Click to edit & add, or drag onto the board",className:`group relative bg-surface border border-theme rounded-xl p-2.5 shadow-sm transition-all duration-200 cursor-grab active:cursor-grabbing hover:shadow-md hover:-translate-y-0.5 ${x.cardHoverBorder} ${x.cardHoverRing} ${x.cardHoverShadow} flex flex-col justify-between min-h-[92px]`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-1",children:[e.jsx("div",{className:`p-2 rounded-lg ${x.iconBg} ${x.iconText} transition-transform group-hover:scale-105 shrink-0`,children:e.jsx(p,{size:16})}),s&&e.jsx("button",{type:"button",onClick:m=>{m.stopPropagation(),s(r.type,m)},className:`p-1 rounded-md transition-colors ${b?"text-amber-400 opacity-100":"text-slate-300 opacity-0 group-hover:opacity-100 hover:text-amber-400 hover:bg-surface-secondary"}`,title:b?o==="zh"?"取消收藏":"Remove favorite":o==="zh"?"收藏组件":"Add favorite",children:e.jsx(Q,{size:13,className:b?"fill-amber-400":""})})]}),e.jsxs("div",{className:"flex flex-col min-w-0 mt-1.5",children:[e.jsx("span",{className:"font-semibold text-xs text-main truncate group-hover:text-primary-theme transition-colors",children:o==="zh"?r.labelZh:r.labelEn}),e.jsx("span",{className:"text-[10px] text-muted leading-tight mt-0.5 truncate",children:o==="zh"?r.descriptionZh:r.descriptionEn})]}),e.jsx("div",{className:"absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none",children:e.jsx("span",{className:"text-[9px] font-bold text-indigo-500 bg-indigo-50 px-1 py-0.5 rounded border border-indigo-100",children:"+ Drag"})})]})}function ke({lang:r,onActivate:o}){const[d,b]=C.useState(""),[s,p]=C.useState("all"),[x,m]=C.useState(()=>{try{const t=localStorage.getItem("openlearn_palette_favs");return t?JSON.parse(t):[]}catch{return[]}}),[c,y]=C.useState(()=>{try{const t=localStorage.getItem("openlearn_palette_recent");return t?JSON.parse(t):[]}catch{return[]}}),[u,w]=C.useState({}),z=t=>{y(n=>{const h=[t,...n.filter(j=>j!==t)].slice(0,6);try{localStorage.setItem("openlearn_palette_recent",JSON.stringify(h))}catch{}return h}),o(t)},k=(t,n)=>{n.stopPropagation(),m(h=>{const f=h.includes(t)?h.filter($=>$!==t):[...h,t];try{localStorage.setItem("openlearn_palette_favs",JSON.stringify(f))}catch{}return f})},l=t=>{w(n=>({...n,[t]:!n[t]}))},a=te.filter(t=>{if(d.trim()){const n=d.toLowerCase(),h=t.labelZh.toLowerCase().includes(n)||t.descriptionZh.toLowerCase().includes(n),j=t.labelEn.toLowerCase().includes(n)||t.descriptionEn.toLowerCase().includes(n);if(!h&&!j)return!1}return s==="favorites"?x.includes(t.type):s==="recent"?c.includes(t.type):!0});return e.jsxs("div",{className:"w-[240px] shrink-0 border-r border-theme bg-surface-secondary/70 p-3 overflow-y-auto flex flex-col gap-3 font-sans select-none text-main",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("h3",{className:"flex items-center gap-1.5 text-xs font-bold text-main uppercase tracking-wider",children:[e.jsx(oe,{size:15,className:"text-primary-theme"}),r==="zh"?"备课画板组件":"Components"]}),e.jsx("span",{className:"text-[10px] font-semibold text-muted bg-surface border border-theme px-1.5 py-0.5 rounded-full",children:a.length})]}),e.jsx("p",{className:"text-[10px] text-muted leading-tight mt-0.5",children:r==="zh"?"拖拽到右侧白板,或点击配置添加到画板。":"Drag to whiteboard or click to configure."})]}),e.jsxs("div",{className:"relative",children:[e.jsx(ne,{size:13,className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-muted"}),e.jsx("input",{type:"text",value:d,onChange:t=>b(t.target.value),placeholder:r==="zh"?"搜索画板组件...":"Search components...",className:"w-full pl-8 pr-7 py-1.5 bg-surface border border-theme rounded-lg text-xs text-main placeholder-muted focus:outline-none focus:ring-1 focus:ring-primary-theme transition-all shadow-2xs"}),d&&e.jsx("button",{onClick:()=>b(""),className:"absolute right-2 top-1/2 -translate-y-1/2 text-muted hover:text-main",children:e.jsx(J,{size:12})})]}),e.jsxs("div",{className:"flex items-center gap-1 bg-surface-secondary border border-theme p-1 rounded-lg",children:[e.jsx("button",{onClick:()=>p("all"),className:`flex-1 py-1 text-[11px] font-medium rounded-md transition-all ${s==="all"?"bg-surface text-main shadow-2xs font-bold":"text-muted hover:text-main"}`,children:r==="zh"?"全部":"All"}),e.jsxs("button",{onClick:()=>p("favorites"),className:`flex-1 py-1 text-[11px] font-medium rounded-md transition-all flex items-center justify-center gap-1 ${s==="favorites"?"bg-surface text-amber-500 shadow-2xs font-bold":"text-muted hover:text-amber-500"}`,children:[e.jsx(Q,{size:11,className:s==="favorites"?"fill-amber-500":""}),e.jsx("span",{children:r==="zh"?"收藏":"Favs"})]}),e.jsxs("button",{onClick:()=>p("recent"),className:`flex-1 py-1 text-[11px] font-medium rounded-md transition-all flex items-center justify-center gap-1 ${s==="recent"?"bg-surface text-primary-theme shadow-2xs font-bold":"text-muted hover:text-primary-theme"}`,children:[e.jsx(L,{size:11}),e.jsx("span",{children:r==="zh"?"最近":"Recent"})]})]}),e.jsx("div",{className:"flex-1 flex flex-col gap-3 overflow-y-auto pr-0.5",children:a.length===0?e.jsxs("div",{className:"text-center py-8 text-slate-400 text-xs",children:[e.jsx(le,{size:24,className:"mx-auto mb-2 opacity-30 text-indigo-500"}),e.jsx("p",{className:"font-medium text-slate-500",children:r==="zh"?"未找到相关组件":"No components found"}),e.jsx("p",{className:"text-[10px] mt-1 text-slate-400",children:s!=="all"?r==="zh"?"尝试切换到全部组件":"Try switching to All tab":r==="zh"?"更换搜索关键词":"Try a different search term"})]}):s!=="all"||d.trim()?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:a.map(t=>e.jsx(B,{config:t,lang:r,onActivate:z,isFavorite:x.includes(t.type),onToggleFavorite:k},t.type))}):re.map(t=>{const n=a.filter(f=>f.group===t.id);if(n.length===0)return null;const h=E[n[0].color]||E.indigo,j=u[t.id];return e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("button",{type:"button",onClick:()=>l(t.id),className:"flex items-center justify-between px-1 py-0.5 text-left group/grp cursor-pointer hover:bg-slate-200/40 rounded transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${h.groupAccent}`}),e.jsx("span",{className:`text-[10px] font-bold uppercase tracking-wider ${h.groupText}`,children:r==="zh"?t.labelZh:t.labelEn})]}),e.jsxs("div",{className:"flex items-center gap-1 text-slate-400 group-hover/grp:text-slate-600",children:[e.jsxs("span",{className:"text-[9px] font-mono font-medium opacity-70",children:["(",n.length,")"]}),j?e.jsx(H,{size:12}):e.jsx(ie,{size:12})]})]}),!j&&e.jsx("div",{className:"grid grid-cols-2 gap-2",children:n.map(f=>e.jsx(B,{config:f,lang:r,onActivate:z,isFavorite:x.includes(f.type),onToggleFavorite:k},f.type))})]},t.id)})})]})}const M=[{id:"intro",labelZh:"准备环节",labelEn:"Intro",icon:ce},{id:"lecture",labelZh:"讲授新课",labelEn:"Lecture",icon:de},{id:"practice",labelZh:"互动练习",labelEn:"Practice",icon:xe},{id:"quiz",labelZh:"随堂测试",labelEn:"Quiz",icon:he},{id:"summary",labelZh:"要点总结",labelEn:"Summary",icon:F}],O=[{name:"Blue",color:"bg-blue-50 text-blue-700 border-blue-200 hover:bg-blue-100",solid:"bg-blue-500 text-white border-blue-500 shadow-md ring-2 ring-blue-200",rail:"bg-blue-400"},{name:"Indigo",color:"bg-indigo-50 text-indigo-700 border-indigo-200 hover:bg-indigo-100",solid:"bg-indigo-500 text-white border-indigo-500 shadow-md ring-2 ring-indigo-200",rail:"bg-indigo-400"},{name:"Green",color:"bg-green-50 text-green-700 border-green-200 hover:bg-green-100",solid:"bg-green-500 text-white border-green-500 shadow-md ring-2 ring-green-200",rail:"bg-green-400"},{name:"Purple",color:"bg-purple-50 text-purple-700 border-purple-200 hover:bg-purple-100",solid:"bg-purple-500 text-white border-purple-500 shadow-md ring-2 ring-purple-200",rail:"bg-purple-400"},{name:"Amber",color:"bg-amber-50 text-amber-700 border-amber-200 hover:bg-amber-100",solid:"bg-amber-500 text-white border-amber-500 shadow-md ring-2 ring-amber-200",rail:"bg-amber-400"}],Ce=O[1].color;function $e(r){return M.find(o=>o.id===r)||M[1]}function G(r){return O.find(o=>o.color===r)||O[1]}function Te({lang:r,segments:o,activeSegmentId:d,setActiveSegmentId:b,draggedSegmentIdx:s,setDraggedSegmentIdx:p,selectedLesson:x,saveTimeline:m,editorPanelsExpanded:c,setEditorPanelsExpanded:y}){const u=o.findIndex(a=>a.id===d),w=o.length>1&&u>=0?u/(o.length-1):0,z=u>=0?G(o[u].color):null,k=a=>{if(s===null||s===a){p(null);return}const t=[...o],[n]=t.splice(s,1);t.splice(a,0,n),p(null),x&&m(x,t)},l=()=>{if(!x)return;const a="seg-"+Math.random().toString(36).slice(2,9),t={id:a,title:r==="zh"?`新环节 ${o.length+1}`:`Segment ${o.length+1}`,notes:"",type:"lecture",duration:"10m",color:Ce};m(x,[...o,t]),b(a)};return e.jsxs("div",{className:"relative flex items-center gap-3 px-3 py-1.5 border-b border-slate-200/80 bg-slate-50/70 shrink-0 overflow-x-auto select-none",children:[e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0 pl-1 border-r border-slate-200/80 pr-2.5",children:[e.jsx(pe,{size:15,className:"text-indigo-600 shrink-0"}),e.jsx("span",{className:"text-xs font-extrabold uppercase tracking-wider text-slate-600 whitespace-nowrap",children:r==="zh"?"教学流程":"Lesson Flow"})]}),e.jsxs("div",{className:"relative flex items-center gap-1.5 py-0.5 min-w-0 flex-1",children:[e.jsx("div",{className:"absolute left-2 right-2 top-1/2 h-0.5 -translate-y-1/2 bg-slate-200 rounded-full"}),u>=0&&e.jsx("div",{className:`absolute left-2 top-1/2 h-0.5 -translate-y-1/2 rounded-full transition-all duration-300 ${z?.rail||"bg-indigo-500"}`,style:{width:`calc(${w*100}% - 0.5rem)`}}),o.map((a,t)=>{const n=a.id===d,h=u>=0&&t<u,j=s===t,f=$e(a.type),$=G(a.color),D=f.icon,_=n?$.solid+" shadow-md shadow-indigo-500/20 ring-2 ring-indigo-400/30":h?"bg-slate-100 border-slate-300 text-slate-700 hover:bg-slate-200/80":`${a.color} hover:shadow-sm hover:brightness-105`;return e.jsxs(ee.Fragment,{children:[e.jsxs("button",{draggable:!0,onDragStart:g=>{p(t),g.dataTransfer.effectAllowed="move",g.dataTransfer.setData("text/plain",t.toString())},onDragOver:g=>g.preventDefault(),onDrop:g=>{g.preventDefault(),k(t)},onClick:()=>b(a.id),title:`${a.title} · ${a.duration}${a.notes?" · 📝":""}`+(r==="zh"?"(点击编辑 / 拖拽排序)":" (click to edit / drag to reorder)"),className:`relative z-10 group flex items-center gap-1.5 pl-1.5 pr-2.5 py-1 rounded-full border text-xs font-semibold cursor-grab active:cursor-grabbing transition-all duration-200 ${j?"opacity-40 border-dashed scale-95":""} ${_}`,children:[e.jsx(me,{size:11,className:`opacity-0 group-hover:opacity-60 transition-opacity -mr-1 ${n?"text-white":"text-slate-400"}`}),e.jsx("span",{className:`flex items-center justify-center w-4 h-4 rounded-full text-[10px] font-bold shrink-0 ${n?"bg-white/25 text-white":h?"bg-emerald-500 text-white":"bg-white text-slate-600 border border-slate-200"}`,children:h?e.jsx(F,{size:11}):t+1}),e.jsx(D,{size:13,className:"shrink-0"}),e.jsx("span",{className:"max-w-[110px] truncate font-medium",children:a.title}),a.duration&&e.jsxs("span",{className:`text-[10px] px-1 py-0.2 rounded font-mono font-normal flex items-center gap-0.5 ${n?"bg-black/20 text-white":"bg-black/5 text-slate-500"}`,children:[e.jsx(L,{size:9}),a.duration]}),a.notes&&e.jsx(S,{size:10,className:`shrink-0 ${n?"text-white/90":"text-amber-500"}`}),n&&e.jsxs("span",{className:"flex items-center gap-1 ml-0.5 pl-1.5 border-l border-white/30 text-[10px] font-extrabold uppercase tracking-wide shrink-0",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-white animate-pulse"}),r==="zh"?"进行中":"LIVE"]})]}),t<o.length-1&&e.jsx(H,{size:12,className:"text-slate-300 shrink-0 z-10"})]},a.id)}),x&&e.jsxs("button",{onClick:l,className:"relative z-10 shrink-0 ml-1 px-2.5 py-1 rounded-full border border-dashed border-slate-300 text-xs font-semibold text-slate-500 hover:border-indigo-400 hover:text-indigo-600 hover:bg-indigo-50/50 transition-all flex items-center gap-1 cursor-pointer shadow-2xs",title:r==="zh"?"新增教学环节":"Add flow segment",children:[e.jsx(ue,{size:13}),e.jsx("span",{className:"text-[11px]",children:r==="zh"?"添加环节":"Add Step"})]})]}),e.jsxs("button",{onClick:()=>y(a=>!a),className:"ml-auto shrink-0 px-2.5 py-1 bg-white hover:bg-slate-100 border border-slate-200 text-slate-700 text-xs font-semibold rounded-lg shadow-2xs transition-all cursor-pointer flex items-center gap-1.5",children:[e.jsx(be,{size:13,className:c?"text-indigo-600":"text-slate-400"}),e.jsx("span",{children:c?r==="zh"?"隐藏环节编辑":"Hide Details":r==="zh"?"展开环节编辑":"Edit Step"})]})]})}function Ee({lang:r,segment:o,onPatch:d,onDelete:b}){return e.jsxs("div",{className:"flex flex-col gap-2 p-2 bg-slate-50/80 border-b border-gray-100 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-indigo-500"}),e.jsx("span",{className:"text-xs font-bold text-gray-700",children:r==="zh"?`环节设置:${o.title}`:`Segment: ${o.title}`})]}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-2",children:[e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-gray-400",children:r==="zh"?"名称":"Title"}),e.jsx("input",{type:"text",value:o.title||"",onChange:s=>d({title:s.target.value}),className:"border border-gray-200 px-2 py-1 rounded-lg bg-white text-[13px] outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-gray-400",children:r==="zh"?"时长":"Duration"}),e.jsx("input",{type:"text",value:o.duration||"10m",onChange:s=>d({duration:s.target.value}),className:"border border-gray-200 px-2 py-1 rounded-lg bg-white text-[13px] outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100"})]}),e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-gray-400",children:r==="zh"?"类型":"Type"}),e.jsx("select",{value:o.type||"lecture",onChange:s=>d({type:s.target.value}),className:"border border-gray-200 px-2 py-1 rounded-lg bg-white text-[13px] outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100",children:M.map(s=>e.jsx("option",{value:s.id,children:r==="zh"?s.labelZh:s.labelEn},s.id))})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-gray-400",children:r==="zh"?"配色":"Color"}),e.jsx("div",{className:"flex items-center gap-1.5 pt-1",children:O.map(s=>e.jsx("button",{onClick:()=>d({color:s.color}),className:`w-5 h-5 rounded-full border transition-transform hover:scale-110 ${s.color.split(" ")[0]} ${o.color===s.color?"ring-2 ring-indigo-500 ring-offset-1":""}`,title:s.name},s.name))})]})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-[10px] font-semibold uppercase tracking-wide text-gray-400 flex items-center gap-1",children:[e.jsx(S,{size:12,className:"text-amber-500"}),r==="zh"?"环节备注 & 教学提示":"Instructional Notes"]}),e.jsx("textarea",{rows:2,value:o.notes||"",onChange:s=>d({notes:s.target.value}),placeholder:r==="zh"?"教学要点、学生互动提示、教学设计分配…":"Teaching points, student interaction hints…",className:"w-full border border-gray-200 px-2 py-1 rounded-lg bg-white text-[13px] outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 placeholder:text-gray-400 placeholder:italic resize-y"})]}),e.jsx("div",{className:"flex justify-end",children:e.jsxs("button",{onClick:b,className:"text-red-500 hover:text-red-700 font-semibold hover:underline flex items-center gap-1 cursor-pointer text-xs",children:[e.jsx(fe,{size:12})," ",r==="zh"?"删除此环节":"Delete segment"]})})]})}function De({config:r,lang:o,initialData:d,onConfirm:b,onCancel:s}){const[p,x]=C.useState(()=>({...d})),[m,c]=C.useState({}),y=r.icon,u=E[r.color];C.useEffect(()=>{let l=!1;const a=r.editFields.filter(t=>t.kind==="select"&&t.loadOptions);if(a.length!==0)return Promise.all(a.map(async t=>{try{const n=await t.loadOptions();return[t.key,n]}catch{return[t.key,[]]}})).then(t=>{l||c(Object.fromEntries(t))}),()=>{l=!0}},[r]);const w=(l,a)=>{x(t=>({...t,[l]:a}))},z=Array.isArray(p.options)?p.options:[],k=(l,a)=>{x(t=>({...t,options:z.map((n,h)=>h===l?a:n)}))};return e.jsx("div",{className:"fixed inset-0 bg-gray-900/40 backdrop-blur-sm flex items-center justify-center p-6 z-50",children:e.jsxs("div",{className:"bg-white border text-gray-900 border-gray-200 rounded-2xl shadow-2xl w-full max-w-md flex flex-col overflow-hidden",children:[e.jsxs("div",{className:"p-4 border-b border-gray-100 flex items-center justify-between bg-gray-50/80",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`p-2 rounded-xl ${u.iconBg} ${u.iconText}`,children:e.jsx(y,{size:18})}),e.jsx("h2",{className:"font-bold text-gray-800 text-base",children:o==="zh"?`编辑:${r.labelZh}`:`Edit: ${r.labelEn}`})]}),e.jsx("button",{onClick:s,className:"text-gray-400 hover:text-gray-600 font-bold p-1 hover:bg-gray-200 rounded transition-colors text-lg",children:"×"})]}),e.jsx("div",{className:"p-5 space-y-4",children:r.editFields.length===0?e.jsx("p",{className:"text-sm text-gray-500 leading-relaxed",children:o==="zh"?"该组件无需预编辑内容,确认后即可添加到画板。":"No content to edit for this component. Confirm to add it to the board."}):r.editFields.map(l=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"text-xs font-semibold text-gray-600",children:o==="zh"?l.labelZh:l.labelEn}),l.kind==="options"?e.jsx("div",{className:"grid grid-cols-2 gap-2",children:z.map((a,t)=>e.jsx("input",{value:a,onChange:n=>k(t,n.target.value),placeholder:`${String.fromCharCode(65+t)}`,className:"border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"},t))}):l.kind==="textarea"?e.jsx("textarea",{value:p[l.key]??"",onChange:a=>w(l.key,a.target.value),placeholder:o==="zh"?l.placeholderZh:l.placeholderEn,rows:5,className:`w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-y ${l.key==="code"||l.key==="markdown"?"font-mono text-[12px]":""}`}):l.kind==="select"?e.jsxs("select",{value:p[l.key]??"",onChange:a=>w(l.key,a.target.value),className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white",children:[e.jsx("option",{value:"",children:o==="zh"?"— 不选择 —":"— None —"}),(m[l.key]??l.options??[]).map(a=>e.jsx("option",{value:a.value,children:a.label},a.value))]}):e.jsx("input",{type:"text",value:p[l.key]??"",onChange:a=>w(l.key,a.target.value),placeholder:o==="zh"?l.placeholderZh:l.placeholderEn,className:"w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"})]},l.key))}),e.jsxs("div",{className:"p-4 border-t border-gray-100 flex justify-end gap-2",children:[e.jsx("button",{onClick:s,className:"px-4 py-2 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-100 cursor-pointer",children:o==="zh"?"取消":"Cancel"}),e.jsx("button",{onClick:()=>b(p),className:"px-4 py-2 text-sm rounded-lg bg-indigo-600 text-white hover:bg-indigo-700 cursor-pointer",children:o==="zh"?"添加到画板":"Add to Board"})]})]})})}function Ge({lang:r,session:o,onCopyCourse:d,lessons:b,selectedLesson:s,activeRole:p,setActiveRole:x,editorSaveStatus:m,setEditorSaveStatus:c,editorLastSavedTime:y,setEditorLastSavedTime:u,setIsLessonPreviewVisible:w,setPreviewLessonTab:z,setPreviewSelectedCourseware:k,setTeacherTab:l,handlePaletteActivate:a,timelineSegments:t,activeSegmentId:n,setActiveSegmentId:h,draggedSegmentIdx:j,setDraggedSegmentIdx:f,saveTimeline:$,editorPanelsExpanded:D,setEditorPanelsExpanded:_,fetchElements:g,whiteboardRef:U,elements:V,paletteEdit:A,handlePaletteConfirm:W,setPaletteEdit:q}){const I=se(i=>i.session),T=o||I,v=b.find(i=>i.id===s),Y=T?.username==="admin"||T?.userId==="usr_admin"||T?.role==="administrator"||T?.subRole==="administrator",X=!v?.creator_id||v.creator_id===T?.userId||v.creator_id===T?.username,R=Y||X,K=i=>{if(!R){alert(r==="zh"?"【只读模式】您无法直接修改其他教师创建的课程。请点击上方的「一键克隆为我的备课」生成您的专属教案副本。":"[Read-Only Mode] You cannot modify lessons created by other teachers. Please clone it to your own lessons.");return}a(i)};return e.jsxs("div",{className:"flex-1 flex flex-col min-h-0 min-w-0 bg-surface rounded-2xl border border-theme overflow-hidden shadow-sm text-main",children:[e.jsxs("div",{className:"px-3.5 py-2 border-b border-theme flex items-center justify-between shrink-0 bg-surface-secondary/80 backdrop-blur-xs",children:[e.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[e.jsxs("h3",{className:"font-bold text-main text-xs sm:text-sm flex items-center gap-2 truncate",children:[e.jsx(ge,{size:16,className:"text-primary-theme shrink-0"}),e.jsxs("span",{className:"truncate",children:[r==="zh"?"课程编辑器: ":"Lesson Editor: ",v?.title||(r==="zh"?"未选择课程":"No Lesson Selected")]})]}),e.jsxs("div",{className:"bg-slate-200/80 p-0.5 rounded-lg flex items-center gap-0.5 border border-slate-300/60 shadow-3xs",children:[e.jsxs("button",{onClick:()=>x("teacher"),className:`px-2.5 py-1 text-[11px] font-bold rounded transition-all cursor-pointer ${p==="teacher"?"bg-white text-indigo-700 shadow-2xs font-extrabold":"text-slate-600 hover:text-slate-900"}`,children:["👨🏫 ",r==="zh"?"教师模式":"Teacher Mode"]}),e.jsxs("button",{onClick:()=>x("student"),className:`px-2.5 py-1 text-[11px] font-bold rounded transition-all cursor-pointer ${p==="student"?"bg-pink-600 text-white shadow-2xs font-extrabold":"text-slate-600 hover:text-slate-900"}`,children:["🎓 ",r==="zh"?"学生模式":"Student Mode"]})]}),s&&e.jsxs("div",{className:"hidden sm:flex items-center gap-1.5 shrink-0 ml-1",children:[m==="saving"&&e.jsxs("div",{className:"flex items-center gap-1 text-[10px] font-semibold text-amber-700 bg-amber-50 border border-amber-200 px-2 py-0.5 rounded-full animate-pulse",children:[e.jsx(ye,{size:10,className:"animate-spin text-amber-600"}),e.jsx("span",{children:r==="zh"?"同步 SQLite...":"Saving..."})]}),m==="saved"&&e.jsxs("div",{className:"flex items-center gap-1 text-[10px] font-semibold text-emerald-700 bg-emerald-50 border border-emerald-250 px-2 py-0.5 rounded-full",children:[e.jsx(F,{size:10,className:"text-emerald-600"}),e.jsx("span",{children:r==="zh"?"已同步 SQLite":"Saved to SQLite"}),y&&e.jsx("span",{className:"text-emerald-600/70 text-[9px] font-mono",children:y.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})})]}),m==="error"&&e.jsxs("div",{className:"flex items-center gap-1 text-[10px] font-semibold text-rose-700 bg-rose-50 border border-rose-250 px-2 py-0.5 rounded-full",children:[e.jsx(J,{size:10,className:"text-rose-600"}),e.jsx("span",{children:r==="zh"?"写入失败":"Failed to save"})]}),m==="none"&&e.jsxs("div",{className:"flex items-center gap-1 text-[10px] font-semibold text-muted bg-surface-secondary border border-theme px-2 py-0.5 rounded-full",children:[e.jsx(je,{size:10,className:"text-muted"}),e.jsx("span",{children:r==="zh"?"SQLite 就绪":"SQLite Ready"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[s&&e.jsxs("button",{onClick:()=>{w(!0),z("whiteboard"),k(null)},className:"px-2.5 py-1 bg-primary-theme hover:bg-primary-theme-hover text-white text-xs font-semibold rounded-lg flex items-center gap-1.5 shadow-2xs transition-all cursor-pointer",children:[e.jsx(Ne,{size:13}),e.jsx("span",{children:r==="zh"?"学生视角预览":"Student View"})]}),e.jsx("button",{onClick:()=>l("courses"),className:"px-2.5 py-1 bg-surface-secondary hover:bg-surface border border-theme text-muted hover:text-main text-xs font-medium rounded-lg transition-colors cursor-pointer",children:r==="zh"?"返回课程库":"Back to Courses"})]})]}),!R&&v&&e.jsxs("div",{className:"bg-amber-50 border-b border-amber-200 px-4 py-2 flex items-center justify-between text-xs text-amber-900 shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ve,{size:15,className:"text-amber-600 shrink-0"}),e.jsx("span",{children:r==="zh"?`【他人课程只读模式】当前课程由教师「${v.creator_name||v.creator_id}」创建。您拥有完整查看与备课参考权限。如需编辑调整,请克隆为您的专属教案。`:`[Read-Only Mode] This lesson was created by teacher "${v.creator_name||v.creator_id}". To customize, please clone it.`})]}),d&&e.jsxs("button",{onClick:()=>d(v.id),className:"flex items-center gap-1.5 bg-amber-600 hover:bg-amber-700 text-white font-semibold px-3 py-1 rounded-lg shadow-xs transition-all hover:shadow cursor-pointer shrink-0",children:[e.jsx(we,{size:13}),e.jsx("span",{children:r==="zh"?"一键克隆为我的备课":"Clone as My Lesson"})]})]}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx(ke,{lang:r,onActivate:K}),e.jsxs("div",{className:"flex-1 relative bg-surface flex flex-col min-w-0 overflow-y-auto",children:[e.jsx(Te,{lang:r,segments:t,activeSegmentId:n,setActiveSegmentId:h,draggedSegmentIdx:j,setDraggedSegmentIdx:f,selectedLesson:s,saveTimeline:$,editorPanelsExpanded:D,setEditorPanelsExpanded:_}),s&&n&&D&&t.some(i=>i.id===n)&&e.jsx(Ee,{lang:r,segment:t.find(i=>i.id===n),onPatch:i=>$(s,t.map(N=>N.id===n?{...N,...i}:N)),onDelete:()=>{if(t.length<=1){alert("无法删除!课程必须包含至少一个环节。");return}if(window.confirm(`确定要删除环节"${t.find(i=>i.id===n)?.title}"吗?`)){const i=t.filter(N=>N.id!==n);$(s,i),h(i[0]?.id||null)}}}),e.jsx("div",{className:"flex-1 min-h-[500px] relative flex flex-col min-w-0",children:s?e.jsxs(e.Fragment,{children:[e.jsx(ae,{ref:U,lessonId:s,userRole:p,elements:V,activeSegmentId:n,onSegmentSync:i=>h(i),onElementAdd:async(i,N)=>{c("saving");try{(await fetch(`/api/lessons/${s}/whiteboard`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:i,data:N})})).ok?(c("saved"),u(new Date),g(s)):c("error")}catch{c("error")}},onElementUpdate:async(i,N)=>{c("saving");try{(await fetch(`/api/lessons/${s}/whiteboard/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:N})})).ok?(c("saved"),u(new Date),g(s)):c("error")}catch{c("error")}},onElementDelete:async i=>{c("saving");try{(await fetch(`/api/lessons/${s}/whiteboard/${i}`,{method:"DELETE"})).ok?(c("saved"),u(new Date),g(s)):c("error")}catch{c("error")}},onClearBoard:async()=>{c("saving");try{(await fetch(`/api/lessons/${s}/whiteboard`,{method:"DELETE"})).ok?(c("saved"),u(new Date),g(s)):c("error")}catch{c("error")}},onRefresh:()=>g(s)}),A&&Z[A.type]&&e.jsx(De,{config:Z[A.type],lang:r,initialData:A.data,onConfirm:W,onCancel:()=>q(null)})]}):e.jsx("div",{className:"absolute inset-0 flex items-center justify-center text-muted p-8 text-center bg-surface-secondary/50",children:e.jsxs("div",{children:[e.jsx(ze,{size:48,className:"mx-auto mb-4 opacity-30"}),e.jsx("p",{className:"font-medium text-lg text-main mb-2",children:"No active lesson selected"}),e.jsx("p",{className:"text-sm",children:"Please select a lesson from the Dashboard to orchestrate."})]})})})]})]})]})}export{Ge as LessonEditorView};
|