PageSourceSearch

https://privawell.net/assets/badges-jsJUSiTM.js

js privawell.net collected 2026-10-07 01:36:52 UTC 18,614 bytes, 9 lines download raw bytes

1import{bE as l,aa as je,by as e,bO as oe,ak as fe,bX as ve,_ as be,bB as me,h as N,i as y,b7 as se,f as E,a$ as he,cb as Ne,c4 as B,b_ as H,$ as ye,b as we,b0 as Ce,k as $,l as F,j as V,ag as ke,au as te,ax as ae,ay as ie,av as le,aw as q,X as Q,o as Se,bC as I,b4 as Y}from"./index-BOgKjTHI.js";import{T as Te,b as Be,c as X,a as _}from"./tabs-BvDQyrLU.js";import{B as ne}from"./badge-xYseOKTI.js";import{P as re}from"./progress-BBYXso8q.js";import{A as Ee,B as de}from"./BadgeCard-CkcEYtSA.js";import{T as P}from"./trophy-CIH_yhVq.js";import{H as Pe}from"./header-CJTmc9rc.js";import{T as Z}from"./target-Ch7hvnId.js";import{B as Re}from"./bell-C98r7CLz.js";import"./index-BmDmaUwa.js";import"./thumbs-up-BQV-itsw.js";import"./eye-BzVU7-M-.js";import"./flame-CW9qjnop.js";import"./chart-no-axes-column-DRGpsNay.js";import"./brain-DOCIi3Br.js";import"./dumbbell-BhcG6Jri.js";import"./activity-NJt4tlT_.js";import"./circle-check-big-ltvJeKDU.js";import"./crown-D8u0eGKW.js";import"./star-CPINmHzQ.js";import"./popover-Cxd-kruw.js";import"./circle-plus-BNG10dHi.js";class Ae extends l.Component{getSnapshotBeforeUpdate(d){const i=this.props.childRef.current;if(i&&d.isPresent&&!this.props.isPresent){const r=this.props.sizeRef.current;r.height=i.offsetHeight||0,r.width=i.offsetWidth||0,r.top=i.offsetTop,r.left=i.offsetLeft}return null}componentDidUpdate(){}render(){return this.props.children}}function Me({children:a,isPresent:d}){const i=l.useId(),r=l.useRef(null),x=l.useRef({width:0,height:0,top:0,left:0}),{nonce:f}=l.useContext(je);return l.useInsertionEffect(()=>{const{width:u,height:n,top:p,left:b}=x.current;if(d||!r.current||!u||!n)return;r.current.dataset.motionPopId=i;const j=document.createElement("style");return f&&(j.nonce=f),document.head.appendChild(j),j.sheet&&j.sheet.insertRule(`
2          [data-motion-pop-id="${i}"] {
3            position: absolute !important;
4            width: ${u}px !important;
5            height: ${n}px !important;
6            top: ${p}px !important;
7            left: ${b}px !important;
8          }
9        `),()=>{document.head.removeChild(j)}},[d]),e.jsx(Ae,{isPresent:d,childRef:r,sizeRef:x,children:l.cloneElement(a,{ref:r})})}const Ue=({children:a,initial:d,isPresent:i,onExitComplete:r,custom:x,presenceAffectsLayout:f,mode:u})=>{const n=oe(Ge),p=l.useId(),b=l.useCallback(m=>{n.set(m,!0);for(const C of n.values())if(!C)return;r&&r()},[n,r]),j=l.useMemo(()=>({id:p,initial:d,isPresent:i,custom:x,onExitComplete:b,register:m=>(n.set(m,!1),()=>n.delete(m))}),f?[Math.random(),b]:[i,b]);return l.useMemo(()=>{n.forEach((m,C)=>n.set(C,!1))},[i]),l.useEffect(()=>{!i&&!n.size&&r&&r()},[i]),u==="popLayout"&&(a=e.jsx(Me,{isPresent:i,children:a})),e.jsx(fe.Provider,{value:j,children:a})};function Ge(){return new Map}const L=a=>a.key||"";function ce(a){const d=[];return l.Children.forEach(a,i=>{l.isValidElement(i)&&d.push(i)}),d}const Ke=({children:a,exitBeforeEnter:d,custom:i,initial:r=!0,onExitComplete:x,presenceAffectsLayout:f=!0,mode:u="sync"})=>{const n=l.useMemo(()=>ce(a),[a]),p=n.map(L),b=l.useRef(!0),j=l.useRef(n),m=oe(()=>new Map),[C,M]=l.useState(n),[g,S]=l.useState(n);ve(()=>{b.current=!1,j.current=n;for(let v=0;v<g.length;v++){const c=L(g[v]);p.includes(c)?m.delete(c):m.get(c)!==!0&&m.set(c,!1)}},[g,p.length,p.join("-")]);const t=[];if(n!==C){let v=[...n];for(let c=0;c<g.length;c++){const w=g[c],R=L(w);p.includes(R)||(v.splice(c,0,w),t.push(w))}u==="wait"&&t.length&&(v=t),S(ce(v)),M(n);return}const{forceRender:T}=l.useContext(be);return e.jsx(e.Fragment,{children:g.map(v=>{const c=L(v),w=n===g||p.includes(c),R=()=>{if(m.has(c))m.set(c,!0);else return;let U=!0;m.forEach(A=>{A||(U=!1)}),U&&(T==null||T(),S(j.current),x&&x())};return e.jsx(Ue,{isPresent:w,initial:!b.current||r?void 0:!1,custom:w?void 0:i,presenceAffectsLayout:f,mode:u,onExitComplete:w?void 0:R,children:v},c)})})};function $e({notification:a,onClose:d,onMarkAsRead:i,variant:r="popup"}){const x=()=>{i&&!a.isRead&&i(a.id)},f=r==="popup",u=e.jsx(N,{className:se("border-2",a.type==="earned"&&"border-green-500 bg-green-50 dark:bg-green-950",!a.isRead&&"shadow-lg",f&&"max-w-sm"),children:e.jsx(y,{className:"p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:se("rounded-full p-2 shrink-0",a.type==="earned"&&"bg-green-500"),children:e.jsx(P,{className:"h-5 w-5 text-white"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-medium text-foreground mb-1",children:a.type==="earned"?"🎉 Badge Earned!":"Badge Update"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:a.message}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:new Date(a.createdAt).toLocaleStr
9ing()})]}),e.jsxs("div",{className:"flex gap-1 shrink-0",children:[!a.isRead&&e.jsxs(E,{size:"sm",variant:"ghost",onClick:x,className:"h-8 w-8 p-0","data-testid":`mark-read-${a.id}`,children:[e.jsx("span",{className:"sr-only",children:"Mark as read"}),"✓"]}),d&&e.jsx(E,{size:"sm",variant:"ghost",onClick:d,className:"h-8 w-8 p-0","data-testid":`close-notification-${a.id}`,children:e.jsx(he,{className:"h-4 w-4"})})]})]})})});return f?e.jsx(me.div,{initial:{opacity:0,y:50,scale:.9},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-50,scale:.9},className:"fixed bottom-4 right-4 z-50","data-testid":`badge-notification-${a.id}`,children:u}):e.jsx("div",{"data-testid":`badge-notification-${a.id}`,children:u})}function Fe({notifications:a,onMarkAsRead:d}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx(Ke,{children:a.map(i=>e.jsx(me.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},children:e.jsx($e,{notification:i,onMarkAsRead:d,variant:"inline"})},i.id))}),a.length===0&&e.jsxs("div",{className:"text-center py-8",children:[e.jsx(P,{className:"h-10 w-10 mx-auto mb-4 text-amber-300"}),e.jsx("p",{className:"font-medium text-gray-600 mb-1",children:"All caught up"}),e.jsx("p",{className:"text-sm text-gray-400",children:"New badge notifications will appear here as you reach milestones."})]})]})}const z=[{value:"sauna",label:"Sauna",icon:"🔥",defaultUnit:"Sessions"},{value:"workout",label:"Workout",icon:"💪",defaultUnit:"Sessions"},{value:"supplements",label:"Supplements",icon:"💊",defaultUnit:"Times"},{value:"vitals",label:"Vital Signs",icon:"📊",defaultUnit:"Measurements"},{value:"sleep",label:"Sleep",icon:"😴",defaultUnit:"Hours"},{value:"water",label:"Water Intake",icon:"💧",defaultUnit:"ml"},{value:"redlight",label:"Red Light",icon:"🔴",defaultUnit:"Sessions"}];function rs(){const[a,d]=l.useState("earned"),[i,r]=l.useState(!1),[x,f]=l.useState(""),[u,n]=l.useState(""),[p,b]=l.useState(""),[j,m]=l.useState(""),[C,M]=l.useState("week"),{toast:g}=Ne(),{data:S}=B({queryKey:["/api/auth/me"]}),t=S==null?void 0:S.user,{data:T=[]}=B({queryKey:["/api/goals",t==null?void 0:t.id],enabled:!!(t!=null&&t.id),retry:1}),{data:v=[]}=B({queryKey:[`/api/goals/compute-progress/${t==null?void 0:t.id}`],enabled:!!(t!=null&&t.id),retry:1,refetchInterval:3e4}),{data:c=[],isLoading:w}=B({queryKey:["/api/badges"],enabled:!!t,retry:1,refetchOnWindowFocus:!1}),{data:R=[],isLoading:U}=B({queryKey:["/api/badges/user",t==null?void 0:t.id],enabled:!!(t!=null&&t.id),retry:1,refetchOnWindowFocus:!1}),{data:A=[]}=B({queryKey:["/api/badges/notifications",t==null?void 0:t.id],enabled:!!(t!=null&&t.id),retry:1,refetchOnWindowFocus:!1}),G=H({mutationFn:async()=>await(await Y(`/api/badges/check/${t==null?void 0:t.id}`,"POST")).json(),onSuccess:s=>{s.newBadges.length>0?g({title:"🎉 New Badge Earned!",description:s.message}):g({title:"No New Badges",description:"Keep working towards your wellness goals!"}),I.invalidateQueries({queryKey:["/api/badges/user"]}),I.invalidateQueries({queryKey:["/api/badges/notifications"]})},onError:()=>{g({title:"Error",description:"Failed to check for new badges",variant:"destructive"})}}),xe=H({mutationFn:async s=>await(await Y(`/api/badges/notifications/${s}/read`,"PATCH")).json(),onSuccess:()=>{I.invalidateQueries({queryKey:["/api/badges/notifications"]})}}),O=H({mutationFn:async s=>await(await Y("/api/goals","POST",s)).json(),onSuccess:()=>{g({title:"Goal Created!",description:"Your wellness goal has been set. Keep tracking to earn badges!"}),I.invalidateQueries({queryKey:["/api/goals"]}),r(!1),f(""),n(""),b(""),m(""),M("week"),G.mutate()},onError:()=>{g({title:"Error",description:"Failed to create goal. Please try again.",variant:"destructive"})}}),ue=()=>{if(!x||!u||!p){g({title:"Missing Information",description:"Please fill in all required fields",variant:"destructive"});return}const s=z.find(h=>h.value===x);O.mutate({userId:t==null?void 0:t.id,type:x,title:u,targetValue:parseFloat(p),targetUnit:j||(s==null?void 0:s.defaultUnit)||"times",targetPeriod:C,isActive:!0})},k=R,ge=k.map(s=>s.badgeId),J=c.filter(s=>
9!ge.includes(s.id)),pe=k.reduce((s,h)=>s+h.badge.pointValue,0);k.reduce((s,h)=>(s[h.badge.category]=(s[h.badge.category]||0)+1,s),{});const W=Math.round(k.length/c.length*100);return w||U?e.jsx("div",{className:"container mx-auto p-6",children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsxs("div",{className:"text-center",children:[e.jsx(P,{className:"h-12 w-12 mx-auto mb-4 animate-spin"}),e.jsx("p",{children:"Loading your achievements..."})]})})}):e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx(Pe,{}),e.jsxs("div",{className:"container mx-auto p-6 space-y-6",children:[e.jsxs(ye,{href:"/trends",className:"inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-4",children:[e.jsx(we,{className:"h-4 w-4"}),"Back to Dashboard"]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-semibold flex items-center gap-3",style:{color:"#0E1A2B"},children:[e.jsx(P,{className:"h-7 w-7 text-yellow-500"}),"Achievement Badges"]}),e.jsx("p",{className:"mt-2",style:{color:"#6E7278"},children:"Milestones recorded in your vault"})]}),e.jsxs(E,{onClick:()=>G.mutate(),disabled:G.isPending,"data-testid":"check-badges-button",children:[e.jsx(Ce,{className:"h-4 w-4 mr-2"}),G.isPending?"Checking...":"Check for New Badges"]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[e.jsx(N,{children:e.jsx(y,{className:"p-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ee,{className:"h-8 w-8 text-blue-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:k.length}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Badges Earned"})]})]})})}),e.jsx(N,{children:e.jsx(y,{className:"p-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Z,{className:"h-8 w-8 text-green-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:pe}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Total Points"})]})]})})}),e.jsx(N,{children:e.jsx(y,{className:"p-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(P,{className:"h-8 w-8 text-yellow-500"}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-2xl font-bold",children:[W,"%"]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Completion"})]})]})})}),e.jsx(N,{children:e.jsx(y,{className:"p-6",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Re,{className:"h-8 w-8 text-purple-500"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-2xl font-bold",children:A.filter(s=>!s.isRead).length}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"New Notifications"})]})]})})})]}),e.jsx(N,{children:e.jsxs(y,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-sm font-medium",children:"Overall Progress"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[W,"%"]})]}),e.jsx(re,{value:W,className:"h-2"})]})}),e.jsxs(N,{children:[e.jsx($,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(F,{className:"flex items-center gap-2",children:[e.jsx(Z,{className:"h-5 w-5",style:{color:"#C2A86D"}}),"Your Goals"]}),e.jsx(V,{children:"Set wellness goals to record achievement milestones"})]}),e.jsxs(E,{onClick:()=>r(!i),variant:i?"outline":"default",size:"sm","data-testid":"button-add-goal",children:[i?e.jsx(he,{className:"h-4 w-4 mr-2"}):e.jsx(ke,{className:"h-4 w-4 mr-2"}),i?"Cancel":"Add Goal"]})]})}),e.jsxs(y,{children:[i&&e.jsxs("div",{className:"mb-6 p-4 bg-muted/50 rounded-lg space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Goal Type"}),e.jsxs(te,{value:x,onValueChange:s=>{f(s);const h=z.find(o=>o.value===s);h&&(n(`${h.label} Goal`),m(h.defaultUnit))},children:[e.jsx(ae,{"data-testid":"select-goal-type",children:e.jsx(ie,{placeholder:"Choose type..."})}),e.jsx(le,{children:z.map(s=>e.jsx(q,{value:s.value,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{children:s.icon})," ",s.label]})},s.value))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Goal Title"}),e.jsx(Q,{value:u,onChange:s=>n(s.target.value),placeholder:"e.g., Workout 3x per week","data-testid":"input-goal-title"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Target"}),e.jsx(Q,{type:"number",value:p,onChange:s=>b(s.target.value),placeholder:"3","data-testid":"input-goal-target"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Unit"}),e.jsx(Q,{value:j,onChange:s=>m(s.target.value),placeholder:"Sessions","data-testid":"input-goal-unit"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Period"}),e.jsxs(te,{value:C,onValueChange:M,children:[e.jsx(ae,{"data-testid":"select-goal-period",children:e.jsx(ie,{})}),e.jsxs(le,{children:[e.jsx(q,{value:"day",children:"Daily"}),e.jsx(q,{value:"week",children:"Weekly"}),e.jsx(q,{value:"month",children:"Monthly"})]})]})]})]}),e.jsxs(E,{onClick:ue,disabled:O.isPending,"data-testid":"button-save-goal",children:[e.jsx(Se,{className:"h-4 w-4 mr-2"}),O.isPending?"Creating...":"Create Goal"]})]}),T.length>0?e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3",children:T.map(s=>{const h=z.find(D=>D.value===s.type),o=v.find(D=>D.goalId===s.id),ee=(o==null?void 0:o.completionRate)||0,K=(o==null?void 0:o.isCompleted)||!1;return e.jsxs("div",{className:"p-4 border rounded-lg space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"text-2xl",children:(h==null?void 0:h.icon)||"🎯"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-medium text-sm truncate",children:s.title}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[s.targetValue," ",s.targetUnit," / ",s.targetPeriod]})]}),K?e.jsx(ne,{className:"bg-green-500 text-white text-xs",children:"Complete!"}):s.isActive?e.jsx(ne,{variant:"secondary",className:"text-xs",children:"Active"}):null]}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsxs("span",{children:[(o==null?void 0:o.actualValue)||0," / ",(o==null?void 0:o.targetValue)||s.targetValue," done"]}),e.jsxs("span",{className:K?"text-green-600 dark:text-green-400 font-medium":"",children:[ee,"%"]})]}),e.jsx(re,{value:ee,className:`h-2${K?"[&>div]:bg-green-500":""}`}),!K&&o&&o.remainingToGoal>
90&&e.jsxs("p",{className:"text-xs text-amber-600 dark:text-amber-400",children:[o.remainingToGoal," more to go this ",s.targetPeriod]})]})]},s.id)})}):e.jsxs("div",{className:"text-center py-8 text-muted-foreground",children:[e.jsx(Z,{className:"h-10 w-10 mx-auto mb-3 opacity-50"}),e.jsx("p",{className:"font-medium",children:"No goals yet"}),e.jsx("p",{className:"text-sm",children:"Set your first goal to start earning badges!"})]})]})]}),e.jsxs(Te,{value:a,onValueChange:d,children:[e.jsxs(Be,{className:"grid w-full grid-cols-3",style:{backgroundColor:"#F4F2EE"},children:[e.jsxs(X,{value:"earned",className:"data-[state=active]:bg-white",style:{color:"#6E7278"},"data-testid":"earned-badges-tab",children:["Earned (",k.length,")"]}),e.jsxs(X,{value:"available",className:"data-[state=active]:bg-white",style:{color:"#6E7278"},"data-testid":"available-badges-tab",children:["Available (",J.length,")"]}),e.jsxs(X,{value:"notifications",className:"data-[state=active]:bg-white",style:{color:"#6E7278"},"data-testid":"notifications-tab",children:["Notifications (",A.filter(s=>!s.isRead).length,")"]})]}),e.jsx(_,{value:"earned",className:"mt-6",children:e.jsxs(N,{children:[e.jsxs($,{children:[e.jsx(F,{children:"Your Earned Badges"}),e.jsx(V,{children:"Congratulations on these achievements! Keep up the great work."})]}),e.jsx(y,{children:k.length>0?e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:k.map(s=>e.jsx(de,{badge:{...s.badge,earnedAt:s.earnedAt},earned:!0,size:"md"},s.id))}):e.jsxs("div",{className:"text-center py-12",children:[e.jsx(P,{className:"h-14 w-14 mx-auto mb-4 text-amber-300"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"Your achievements will shine here"}),e.jsx("p",{className:"text-muted-foreground mb-4 max-w-sm mx-auto",children:"Keep tracking your health at your own pace. Every small step counts, and badges will come naturally."}),e.jsx(E,{variant:"outline",className:"calm-button",onClick:()=>d("available"),children:"See what's available"})]})})]})}),e.jsx(_,{value:"available",className:"mt-6",children:e.jsxs(N,{children:[e.jsxs($,{children:[e.jsx(F,{children:"Available Badges"}),e.jsx(V,{children:"Continue recording to reach these milestones"})]}),e.jsx(y,{children:e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:J.map(s=>e.jsx(de,{badge:s,earned:!1,size:"md"},s.id))})})]})}),e.jsx(_,{value:"notifications",className:"mt-6",children:e.jsxs(N,{children:[e.jsxs($,{children:[e.jsx(F,{children:"Badge Notifications"}),e.jsx(V,{children:"Stay updated on your achievement progress"})]}),e.jsx(y,{children:e.jsx(Fe,{notifications:A,onMarkAsRead:s=>xe.mutate(s)})})]})})]})]})]})}export{rs 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.