PageSourceSearch

https://xynergy.ai/_next/static/chunks/9621.b763971c8abce396.js

js xynergy.ai collected 2026-10-05 16:02:49 UTC 10,056 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9621],{19621:(e,a,r)=>{r.r(a),r.d(a,{default:()=>A});var t=r(85047),s=r(31615),i=r(82520),c=r(21410),d=r(6386),l=r(38187),n=r(41178),o=r(73521),m=r(24571),g=r(76458),x=r(15418);let p=x.Ik({id:x.Yj().min(1),rewardId:x.Yj().min(1),userId:x.Yj().min(1),redeemedAt:x.Yj().min(1),used:x.zM(),cost:x.ai().finite()});function u(){if(!g.db)throw Error("Firestore 尚未初始化");return g.db}async function h(e){let a=u();if(!e)throw Error("用戶 ID 未提供");let r=(0,m.rJ)(a,"users",e,"rewards"),t=(0,m.P)(r,(0,m.My)("redeemedAt","desc")),s=await (0,m.GG)(t),i=[];for(let e of s.docs){let a=p.safeParse({id:e.id,...e.data()});a.success&&i.push(a.data)}return i}async function y(e,a){let r=u();if(!e)throw Error("用戶 ID 未提供");let t=p.parse(a);await (0,m.setDoc)((0,m.doc)(r,"users",e,"rewards",t.id),t)}var b=r(19548);let j=[{id:"feature_theme",name:"客製化主題",description:"解鎖更多個人化主題選項",cost:200,category:"feature",icon:"\uD83C\uDFA8",available:!0},{id:"physical_gift_100",name:"禮品卡 $100",description:"可兌換等值商品或服務",cost:1e3,category:"physical",icon:"\uD83C\uDF81",available:!0},{id:"physical_consult",name:"免費顧問諮詢乙次",description:"專業理財顧問財務諮詢乙次",cost:1500,category:"physical",icon:"\uD83D\uDCBC",available:!0}],v=[{id:"stage_foundation",name:"基礎盤點",description:"完成「基礎盤點」階段:帳戶、收支、生日",cost:0,category:"badge",icon:"\uD83E\uDDED",available:!0,rarity:"common"},{id:"stage_balance_sheet",name:"資產負債",description:"完成「資產負債」階段:資產與負債盤點",cost:0,category:"badge",icon:"\uD83D\uDCD2",available:!0,rarity:"common"},{id:"stage_protection",name:"保障到位",description:"完成「保障與風險」階段:保險與緊急預備金",cost:0,category:"badge",icon:"\uD83D\uDEE1️",available:!0,rarity:"rare"},{id:"stage_planning",name:"規劃完備",description:"完成「長期規劃」階段:投資、退休試算、財務目標",cost:0,category:"badge",icon:"\uD83C\uDFAF",available:!0,rarity:"rare"},{id:"stage_legacy",name:"傳承有序",description:"完成「傳承」階段:傳承規劃與信託",cost:0,category:"badge",icon:"\uD83D\uDD4A️",available:!0,rarity:"epic"},{id:"data_100",name:"全景視野",description:"資料完整度達 100%",cost:0,category:"badge",icon:"\uD83C\uDFC6",available:!0,rarity:"legendary"},{id:"emergency_fund_3m",name:"安全氣囊",description:"緊急預備金可支撐 3 個月支出",cost:0,category:"badge",icon:"\uD83E\uDDEF",available:!0,rarity:"epic"},{id:"positive_cashflow",name:"收支健康",description:"本月收入大於支出",cost:0,category:"badge",icon:"\uD83D\uDCA7",available:!0,rarity:"rare"},{id:"low_debt",name:"輕裝上陣",description:"負債比低於 50%",cost:0,category:"badge",icon:"\uD83E\uDEB6",available:!0,rarity:"rare"},{id:"streak_7",name:"堅持一週",description:"連續簽到 7 天",cost:0,category:"badge",icon:"\uD83D\uDD25",available:!0,rarity:"common"},{id:"streak_30",name:"月月報到",description:"連續簽到 30 天",cost:0,category:"badge",icon:"⚡",available:!0,rarity:"rare"},{id:"streak_90",name:"一季不斷",description:"連續簽到 90 天",cost:0,category:"badge",icon:"\uD83C\uDF1F",available:!0,rarity:"epic"},{id:"streak_180",name:"半年如一",description:"連續簽到 180 天",cost:0,category:"badge",icon:"\uD83C\uDFC5",available:!0,rarity:"epic"},{id:"streak_365",name:"全年無休",description:"連續簽到 365 天",cost:0,category:"badge",icon:"\uD83D\uDC51",available:!0,rarity:"legendary"},{id:"networth_100k",name:"小有積蓄",description:"淨值達 100,000",cost:0,category:"badge",icon:"\uD83C\uDF31",available:!0,rarity:"common"},{id:"networth_500k",name:"穩健累積",description:"淨值達 500,000",cost:0,category:"badge",icon:"\uD83C\uDF3F",available:!0,rarity:"rare"},{id:"networth_1m",name:"百萬俱樂部",description:"淨值達 1,000,000",cost:0,category:"badge",icon:"\uD83C\uDF33",available:!0,rarity:"epic"},{id:"networth_5m",name:"財富自由前哨",description:"淨值達 5,000,000",cost:0,category:"badge",icon:"\uD83C\uDFD4️",available:!0,rarity:"legendary"}],f={common:"text-gray-600 bg-gray-100 dark:bg-gray-800 dark:text-gray-300",rare:"text-blue-600 bg-blue-100 dar
1k:bg-blue-900 dark:text-blue-300",epic:"text-purple-600 bg-purple-100 dark:bg-purple-900 dark:text-purple-300",legendary:"text-yellow-600 bg-yellow-100 dark:bg-yellow-900 dark:text-yellow-300"},w={common:"普通",rare:"稀有",epic:"史詩",legendary:"傳說"};var N=r(58462),_=r(98896),k=r(34619),E=r(68341),I=r(9807);function A(){let{toast:e}=(0,n.dj)(),{user:a}=(0,o.A)(),{achievements:r,milestones:m,totalXp:g}=(0,N.I)(),[x,p]=(0,s.useState)([]),[u,A]=(0,s.useState)(null);(0,s.useEffect)(()=>{(async()=>{if(a?.uid)try{let e=await h(a.uid);p(e)}catch(r){let e=r instanceof Error?r:Error(String(r));b.Cp(e,{level:"error",extra:{message:"[tasks/rewards] 載入兌換歷史失敗",userId:a.uid},tags:{source:"RewardsTab.loadUserRewards"}})}})()},[a?.uid]);let $=(0,s.useMemo)(()=>{let e=new Set;return r.forEach(a=>{a.achieved&&e.add(a.id)}),m.forEach(a=>{a.reached&&e.add(a.id)}),a=>e.has(a)},[r,m]),R=v.filter(e=>$(e.id)).length,S=async r=>{if(a?.uid&&!u){if(g<r.cost)return void e({title:"積分不足",description:`需要 ${r.cost} 積分,您目前有 ${g} 積分`,variant:"destructive"});A(r.id);try{let t={id:`${r.id}_${Date.now()}`,rewardId:r.id,userId:a.uid,redeemedAt:new Date().toISOString(),used:!1,cost:r.cost};await y(a.uid,t),p(e=>[t,...e]),e({title:"兌換成功!",description:`已成功兌換 ${r.name}`,duration:3e3})}catch(t){let a=t instanceof Error?t:Error(String(t));b.Cp(a,{level:"error",extra:{message:"[tasks/rewards] 兌換失敗",rewardId:r.id},tags:{source:"RewardsTab.handleRedeem"}}),e({title:"兌換失敗",description:"請稍後再試",variant:"destructive"})}finally{A(null)}}},Z=g-x.reduce((e,a)=>e+a.cost,0);return(0,t.jsx)(d.av,{value:"rewards",className:"space-y-4",children:(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)(i.Zp,{children:[(0,t.jsxs)(i.aR,{children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)(i.ZB,{className:"flex items-center gap-2",children:[(0,t.jsx)(_.A,{className:"h-5 w-5"}),"徽章"]}),(0,t.jsxs)("span",{className:"text-sm text-muted-foreground",children:["已獲得 ",R," / ",v.length]})]}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"完成對應的成就或里程碑即自動獲得,無需兌換"})]}),(0,t.jsx)(i.Wu,{children:(0,t.jsx)("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4",children:v.map(e=>{let a=$(e.id);return(0,t.jsxs)("div",{className:`flex flex-col items-center gap-2 rounded-lg border p-4 text-center transition-colors ${a?"bg-card":"opacity-45 grayscale"}`,children:[(0,t.jsx)("div",{className:"text-4xl",children:e.icon}),(0,t.jsx)("p",{className:"font-medium text-sm",children:e.name}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:e.description}),e.rarity&&(0,t.jsx)(l.E,{variant:"secondary",className:`text-xs ${f[e.rarity]}`,children:w[e.rarity]})]},e.id)})})})]}),(0,t.jsxs)(i.Zp,{children:[(0,t.jsxs)(i.aR,{children:[(0,t.jsxs)(i.ZB,{className:"flex items-center gap-2",children:[(0,t.jsx)(k.A,{className:"h-5 w-5"}),"積分兌換"]}),(0,t.jsxs)("p",{className:"text-sm text-muted-foreground",children:["可用積分:",Z,"(兌換功能即將開放)"]})]}),(0,t.jsx)(i.Wu,{children:(0,t.jsx)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:j.map(e=>{let a,r=(a=e.id,x.some(e=>e.rewardId===a)),s=Z>=e.cost&&!r;return(0,t.jsxs)(i.Zp,{className:`transition-all duration-200 hover:shadow-lg ${r?"opacity-75":""}`,children:[(0,t.jsxs)(i.aR,{className:"pb-3",children:[(0,t.jsx)("div",{className:"text-3xl",children:e.icon}),(0,t.jsx)(i.ZB,{className:"text-lg",children:e.name}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:e.description})]}),(0,t.jsx)(i.Wu,{className:"pt-0",children:(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)(k.A,{className:"h-4 w-4 text-yellow-500"}),(0,t.jsx)("span",{className:"font-bold text-lg",children:e.cost}),(0,t.jsx)("span",{className:"text-sm text-muted-foreground",children:"積分"})]}),(0,t.jsx)(c.$,{size:"sm",onClick:()=>S(e),disabled:!0,className:r?"bg-green-500 hover:bg-green-600":"",children:u===e.id?"兌換中...":r?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(E.A,{className:"h-4 w-4 mr-1"}),"已兌換"]}):s?"兌換":"積分不足"})]})})]},e.id)})})})]}),x.length>0&&(0,t.jsxs)(i.Zp,{children:[(0,t.jsx)(i.aR,{children:(0,t.jsxs)(i.ZB,{className:"flex items-center gap-2",children:[(0,t.jsx)(I.A,{className:"h-5 w-5"}),"兌換歷史"]})}),(0,t.jsx)(i.Wu,{children:(0,t.jsx)("div",{className:"space-y-3",children:x.map(e=>{let a=j.find(a=>a.id===e.rewardId);return(0,t.jsxs)("div",{className:"flex items-center justify-between p-3 rounded-lg border bg-card",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"text-2xl",children:a?.icon||"\uD83C\uDF81"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"font-medium",children:a?.name||"未知獎勵"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:new Date(e.redeemedAt).toLocaleDateString("zh-TW")})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsxs)(l.E,{variant:"outline",children:[e.cost," 積分"]}),(0,t.jsx)(l.E,{variant:e.used?"default":"secondary",className:e.used?"bg-green-500":"",children:e.used?"已使用":"未使用"})]})]},e.id)})})})]})]})})}},98896:(e,a,r)=>{r.d(a,{A:()=>t});let t=(0,r(46775).A)("award",[["path",{d:"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526",key:"1yiouv"}],["circle",{cx:"12",cy:"8",r:"6",key:"1vp47v"}]])}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.