PageSourceSearch

https://seodoon-church-admin.web.app/assets/EducationDashboardPage-BAcdkDcL.js

js seodoon-church-admin.web.app collected 2026-10-03 12:36:57 UTC 5,072 bytes, 1 lines download raw bytes

1import{j as e}from"./vendor-data-Z5doMMu-.js";import{r as u,b as w}from"./vendor-react-zNM0AU50.js";import{x as C,E}from"./index-D1K3lVhu.js";import{D as k}from"./DepartmentSelectorBar-EFx-1H4v.js";import{e as m}from"./educationService-BxXX95Q0.js";import{U as b,y as g,J as p,K as h}from"./vendor-ui-CW5bJ11U.js";import"./vendor-firebase-Da9KY1q_.js";import"./vendor-charts-08G1rM8P.js";function M(){const{selectedDepartment:t,isAllSelected:n}=C(),[r,o]=u.useState([]),[l,i]=u.useState(!0),c=w();u.useEffect(()=>{j()},[t]);const j=async()=>{i(!0);try{if(n){const s=await m.getAllDepartmentStats();o(s)}else if(t){const s=await m.getDepartmentStats(t.firestorePrefix,t.name);o([s])}}catch(s){console.error("통계 로딩 실패:",s)}finally{i(!1)}},f=r.reduce((s,a)=>s+a.totalStudents,0),N=r.reduce((s,a)=>s+a.activeStudents,0),v=r.reduce((s,a)=>s+a.totalTeachers,0),y=r.reduce((s,a)=>s+a.totalGroups,0);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"교회학교 관리"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:n?"전체 부서 현황":`${t==null?void 0:t.name} 현황`})]}),e.jsx(k,{}),e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsx(d,{icon:b,label:"전체 학생",value:f,sub:`활동 ${N}명`,color:"blue",loading:l}),e.jsx(d,{icon:g,label:"교사",value:v,color:"green",loading:l}),e.jsx(d,{icon:p,label:"반",value:y,color:"purple",loading:l}),e.jsx(d,{icon:h,label:"출석률",value:"-",sub:"최근 주일",color:"amber",loading:l})]}),n&&!l&&e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-6",children:[e.jsx("h2",{className:"text-lg font-bold text-gray-900 mb-4",children:"부서별 현황"}),e.jsx("div",{className:"grid grid-cols-2 lg:grid-cols-3 gap-4",children:r.map(s=>{const a=E.find(S=>S.id===s.departmentId);return e.jsxs("div",{className:"p-4 rounded-xl border border-gray-100 hover:border-gray-200 transition-colors cursor-pointer",onClick:()=>c("/education/students"),children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx("div",{className:"w-3 h-3 rounded-full",style:{backgroundColor:(a==null?void 0:a.color)||"#6b7280"}}),e.jsx("span",{className:"font-semibold text-gray-900",children:s.departmentName})]}),e.jsxs("div",{className:"space-y-1 text-sm text-gray-600",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"학생"}),e.jsxs("span",{className:"font-medium text-gray-900",children:[s.totalStudents,"명"]})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"활동"}),e.jsxs("span",{className:"font-medium text-green-600",children:[s.activeStudents,"명"]})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"교사"}),e.jsxs("span",{className:"font-medium text-gray-900",children:[s.totalTeachers,"명"]})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"반"}),e.jsxs("span",{className:"font-medium text-gray-900",children:[s.totalGroups,"개"]})]})]})]},s.departmentId)})})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-6",children:[e.jsx("h2",{className:"text-lg font-bold text-gray-900 mb-4",children:"빠른 액션"}),e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-3",children:[e.jsx(x,{label:"출석체크",icon:p,color:"blue",onClick:()=>c("/education/attendance")}),e.jsx(x,{label:"학생등록",icon:b,color:"green",onClick:()=>c("/education/students")}),e.jsx(x,{label:"교사관리",icon:g,color:"purple",onClick:()=>c("/education/teachers")}),e.jsx(x,{label:"보고서",icon:h,color:"amber",onClick:()=>c("/education/reports")})]})]})]})}function d({icon:t,label:n,value:r,sub:o,color:l,loading:i}){const c={blue:"bg-blue-50 text-blue-600",green:"bg-green-50 text-green-600",purple:"bg-blue-50 text-blue-600",amber:"bg-blue-50 text-blue-600"};return e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-5",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx("div",{className:`w-10 h-10 rounded-lg flex items-center justify-center ${c[l]}`,children:e.jsx(t,{className:"w-5 h-5"})}),e.jsx("span",{className:"text-sm text-gray-500",children:n})]}),i?e.jsx("div",{className:"h-8 bg-gray-100 rounded animate-pulse"}):e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold text-gray-900 tabular-nums",children:typeof r=="number"?`${r}명`:r}),o&&e.jsx("p",{className:"text-xs text-gray-400 mt-1",children:o})]})]})}function x({label:t,icon:n,color:r,onClick:o}){const l={blue:"bg-blue-50 hover:bg-blue-100 text-blue-700",green:"bg-green-50 hover:bg-green-100 text-green-700",purple:"bg-blue-50 hover:bg-blue-100 text-blue-700",amber:"bg-blue-50 hover:bg-blue-100 text-blue-700"};return e.jsxs("button",{onClick:o,className:`flex items-center gap-2 px-4 py-3 rounded-xl text-sm font-medium transition-colors ${l[r]}`,children:[e.jsx(n,{className:"w-4 h-4"}),t]})}export{M as EducationDashboardPage};

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.