1"use strict";(self.webpackChunkstudent_management_app=self.webpackChunkstudent_management_app||[]).push([[3758],{53758:(e,t,a)=>{a.r(t),a.d(t,{default:()=>q});var s=a(9950),n=a(23849),r=a(56600),l=a(29402),i=a(32398),d=a(3939),o=a(35320),c=a(33720),u=a(81714),m=a(9401),x=a(73814),g=a(45532),h=a(87949),p=a(5588),v=a(25941),f=a(69212),b=a(81095),j=a(95575),y=a(75459),w=a(72528),N=a(606),S=a(65253),C=a(47138),D=a(60378),A=a(44414);const k=["#2a78d6","#1baf7a","#eda100","#008300","#4a3aa7","#e34948","#e87ba4","#eb6834"],P=e=>String(e||"").trim().toLowerCase().split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" "),M={male:"Male",female:"Female",other:"Other","prefer not to say":"Prefer not to say"},L=["Male","Female","Other","Prefer not to say"],E={Male:k[0],Female:k[1],Other:k[2],"Prefer not to say":k[3],Unspecified:"#98968f"},O=(e,t)=>t>0?Math.round(e/t*100):0,$=()=>(0,A.jsxs)("span",{className:"inline-flex items-center gap-1.5 rounded-full bg-green-50 px-2.5 py-1 text-[11px] font-semibold text-green-700 ring-1 ring-green-100",children:[(0,A.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,A.jsx)("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-70"}),(0,A.jsx)("span",{className:"relative inline-flex h-2 w-2 rounded-full bg-green-500"})]}),"Live"]}),U=e=>{let{items:t,total:a,empty:s}=e;if(!t.length)return(0,A.jsx)("p",{className:"text-sm text-gray-400 py-6 text-center",children:s});const n=Math.max(...t.map(e=>e.value),1);return(0,A.jsx)("div",{className:"space-y-3.5",children:t.map(e=>(0,A.jsxs)("div",{children:[(0,A.jsxs)("div",{className:"flex items-center justify-between mb-1",children:[(0,A.jsx)("span",{className:"text-sm text-gray-700 truncate pr-2",children:e.label}),(0,A.jsxs)("span",{className:"text-sm font-semibold text-gray-900 tabular-nums whitespace-nowrap",children:[e.value,(0,A.jsxs)("span",{className:"ml-1 text-xs font-normal text-gray-400",children:[O(e.value,a),"%"]})]})]}),(0,A.jsx)("div",{className:"h-2 rounded-full bg-gray-100 overflow-hidden",children:(0,A.jsx)("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${Math.max(e.value/n*100,3)}%`,backgroundColor:"#2a78d6"}})})]},e.label))})},F=e=>{let{icon:t,label:a,value:s}=e;return(0,A.jsxs)("div",{className:"flex items-center gap-2.5 rounded-xl border border-gray-100 bg-gray-50/60 px-3.5 py-2.5",children:[(0,A.jsx)("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-white text-blue-600 ring-1 ring-gray-100",children:(0,A.jsx)(t,{className:"h-4 w-4"})}),(0,A.jsxs)("div",{children:[(0,A.jsx)("div",{className:"text-base font-bold text-gray-900 leading-none tabular-nums",children:s}),(0,A.jsx)("div",{className:"text-[11px] text-gray-500 mt-0.5",children:a})]})]})},R=e=>{let{title:t,children:a}=e;return(0,A.jsxs)("div",{children:[(0,A.jsx)("h4",{className:"text-xs font-semibold uppercase tracking-wider text-gray-400 mb-4",children:t}),a]})},_=e=>{let{students:t=[]}=e;const a=(0,s.useMemo)(()=>{const e=t.length,a={};t.forEach(e=>{const t=String(e.gender||"").trim().toLowerCase(),s=t?M[t]||P(t):"Unspecified";a[s]=(a[s]||0)+1});const s=Object.entries(a).map(e=>{let[t,a]=e;return{label:t,value:a,color:E[t]||k[L.length%k.length]}}).sort((e,t)=>{const a=L.indexOf(e.label),s=L.indexOf(t.label);return"Unspecified"===e.label?1:"Unspecified"===t.label?-1:-1===a&&-1===s?t.value-e.value:-1===a?1:-1===s?-1:a-s}),n={};t.forEach(e=>{const t=P(e.status||"Active");n[t]=(n[t]||0)+1});const r=Object.entries(n).map(e=>{let[t,a]=e;return{label:t,value:a}}).sort((e,t)=>t.value-e.value),l={};t.forEach(e=>{const t=P(e.countryOfOrigin||e.nationality||"Unknown")||"Unknown";l[t]=(l[t]||0)+1});const i=Object.entries(l).map(e=>{let[t,a]=e;return{label:t,value:a}}).sort((e,t)=>t.value-e.value),d=i.slice(0,6),o=i.slice(6).reduce((e,t)=>e+t.value,0);o>0&&d.push({label:`Other (${i.length-6})`,value:o});return{total:e,gender:s,status:r,nationality:d,active:t.filter(e=>"active"===(e.status||"active").toLowerCase()).length,accommodation:t.filter(e=>{var t;
1return!0===(null===(t=e.accommodationDetails)||void 0===t?void 0:t.required)}).length,countries:i.length}},[t]);return(0,A.jsxs)("div",{className:"bg-white rounded-2xl border border-gray-100 shadow-sm p-6",children:[(0,A.jsxs)("div",{className:"flex items-start justify-between mb-6",children:[(0,A.jsxs)("div",{children:[(0,A.jsx)("h3",{className:"text-lg font-bold text-gray-900",children:"Student Demographics"}),(0,A.jsx)("p",{className:"text-sm text-gray-500 mt-0.5",children:"A live, inclusive overview of your student body"})]}),(0,A.jsx)($,{})]}),0===a.total?(0,A.jsxs)("div",{className:"py-16 text-center text-gray-400",children:[(0,A.jsx)(N.A,{className:"w-10 h-10 mx-auto mb-3 text-gray-200"}),(0,A.jsx)("p",{className:"text-sm",children:"No student data yet."})]}):(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-8",children:[(0,A.jsx)(R,{title:"Gender",children:(0,A.jsxs)("div",{className:"flex items-center gap-5",children:[(0,A.jsxs)("div",{className:"relative flex-shrink-0",style:{width:132,height:132},children:[(0,A.jsx)(b.u,{width:"100%",height:"100%",children:(0,A.jsx)(j.r,{children:(0,A.jsx)(y.F,{data:a.gender,dataKey:"value",nameKey:"label",cx:"50%",cy:"50%",innerRadius:"66%",outerRadius:"100%",paddingAngle:2,stroke:"#ffffff",strokeWidth:2,isAnimationActive:!0,children:a.gender.map(e=>(0,A.jsx)(w.f,{fill:e.color},e.label))})})}),(0,A.jsxs)("div",{className:"absolute inset-0 flex flex-col items-center justify-center pointer-events-none",children:[(0,A.jsx)("span",{className:"text-2xl font-bold text-gray-900 leading-none tabular-nums",children:a.total}),(0,A.jsx)("span",{className:"text-[10px] uppercase tracking-wide text-gray-400 mt-0.5",children:"Students"})]})]}),(0,A.jsx)("ul",{className:"flex-1 space-y-2",children:a.gender.map(e=>(0,A.jsxs)("li",{className:"flex items-center gap-2 text-sm",children:[(0,A.jsx)("span",{className:"h-2.5 w-2.5 rounded-sm flex-shrink-0",style:{backgroundColor:e.color}}),(0,A.jsx)("span",{className:"text-gray-600 flex-1 truncate",children:e.label}),(0,A.jsx)("span",{className:"font-semibold text-gray-900 tabular-nums",children:e.value}),(0,A.jsxs)("span",{className:"text-xs text-gray-400 tabular-nums w-9 text-right",children:[O(e.value,a.total),"%"]})]},e.label))})]})}),(0,A.jsx)(R,{title:"Enrollment status",children:(0,A.jsx)(U,{items:a.status,total:a.total,empty:"No status data"})}),(0,A.jsx)(R,{title:"Top nationalities",children:(0,A.jsx)(U,{items:a.nationality,total:a.total,empty:"No nationality data"})})]}),(0,A.jsxs)("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3 mt-7 pt-6 border-t border-gray-100",children:[(0,A.jsx)(F,{icon:N.A,label:"Total students",value:a.total}),(0,A.jsx)(F,{icon:S.A,label:"Active",value:a.active}),(0,A.jsx)(F,{icon:C.A,label:"Countries",value:a.countries}),(0,A.jsx)(F,{icon:D.A,label:"In accommodation",value:a.accommodation})]})]})]})};var G=a(52746),T=a(93320),B=a(40732),I=a(17818);a(75854);const K=e=>{let{title:t,value:a,icon:s,gradient:n,subtext:r,trend:l,breakdown:o,description:c,onClick:u}=e;return(0,A.jsxs)("div",{className:"group relative bg-white rounded-md shadow-md border border-gray-300 p-5 hover:shadow-lg transition-all duration-200 "+(u?"cursor-pointer":""),onClick:u,role:u?"button":void 0,tabIndex:u?0:void 0,onKeyDown:u?e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),u())}:void 0,children:[(0,A.jsx)("div",{className:`absolute top-0 left-0 right-0 h-1 ${n} rounded-t-md`}),(0,A.jsx)("div",{className:"flex items-start justify-between",children:(0,A.jsxs)("div",{className:"flex-1",children:[(0,A.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,A.jsxs)("div",{className:"flex items-center space-x-3",children:[(0,A.jsx)("div",{className:`p-2.5 rounded-md ${n} shadow-sm`,children:(0,A.jsx)(s,{className:"w-5 h-5 text-white"})}),(0,A.jsx)("h3",{className:"text-sm font-bold text-gray-700 uppercase tracking-wide",children:t})]}),l&&(0,A.jsxs)("div",{className:"flex items-center space-x-1 text-xs font-semibold "+("increase"===l.type?"text-green-700":"text-red-700"),children:["increase"===l.type?(0,A.jsx)(i.A,{className:"w-4 h-4"}):(0,A.jsx)(d.A,{className:"w-4 h-4"}),(0,A.jsx)("span",{children:l.value})]})]}),(0,A.jsx)("p",{className:"text-3xl font-bold text-gray-900 mb-1",children:a}),r&&(0,A.jsx)("p",{className:"text-sm text-gray-600 font-medium",children:r}),c&&(0,A.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:c})]})}),o&&(0,A.jsx)("div",{className:"mt-4 pt-4 border-t-2 border-gray-200",children:(0,A.jsx)("div",{className:"grid grid-cols-2 gap-3",children:o.items.map((e,t)=>(0,A.jsxs)("div",{className:"flex justify-between items-center",children:[(0,A.jsx)("span",{className:"text-sm text-gray-600 font-medium",children:e.label}),(0,A.jsx)("span",{className:"text-sm font-bold text-gray-800",children:e.value})]},t))})})]})},q=()=>{const e=(0,x.Zp)(),{hasAccess:t}
1=(0,g.As)(),[a,i]=(0,s.useState)("dashboard"),[d,b]=(0,s.useState)(!1),[j,y]=(0,s.useState)({totalStudents:0,activeStudents:0,pendingPayments:0,graduatedStudents:0,certifiedCount:0,pendingCertificateCount:0,pendingAmount:0,genderDistribution:{male:0,female:0},countryDistribution:{},accommodationUsage:0,averageCourseStartDelay:0,certificationRate:0,revenueBySource:{courseFees:0,optionalServices:0}}),[w,N]=(0,s.useState)(!0),[S,C]=(0,s.useState)([]),[D,k]=(0,s.useState)([]),[P,M]=(0,s.useState)([]),[L,E]=(0,s.useState)(!0),O=(0,s.useMemo)(()=>(0,l.YM)(P),[P]);(0,s.useEffect)(()=>{(async()=>{try{const e=(0,n.P)((0,n.rJ)(r.db,"payments"),(0,n.My)("createdAt","desc")),t=(0,n.aQ)(e,e=>{const t=e.docs.map(e=>({id:e.id,...e.data()}));M(t);let a=0,s=0,n=0,r=0;const l=(0,h.e)(new Date,30);t.forEach(e=>{var t,i,d,o;const c=(null===(t=e.createdAt)||void 0===t||null===(i=t.toDate)||void 0===i?void 0:i.call(t))||new Date,u=e.amount||0;if(["cancelled","void","refunded","reversed"].includes((e.status||"").toLowerCase()))return;a+=u;const m=(null===(d=e.type)||void 0===d?void 0:d.toLowerCase())||"",x=(null===(o=e.description)||void 0===o?void 0:o.toLowerCase())||"";"course_fee"===m||"course"===m||x.includes("course")||x.includes("tuition")||x.includes("training fee")?n+=u:r+=u,(0,p.v)(c,{start:l,end:new Date})&&(s+=u)}),y(e=>({...e,totalRevenue:a,recentPayments:s,revenueBySource:{courseFees:n,optionalServices:r}}))}),a=(0,n.P)((0,n.rJ)(r.db,"students")),s=(0,n.aQ)(a,e=>{const t=e.docs.map(e=>({id:e.id,...e.data()})).filter(e=>!e.isDeleted&&"deleted"!==e.status),a=t.length,s=t.filter(e=>"active"===e.status).length,n=t.filter(e=>"completed"===e.status||"graduated"===e.status).length,r=["suspended","withdrawn"];t.filter(e=>!r.includes(e.status));k(t),C(t.filter(e=>{if(!e.stateRegistrationDeadline)return!1;const t=new Date(e.stateRegistrationDeadline),a=Math.ceil((t-new Date)/864e5);return a<=30&&a>0}));const l=t.filter(e=>{var t;return"male"===(null===(t=e.gender)||void 0===t?void 0:t.toLowerCase())}).length,i=t.filter(e=>{var t;return"female"===(null===(t=e.gender)||void 0===t?void 0:t.toLowerCase())}).length,d=t.reduce((e,t)=>{const a=(t.countryOfOrigin||"Unknown").toLowerCase().split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ");return e[a]=(e[a]||0)+1,e},{}),o=t.filter(e=>{var t;return!0===(null===(t=e.accommodationDetails)||void 0===t?void 0:t.required)}).length,c=t.filter(e=>e.registrationDate&&e.courseStartDate).map(e=>{var t,a;const s=null!==(t=e.registrationDate)&&void 0!==t&&t.toDate?e.registrationDate.toDate():new Date(e.registrationDate),n=null!==(a=e.courseStartDate)&&void 0!==a&&a.toDate?e.courseStartDate.toDate():new Date(e.courseStartDate);return(0,v.c)(n,s)}),u=c.length>0?c.reduce((e,t)=>e+t,0)/c.length:0,m=t.filter(e=>"completed"===e.status||"graduated"===e.status).length,x=a>0?m/a*100:0,g=t.filter(e=>"completed"===e.status||"graduated"===e.status),h=g.filter(e=>{var t;return"completed"===(null===(t=e.certificateCollection)||void 0===t?void 0:t.status)}).length,p=g.length-h;y(e=>({...e,totalStudents:a,activeStudents:s,graduatedStudents:n,certifiedCount:h,pendingCertificateCount:p,genderDistribution:{male:l,female:i},countryDistribution:d,accommodationUsage:o,averageCourseStartDelay:u.toFixed(1),certificationRate:x.toFixed(0)}))});return N(!1),()=>{t(),s()}}catch(e){console.error("Error fetching dashboard data:",e),N(!1)}})()},[]),(0,s.useEffect)(()=>{if(0===D.length)return;const e=["suspended","withdrawn"],t=D.filter(t=>!e.includes(t.status)).filter(e=>(0,l.cU)(e,O)>0).length,a=D.filter(e=>["active","graduated"].includes(String(e.status||"").trim().toLowerCase())).reduce((e,t)=>{const a=(0,l.cU)(t,O);return e+(a>0?a:0)},0);y(e=>({...e,pendingPayments:t,pendingAmount:a}))},[D,O]);return(0,A.jsxs)("div",{className:"min-h-screen bg-gradient-to-br from-gray-50 via-white to-gray-100",children:[(0,A.jsx)("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-6 pb-4",children:(0,A.jsxs)("div",{className:"flex items-center justify-between",children:[(0,A.jsxs)("div",{children:[(0,A.jsx)("h1",{className:"text-2xl font-bold text-gray-900",children:"Dashboard"}),(0,A.jsx)("p",{className:"text-sm text-gray-500 mt-0.5",children:"Welcome back! Here's what's happening today"})]}),(0,A.jsxs)("div",{className:"flex items-center space-x-3",children:[(0,A.jsxs)("div",{className:"hidden md:flex items-center space-x-2 px-3 py-1.5 bg-green-50 rounded-full border border-green-200",children:[(0,A.jsx)("div",{className:"w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"}),(0,A.jsx)("span",{className:"text-xs font-semibold text-green-700",children:"LIVE"})]}),(0,A.jsxs)("div",{className:"text-right hidden sm:block",children:[(0,A.jsx)("p",{className:"text-xs font-semibold text-gray-900",children:(0,f.GP)(new Date,"EEEE, MMMM d")}),(0,A.jsx)("p",{className:"text-xs text-gray-500",children:(0,f.GP)(new Date,"h:mm a")})]})]})]})}),(0,A.jsx)("main",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-8",children:(0,A.jsx)("div",{className:"space-y-6",children:(()=>{var s;switch(a){case"dashboard":return(0,A.jsx)(A.Fragment,{children:w?(0,A.jsxs)("div",{className:"bg-white rounded-2xl shadow-sm border border-slate-200 p-16 text-center",children:[(0,A.jsx)(B.A,{size:"large"}),(0,A.jsx)("p",{className:"mt-4 text-slate-600",children:"Loading dashboard data..."})]}):(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",children:[t("students")&&(0,A.jsx)(K,{title:"Total Students",value:j.totalStudents,icon:o.A,gradient:"bg-gradient-to-r from-blue-700 to-blue-900",subtext:"All-time registered",breakdown:{title:"Gender Distribution",items:[{label:"Male",value:`${j.genderDistribution.male}`},{label:"Female",value:`${j.genderDistribution.female}`}]},onClick:()=>e("/dashboard/students/total")}),t("students")&&(0,A.jsx)(K,{title:"Active Students",value:j.activeStudents,icon:c.A,gradient:"bg-gradient-to-r from-green-700 to-green-900",subtext:"Currently enrolled",trend:{type:"increase",value:`+${Math.floor(.15*j.activeStudents)} this month`},onClick:()=>
1e("/dashboard/students/active")}),t("students")&&(0,A.jsx)(K,{title:"Graduated Students",value:j.graduatedStudents,icon:m.A,gradient:"bg-gradient-to-r from-purple-700 to-purple-900",subtext:"Program completed",trend:{type:"increase",value:"+5 this month"},breakdown:{title:"Certification Status",items:[{label:"Certified",value:`${j.certifiedCount}`},{label:"Pending",value:`${j.pendingCertificateCount}`}]}}),t("payments")&&(0,A.jsx)(K,{title:"Pending Payments",value:j.pendingPayments,icon:u.A,gradient:"bg-gradient-to-r from-amber-600 to-amber-800",subtext:`$${(null===(s=j.pendingAmount)||void 0===s?void 0:s.toLocaleString())||0} outstanding`,description:"Click to view & follow up",breakdown:{title:"Payment Status",items:[{label:"Students",value:`${j.pendingPayments}`},{label:"Amount",value:`$${(j.pendingAmount||0).toLocaleString()}`}]},onClick:()=>b(!0)})]}),(0,A.jsx)(I.A,{isOpen:d,onClose:()=>b(!1),onSuccess:()=>{b(!1),e("/dashboard/pending-payments")},title:"Payment Access Authorization"}),(0,A.jsx)(_,{students:D})]})});case"register":return(0,A.jsx)(G.default,{onTabChange:i});case"payments":return(0,A.jsx)(T.default,{});default:return null}})()})})]})}}}]);
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.