PageSourceSearch

https://seodoon-church-admin.web.app/assets/AttendanceManagementPage-DSadnxWI.js

js seodoon-church-admin.web.app collected 2026-10-03 12:37:01 UTC 6,920 bytes, 1 lines download raw bytes

1import{j as e}from"./vendor-data-Z5doMMu-.js";import{r as i}from"./vendor-react-zNM0AU50.js";import{x as O}from"./index-D1K3lVhu.js";import{D as f}from"./DepartmentSelectorBar-EFx-1H4v.js";import{e as u}from"./educationService-BxXX95Q0.js";import{J as j,c as v,ae as z,z as h}from"./vendor-ui-CW5bJ11U.js";import"./vendor-firebase-Da9KY1q_.js";import"./vendor-charts-08G1rM8P.js";function Q(){const{selectedDepartment:o,isAllSelected:N}=O(),[l,w]=i.useState("check"),[c,S]=i.useState([]),[m,k]=i.useState([]),[C,p]=i.useState(!0),[b,E]=i.useState(()=>new Date().toISOString().split("T")[0]),[y,M]=i.useState("주일예배"),[x,g]=i.useState({}),[A,G]=i.useState({});i.useEffect(()=>{o&&I()},[o]);const I=async()=>{if(o){p(!0);try{const[t,n]=await Promise.all([u.getStudents(o.firestorePrefix),u.getGroups(o.firestorePrefix)]);S(t.filter(s=>s.status==="활동")),k(n);const r={};t.forEach(s=>{s.status==="활동"&&(r[s.id]="출석")}),g(r)}catch(t){console.error("데이터 로딩 실패:",t)}finally{p(!1)}}},D=async()=>{if(!o){h.error("부서를 선택해주세요");return}const t=c.map(a=>({studentId:a.id,studentName:a.name,groupId:a.groupId,groupName:a.groupName,status:x[a.id]||"출석",memo:A[a.id]||""})),n=t.filter(a=>a.status==="출석").length,r=t.filter(a=>a.status==="결석").length,s=t.filter(a=>a.status==="지각").length,d=t.filter(a=>a.status==="사유결석").length;try{await u.createAttendance(o.firestorePrefix,{date:b,type:y,records:t,totalPresent:n,totalAbsent:r,totalLate:s,totalExcused:d}),h.success(`출석이 저장되었습니다 (출석 ${n} / 결석 ${r})`)}catch{h.error("출석 저장에 실패했습니다")}},P=m.length>0?m.map(t=>({group:t,students:c.filter(n=>n.groupId===t.id)})).concat([{group:{id:"",name:"미배정",sortOrder:999},students:c.filter(t=>!t.groupId||!m.find(n=>n.id===t.groupId))}]).filter(t=>t.students.length>0):[{group:{id:"",name:"전체",sortOrder:0},students:c}],T=[{id:"check",label:"출석체크"},{id:"history",label:"출석기록"},{id:"stats",label:"출석통계"}];return N?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:"부서를 선택하면 출석체크를 시작할 수 있습니다"})]}),e.jsx(f,{}),e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-12 text-center text-gray-400",children:[e.jsx(j,{className:"w-12 h-12 mx-auto mb-3 opacity-30"}),e.jsx("p",{children:"출석체크를 위해 부서를 선택해주세요"})]})]}):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:o==null?void 0:o.name})]}),e.jsx(f,{}),e.jsx("div",{className:"flex gap-1 bg-gray-100 p-1 rounded-lg w-fit",children:T.map(t=>e.jsx("button",{onClick:()=>w(t.id),className:`px-4 py-2 text-sm font-medium rounded-md transition-colors ${l===t.id?"bg-white text-gray-900 shadow-sm":"text-gray-500 hover:text-gray-700"}`,children:t.label},t.id))}),l==="check"&&e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-4 bg-white rounded-xl border border-gray-200 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(v,{className:"w-4 h-4 text-gray-400"}),e.jsx("input",{type:"date",value:b,onChange:t=>E(t.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20"})]}),e.jsxs("select",{value:y,onChange:t=>M(t.target.value),className:"px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20",children:[e.jsx("option",{value:"주일예배",children:"주일예배"}),e.jsx("option",{value:"수요예배",children:"수요예배"}),e.jsx("option",{value:"금요예배",children:"금요예배"}),e.jsx("option",{value:"특별예배",children:"특별예배"})]}),e.jsx("div",{className:"ml-auto",children:e.jsxs("button",{onClick:D,className:"flex items-center gap-2 px-5 py-2.5 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 transition-colors",children:[e.jsx(z,{className:"w-4 h-4"}),"저장"]})})]}),C?e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-12 text-center text-gray-400",children:[e.jsx("div",{className:"inline-block w-8 h-8 border-2 border-gray-200 border-t-blue-500 rounded-full animate-spin mb
1-3"}),e.jsx("p",{children:"학생 목록을 불러오는 중..."})]}):P.map(({group:t,students:n})=>e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3 bg-gray-50 border-b border-gray-200",children:[e.jsxs("span",{className:"font-medium text-gray-900",children:[t.name," (",n.length,"명)"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>{const r={...x};n.forEach(s=>{r[s.id]="출석"}),g(r)},className:"px-2 py-1 text-xs bg-green-100 text-green-700 rounded hover:bg-green-200",children:"전체출석"}),e.jsx("button",{onClick:()=>{const r={...x};n.forEach(s=>{r[s.id]="결석"}),g(r)},className:"px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200",children:"전체결석"})]})]}),e.jsx("div",{className:"divide-y divide-gray-100",children:n.map(r=>e.jsxs("div",{className:"flex items-center gap-3 px-4 py-3",children:[e.jsx("span",{className:"w-20 font-medium text-gray-900 truncate",children:r.name}),e.jsx("span",{className:"w-12 text-xs text-gray-400",children:r.grade||""}),e.jsx("div",{className:"flex gap-1 ml-auto",children:["출석","결석","지각","사유결석"].map(s=>{const d=(x[r.id]||"출석")===s,a={출석:d?"bg-green-500 text-white":"bg-gray-100 text-gray-500 hover:bg-green-100",결석:d?"bg-red-500 text-white":"bg-gray-100 text-gray-500 hover:bg-red-100",지각:d?"bg-yellow-500 text-white":"bg-gray-100 text-gray-500 hover:bg-yellow-100",사유결석:d?"bg-blue-500 text-white":"bg-gray-100 text-gray-500 hover:bg-blue-100"};return e.jsx("button",{onClick:()=>g($=>({...$,[r.id]:s})),className:`px-2.5 py-1.5 text-xs rounded-lg font-medium transition-colors ${a[s]}`,children:s==="사유결석"?"사유":s},s)})})]},r.id))})]},t.id||"unassigned"))]}),l==="history"&&e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-12 text-center text-gray-400",children:[e.jsx(v,{className:"w-12 h-12 mx-auto mb-3 opacity-30"}),e.jsx("p",{children:"출석 기록 페이지 (구현 예정)"})]}),l==="stats"&&e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-12 text-center text-gray-400",children:[e.jsx(j,{className:"w-12 h-12 mx-auto mb-3 opacity-30"}),e.jsx("p",{children:"출석 통계 페이지 (구현 예정)"})]})]})}export{Q as AttendanceManagementPage};

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.