PageSourceSearch

https://www.ic-pbl.com/assets/AdminOrgComparisonPage-DVEjHpdF.js

js ic-pbl.com collected 2026-10-09 02:53:15 UTC 10,400 bytes, 4 lines download raw bytes

1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/orgComparisonPdf-DMhcaKdP.js","assets/pdfKoreanFont-BEcbStsP.js","assets/index-DArpIf0g.js","assets/vendor-ui-BTq5TDLN.js","assets/vendor-sentry-BFHQO6cl.js","assets/vendor-react-65r6d5Wi.js","assets/vendor-supabase-DNBNrwrO.js","assets/vendor-charts-D1MhMD93.js","assets/vendor-editor-DdE53h-I.js","assets/index-D90mv9cg.css","assets/pdfLayout-CAI7n3Rd.js"])))=>i.map(i=>d[i]);
2import{a as S,U as k,G as C,m as T,s as $,t as u,_ as U}from"./index-DArpIf0g.js";import{j as e}from"./vendor-ui-BTq5TDLN.js";import{a as i}from"./vendor-sentry-BFHQO6cl.js";import{A as R}from"./AdminPageHeader-DP1d-s2m.js";import{C as V}from"./card-B8wgubsl.js";import{B as G}from"./badge-KKutdbJO.js";import{c as K}from"./skeletons-C6Pk_gAO.js";import{A as h}from"./AdminStatCard-C5cJOdRl.js";import{A as Y}from"./AdminEmptyState-BaPVhu--.js";import{D as z}from"./download-B0RjiA2V.js";import{F as H}from"./file-text-DSg5sT3k.js";import{B as A}from"./building-2-D8cwCxLJ.js";import{L as q}from"./library-D4eZl3Fj.js";import{E as J}from"./eye-MYcDDGOP.js";import{A as Q}from"./arrow-up-down-C0r40jeU.js";import"./vendor-react-65r6d5Wi.js";import"./vendor-supabase-DNBNrwrO.js";import"./vendor-charts-D1MhMD93.js";import"./vendor-editor-DdE53h-I.js";const N={UNIVERSITY:"대학",COMPANY:"기업",INSTITUTION:"기관",CONSORTIUM:"컨소시엄"};function x(c){return c>=1e4?`${(c/1e3).toFixed(0)}K`:c>=1e3?`${(c/1e3).toFixed(1)}K`:c.toLocaleString()}function fe(){const[c,F]=i.useState([]),[I,v]=i.useState(!0),[f,P]=i.useState("member_count"),[b,y]=i.useState(!1),[g,E]=i.useState(!1),[j,D]=i.useState([]);i.useEffect(()=>{async function t(){v(!0);try{const[{data:o,error:a},{data:s}]=await Promise.all([$.rpc("get_org_comparison_stats"),$.from("consortium_memberships").select("consortium_id, member_id")]);if(a)throw a;F(o??[]),D(s??[])}catch{u.error("기관별 성과 데이터를 불러오지 못했습니다.")}finally{v(!1)}}t()},[]);const r=i.useMemo(()=>{if(!g||j.length===0)return c;const t=new Map;for(const s of j){const d=t.get(s.member_id)??[];d.push(s.consortium_id),t.set(s.member_id,d)}const o=new Set(j.map(s=>s.member_id)),a=new Map(c.map(s=>[s.org_id,{...s}]));for(const s of c){if(!o.has(s.org_id))continue;const d=t.get(s.org_id)??[];for(const _ of d){const n=a.get(_);n&&(n.member_count+=s.member_count,n.content_count+=s.content_count,n.total_views+=s.total_views,n.ai_usage_count+=s.ai_usage_count,n.ai_cost+=s.ai_cost,n.enrollment_count+=s.enrollment_count,n.completion_count+=s.completion_count,n.community_posts+=s.community_posts)}}return Array.from(a.values()).filter(s=>!o.has(s.org_id))},[c,j,g]),p=i.useMemo(()=>[...r].sort((t,o)=>{const a=t[f],s=o[f];return b?a-s:s-a}),[r,f,b]),m=i.useMemo(()=>({orgs:r.length,members:r.reduce((t,o)=>t+o.member_count,0),contents:r.reduce((t,o)=>t+o.content_count,0),views:r.reduce((t,o)=>t+o.total_views,0),enrollments:r.reduce((t,o)=>t+o.enrollment_count,0),completions:r.reduce((t,o)=>t+o.completion_count,0)}),[r]),w=i.useMemo(()=>({member_count:Math.max(...r.map(t=>t.member_count),1),content_count:Math.max(...r.map(t=>t.content_count),1),total_views:Math.max(...r.map(t=>t.total_views),1),enrollment_count:Math.max(...r.map(t=>t.enrollment_count),1)}),[r]),L=t=>{f===t?y(!b):(P(t),y(!1))},M=()=>{if(p.length===0)return;const t=`순위,기관명,유형,구성원,콘텐츠,조회수,평점,AI사용,수강,수료,커뮤니티
3`,o=p.map((n,O)=>`${O+1},"${n.org_name}",${N[n.org_type]||n.org_type},${n.member_count},${n.content_count},${n.total_views},${Number(n.avg_rating).toFixed(1)},${n.ai_usage_count},${n.enrollment_count},${n.completion_count},${n.community_posts}`).join(`
4`),a="\uFEFF",s=new Blob([a+t+o],{type:"text/csv;charset=utf-8;"}),d=URL.createObjectURL(s),_=document.createElement("a");_.href=d,_.download=`기관별_성과비교_${new Date().toISOString().slice(0,10)}.csv`,_.click(),URL.revokeObjectURL(d),u.success("CSV 파일이 다운로드되었습니다.")},B=async()=>{if(p.length!==0){u.loading("PDF 생성 중...");try{const{buildOrgComparisonPdf:t}=await U(async()=>{const{buildOrgComparisonPdf:a}
4=await import("./orgComparisonPdf-DMhcaKdP.js");return{buildOrgComparisonPdf:a}},__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10]));(await t(p,m,{typeLabel:a=>N[a]||a})).save(`IC-PBL_Performance_Report_${new Date().toISOString().slice(0,10)}.pdf`),u.dismiss(),u.success("PDF 리포트가 다운로드되었습니다.")}catch{u.dismiss(),u.error("PDF 생성에 실패했습니다.")}}},l=({field:t,label:o})=>e.jsxs("button",{className:`flex items-center gap-0.5 font-medium ${f===t?"text-indigo-600 dark:text-indigo-400":""}`,onClick:()=>L(t),children:[o,e.jsx(Q,{className:"w-3 h-3"})]});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs(R,{title:"기관별 성과 비교",description:"참여 기관 간 핵심 성과 지표를 비교 분석합니다.",children:[e.jsxs("label",{className:"flex items-center gap-2 text-sm cursor-pointer mr-2 px-3 py-1.5 rounded-lg border border-border hover:bg-muted/40",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:t=>E(t.target.checked),className:"w-4 h-4"}),e.jsx("span",{children:"컨소시엄 단위로 보기"})]}),e.jsxs(S,{variant:"outline",size:"sm",onClick:M,disabled:c.length===0,children:[e.jsx(z,{className:"w-4 h-4 mr-1.5"}),"CSV"]}),e.jsxs(S,{variant:"outline",size:"sm",onClick:B,disabled:c.length===0,children:[e.jsx(H,{className:"w-4 h-4 mr-1.5"}),"PDF"]})]}),I?e.jsx(K,{rows:5,cols:8}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-6 gap-4",children:[e.jsx(h,{label:"참여 기관",value:m.orgs,icon:e.jsx(A,{className:"w-4 h-4 text-indigo-600"})}),e.jsx(h,{label:"총 구성원",value:x(m.members),icon:e.jsx(k,{className:"w-4 h-4 text-blue-500"})}),e.jsx(h,{label:"총 콘텐츠",value:x(m.contents),icon:e.jsx(q,{className:"w-4 h-4 text-emerald-500"})}),e.jsx(h,{label:"총 조회수",value:x(m.views),icon:e.jsx(J,{className:"w-4 h-4 text-purple-500"})}),e.jsx(h,{label:"총 수강",value:x(m.enrollments),icon:e.jsx(C,{className:"w-4 h-4 text-amber-500"})}),e.jsx(h,{label:"총 수료",value:x(m.completions),icon:e.jsx(C,{className:"w-4 h-4 text-emerald-500"})})]}),e.jsxs(V,{className:"overflow-hidden border border-border",children:[e.jsxs("div",{className:"p-4 border-b border-border",children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground",children:"기관별 KPI 비교"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:"컬럼 헤더를 클릭하면 정렬됩니다"})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm text-left",children:[e.jsx("thead",{className:"text-xs text-muted-foreground bg-muted uppercase border-b border-border",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 font-medium w-8",children:"#"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"기관"}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"member_count",label:"구성원"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"content_count",label:"콘텐츠"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"total_views",label:"조회수"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"avg_rating",label:"평점"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"ai_usage_count",label:"AI 사용"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"enrollment_count",label:"수강"})}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:e.jsx(l,{field:"community_posts",label:"커뮤니티"})})]})}),e.jsx("tbody",{className:"divide-y divide-border",children:p.length>0?p.map((t,o)=>e.jsxs("tr",{className:"hover:bg-muted",children:[e.jsx("td",{className:"px-4 py-3 text-muted-foreground font-medium",children:o+1}),e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"font-medium text-foreground",children:t.org_name}),e.jsx(G,{variant:"outline",className:"text-[10px] mt-0.5",children:N[t.org_type]||t.org_type})]}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx("div",{className:"w-16 bg-muted rounded-full h-1.5",children:e.jsx("div",{className:"bg-blue-500 h-1.5 rounded-full",style:{width:`${t.member_count/w.member_count*100}%`}})}),e.jsx("span",{className:"font-medium text-foreground w-10 text-right",children:t.member_count})]})}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx("div",{className:"w-16 bg-muted rounded-full h-1.5",children:e.jsx("div",{className:"bg-emerald-500 h-1.5 rounded-full",style:{width:`${t.content_count/w.content_count*100}%`}})}),e.jsx("span",{className:"font-medium text-foreground w-10 text-right",children:t.content_count})]})}),e.jsx("td",{className:"px-4 py-3 text-right font-medium text-foreground",children:x(t.total_views)}),e.jsx("td",{className:"px-4 py-3 text-right",children:Number(t.avg_rating)>0?e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(T,{className:"w-3.5 h-3.5 text-amber-500 fill-amber-500"}),e.jsx("span",{className:"text-foreground",children:Number(t.avg_rating).toFixed(1)})]}):e.jsx("span",{className:"text-muted-foreground",children:"-"})}),e.jsxs("td",{className:"px-4 py-3 text-right",children:[e.jsx("div",{className:"text-foreground",children:x(t.ai_usage_count)}
4),Number(t.ai_cost)>0&&e.jsxs("div",{className:"text-[10px] text-muted-foreground",children:["$",Number(t.ai_cost).toFixed(2)]})]}),e.jsxs("td",{className:"px-4 py-3 text-right",children:[e.jsx("div",{className:"text-foreground",children:t.enrollment_count}),t.enrollment_count>0&&e.jsxs("div",{className:"text-[10px] text-muted-foreground",children:["수료 ",t.completion_count," (",Math.round(t.completion_count/t.enrollment_count*100),"%)"]})]}),e.jsx("td",{className:"px-4 py-3 text-right font-medium text-foreground",children:t.community_posts})]},t.org_id)):e.jsx("tr",{children:e.jsx("td",{colSpan:9,children:e.jsx(Y,{icon:e.jsx(A,{className:"w-8 h-8"}),title:"승인된 참여 기관이 없습니다"})})})})]})})]})]})]})}export{fe as AdminOrgComparisonPage};

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.