PageSourceSearch

https://academytriumph.com/assets/admin.index-BAg-rT98.js

js academytriumph.com collected 2026-10-09 22:06:27 UTC 8,840 bytes, 6 lines download raw bytes

1import{s,j as e,L as k,t as A}from"./index-Y15_YY1k.js";import{u as y}from"./useQuery-BMg7JJVt.js";import{C as l,a as d,b as f,c as b}from"./card-DGn1OPH0.js";import{S as q}from"./skeleton-D-iA6qsV.js";import{B as v}from"./badge-6dOpqurg.js";import{U as C}from"./users-CyrJy6pL.js";import{A as S}from"./activity-B4sSSUQZ.js";import{Z as D}from"./zap-064Bp_mA.js";import{S as T}from"./swords-C5sS9fr9.js";import{L as M}from"./list-checks-DRS6Edne.js";import{M as I}from"./message-square-By26BRfn.js";import{M as L}from"./megaphone-BhuPtbXn.js";import{C as P}from"./copy-knmp_0cx.js";import"./utils-BQHNewu7.js";import"./index-LHNt3CwB.js";import"./createLucideIcon-CFduoS8H.js";const n=(m,u)=>`/dna?utm_source=${u}&utm_medium=cpc&utm_campaign=dna_l1&utm_content=${m}`,U=[{slug:"pain",platform:"meta",hook:"Still confused between BDS, MDS, clinic, or going abroad?",body:"Take Triumph's 20-min Career DNA test. Get a personalised report — your cognitive type, top 3 dental career fits, and a 90-day plan. Delivered to your inbox today. ₹999 (worth ₹50,000).",cta:"Unlock my Career DNA — ₹999",landing_url:n("pain","meta")},{slug:"value-anchor",platform:"meta",hook:"A ₹50,000 career-clarity report. Today ₹999.",body:"Built for dentists, by dentists. AI-personalised across personality, IQ, EQ and aspiration. 20 min. PDF + email. 7-day refund.",cta:"Get my Career DNA",landing_url:n("value-anchor","meta")},{slug:"sample-report",platform:"meta",hook:"This is what a real dentist's Career DNA report looks like.",body:"See the actual format — cognitive type, archetype, strength radar, top 3 fits, hidden risks, 90-day plan. Then unlock yours for ₹999.",cta:"Take the 20-min test",landing_url:n("sample-report","meta")},{slug:"specialty-fit",platform:"google",hook:"Don't pick your MDS branch by guesswork.",body:"Triumph's AI scores you across 6 dental career pathways and tells you the top 3 fits with % match — in 20 min. ₹999.",cta:"Unlock now",landing_url:n("specialty-fit","google")},{slug:"outcome",platform:"whatsapp",hook:"20 minutes. ₹999. A 90-day plan you'll actually use.",body:"Stop scrolling for advice. Get a personalised Career DNA report that tells you exactly what to do next month, the month after, and the month after that. Download + emailed copy.",cta:"Start now",landing_url:n("outcome","whatsapp")}];function Y(){const m=new Date().toISOString().slice(0,10),u=new Date(Date.now()-1440*60*1e3).toISOString(),{data:o,isLoading:_}=y({queryKey:["admin","overview-kpis"],staleTime:6e4,queryFn:async()=>{const[t,r,i,p,c]=await Promise.all([s.from("profiles").select("user_id",{count:"exact",head:!0}),s.from("daily_activity").select("user_id",{count:"exact",head:!0}).eq("activity_date",m),s.from("quest_progress").select("id",{count:"exact",head:!0}).eq("status","completed"),s.from("chat_messages").select("id",{count:"exact",head:!0}).gte("created_at",u),s.from("quest_progress").select("xp_earned, total_answered")]),x=(c.data??[]).reduce((a,g)=>a+(g.xp_earned??0),0),h=(c.data??[]).reduce((a,g)=>a+(g.total_answered??0),0);return{totalUsers:t.count??0,activeToday:r.count??0,questsCompleted:i.count??0,chatLast24h:p.count??0,totalXp:x,totalAnswered:h}}}),{data:j}=y({queryKey:["admin","recent-signups"],staleTime:6e4,queryFn:async()=>{const{data:t}=await s.from("profiles").select("user_id, name, role, target_exam, created_at").order("created_at",{ascending:!1}).limit(10);return t??[]}}),{data:N}=y({queryKey:["admin","recent-activity"],staleTime:6e4,queryFn:async()=>{const{data:t}=await s.from("quest_progress").select("id, user_id, quest_id, xp_earned, accuracy_percent, completed_at").eq("status","completed").order("completed_at",{ascending:!1}).limit(20),r=Array.from(new Set((t??[]).map(a=>a.user_id))),i=Array.from(new Set((t??[]).map(a=>a.quest_id))),[{data:p},{data:c}]=await Promise.all([r.length?s.from("profiles").select("user_id, name").in("user_id",r):Promise.resolve({data:[]}),i.length?s.from("cluster_quests").select("id, name").in("id",i):Promise.resolve({data:[]})]),x=new Map((p??[]).map(a=>[a.user_id,a.name??"—"])),h=new Map((c??[]).map(a=>[a.id,a.name]));return(t??[]).map(a=>
1({...a,userName:x.get(a.user_id)??"—",questName:h.get(a.quest_id)??"—"}))}}),w=[{label:"Total users",icon:C,value:o?.totalUsers,accent:"text-primary"},{label:"Active today",icon:S,value:o?.activeToday,accent:"text-emerald-500"},{label:"Total XP awarded",icon:D,value:o?.totalXp,accent:"text-amber-500"},{label:"Quests completed",icon:T,value:o?.questsCompleted,accent:"text-violet-500"},{label:"MCQs answered",icon:M,value:o?.totalAnswered,accent:"text-sky-500"},{label:"Chat msgs (24h)",icon:I,value:o?.chatLast24h,accent:"text-rose-500"}];return e.jsxs("div",{className:"mx-auto max-w-6xl space-y-6 p-6",children:[e.jsxs("header",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Admin Overview"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Platform-wide read-only KPIs and recent activity."})]}),e.jsx("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-6",children:w.map(t=>{const r=t.icon;return e.jsx(l,{children:e.jsxs(d,{className:"p-4",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx(r,{className:`h-4 w-4 ${t.accent}`})}),e.jsx("div",{className:"mt-2 text-2xl font-bold tabular-nums",children:_?e.jsx(q,{className:"h-7 w-16"}):(t.value??0).toLocaleString()}),e.jsx("div",{className:"text-[11px] uppercase tracking-wider text-muted-foreground",children:t.label})]})},t.label)})}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs(l,{children:[e.jsx(f,{children:e.jsx(b,{className:"text-base",children:"Recent signups"})}),e.jsxs(d,{className:"space-y-2",children:[(j??[]).map(t=>e.jsxs(k,{to:"/admin/users",className:"flex items-center justify-between rounded-md border border-border p-2 text-sm hover:bg-muted/50",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:t.name??"—"}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[t.target_exam??"no exam"," · ",new Date(t.created_at).toLocaleDateString()]})]}),e.jsx(v,{variant:"outline",className:"text-[10px]",children:t.role})]},t.user_id)),!j?.length&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"No signups yet."})]})]}),e.jsxs(l,{children:[e.jsx(f,{children:e.jsx(b,{className:"text-base",children:"Recent quest completions"})}),e.jsxs(d,{className:"space-y-2",children:[(N??[]).map(t=>e.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border p-2 text-sm",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:t.userName}),e.jsx("div",{className:"text-xs text-muted-foreground truncate max-w-[260px]",children:t.questName})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("div",{className:"text-xs font-semibold text-primary",children:["+",t.xp_earned," XP"]}),e.jsx("div",{className:"text-[10px] text-muted-foreground",children:t.accuracy_percent?`${Math.round(t.accuracy_percent)}%`:"—"})]})]},t.id)),!N?.length&&e.jsx("div",{className:"text-xs text-muted-foreground",children:"No completions yet."})]})]})]}),e.jsxs(l,{children:[e.jsx(f,{children:e.jsxs(b,{className:"text-base flex items-center gap-2",children:[e.jsx(L,{className:"h-4 w-4 text-[color:var(--neon-magenta)]"}),"Career DNA — L1 ad copy pack"]})}),e.jsxs(d,{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Drop these straight into Meta / Google / WhatsApp. Each variant uses the same UTM-tagged landing URL so you can attribute conversions."}),U.map(t=>{const r=`${t.hook}
2
3${t.body}
4
5${t.cta}
6https://academytriumph.com${t.landing_url}`;return e.jsxs("div",{className:"rounded-lg border border-border/60 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(v,{variant:"outline",className:"text-[10px] uppercase",children:t.platform}),e.jsx("span",{className:"text-xs font-semibold",children:t.slug})]}),e.jsxs("button",{type:"button",onClick:()=>{navigator.clipboard.writeText(r),A.success("Copied to clipboard")},className:"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[11px] hover:bg-muted/50",children:[e.jsx(P,{className:"h-3 w-3"})," Copy"]})]}),e.jsx("div",{className:"text-sm font-semibold",children:t.hook}),e.jsx("div",{className:"mt-1 text-xs text-muted-foreground",children:t.body}),e.jsxs("div",{className:"mt-2 flex items-center justify-between text-[11px]",children:[e.jsx("span",{className:"font-semibold text-[color:var(--neon-cyan)]",children:t.cta}),e.jsx("code",{className:"rounded bg-muted/50 px-1.5 py-0.5",children:t.landing_url})]})]},t.slug)})]})]})]})}export{Y as component};

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.