@gamifyio/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import {createContext,useRef,useMemo,useEffect,useCallback,useState,cloneElement,useContext}from'react';import {Gamify}from'@gamifyio/core';import {jsx,Fragment,jsxs}from'react/jsx-runtime';var K=createContext(null);function X(){return typeof window>"u"}function Z({config:r,children:t}){let o=useRef(null),a=useMemo(()=>{if(X())return null;if(o.current)return o.current;let i=new Gamify(r);return o.current=i,i},[r.apiKey,r.endpoint]);useEffect(()=>()=>{o.current&&(o.current.shutdown(),o.current=null);},[]);let u=useMemo(()=>a?{client:a,track:(i,e)=>a.track(i,e),identify:(i,e)=>a.identify(i,e),reset:()=>a.reset(),getUserId:()=>a.getUserId(),getAnonymousId:()=>a.getAnonymousId()}:null,[a]);return u?jsx(K.Provider,{value:u,children:t}):jsx(Fragment,{children:t})}function w(){return useContext(K)}function re(){let r=w();if(!r)throw new Error("useGamify must be used within a GamifyProvider. Make sure your component is wrapped with <GamifyProvider>.");return r}function G(){let r=w();return useCallback((t,o)=>{r&&r.track(t,o);},[r])}function te(){let r=w();return useCallback((t,o)=>{r&&r.identify(t,o);},[r])}function oe(){let r=w(),[t,o]=useState({session:r?.client?.session?.getCachedSession()??null,loading:false,error:null}),a=useCallback(async(l,d,R)=>{if(!r?.client){o(S=>({...S,error:"SDK not initialized"}));return}o(S=>({...S,loading:true,error:null}));try{let S=await r.client.updateCart(l,d,R);o({session:S,loading:!1,error:null});}catch(S){let x=S instanceof Error?S.message:"Unknown error";o(P=>({...P,loading:false,error:x}));}},[r]),u=useCallback(async l=>{if(!r?.client?.session){o(d=>({...d,error:"SDK not initialized"}));return}o(d=>({...d,loading:true,error:null}));try{let d=await r.client.session.applyCoupon(l);o({session:d,loading:!1,error:null});}catch(d){let R=d instanceof Error?d.message:"Unknown error";o(S=>({...S,loading:false,error:R}));}},[r]),i=useCallback(async()=>{if(!r?.client?.session){o(l=>({...l,error:"SDK not initialized"}));return}o(l=>({...l,loading:true,error:null}));try{let l=await r.client.session.complete();o({session:l,loading:!1,error:null});}catch(l){let d=l instanceof Error?l.message:"Unknown error";o(R=>({...R,loading:false,error:d}));}},[r]),e=useCallback(()=>{r?.client?.session&&(r.client.session.clearSession(),o({session:null,loading:false,error:null}));},[r]),s=useCallback(async()=>{if(r?.client?.session){o(l=>({...l,loading:true,error:null}));try{let l=await r.client.session.getSession();o({session:l,loading:!1,error:null});}catch(l){let d=l instanceof Error?l.message:"Unknown error";o(R=>({...R,loading:false,error:d}));}}},[r]);return {...t,updateCart:a,applyCoupon:u,complete:i,clearSession:e,refresh:s}}function U(r){let t=w(),[o,a]=useState({profile:t?.client?.loyalty?.getCachedProfile()??null,history:null,loading:false,error:null}),u=useCallback(async()=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getLoyaltyProfile();a(s=>({...s,profile:e,loading:!1,error:null}));}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t]),i=useCallback(async(e,s)=>{if(!t?.client){a(l=>({...l,error:"SDK not initialized"}));return}a(l=>({...l,loading:true,error:null}));try{let l=await t.client.getLoyaltyHistory(e,s);a(d=>({...d,history:l,loading:!1,error:null}));}catch(l){let d=l instanceof Error?l.message:"Unknown error";a(R=>({...R,loading:false,error:d}));}},[t]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refreshProfile:u,refreshHistory:i}}function ae(){let r=w(),[t,o]=useState({referrerCode:r?.client?.referral?.getReferrer()??null,hasReferrer:r?.client?.referral?.hasReferrer()??false}),a=useCallback(e=>{r?.client?.referral&&(r.client.referral.setReferrer(e),o({referrerCode:e,hasReferrer:true}));},[r]),u=useCallback(()=>{r?.client?.referral&&(r.client.referral.clearReferrer(),o({referrerCode:null,hasReferrer:false}));},[r]),i=useCallback(()=>{if(r?.client?.referral){let e=r.client.referral.detectReferrerFromUrl();return e&&o({referrerCode:e,hasReferrer:true}),e}return null},[r]);return useEffect(()=>{if(r?.client?.referral){let e=r.client.referral.getReferrer();o({referrerCode:e,hasReferrer:e!==null});}},[r]),{...t,setReferrer:a,clearReferrer:u,detectFromUrl:i}}function T(r){let t=w(),[o,a]=useState({stats:t?.client?.affiliate?.getCachedStats()??null,loading:false,error:null}),u=useCallback(async(i=false)=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getAffiliateStats(i);a({stats:e,loading:!1,error:null});}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refreshStats:u}}function E(r=10){let t=w(),[o,a]=useState({leaderboard:null,loading:false,error:null}),u=useCallback(async i=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getLeaderboard(i??r);a({leaderboard:e,loading:!1,error:null});}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t,r]);return {...o,refresh:u}}function W(r){let t=w(),[o,a]=useState({quests:[],loading:false,error:null}),u=useCallback(async()=>{if(!t?.client){a(i=>({...i,error:"SDK not initialized"}));return}a(i=>({...i,loading:true,error:null}));try{let i=await t.client.getQuests();a({quests:i.quests,loading:!1,error:null});}catch(i){let e=i instanceof Error?i.message:"Unknown error";a(s=>({...s,loading:false,error:e}));}},[t]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refresh:u}}function F(r){let t=w(),[o,a]=useState({streaks:[],stats:null,loading:false,error:null}),u=useCallback(async()=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getStreaks();a({streaks:e.streaks,stats:e.stats,loading:!1,error:null});}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t]),i=useCallback(async e=>{if(!t?.client)return a(s=>({...s,error:"SDK not initialized"})),null;try{let s=await t.client.useStreakFreeze(e);return await u(),s}catch(s){let l=s instanceof Error?s.message:"Unknown error";return a(d=>({...d,error:l})),null}},[t,u]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refresh:u,freeze:i}}function D(r){let t=w(),[o,a]=useState({badges:[],stats:null,earned:[],locked:[],loading:false,error:null}),u=useCallback(async i=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getBadges(i??r?.category),s=e.badges.filter(d=>d.isUnlocked),l=e.badges.filter(d=>!d.isUnlocked);a({badges:e.badges,stats:e.stats,earned:s,locked:l,loading:!1,error:null});}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t,r?.category]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refresh:u}}function Q(r){let t=w(),[o,a]=useState({items:[],userPoints:0,available:[],unavailable:[],loading:false,error:null}),u=useCallback(async()=>{if(!t?.client){a(e=>({...e,error:"SDK not initialized"}));return}a(e=>({...e,loading:true,error:null}));try{let e=await t.client.getRewardsStore(),s=e.items.filter(d=>d.isAvailable),l=e.items.filter(d=>!d.isAvailable);a({items:e.items,userPoints:e.userPoints,available:s,unavailable:l,loading:!1,error:null});}catch(e){let s=e instanceof Error?e.message:"Unknown error";a(l=>({...l,loading:false,error:s}));}},[t]),i=useCallback(async e=>{if(!t?.client)return a(s=>({...s,error:"SDK not initialized"})),null;a(s=>({...s,loading:true,error:null}));try{let s=await t.client.redeemReward(e);return await u(),s}catch(s){let l=s instanceof Error?s.message:"Unknown error";return a(d=>({...d,loading:false,error:l})),null}},[t,u]);return useEffect(()=>{r?.autoRefresh&&t?.client?.getUserId()&&u();},[r?.autoRefresh,t,u]),{...o,refresh:u,redeem:i}}function ne({pageName:r,properties:t,pathname:o}){let a=G(),u=useRef(null);return useEffect(()=>{if(typeof window>"u")return;if(o!==void 0){if(u.current===o)return;u.current=o;}let i=r??(typeof document<"u"?document.title:null)??(typeof window<"u"?window.location.pathname:"unknown");a("page_view",{page:i,url:typeof window<"u"?window.location.href:void 0,referrer:typeof document<"u"?document.referrer:void 0,...t});},[a,r,o,t]),null}function ie({eventType:r,properties:t,children:o}){let a=G();return cloneElement(o,{onClick:i=>{a(r,t),o.props.onClick&&o.props.onClick(i);}})}var k={statsContainer:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(150px, 1fr))",gap:"16px",padding:"16px"},statsCard:{backgroundColor:"#f8f9fa",borderRadius:"8px",padding:"16px",textAlign:"center",border:"1px solid #e9ecef"},statsValue:{fontSize:"24px",fontWeight:"bold",color:"#212529",marginBottom:"4px"},statsLabel:{fontSize:"14px",color:"#6c757d"},leaderboardContainer:{padding:"16px"},leaderboardList:{listStyle:"none",padding:0,margin:0},leaderboardRow:{display:"flex",alignItems:"center",padding:"12px",borderBottom:"1px solid #e9ecef"},leaderboardRowHighlighted:{display:"flex",alignItems:"center",padding:"12px",borderBottom:"1px solid #e9ecef",backgroundColor:"#fff3cd"},leaderboardRank:{fontWeight:"bold",width:"40px",color:"#212529"},leaderboardName:{flex:1,marginLeft:"12px",color:"#212529"},leaderboardStats:{color:"#6c757d",fontSize:"14px"},leaderboardEmpty:{textAlign:"center",padding:"32px",color:"#6c757d"},referralContainer:{display:"flex",gap:"8px",padding:"8px"},referralInput:{flex:1,padding:"10px 12px",border:"1px solid #ced4da",borderRadius:"6px",fontSize:"14px",backgroundColor:"#f8f9fa",color:"#212529"},referralButton:{padding:"10px 16px",border:"none",borderRadius:"6px",backgroundColor:"#0d6efd",color:"white",cursor:"pointer",fontSize:"14px",fontWeight:"500"}};function le({className:r,style:t,theme:o,autoRefresh:a=true,renderLoading:u,renderError:i}){let{stats:e,loading:s,error:l,refreshStats:d}=T({autoRefresh:a});if(useEffect(()=>{a&&d();},[a,d]),s)return u?u():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(l)return i?i(l):jsx("div",{style:{color:"red",padding:"16px"},children:l});if(!e)return null;let R={...k.statsCard,...o?.cardBackground&&{backgroundColor:o.cardBackground},...o?.cardBorder&&{border:`1px solid ${o.cardBorder}`}},S={...k.statsValue,...o?.valueColor&&{color:o.valueColor}},x={...k.statsLabel,...o?.labelColor&&{color:o.labelColor}},P=m=>`$${(m/100).toFixed(2)}`;return jsxs("div",{className:r,style:{...k.statsContainer,...t},children:[jsxs("div",{style:R,children:[jsx("div",{style:S,children:e.referralCount}),jsx("div",{style:x,children:"Referrals"})]}),jsxs("div",{style:R,children:[jsx("div",{style:S,children:e.earnings.transactionCount}),jsx("div",{style:x,children:"Commissions"})]}),jsxs("div",{style:R,children:[jsx("div",{style:S,children:P(e.earnings.totalEarned)}),jsx("div",{style:x,children:"Earnings"})]})]})}function de({limit:r=10,className:t,style:o,currentUserId:a,emptyMessage:u="No leaderboard data available yet.",theme:i,renderRow:e,renderLoading:s,renderError:l}){let{leaderboard:d,loading:R,error:S,refresh:x}=E(r);if(useEffect(()=>{x();},[x]),R)return s?s():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(S)return l?l(S):jsx("div",{style:{color:"red",padding:"16px"},children:S});if(!d||d.entries.length===0)return jsx("div",{className:t,style:{...k.leaderboardEmpty,...o},children:u});let P=f=>({...f?k.leaderboardRowHighlighted:k.leaderboardRow,...i?.rowBackground&&!f&&{backgroundColor:i.rowBackground},...i?.highlightBackground&&f&&{backgroundColor:i.highlightBackground}}),m=i?.textColor?{color:i.textColor}:{},h=i?.secondaryColor?{...k.leaderboardStats,color:i.secondaryColor}:k.leaderboardStats;return jsx("div",{className:t,style:{...k.leaderboardContainer,...o},children:jsx("ol",{style:k.leaderboardList,children:d.entries.map(f=>{let b=a===f.userId;return e?jsx("li",{children:e(f,b)},f.userId):jsxs("li",{style:P(b),children:[jsxs("span",{style:{...k.leaderboardRank,...m},children:["#",f.rank]}),jsx("span",{style:{...k.leaderboardName,...m},children:f.displayName??`User ${f.userId.slice(0,8)}`}),jsxs("span",{style:h,children:[f.referralCount," referrals"]})]},f.userId)})})})}function ce({baseUrl:r,className:t,style:o,copyButtonText:a="Copy",copiedText:u="Copied!",shareButtonText:i="Share",shareTitle:e="Check this out!",shareText:s="Join using my referral link",showShareButton:l=true,theme:d,onCopy:R,onShare:S}){let{stats:x}=T({autoRefresh:true}),[P,m]=useState(false),h=x?.referralCode;if(!h)return null;let f=typeof window<"u"?window.location.origin:"",b=`${r??f}?ref=${h}`,g=async()=>{try{await navigator.clipboard.writeText(b),m(!0),R?.(b),setTimeout(()=>m(!1),2e3);}catch(N){console.error("Failed to copy:",N);}},y=async()=>{if(typeof navigator<"u"&&navigator.share)try{await navigator.share({title:e,text:s,url:b}),S?.(b);}catch(N){N.name!=="AbortError"&&console.error("Failed to share:",N);}},v=typeof navigator<"u"&&"share"in navigator,B={...k.referralInput,...d?.inputBackground&&{backgroundColor:d.inputBackground},...d?.inputBorder&&{border:`1px solid ${d.inputBorder}`},...d?.inputColor&&{color:d.inputColor}},z={...k.referralButton,...d?.buttonBackground&&{backgroundColor:d.buttonBackground},...d?.buttonColor&&{color:d.buttonColor}};return jsxs("div",{className:t,style:{...k.referralContainer,...o},children:[jsx("input",{type:"text",readOnly:true,value:b,style:B,onClick:N=>N.target.select()}),jsx("button",{type:"button",onClick:g,style:z,children:P?u:a}),l&&v&&jsx("button",{type:"button",onClick:y,style:z,children:i})]})}var c={questContainer:{padding:"16px",backgroundColor:"#fff",borderRadius:"8px",border:"1px solid #e9ecef",marginBottom:"12px"},questHeader:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"12px"},questTitle:{fontSize:"16px",fontWeight:"600",color:"#212529",margin:0},questDescription:{fontSize:"14px",color:"#6c757d",margin:"4px 0 0 0"},questBadge:{fontSize:"12px",padding:"4px 8px",borderRadius:"12px",fontWeight:"500"},questProgressBar:{width:"100%",height:"8px",backgroundColor:"#e9ecef",borderRadius:"4px",overflow:"hidden",marginBottom:"12px"},questProgressFill:{height:"100%",backgroundColor:"#0d6efd",borderRadius:"4px",transition:"width 0.3s ease"},questStepList:{listStyle:"none",padding:0,margin:0},questStep:{display:"flex",alignItems:"center",padding:"8px 0",borderBottom:"1px solid #f8f9fa",fontSize:"14px"},questStepIcon:{width:"20px",height:"20px",borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",marginRight:"12px",fontSize:"12px"},questStepText:{flex:1,color:"#212529"},questStepCount:{fontSize:"12px",color:"#6c757d"},questReward:{display:"flex",alignItems:"center",marginTop:"12px",padding:"8px 12px",backgroundColor:"#fff3cd",borderRadius:"6px",fontSize:"14px",color:"#856404"},streakContainer:{display:"flex",alignItems:"center",padding:"16px",backgroundColor:"#fff",borderRadius:"8px",border:"1px solid #e9ecef"},streakFlame:{fontSize:"32px",marginRight:"12px"},streakCount:{fontSize:"28px",fontWeight:"bold",color:"#212529",marginRight:"8px"},streakLabel:{fontSize:"14px",color:"#6c757d"},streakInfo:{flex:1},streakName:{fontSize:"16px",fontWeight:"600",color:"#212529"},streakStatus:{fontSize:"12px",padding:"2px 8px",borderRadius:"10px",marginLeft:"8px"},freezeButton:{padding:"8px 16px",border:"none",borderRadius:"6px",backgroundColor:"#17a2b8",color:"white",cursor:"pointer",fontSize:"14px",display:"flex",alignItems:"center",gap:"6px"},freezeButtonDisabled:{padding:"8px 16px",border:"none",borderRadius:"6px",backgroundColor:"#6c757d",color:"white",cursor:"not-allowed",fontSize:"14px",opacity:.6},badgeGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(120px, 1fr))",gap:"16px",padding:"16px"},badgeCard:{display:"flex",flexDirection:"column",alignItems:"center",padding:"16px",backgroundColor:"#fff",borderRadius:"8px",border:"1px solid #e9ecef",cursor:"pointer",transition:"transform 0.2s, box-shadow 0.2s"},badgeCardLocked:{display:"flex",flexDirection:"column",alignItems:"center",padding:"16px",backgroundColor:"#f8f9fa",borderRadius:"8px",border:"1px solid #e9ecef",cursor:"pointer",opacity:.6,filter:"grayscale(100%)"},badgeIcon:{width:"64px",height:"64px",borderRadius:"50%",objectFit:"cover",marginBottom:"8px",backgroundColor:"#e9ecef"},badgeName:{fontSize:"14px",fontWeight:"500",color:"#212529",textAlign:"center",marginBottom:"4px"},badgeRarity:{fontSize:"11px",padding:"2px 8px",borderRadius:"10px",fontWeight:"500",textTransform:"uppercase"},badgeStats:{display:"flex",justifyContent:"center",gap:"16px",padding:"12px",backgroundColor:"#f8f9fa",borderRadius:"8px",marginBottom:"16px"},badgeStat:{textAlign:"center"},badgeStatValue:{fontSize:"20px",fontWeight:"bold",color:"#212529"},badgeStatLabel:{fontSize:"12px",color:"#6c757d"},levelContainer:{padding:"16px",backgroundColor:"#fff",borderRadius:"8px",border:"1px solid #e9ecef"},levelHeader:{display:"flex",alignItems:"center",marginBottom:"12px"},levelIcon:{width:"48px",height:"48px",borderRadius:"50%",marginRight:"12px",backgroundColor:"#e9ecef",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"24px"},levelInfo:{flex:1},levelTierName:{fontSize:"18px",fontWeight:"600",color:"#212529"},levelPoints:{fontSize:"14px",color:"#6c757d"},levelProgressContainer:{marginTop:"12px"},levelProgressHeader:{display:"flex",justifyContent:"space-between",marginBottom:"6px",fontSize:"13px"},levelProgressBar:{width:"100%",height:"10px",backgroundColor:"#e9ecef",borderRadius:"5px",overflow:"hidden"},levelProgressFill:{height:"100%",background:"linear-gradient(90deg, #667eea 0%, #764ba2 100%)",borderRadius:"5px",transition:"width 0.3s ease"},levelBenefits:{marginTop:"16px",padding:"12px",backgroundColor:"#f8f9fa",borderRadius:"6px"},levelBenefitsTitle:{fontSize:"14px",fontWeight:"600",color:"#212529",marginBottom:"8px"},levelBenefitsList:{listStyle:"none",padding:0,margin:0,fontSize:"13px",color:"#495057"},levelBenefitItem:{padding:"4px 0",display:"flex",alignItems:"center"},rewardStoreGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(200px, 1fr))",gap:"16px",padding:"16px"},rewardCard:{display:"flex",flexDirection:"column",backgroundColor:"#fff",borderRadius:"8px",border:"1px solid #e9ecef",overflow:"hidden"},rewardCardUnavailable:{display:"flex",flexDirection:"column",backgroundColor:"#f8f9fa",borderRadius:"8px",border:"1px solid #e9ecef",overflow:"hidden",opacity:.7},rewardImage:{width:"100%",height:"120px",objectFit:"cover",backgroundColor:"#e9ecef"},rewardContent:{padding:"12px",flex:1,display:"flex",flexDirection:"column"},rewardName:{fontSize:"16px",fontWeight:"600",color:"#212529",marginBottom:"4px"},rewardDescription:{fontSize:"13px",color:"#6c757d",marginBottom:"8px",flex:1},rewardCost:{fontSize:"14px",fontWeight:"600",color:"#0d6efd",marginBottom:"8px"},rewardButton:{padding:"10px 16px",border:"none",borderRadius:"6px",backgroundColor:"#0d6efd",color:"white",cursor:"pointer",fontSize:"14px",fontWeight:"500",width:"100%"},rewardButtonDisabled:{padding:"10px 16px",border:"none",borderRadius:"6px",backgroundColor:"#6c757d",color:"white",cursor:"not-allowed",fontSize:"14px",fontWeight:"500",width:"100%"},rewardPointsHeader:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"16px",backgroundColor:"#f8f9fa",borderRadius:"8px",marginBottom:"16px"},rewardPointsLabel:{fontSize:"14px",color:"#6c757d"},rewardPointsValue:{fontSize:"24px",fontWeight:"bold",color:"#212529"}};function $(r){switch(r){case "completed":return {bg:"#d4edda",color:"#155724"};case "in_progress":return {bg:"#cce5ff",color:"#004085"};case "active":return {bg:"#cce5ff",color:"#004085"};case "frozen":return {bg:"#cce5ff",color:"#17a2b8"};case "at_risk":return {bg:"#fff3cd",color:"#856404"};case "broken":return {bg:"#f8d7da",color:"#721c24"};default:return {bg:"#e9ecef",color:"#6c757d"}}}function ue(r){switch(r){case "COMMON":return {bg:"#e9ecef",color:"#495057"};case "RARE":return {bg:"#cce5ff",color:"#004085"};case "EPIC":return {bg:"#e2d5f1",color:"#6f42c1"};case "LEGENDARY":return {bg:"#fff3cd",color:"#856404"};default:return {bg:"#e9ecef",color:"#6c757d"}}}function fe({questId:r,hideCompleted:t=false,className:o,style:a,onComplete:u,theme:i,renderLoading:e,renderError:s,renderQuest:l}){let{quests:d,loading:R,error:S,refresh:x}=W({autoRefresh:true}),P=useRef(new Map);if(useEffect(()=>{x();},[x]),useEffect(()=>{u&&d.forEach(b=>{let g=P.current.get(b.id);g&&g.status!=="completed"&&b.status==="completed"&&u(b);});let f=new Map;d.forEach(b=>f.set(b.id,b)),P.current=f;},[d,u]),R)return e?e():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(S)return s?s(S):jsx("div",{style:{color:"red",padding:"16px"},children:S});let m=d;if(r&&(m=d.filter(f=>f.id===r)),t&&(m=m.filter(f=>f.status!=="completed")),m.length===0)return jsx("div",{style:{textAlign:"center",padding:"16px",color:"#6c757d"},children:"No quests available"});let h={...c.questContainer,...i?.cardBackground&&{backgroundColor:i.cardBackground},...i?.cardBorder&&{border:`1px solid ${i.cardBorder}`}};return jsx("div",{className:o,style:a,children:m.map(f=>{if(l)return jsx("div",{children:l(f)},f.id);let b=$(f.status);return jsxs("div",{style:h,children:[jsxs("div",{style:c.questHeader,children:[jsxs("div",{children:[jsx("h3",{style:{...c.questTitle,...i?.textColor&&{color:i.textColor}},children:f.name}),f.description&&jsx("p",{style:c.questDescription,children:f.description})]}),jsx("span",{style:{...c.questBadge,backgroundColor:b.bg,color:b.color},children:f.status.replace("_"," ")})]}),jsx("div",{style:c.questProgressBar,children:jsx("div",{style:{...c.questProgressFill,width:`${f.percentComplete}%`,...i?.progressColor&&{backgroundColor:i.progressColor}}})}),jsx("ul",{style:c.questStepList,children:f.steps.map(g=>jsxs("li",{style:c.questStep,children:[jsx("span",{style:{...c.questStepIcon,backgroundColor:g.completed?"#d4edda":"#e9ecef",color:g.completed?"#155724":"#6c757d"},children:g.completed?"\u2713":g.order}),jsx("span",{style:{...c.questStepText,textDecoration:g.completed?"line-through":"none",color:g.completed?"#6c757d":"#212529"},children:g.name}),jsxs("span",{style:c.questStepCount,children:[g.currentCount,"/",g.requiredCount]})]},g.id))}),f.xpReward>0&&jsxs("div",{style:c.questReward,children:[jsx("span",{style:{marginRight:"6px"},children:"\u2B50"}),f.xpReward," XP reward",f.badgeReward&&" + Badge"]})]},f.id)})})}function pe({ruleId:r,size:t="md",showFreezeButton:o=true,className:a,style:u,onFreeze:i,theme:e,renderLoading:s,renderError:l}){let{streaks:d,stats:R,loading:S,error:x,freeze:P,refresh:m}=F({autoRefresh:true}),[h,f]=useState(false);if(useEffect(()=>{m();},[m]),S)return s?s():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(x)return l?l(x):jsx("div",{style:{color:"red",padding:"16px"},children:x});let b=d;if(r&&(b=d.filter(v=>v.id===r)),b.length===0)return jsx("div",{style:{textAlign:"center",padding:"16px",color:"#6c757d"},children:"No streaks available"});let g={sm:{flame:"24px",count:"20px",container:"12px"},md:{flame:"32px",count:"28px",container:"16px"},lg:{flame:"48px",count:"40px",container:"20px"}},y=async v=>{f(true);try{let B=await P(v);B&&i&&i(v,B.remainingFreezes);}finally{f(false);}};return jsx("div",{className:a,style:u,children:b.map(v=>{let B=$(v.status),z=v.freezeInventory>0&&!v.freezeUsedToday;return jsxs("div",{style:{...c.streakContainer,padding:g[t].container,...e?.cardBackground&&{backgroundColor:e.cardBackground}},children:[jsx("span",{style:{...c.streakFlame,fontSize:g[t].flame,...e?.flameColor&&{color:e.flameColor}},children:"\u{1F525}"}),jsx("span",{style:{...c.streakCount,fontSize:g[t].count,...e?.countColor&&{color:e.countColor}},children:v.currentCount}),jsxs("div",{style:c.streakInfo,children:[jsxs("div",{style:{display:"flex",alignItems:"center"},children:[jsx("span",{style:c.streakName,children:v.name}),jsx("span",{style:{...c.streakStatus,backgroundColor:B.bg,color:B.color},children:v.status})]}),jsxs("span",{style:c.streakLabel,children:["Best: ",v.maxStreak," days"]})]}),o&&jsxs("button",{type:"button",onClick:()=>{y(v.id);},disabled:!z||h,style:z?c.freezeButton:c.freezeButtonDisabled,children:[jsx("span",{children:"\u2744\uFE0F"}),jsx("span",{children:v.freezeInventory})]})]},v.id)})})}function ge({showLocked:r=true,category:t,columns:o=4,className:a,style:u,showStats:i=true,onBadgeClick:e,theme:s,renderLoading:l,renderError:d,renderBadge:R}){let{badges:S,stats:x,loading:P,error:m,refresh:h}=D({autoRefresh:true,category:t});if(useEffect(()=>{h(t);},[h,t]),P)return l?l():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(m)return d?d(m):jsx("div",{style:{color:"red",padding:"16px"},children:m});let f=S;r||(f=S.filter(g=>g.isUnlocked));let b={...c.badgeGrid,gridTemplateColumns:`repeat(${o}, 1fr)`};return jsxs("div",{className:a,style:u,children:[i&&x&&jsxs("div",{style:c.badgeStats,children:[jsxs("div",{style:c.badgeStat,children:[jsx("div",{style:c.badgeStatValue,children:x.unlocked}),jsx("div",{style:c.badgeStatLabel,children:"Unlocked"})]}),jsxs("div",{style:c.badgeStat,children:[jsx("div",{style:c.badgeStatValue,children:x.total}),jsx("div",{style:c.badgeStatLabel,children:"Total"})]}),jsxs("div",{style:c.badgeStat,children:[jsxs("div",{style:c.badgeStatValue,children:[x.total>0?Math.round(x.unlocked/x.total*100):0,"%"]}),jsx("div",{style:c.badgeStatLabel,children:"Progress"})]})]}),jsx("div",{style:b,children:f.map(g=>{if(R)return jsx("div",{children:R(g)},g.id);let y=ue(g.rarity),v=g.isUnlocked?{...c.badgeCard,...s?.cardBackground&&{backgroundColor:s.cardBackground},...s?.cardBorder&&{border:`1px solid ${s.cardBorder}`}}:c.badgeCardLocked;return jsxs("div",{style:v,onClick:()=>e?.(g),onKeyDown:B=>B.key==="Enter"&&e?.(g),role:"button",tabIndex:0,children:[g.iconUrl?jsx("img",{src:g.iconUrl,alt:g.name,style:c.badgeIcon}):jsx("div",{style:c.badgeIcon,children:g.isUnlocked?"\u{1F3C6}":"\u{1F512}"}),jsx("span",{style:c.badgeName,children:g.name}),jsx("span",{style:{...c.badgeRarity,backgroundColor:y.bg,color:y.color},children:g.rarity})]},g.id)})})]})}function ye({showNextTier:r=true,showBenefits:t=false,className:o,style:a,theme:u,renderLoading:i,renderError:e}){let{profile:s,loading:l,error:d,refreshProfile:R}=U({autoRefresh:true});if(useEffect(()=>{R();},[R]),l)return i?i():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(d)return e?e(d):jsx("div",{style:{color:"red",padding:"16px"},children:d});if(!s)return null;let S=s.nextTier?Math.min(100,s.points/s.nextTier.minPoints*100):100,x={...c.levelContainer,...u?.cardBackground&&{backgroundColor:u.cardBackground}},P={...c.levelProgressFill,width:`${S}%`,...u?.progressGradient&&{background:u.progressGradient}};return jsxs("div",{className:o,style:{...x,...a},children:[jsxs("div",{style:c.levelHeader,children:[jsx("div",{style:{...c.levelIcon,...s.tier?.color&&{backgroundColor:s.tier.color}},children:s.tier?.iconUrl?jsx("img",{src:s.tier.iconUrl,alt:s.tier.name,style:{width:"100%",height:"100%",borderRadius:"50%"}}):"\u2B50"}),jsxs("div",{style:c.levelInfo,children:[jsx("div",{style:{...c.levelTierName,...u?.textColor&&{color:u.textColor}},children:s.tier?.name??"No Tier"}),jsxs("div",{style:c.levelPoints,children:[s.points.toLocaleString()," points"]})]})]}),r&&s.nextTier&&jsxs("div",{style:c.levelProgressContainer,children:[jsxs("div",{style:c.levelProgressHeader,children:[jsxs("span",{style:{color:"#6c757d"},children:["Progress to ",s.nextTier.name]}),jsxs("span",{style:{fontWeight:"500"},children:[s.nextTier.pointsNeeded.toLocaleString()," points needed"]})]}),jsx("div",{style:c.levelProgressBar,children:jsx("div",{style:P})})]}),t&&s.tier?.benefits&&Object.keys(s.tier.benefits).length>0&&jsxs("div",{style:c.levelBenefits,children:[jsx("div",{style:c.levelBenefitsTitle,children:"Your Benefits"}),jsx("ul",{style:c.levelBenefitsList,children:Object.entries(s.tier.benefits).map(([m,h])=>jsxs("li",{style:c.levelBenefitItem,children:[jsx("span",{style:{marginRight:"8px",color:"#28a745"},children:"\u2713"}),String(h)]},m))})]})]})}function Se({showUnavailable:r=true,className:t,style:o,showPointsHeader:a=true,onRedeem:u,theme:i,renderLoading:e,renderError:s,renderItem:l}){let{items:d,userPoints:R,loading:S,error:x,redeem:P,refresh:m}=Q({autoRefresh:true}),[h,f]=useState(null);if(useEffect(()=>{m();},[m]),S&&d.length===0)return e?e():jsx("div",{style:{textAlign:"center",padding:"16px"},children:"Loading..."});if(x)return s?s(x):jsx("div",{style:{color:"red",padding:"16px"},children:x});let b=d;r||(b=d.filter(y=>y.isAvailable));let g=async y=>{f(y.id);try{let v=await P(y.id);v&&u&&u(y,v);}finally{f(null);}};return jsxs("div",{className:t,style:o,children:[a&&jsxs("div",{style:c.rewardPointsHeader,children:[jsx("span",{style:c.rewardPointsLabel,children:"Your Points"}),jsx("span",{style:c.rewardPointsValue,children:R.toLocaleString()})]}),jsx("div",{style:c.rewardStoreGrid,children:b.map(y=>{if(l)return jsx("div",{children:l(y,()=>{g(y);})},y.id);let v=y.isAvailable?{...c.rewardCard,...i?.cardBackground&&{backgroundColor:i.cardBackground}}:c.rewardCardUnavailable,B=y.isAvailable&&y.canAfford?{...c.rewardButton,...i?.buttonColor&&{backgroundColor:i.buttonColor}}:c.rewardButtonDisabled,z=h===y.id;return jsxs("div",{style:v,children:[y.imageUrl?jsx("img",{src:y.imageUrl,alt:y.name,style:c.rewardImage}):jsx("div",{style:{...c.rewardImage,display:"flex",alignItems:"center",justifyContent:"center",fontSize:"32px"},children:"\u{1F381}"}),jsxs("div",{style:c.rewardContent,children:[jsx("span",{style:c.rewardName,children:y.name}),y.description&&jsx("span",{style:c.rewardDescription,children:y.description}),jsxs("span",{style:c.rewardCost,children:[y.pointsCost.toLocaleString()," points"]}),y.requiredBadgeName&&!y.hasBadge&&jsxs("span",{style:{fontSize:"12px",color:"#dc3545",marginBottom:"8px"},children:["Requires: ",y.requiredBadgeName]}),jsx("button",{type:"button",onClick:()=>{g(y);},disabled:!y.isAvailable||!y.canAfford||z,style:B,children:z?"Redeeming...":y.canAfford?"Redeem":`Need ${(y.pointsCost-R).toLocaleString()} more`})]})]},y.id)})})]})}export{le as AffiliateStats,ge as BadgeGrid,ne as GamifyPageView,Z as GamifyProvider,ie as GamifyTrackClick,de as Leaderboard,ye as LevelProgress,fe as QuestProgress,ce as ReferralLink,Se as RewardStore,pe as StreakFlame,T as useAffiliateStats,D as useBadges,re as useGamify,te as useIdentify,E as useLeaderboard,U as useLoyalty,W as useQuests,ae as useReferral,Q as useRewards,oe as useSession,F as useStreaks,G as useTrack};//# sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context.tsx","../src/hooks.ts","../src/components.tsx"],"names":["GamifyContext","createContext","isServer","GamifyProvider","config","children","clientRef","useRef","client","useMemo","newClient","Gamify","useEffect","contextValue","eventType","properties","userId","traits","jsx","Fragment","useGamifyContext","useContext","useGamify","context","useTrack","useCallback","useIdentify","useSession","state","setState","useState","updateCart","items","coupons","currency","s","session","error","message","applyCoupon","code","complete","clearSession","refresh","useLoyalty","options","refreshProfile","profile","refreshHistory","limit","offset","history","useReferral","setReferrer","clearReferrer","detectFromUrl","useAffiliateStats","refreshStats","forceRefresh","stats","useLeaderboard","customLimit","leaderboard","useQuests","response","useStreaks","freeze","ruleId","result","useBadges","category","earned","b","locked","useRewards","available","i","unavailable","redeem","itemId","GamifyPageView","pageName","pathname","track","lastPathRef","page","GamifyTrackClick","cloneElement","e","defaultStyles","AffiliateStats","className","style","theme","autoRefresh","renderLoading","renderError","loading","cardStyle","valueStyle","labelStyle","formatCurrency","cents","jsxs","Leaderboard","currentUserId","emptyMessage","renderRow","getRowStyle","isCurrentUser","textStyle","secondaryStyle","entry","ReferralLink","baseUrl","copyButtonText","copiedText","shareButtonText","shareTitle","shareText","showShareButton","onCopy","onShare","copied","setCopied","referralCode","origin","referralLink","handleCopy","err","handleShare","canShare","inputStyle","buttonStyle","gamificationStyles","getStatusColors","status","getRarityColors","rarity","QuestProgress","questId","hideCompleted","onComplete","renderQuest","quests","previousQuests","quest","prev","newMap","q","filteredQuests","statusColors","step","StreakFlame","size","showFreezeButton","onFreeze","streaks","freezing","setFreezing","displayStreaks","sizeStyles","handleFreeze","streakId","streak","canFreeze","BadgeGrid","showLocked","columns","showStats","onBadgeClick","renderBadge","badges","displayBadges","gridStyle","badge","rarityColors","LevelProgress","showNextTier","showBenefits","progressPercent","containerStyle","progressFillStyle","key","value","RewardStore","showUnavailable","showPointsHeader","onRedeem","renderItem","userPoints","redeemingId","setRedeemingId","displayItems","handleRedeem","item","isRedeeming"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useMemo,\n useEffect,\n useRef,\n type ReactNode,\n} from 'react';\nimport { Gamify, type GamifyConfig } from '@gamifyio/core';\n\n/**\n * Context value for Gamify React SDK\n */\nexport interface GamifyContextValue {\n /** The underlying Gamify client instance */\n client: Gamify;\n /** Track an event */\n track: (eventType: string, properties?: Record<string, unknown>) => void;\n /** Identify a user */\n identify: (userId: string, traits?: Record<string, unknown>) => void;\n /** Reset user identity */\n reset: () => void;\n /** Get current user ID */\n getUserId: () => string | null;\n /** Get anonymous ID */\n getAnonymousId: () => string;\n}\n\nconst GamifyContext = createContext<GamifyContextValue | null>(null);\n\n/**\n * Props for GamifyProvider\n */\nexport interface GamifyProviderProps {\n /** Gamify SDK configuration */\n config: GamifyConfig;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Check if code is running on the server\n */\nfunction isServer(): boolean {\n return typeof window === 'undefined';\n}\n\n/**\n * GamifyProvider - Initializes and provides Gamify SDK to React components\n *\n * @example\n * ```tsx\n * <GamifyProvider config={{ apiKey: 'your-api-key' }}>\n * <App />\n * </GamifyProvider>\n * ```\n */\nexport function GamifyProvider({ config, children }: GamifyProviderProps) {\n const clientRef = useRef<Gamify | null>(null);\n\n // Initialize client only once and only on client-side\n const client = useMemo(() => {\n // SSR safety: return null on server\n if (isServer()) {\n return null;\n }\n\n // Reuse existing client if config hasn't changed\n if (clientRef.current) {\n return clientRef.current;\n }\n\n const newClient = new Gamify(config);\n clientRef.current = newClient;\n return newClient;\n }, [config.apiKey, config.endpoint]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (clientRef.current) {\n clientRef.current.shutdown();\n clientRef.current = null;\n }\n };\n }, []);\n\n // Create context value with wrapper methods\n const contextValue = useMemo<GamifyContextValue | null>(() => {\n if (!client) return null;\n\n return {\n client,\n track: (eventType, properties) => client.track(eventType, properties),\n identify: (userId, traits) => client.identify(userId, traits),\n reset: () => client.reset(),\n getUserId: () => client.getUserId(),\n getAnonymousId: () => client.getAnonymousId(),\n };\n }, [client]);\n\n // During SSR, render children without context\n if (!contextValue) {\n return <>{children}</>;\n }\n\n return (\n <GamifyContext.Provider value={contextValue}>\n {children}\n </GamifyContext.Provider>\n );\n}\n\n/**\n * useGamifyContext - Internal hook to access Gamify context\n */\nexport function useGamifyContext(): GamifyContextValue | null {\n return useContext(GamifyContext);\n}\n","'use client';\n\nimport { useCallback, useState, useEffect } from 'react';\nimport { useGamifyContext, type GamifyContextValue } from './context.js';\nimport type {\n CartItem,\n SessionResponse,\n LoyaltyProfile,\n LoyaltyHistoryResponse,\n // Issue #22: Affiliate types\n AffiliateStats,\n LeaderboardResponse,\n // Gamification types\n QuestWithProgress,\n StreakWithProgress,\n StreaksResponse,\n FreezeResponse,\n BadgeWithStatus,\n BadgesResponse,\n RewardItem,\n RewardsStoreResponse,\n RedemptionResult,\n} from '@gamifyio/core';\n\n/**\n * useGamify - Hook to access Gamify SDK methods\n *\n * @throws Error if used outside of GamifyProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { track, identify } = useGamify();\n *\n * const handleClick = () => {\n * track('button_click', { buttonId: 'submit' });\n * };\n *\n * return <button onClick={handleClick}>Submit</button>;\n * }\n * ```\n */\nexport function useGamify(): GamifyContextValue {\n const context = useGamifyContext();\n\n if (!context) {\n throw new Error(\n 'useGamify must be used within a GamifyProvider. ' +\n 'Make sure your component is wrapped with <GamifyProvider>.'\n );\n }\n\n return context;\n}\n\n/**\n * useTrack - Hook for tracking events\n *\n * Returns a memoized track function that can be safely used in dependencies.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const track = useTrack();\n *\n * useEffect(() => {\n * track('component_viewed', { componentName: 'MyComponent' });\n * }, [track]);\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useTrack(): (\n eventType: string,\n properties?: Record<string, unknown>\n) => void {\n const context = useGamifyContext();\n\n return useCallback(\n (eventType: string, properties?: Record<string, unknown>) => {\n if (context) {\n context.track(eventType, properties);\n }\n },\n [context]\n );\n}\n\n/**\n * useIdentify - Hook for identifying users\n *\n * Returns a memoized identify function.\n *\n * @example\n * ```tsx\n * function LoginButton() {\n * const identify = useIdentify();\n *\n * const handleLogin = async (user: User) => {\n * await loginUser(user);\n * identify(user.id, { email: user.email, name: user.name });\n * };\n *\n * return <button onClick={handleLogin}>Login</button>;\n * }\n * ```\n */\nexport function useIdentify(): (\n userId: string,\n traits?: Record<string, unknown>\n) => void {\n const context = useGamifyContext();\n\n return useCallback(\n (userId: string, traits?: Record<string, unknown>) => {\n if (context) {\n context.identify(userId, traits);\n }\n },\n [context]\n );\n}\n\n// ============================================\n// Issue #14: useSession Hook\n// ============================================\n\ninterface SessionState {\n session: SessionResponse | null;\n loading: boolean;\n error: string | null;\n}\n\ninterface SessionActions {\n updateCart: (items: CartItem[], coupons?: string[], currency?: string) => Promise<void>;\n applyCoupon: (code: string) => Promise<void>;\n complete: () => Promise<void>;\n clearSession: () => void;\n refresh: () => Promise<void>;\n}\n\n/**\n * useSession - Hook for managing cart sessions with discounts\n *\n * @example\n * ```tsx\n * function CartPage() {\n * const { session, loading, updateCart, applyCoupon, complete } = useSession();\n *\n * const handleAddItem = async (item: CartItem) => {\n * const items = [...(session?.items || []), item];\n * await updateCart(items);\n * };\n *\n * return (\n * <div>\n * {loading && <Spinner />}\n * <p>Subtotal: ${session?.subtotal}</p>\n * <p>Discount: ${session?.discount}</p>\n * <p>Total: ${session?.total}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useSession(): SessionState & SessionActions {\n const context = useGamifyContext();\n const [state, setState] = useState<SessionState>({\n session: context?.client?.session?.getCachedSession() ?? null,\n loading: false,\n error: null,\n });\n\n const updateCart = useCallback(\n async (items: CartItem[], coupons?: string[], currency?: string) => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const session = await context.client.updateCart(items, coupons, currency);\n setState({ session, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context]\n );\n\n const applyCoupon = useCallback(\n async (code: string) => {\n if (!context?.client?.session) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const session = await context.client.session.applyCoupon(code);\n setState({ session, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context]\n );\n\n const complete = useCallback(async () => {\n if (!context?.client?.session) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const session = await context.client.session.complete();\n setState({ session, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n const clearSession = useCallback(() => {\n if (context?.client?.session) {\n context.client.session.clearSession();\n setState({ session: null, loading: false, error: null });\n }\n }, [context]);\n\n const refresh = useCallback(async () => {\n if (!context?.client?.session) {\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const session = await context.client.session.getSession();\n setState({ session, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n return {\n ...state,\n updateCart,\n applyCoupon,\n complete,\n clearSession,\n refresh,\n };\n}\n\n// ============================================\n// Issue #15: useLoyalty Hook\n// ============================================\n\ninterface LoyaltyState {\n profile: LoyaltyProfile | null;\n history: LoyaltyHistoryResponse | null;\n loading: boolean;\n error: string | null;\n}\n\ninterface LoyaltyActions {\n refreshProfile: () => Promise<void>;\n refreshHistory: (limit?: number, offset?: number) => Promise<void>;\n}\n\n/**\n * useLoyalty - Hook for managing customer loyalty data\n *\n * @param options - Auto-refresh options\n *\n * @example\n * ```tsx\n * function LoyaltyDashboard() {\n * const { profile, history, loading, refreshProfile } = useLoyalty({\n * autoRefresh: true,\n * });\n *\n * return (\n * <div>\n * {loading && <Spinner />}\n * <p>Points: {profile?.points}</p>\n * <p>Tier: {profile?.tier?.name}</p>\n * <p>Next tier: {profile?.nextTier?.name} ({profile?.nextTier?.pointsNeeded} points needed)</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useLoyalty(options?: {\n autoRefresh?: boolean;\n}): LoyaltyState & LoyaltyActions {\n const context = useGamifyContext();\n const [state, setState] = useState<LoyaltyState>({\n profile: context?.client?.loyalty?.getCachedProfile() ?? null,\n history: null,\n loading: false,\n error: null,\n });\n\n const refreshProfile = useCallback(async () => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const profile = await context.client.getLoyaltyProfile();\n setState((s) => ({ ...s, profile, loading: false, error: null }));\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n const refreshHistory = useCallback(\n async (limit?: number, offset?: number) => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const history = await context.client.getLoyaltyHistory(limit, offset);\n setState((s) => ({ ...s, history, loading: false, error: null }));\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context]\n );\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refreshProfile();\n }\n }, [options?.autoRefresh, context, refreshProfile]);\n\n return {\n ...state,\n refreshProfile,\n refreshHistory,\n };\n}\n\n// ============================================\n// Issue #22: useReferral Hook\n// ============================================\n\ninterface ReferralState {\n referrerCode: string | null;\n hasReferrer: boolean;\n}\n\ninterface ReferralActions {\n setReferrer: (code: string) => void;\n clearReferrer: () => void;\n detectFromUrl: () => string | null;\n}\n\n/**\n * useReferral - Hook for managing referral attribution\n *\n * Automatically detects `?ref=code` parameter from URLs and stores\n * the referrer code in localStorage for attribution tracking.\n *\n * @example\n * ```tsx\n * function SignupPage() {\n * const { referrerCode, hasReferrer, setReferrer } = useReferral();\n *\n * useEffect(() => {\n * if (hasReferrer) {\n * console.log('User was referred by:', referrerCode);\n * }\n * }, [hasReferrer, referrerCode]);\n *\n * return (\n * <div>\n * {hasReferrer && <p>Thanks for using referral code: {referrerCode}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useReferral(): ReferralState & ReferralActions {\n const context = useGamifyContext();\n const [state, setState] = useState<ReferralState>({\n referrerCode: context?.client?.referral?.getReferrer() ?? null,\n hasReferrer: context?.client?.referral?.hasReferrer() ?? false,\n });\n\n const setReferrer = useCallback(\n (code: string) => {\n if (context?.client?.referral) {\n context.client.referral.setReferrer(code);\n setState({\n referrerCode: code,\n hasReferrer: true,\n });\n }\n },\n [context]\n );\n\n const clearReferrer = useCallback(() => {\n if (context?.client?.referral) {\n context.client.referral.clearReferrer();\n setState({\n referrerCode: null,\n hasReferrer: false,\n });\n }\n }, [context]);\n\n const detectFromUrl = useCallback(() => {\n if (context?.client?.referral) {\n const code = context.client.referral.detectReferrerFromUrl();\n if (code) {\n setState({\n referrerCode: code,\n hasReferrer: true,\n });\n }\n return code;\n }\n return null;\n }, [context]);\n\n // Auto-detect on mount\n useEffect(() => {\n if (context?.client?.referral) {\n const code = context.client.referral.getReferrer();\n setState({\n referrerCode: code,\n hasReferrer: code !== null,\n });\n }\n }, [context]);\n\n return {\n ...state,\n setReferrer,\n clearReferrer,\n detectFromUrl,\n };\n}\n\n// ============================================\n// Issue #22: useAffiliateStats Hook\n// ============================================\n\ninterface AffiliateState {\n stats: AffiliateStats | null;\n loading: boolean;\n error: string | null;\n}\n\ninterface AffiliateActions {\n refreshStats: (forceRefresh?: boolean) => Promise<void>;\n}\n\n/**\n * useAffiliateStats - Hook for fetching user affiliate statistics\n *\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * function AffiliateDashboard() {\n * const { stats, loading, error, refreshStats } = useAffiliateStats({\n * autoRefresh: true,\n * });\n *\n * if (loading) return <Spinner />;\n * if (error) return <Error message={error} />;\n *\n * return (\n * <div>\n * <p>Your referral code: {stats?.referralCode}</p>\n * <p>Referrals: {stats?.referralCount}</p>\n * <p>Total earnings: ${(stats?.earnings.totalEarned ?? 0) / 100}</p>\n * <p>Current tier: {stats?.tier?.name ?? 'None'}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useAffiliateStats(options?: {\n autoRefresh?: boolean;\n}): AffiliateState & AffiliateActions {\n const context = useGamifyContext();\n const [state, setState] = useState<AffiliateState>({\n stats: context?.client?.affiliate?.getCachedStats() ?? null,\n loading: false,\n error: null,\n });\n\n const refreshStats = useCallback(\n async (forceRefresh = false) => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const stats = await context.client.getAffiliateStats(forceRefresh);\n setState({ stats, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context]\n );\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refreshStats();\n }\n }, [options?.autoRefresh, context, refreshStats]);\n\n return {\n ...state,\n refreshStats,\n };\n}\n\n// ============================================\n// Issue #22: useLeaderboard Hook\n// ============================================\n\ninterface LeaderboardState {\n leaderboard: LeaderboardResponse | null;\n loading: boolean;\n error: string | null;\n}\n\ninterface LeaderboardActions {\n refresh: (limit?: number) => Promise<void>;\n}\n\n/**\n * useLeaderboard - Hook for fetching affiliate leaderboard data\n *\n * @param limit - Number of entries to fetch (default: 10)\n *\n * @example\n * ```tsx\n * function LeaderboardPage() {\n * const { leaderboard, loading, error, refresh } = useLeaderboard(10);\n *\n * useEffect(() => {\n * refresh();\n * }, [refresh]);\n *\n * if (loading) return <Spinner />;\n * if (error) return <Error message={error} />;\n *\n * return (\n * <ol>\n * {leaderboard?.entries.map((entry) => (\n * <li key={entry.userId}>\n * #{entry.rank} - {entry.displayName}: {entry.referralCount} referrals\n * </li>\n * ))}\n * </ol>\n * );\n * }\n * ```\n */\nexport function useLeaderboard(\n limit = 10\n): LeaderboardState & LeaderboardActions {\n const context = useGamifyContext();\n const [state, setState] = useState<LeaderboardState>({\n leaderboard: null,\n loading: false,\n error: null,\n });\n\n const refresh = useCallback(\n async (customLimit?: number) => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const leaderboard = await context.client.getLeaderboard(customLimit ?? limit);\n setState({ leaderboard, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context, limit]\n );\n\n return {\n ...state,\n refresh,\n };\n}\n\n// ============================================\n// Issue #25-28: useQuests Hook\n// ============================================\n\ninterface QuestsState {\n quests: QuestWithProgress[];\n loading: boolean;\n error: string | null;\n}\n\ninterface QuestsActions {\n refresh: () => Promise<void>;\n}\n\n/**\n * useQuests - Hook for fetching user's quest progress\n *\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * function QuestsPage() {\n * const { quests, loading, error, refresh } = useQuests({ autoRefresh: true });\n *\n * if (loading) return <Spinner />;\n * if (error) return <Error message={error} />;\n *\n * return (\n * <div>\n * {quests.map((quest) => (\n * <div key={quest.id}>\n * <h3>{quest.name}</h3>\n * <p>Progress: {quest.percentComplete}%</p>\n * <p>Status: {quest.status}</p>\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useQuests(options?: {\n autoRefresh?: boolean;\n}): QuestsState & QuestsActions {\n const context = useGamifyContext();\n const [state, setState] = useState<QuestsState>({\n quests: [],\n loading: false,\n error: null,\n });\n\n const refresh = useCallback(async () => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const response = await context.client.getQuests();\n setState({ quests: response.quests, loading: false, error: null });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refresh();\n }\n }, [options?.autoRefresh, context, refresh]);\n\n return {\n ...state,\n refresh,\n };\n}\n\n// ============================================\n// Issue #32: useStreaks Hook\n// ============================================\n\ninterface StreaksState {\n streaks: StreakWithProgress[];\n stats: StreaksResponse['stats'] | null;\n loading: boolean;\n error: string | null;\n}\n\ninterface StreaksActions {\n refresh: () => Promise<void>;\n freeze: (ruleId: string) => Promise<FreezeResponse | null>;\n}\n\n/**\n * useStreaks - Hook for managing user's streak progress\n *\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * function StreaksPage() {\n * const { streaks, stats, loading, freeze } = useStreaks({ autoRefresh: true });\n *\n * return (\n * <div>\n * <p>Active streaks: {stats?.totalActive}</p>\n * {streaks.map((streak) => (\n * <div key={streak.id}>\n * <span>🔥 {streak.currentCount}</span>\n * <span>{streak.name}</span>\n * {streak.freezeInventory > 0 && (\n * <button onClick={() => freeze(streak.id)}>\n * Use Freeze ({streak.freezeInventory} left)\n * </button>\n * )}\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useStreaks(options?: {\n autoRefresh?: boolean;\n}): StreaksState & StreaksActions {\n const context = useGamifyContext();\n const [state, setState] = useState<StreaksState>({\n streaks: [],\n stats: null,\n loading: false,\n error: null,\n });\n\n const refresh = useCallback(async () => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const response = await context.client.getStreaks();\n setState({\n streaks: response.streaks,\n stats: response.stats,\n loading: false,\n error: null,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n const freeze = useCallback(\n async (ruleId: string): Promise<FreezeResponse | null> => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return null;\n }\n\n try {\n const result = await context.client.useStreakFreeze(ruleId);\n // Refresh to update freeze count\n await refresh();\n return result;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, error: message }));\n return null;\n }\n },\n [context, refresh]\n );\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refresh();\n }\n }, [options?.autoRefresh, context, refresh]);\n\n return {\n ...state,\n refresh,\n freeze,\n };\n}\n\n// ============================================\n// Issue #33: useBadges Hook\n// ============================================\n\ninterface BadgesState {\n badges: BadgeWithStatus[];\n stats: BadgesResponse['stats'] | null;\n earned: BadgeWithStatus[];\n locked: BadgeWithStatus[];\n loading: boolean;\n error: string | null;\n}\n\ninterface BadgesActions {\n refresh: (category?: string) => Promise<void>;\n}\n\n/**\n * useBadges - Hook for fetching user's badge collection\n *\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * function BadgesPage() {\n * const { badges, earned, locked, stats, loading } = useBadges({ autoRefresh: true });\n *\n * return (\n * <div>\n * <p>Unlocked: {stats?.unlocked} / {stats?.total}</p>\n * <div className=\"grid\">\n * {badges.map((badge) => (\n * <div key={badge.id} className={badge.isUnlocked ? '' : 'grayscale'}>\n * <img src={badge.iconUrl} alt={badge.name} />\n * <span>{badge.name}</span>\n * <span className={`rarity-${badge.rarity.toLowerCase()}`}>\n * {badge.rarity}\n * </span>\n * </div>\n * ))}\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useBadges(options?: {\n autoRefresh?: boolean;\n category?: string;\n}): BadgesState & BadgesActions {\n const context = useGamifyContext();\n const [state, setState] = useState<BadgesState>({\n badges: [],\n stats: null,\n earned: [],\n locked: [],\n loading: false,\n error: null,\n });\n\n const refresh = useCallback(\n async (category?: string) => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const response = await context.client.getBadges(category ?? options?.category);\n const earned = response.badges.filter((b) => b.isUnlocked);\n const locked = response.badges.filter((b) => !b.isUnlocked);\n setState({\n badges: response.badges,\n stats: response.stats,\n earned,\n locked,\n loading: false,\n error: null,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n },\n [context, options?.category]\n );\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refresh();\n }\n }, [options?.autoRefresh, context, refresh]);\n\n return {\n ...state,\n refresh,\n };\n}\n\n// ============================================\n// Issue #34: useRewards Hook\n// ============================================\n\ninterface RewardsState {\n items: RewardItem[];\n userPoints: number;\n available: RewardItem[];\n unavailable: RewardItem[];\n loading: boolean;\n error: string | null;\n}\n\ninterface RewardsActions {\n refresh: () => Promise<void>;\n redeem: (itemId: string) => Promise<RedemptionResult | null>;\n}\n\n/**\n * useRewards - Hook for fetching and redeeming rewards\n *\n * @param options - Configuration options\n *\n * @example\n * ```tsx\n * function RewardsStore() {\n * const { items, userPoints, loading, redeem } = useRewards({ autoRefresh: true });\n *\n * const handleRedeem = async (itemId: string) => {\n * const result = await redeem(itemId);\n * if (result?.success) {\n * alert('Reward redeemed!');\n * }\n * };\n *\n * return (\n * <div>\n * <p>Your points: {userPoints}</p>\n * <div className=\"grid\">\n * {items.map((item) => (\n * <div key={item.id}>\n * <img src={item.imageUrl} alt={item.name} />\n * <span>{item.name}</span>\n * <span>{item.pointsCost} points</span>\n * <button\n * disabled={!item.isAvailable}\n * onClick={() => handleRedeem(item.id)}\n * >\n * {item.canAfford ? 'Redeem' : `Need ${item.pointsCost - userPoints} more`}\n * </button>\n * </div>\n * ))}\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useRewards(options?: {\n autoRefresh?: boolean;\n}): RewardsState & RewardsActions {\n const context = useGamifyContext();\n const [state, setState] = useState<RewardsState>({\n items: [],\n userPoints: 0,\n available: [],\n unavailable: [],\n loading: false,\n error: null,\n });\n\n const refresh = useCallback(async () => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const response = await context.client.getRewardsStore();\n const available = response.items.filter((i) => i.isAvailable);\n const unavailable = response.items.filter((i) => !i.isAvailable);\n setState({\n items: response.items,\n userPoints: response.userPoints,\n available,\n unavailable,\n loading: false,\n error: null,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n }\n }, [context]);\n\n const redeem = useCallback(\n async (itemId: string): Promise<RedemptionResult | null> => {\n if (!context?.client) {\n setState((s) => ({ ...s, error: 'SDK not initialized' }));\n return null;\n }\n\n setState((s) => ({ ...s, loading: true, error: null }));\n\n try {\n const result = await context.client.redeemReward(itemId);\n // Refresh to update points and availability\n await refresh();\n return result;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n setState((s) => ({ ...s, loading: false, error: message }));\n return null;\n }\n },\n [context, refresh]\n );\n\n // Auto-refresh on mount if user is identified\n useEffect(() => {\n if (options?.autoRefresh && context?.client?.getUserId()) {\n void refresh();\n }\n }, [options?.autoRefresh, context, refresh]);\n\n return {\n ...state,\n refresh,\n redeem,\n };\n}\n","'use client';\n\nimport React, { useEffect, useRef, useState, cloneElement } from 'react';\nimport {\n useTrack,\n useAffiliateStats,\n useLeaderboard,\n useReferral,\n useQuests,\n useStreaks,\n useBadges,\n useRewards,\n useLoyalty,\n} from './hooks.js';\nimport type {\n AffiliateStats,\n LeaderboardEntry,\n QuestWithProgress,\n QuestStep,\n StreakWithProgress,\n BadgeWithStatus,\n BadgeRarity,\n RewardItem,\n RedemptionResult,\n} from '@gamifyio/core';\n\n/**\n * Props for GamifyPageView component\n */\nexport interface GamifyPageViewProps {\n /** Custom page name (defaults to document.title or window.location.pathname) */\n pageName?: string;\n /** Additional properties to include with page view events */\n properties?: Record<string, unknown>;\n /** Track on route changes (for SPAs) - requires pathname prop */\n pathname?: string;\n}\n\n/**\n * GamifyPageView - Component for automatic page view tracking\n *\n * Place this component in your layout or page components to automatically\n * track page views. For SPAs using Next.js App Router, pass the pathname\n * from usePathname() to track route changes.\n *\n * @example\n * ```tsx\n * // Basic usage - tracks on mount\n * function Page() {\n * return (\n * <>\n * <GamifyPageView />\n * <div>Page content</div>\n * </>\n * );\n * }\n *\n * // With Next.js App Router\n * 'use client';\n * import { usePathname } from 'next/navigation';\n *\n * function Layout({ children }) {\n * const pathname = usePathname();\n * return (\n * <>\n * <GamifyPageView pathname={pathname} />\n * {children}\n * </>\n * );\n * }\n *\n * // With custom properties\n * function ProductPage({ productId }) {\n * return (\n * <>\n * <GamifyPageView\n * pageName=\"Product Detail\"\n * properties={{ productId, category: 'electronics' }}\n * />\n * <div>Product content</div>\n * </>\n * );\n * }\n * ```\n */\nexport function GamifyPageView({\n pageName,\n properties,\n pathname,\n}: GamifyPageViewProps) {\n const track = useTrack();\n const lastPathRef = useRef<string | null>(null);\n\n useEffect(() => {\n // Skip if running on server\n if (typeof window === 'undefined') {\n return;\n }\n\n // For SPA routing: only track if pathname changed\n if (pathname !== undefined) {\n if (lastPathRef.current === pathname) {\n return;\n }\n lastPathRef.current = pathname;\n }\n\n // Determine page name\n const page =\n pageName ??\n (typeof document !== 'undefined' ? document.title : null) ??\n (typeof window !== 'undefined' ? window.location.pathname : 'unknown');\n\n // Track page view\n track('page_view', {\n page,\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n referrer: typeof document !== 'undefined' ? document.referrer : undefined,\n ...properties,\n });\n }, [track, pageName, pathname, properties]);\n\n // This component doesn't render anything\n return null;\n}\n\n/**\n * Props for GamifyTrackClick component\n */\nexport interface GamifyTrackClickProps {\n /** Event type to track */\n eventType: string;\n /** Properties to include with the event */\n properties?: Record<string, unknown>;\n /** Child element (must accept onClick) */\n children: React.ReactElement<{ onClick?: (e: React.MouseEvent) => void }>;\n}\n\n/**\n * GamifyTrackClick - Component wrapper for click tracking\n *\n * Wraps a child element and tracks clicks automatically.\n *\n * @example\n * ```tsx\n * <GamifyTrackClick\n * eventType=\"button_click\"\n * properties={{ buttonId: 'subscribe', location: 'header' }}\n * >\n * <button>Subscribe</button>\n * </GamifyTrackClick>\n * ```\n */\nexport function GamifyTrackClick({\n eventType,\n properties,\n children,\n}: GamifyTrackClickProps) {\n const track = useTrack();\n\n const handleClick = (e: React.MouseEvent) => {\n track(eventType, properties);\n\n // Call original onClick if it exists\n if (children.props.onClick) {\n children.props.onClick(e);\n }\n };\n\n // Clone the child and inject onClick handler\n return cloneElement(children, { onClick: handleClick });\n}\n\n// ============================================\n// Issue #23: Affiliate UI Components\n// ============================================\n\n/**\n * Default styles for affiliate components\n * Uses CSS-in-JS for zero-dependency styling\n */\nconst defaultStyles = {\n statsContainer: {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))',\n gap: '16px',\n padding: '16px',\n } as React.CSSProperties,\n statsCard: {\n backgroundColor: '#f8f9fa',\n borderRadius: '8px',\n padding: '16px',\n textAlign: 'center' as const,\n border: '1px solid #e9ecef',\n } as React.CSSProperties,\n statsValue: {\n fontSize: '24px',\n fontWeight: 'bold',\n color: '#212529',\n marginBottom: '4px',\n } as React.CSSProperties,\n statsLabel: {\n fontSize: '14px',\n color: '#6c757d',\n } as React.CSSProperties,\n leaderboardContainer: {\n padding: '16px',\n } as React.CSSProperties,\n leaderboardList: {\n listStyle: 'none',\n padding: 0,\n margin: 0,\n } as React.CSSProperties,\n leaderboardRow: {\n display: 'flex',\n alignItems: 'center',\n padding: '12px',\n borderBottom: '1px solid #e9ecef',\n } as React.CSSProperties,\n leaderboardRowHighlighted: {\n display: 'flex',\n alignItems: 'center',\n padding: '12px',\n borderBottom: '1px solid #e9ecef',\n backgroundColor: '#fff3cd',\n } as React.CSSProperties,\n leaderboardRank: {\n fontWeight: 'bold',\n width: '40px',\n color: '#212529',\n } as React.CSSProperties,\n leaderboardName: {\n flex: 1,\n marginLeft: '12px',\n color: '#212529',\n } as React.CSSProperties,\n leaderboardStats: {\n color: '#6c757d',\n fontSize: '14px',\n } as React.CSSProperties,\n leaderboardEmpty: {\n textAlign: 'center' as const,\n padding: '32px',\n color: '#6c757d',\n } as React.CSSProperties,\n referralContainer: {\n display: 'flex',\n gap: '8px',\n padding: '8px',\n } as React.CSSProperties,\n referralInput: {\n flex: 1,\n padding: '10px 12px',\n border: '1px solid #ced4da',\n borderRadius: '6px',\n fontSize: '14px',\n backgroundColor: '#f8f9fa',\n color: '#212529',\n } as React.CSSProperties,\n referralButton: {\n padding: '10px 16px',\n border: 'none',\n borderRadius: '6px',\n backgroundColor: '#0d6efd',\n color: 'white',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: '500',\n } as React.CSSProperties,\n};\n\n/**\n * Props for AffiliateStats component\n */\nexport interface AffiliateStatsProps {\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Theme customization */\n theme?: {\n cardBackground?: string;\n cardBorder?: string;\n valueColor?: string;\n labelColor?: string;\n };\n /** Auto-refresh stats on mount */\n autoRefresh?: boolean;\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n}\n\n/**\n * AffiliateStats - Display grid with affiliate statistics\n *\n * Shows referral count, clicks, and earnings in a card layout.\n * Headless-first: unstyled by default but includes sensible defaults.\n *\n * @example\n * ```tsx\n * <AffiliateStats autoRefresh />\n *\n * // With custom theme\n * <AffiliateStats\n * theme={{ cardBackground: '#1a1a1a', valueColor: '#fff' }}\n * />\n * ```\n */\nexport function AffiliateStats({\n className,\n style,\n theme,\n autoRefresh = true,\n renderLoading,\n renderError,\n}: AffiliateStatsProps) {\n const { stats, loading, error, refreshStats } = useAffiliateStats({ autoRefresh });\n\n useEffect(() => {\n if (autoRefresh) {\n void refreshStats();\n }\n }, [autoRefresh, refreshStats]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n if (!stats) {\n return null;\n }\n\n const cardStyle = {\n ...defaultStyles.statsCard,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n ...(theme?.cardBorder && { border: `1px solid ${theme.cardBorder}` }),\n };\n\n const valueStyle = {\n ...defaultStyles.statsValue,\n ...(theme?.valueColor && { color: theme.valueColor }),\n };\n\n const labelStyle = {\n ...defaultStyles.statsLabel,\n ...(theme?.labelColor && { color: theme.labelColor }),\n };\n\n const formatCurrency = (cents: number) => {\n return `$${(cents / 100).toFixed(2)}`;\n };\n\n return (\n <div className={className} style={{ ...defaultStyles.statsContainer, ...style }}>\n <div style={cardStyle}>\n <div style={valueStyle}>{stats.referralCount}</div>\n <div style={labelStyle}>Referrals</div>\n </div>\n <div style={cardStyle}>\n <div style={valueStyle}>{stats.earnings.transactionCount}</div>\n <div style={labelStyle}>Commissions</div>\n </div>\n <div style={cardStyle}>\n <div style={valueStyle}>{formatCurrency(stats.earnings.totalEarned)}</div>\n <div style={labelStyle}>Earnings</div>\n </div>\n </div>\n );\n}\n\n/**\n * Props for Leaderboard component\n */\nexport interface LeaderboardProps {\n /** Number of entries to display (default: 10) */\n limit?: number;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Current user ID for highlighting */\n currentUserId?: string;\n /** Custom empty state message */\n emptyMessage?: string;\n /** Theme customization */\n theme?: {\n rowBackground?: string;\n highlightBackground?: string;\n textColor?: string;\n secondaryColor?: string;\n };\n /** Custom render for each row */\n renderRow?: (entry: LeaderboardEntry, isCurrentUser: boolean) => React.ReactNode;\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n}\n\n/**\n * Leaderboard - Ranked affiliate leaderboard display\n *\n * Shows ranked list of top affiliates with referral counts.\n * Highlights the current user if their ID is provided.\n *\n * @example\n * ```tsx\n * <Leaderboard limit={10} currentUserId={userId} />\n *\n * // With custom render\n * <Leaderboard\n * renderRow={(entry, isCurrent) => (\n * <div className={isCurrent ? 'highlight' : ''}>\n * #{entry.rank} - {entry.displayName}\n * </div>\n * )}\n * />\n * ```\n */\nexport function Leaderboard({\n limit = 10,\n className,\n style,\n currentUserId,\n emptyMessage = 'No leaderboard data available yet.',\n theme,\n renderRow,\n renderLoading,\n renderError,\n}: LeaderboardProps) {\n const { leaderboard, loading, error, refresh } = useLeaderboard(limit);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n if (!leaderboard || leaderboard.entries.length === 0) {\n return (\n <div className={className} style={{ ...defaultStyles.leaderboardEmpty, ...style }}>\n {emptyMessage}\n </div>\n );\n }\n\n const getRowStyle = (isCurrentUser: boolean) => ({\n ...(isCurrentUser ? defaultStyles.leaderboardRowHighlighted : defaultStyles.leaderboardRow),\n ...(theme?.rowBackground && !isCurrentUser && { backgroundColor: theme.rowBackground }),\n ...(theme?.highlightBackground && isCurrentUser && { backgroundColor: theme.highlightBackground }),\n });\n\n const textStyle = theme?.textColor ? { color: theme.textColor } : {};\n const secondaryStyle = theme?.secondaryColor\n ? { ...defaultStyles.leaderboardStats, color: theme.secondaryColor }\n : defaultStyles.leaderboardStats;\n\n return (\n <div className={className} style={{ ...defaultStyles.leaderboardContainer, ...style }}>\n <ol style={defaultStyles.leaderboardList}>\n {leaderboard.entries.map((entry) => {\n const isCurrentUser = currentUserId === entry.userId;\n\n if (renderRow) {\n return <li key={entry.userId}>{renderRow(entry, isCurrentUser)}</li>;\n }\n\n return (\n <li key={entry.userId} style={getRowStyle(isCurrentUser)}>\n <span style={{ ...defaultStyles.leaderboardRank, ...textStyle }}>#{entry.rank}</span>\n <span style={{ ...defaultStyles.leaderboardName, ...textStyle }}>\n {entry.displayName ?? `User ${entry.userId.slice(0, 8)}`}\n </span>\n <span style={secondaryStyle}>\n {entry.referralCount} referrals\n </span>\n </li>\n );\n })}\n </ol>\n </div>\n );\n}\n\n/**\n * Props for ReferralLink component\n */\nexport interface ReferralLinkProps {\n /** Base URL for referral link (defaults to current origin) */\n baseUrl?: string;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Text for copy button */\n copyButtonText?: string;\n /** Text shown after copying */\n copiedText?: string;\n /** Text for share button (mobile only) */\n shareButtonText?: string;\n /** Share title */\n shareTitle?: string;\n /** Share text */\n shareText?: string;\n /** Show share button on mobile */\n showShareButton?: boolean;\n /** Theme customization */\n theme?: {\n inputBackground?: string;\n inputBorder?: string;\n inputColor?: string;\n buttonBackground?: string;\n buttonColor?: string;\n };\n /** Callback when link is copied */\n onCopy?: (link: string) => void;\n /** Callback when link is shared */\n onShare?: (link: string) => void;\n}\n\n/**\n * ReferralLink - Input field with user's referral code and copy/share buttons\n *\n * Displays the user's unique referral link with easy copy functionality.\n * Includes native share button for mobile devices.\n *\n * @example\n * ```tsx\n * <ReferralLink />\n *\n * // With custom base URL\n * <ReferralLink\n * baseUrl=\"https://myapp.com/signup\"\n * shareTitle=\"Join my app!\"\n * shareText=\"Sign up using my referral link\"\n * />\n * ```\n */\nexport function ReferralLink({\n baseUrl,\n className,\n style,\n copyButtonText = 'Copy',\n copiedText = 'Copied!',\n shareButtonText = 'Share',\n shareTitle = 'Check this out!',\n shareText = 'Join using my referral link',\n showShareButton = true,\n theme,\n onCopy,\n onShare,\n}: ReferralLinkProps) {\n const { stats } = useAffiliateStats({ autoRefresh: true });\n const [copied, setCopied] = useState(false);\n\n const referralCode = stats?.referralCode;\n\n if (!referralCode) {\n return null;\n }\n\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n const referralLink = `${baseUrl ?? origin}?ref=${referralCode}`;\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(referralLink);\n setCopied(true);\n onCopy?.(referralLink);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n };\n\n const handleShare = async () => {\n if (typeof navigator !== 'undefined' && navigator.share) {\n try {\n await navigator.share({\n title: shareTitle,\n text: shareText,\n url: referralLink,\n });\n onShare?.(referralLink);\n } catch (err) {\n // User cancelled or share failed\n if ((err as Error).name !== 'AbortError') {\n console.error('Failed to share:', err);\n }\n }\n }\n };\n\n const canShare = typeof navigator !== 'undefined' && 'share' in navigator;\n\n const inputStyle = {\n ...defaultStyles.referralInput,\n ...(theme?.inputBackground && { backgroundColor: theme.inputBackground }),\n ...(theme?.inputBorder && { border: `1px solid ${theme.inputBorder}` }),\n ...(theme?.inputColor && { color: theme.inputColor }),\n };\n\n const buttonStyle = {\n ...defaultStyles.referralButton,\n ...(theme?.buttonBackground && { backgroundColor: theme.buttonBackground }),\n ...(theme?.buttonColor && { color: theme.buttonColor }),\n };\n\n return (\n <div className={className} style={{ ...defaultStyles.referralContainer, ...style }}>\n <input\n type=\"text\"\n readOnly\n value={referralLink}\n style={inputStyle}\n onClick={(e) => (e.target as HTMLInputElement).select()}\n />\n <button type=\"button\" onClick={handleCopy} style={buttonStyle}>\n {copied ? copiedText : copyButtonText}\n </button>\n {showShareButton && canShare && (\n <button type=\"button\" onClick={handleShare} style={buttonStyle}>\n {shareButtonText}\n </button>\n )}\n </div>\n );\n}\n\n// ============================================\n// Issue #25-28: Quest Components\n// ============================================\n\n/**\n * Extended styles for gamification components\n */\nconst gamificationStyles = {\n // Quest styles\n questContainer: {\n padding: '16px',\n backgroundColor: '#fff',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n marginBottom: '12px',\n } as React.CSSProperties,\n questHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n marginBottom: '12px',\n } as React.CSSProperties,\n questTitle: {\n fontSize: '16px',\n fontWeight: '600',\n color: '#212529',\n margin: 0,\n } as React.CSSProperties,\n questDescription: {\n fontSize: '14px',\n color: '#6c757d',\n margin: '4px 0 0 0',\n } as React.CSSProperties,\n questBadge: {\n fontSize: '12px',\n padding: '4px 8px',\n borderRadius: '12px',\n fontWeight: '500',\n } as React.CSSProperties,\n questProgressBar: {\n width: '100%',\n height: '8px',\n backgroundColor: '#e9ecef',\n borderRadius: '4px',\n overflow: 'hidden',\n marginBottom: '12px',\n } as React.CSSProperties,\n questProgressFill: {\n height: '100%',\n backgroundColor: '#0d6efd',\n borderRadius: '4px',\n transition: 'width 0.3s ease',\n } as React.CSSProperties,\n questStepList: {\n listStyle: 'none',\n padding: 0,\n margin: 0,\n } as React.CSSProperties,\n questStep: {\n display: 'flex',\n alignItems: 'center',\n padding: '8px 0',\n borderBottom: '1px solid #f8f9fa',\n fontSize: '14px',\n } as React.CSSProperties,\n questStepIcon: {\n width: '20px',\n height: '20px',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n marginRight: '12px',\n fontSize: '12px',\n } as React.CSSProperties,\n questStepText: {\n flex: 1,\n color: '#212529',\n } as React.CSSProperties,\n questStepCount: {\n fontSize: '12px',\n color: '#6c757d',\n } as React.CSSProperties,\n questReward: {\n display: 'flex',\n alignItems: 'center',\n marginTop: '12px',\n padding: '8px 12px',\n backgroundColor: '#fff3cd',\n borderRadius: '6px',\n fontSize: '14px',\n color: '#856404',\n } as React.CSSProperties,\n\n // Streak styles\n streakContainer: {\n display: 'flex',\n alignItems: 'center',\n padding: '16px',\n backgroundColor: '#fff',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n } as React.CSSProperties,\n streakFlame: {\n fontSize: '32px',\n marginRight: '12px',\n } as React.CSSProperties,\n streakCount: {\n fontSize: '28px',\n fontWeight: 'bold',\n color: '#212529',\n marginRight: '8px',\n } as React.CSSProperties,\n streakLabel: {\n fontSize: '14px',\n color: '#6c757d',\n } as React.CSSProperties,\n streakInfo: {\n flex: 1,\n } as React.CSSProperties,\n streakName: {\n fontSize: '16px',\n fontWeight: '600',\n color: '#212529',\n } as React.CSSProperties,\n streakStatus: {\n fontSize: '12px',\n padding: '2px 8px',\n borderRadius: '10px',\n marginLeft: '8px',\n } as React.CSSProperties,\n freezeButton: {\n padding: '8px 16px',\n border: 'none',\n borderRadius: '6px',\n backgroundColor: '#17a2b8',\n color: 'white',\n cursor: 'pointer',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n } as React.CSSProperties,\n freezeButtonDisabled: {\n padding: '8px 16px',\n border: 'none',\n borderRadius: '6px',\n backgroundColor: '#6c757d',\n color: 'white',\n cursor: 'not-allowed',\n fontSize: '14px',\n opacity: 0.6,\n } as React.CSSProperties,\n\n // Badge styles\n badgeGrid: {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))',\n gap: '16px',\n padding: '16px',\n } as React.CSSProperties,\n badgeCard: {\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n padding: '16px',\n backgroundColor: '#fff',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n cursor: 'pointer',\n transition: 'transform 0.2s, box-shadow 0.2s',\n } as React.CSSProperties,\n badgeCardLocked: {\n display: 'flex',\n flexDirection: 'column' as const,\n alignItems: 'center',\n padding: '16px',\n backgroundColor: '#f8f9fa',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n cursor: 'pointer',\n opacity: 0.6,\n filter: 'grayscale(100%)',\n } as React.CSSProperties,\n badgeIcon: {\n width: '64px',\n height: '64px',\n borderRadius: '50%',\n objectFit: 'cover' as const,\n marginBottom: '8px',\n backgroundColor: '#e9ecef',\n } as React.CSSProperties,\n badgeName: {\n fontSize: '14px',\n fontWeight: '500',\n color: '#212529',\n textAlign: 'center' as const,\n marginBottom: '4px',\n } as React.CSSProperties,\n badgeRarity: {\n fontSize: '11px',\n padding: '2px 8px',\n borderRadius: '10px',\n fontWeight: '500',\n textTransform: 'uppercase' as const,\n } as React.CSSProperties,\n badgeStats: {\n display: 'flex',\n justifyContent: 'center',\n gap: '16px',\n padding: '12px',\n backgroundColor: '#f8f9fa',\n borderRadius: '8px',\n marginBottom: '16px',\n } as React.CSSProperties,\n badgeStat: {\n textAlign: 'center' as const,\n } as React.CSSProperties,\n badgeStatValue: {\n fontSize: '20px',\n fontWeight: 'bold',\n color: '#212529',\n } as React.CSSProperties,\n badgeStatLabel: {\n fontSize: '12px',\n color: '#6c757d',\n } as React.CSSProperties,\n\n // Level/Tier styles\n levelContainer: {\n padding: '16px',\n backgroundColor: '#fff',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n } as React.CSSProperties,\n levelHeader: {\n display: 'flex',\n alignItems: 'center',\n marginBottom: '12px',\n } as React.CSSProperties,\n levelIcon: {\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n marginRight: '12px',\n backgroundColor: '#e9ecef',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '24px',\n } as React.CSSProperties,\n levelInfo: {\n flex: 1,\n } as React.CSSProperties,\n levelTierName: {\n fontSize: '18px',\n fontWeight: '600',\n color: '#212529',\n } as React.CSSProperties,\n levelPoints: {\n fontSize: '14px',\n color: '#6c757d',\n } as React.CSSProperties,\n levelProgressContainer: {\n marginTop: '12px',\n } as React.CSSProperties,\n levelProgressHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '6px',\n fontSize: '13px',\n } as React.CSSProperties,\n levelProgressBar: {\n width: '100%',\n height: '10px',\n backgroundColor: '#e9ecef',\n borderRadius: '5px',\n overflow: 'hidden',\n } as React.CSSProperties,\n levelProgressFill: {\n height: '100%',\n background: 'linear-gradient(90deg, #667eea 0%, #764ba2 100%)',\n borderRadius: '5px',\n transition: 'width 0.3s ease',\n } as React.CSSProperties,\n levelBenefits: {\n marginTop: '16px',\n padding: '12px',\n backgroundColor: '#f8f9fa',\n borderRadius: '6px',\n } as React.CSSProperties,\n levelBenefitsTitle: {\n fontSize: '14px',\n fontWeight: '600',\n color: '#212529',\n marginBottom: '8px',\n } as React.CSSProperties,\n levelBenefitsList: {\n listStyle: 'none',\n padding: 0,\n margin: 0,\n fontSize: '13px',\n color: '#495057',\n } as React.CSSProperties,\n levelBenefitItem: {\n padding: '4px 0',\n display: 'flex',\n alignItems: 'center',\n } as React.CSSProperties,\n\n // Reward store styles\n rewardStoreGrid: {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',\n gap: '16px',\n padding: '16px',\n } as React.CSSProperties,\n rewardCard: {\n display: 'flex',\n flexDirection: 'column' as const,\n backgroundColor: '#fff',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n overflow: 'hidden',\n } as React.CSSProperties,\n rewardCardUnavailable: {\n display: 'flex',\n flexDirection: 'column' as const,\n backgroundColor: '#f8f9fa',\n borderRadius: '8px',\n border: '1px solid #e9ecef',\n overflow: 'hidden',\n opacity: 0.7,\n } as React.CSSProperties,\n rewardImage: {\n width: '100%',\n height: '120px',\n objectFit: 'cover' as const,\n backgroundColor: '#e9ecef',\n } as React.CSSProperties,\n rewardContent: {\n padding: '12px',\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n } as React.CSSProperties,\n rewardName: {\n fontSize: '16px',\n fontWeight: '600',\n color: '#212529',\n marginBottom: '4px',\n } as React.CSSProperties,\n rewardDescription: {\n fontSize: '13px',\n color: '#6c757d',\n marginBottom: '8px',\n flex: 1,\n } as React.CSSProperties,\n rewardCost: {\n fontSize: '14px',\n fontWeight: '600',\n color: '#0d6efd',\n marginBottom: '8px',\n } as React.CSSProperties,\n rewardButton: {\n padding: '10px 16px',\n border: 'none',\n borderRadius: '6px',\n backgroundColor: '#0d6efd',\n color: 'white',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: '500',\n width: '100%',\n } as React.CSSProperties,\n rewardButtonDisabled: {\n padding: '10px 16px',\n border: 'none',\n borderRadius: '6px',\n backgroundColor: '#6c757d',\n color: 'white',\n cursor: 'not-allowed',\n fontSize: '14px',\n fontWeight: '500',\n width: '100%',\n } as React.CSSProperties,\n rewardPointsHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '16px',\n backgroundColor: '#f8f9fa',\n borderRadius: '8px',\n marginBottom: '16px',\n } as React.CSSProperties,\n rewardPointsLabel: {\n fontSize: '14px',\n color: '#6c757d',\n } as React.CSSProperties,\n rewardPointsValue: {\n fontSize: '24px',\n fontWeight: 'bold',\n color: '#212529',\n } as React.CSSProperties,\n};\n\n/**\n * Helper function to get status badge colors\n */\nfunction getStatusColors(status: string): { bg: string; color: string } {\n switch (status) {\n case 'completed':\n return { bg: '#d4edda', color: '#155724' };\n case 'in_progress':\n return { bg: '#cce5ff', color: '#004085' };\n case 'active':\n return { bg: '#cce5ff', color: '#004085' };\n case 'frozen':\n return { bg: '#cce5ff', color: '#17a2b8' };\n case 'at_risk':\n return { bg: '#fff3cd', color: '#856404' };\n case 'broken':\n return { bg: '#f8d7da', color: '#721c24' };\n default:\n return { bg: '#e9ecef', color: '#6c757d' };\n }\n}\n\n/**\n * Helper function to get rarity colors\n */\nfunction getRarityColors(rarity: BadgeRarity): { bg: string; color: string } {\n switch (rarity) {\n case 'COMMON':\n return { bg: '#e9ecef', color: '#495057' };\n case 'RARE':\n return { bg: '#cce5ff', color: '#004085' };\n case 'EPIC':\n return { bg: '#e2d5f1', color: '#6f42c1' };\n case 'LEGENDARY':\n return { bg: '#fff3cd', color: '#856404' };\n default:\n return { bg: '#e9ecef', color: '#6c757d' };\n }\n}\n\n/**\n * Props for QuestProgress component\n */\nexport interface QuestProgressProps {\n /** Specific quest ID to display (shows all if not provided) */\n questId?: string;\n /** Hide completed quests */\n hideCompleted?: boolean;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Callback when a quest is completed */\n onComplete?: (quest: QuestWithProgress) => void;\n /** Theme customization */\n theme?: {\n cardBackground?: string;\n cardBorder?: string;\n progressColor?: string;\n textColor?: string;\n };\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n /** Custom render for each quest */\n renderQuest?: (quest: QuestWithProgress) => React.ReactNode;\n}\n\n/**\n * QuestProgress - Display quest progress with step checklist\n *\n * Shows quest name, description, progress bar, and step completion status.\n *\n * @example\n * ```tsx\n * <QuestProgress hideCompleted onComplete={(quest) => console.log('Completed:', quest.name)} />\n * ```\n */\nexport function QuestProgress({\n questId,\n hideCompleted = false,\n className,\n style,\n onComplete,\n theme,\n renderLoading,\n renderError,\n renderQuest,\n}: QuestProgressProps) {\n const { quests, loading, error, refresh } = useQuests({ autoRefresh: true });\n const previousQuests = useRef<Map<string, QuestWithProgress>>(new Map());\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n // Track completions\n useEffect(() => {\n if (onComplete) {\n quests.forEach((quest) => {\n const prev = previousQuests.current.get(quest.id);\n if (prev && prev.status !== 'completed' && quest.status === 'completed') {\n onComplete(quest);\n }\n });\n }\n // Update previous state\n const newMap = new Map<string, QuestWithProgress>();\n quests.forEach((q) => newMap.set(q.id, q));\n previousQuests.current = newMap;\n }, [quests, onComplete]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n let filteredQuests = quests;\n if (questId) {\n filteredQuests = quests.filter((q) => q.id === questId);\n }\n if (hideCompleted) {\n filteredQuests = filteredQuests.filter((q) => q.status !== 'completed');\n }\n\n if (filteredQuests.length === 0) {\n return <div style={{ textAlign: 'center', padding: '16px', color: '#6c757d' }}>No quests available</div>;\n }\n\n const cardStyle = {\n ...gamificationStyles.questContainer,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n ...(theme?.cardBorder && { border: `1px solid ${theme.cardBorder}` }),\n };\n\n return (\n <div className={className} style={style}>\n {filteredQuests.map((quest) => {\n if (renderQuest) {\n return <div key={quest.id}>{renderQuest(quest)}</div>;\n }\n\n const statusColors = getStatusColors(quest.status);\n\n return (\n <div key={quest.id} style={cardStyle}>\n <div style={gamificationStyles.questHeader}>\n <div>\n <h3 style={{ ...gamificationStyles.questTitle, ...(theme?.textColor && { color: theme.textColor }) }}>\n {quest.name}\n </h3>\n {quest.description && (\n <p style={gamificationStyles.questDescription}>{quest.description}</p>\n )}\n </div>\n <span\n style={{\n ...gamificationStyles.questBadge,\n backgroundColor: statusColors.bg,\n color: statusColors.color,\n }}\n >\n {quest.status.replace('_', ' ')}\n </span>\n </div>\n\n <div style={gamificationStyles.questProgressBar}>\n <div\n style={{\n ...gamificationStyles.questProgressFill,\n width: `${quest.percentComplete}%`,\n ...(theme?.progressColor && { backgroundColor: theme.progressColor }),\n }}\n />\n </div>\n\n <ul style={gamificationStyles.questStepList}>\n {quest.steps.map((step) => (\n <li key={step.id} style={gamificationStyles.questStep}>\n <span\n style={{\n ...gamificationStyles.questStepIcon,\n backgroundColor: step.completed ? '#d4edda' : '#e9ecef',\n color: step.completed ? '#155724' : '#6c757d',\n }}\n >\n {step.completed ? '✓' : step.order}\n </span>\n <span\n style={{\n ...gamificationStyles.questStepText,\n textDecoration: step.completed ? 'line-through' : 'none',\n color: step.completed ? '#6c757d' : '#212529',\n }}\n >\n {step.name}\n </span>\n <span style={gamificationStyles.questStepCount}>\n {step.currentCount}/{step.requiredCount}\n </span>\n </li>\n ))}\n </ul>\n\n {quest.xpReward > 0 && (\n <div style={gamificationStyles.questReward}>\n <span style={{ marginRight: '6px' }}>⭐</span>\n {quest.xpReward} XP reward\n {quest.badgeReward && ` + Badge`}\n </div>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================\n// Issue #32: Streak Components\n// ============================================\n\n/**\n * Props for StreakFlame component\n */\nexport interface StreakFlameProps {\n /** Specific streak rule ID to display */\n ruleId?: string;\n /** Size variant */\n size?: 'sm' | 'md' | 'lg';\n /** Show freeze button */\n showFreezeButton?: boolean;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Callback when freeze is used */\n onFreeze?: (ruleId: string, remainingFreezes: number) => void;\n /** Theme customization */\n theme?: {\n flameColor?: string;\n countColor?: string;\n cardBackground?: string;\n };\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n}\n\n/**\n * StreakFlame - Display streak counter with flame icon\n *\n * Shows current streak count with status indicator and optional freeze button.\n *\n * @example\n * ```tsx\n * <StreakFlame showFreezeButton onFreeze={(id, remaining) => console.log('Freeze used')} />\n * ```\n */\nexport function StreakFlame({\n ruleId,\n size = 'md',\n showFreezeButton = true,\n className,\n style,\n onFreeze,\n theme,\n renderLoading,\n renderError,\n}: StreakFlameProps) {\n const { streaks, stats, loading, error, freeze, refresh } = useStreaks({ autoRefresh: true });\n const [freezing, setFreezing] = useState(false);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n let displayStreaks = streaks;\n if (ruleId) {\n displayStreaks = streaks.filter((s) => s.id === ruleId);\n }\n\n if (displayStreaks.length === 0) {\n return <div style={{ textAlign: 'center', padding: '16px', color: '#6c757d' }}>No streaks available</div>;\n }\n\n const sizeStyles = {\n sm: { flame: '24px', count: '20px', container: '12px' },\n md: { flame: '32px', count: '28px', container: '16px' },\n lg: { flame: '48px', count: '40px', container: '20px' },\n };\n\n const handleFreeze = async (streakId: string) => {\n setFreezing(true);\n try {\n const result = await freeze(streakId);\n if (result && onFreeze) {\n onFreeze(streakId, result.remainingFreezes);\n }\n } finally {\n setFreezing(false);\n }\n };\n\n return (\n <div className={className} style={style}>\n {displayStreaks.map((streak) => {\n const statusColors = getStatusColors(streak.status);\n const canFreeze = streak.freezeInventory > 0 && !streak.freezeUsedToday;\n\n return (\n <div\n key={streak.id}\n style={{\n ...gamificationStyles.streakContainer,\n padding: sizeStyles[size].container,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n }}\n >\n <span\n style={{\n ...gamificationStyles.streakFlame,\n fontSize: sizeStyles[size].flame,\n ...(theme?.flameColor && { color: theme.flameColor }),\n }}\n >\n 🔥\n </span>\n <span\n style={{\n ...gamificationStyles.streakCount,\n fontSize: sizeStyles[size].count,\n ...(theme?.countColor && { color: theme.countColor }),\n }}\n >\n {streak.currentCount}\n </span>\n <div style={gamificationStyles.streakInfo}>\n <div style={{ display: 'flex', alignItems: 'center' }}>\n <span style={gamificationStyles.streakName}>{streak.name}</span>\n <span\n style={{\n ...gamificationStyles.streakStatus,\n backgroundColor: statusColors.bg,\n color: statusColors.color,\n }}\n >\n {streak.status}\n </span>\n </div>\n <span style={gamificationStyles.streakLabel}>\n Best: {streak.maxStreak} days\n </span>\n </div>\n {showFreezeButton && (\n <button\n type=\"button\"\n onClick={() => void handleFreeze(streak.id)}\n disabled={!canFreeze || freezing}\n style={canFreeze ? gamificationStyles.freezeButton : gamificationStyles.freezeButtonDisabled}\n >\n <span>❄️</span>\n <span>{streak.freezeInventory}</span>\n </button>\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\n// ============================================\n// Issue #33: Badge Components\n// ============================================\n\n/**\n * Props for BadgeGrid component\n */\nexport interface BadgeGridProps {\n /** Show locked (unearned) badges */\n showLocked?: boolean;\n /** Filter by category */\n category?: string;\n /** Number of grid columns */\n columns?: number;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Show stats header */\n showStats?: boolean;\n /** Callback when a badge is clicked */\n onBadgeClick?: (badge: BadgeWithStatus) => void;\n /** Theme customization */\n theme?: {\n cardBackground?: string;\n cardBorder?: string;\n };\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n /** Custom render for each badge */\n renderBadge?: (badge: BadgeWithStatus) => React.ReactNode;\n}\n\n/**\n * BadgeGrid - Display badge collection in a grid\n *\n * Shows badges with unlock status, rarity indicators, and optional filtering.\n *\n * @example\n * ```tsx\n * <BadgeGrid showLocked showStats onBadgeClick={(badge) => showBadgeModal(badge)} />\n * ```\n */\nexport function BadgeGrid({\n showLocked = true,\n category,\n columns = 4,\n className,\n style,\n showStats = true,\n onBadgeClick,\n theme,\n renderLoading,\n renderError,\n renderBadge,\n}: BadgeGridProps) {\n const { badges, stats, loading, error, refresh } = useBadges({ autoRefresh: true, category });\n\n useEffect(() => {\n void refresh(category);\n }, [refresh, category]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n let displayBadges = badges;\n if (!showLocked) {\n displayBadges = badges.filter((b) => b.isUnlocked);\n }\n\n const gridStyle = {\n ...gamificationStyles.badgeGrid,\n gridTemplateColumns: `repeat(${columns}, 1fr)`,\n };\n\n return (\n <div className={className} style={style}>\n {showStats && stats && (\n <div style={gamificationStyles.badgeStats}>\n <div style={gamificationStyles.badgeStat}>\n <div style={gamificationStyles.badgeStatValue}>{stats.unlocked}</div>\n <div style={gamificationStyles.badgeStatLabel}>Unlocked</div>\n </div>\n <div style={gamificationStyles.badgeStat}>\n <div style={gamificationStyles.badgeStatValue}>{stats.total}</div>\n <div style={gamificationStyles.badgeStatLabel}>Total</div>\n </div>\n <div style={gamificationStyles.badgeStat}>\n <div style={gamificationStyles.badgeStatValue}>\n {stats.total > 0 ? Math.round((stats.unlocked / stats.total) * 100) : 0}%\n </div>\n <div style={gamificationStyles.badgeStatLabel}>Progress</div>\n </div>\n </div>\n )}\n\n <div style={gridStyle}>\n {displayBadges.map((badge) => {\n if (renderBadge) {\n return <div key={badge.id}>{renderBadge(badge)}</div>;\n }\n\n const rarityColors = getRarityColors(badge.rarity);\n const cardStyle = badge.isUnlocked\n ? {\n ...gamificationStyles.badgeCard,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n ...(theme?.cardBorder && { border: `1px solid ${theme.cardBorder}` }),\n }\n : gamificationStyles.badgeCardLocked;\n\n return (\n <div\n key={badge.id}\n style={cardStyle}\n onClick={() => onBadgeClick?.(badge)}\n onKeyDown={(e) => e.key === 'Enter' && onBadgeClick?.(badge)}\n role=\"button\"\n tabIndex={0}\n >\n {badge.iconUrl ? (\n <img src={badge.iconUrl} alt={badge.name} style={gamificationStyles.badgeIcon} />\n ) : (\n <div style={gamificationStyles.badgeIcon}>\n {badge.isUnlocked ? '🏆' : '🔒'}\n </div>\n )}\n <span style={gamificationStyles.badgeName}>{badge.name}</span>\n <span\n style={{\n ...gamificationStyles.badgeRarity,\n backgroundColor: rarityColors.bg,\n color: rarityColors.color,\n }}\n >\n {badge.rarity}\n </span>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ============================================\n// Issue #15: Level/Tier Components\n// ============================================\n\n/**\n * Props for LevelProgress component\n */\nexport interface LevelProgressProps {\n /** Show progress to next tier */\n showNextTier?: boolean;\n /** Show tier benefits */\n showBenefits?: boolean;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Theme customization */\n theme?: {\n cardBackground?: string;\n progressGradient?: string;\n textColor?: string;\n };\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n}\n\n/**\n * LevelProgress - Display tier/level progress\n *\n * Shows current tier, XP/points, and progress to next tier.\n *\n * @example\n * ```tsx\n * <LevelProgress showNextTier showBenefits />\n * ```\n */\nexport function LevelProgress({\n showNextTier = true,\n showBenefits = false,\n className,\n style,\n theme,\n renderLoading,\n renderError,\n}: LevelProgressProps) {\n const { profile, loading, error, refreshProfile } = useLoyalty({ autoRefresh: true });\n\n useEffect(() => {\n void refreshProfile();\n }, [refreshProfile]);\n\n if (loading) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n if (!profile) {\n return null;\n }\n\n const progressPercent = profile.nextTier\n ? Math.min(100, ((profile.points) / (profile.nextTier.minPoints)) * 100)\n : 100;\n\n const containerStyle = {\n ...gamificationStyles.levelContainer,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n };\n\n const progressFillStyle = {\n ...gamificationStyles.levelProgressFill,\n width: `${progressPercent}%`,\n ...(theme?.progressGradient && { background: theme.progressGradient }),\n };\n\n return (\n <div className={className} style={{ ...containerStyle, ...style }}>\n <div style={gamificationStyles.levelHeader}>\n <div\n style={{\n ...gamificationStyles.levelIcon,\n ...(profile.tier?.color && { backgroundColor: profile.tier.color }),\n }}\n >\n {profile.tier?.iconUrl ? (\n <img\n src={profile.tier.iconUrl}\n alt={profile.tier.name}\n style={{ width: '100%', height: '100%', borderRadius: '50%' }}\n />\n ) : (\n '⭐'\n )}\n </div>\n <div style={gamificationStyles.levelInfo}>\n <div\n style={{\n ...gamificationStyles.levelTierName,\n ...(theme?.textColor && { color: theme.textColor }),\n }}\n >\n {profile.tier?.name ?? 'No Tier'}\n </div>\n <div style={gamificationStyles.levelPoints}>\n {profile.points.toLocaleString()} points\n </div>\n </div>\n </div>\n\n {showNextTier && profile.nextTier && (\n <div style={gamificationStyles.levelProgressContainer}>\n <div style={gamificationStyles.levelProgressHeader}>\n <span style={{ color: '#6c757d' }}>Progress to {profile.nextTier.name}</span>\n <span style={{ fontWeight: '500' }}>\n {profile.nextTier.pointsNeeded.toLocaleString()} points needed\n </span>\n </div>\n <div style={gamificationStyles.levelProgressBar}>\n <div style={progressFillStyle} />\n </div>\n </div>\n )}\n\n {showBenefits && profile.tier?.benefits && Object.keys(profile.tier.benefits).length > 0 && (\n <div style={gamificationStyles.levelBenefits}>\n <div style={gamificationStyles.levelBenefitsTitle}>Your Benefits</div>\n <ul style={gamificationStyles.levelBenefitsList}>\n {Object.entries(profile.tier.benefits).map(([key, value]) => (\n <li key={key} style={gamificationStyles.levelBenefitItem}>\n <span style={{ marginRight: '8px', color: '#28a745' }}>✓</span>\n {String(value)}\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n}\n\n// ============================================\n// Issue #34: Reward Components\n// ============================================\n\n/**\n * Props for RewardStore component\n */\nexport interface RewardStoreProps {\n /** Show unavailable items */\n showUnavailable?: boolean;\n /** Custom CSS class name */\n className?: string;\n /** Custom styles override */\n style?: React.CSSProperties;\n /** Show points header */\n showPointsHeader?: boolean;\n /** Callback when item is redeemed */\n onRedeem?: (item: RewardItem, result: RedemptionResult) => void;\n /** Theme customization */\n theme?: {\n cardBackground?: string;\n buttonColor?: string;\n };\n /** Custom render for loading state */\n renderLoading?: () => React.ReactNode;\n /** Custom render for error state */\n renderError?: (error: string) => React.ReactNode;\n /** Custom render for each item */\n renderItem?: (item: RewardItem, onRedeem: () => void) => React.ReactNode;\n}\n\n/**\n * RewardStore - Display reward catalog with redeem functionality\n *\n * Shows available rewards with point costs and redeem buttons.\n *\n * @example\n * ```tsx\n * <RewardStore\n * showPointsHeader\n * onRedeem={(item, result) => {\n * if (result.success) toast.success(`Redeemed ${item.name}!`);\n * }}\n * />\n * ```\n */\nexport function RewardStore({\n showUnavailable = true,\n className,\n style,\n showPointsHeader = true,\n onRedeem,\n theme,\n renderLoading,\n renderError,\n renderItem,\n}: RewardStoreProps) {\n const { items, userPoints, loading, error, redeem, refresh } = useRewards({ autoRefresh: true });\n const [redeemingId, setRedeemingId] = useState<string | null>(null);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n if (loading && items.length === 0) {\n return renderLoading ? renderLoading() : <div style={{ textAlign: 'center', padding: '16px' }}>Loading...</div>;\n }\n\n if (error) {\n return renderError ? renderError(error) : <div style={{ color: 'red', padding: '16px' }}>{error}</div>;\n }\n\n let displayItems = items;\n if (!showUnavailable) {\n displayItems = items.filter((i) => i.isAvailable);\n }\n\n const handleRedeem = async (item: RewardItem) => {\n setRedeemingId(item.id);\n try {\n const result = await redeem(item.id);\n if (result && onRedeem) {\n onRedeem(item, result);\n }\n } finally {\n setRedeemingId(null);\n }\n };\n\n return (\n <div className={className} style={style}>\n {showPointsHeader && (\n <div style={gamificationStyles.rewardPointsHeader}>\n <span style={gamificationStyles.rewardPointsLabel}>Your Points</span>\n <span style={gamificationStyles.rewardPointsValue}>{userPoints.toLocaleString()}</span>\n </div>\n )}\n\n <div style={gamificationStyles.rewardStoreGrid}>\n {displayItems.map((item) => {\n if (renderItem) {\n return <div key={item.id}>{renderItem(item, () => void handleRedeem(item))}</div>;\n }\n\n const cardStyle = item.isAvailable\n ? {\n ...gamificationStyles.rewardCard,\n ...(theme?.cardBackground && { backgroundColor: theme.cardBackground }),\n }\n : gamificationStyles.rewardCardUnavailable;\n\n const buttonStyle = item.isAvailable && item.canAfford\n ? {\n ...gamificationStyles.rewardButton,\n ...(theme?.buttonColor && { backgroundColor: theme.buttonColor }),\n }\n : gamificationStyles.rewardButtonDisabled;\n\n const isRedeeming = redeemingId === item.id;\n\n return (\n <div key={item.id} style={cardStyle}>\n {item.imageUrl ? (\n <img src={item.imageUrl} alt={item.name} style={gamificationStyles.rewardImage} />\n ) : (\n <div style={{ ...gamificationStyles.rewardImage, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '32px' }}>\n 🎁\n </div>\n )}\n <div style={gamificationStyles.rewardContent}>\n <span style={gamificationStyles.rewardName}>{item.name}</span>\n {item.description && (\n <span style={gamificationStyles.rewardDescription}>{item.description}</span>\n )}\n <span style={gamificationStyles.rewardCost}>\n {item.pointsCost.toLocaleString()} points\n </span>\n {item.requiredBadgeName && !item.hasBadge && (\n <span style={{ fontSize: '12px', color: '#dc3545', marginBottom: '8px' }}>\n Requires: {item.requiredBadgeName}\n </span>\n )}\n <button\n type=\"button\"\n onClick={() => void handleRedeem(item)}\n disabled={!item.isAvailable || !item.canAfford || isRedeeming}\n style={buttonStyle}\n >\n {isRedeeming\n ? 'Redeeming...'\n : item.canAfford\n ? 'Redeem'\n : `Need ${(item.pointsCost - userPoints).toLocaleString()} more`}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@gamifyio/react",
3
+ "version": "0.1.0",
4
+ "description": "React SDK for Gamify event tracking",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "check-types": "tsc --noEmit",
28
+ "lint": "eslint src --max-warnings 0",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@gamifyio/core": "*"
33
+ },
34
+ "peerDependencies": {
35
+ "react": ">=16.8.0"
36
+ },
37
+ "devDependencies": {
38
+ "@repo/typescript-config": "*",
39
+ "@types/react": "^19.0.0",
40
+ "react": "^19.0.0",
41
+ "tsup": "^8.0.0",
42
+ "typescript": "5.9.2"
43
+ },
44
+ "sideEffects": false,
45
+ "license": "MIT",
46
+ "keywords": [
47
+ "analytics",
48
+ "tracking",
49
+ "events",
50
+ "sdk",
51
+ "react"
52
+ ]
53
+ }