PageSourceSearch

https://teacherss.kr/assets/EvaluationPlanPage-CHlLoSOX.js

js teacherss.kr collected 2026-10-02 02:01:00 UTC 43,709 bytes, 7 lines download raw bytes

1import{r as b,j as e,n as Rt}from"./vendor-react-D4NFYCVY.js";import{B as Ee}from"./badge-USJELIE-.js";import{a7 as Ut,bz as Dt,cW as Ft,T as D,I as $e,u as Lt,b2 as Gt,a9 as Ot,be as Ht,B as M,h as q,z as Qe,bf as et,aI as Wt,aE as Vt,ah as Xt,ba as Yt,ao as qt}from"./index-Bo7vBx4r.js";import{C as R,a as L,b as G,d as U}from"./card-qiphA94G.js";import{I as A}from"./input-D7jdUXkC.js";import{L as ne}from"./label-B3SoQVvX.js";import{S as le,a as oe,b as ie,c as ce,d as re}from"./select-tgHeBxeb.js";import{c as Jt,s as Kt,g as be,b as Zt,a as tt,d as Qt}from"./achievementStandards-xS7BOrH5.js";import{a as es,b as ts}from"./evaluationAi-Cw7B_yN2.js";import{c as ss,d as as}from"./jindoAllGradesData-9Y930MKa.js";import{g as rs}from"./evaluationDefaults-q1-BxTnp.js";import{a as ns,b as ls,c as os,d as is,e as cs,f as ds}from"./useEvaluationPlans-BW-LR0Kt.js";import{u as ms}from"./useTeachers-aqM1Monj.js";import{J as ot}from"./jszip.min-C14Pdgpc.js";import{x as st}from"./vendor-data-DiuZHwsT.js";import{D as us}from"./download-2uolYGOU.js";import{F as at}from"./file-up-DXvmGnuz.js";import"./vendor-utils-CBGDym6X.js";import"./vendor-state-mPENyaSF.js";import"./vendor-firebase-BXtaSaVx.js";import"./vendor-ui-DW-ZtMoV.js";import"./vendor-motion-LReuCgk7.js";import"./vendor-tiptap-DOlczfgE.js";import"./geminiClient-FL-YBFG-.js";import"./evaluationComments-BMKqDQbo.js";import"./jindo-allgrades-D9mVADRi.js";import"./evaluationHelpers-Bgbhgi-B.js";import"./yearRoleWriter-DzpUnKmW.js";import"./useRecalculateTeacherScores-D6g12zfH.js";import"./jszip.min-UGz-DpNl.js";/**
2 * @license lucide-react v0.469.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const xs=Ut("FolderUp",[["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}],["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"m9 13 3-3 3 3",key:"1pxg3c"}]]),hs=Dt();function ps(l,a){return Ft(l,a)}const fs=/^Contents\/section\d+\.xml$/;function bs(l){return l.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function ee(l,a){let s=0;return l.replace(/(<hp:t(?:\s[^>]*)?>)([\s\S]*?)(<\/hp:t>)/g,(d,g,f,h)=>{const p=s<a.length?a[s]:"";return s++,`${g}${bs(p)}${h}`})}function te(l,a,s){return l.replace(/rowAddr="(\d+)"/g,(d,g)=>`rowAddr="${Number(g)-a+s}"`)}function gs(l,a,s,d,g){const f=[s,`[${a.standardCode}] ${a.standardText}`,a.timing,a.unitName,`(${a.domainName})`,a.evaluationElement,a.teachingMethod,a.evaluationMethod,"우수",a.criteria.upper];let h=ee(l[2],f);h=h.replace(/(<hp:cellSpan colSpan="1" rowSpan=)"7"/,`$1"${d}"`),h=te(h,2,g);const p=["보통",a.criteria.middle];let j=ee(l[3],p);j=te(j,3,g+1);let o=ee(l[4],["",""]);o=te(o,4,g+2);const w=["기초",a.criteria.basic];let i=ee(l[5],w);return i=te(i,5,g+3),h+j+o+i}function js(l,a,s){const d=[`[${a.standardCode}] ${a.standardText}`,a.timing,a.unitName,`(${a.domainName})`,a.evaluationElement,a.teachingMethod,a.evaluationMethod,"우수",a.criteria.upper];let g=ee(l[6],d);g=te(g,6,s);const f=["","","보통",a.criteria.middle];let h=ee(l[7],f);h=te(h,7,s+1);const p=["기초",a.criteria.basic];let j=ee(l[8],p);return j=te(j,8,s+2),g+h+j}function ws(l,a){const s=URL.createObjectURL(l),d=document.createElement("a");d.href=s,d.download=a,d.click(),setTimeout(()=>URL.revokeObjectURL(s),100)}async function Ns(l){const a=l.filter(u=>u.items.length>0);if(a.length===0)throw new Error("합본할 발행본이 없습니다.");const s=await fetch("/templates/evaluation-plan-template.hwpx");if(!s.ok)throw new Error("평가계획 템플릿을 불러오지 못했습니다.");const d=await ot.loadAsync(await s.blob()),g=Object.keys(d.files).find(u=>fs.test(u));if(!g)throw new Error("템플릿 섹션 XML을 찾지 못했습니다.");let f=await d.files[g].async("string");const h=f.match(/<hp:tr\b[\s\S]*?<\/hp:tr>/g)??[];if(h.length<9)throw new Error("템플릿 표 구조가 예상과 다릅니다.");let p=2,j="";for(const u of a){const $=u.items.length,O=4+($-1)*3;j+=gs(h,u.items[0],u.subject,O,p);for(let I=1;I<$;I++){const _=p+4+(I-1)*3;j+=js(h,u.items[I],_)}p+=O}const o=p,w=h.slice(2).join("");if(!f.includes(w))throw new Error("템플릿 데이터 행을 교체할 위치를 찾지 못했습니다.");f=f.replace(w,j),f=f.replace(/rowCnt="\d+"/,`rowCnt="${o}"`),d.file(g,f);const i=await d.generateAsync({type:"blob"}),x=a[0];ws(i,`${x.academicYear}학년도 ${x.grade}학년 ${x.semester}학기 교수학습 및 평가 계획.hwpx`)}const Ie=/\[?\s*([0-9]+\s*[가-힣]+\s*-?\s*[0-9]{2}-[0-9]{2})\]?/,vs=new RegExp(Ie.source,"g");function it(l){const a=[...l.matchAll(vs)];return a.length===0?[{code:"",text:l.trim()}]:a.map((s,d)=>{const g=(s.index??0)+s[0].length,f=d+1<a.length?a[d+1].index??l.length:l.length;return{code:s[1].replace(/\s+/g,""),text:l.slice(g,f).trim()}})}function ct(l){return l.filter(a=>a.some(s=>(s||"").trim().length>0)).flatMap(a=>{const s=d=>(a[d]||"").trim();return it(s(1)).map(({code:d,text:g})=>({standardCode:d,standardText:g,domain:"",domainName:s(4).replace(/[()]/g,""),unitName:s(3),timing:s(2),evaluationElement:s(5),teachingMethod:s(6),evaluationMethod:s(7),criteria:{upper:s(8),middle:s(9),basic:s(10)}}))}).filter(a=>a.standardCode||a.standardText)}async function rt(l){const a=st.read(await l.arrayBuffer(),{type:"array"}),s=a.Sheets[a.SheetNames[0]],d=st.utils.sheet_to_json(s,{header:1,blankrows:!1});return ct(d.slice(1))}function ys(l){return[...l.matchAll(/<hp:t[^>]*>([\s\S]*?)<\/hp:t>/g)].map(a=>a[1].replace(/<[^>]+>/g,"")).join("").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/\s+/g," ").trim()}function Cs(l){const a=[];for(const s of l.match(/<hp:tc\b[\s\S]*?<\/hp:tc>/g)||[]){const d=s.match(/colAddr="(\d+)"/),g=s.match(/rowAddr="(\d+)"/);if(!d||!g)continue;const f=s.match(/colSpan="(\d+)"/),h=s.match(/rowSpan="(\d+)"/);
6a.push({col:Number(d[1]),row:Number(g[1]),colSpan:f?Number(f[1]):1,rowSpan:h?Number(h[1]):1,text:ys(s)})}return a}const ge=l=>l.replace(/\s+/g,"");function ks(l){var _,P;const a=l.find(m=>ge(m.text)==="성취기준");let s,d;if(a)s=a.col,d=a.row+a.rowSpan;else{const m=new Map;for(const N of l)Ie.test(N.text)&&m.set(N.col,(m.get(N.col)??0)+1);s=((_=[...m.entries()].sort((N,k)=>k[1]-N[1])[0])==null?void 0:_[0])??1;const v=l.filter(N=>Ie.test(N.text)).map(N=>N.row);d=v.length?Math.min(...v):1}const g=l.filter(m=>m.row<d),f=m=>{const v=g.filter(N=>m(N.text)).sort((N,k)=>N.row-k.row||N.col-k.col);return v.length?v[0].col:null},h=(m,...v)=>v.every(N=>m.includes(N)),p=f(m=>m.includes("시기")),j=f(m=>m.includes("단원")||m.includes("영역")),o=f(m=>m.includes("요소")||h(m,"평가","내용")),w=f(m=>h(m,"수업","방법")||m.includes("교수")),i=f(m=>h(m,"평가","방법")),x=l.filter(m=>m.row>=d),u=new Map;for(const m of x)/^(우수|보통|기초|잘함|노력요함|상|중|하)$/.test(ge(m.text))&&u.set(m.col,(u.get(m.col)??0)+1);const $=((P=[...u.entries()].sort((m,v)=>v[1]-m[1])[0])==null?void 0:P[0])??s+6,I=[...new Set(x.map(m=>m.col))].filter(m=>m>$).sort((m,v)=>m-v)[0]??$+1;return{code:s,timing:p??s+1,unit:j??s+2,element:o??s+3,teaching:w??s+4,evalMethod:i??s+5,levelLabel:$,levelText:I}}function Ss(l){var f,h;const a=ks(l),s=(p,j,o)=>l.filter(w=>w.col===p&&w.row>=j&&w.row<o),d=l.filter(p=>p.col===a.code&&p.text.trim()!==""&&ge(p.text)!=="성취기준").sort((p,j)=>p.row-j.row),g=[];for(const p of d){const j=p.row,o=p.row+p.rowSpan,w=m=>{var v;return((v=s(m,j,o)[0])==null?void 0:v.text)??""},i=w(a.unit),x=i.match(/^(.*?)\s*\(([^)]*)\)\s*$/),u=x?x[1].trim():i,$=x?x[2].trim():"",O=((f=s(a.teaching,j,o).find(m=>m.colSpan===1))==null?void 0:f.text)??"",I={upper:"",middle:"",basic:""},_=s(a.levelLabel,j,o),P=s(a.levelText,j,o);for(const m of _){const v=((h=P.find(k=>k.row===m.row))==null?void 0:h.text)??"",N=ge(m.text);m.text.includes("우수")||m.text.includes("잘함")||N==="상"?I.upper=v:m.text.includes("기초")||m.text.includes("노력")||N==="하"?I.basic=v:(m.text.includes("보통")||N==="중")&&(I.middle=v)}for(const{code:m,text:v}of it(p.text))g.push({standardCode:m,standardText:v,domain:"",domainName:$,unitName:u,timing:w(a.timing),evaluationElement:w(a.element),teachingMethod:O,evaluationMethod:w(a.evalMethod),criteria:{...I}})}return g}async function nt(l){const a=await ot.loadAsync(l),s=Object.keys(a.files).find(h=>/^Contents\/section\d+\.xml$/.test(h));if(!s)throw new Error("HWPX 섹션을 찾지 못했습니다.");const g=(await a.files[s].async("string")).match(/<hp:tbl[\s\S]*?<\/hp:tbl>/);if(!g)throw new Error("HWPX에서 표를 찾지 못했습니다.");const f=Cs(g[0]);if(f.length===0){const h=[];for(const j of g[0].match(/<hp:tr\b[\s\S]*?<\/hp:tr>/g)||[])h.push([...j.matchAll(/<hp:t[^>]*>([\s\S]*?)<\/hp:t>/g)].map(o=>o[1].replace(/<[^>]+>/g,"").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").trim()));const p=h.findIndex(j=>j.join("").includes("성취기준"));return ct(p>=0?h.slice(p+1):h)}return Ss(f)}function Ts(l){return l.map(a=>({...a,subject:Kt(a.standardCode)??""}))}function Es(l){for(const a of l){const s=Jt(a.standardCode);if(s!=null)return s}return null}const Ms=[{key:"standardCode",label:"성취기준 코드",w:"w-[120px]"},{key:"standardText",label:"성취기준 내용",w:"w-[240px]"},{key:"domainName",label:"영역명",w:"w-[110px]"},{key:"unitName",label:"단원명",w:"w-[150px]"},{key:"timing",label:"시기",w:"w-[70px]"},{key:"evaluationElement",label:"평가 요소",w:"w-[200px]"},{key:"teachingMethod",label:"수업 방법",w:"w-[120px]"},{key:"evaluationMethod",label:"평가 방법",w:"w-[120px]"},{key:"upper",label:"우수(상)",w:"w-[180px]"},{key:"middle",label:"보통(중)",w:"w-[180px]"},{key:"basic",label:"기초(하)",w:"w-[180px]"}];function $s({rows:l,grade:a,onChangeRow:s,onChangeCriteria:d,onDeleteRow:g,onAssignSubject:f}){const h=b.useMemo(()=>be(a),[a]),p=b.useMemo(()=>{const o=[],w=new Map;for(const u of l){const $=u.subject||"";w.has($)||(w.set($,[]),o.push($)),w.get($).push(u)}const i=o.filter(u=>u!=="").map(u=>({subject:u,rows:w.get(u)})),x=w.get("")??[];return{resolved:i,unresolved:x}},[l]);function j(o,w){return e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"text-sm border-collapse table-fixed min-w-[1780px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-muted text-foreground",children:[w&&e.jsx("th",{className:"border border-border px-2 py-2 w-[130px] text-left font-medium",children:"과목"}),Ms.map(i=>e.jsx("th",{className:`border border-border px-2 py-2 text-left font-medium ${i.w}`,children:i.label},i.key)),e.jsx("th",{className:"border border-border px-2 py-2 w-[44px]"})]})}),e.jsx("tbody",{children:o.map(i=>e.jsxs("tr",{className:"hover:bg-muted/50",children:[w&&e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsxs(le,{value:i.subject||void 0,onValueChange:x=>f(i._key,x),children:[e.jsx(oe,{className:"h-8 text-sm",children:e.jsx(ie,{placeholder:"과목 선택"})}),e.jsx(ce,{children:h.map(x=>e.jsx(re,{value:x,children:x},x))})]})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.standardCode,onChange:x=>s(i._key,{standardCode:x.target.value}),className:"h-8 text-sm",placeholder:"코드"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:i.standardText,onChange:x=>s(i._key,{standardText:x.target.value}
6),className:"text-sm min-h-[60px] resize-none",placeholder:"성취기준 내용"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.domainName,onChange:x=>s(i._key,{domainName:x.target.value}),className:"h-8 text-sm",placeholder:"영역"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.unitName,onChange:x=>s(i._key,{unitName:x.target.value}),className:"h-8 text-sm",placeholder:"단원명"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.timing,onChange:x=>s(i._key,{timing:x.target.value}),className:"h-8 text-sm",placeholder:"월"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:i.evaluationElement,onChange:x=>s(i._key,{evaluationElement:x.target.value}),className:"text-sm min-h-[60px] resize-none",placeholder:"평가 요소"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.teachingMethod,onChange:x=>s(i._key,{teachingMethod:x.target.value}),className:"h-8 text-sm",placeholder:"수업 방법"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:i.evaluationMethod,onChange:x=>s(i._key,{evaluationMethod:x.target.value}),className:"h-8 text-sm",placeholder:"평가 방법"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:i.criteria.upper,onChange:x=>d(i._key,"upper",x.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"우수(상)"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:i.criteria.middle,onChange:x=>d(i._key,"middle",x.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"보통(중)"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:i.criteria.basic,onChange:x=>d(i._key,"basic",x.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"기초(하)"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top text-center",children:e.jsx("button",{onClick:()=>g(i._key),className:"text-muted-foreground hover:text-red-500 transition-colors p-1",title:"행 삭제",type:"button",children:e.jsx($e,{className:"w-4 h-4"})})})]},i._key))})]})})}return e.jsxs("div",{className:"space-y-4",children:[p.resolved.map(o=>e.jsxs(R,{children:[e.jsx(L,{className:"py-3",children:e.jsxs(G,{className:"text-sm font-semibold text-foreground",children:[o.subject," ",e.jsxs("span",{className:"text-muted-foreground font-normal",children:["(",o.rows.length,"항목)"]})]})}),e.jsx(U,{children:j(o.rows,!1)})]},o.subject)),p.unresolved.length>0&&e.jsxs(R,{className:"border-amber-300",children:[e.jsx(L,{className:"py-3",children:e.jsxs(G,{className:"text-sm font-semibold text-amber-700",children:["⚠ 미분류 (",p.unresolved.length,"항목). 각 행의 과목을 지정하세요"]})}),e.jsx(U,{children:j(p.unresolved,!0)})]})]})}const Is=[1,2,3,4,5,6],dt=[{key:"standardCode",label:"성취기준 코드",w:"w-[120px]"},{key:"standardText",label:"성취기준 내용",w:"w-[240px]"},{key:"domainName",label:"영역명",w:"w-[110px]"},{key:"unitName",label:"단원명",w:"w-[150px]"},{key:"timing",label:"시기",w:"w-[70px]"},{key:"evaluationElement",label:"평가 요소",w:"w-[200px]"},{key:"teachingMethod",label:"수업 방법",w:"w-[120px]"},{key:"evaluationMethod",label:"평가 방법",w:"w-[120px]"},{key:"upper",label:"우수(상)",w:"w-[180px]"},{key:"middle",label:"보통(중)",w:"w-[180px]"},{key:"basic",label:"기초(하)",w:"w-[180px]"}];function As(){return{standardCode:"",standardText:"",domain:"",domainName:"",unitName:"",timing:"",evaluationElement:"",teachingMethod:"",evaluationMethod:"",criteria:{upper:"",middle:"",basic:""},_key:crypto.randomUUID()}}function _s(l){const{_key:a,...s}=l;return s}function Me(l){return{...l,_key:crypto.randomUUID()}}function lt({status:l}){return l==="published"?e.jsx(Ee,{className:"bg-blue-600 text-white",children:"발행됨"}):l==="submitted"?e.jsx(Ee,{variant:"secondary",children:"제출됨"}):e.jsx(Ee,{variant:"outline",children:"임시저장"})}function Ps({plan:l}){return e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"text-sm border-collapse table-fixed min-w-[1750px]",children:[e.jsx("thead",{children:e.jsx("tr",{className:"bg-muted text-foreground",children:dt.map(a=>e.jsx("th",{className:`border border-border px-2 py-2 text-left font-medium ${a.w}`,children:a.label},a.key))})}),e.jsx("tbody",{children:l.items.map((a,s)=>e.jsxs("tr",{className:"align-top",children:[e.jsx("td",{className:"border border-border px-2 py-1.5 font-mono text-muted-foreground",children:a.standardCode}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.standardText}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.domainName}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.unitName}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.timing}),e.jsx("td",{className:"border border-border px-2 py-1.5 whitespace-pre-wrap",children:a.evaluationElement}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.teachingMethod}),e.jsx("td",{className:"border border-border px-2 py-1.5",children:a.evaluationMethod}),e.jsx("td",{className:"border border-border px-2 py-1.5 whitespace-pre-wrap",children:a.criteria.upper}),e.jsx("td",{className:"border border-border px-2 py-1.5 whitespace-pre-wrap",children:a.criteria.middle}),e.jsx("td",{className:"border border-border px-2 py-1.5 whitespace-pre-wrap",children:a.criteria.basic})]},s))})]})})}function ua({fixedGrade:l,embedded:a}={}){const{tenant:s,user:d,isAdmin:g,teacherProfile:f}=Lt(),{data:h}=Gt(s==null?void 0:s.id),p=Ot(s==null?void 0:s.id),j=hs(g,f,h==null?void 0:h.evaluationManagerBujangCodes),[o,w]=b.useState(l??1),[i,x]=b.useState("국어"),[u,$]=b.useState(1),[O,I]=b.useState(""),[_,P]=b.useState(new Set),[m,v]=b.useState(new Set),[N,k]=b.useState([]),[de,F]=b.useState(),[mt,H]=b.useState(!1),[me,S]=b.useState(!1),[Ae,_e]=b.useState(!1),[W,ue]=b.useState(!1),[xe,J]=b.useState("choose"),[ut,je]=b.useState(!1),[K,z]=b.useState([]),[Pe,ze]=b.useState(!1),Be=b.useRef(null),Re=b.useRef(null),xt=b.useMemo(()=>be(o),[o]);b.useEffect(()=>{l&&l!==o&&w(l)},[l,o]);const Ue=b.useRef(!1);b.useEffect(()=>{if(Ue.current||!f)return;const t=rs(f);t.grade&&!l&&w(t.grade),t.subject&&be(t.grade??o).includes(t.subject)&&x(t.subject),Ue.current=!0},[f,o]);const he=b.useMemo(()=>[...new Set(ss(o,i,u).map(t=>t.publisher))],[o,i,u]),se=he.includes(O)?O:he[0]??"",we=b.useMemo(()=>
6{const t=as(o,i,u,se);if(t.length>0)return t;const n=new Map;for(const r of Zt(o,i)){const c=r.domainName||r.domain||"기타";n.has(c)||n.set(c,[]),n.get(c).push(r.code)}return[...n.entries()].map(([r,c])=>({unit:r,codes:c}))},[o,i,u,se]),{data:V=[],isLoading:ht}=ns(s==null?void 0:s.id,{year:p,semester:u}),Z=b.useMemo(()=>V.filter(t=>t.grade===o&&t.subject===i&&t.semester===u),[V,o,i,u]),ae=b.useMemo(()=>Z.find(t=>t.status==="published")??Z.find(t=>t.status==="submitted")??null,[Z]),De=b.useMemo(()=>Z.filter(t=>t.status==="submitted"||t.status==="published"),[Z]),pe=b.useMemo(()=>V.filter(t=>t.grade===o&&t.semester===u&&t.status==="submitted"),[V,o,u]),{data:Fe=[]}=ms(s==null?void 0:s.id),pt=ls(),Le=b.useMemo(()=>ps(Fe,h==null?void 0:h.evaluationManagerBujangCodes),[Fe,h]),Ne=Le.length?`${Le.join(" · ")} 선생님`:"관리자",Ge=b.useMemo(()=>Z.find(t=>t.status==="submitted"&&t.createdBy===(d==null?void 0:d.id))??null,[Z,d]),ve=b.useMemo(()=>V.filter(t=>t.grade===o&&t.semester===u&&t.status==="published"),[V,o,u]),Oe=os(),He=is(),We=cs(),[Ve,Xe]=b.useState(!1),ft=ds(),{confirm:Q,alert:y}=Ht();b.useEffect(()=>{k([]),F(void 0),H(!1),S(!1),P(new Set),v(new Set),z([]),J("choose"),je(!1)},[o,i,u,se]);const X=Rt(({currentLocation:t,nextLocation:n})=>me&&t.pathname!==n.pathname);b.useEffect(()=>{if(X.state!=="blocked")return;let t=!1;return(async()=>{var r,c;const n=await Q({title:"저장하지 않고 나가시겠어요?",description:"작성 중인 평가계획이 저장되지 않았습니다. 페이지를 떠나면 사라집니다.",confirmText:"나가기",cancelText:"머무르기",variant:"destructive"});t||(n?(r=X.proceed)==null||r.call(X):(c=X.reset)==null||c.call(X))})(),()=>{t=!0}},[X.state]),b.useEffect(()=>{if(!me)return;const t=n=>{n.preventDefault(),n.returnValue=""};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[me]);const bt=mt||N.length>0||!!de||K.length>0||xe!=="choose"||ut,Ye=!!ae&&!bt,gt=!Ye;function jt(t){P(n=>{const r=new Set(n);return r.has(t)?r.delete(t):r.add(t),r})}function wt(t){v(n=>{const r=new Set(n);return r.has(t)?r.delete(t):r.add(t),r})}async function Nt(){const t=[],n=new Set;for(const r of we)if(_.has(r.unit))for(const c of r.codes){if(n.has(c))continue;const C=tt(c);if(!C)continue;n.add(c);const T=es(c);t.push({code:c,text:C.description,domain:C.domain,domainName:C.domainName,levels:T?{A:T.A,B:T.B,C:T.C}:void 0,unit:r.unit})}if(t.length===0){await y({title:"단원을 1개 이상 선택하세요",confirmText:"확인"});return}_e(!0);try{const r=await ts({grade:o,subject:i,standards:t});k(r.map(Me)),S(!0)}catch(r){await y({title:"AI 생성 실패",description:r.message,confirmText:"확인"})}finally{_e(!1)}}async function qe(t){if(!(!(s!=null&&s.id)||!d)){ue(!0);try{const n=await Oe.mutateAsync({tenantId:s.id,plan:{id:de,tenantId:s.id,academicYear:p,semester:u,grade:o,subject:i,items:N.map(_s),status:"draft",createdBy:d.id,createdByName:d.name??""}});F(n),S(!1),t==="submitted"?(await He.mutateAsync({tenantId:s.id,planId:n}),await y({title:"제출 완료",description:`평가계획이 제출되었습니다. ${Ne}이(가) 발행(승인)해야 실제 반영됩니다.`,confirmText:"확인"}),k([]),F(void 0),H(!1),P(new Set)):await y({title:"임시저장 완료",confirmText:"확인"})}catch(n){await y({title:"저장 실패",description:n.message,confirmText:"확인"})}finally{ue(!1)}}}async function vt(t){try{const n=t.name.endsWith(".hwpx")?await nt(t):await rt(t);z([]),k(n.map(Me)),F(void 0),H(!0),S(!0),await y({title:`${n.length}개 항목을 불러왔습니다`,description:"표를 확인·수정한 뒤 제출하세요.",confirmText:"확인"})}catch(n){await y({title:"파싱 실패",description:n.message,confirmText:"확인"})}}async function yt(t){try{const n=t.name.endsWith(".hwpx")?await nt(t):await rt(t);if(n.length===0){await y({title:"항목을 찾지 못했습니다",confirmText:"확인"});return}const r=Es(n);if(r!=null&&r!==Qt(o)){await y({title:"학년이 일치하지 않습니다",description:`파일은 ${r===2?"1~2":r===4?"3~4":"5~6"}학년군 성취기준입니다. 상단 학년 선택을 확인하세요.`,confirmText:"확인"});return}const c=Ts(n).map(T=>({...T,_key:crypto.randomUUID()}));k([]),F(void 0),H(!1),z(c),S(!0);const C=new Set(c.map(T=>
6T.subject).filter(Boolean)).size;await y({title:`${C}개 과목 · ${c.length}개 항목 감지됨`,description:"과목별로 확인·수정한 뒤 전체 저장하세요.",confirmText:"확인"})}catch(n){await y({title:"파싱 실패",description:n.message,confirmText:"확인"})}}function Ct(t,n){S(!0),z(r=>r.map(c=>c._key===t?{...c,...n}:c))}function kt(t,n,r){S(!0),z(c=>c.map(C=>C._key===t?{...C,criteria:{...C.criteria,[n]:r}}:C))}function St(t){S(!0),z(n=>n.filter(r=>r._key!==t))}function Tt(t,n){S(!0),z(r=>r.map(c=>c._key===t?{...c,subject:n}:c))}async function Je(t){if(!(s!=null&&s.id)||!d)return;const n=K.filter(E=>!E.subject).length;if(n>0){await y({title:`${n}개 행의 과목을 지정하세요`,confirmText:"확인"});return}const r=new Map;for(const E of K)r.has(E.subject)||r.set(E.subject,[]),r.get(E.subject).push(E);const c=E=>V.filter(B=>B.grade===o&&B.semester===u&&B.subject===E),C=[...r.keys()].filter(E=>c(E).some(B=>B.status==="submitted"||B.status==="published"));if(C.length>0&&!await Q({title:"기존 평가계획을 덮어쓸까요?",description:`${C.join("·")} 과목에 이미 제출/발행본이 있습니다. 저장하면 덮어씁니다.`,confirmText:t==="submitted"?"저장 후 제출":"덮어쓰기"}))return;ue(!0);const T=[],ke=[];try{for(const[E,B]of r)try{const Se=c(E),Te=Se.find(fe=>fe.status==="published")??Se.find(fe=>
6fe.status==="submitted")??Se[0],zt=await Oe.mutateAsync({tenantId:s.id,plan:{id:Te==null?void 0:Te.id,tenantId:s.id,academicYear:p,semester:u,grade:o,subject:E,items:B.map(({_key:fe,subject:zs,...Bt})=>Bt),status:"draft",createdBy:d.id,createdByName:d.name??""}});t==="submitted"&&await He.mutateAsync({tenantId:s.id,planId:zt}),T.push(E)}catch{ke.push(E)}ke.length===0?(await y({title:t==="submitted"?`${T.length}개 과목 제출 완료`:`${T.length}개 과목 임시저장 완료`,description:t==="submitted"?`${T.join("·")}. ${Ne}이(가) 발행(승인)해야 실제 반영됩니다.`:T.join("·"),confirmText:"확인"}),z([]),S(!1),J("choose")):(await y({title:"일부 과목 저장 실패",description:`완료: ${T.join("·")||"없음"} / 실패: ${ke.join("·")}`,confirmText:"확인"}),z(E=>E.filter(B=>!T.includes(B.subject))))}finally{ue(!1)}}async function ye(){me&&!await Q({title:"저장하지 않고 나가시겠어요?",description:"작성 중인 내용이 사라집니다.",confirmText:"나가기",cancelText:"머무르기",variant:"destructive"})||(k([]),F(void 0),H(!1),P(new Set),v(new Set),z([]),S(!1),J("choose"),je(!1))}async function Et(t){if(!(!(s!=null&&s.id)||!d||!await Q({title:"평가계획을 발행하시겠습니까?",description:"발행하면 동일 학년/과목/학기의 기존 발행본이 임시저장으로 변경됩니다.",confirmText:"발행"})))try{await We.mutateAsync({tenantId:s.id,plan:t,publishedBy:d.id,publishedByName:d.name??""})}catch(r){await y({title:"발행 실패",description:r.message,confirmText:"확인"})}}async function Mt(){if(!(s!=null&&s.id)||!d)return;const t=pe;if(t.length===0){await y({title:"발행할 과목 없음",description:"현재 학년·학기에 제출되어 발행 대기 중인 과목이 없습니다.",confirmText:"확인"});return}if(!await Q({title:"전 과목 발행",description:`${o}학년 ${u}학기 제출된 ${t.length}개 과목을 모두 발행합니다. 같은 과목의 기존 발행본은 임시저장으로 바뀝니다.`,confirmText:"전체 발행",cancelText:"취소"}))return;Xe(!0);let r=0;try{for(const c of t)await We.mutateAsync({tenantId:s.id,plan:c,publishedBy:d.id,publishedByName:d.name??""}),r++;await y({title:`${r}개 과목 발행 완료`,confirmText:"확인"})}catch(c){await y({title:"발행 실패",description:`${c.message}
7(지금까지 ${r}개 발행됨)`,confirmText:"확인"})}finally{Xe(!1)}}function $t(t){k(t.items.map(Me)),F(t.id),H(!0),S(!1),J("ai")}async function It(t){if(!(!(s!=null&&s.id)||!await Q({title:"평가계획을 삭제하시겠습니까?",confirmText:"삭제",variant:"destructive"})))try{await ft.mutateAsync({tenantId:s.id,planId:t.id}),de===t.id&&(k([]),F(void 0),H(!1),S(!1))}catch(r){await y({title:"삭제 실패",description:r.message,confirmText:"확인"})}}async function At(){if(ve.length===0){await y({title:"발행본 없음",description:`${o}학년 ${u}학기에 발행된 과목이 없습니다. 담당자 발행 후 다운로드할 수 있습니다.`,confirmText:"확인"});return}const t=new Set(ve.map(c=>c.subject)),r=[...new Set(V.filter(c=>c.grade===o&&c.semester===u).map(c=>c.subject))].filter(c=>!t.has(c));try{ze(!0),await Ns(ve),await y({title:"다운로드 완료",description:`발행된 ${t.size}개 과목을 합본했습니다.${r.length?` 미발행 ${r.length}개 과목(${r.join(", ")})은 제외됨.`:""}`,confirmText:"확인"})}catch(c){await y({title:"다운로드 실패",description:c.message,confirmText:"확인"})}finally{ze(!1)}}function Y(t,n){S(!0),k(r=>r.map((c,C)=>C===t?{...c,...n}:c))}function Ce(t,n,r){S(!0),k(c=>c.map((C,T)=>T===t?{...C,criteria:{...C.criteria,[n]:r}}:C))}function _t(){S(!0),k(t=>[...t,As()])}function Pt(t){S(!0),k(n=>n.filter((r,c)=>c!==t))}const Ke=_.size;function Ze(){return e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs(G,{className:"text-base",children:["평가계획 편집",de&&e.jsx("span",{className:"ml-2 text-xs text-muted-foreground font-normal",children:"(불러온 계획 편집 중)"})]}),e.jsxs(M,{variant:"outline",size:"sm",onClick:_t,className:"gap-1.5",children:[e.jsx(Qe,{className:"w-4 h-4"}),"행 추가"]})]})}),e.jsxs(U,{children:[N.length===0?e.jsxs("div",{className:"text-center py-12 text-muted-foreground",children:[e.jsx(qt,{className:"w-10 h-10 mx-auto mb-3 opacity-40"}),e.jsx("p",{children:"단원을 선택해 AI 생성 버튼을 누르거나, 기존 파일ì
7„ 올리세요."})]}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"text-sm border-collapse table-fixed min-w-[1780px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-muted text-foreground",children:[dt.map(t=>e.jsx("th",{className:`border border-border px-2 py-2 text-left font-medium ${t.w}`,children:t.label},t.key)),e.jsx("th",{className:"border border-border px-2 py-2 w-[44px]"})]})}),e.jsx("tbody",{children:N.map((t,n)=>e.jsxs("tr",{className:"hover:bg-muted/50",children:[e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.standardCode,onChange:r=>Y(n,{standardCode:r.target.value}),className:"h-8 text-sm",placeholder:"코드"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:t.standardText,onChange:r=>Y(n,{standardText:r.target.value}),className:"text-sm min-h-[60px] resize-none",placeholder:"성취기준 내용"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.domainName,onChange:r=>Y(n,{domainName:r.target.value}),className:"h-8 text-sm",placeholder:"영역"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.unitName,onChange:r=>Y(n,{unitName:r.target.value}),className:"h-8 text-sm",placeholder:"단원명"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.timing,onChange:r=>Y(n,{timing:r.target.value}),className:"h-8 text-sm",placeholder:"월"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:t.evaluationElement,onChange:r=>Y(n,{evaluationElement:r.target.value}),className:"text-sm min-h-[60px] resize-none",placeholder:"평가 요소"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.teachingMethod,onChange:r=>Y(n,{teachingMethod:r.target.value}),className:"h-8 text-sm",placeholder:"수업 방법"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(A,{value:t.evaluationMethod,onChange:r=>Y(n,{evaluationMethod:r.target.value}),className:"h-8 text-sm",placeholder:"평가 방법"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:t.criteria.upper,onChange:r=>Ce(n,"upper",r.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"우수(상) 기준"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:t.criteria.middle,onChange:r=>Ce(n,"middle",r.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"보통(중) 기준"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top",children:e.jsx(D,{value:t.criteria.basic,onChange:r=>Ce(n,"basic",r.target.value),className:"text-sm min-h-[60px] resize-none",placeholder:"기초(하) 기준"})}),e.jsx("td",{className:"border border-border px-2 py-1.5 align-top text-center",children:e.jsx("button",{onClick:()=>Pt(n),className:"text-muted-foreground hover:text-red-500 transition-colors p-1",title:"행 삭제",type:"button",children:e.jsx($e,{className:"w-4 h-4"})})})]},t._key))})]})}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-3",children:[e.jsxs(M,{variant:"outline",onClick:()=>qe("draft"),disabled:W||N.length===0,className:"gap-2",children:[W&&e.jsx(q,{className:"w-4 h-4 animate-spin"}),"임시저장"]}),e.jsxs(M,{onClick:()=>qe("submitted"),disabled:W||N.length===0,className:"gap-2",children:[W&&e.jsx(q,{className:"w-4 h-4 animate-spin"}),"제출"]}),ae&&e.jsx(M,{variant:"ghost",onClick:()=>{k([]),F(void 0),H(!1),S(!1),P(new Set)},children:"취소"})]})]})]})}return e.jsx("div",{className:a?"":"min-h-screen bg-background",children:e.jsxs("div",{className:a?"space-y-6":"max-w-7xl mx-auto px-4 py-8 space-y-6",children:[!a&&e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-foreground",children:"교수학습 및 평가 계획"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-0.5",children:[p,"학년도"]})]})}),e.jsx(R,{children:e.jsx(U,{className:"pt-6",children:e.jsxs("div",{className:"flex flex-wrap gap-4",children:[l?e.jsxs("div",{className:"space-y-1 min-w-[100px]",children:[e.jsx(ne,{className:"text-sm font-medium",children:"학년"}),e.jsxs("p",{className:"flex h-10 items-center text-sm font-semibold",children:[o,"학년"]})]}):e.jsxs("div",{className:"space-y-1 min-w-[100px]",children:[e.jsx(ne,{className:"text-sm font-medium",children:"학년"}),e.jsxs(le,{value:String(o),onValueChange:t=>{const n=Number(t);w(n);const r=be(n);r.includes(i)||x(r[0]??"국어")},children:[e.jsx(oe,{className:"w-[100px]",children:e.jsx(ie,{})}),e.jsx(ce,{children:Is.map(t=>e.jsxs(re,{value:String(t),children:[t,"학년"]},t))})]})]}),e.jsxs("div",{className:"space-y-1 min-w-[120px]",children:[e.jsx(ne,{className:"text-sm font-medium",children:"교과"}),e.jsxs(le,{value:i,onValueChange:x,disabled:K.length>0,children:[e.jsx(oe,{className:"w-[120px]",children:e.jsx(ie,{})}),e.jsx(ce,{children:xt.map(t=>e.jsx(re,{value:t,children:t},t))})]})]}),e.jsxs("div",{className:"space-y-1 min-w-[100px]",children:[e.jsx(ne,{className:"text-sm font-medium",children:"학기"}),e.jsxs(le,{value:String(u),onValueChange:t=>$(Number(t)),children:[e.jsx(oe,{className:"w-[100px]",children:e.jsx(ie,{})}),e.jsxs(ce,{children:[e.jsx(re,{value:"1",children:"1학기"}),e.jsx(re,{value:"2",children:"2학기"})]})]})]}),he.length>0&&e.jsxs("div",{className:"space-y-1 min-w-[180px]",children:[e.jsx(ne,{className:"text-sm font-medium",children:"교과서(출판사)"}),e.jsxs(le,{value:se,onValueChange:I,children:[e.jsx(oe,{className:"w-[200px]",children:e.jsx(ie,{})}),e.jsx(ce,{children:he.map(t=>e.jsx(re,{value:t,children:t},t))})]})]})]})})}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(M,{variant:"outline",size:"sm",onClick:At,disabled:Pe,className:"gap-1.5",children:[Pe?e.jsx(q,{className:"w-4 h-4 animate-spin"}):e.jsx(us,{className:"w-4 h-4"}),"전 과목 HWPX 다운로드"]})}),Ye&&ae&&e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs(G,{className:"text-base flex items-center gap-2",children:["현재 평가계획 · ",o,"학년 ",i," ",u,"학기",e.jsx(lt,{status:ae.status})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(M,{size:"sm",onClick:()=>{je(!0),J("choose")},className:"gap-1.5",children:[e.jsx(Qe,{className:"w-4 h-4"}),"새로 작성"]}),Ge&&e.jsx(M,{size:"sm",variant:"outline",onClick:async()=>
7{if(!(!(s!=null&&s.id)||!await Q({title:"제출 취소",description:"내 제출을 취소하고 임시저장으로 되돌립니다. 발행 전에만 가능합니다.",confirmText:"제출 취소",cancelText:"닫기"})))try{await pt.mutateAsync({tenantId:s.id,planId:Ge.id}),await y({title:"제출 취소됨",confirmText:"확인"})}catch(n){await y({title:"제출 취소 실패",description:n.message,confirmText:"확인"})}},className:"gap-1.5",children:"제출 취소"})]})]})}),e.jsx(U,{children:e.jsx(Ps,{plan:ae})})]}),gt&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-lg bg-blue-50 border border-blue-200 px-4 py-2.5 text-sm text-blue-800",children:["ℹ️ 평가계획을 제출하면 ",e.jsx("strong",{children:Ne}),"의 발행(승인) 후 실제 반영됩니다."]}),xe==="choose"&&e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(G,{className:"text-base",children:["평가계획 작성 · ",o,"학년 ",i," ",u,"학기"]}),ae&&e.jsx(M,{variant:"ghost",size:"sm",onClick:ye,className:"text-muted-foreground",children:"취소"})]})}),e.jsx(U,{children:e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("button",{type:"button",onClick:()=>J("ai"),className:"flex flex-col items-start gap-2 rounded-xl border border-border bg-card p-5 text-left transition-colors hover:border-blue-400 hover:bg-blue-50/40",children:[e.jsx(et,{className:"w-6 h-6 text-blue-500"}),e.jsx("span",{className:"font-semibold text-foreground",children:"AI로 만들기"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"단원을 선택하면 평가계획을 자동 생성합니다."})]}),e.jsxs("button",{type:"button",onClick:()=>J("upload"),className:"flex flex-col items-start gap-2 rounded-xl border border-border bg-card p-5 text-left transition-colors hover:border-blue-400 hover:bg-blue-50/40",children:[e.jsx(at,{className:"w-6 h-6 text-blue-500"}),e.jsx("span",{className:"font-semibold text-foreground",children:"기존 파일 올리기"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"HWPX/엑셀 평가계획을 불러옵니다. 학년 통파일도 가능."})]})]})})]}),xe==="ai"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{children:e.jsx(M,{variant:"ghost",size:"sm",onClick:ye,className:"gap-1.5 text-muted-foreground",children:"← 뒤로"})}),e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs(G,{className:"text-base",children:["단원 선택 · ",o,"학년 ",i," ",u,"학기",se?` · ${se}`:""]})}),e.jsxs(U,{children:[we.length===0?e.jsx("p",{className:"text-muted-foreground text-sm",children:"해당 학년/교과 단원 데이터가 없습니다."}):e.jsx("div",{className:"space-y-2",children:we.map(({unit:t,codes:n})=>{const r=m.has(t);return e.jsxs("div",{className:"border border-border rounded-lg overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 bg-muted px-3 py-2",children:[e.jsx(Wt,{id:`unit-${t}`,checked:_.has(t),onCheckedChange:()=>jt(t)}),e.jsxs("button",{type:"button",onClick:()=>wt(t),className:"flex flex-1 items-center gap-2 text-left","aria-expanded":r,children:[r?e.jsx(Vt,{className:"w-4 h-4 text-muted-foreground flex-shrink-0"}):e.jsx(Xt,{className:"w-4 h-4 text-muted-foreground flex-shrink-0"}),e.jsx("span",{className:"font-semibold text-foreground",children:t}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["성취기준 ",n.length,"개"]})]})]}),r&&e.jsx("div",{className:"px-3 py-2 space-y-1.5",children:n.map(c=>{const C=tt(c);return e.jsxs("p",{className:"text-sm text-foreground leading-snug",children:[e.jsxs("span",{className:"font-mono text-muted-foreground mr-1.5",children:["[",c,"]"]}),(C==null?void 0:C.description)??"(성취기준 정보 없음)"]},c)})})]},t)})}),e.jsxs("div",{className:"mt-5 flex flex-wrap items-center gap-3",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[Ke,"개 단원 선택됨"]}),e.jsxs(M,{onClick:Nt,disabled:Ae||Ke===0,className:"gap-2",children:[Ae?e.jsx(q,{className:"w-4 h-4 animate-spin"}):e.jsx(et,{className:"w-4 h-4"}),"AI로 평가계획 생성"]})]})]})]}),Ze()]}),xe==="upload"&&e.jsxs(e.Fragment,{children:[e.jsx("div",{children:e.jsx(M,{variant:"ghost",size:"sm",onClick:ye,className:"gap-1.5 text-muted-foreground",children:"← 뒤로"})}),e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs(G,{className:"text-base",children:["기존 파일 올리기 · ",o,"학년 ",u,"학기"]})}),e.jsxs(U,{children:[e.jsx("input",{ref:Be,type:"file",accept:".hwpx,.xlsx,.xls",className:"hidden",onChange:t=>{var r;const n=(r=t.target.files)==null?void 0:r[0];n&&vt(n),t.target.value=""}}),e.jsx("input",{ref:Re,type:"file",accept:".hwpx,.xlsx,.xls",className:"hidden",onChange:t=>{var r;const n=(r=t.target.files)==null?void 0:r[0];n&&yt(n),t.target.value=""}}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("button",{type:"button",onClick:()=>{var t;return(t=Be.current)==null?void 0:t.click()},className:"flex flex-col items-start gap-2 rounded-xl border border-border bg-card p-5 text-left transition-colors hover:border-blue-400 hover:bg-blue-50/40",children:[e.jsx(at,{className:"w-6 h-6 text-blue-500"}),e.jsx("span",{className:"font-semibold text-foreground",children:"단일 과목 파일"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:["현재 선택 과목(",i,") 1개로 불러옵니다."]})]}),e.jsxs("button",{type:"button",onClick:()=>{var t;return(t=Re.current)==null?void 0:t.click()},className:"flex flex-col items-start gap-2 rounded-xl border border-border bg-card p-5 text-left transition-colors hover:border-blue-400 hover:bg-blue-50/40",children:[e.jsx(xs,{className:"w-6 h-6 text-blue-500"}),e.jsx("span",{className:"font-semibold text-foreground",children:"학년 통파일"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"여러 과목이 섞
7인 학년 전체 파일 → 과목별로 분리 저장합니다."})]})]})]})]}),K.length>0&&e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs(G,{className:"text-base",children:["평가계획 편집 (학년 통파일 · ",o,"학년 ",u,"학기)"]})}),e.jsxs(U,{children:[e.jsx($s,{rows:K,grade:o,onChangeRow:Ct,onChangeCriteria:kt,onDeleteRow:St,onAssignSubject:Tt}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-3",children:[e.jsxs(M,{variant:"outline",onClick:()=>Je("draft"),disabled:W,className:"gap-2",children:[W&&e.jsx(q,{className:"w-4 h-4 animate-spin"})," 전체 임시저장"]}),e.jsxs(M,{onClick:()=>Je("submitted"),disabled:W,className:"gap-2",children:[W&&e.jsx(q,{className:"w-4 h-4 animate-spin"})," 전체 제출"]})]})]})]}),K.length===0&&N.length>0&&Ze()]})]}),j&&e.jsxs(R,{children:[e.jsx(L,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs(G,{className:"text-base",children:["제출된 평가계획 관리 · ",o,"학년 ",i," ",u,"학기"]}),e.jsxs(M,{size:"sm",onClick:Mt,disabled:Ve||pe.length===0,className:"gap-1.5",children:[Ve?e.jsx(q,{className:"w-3.5 h-3.5 animate-spin"}):null,"이 학년·학기 전 과목 발행",pe.length>0?` (${pe.length})`:""]})]})}),e.jsx(U,{children:ht?e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground py-6",children:[e.jsx(q,{className:"w-4 h-4 animate-spin"}),e.jsx("span",{children:"불러오는 중..."})]}):De.length===0?e.jsx("p",{className:"text-muted-foreground text-sm py-4",children:"제출된 평가계획이 없습니다. 교사가 제출하면 여기에 표시됩니다."}):e.jsx("div",{className:"space-y-3",children:De.map(t=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border bg-card px-4 py-3",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx(lt,{status:t.status}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm font-medium text-foreground truncate",children:t.createdByName||"(작성자 미상)"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[t.items.length,"개 항목",t.status==="published"&&t.publishedByName?` · 발행: ${t.publishedByName}`:""]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(M,{size:"sm",variant:"outline",onClick:()=>$t(t),children:[e.jsx(Yt,{className:"w-3.5 h-3.5 mr-1"}),"불러와 편집"]}),t.status!=="published"&&e.jsx(M,{size:"sm",onClick:()=>Et(t),children:"발행"}),e.jsx(M,{size:"sm",variant:"ghost",onClick:()=>It(t),className:"text-red-500 hover:text-red-600 hover:bg-red-50",children:e.jsx($e,{className:"w-3.5 h-3.5"})})]})]},t.id))})})]})]})})}export{ua as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.