PageSourceSearch

https://seodoon-church-admin.web.app/assets/ErrorReportsPage-CLcwCKS-.js

js seodoon-church-admin.web.app collected 2026-10-03 12:36:43 UTC 12,099 bytes, 2 lines download raw bytes

1import{j as e}from"./vendor-data-Z5doMMu-.js";import{r as i}from"./vendor-react-zNM0AU50.js";import{q as L,l as M,x as U,m as _,u as q,k as v,y as $}from"./vendor-firebase-Da9KY1q_.js";import{d as u}from"./index-D1K3lVhu.js";import{R as f,D as z,e as w,i as O,ar as V,aT as I,S as X,X as G,T as H}from"./vendor-ui-CW5bJ11U.js";import"./vendor-charts-08G1rM8P.js";function ee(){const[j,C]=i.useState([]),[o,S]=i.useState([]),[b,y]=i.useState(!0),[m,k]=i.useState(""),[x,T]=i.useState(""),[h,R]=i.useState(""),[t,c]=i.useState(null),[n,E]=i.useState({total:0,new:0,progress:0,resolved:0,auto:0,manual:0}),g=async()=>{y(!0);try{const s=L(M(u,"error_reports"),U("createdAt","desc")),r=(await _(s)).docs.map(l=>({id:l.id,...l.data()}));C(r),E({total:r.length,new:r.filter(l=>l.status==="new").length,progress:r.filter(l=>l.status==="progress").length,resolved:r.filter(l=>l.status==="resolved").length,auto:r.filter(l=>l.type==="auto"||l.type==="promise").length,manual:r.filter(l=>l.type==="manual").length})}catch(s){console.error("Failed to fetch error reports:",s)}finally{y(!1)}};i.useEffect(()=>{g()},[]),i.useEffect(()=>{let s=j;m&&(s=s.filter(a=>a.status===m)),x&&(x==="auto"?s=s.filter(a=>a.type==="auto"||a.type==="promise"):s=s.filter(a=>a.type===x)),h&&(s=s.filter(a=>{var r;return((r=a.timestamp)==null?void 0:r.split("T")[0])===h})),S(s)},[j,m,x,h]);const N=async(s,a)=>{try{await q(v(u,"error_reports",s),{status:a}),await g(),(t==null?void 0:t.id)===s&&c({...t,status:a})}catch(r){console.error("Failed to update status:",r),alert("상태 업데이트 실패")}},F=async s=>{if(confirm("정말 삭제하시겠습니까?"))try{await $(v(u,"error_reports",s)),c(null),await g()}catch(a){console.error("Failed to delete report:",a),alert("삭제 실패")}},D=s=>{switch(s){case"new":return e.jsx("span",{className:"px-2 py-0.5 bg-red-100 text-red-700 rounded-full text-xs font-medium",children:"신규"});case"progress":return e.jsx("span",{className:"px-2 py-0.5 bg-yellow-100 text-yellow-700 rounded-full text-xs font-medium",children:"처리중"});case"resolved":return e.jsx("span",{className:"px-2 py-0.5 bg-green-100 text-green-700 rounded-full text-xs font-medium",children:"해결됨"});default:return null}},A=s=>s==="auto"||s==="promise"?e.jsx("span",{className:"px-2 py-0.5 bg-blue-100 text-blue-700 rounded-full text-xs font-medium",children:"자동 수집"}):e.jsx("span",{className:"px-2 py-0.5 bg-blue-100 text-blue-700 rounded-full text-xs font-medium",children:"사용자 신고"}),P=()=>{const s=["상태","유형","메시지","페이지","사용자","기기","발생시간"],a=o.map(d=>[d.status==="new"?"신규":d.status==="progress"?"처리중":"해결됨",d.type==="manual"?"사용자신고":"자동수집",d.message,d.page||d.url,d.userEmail||"비로그인",d.isMobile?"모바일":"PC",d.localTime]),r=[s.join(","),...a.map(d=>d.map(B=>`"${String(B).replace(/"/g,'""')}"`).join(","))].join(`
2`),l=new Blob(["\uFEFF"+r],{type:"text/csv;charset=utf-8;"}),p=document.createElement("a");p.href=URL.createObjectURL(l),p.download=`오류신고_${new Date().toISOString().split("T")[0]}.csv`,p.click()};return e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",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.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:g,className:"flex items-center gap-2 px-4 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 text-sm",children:[e.jsx(f,{className:`w-4 h-4 ${b?"animate-spin":""}`}),"새로고침"]}),e.jsxs("button",{onClick:P,className:"flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 text-sm",children:[e.jsx(z,{className:"w-4 h-4"}),"CSV 다운로드"]})]})]}),e.jsxs("div",{className:"grid grid-cols-6 gap-4",children:[e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-gray-100 rounded-lg",children:e.jsx(w,{className:"w-5 h-5 text-gray-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"전체"}),e.jsx("p",{className:"text-xl font-bold text-gray-900",children:n.total})]})]})}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-red-100 rounded-lg",children:e.jsx(w,{className:"w-5 h-5 text-red-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"신규"}),e.jsx("p",{className:"text-xl font-bold text-red-600",children:n.new})]})]})}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-yellow-100 rounded-lg",children:e.jsx(O,{className:"w-5 h-5 text-yellow-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"처리중"}),e.jsx("p",{className:"text-xl font-bold text-yellow-600",children:n.progress})]})]})}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-green-100 rounded-lg",children:e.jsx(V,{className:"w-5 h-5 text-green-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"해결됨"}),e.jsx("p",{className:"text-xl font-bold text-green-600",children:n.resolved})]})]})}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-blue-100 rounded-lg",children:e.jsx(I,{className:"w-5 h-5 text-blue-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"자동 수집"}),e.jsx("p",{className:"text-xl font-bold text-blue-600",children:n.auto})]})]})}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 p-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-2 bg-blue-50 rounded-lg",children:e.jsx(X,{className:"w-5 h-5 text-blue-600"})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-500",children:"사용자 신고"}),e.jsx("p",{className:"text-xl font-bold text-blue-600",children:n.manual})]})]})})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-gray-200 p-4 flex flex-wrap gap-4",children:[e.jsxs("select",{value:m,onChange:s=>k(s.target.value),className:"px-3 py-2 border rounded-lg text-sm",children:[e.jsx("option",{value:"",children:"모든 상태"}),e.jsx("option",{value:"new",children:"신규"}),e.jsx("option",{value:"progress",children:"처리중"}),e.jsx("option",{value:"resolved",children:"해결됨"})]}),e.jsxs("select",{value:x,onChange:s=>T(s.target.value),className:"px-3 py-2 border rounded-lg text-sm",children:[e.jsx("option",{value:"",children:"모든 유형"}),e.jsx("option",{value:"auto",children:"자동 수집"}),e.jsx("option",{value:"manual",children:"사용자 신고"})]}),e.jsx("input",{type:"date",value:h,onChange:s=>R(s.target.value),className:"px-3 py-2 border rounded-lg text-sm"}),e.jsxs("span",{className:"flex items-center text-sm text-gray-500",children:["총 ",o.length,"건"]})]}),e.jsx("div",{className:"bg-white rounded-xl border border-gray-200 overflow-hidden",children:b?e.jsxs("div",{className:"p-8 text-center text-gray-500",children:[e.jsx(f,{className:"w-6 h-6 animate-spin mx-auto mb-2"}),"로딩 중..."]}):o.length===0?e.jsx("div",{className:"p-8 text-center text-gray-500",children:"오류 신고가 없습니다"}):e.jsx("div",{className:"divide-y divide-gray-200",children:o.map(s=>e.jsx("div",{className:"p-4 hover:bg-gray-50 cursor-pointer transition-colors",onClick:()=>c(s),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[D(s.status),A(s.type),e.jsx("span",{className:"text-xs text-gray-400",children:s.isMobile?"📱 모바일":"💻 PC"})]}),e.jsx("p",{className:"text-sm font-medium text-gray-900 truncate",children:s.message||"알 수 없는 에러"}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:s.page||s.url||""})]}),e.jsxs("div",{className:"text-right flex-shrink-0",children:[e.jsx("p",{className:"text-xs text-gray-400",children:s.localTime||""}),s.userEmail&&e.jsx("p",{className:"text-xs text-blue-500 mt-1",children:s.userEmail})]})]})},s.id))})}),t&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",onClick:()=>c(null),children:e.jsxs("div",{className:"bg-white rounded-xl w-full max-w-2xl max-h-[90vh] overflow-hidden",onClick:s=>s.stopPropagation(),children:[e.jsxs("div",{className:"p-4 border-b flex items-center justify-between",children:[e.jsx("h3",{className:"font-bold text-lg",children:"오류 상세"}),e.jsx("button",{onClick:()=>c(null),className:"text-gray-500 hover:text-gray-700",children:e.jsx(G,{className:"w-6 h-6"})})]}),e.jsxs("div",{className:"p-4 overflow-y-auto max-h-[60vh] space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"에러 메시지"}),e.jsx("p",{className:"text-sm font-medium text-gray-900 bg-gray-50 p-3 rounded-lg mt-1",children:t.message||"-"})]}),t.detail&&e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"상세 내용"}),e.jsx("p",{className:"text-sm text-gray-700 bg-gray-50 p-3 rounded-lg mt-1 whitespace-pre-wrap",children:t.detail})]}),t.stack&&e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"스택 트레이스"}),e.jsx("pre",{className:"text-xs bg-gray-900 text-green-400 p-3 rounded-lg mt-1 overflow-x-auto",children:t.stack})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"페이지"}),e.jsx("p",{className:"text-sm text-gray-700 mt-1",children:t.page||"-"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"URL"}),e.jsx("p",{className:"text-sm text-gray-700 mt-1 break-all",children:t.url||"-"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"기기"}),e.jsxs("p",{className:"text-sm text-gray-700 mt-1",children:[t.isMobile?"모바일":"PC"," 
2(",t.screenSize||"-",")"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"발생 시간"}),e.jsx("p",{className:"text-sm text-gray-700 mt-1",children:t.localTime||"-"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"사용자"}),e.jsx("p",{className:"text-sm text-gray-700 mt-1",children:t.userEmail||"비로그인"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"유형"}),e.jsx("p",{className:"text-sm text-gray-700 mt-1",children:t.type==="auto"||t.type==="promise"?"자동 수집":"사용자 신고"})]})]}),t.userAgent&&e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-gray-500",children:"User Agent"}),e.jsx("p",{className:"text-xs text-gray-500 bg-gray-50 p-2 rounded mt-1 break-all",children:t.userAgent})]})]}),e.jsxs("div",{className:"p-4 border-t flex justify-end gap-2",children:[e.jsx("button",{onClick:()=>N(t.id,"progress"),className:"px-4 py-2 bg-yellow-500 text-white rounded-lg text-sm hover:bg-yellow-600",children:"처리중"}),e.jsx("button",{onClick:()=>N(t.id,"resolved"),className:"px-4 py-2 bg-green-500 text-white rounded-lg text-sm hover:bg-green-600",children:"해결됨"}),e.jsx("button",{onClick:()=>F(t.id),className:"px-4 py-2 bg-red-500 text-white rounded-lg text-sm hover:bg-red-600",children:e.jsx(H,{className:"w-4 h-4"})})]})]})})]})}export{ee as ErrorReportsPage};

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.