PageSourceSearch

https://seodoon-church-admin.web.app/assets/CouncilVotingPage-Sbe-jGs-.js

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

1import{j as e}from"./vendor-data-Z5doMMu-.js";import{r as n}from"./vendor-react-zNM0AU50.js";import{u as V}from"./index-D1K3lVhu.js";import{a as k}from"./councilService-CCqwDmOg.js";import{V as E}from"./council-CvBHSAtS.js";import{L as $,V as D,aa as L,U as z,K as A,ba as M,T as O,z as j,X as S}from"./vendor-ui-CW5bJ11U.js";import"./vendor-firebase-Da9KY1q_.js";import"./vendor-charts-08G1rM8P.js";function G(){const{user:r}=V(),[h,c]=n.useState([]),[o,g]=n.useState(!0),[i,d]=n.useState(!1),[x,N]=n.useState(null),[a,m]=n.useState("active");n.useEffect(()=>{u()},[]);async function u(){g(!0);const s=await k.getAll();c(s),g(!1)}const y=h.filter(s=>s.status==="active"),f=h.filter(s=>s.status==="ended"),v=a==="active"?y:f;async function w(s){confirm("투표를 마감하시겠습니까?")&&(await k.endVote(s),j.success("투표가 마감되었습니다"),u())}async function C(s){confirm("삭제하시겠습니까?")&&(await k.remove(s),j.success("삭제되었습니다"),u())}return o?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx($,{className:"w-6 h-6 animate-spin text-gray-400"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"bg-white border border-gray-200 rounded-2xl p-6 text-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-2",children:[e.jsx(D,{className:"w-7 h-7 text-blue-600"}),e.jsx("h1",{className:"text-2xl font-bold",children:"투표 / 의결"})]}),e.jsx("p",{className:"text-gray-500 text-sm",children:"당회 안건에 대한 투표 및 의결 관리"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex gap-1 bg-gray-100 rounded-lg p-1",children:[e.jsxs("button",{onClick:()=>m("active"),className:`px-4 py-2 rounded-md text-sm font-medium transition ${a==="active"?"bg-white shadow text-gray-800":"text-gray-500"}`,children:["진행중 (",y.length,")"]}),e.jsxs("button",{onClick:()=>m("ended"),className:`px-4 py-2 rounded-md text-sm font-medium transition ${a==="ended"?"bg-white shadow text-gray-800":"text-gray-500"}`,children:["마감 (",f.length,")"]})]}),e.jsxs("button",{onClick:()=>d(!0),className:"flex items-center gap-1.5 px-4 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-700",children:[e.jsx(L,{className:"w-4 h-4"})," 투표 생성"]})]}),v.length===0?e.jsx("div",{className:"bg-white rounded-xl border p-8 text-center text-gray-400",children:a==="active"?"진행중인 투표가 없습니다":"마감된 투표가 없습니다"}):e.jsx("div",{className:"grid gap-4",children:v.map(s=>e.jsxs("div",{className:"bg-white rounded-xl border p-5",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${s.status==="active"?"bg-green-100 text-green-700":"bg-gray-100 text-gray-600"}`,children:s.status==="active"?"진행중":"마감"}),e.jsx("span",{className:"px-2 py-0.5 rounded text-xs bg-blue-100 text-blue-700",children:E[s.type]||s.type}),s.anonymous&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs bg-blue-100 text-blue-700",children:"익명"})]}),e.jsx("h3",{className:"font-bold text-gray-800 text-lg",children:s.title}),s.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:s.description}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-gray-500",children:[e.jsxs("span",{children:["마감일: ",s.endDate]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(z,{className:"w-3 h-3"})," ",s.voterCount||0,"명 참여"]})]})]}),e.jsxs("div",{className:"flex items-center gap-1 ml-3",children:[e.jsx("button",{onClick:()=>N(s),className:"p-2 hover:bg-gray-100 rounded-lg",title:"ê²°ê³¼ 보기",children:e.jsx(A,{className:"w-4 h-4 text-gray-600"})}),s.status==="active"&&e.jsx("button",{onClick:()=>w(s.id),className:"p-2 hover:bg-orange-100 rounded-lg",title:"마감",children:e.jsx(M,{className:"w-4 h-4 text-orange-600"})}),e.jsx("button",{onClick:()=>C(s.id),className:"p-2 hover:bg-red-100 rounded-lg",title:"삭제",children:e.jsx(O,{className:"w-4 h-4 text-red-500"})})]})]}),s.options&&s.options.length>0&&e.jsx("div",{className:"mt-4 space-y-2",children:s.options.map(t=>{const l=s.options.reduce((b,T)=>b+(T.votes||0),0),p=l>0?Math.round((t.votes||0)/l*100):0;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm text-gray-700 w-24 truncate",children:t.text}),e.jsx("div",{className:"flex-1 bg-gray-100 rounded-full h-5 overflow-hidden",children:e.jsx("div",{className:"bg-blue-500 h-full rounded-full transition-all",style:{width:`${p}%`}})}),e.jsxs("span",{className:"text-xs text-gray-500 w-16 text-right",children:[t.votes||0,"표 (",p,"%)"]})]},t.id)})})]},s.id))}),i&&e.jsx(_,{onClose:()=>d(!1),onSave:u}),x&&e.jsx(B,{vote:x,onClose:()=>N(null)})]})}function _({onClose:r,onSave:h}){const{user:c}=V(),[o,g]=n.useState(""),[i,d]=n.useState(""),[x,N]=n.useState("yesno"),[a,m]=n.useState(["찬성","반대"]),[u,y]=n.useState(""),[f,v]=n.useState(!1),[w,C]=n.useState(!1);n.useEffect(()=>{x==="yesno"?m(["찬성","반대"]):(a.length<2||a[0]==="찬성"&&a[1]==="반대")&&m(["",""])},[x]);async function s(){if(!o.trim()||!u){j.error("제목과 마감일ì
1„ 입력하세요");return}const t=a.filter(l=>l.trim());if(t.length<2){j.error("선택지를 2개 이상 입력하세요");return}C(!0);try{await k.create({title:o,description:i,type:x,options:t.map((l,p)=>({id:`opt_${p}`,text:l,votes:0})),endDate:u,anonymous:f,status:"active",voters:[],voterCount:0,createdBy:c==null?void 0:c.uid}),j.success("투표가 생성되었습니다"),h(),r()}catch{j.error("생성 실패")}finally{C(!1)}}return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-white rounded-xl w-full max-w-lg max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[e.jsx("h3",{className:"font-bold text-lg",children:"투표 생성"}),e.jsx("button",{onClick:r,className:"p-1 hover:bg-gray-100 rounded",children:e.jsx(S,{className:"w-5 h-5"})})]}),e.jsxs("div",{className:"p-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:"제목 *"}),e.jsx("input",{value:o,onChange:t=>g(t.target.value),className:"w-full border rounded-lg px-3 py-2 text-sm"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:"설명"}),e.jsx("textarea",{value:i,onChange:t=>d(t.target.value),rows:3,className:"w-full border rounded-lg px-3 py-2 text-sm"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:"투표 유형"}),e.jsx("select",{value:x,onChange:t=>N(t.target.value),className:"w-full border rounded-lg px-3 py-2 text-sm",children:Object.entries(E).map(([t,l])=>e.jsx("option",{value:t,children:l},t))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:"마감일 *"}),e.jsx("input",{type:"date",value:u,onChange:t=>y(t.target.value),className:"w-full border rounded-lg px-3 py-2 text-sm"})]})]}),x!=="yesno"&&e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium text-gray-700 block mb-1",children:"선택지"}),a.map((t,l)=>e.jsxs("div",{className:"flex gap-2 mb-2",children:[e.jsx("input",{value:t,onChange:p=>{const b=[...a];b[l]=p.target.value,m(b)},className:"flex-1 border rounded-lg px-3 py-2 text-sm",placeholder:`선택지 ${l+1}`}),a.length>2&&e.jsx("button",{onClick:()=>m(a.filter((p,b)=>b!==l)),className:"p-2 hover:bg-red-100 rounded",children:e.jsx(S,{className:"w-4 h-4 text-red-500"})})]},l)),e.jsx("button",{onClick:()=>m([...a,""]),className:"text-sm text-blue-600 hover:underline",children:"+ 선택지 추가"})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:f,onChange:t=>v(t.target.checked),className:"rounded"}),"익명 투표"]})]}),e.jsxs("div",{className:"flex justify-end gap-2 p-4 border-t",children:[e.jsx("button",{onClick:r,className:"px-4 py-2 text-sm border rounded-lg",children:"취소"}),e.jsx("button",{onClick:s,disabled:w,className:"px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50",children:w?"생성중...":"생성"})]})]})})}function B({vote:r,onClose:h}){var o,g;const c=((o=r.options)==null?void 0:o.reduce((i,d)=>i+(d.votes||0),0))||0;return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4",children:e.jsxs("div",{className:"bg-white rounded-xl w-full max-w-lg",children:[e.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[e.jsx("h3",{className:"font-bold text-lg",children:"투표 ê²°ê³¼"}),e.jsx("button",{onClick:h,className:"p-1 hover:bg-gray-100 rounded",children:e.jsx(S,{className:"w-5 h-5"})})]}),e.jsxs("div",{className:"p-4",children:[e.jsx("h4",{className:"font-bold text-gray-800 mb-1",children:r.title}),r.description&&e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:r.description}),e.jsx("div",{className:"space-y-3",children:(g=r.options)==null?void 0:g.map(i=>{const d=c>0?Math.round((i.votes||0)/c*100):0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between text-sm mb-1",children:[e.jsx("span",{className:"font-medium",children:i.text}),e.jsxs("span",{className:"text-gray-500",children:[i.votes||0,"표 (",d,"%)"]})]}),e.jsx("div",{className:"bg-gray-100 rounded-full h-6 overflow-hidden",children:e.jsx("div",{className:"bg-blue-500 h-full rounded-full transition-all",style:{width:`${d}%`}})})]},i.id)})}),e.jsxs("p",{className:"text-sm text-gray-500 mt-4 text-center",children:["총 ",c,"표 · ",r.voterCount||0,"명 참여"]})]}),e.jsx("div",{className:"flex justify-end p-4 border-t",children:e.jsx("button",{onClick:h,className:"px-4 py-2 text-sm border rounded-lg",children:"닫기"})})]})})}export{G as CouncilVotingPage,G 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.