PageSourceSearch

https://naemo.ai/_next/static/chunks/5268.9d1c7c0fa1110446.js

js naemo.ai collected 2026-09-24 14:31:11 UTC 13,863 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5268],{67404:function(e,t,n){n.d(t,{Z:function(){return i}});let i=(0,n(79205).Z)("QrCode",[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]])},45268:function(e,t,n){n.r(t),n.d(t,{default:function(){return y}});var i=n(57437),s=n(10136),a=n(2265),r=n(54887),d=n(32489),c=n(82431);let l=(0,n(79205).Z)("Power",[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]]);var o=n(18930),x=n(22135),u=n(40875),m=n(87769),p=n(42208),h=n(17625),b=n(30401),f=n(78867),g=n(67404),k=n(35398),z=n(93448);let j=window.location.origin;function y(e){let{students:t,onClose:n,isSystemAdmin:y=!1,focusStudentId:N}=e,[v,w]=(0,a.useState)([]),[S,C]=(0,a.useState)(!0),[P,q]=(0,a.useState)(null),[T,I]=(0,a.useState)({}),[Z,M]=(0,a.useState)({}),[E,A]=(0,a.useState)(null),[R,O]=(0,a.useState)(null),[Q,_]=(0,a.useState)(null),[F,J]=(0,a.useState)(""),[D,H]=(0,a.useState)(null),[L,B]=(0,a.useState)(null),U=(0,a.useRef)(null),V=(0,a.useMemo)(()=>new Map(t.map(e=>[e.id,e])),[t]),Y=(0,a.useCallback)(async()=>{let e=await fetch("/api/admin/grade-links");return e.ok?(await e.json()).links:[]},[]),G=(0,a.useCallback)(async()=>(await fetch("/api/admin/grade-links",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({label:function(e){if(!e.length)return"성적표";let{grade:t,classNum:n}=e[0],i=new Date().getFullYear();return t&&n?"".concat(t,"학년 ").concat(n,"반 (").concat(i,")"):t?"".concat(t,"학년 (").concat(i,")"):"성적표 (".concat(i,")")}(t),studentIds:t.map(e=>e.id)})})).ok,[t]);(0,a.useEffect)(()=>{(async()=>{C(!0);try{let t=await Y();if(0===t.length&&(await G(),t=await Y()),w(t),N){var e;let n=e=>e.studentPins.some(e=>e.studentId===N),i=null!==(e=t.find(e=>e.isActive&&n(e)))&&void 0!==e?e:t.find(n);i&&(q(i.id),H(i.id),K(i.id))}}finally{C(!1)}})()},[]);let K=(0,a.useCallback)(async e=>{let t=await fetch("/api/admin/grade-links/".concat(e,"/pins"));if(t.ok){let n=await t.json();I(t=>({...t,[e]:n.pins||[]}))}},[]),W=(0,a.useCallback)(e=>{q(t=>{let n=t===e?null:e;return n&&!T[n]&&K(n),n})},[T,K]),X=D?T[D]:void 0,$=(0,a.useRef)(!1);(0,a.useEffect)(()=>{var e;if($.current||!X||!N)return;$.current=!0;let t=null===(e=U.current)||void 0===e?void 0:e.querySelector('[data-student-id="'.concat(N,'"]'));if(!t)return;let n=window.matchMedia("(prefers-reduced-motion: reduce)").matches;t.scrollIntoView({block:"center",behavior:n?"auto":"smooth"}),B(N)},[X,N]),(0,a.useEffect)(()=>{if(!L)return;let e=setTimeout(()=>B(null),2400);return()=>clearTimeout(e)},[L]);let ee=(0,a.useCallback)(async(e,t)=>{let n=T[e];if(!n){let t=await fetch("/api/admin/grade-links/".concat(e,"/pins"));t.ok&&(n=(await t.json()).pins||[],I(t=>({...t,[e]:n})))}n&&(J(t||"성적표"),_([...n]))},[T]);(0,a.useEffect)(()=>{if(!Q)return;let e=setTimeout(()=>{let e=document.title;document.title="",window.print(),document.title=e,_(null)},150);return()=>clearTimeout(e)},[Q]);let et=e=>{let t="".concat(j,"/report/").concat(e);navigator.clipboard.writeText(t).then(()=>{A(e),setTimeout(()=>A(null),2e3)})},[en,ei]=(0,a.useState)(null),[es,ea]=(0,a.useState)(null),er=(0,s.N)(),ed=async(e,t)=>{if(en!==e&&es!==e){ei(e);try{(await fetch("/api/admin/grade-links/".concat(e),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:!t})})).ok&&w(await Y())}finally{ei(null)}}},ec=async e=>{if(en!==e&&es!==e&&await er({title:"이 링크를 삭제할까요?",description:"삭제하면 학생들이 이 주소로 더 이상 성적을 ë³¼ 수 없습니다."})){ea(e);try{(await fetch("/api/admin/grade-links/".concat(e),{method:"DELETE"})).ok&&(w(await Y()),P===e&&q(null))}finally{ea(null)}}},el=async(e,t,n)=>{await er({title:"".concat(n," 학생의 PIN을 초기화할까요?"),description:"학생이 다음에 접속할 때 새 PIN을 직접 정하게 됩니다.",confirmLabel:"초기화",tone:"default"})&&(await fetch("/api/admin/grade-links/".concat(e,"/pins"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({studentId:t})})).ok&&K(e)};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("div",{className:"fixed inset-0 z-50 bg-black/50 flex items-end sm:items-center justify-center p-0 sm:p-4",children:(0,i.jsxs)("div",{className:"bg-white dark:bg-zinc-900 rounded-t-2xl sm:rounded-2xl w-full sm:max-w-lg max-h-[90vh] flex flex-col shadow-2xl",style:{paddingBottom:"env(safe-area-inset-bottom, 0px)"},children:[(0,i.jsxs)("div",{className:"flex items-center justify-between px-5 py-4 border-b border-zinc-100 dark:border-zinc-800",children:[(0,i.jsx)("h2",{className:"font-bold text-zinc-900 dark:text-zinc-100 text-base",children:"모바일 성적표"}),(0,i.jsx)("button",{"aria-label":"닫기",onClick:n,className:"p-1.5 rounded-lg text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800",children:(0,i.jsx)(d.Z,{size:18})})]}),(0,i.jsx)("div",{ref:U,className:"flex-1 overflow-y-auto",children:S?(0,i.jsx)("div",{className:"flex justify-center items-center py-16",children:(0,i.jsx)(c.Z,{size:20,className:"animate-spin text-zinc-400"})}):0===v.length?(0,i.jsx)("p",{className:"text-center text-sm text-zinc-400 py-12",children:"링크를 불러올 수 없습니다."}):(0,i.jsx)("div",{className:"p-5 space-y-3",children:v.map(e=>{let t=P===e.id,n=T[e.id]||[],s=e.studentPins.filter(e=>e.isPinSet).length,a=e.studentPins.length;return(0,i.jsxs)("div",{className:"rounded-xl border border-zinc-100 dark:border-zinc-800 overflow-hidden",children:[(0,i.jsxs)("div",{className:"p-3 bg-zinc-50 dark:bg-zinc-800/50",children:[(0,i.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,i.jsx)("span",{className:(0,z.cn)("text-xs font-semibold",e.isActive?"text-zinc-700 dark:text-zinc-300":"text-zinc-400 dark:text-zinc-500"),children:e.isActive?"í™
1œì„±":"비활성"}),(0,i.jsx)("span",{className:"text-sm font-medium text-zinc-800 dark:text-zinc-200 flex-1 truncate",children:e.label||"성적표 링크"}),(0,i.jsxs)("span",{className:"text-xs text-zinc-400",children:[s,"/",a,"명 설정"]})]}),(0,i.jsxs)("div",{className:"flex items-center gap-2 flex-wrap",children:[(0,i.jsxs)("button",{onClick:()=>ed(e.id,e.isActive),disabled:en===e.id||es===e.id,className:"flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg bg-white dark:bg-zinc-700 border border-zinc-200 dark:border-zinc-600 text-zinc-600 dark:text-zinc-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[(0,i.jsx)(l,{size:12}),en===e.id?"처리 중...":e.isActive?"비활성화":"활성화"]}),(0,i.jsxs)("button",{onClick:()=>ec(e.id),disabled:es===e.id||en===e.id,className:"flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-100 dark:border-red-900/50 text-red-600 dark:text-red-400 disabled:opacity-50 disabled:cursor-not-allowed",children:[(0,i.jsx)(o.Z,{size:12}),es===e.id?"삭제 중...":"삭제"]}),(0,i.jsxs)("button",{onClick:()=>W(e.id),className:"flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg bg-white dark:bg-zinc-700 border border-zinc-200 dark:border-zinc-600 text-zinc-600 dark:text-zinc-300 ml-auto",children:[t?(0,i.jsx)(x.Z,{size:12}):(0,i.jsx)(u.Z,{size:12}),y?"학생 링크 / PIN":"학생 링크"]})]})]}),t&&(0,i.jsx)("div",{className:"border-t border-zinc-100 dark:border-zinc-800",children:0===n.length?(0,i.jsx)("div",{className:"flex justify-center py-4",children:(0,i.jsx)(c.Z,{size:16,className:"animate-spin text-zinc-400"})}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("div",{className:"flex items-center justify-between px-3 py-2 bg-white dark:bg-zinc-900",children:[(0,i.jsx)("span",{className:"text-xs text-zinc-500",children:"학생별 개별 링크"}),(0,i.jsxs)("div",{className:"flex items-center gap-2",children:[y&&(0,i.jsxs)("button",{onClick:()=>M(t=>({...t,[e.id]:!t[e.id]})),className:"flex items-center gap-1 text-xs text-zinc-400",children:[Z[e.id]?(0,i.jsx)(m.Z,{size:12}):(0,i.jsx)(p.Z,{size:12}),Z[e.id]?"PIN 숨기기":"PIN 표시"]}),(0,i.jsxs)("button",{onClick:()=>ee(e.id,e.label),className:"flex items-center gap-1 text-xs text-zinc-400",children:[(0,i.jsx)(h.Z,{size:12}),"QR 인쇄"]})]})]}),(0,i.jsx)("div",{className:"divide-y divide-zinc-50 dark:divide-zinc-800/50",children:n.map(t=>{let n="".concat(j,"/report/").concat(t.studentToken);return(0,i.jsxs)("div",{"data-student-id":t.studentId,className:(0,z.cn)("transition-colors duration-700",L===t.studentId&&e.id===P?"bg-amber-50 dark:bg-amber-500/10":"bg-white dark:bg-zinc-900"),children:[(0,i.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 text-sm",children:[(0,i.jsxs)("span",{className:"text-xs text-zinc-400 w-8 text-right shrink-0",children:[t.studentNumber,"번"]}),(0,i.jsx)("span",{className:"flex-1 text-zinc-800 dark:text-zinc-200 font-medium truncate",children:t.studentName}),(0,i.jsx)("div",{className:"text-right shrink-0",children:y&&Z[e.id]?(0,i.jsx)("div",{children:t.isPinSet&&t.currentPin?(0,i.jsxs)("p",{className:"text-xs text-blue-500",children:["PIN: ",(0,i.jsx)("span",{className:"font-mono",children:t.currentPin})]}):(0,i.jsx)("p",{className:"text-xs text-zinc-400",children:"미설정"})}):(0,i.jsx)("span",{className:(0,z.cn)("text-xs",t.isPinSet?"text-zinc-600 dark:text-zinc-300 font-medium":"text-zinc-400"),children:t.isPinSet?"설정완료":"미설정"})}),(0,i.jsx)("button",{onClick:()=>et(t.studentToken),className:"flex items-center gap-1 text-xs px-2 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-500 shrink-0",title:"링크 복사",children:E===t.studentToken?(0,i.jsx)(b.Z,{size:11,className:"text-green-500"}):(0,i.jsx)(f.Z,{size:11})}),(0,i.jsx)("button",{onClick:()=>O(R===t.studentToken?null:t.studentToken),className:"flex items-center gap-1 text-xs px-2 py-1 rounded-lg bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-500 shrink-0",title:"QR 코드",children:(0,i.jsx)(g.Z,{size:11})}),(0,i.jsx)("button",{onClick:()=>el(e.id,t.studentId,t.studentName),className:"text-xs text-zinc-400 hover:text-zinc-600 px-1.5 py-1 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800 shrink-0",title:"PIN 초기화",children:(0,i.jsx)(c.Z,{size:11})})]}
1),R===t.studentToken&&(0,i.jsxs)("div",{className:"flex flex-col items-center gap-2 px-3 pb-3",children:[(0,i.jsx)("div",{className:"bg-white p-3 rounded-xl",children:(0,i.jsx)(k.t,{value:n,size:140})}),(0,i.jsx)("p",{className:"text-xs text-zinc-400 text-center truncate max-w-full px-2",children:n})]})]},t.studentId)})})]})})]},e.id)})})})]})}),Q&&"undefined"!=typeof document&&(0,r.createPortal)((0,i.jsxs)("div",{className:"print-qr-container",children:[(0,i.jsxs)("div",{className:"print-qr-header",children:[(0,i.jsx)("h1",{children:"모바일 성적표 QR코드"}),(0,i.jsx)("p",{children:F})]}),(0,i.jsx)("div",{className:"print-qr-grid",children:Q.map(e=>{let t=V.get(e.studentId),n=(null==t?void 0:t.grade)&&(null==t?void 0:t.classNum)?"".concat(t.grade,"학년 ").concat(t.classNum,"반 ").concat(e.studentNumber,"번"):"".concat(e.studentNumber,"번");return(0,i.jsxs)("div",{className:"print-qr-card",children:[(0,i.jsx)(k.t,{value:"".concat(j,"/report/").concat(e.studentToken),size:150}),(0,i.jsx)("p",{className:"print-qr-classinfo",children:n}),(0,i.jsx)("p",{className:"print-qr-name",children:e.studentName})]},e.studentId)})}),(0,i.jsx)("style",{children:"\n                        @media screen { .print-qr-container { display: none; } }\n                        @media print {\n                            body > *:not(.print-qr-container) { display: none !important; }\n                            .print-qr-container {\n                                display: block;\n                                background: white;\n                                padding: 15mm 15mm 10mm;\n                                font-family: -apple-system, sans-serif;\n                            }\n                            .print-qr-header { margin-bottom: 8mm; }\n                            .print-qr-header h1 { font-size: 16pt; font-weight: 700; margin: 0 0 2mm; }\n                            .print-qr-header p { font-size: 11pt; color: #555; margin: 0; }\n                            .print-qr-grid {\n                                display: grid;\n                                grid-template-columns: repeat(3, 1fr);\n                                gap: 8mm;\n                            }\n                            .print-qr-card {\n                                border: 1px solid #e5e7eb;\n                                border-radius: 8px;\n                                padding: 12px 8px;\n                                display: flex;\n                                flex-direction: column;\n                                align-items: center;\n                                break-inside: avoid;\n                                page-break-inside: avoid;\n                            }\n                            .print-qr-card svg { display: block; }\n                            .print-qr-classinfo { font-size: 9pt; color: #666; margin: 7px 0 2px; text-align: center; }\n                            .print-qr-name { font-size: 13pt; font-weight: 700; margin: 0; text-align: center; }\n                        }\n                    "})]}),document.body)]})}}}]);

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.