PageSourceSearch

https://xynergy.ai/_next/static/chunks/4387-c9181c98a745c319.js

js xynergy.ai collected 2026-10-05 16:01:29 UTC 52,936 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4387],{6524:(e,t,a)=>{a.d(t,{$m:()=>d,As:()=>c,nD:()=>o,ub:()=>m});var i=a(85047),s=a(31615),r=a(40212),n=a(26345),l=a(34961);let o=r.bL,c=s.forwardRef(({className:e,...t},a)=>(0,i.jsx)(r.q7,{ref:a,className:(0,l.cn)("border-b",e),...t}));c.displayName="AccordionItem";let d=s.forwardRef(({className:e,children:t,...a},s)=>(0,i.jsx)(r.Y9,{className:"flex",children:(0,i.jsxs)(r.l9,{ref:s,className:(0,l.cn)("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",e),...a,children:[t,(0,i.jsx)(n.A,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));d.displayName=r.l9.displayName;let m=s.forwardRef(({className:e,children:t,...a},s)=>(0,i.jsx)(r.UC,{ref:s,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...a,children:(0,i.jsx)("div",{className:(0,l.cn)("pb-4 pt-0",e),children:t})}));m.displayName=r.UC.displayName},15659:(e,t,a)=>{a.r(t),a.d(t,{AdvisorMatchingDialog:()=>w});var i=a(85047),s=a(31615),r=a(18534),n=a(21410),l=a(96968),o=a(866),c=a(21582),d=a(82520),m=a(60373),u=a(38187),h=a(41178),x=a(15139),f=a(18569),p=a(34619),g=a(57321),v=a(93674),y=a(46711);function b(e,t,a){let i=t.budgetMax?Number(t.budgetMax):void 0,s=t.minRating&&"0"!==t.minRating?Number(t.minRating):void 0;return e.filter(e=>(!t.specialty||!!(e.specialties||[]).includes(t.specialty))&&(!t.area||!!(e.serviceAreas||[]).includes(t.area))&&(void 0===i||!((e.fee??0)>i))&&(void 0===s||!((e.rating??0)<s))).slice().sort((e,t)=>(t.rating??0)-(e.rating??0)||(t.reviews??0)-(e.reviews??0)).slice(0,a)}let j={specialty:"",area:"",budgetMax:"",minRating:"0",consultationMethod:""};function w({open:e,onOpenChange:t,advisors:a,onSelectAdvisor:N,bookingContext:C,onTrackOpen:k,onTrackSelect:S,autoRecommend:D=!1,maxResults:A=5}){let{toast:I}=(0,h.dj)(),[L,_]=(0,s.useState)(j),[E,M]=(0,s.useState)([]),[O,$]=(0,s.useState)(!D),F=(0,s.useMemo)(()=>Array.from(new Set(a.flatMap(e=>e.specialties))),[a]),B=(0,s.useMemo)(()=>Array.from(new Set(a.flatMap(e=>e.serviceAreas))),[a]);(0,s.useEffect)(()=>{e&&k&&k()},[e,k]),(0,s.useEffect)(()=>{if(!e){_(j),M([]),$(!D);return}D&&(M(b(a,j,A)),$(!1))},[e,D,a,A]);let T=()=>{_(j),M([]),$(!0)};return(0,i.jsx)(r.lG,{open:e,onOpenChange:t,children:(0,i.jsxs)(r.Cf,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[(0,i.jsxs)(r.c7,{children:[(0,i.jsxs)(r.L3,{className:"flex items-center gap-2",children:[(0,i.jsx)(x.A,{className:"h-5 w-5 text-blue-500"}),D&&!O?"推薦顧問":"篩選顧問"]}),(0,i.jsx)(r.rr,{children:D&&!O?"依評分與評價數為您列出最符合的前幾位顧問":"填寫您的需求條件,我們會依條件為您列出符合的顧問"})]}),(0,i.jsxs)("div",{className:"space-y-6 py-4",children:[O&&(0,i.jsxs)("div",{className:"grid gap-4",children:[(0,i.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(l.J,{htmlFor:"specialty",children:"專長領域"}),(0,i.jsxs)(c.l6,{value:L.specialty||void 0,onValueChange:e=>_(t=>({...t,specialty:e})),children:[(0,i.jsx)(c.bq,{id:"specialty",children:(0,i.jsx)(c.yv,{placeholder:"選擇專長領域(可選)"})}),(0,i.jsx)(c.gC,{children:F.map(e=>(0,i.jsx)(c.eb,{value:e,children:e},e))})]})]}),(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(l.J,{htmlFor:"area",children:"服務地區"}),(0,i.jsxs)(c.l6,{value:L.area||void 0,onValueChange:e=>_(t=>({...t,area:e})),children:[(0,i.jsx)(c.bq,{id:"area",children:(0,i.jsx)(c.yv,{placeholder:"選擇服務地區(可選)"})}),(0,i.jsx)(c.gC,{children:B.map(e=>(0,i.jsx)(c.eb,{value:e,children:e},e))})]})]}),(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(l.J,{htmlFor:"budgetMax",children:"最高預算"}),(0,i.jsx)(o.p,{id:"budgetMax",type:"number",placeholder:"例如:5000",value:L.budgetMax,onChange:e=>_(t=>({...t,budgetMax:e.target.value}))})]}),(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(l.J,{htmlFor:"minRating",children:"最低評分"}),(0,i.jsxs)(c.l6,{value:L.minRating,onValueChange:e=>_(t=>({...t,minRating:e})),children:[(0,i.jsx)(c.bq,{id:"minRating",children:(0,i.jsx)(c.yv,{})}),(0,i.jsxs)(c.gC,{children:[(0,i.jsx)(c.eb,{value:"0",children:"所有評分"}),(0,i.jsx)(c.eb,{value:"4",children:"4 星以上"}),(0,i.jsx)(c.eb,{value:"4.5",children:"4.5 星以上"})]})]})]}),(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(l.J,{htmlFor:"consultationMethod",children:"諮詢方式"}),(0,i.jsxs)(c.l6,{value:L.consultationMethod||void 0,onValueChange:e=>_(t=>({...t,consultationMethod:e})),children:[(0,i.jsx)(c.bq,{id:"consultationMethod",children:(0,i.jsx)(c.yv,{placeholder:"選擇諮詢方式(可選)"})}),(0,i.jsx)(c.gC,{children:["面對面諮詢","線上諮詢","電話諮詢"].map(e=>(0,i.jsx)(c.eb,{value:e,children:e},e))})]})]})]}),(0,i.jsxs)("div",{className:"flex gap-2 justify-end",children:[(0,i.jsx)(n.$,{variant:"outline",onClick:T,children:"重置"}),(0,i.jsxs)(n.$,{onClick:()=>
1{if(0===a.length)return void I({variant:"destructive",title:"錯誤",description:"目前沒有可用的顧問"});let e=b(a,L,A);if(0===e.length){I({title:"沒有找到符合條件的顧問",description:"請嘗試調整搜尋條件"}),M([]);return}M(e),$(!1),I({title:"篩選完成",description:`已為您找到 ${e.length} 位符合條件的顧問`})},children:[(0,i.jsx)(x.A,{className:"mr-2 h-4 w-4"}),"套用篩選"]})]})]}),!O&&(0,i.jsxs)("div",{className:"space-y-4",children:[(0,i.jsxs)("div",{className:"flex items-center justify-between",children:[(0,i.jsx)("h3",{className:"text-lg font-semibold",children:E.length>0?`前 ${E.length} 位符合顧問`:"目前沒有符合的顧問"}),!D&&(0,i.jsx)(n.$,{variant:"outline",size:"sm",onClick:T,children:"重新搜尋"})]}),(0,i.jsx)("div",{className:"grid gap-4",children:E.map(e=>(0,i.jsx)(d.Zp,{className:"hover:shadow-md transition-shadow",children:(0,i.jsx)(d.Wu,{className:"p-6",children:(0,i.jsxs)("div",{className:"flex flex-col lg:flex-row gap-6",children:[(0,i.jsxs)("div",{className:"flex items-start gap-4 flex-1 min-w-0",children:[(0,i.jsxs)(m.eu,{className:"h-16 w-16 flex-shrink-0",children:[(0,i.jsx)(m.BK,{src:e.avatar,alt:e.name}),(0,i.jsx)(m.q5,{children:e.name.substring(0,2)})]}),(0,i.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,i.jsxs)("div",{className:"flex flex-wrap items-center gap-2 mb-1",children:[(0,i.jsx)("div",{className:"font-semibold text-lg",children:e.name}),(0,i.jsx)("div",{className:"flex flex-wrap items-center gap-1.5",children:e.serviceAreas.map((e,t)=>(0,i.jsxs)(u.E,{variant:"outline",className:"text-xs",children:[(0,i.jsx)(f.A,{className:"h-3 w-3 mr-1"}),e]},t))}),e.certifications&&e.certifications.length>0&&(0,i.jsx)("div",{className:"flex flex-wrap items-center gap-1.5",children:e.certifications.map(e=>{let t=(0,v.Bu)(e);return t?(0,i.jsx)(u.E,{variant:"outline",className:"text-xs",children:t.abbreviation},e):null})})]}),(0,i.jsxs)("div",{className:"flex flex-wrap gap-1.5 mb-3",children:[e.specialties.slice(0,3).map((e,t)=>(0,i.jsx)(u.E,{variant:"secondary",className:"text-xs",children:e},t)),e.specialties.length>3&&(0,i.jsxs)(u.E,{variant:"secondary",className:"text-xs",children:["+",e.specialties.length-3]})]}),(0,i.jsxs)("div",{className:"flex items-center gap-4 text-sm",children:[(0,i.jsxs)("div",{className:"flex items-center gap-1",children:[(0,i.jsx)(p.A,{className:"h-4 w-4 fill-yellow-400 text-yellow-400"}),(0,i.jsx)("span",{className:"font-medium",children:e.rating}),(0,i.jsxs)("span",{className:"text-muted-foreground",children:["(",e.reviews," 則評價)"]})]}),(0,i.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,i.jsx)(g.A,{className:"h-4 w-4 text-muted-foreground"}),(0,i.jsx)("span",{className:"font-medium",children:e.fee})]})]})]})]}),(0,i.jsx)("div",{className:"flex items-center",children:(0,i.jsx)(n.$,{onClick:()=>{let a;return a=C?.source??"matching",void((0,y.jh)("matching",e.id),S?.(e.id,a),N&&N(e),t(!1))},children:"立即預約"})})]})})},e.id))})]})]})]})})}},29222:(e,t,a)=>{a.d(t,{R:()=>s});var i=a(31615);function s(e=null){let[t,a]=(0,i.useState)({isLoading:!1,error:null,data:e}),r=(0,i.useCallback)(e=>{a(t=>({...t,isLoading:e}))},[]),n=(0,i.useCallback)(e=>{a(t=>({...t,error:e,isLoading:!1}))},[]),l=(0,i.useCallback)(e=>{a(t=>({...t,data:e,error:null,isLoading:!1}))},[]);return{state:t,setLoading:r,setError:n,setData:l,execute:(0,i.useCallback)(async e=>{try{a(e=>({...e,isLoading:!0,error:null}));let t=await e();return a(e=>({...e,data:t,isLoading:!1,error:null})),t}catch(t){let e=t instanceof Error?t.message:"發生未知錯誤";return a(t=>({...t,error:e,isLoading:!1})),null}},[]),reset:(0,i.useCallback)(()=>{a({isLoading:!1,error:null,data:e})},[e])}}},46955:(e,t,a)=>{a.d(t,{L:()=>c});var i=a(31615),s=a(71931),r=a(76458),n=a(41178),l=a(18654),o=a(87777);function c(){let[e,t]=(0,i.useState)(!1),{toast:a}=(0,n.dj)();return{isPaymentLoading:e,startPayment:async e=>{if(!r.functions)return void a({variant:"destructive",title:"無法建立付款",description:"Firebase Functions 尚未初始化,請重新整理後再試。"});try{t(!0);let a=(0,s.httpsCallable)(r.functions,"createBookingPayment"),i=(await a({bookingId:e.id})).data;if(!i?.success)throw Error(i?.error||"建立付款連結失敗");if(i.formHtml){let e=document.createElement("div");e.innerHTML=i.formHtml,document.body.appendChild(e);let t=e.querySelector("form");if(t)return void t.submit()}if(i.paymentUrl){window.location.href=i.paymentUrl;return}throw Error("無有效的付款連結")}catch(t){(0,l.vV)("建立付款連結失敗",t);let e="建立付款連結失敗,請稍後再試。";t instanceof o.g?"functions/not-found"===t.code?e="付款服務尚未部署或無法使用,請通知系統管理員。":"functions/internal"===t.code?e="付款服務暫時無法使用,工程團隊已收到錯
1誤回報。":t.message&&(e=t.message):t instanceof Error&&(e=t.message),a({variant:"destructive",title:"建立付款連結失敗",description:e})}finally{t(!1)}}}}},56785:(e,t,a)=>{a.r(t),a.d(t,{AdvisorBookingDialog:()=>eh});var i=a(85047),s=a(31615),r=a(46377),n=a(18534),l=a(21410),o=a(54306),c=a(41178),d=a(73521),m=a(85084),u=a(4963);async function h(e){if(window.crypto?.subtle){let t=new TextEncoder().encode(e);return Array.from(new Uint8Array(await window.crypto.subtle.digest("SHA-256",t))).map(e=>e.toString(16).padStart(2,"0")).join("")}try{let{createHash:t}=await Promise.all([a.e(7466),a.e(4923)]).then(a.t.bind(a,80895,23));return t("sha256").update(e).digest("hex")}catch{let t=0;for(let a=0;a<e.length;a+=1)t=(t<<5)-t+e.charCodeAt(a)|0;return t.toString(16)}}let x=e=>e.toISOString().replace(/[-:]/g,"").split(".")[0]+"Z";var f=a(2134),p=a(74265),g=a(71931),v=a(76458),y=a(15418),b=a(67316),j=a(31283),w=a(42165),N=a(87777),C=a(18654),k=a(44832),S=a(8058),D=a(54611),A=a(45762),I=a(24571),L=a(29222),_=a(46955),E=a(92788),M=a(26345),O=a(96968),$=a(866),F=a(21582),B=a(10892),T=a(34961);function R({query:e,title:t="Google Map",className:a}){let s=e.trim();if(!s)return null;let r=`https://www.google.com/maps?q=${encodeURIComponent(s)}&output=embed`,n=`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(s)}`;return(0,i.jsxs)("div",{className:(0,T.cn)("space-y-2",a),children:[(0,i.jsx)("div",{className:"flex justify-end",children:(0,i.jsx)(l.$,{asChild:!0,variant:"outline",size:"sm",className:"gap-2",children:(0,i.jsxs)("a",{href:n,target:"_blank",rel:"noopener noreferrer",children:[(0,i.jsx)(j.A,{className:"h-4 w-4"}),"在 Google 地圖開啟"]})})}),(0,i.jsx)("div",{className:"overflow-hidden rounded-lg border bg-muted/20",children:(0,i.jsx)("iframe",{title:t,src:r,className:"h-[220px] w-full",loading:"lazy",referrerPolicy:"no-referrer-when-downgrade"})})]})}var U=a(24385),V=a(80746),G=a(66592),P=a(77405);function W(e){let{children:t,className:a,calendarMonth:r,displayIndex:n,...l}=e,o=s.Children.toArray(t),c=o.slice(0,3),d=o.slice(3);return(0,i.jsxs)("div",{className:(0,T.cn)("space-y-3",a),...l,children:[(0,i.jsx)("div",{className:"flex flex-row flex-nowrap items-center justify-between w-full gap-2 pt-1",children:c}),d]})}function Y({selectedDate:e,onDateChange:t,minDate:a,maxDate:r,availableDates:n,availableSlotsCount:l,isLoading:o=!1,showWeekNumber:c=!1,embeddedInCard:d=!1}){let m=(0,P.a)(),[u,h]=(0,s.useState)(e?(0,f.SD)(e):void 0);(0,s.useEffect)(()=>{e?h((0,f.SD)(e)):h(void 0)},[e]),(0,s.useMemo)(()=>{if(!n||0===n.size)return[];let t=[],i=(0,f.SD)(a),s=r?(0,f.SD)(r):(0,f.SD)((0,f.o0)(30)),l=new Date(i);for(;l<=s;){let a=(0,U.GP)(l,"yyyy-MM-dd");n.has(a)||a===e||t.push(new Date(l)),l.setUTCDate(l.getUTCDate()+1)}return t},[n,a,r,e]);let x=(0,s.useMemo)(()=>{let e={};n&&n.forEach(t=>{e.hasAvailable||(e.hasAvailable=[]),e.hasAvailable.push((0,f.SD)(t))});let t=l?Object.values(l):[],a=t.length>0?Math.max(...t):0;return a>0&&l?Object.entries(l).forEach(([t,i])=>{if(i<=0)return;let s=Math.min(4,Math.max(1,Math.ceil(i/a*4))),r=`heat${s}`;e[r]||(e[r]=[]),e[r].push((0,f.SD)(t))}):n&&n.forEach(t=>{e.heat2||(e.heat2=[]),e.heat2.push((0,f.SD)(t))}),e},[n,l]);return m?(0,i.jsx)($.p,{type:"date",value:e,onChange:e=>{let i=e.target.value;i>=a&&(!r||i<=r)&&t(i)},min:a,max:r,className:"w-full",disabled:o}):(0,i.jsx)("div",{className:d?"":"space-y-4",children:(0,i.jsx)("div",{className:(0,T.cn)(d?"p-1":"border border-border/50 rounded-lg p-3","booking-date-picker-calendar"),children:(0,i.jsx)(G.V,{mode:"single",selected:u,onSelect:e=>{if(!e)return;let i=(0,U.GP)(e,"yyyy-MM-dd");i<a||r&&i>r||(h(e),t(i))},showWeekNumber:c,navLayout:"around",components:{Month:W},startMonth:(0,f.SD)(a),endMonth:r?(0,f.SD)(r):void 0,defaultMonth:u??(0,f.SD)(a),disabled:e=>{let t=(0,U.GP)(e,"yyyy-MM-dd");return t<a||!!r&&t>r||!!n&&n.size>0&&!n.has(t)},modifiers:x,modifiersClassNames:{hasAvailable:"has-available-slot",heat1:"slot-heat-1",heat2:"slot-heat-2",heat3:"slot-heat-3",heat4:"slot-heat-4"},locale:V.G,classNames:{months:"flex flex-col sm:flex-row space-y-4 sm:sp
1ace-x-4 sm:space-y-0",month:"space-y-3",month_caption:"flex flex-row flex-nowrap items-center justify-between w-full pt-1 px-0 gap-2",caption_label:"text-sm font-medium shrink-0 order-2",nav:"contents",button_previous:(0,T.cn)("order-1 h-7 w-7 shrink-0 bg-transparent p-0 opacity-50 hover:opacity-100 transition-opacity rounded-md"),button_next:(0,T.cn)("order-3 h-7 w-7 shrink-0 bg-transparent p-0 opacity-50 hover:opacity-100 transition-opacity rounded-md"),chevron:"h-4 w-4",month_grid:"w-full border-collapse table-fixed",weekdays:"w-full",weekday:"text-muted-foreground rounded-md h-9 font-normal text-[0.8rem] text-center align-middle w-[14.28%]",week:"w-full mt-0.5",day:(0,T.cn)("h-9 w-[14.28%] text-center text-sm p-0 relative align-middle group","[&:has([aria-selected].day-range-end)]:rounded-r-md","[&:has([aria-selected].day-outside)]:bg-accent/50","[&:has([aria-selected])]:bg-accent","first:[&:has([aria-selected])]:rounded-l-md","last:[&:has([aria-selected])]:rounded-r-md","focus-within:relative focus-within:z-20","[.has-available-slot&]:[&:has([aria-selected])]:!bg-transparent"),day_button:(0,T.cn)("h-8 w-8 p-0 font-normal aria-selected:opacity-100 transition-colors rounded-full flex items-center justify-center","[&[aria-selected]]:bg-primary [&[aria-selected]]:text-primary-foreground [&[aria-selected]]:font-semibold","group-[.has-available-slot]:text-foreground","group-[.slot-heat-1]:bg-blue-500/20 group-[.slot-heat-2]:bg-blue-500/40","group-[.slot-heat-3]:bg-blue-500/65 group-[.slot-heat-4]:bg-blue-500/90","group-[.has-available-slot]:hover:bg-blue-400/50 group-[.has-available-slot]:hover:text-foreground","group-[.has-available-slot]:[&[aria-selected]]:!bg-white group-[.has-available-slot]:[&[aria-selected]]:!text-gray-900"),day_range_end:"day-range-end",day_selected:"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",day_today:"bg-accent text-accent-foreground font-semibold",day_outside:"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",day_disabled:"text-muted-foreground opacity-50 cursor-not-allowed hover:bg-transparent",day_range_middle:"aria-selected:bg-accent aria-selected:text-accent-foreground",day_hidden:"invisible",...c&&{week_number:"text-muted-foreground text-[0.8rem] w-8 text-center align-middle"}}})})})}let q=["面對面諮詢","線上諮詢","電話諮詢"],z=["顧問辦公室","指定地點"],J=["退休規劃","投資策略","稅務規劃","保險規劃","風險管理","家庭財務","資產配置","股票投資","ETF策略","傳承規劃","財富傳承","債務管理","現金流規劃","預算編制","職涯財務","投資入門"];function K({formState:e,onFormStateChange:t,availableTimeOptions:a,isSlotLoading:r,minDate:n,maxDate:l,advisorOfficeAddress:o,onDateChange:c,onTimeChange:d,availableDates:m,availableSlotsCount:u}){let h=(0,s.useRef)(null),[x,f]=(0,s.useState)({canScrollUp:!1,canScrollDown:!1}),p=(0,s.useCallback)(()=>{let e=h.current;if(!e)return;let{scrollTop:t,scrollHeight:a,clientHeight:i}=e,s=t>0,r=t+i<a-1;f(e=>e.canScrollUp!==s||e.canScrollDown!==r?{canScrollUp:s,canScrollDown:r}:e)},[]);(0,s.useEffect)(()=>{p();let e=h.current;if(!e)return;let t=new ResizeObserver(p);return t.observe(e),()=>t.disconnect()},[a.length,p]);let g="面對面諮詢"!==e.method?"":"顧問辦公室"===e.locationChoice?(o||"").trim():"指定地點"===e.locationChoice?(e.customLocation||"").trim():"",v="面對面諮詢"===e.method&&e.locationChoice?"顧問辦公室"!==e.locationChoice||(o||"").trim()?"指定地點"!==e.locationChoice||(e.customLocation||"").trim()?"":"請先輸入指定地點以顯示地圖。":"此顧問尚未設定辦公室地址,請改選「指定地點」或稍後再試。":"";return(0,i.jsxs)("div",{className:"space-y-6 py-4",children:[(0,i.jsxs)("div",{className:"space-y-3",children:[(0,i.jsx)("h3",{className:"text-sm font-medium",children:"選取預約時段"}),(0,i.jsx)("div",{className:"border border-border/50 rounded-lg p-4",children:(0,i.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6 md:gap-8",children:[(0,i.jsx)("div",{children:(0,i.jsx)(Y,{selectedDate:e.date,onDateChange:e=>{t({date:e,time:""}),c&&c(e),d&&d("")},minDate:n,maxDate:l,availableDates:m,availableSlotsCount:u,isLoading:r,embeddedInCard:!0})}),(0,i.jsx)("div",{className:"flex flex-col md:border-l md:border-border/50 md:pl-6",children:e.date?r?(0,i.jsx)("p",{className:"text-sm text-muted-foreground py-4 text-center",children:"載入可預約時段中..."}):0===a.length?(0,i.jsx)("p",{className:"text-sm text-muted-foreground py-4 text-center",children:"此日期已無可預約時段"}):(0,i.jsxs)("div",{className:"flex flex-col min-h-0 max-h-[360px]",children:[x.canScrollUp&&(0,i.jsx)("div",{className:"flex shrink-0 justify-center py-1.5",children:(0,i.jsx)(E.A,{className:"h-5 w-5 text-muted-foreground","aria-hidden":!0})}),(0,i.jsx)("div",{ref:h,onScroll:p,className:"flex flex-col gap-2 overflow-y-auto min-h-0 flex-1 pr-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:a.map(a=>(0,i.jsx)("button",{type:"button",onClick:()=>{t({time:a}),d&&d(a)},className:(0,T.cn)("rounded-md border px-3 py-2 text-sm font-medium transition-colors",e.time===a?"bg-primary text-primary-foreground border-primary":"bg-background hover:bg-accent border-border"),children:a},a))}),x.canScrollDown&&(0,i.jsx)("div",{className:"flex shrink-0 justify-center py-1.5",children:(0,i.jsx)(M.A,{className:"h-5 w-5 text-muted-foreground","aria-hidden":!0})})]}):(0,i.jsx)("p",{className:"text-sm text-muted-foreground py-4 text-center",children:"請先選擇日期"})})]})})]}),(0,i.jsxs)("div",{className:"space-y-4",children:[(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(O.J,{htmlFor:"method",className:"text-sm font-medium",children:"諮詢方式"}),(0,i.jsxs)(F.l6,{value:e.method,onValueChange:a=>{t({method:a,locationChoice:"面對面諮詢"===a?e.locationChoice:"",customLocation:"面對面諮詢"===a?e.customLocation:""})},children:[(0,i.jsx)(F.bq,{children:(0,i.jsx)(F.yv,{placeholder:"請選擇諮詢方式"})}),(0,i.jsx)(F.gC,{children:q.map(e=>(0,i.jsx)(F.eb,{value:e,children:e},e))})]})]}),"面對面諮詢"===e.method&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(O.J,{htmlFor:"locationChoice",className:"text-sm font-medium",children:"地點選擇"}),(0,i.jsxs)(F.l6,{value:e.locationChoice,onValueChange:a=>{t({locationChoice:a,customLocation:"指定地點"===a?e.customLocation:""})},children:[(0,i.jsx)(F.bq,{children:(0,i.jsx)(F.yv,{placeholder:"請選擇地點"})}),(0,i.jsx)(F.gC,{children:z.map(e=>(0,i.jsx)(F.eb,{value:e,children:e},e))})]})]}),"指定地點"===e.locationChoice&&(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(O.J,{htmlFor:"customLocation",className:"text-sm font-medium",children:"指定地點"}),(0,i.jsx)($.p,{id:"customLocation",value:e.customLocation,onChange:e=>t({customLocation:e.target.value}),placeholder:"請輸入地點"})]}),e.locationChoice&&(0,i.jsxs)("div",{className:"space-y-2",children:[v&&(0,i.jsx)("div",{className:"rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive",children:v}),!v&&(0,i.jsx)(R,{query:g,title:"面對面諮詢地圖"})]})]})]}),(0,i.jsxs)("div",{className:"space-y-4",children:[(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(O.J,{htmlFor:"topic",className:"text-sm font-medium",children:"諮詢項目"}),(0,i.jsxs)(F.l6,{value:e.topic,onValueChange:e=>t({topic:e}),children:[(0,i.jsx)(F.bq,{children:(0,i.jsx)(F.yv,{placeholder:"請選擇諮詢項目"})}),(0,i.jsx)(F.gC,{children:J.map(e=>(0,i.jsx)(F.eb,{value:e,children:e},e))})]})]}),(0,i.jsxs)("div",{className:"space-y-2",children:[(0,i.jsx)(O.J,{htmlFor:"note",className:"text-sm font-medium",children:"備註"}),(0,i.jsx)(B.T,{id:"note",value:e.note,onChange:e=>t({note:e.target.value}),placeholder:"可選填,說明您的需求或特殊情況",rows:4,maxLength:800})]})]})]})}var H=a(62557),X=a(21016),Z=a(6524),Q=a(75123),ee=a(99307),et=a(25450),ea=a(90612),ei=a(63533);let es=[{key:"personal",title:"個人資料運用告知",icon:Q.A,summary:"說明è’
1é›†é …目、使用目的、保留期間與使用者權利行使管道。",details:["蒐集項目僅限姓名、聯絡方式、預約紀錄與必要識別資料,用於顧問服務、帳號安全稽核與法規遵循。","資料於帳號存在期間及法令或契約要求的保留年限後,會以匿名化或刪除方式進行處理。","您可透過「設定 > 資料管理」或客服,申請查詢、下載、更正或刪除個人資料。"],checkboxLabel:"我已詳讀並同意平台依上述方式蒐集、處理與利用我的個人資料。",required:!0},{key:"financial",title:"財務資料授權",icon:ee.A,summary:"授權顧問臨時存取必要的財務資料,僅供本次諮詢與計算使用。",details:["授權資料僅包含您主動選擇分享的財務資訊(收入、支出、資產負債、投資明細等)。","顧問不得下載、轉交第三方或另作他用,僅能在本平台介面閱讀並做建議紀錄。","您可隨時撤回授權;撤回後 24 小時內系統即停止共用並完成刪除。"],checkboxLabel:"我同意在本次預約期間授權顧問存取我指定的財務資料並提供建議。",required:!0},{key:"financialEdit",title:"財務資料代為修改授權",icon:et.A,summary:"授權顧問在諮詢過程中代為新增、修改或刪除您的財務資料。",details:["顧問僅可在您授權的範圍內代為操作帳戶、資產、負債、投資、目標等財務資料。","所有修改皆會留下完整稽核紀錄(操作者、時間、修改前/後內容),您可隨時在「設定 > 修改紀錄」中查看。","您可隨時撤回此授權;撤回後顧問將無法繼續代為修改您的財務資料。"],checkboxLabel:"我同意授權顧問在本次預約期間代為新增、修改或刪除我的財務資料。",required:!1},{key:"privacy",title:"隱私權條款",icon:ea.A,summary:"了解平台如何保護資料、第三方合作原則及聯繫窗口。",details:["所有資料傳輸均採 TLS 1.2 以上加密,並以多層金鑰與權限控管保護存放於台灣/亞洲區機房。","若需與金流或雲端分析等第三方合作,僅提供完成服務所需的最小資料並要求等同保護。","如需隱私相關協助,可透過 [email protected] 或客服中心與我們聯繫。"],checkboxLabel:"我已閱讀並同意依隱私權政策處理與保護我的資料。",required:!0}];function er({consentState:e,onConsentStateChange:t,onConfirm:a,onBack:r,isSubmitting:n}){let o=e.personal&&e.financial&&e.privacy,c=(0,s.useMemo)(()=>es.map(e=>e.key),[]),[d,m]=(0,s.useState)(()=>new Set),u=d.size>=c.length,h=(0,s.useMemo)(()=>u?[]:es.filter(e=>!d.has(e.key)).map(e=>e.title),[u,d]),x=o&&u&&!n;return(0,i.jsxs)("div",{className:"space-y-6 py-4",children:[(0,i.jsxs)(X.Fc,{className:"border-border/50",children:[(0,i.jsx)(ei.A,{className:"h-4 w-4"}),(0,i.jsx)(X.TN,{className:"text-sm",children:"每項授權可個別展開查看詳細內容。為確保您至少有機會看過所有條款內容,需將每一段內容展開過一次後,才可前往付款;標示「選填」者為可選授權。"})]}),!u&&(0,i.jsx)(X.Fc,{className:"border-border/50",children:(0,i.jsxs)(X.TN,{className:"text-sm",children:["尚未展開:",h.join("、")]})}),(0,i.jsx)(Z.nD,{type:"multiple",className:"space-y-3",onValueChange:e=>{m(t=>{let a=new Set(t);return e.forEach(e=>a.add(String(e))),a})},children:es.map(a=>{let s=a.icon;return(0,i.jsxs)(Z.As,{value:a.key,className:"border-border/50",children:[(0,i.jsx)(Z.$m,{className:"text-left py-3",children:(0,i.jsxs)("div",{className:"flex items-center gap-2",children:[(0,i.jsx)(s,{className:"h-4 w-4 text-primary"}),(0,i.jsx)("span",{className:"text-sm font-medium",children:a.title}),!a.required&&(0,i.jsx)("span",{className:"text-xs text-muted-foreground bg-muted px-1.5 py-0.5 rounded",children:"選填"})]})}),(0,i.jsxs)(Z.ub,{className:"space-y-3 pt-2 text-sm text-muted-foreground",children:[(0,i.jsx)("p",{children:a.summary}),(0,i.jsx)("ul",{className:"list-disc space-y-1.5 pl-5",children:a.details.map((e,t)=>(0,i.jsx)("li",{children:e},`${a.key}-detail-${t}`))}),(0,i.jsxs)("div",{className:"mt-4 flex items-start gap-3 rounded-md border border-border/50 p-3 bg-muted/30",children:[(0,i.jsx)(H.S,{id:`${a.key}-checkbox`,checked:e[a.key],onCheckedChange:e=>t({[a.key]:!!e}),className:"mt-0.5"}),(0,i.jsx)(O.J,{htmlFor:`${a.key}-checkbox`,className:"text-sm leading-relaxed cursor-pointer",children:a.checkboxLabel})]})]})]},a.key)})}),(0,i.jsx)("div",{className:"sticky bottom-0 bg-background border-t pt-4 mt-6 -mx-4 sm:-mx-6 px-4 sm:px-6 pb-0",children:(0,i.jsxs)("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",children:[(0,i.jsx)(l.$,{variant:"outline",onClick:r,className:"w-full sm:w-auto",children:"上一步"}),(0,i.jsx)(l.$,{onClick:a,disabled:!x,className:"w-full sm:w-auto",children:n?"處理中...":"前往付款"})]})})]})}var en=a(10250);let el=[{id:"form",label:"填寫預約",icon:ei.A},{id:"consent",label:"授權同意",icon:Q.A},{id:"summary",label:"確認付款",icon:en.A}];function eo({currentStep:e}){let t=el.findIndex(t=>t.id===e);return(0,i.jsx)("div",{className:"w-full py-4",children:(0,i.jsx)("div",{className:"flex items-center justify-between",children:el.map((e,a)=>{let s=e.icon,r=a<t,n=a===t,l=a>t;return(0,i.jsxs)("div",{className:"flex items-center flex-1",children:[(0,i.jsxs)("div",{className:"flex flex-col items-center flex-1",children:[(0,i.jsx)("div",{className:(0,T.cn)("flex items-center justify-center w-10 h-10 rounded-full border-2 transition-colors",r&&"bg-primary border-primary text-primary-foreground",n&&"bg-primary border-primary text-primary-foreground",l&&"bg-background border-muted-foreground
1/30 text-muted-foreground"),children:r?(0,i.jsx)(en.A,{className:"h-5 w-5"}):(0,i.jsx)(s,{className:"h-5 w-5"})}),(0,i.jsx)("span",{className:(0,T.cn)("mt-2 text-xs font-medium transition-colors",r&&"text-primary",n&&"text-primary font-semibold",l&&"text-muted-foreground"),children:e.label})]}),a<el.length-1&&(0,i.jsx)("div",{className:(0,T.cn)("h-0.5 flex-1 mx-2 transition-colors",r?"bg-primary":"bg-muted-foreground/30")})]},e.id)})})})}var ec=a(33700);let ed=["顧問辦公室","指定地點"],em=y.Ik({date:y.Yj().min(1,"請選擇日期"),time:y.Yj().min(1,"請選擇時間"),method:y.k5(["面對面諮詢","線上諮詢","電話諮詢"]),locationChoice:y.Yj().optional(),customLocation:y.Yj().optional(),topic:y.Yj().min(1,"請選擇諮詢項目"),note:y.Yj().max(800).optional()}),eu=[{key:"personal",title:"個人資料運用告知",summary:"說明蒐集項目、使用目的、保留期間與使用者權利行使管道。",details:["蒐集項目僅限姓名、聯絡方式、預約紀錄與必要識別資料,用於顧問服務、帳號安全稽核與法規遵循。","資料於帳號存在期間及法令或契約要求的保留年限後,會以匿名化或刪除方式進行處理。","您可透過「設定 > 資料管理」或客服,申請查詢、下載、更正或刪除個人資料。"],checkboxLabel:"我已詳讀並同意平台依上述方式蒐集、處理與利用我的個人資料。"},{key:"financial",title:"財務資料授權",summary:"授權顧問臨時存取必要的財務資料,僅供本次諮詢與計算使用。",details:["授權資料僅包含您主動選擇分享的財務資訊(收入、支出、資產負債、投資明細等)。","顧問不得下載、轉交第三方或另作他用,僅能在本平台介面閱讀並做建議紀錄。","您可隨時撤回授權;撤回後 24 小時內系統即停止共用並完成刪除。"],checkboxLabel:"我同意在本次預約期間授權顧問存取我指定的財務資料並提供建議。"},{key:"financialEdit",title:"財務資料代為修改授權",summary:"授權顧問在諮詢過程中代為新增、修改或刪除您的財務資料。",details:["顧問僅可在您授權的範圍內代為操作帳戶、資產、負債、投資、目標等財務資料。","所有修改皆會留下完整稽核紀錄(操作者、時間、修改前/後內容),您可隨時在「設定 > 修改紀錄」中查看。","您可隨時撤回此授權;撤回後顧問將無法繼續代為修改您的財務資料。"],checkboxLabel:"我同意授權顧問在本次預約期間代為新增、修改或刪除我的財務資料。"},{key:"privacy",title:"隱私權條款",summary:"了解平台如何保護資料、第三方合作原則及聯繫窗口。",details:["所有資料傳輸均採 TLS 1.2 以上加密,並以多層金鑰與權限控管保護存放於台灣/亞洲區機房。","若需與金流或雲端分析等第三方合作,僅提供完成服務所需的最小資料並要求等同保護。","如需隱私相關協助,可透過 [email protected] 或客服中心與我們聯繫。"],checkboxLabel:"我已閱讀並同意依隱私權政策處理與保護我的資料。"}];function eh({advisor:e,open:t,onOpenChange:a,presetDate:y,embedded:E=!1,showCloseButton:M=!0,bookingContext:O}){let $=(0,r.useRouter)(),{toast:F}=(0,c.dj)(),{user:B}
1=(0,d.A)(),[T,R]=(0,s.useState)(e),U=T||e,[V,G]=(0,s.useState)("form"),[P,W]=(0,s.useState)({date:"",time:"",method:"",locationChoice:"",customLocation:"",topic:"",note:""}),[Y,q]=(0,s.useState)({personal:!1,financial:!1,financialEdit:!1,privacy:!1}),[z,J]=(0,s.useState)(null),[H,X]=(0,s.useState)(!1),[Z,Q]=(0,s.useState)(!1),[ee,et]=(0,s.useState)({}),[ea,ei]=(0,s.useState)(!1),{minDate:es,maxDate:en}=(0,s.useMemo)(()=>{let e=U?.advanceBookingDays??p.X.ADVANCE_BOOKING_DAYS,t=U?.bookingWindowDays??p.X.BOOKING_WINDOW_DAYS;return{minDate:(0,f.ll)(e),maxDate:(0,f.ll)(t)}},[U?.advanceBookingDays,U?.bookingWindowDays]),{availableTimeOptions:el}=function({advisor:e,selectedDate:t,bookedSlotsByDate:a,isOpen:i=!0}){let r=(0,s.useMemo)(()=>Array.from({length:48},(e,t)=>{let a=Math.floor(t/2);return`${String(a).padStart(2,"0")}:${String(t%2*30).padStart(2,"0")}`}),[]);return{availableTimeOptions:(0,s.useMemo)(()=>{if(!i||!e||!t)return[];let s=a[t]||{},n=new Date,l=(0,f.ri)(),o=60*n.getHours()+n.getMinutes(),[c,d,m]=t.split("-").map(Number),u=new Date(Date.UTC(c,d-1,m,0,0,0,0)).getUTCDay(),h=e.specificDates?.[t]||[],x=e.weeklySchedule||{},p=[];if(x[u]&&Array.isArray(x[u]))p=x[u];else{let e=String(u);if(x[e]&&Array.isArray(x[e]))p=x[e];else for(let e in x){let t=Number(e);if(!isNaN(t)&&t===u&&Array.isArray(x[e])){p=x[e];break}}}let g=h.length>0?h:p;return 0===g.length?[]:r.filter(e=>!(!g.includes(e)||s[e]||t===l&&(e=>
1{let[t,a]=e.split(":").map(Number);return 60*t+a})(e)<=o)&&!0)},[r,a,t,e,i]),allTimeSlots:r}}({advisor:U,selectedDate:P.date,bookedSlotsByDate:ee,isOpen:t}),{availableDates:ex,availableSlotsCount:ef}=(0,s.useMemo)(()=>{let e=new Set,t={};if(!U)return{availableDates:e,availableSlotsCount:t};let a=U.weeklySchedule||{},i=U.specificDates||{},s=U.advanceBookingDays??p.X.ADVANCE_BOOKING_DAYS,r=U.bookingWindowDays??p.X.BOOKING_WINDOW_DAYS,n=(0,f.ll)(s),l=(0,f.ll)(r),o=(0,f.ri)(),c=(0,f.SD)(o);for(let d=0;d<=r-s;d++){let r=new Date(Date.UTC(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()+s+d)),m=r.toISOString().split("T")[0];if(m<n||m>l)continue;let u=r.getUTCDay(),h=[];if((h=i[m]?i[m]:a[u]||a[String(u)]||[]).length>0){let a=ee[m]||{},i=h.filter(e=>!a[e]).length;if(m===o){let e=new Date,t=60*e.getHours()+e.getMinutes();i=h.filter(e=>{if(a[e])return!1;let[i,s]=e.split(":").map(Number);return 60*i+s>t}).length}i>0&&(e.add(m),t[m]=i)}}return{availableDates:e,availableSlotsCount:t}},[U,ee]),{activeBooking:ep,isLoading:eg,loadPendingBooking:ev,setBooking:ey,clearBooking:eb,checkBookingExpired:ej}=function({onBookingLoaded:e,onBookingExpired:t}={}){let{user:a}=(0,d.A)(),{toast:i}=(0,c.dj)(),{state:r,setLoading:n,setError:l,setData:o}=(0,L.R)(null),m=(0,s.useRef)(!1),u=(0,s.useRef)(null),h=(0,s.useCallback)(async t=>{if(!a||!t)return null;try{n(!0),l(null);let s=await A.y.getBookingById(t);if(!s)return i({variant:"destructive",title:"找不到預約資料",description:"預約可能已被取消或不存在。"}),localStorage.removeItem("pendingBookingId"),null;if(s.userId!==a.uid)return i({variant:"destructive",title:"無權限",description:"此預約不屬於您。"}),null;if("cancelled"===s.status)return i({variant:"destructive",title:"預約已取消",description:"此預約已被取消。"}),localStorage.removeItem("pendingBookingId"),null;if("paid"===s.status)return i({title:"預約已完成",description:"此預約已完成付款。"}),localStorage.removeItem("pendingBookingId"),null;if(!v.db)return i({variant:"destructive",title:"系統錯誤",description:"資料庫尚未初始化。"}),null;let r=(0,I.doc)(v.db,v.ADVISORS,s.advisorId),c=await (0,I.getDoc)(r);if(!c.exists())return i({variant:"destructive",title:"找不到顧問資料",description:"顧問可能已被停用。"}),localStorage.removeItem("pendingBookingId"),null;let d=c.data(),m={id:c.id,...d};if(!1===m.isActive)return i({variant:"destructive",title:"顧問已停用",description:"此顧問已停用,無法繼續預約流程。"}),localStorage.removeItem("pendingBookingId"),null;return o(s),e&&e(s,m),s}catch(t){(0,C.vV)("載入待完成預約失敗:",t);let e="無法載入預約資料,請稍後再試。";return t?.message?e=t.message:t?.code==="permission-denied"?e="您沒有權限查看此預約。":t?.code==="not-found"&&(e="找不到預約資料,預約可能已被刪除。"),l(e),i({variant:"destructive",title:"載入失敗",description:e}),localStorage.removeItem("pendingBookingId"),null}finally{n(!1)}},[a,i,n,l,o,e]),x=(0,s.useCallback)(e=>{if(!e.createdAt)return!1;let a=new Date(e.createdAt);return new Date>new Date(a.getTime()+15e3)&&(t&&t(e.id),!0)},[t]),f=(0,s.useCallback)(e=>{o(e),e?localStorage.setItem("pendingBookingId",e.id):localStorage.removeItem("pendingBookingId")},[o]),p=(0,s.useCallback)(()=>{o(null),l(null),localStorage.removeItem("pendingBookingId"),m.current=!1,u.current=null},[o,l]);return{activeBooking:r.data||null,isLoading:r.isLoading,error:r.error,loadPendingBooking:h,setBooking:f,clearBooking:p,checkBookingExpired:x}}({onBookingLoaded:(0,s.useCallback)((e,t)=>{t&&R(t),W({date:e.date,time:e.time,method:e.method,locationChoice:e.location?ed.includes(e.location)?e.location:"指定地點":"",customLocation:e.location&&!ed.includes(e.location)?e.location:"",topic:e.topic||"",note:e.note||""}),"pending"===e.status?(G("consent"),q({personal:!1,financial:!1,financialEdit:!1,privacy:!1})):"authorized"===e.status&&(G("summary"),e.calendarLink&&J(e.calendarLink))},[R,W,G,q,J])}),ew=(0,s.useCallback)(()=>{G("form"),W({date:"",time:"",method:"",locationChoice:"",customLocation:"",topic:"",note:""}),q({personal:!1,financial:!1,financialEdit:!1,privacy:!1}),eb(),J(null),X(!1),Q(!1)},[eb,G,W,q,J,X,Q]),{isPaymentLoading:eN,startPayment:eC}=(0,_.L)();(0,s.useEffect)(()=>
1{if(!U||!t)return;let e=!1;return ei(!0),(0,m.GB)(U.id).then(t=>{if(e)return;let a={};t.forEach(e=>{if(!e.date||!Array.isArray(e.times))return;let t=e.date.includes("T")?e.date.split("T")[0]:e.date;a[t]||(a[t]=new Set),e.times.forEach(e=>{e&&a[t].add(e)})});let i={},s=U.weeklySchedule||{},r=U.specificDates||{};Object.keys(r).forEach(e=>{let t=e.includes("T")?e.split("T")[0]:e,s=r[e]||[],n=a[t]||new Set;i[t]||(i[t]={}),s.forEach(e=>{n.has(e)||(i[t][e]=!0)})});let n=new Date;n.setUTCHours(0,0,0,0);for(let e=0;e<30;e++){let t=new Date(Date.UTC(n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()+e)),l=t.toISOString().split("T")[0];if(r[l])continue;let o=t.getUTCDay(),c=s[o]||s[String(o)]||[];if(0===c.length)continue;let d=a[l]||new Set;i[l]||(i[l]={}),c.forEach(e=>{d.has(e)||(i[l][e]=!0)})}et(i)}).catch(e=>{(0,C.vV)("載入顧問預約時段失敗:",e),F({variant:"destructive",title:"載入預約時段失敗",description:"暫時無法取得顧問現有時段,請稍後再試。"})}).finally(()=>{e||ei(!1)}),()=>{e=!0}},[U,t,F]);let ek=(0,r.useSearchParams)(),eS=(0,s.useRef)(!1),eD=(0,s.useRef)(null);(0,s.useEffect)(()=>{if(!t){let e=ep?.id;e&&("pending"===ep.status||"authorized"===ep.status)?localStorage.setItem("pendingBookingId",e):localStorage.removeItem("pendingBookingId"),ew(),eS.current=!1,eD.current=null;return}let e=ek?.get("bookingId"),a=localStorage.getItem("pendingBookingId"),i=e||a;if((!i||eD.current!==i)&&(!eS.current||!i))if(i&&B&&t){eS.current=!0,eD.current=i;let t=setTimeout(()=>{ev(i).then(t=>{if(t&&e){let e=window.location.pathname+(window.location.search.replace(/[?&]bookingId=[^&]*/,"").replace(/^&/,"?")||"");window.history.replaceState({},"",e)}}).catch(e=>{(0,C.vV)("載入預約失敗:",e),eS.current=!0})},100);return()=>clearTimeout(t)}else y&&!i&&W(e=>({...e,date:y}))},[t,y,ek,B,ev,ep?.id,ep?.status,ew]),(0,s.useEffect)(()=>{e&&R(e)},[e]),(0,s.useEffect)(()=>{ep&&"consent"===V&&ej(ep)&&eb()},[ep,V,ej,eb,G,q,F]);let eA=(0,s.useMemo)(()=>"面對面諮詢"!==P.method?"":"顧問辦公室"===P.locationChoice?(U?.officeAddress||"").trim():"指定地點"===P.locationChoice?(P.customLocation||"").trim():"",[U?.officeAddress,P.method,P.locationChoice,P.customLocation]),eI=async()=>{if(U&&(B||(F({variant:"destructive",title:"請先登入",description:"預約顧問服務需要登入帳號,將為您導向登入頁面。"}),$.push("/auth"),a(!1),0)))try{X(!0);let e=U.advanceBookingDays??p.X.ADVANCE_BOOKING_DAYS,t=U.bookingWindowDays??p.X.BOOKING_WINDOW_DAYS,a=(0,f.ll)(e),i=(0,f.ll)(t);if(P.date<a)return void F({variant:"destructive",title:"日期不符合提前預約要求",description:`此顧問要求提前 ${e} 天預約,最早可預約日期為 ${a}。`});if(P.date>i)return void F({variant:"destructive",title:"日期超出開放範圍",description:`此顧問只開放未來 ${t} 天內的預約,最晚可預約日期為 ${i}。`});let s=em.safeParse({...P,locationChoice:"面對面諮詢"===P.method?P.locationChoice:"",customLocation:P.customLocation});if(!s.success){let e=s.error.issues[0]?.message??"請檢查表單欄位";F({variant:"destructive",title:"表單驗證失敗",description:e});return}if("面對面諮詢"===P.method){if(!P.locationChoice)return void F({variant:"destructive",title:"請選擇諮詢地點",description:"面對面諮詢需要選擇諮詢地點。"});if("顧問辦公室"===P.locationChoice&&!eA)return void F({variant:"destructive",title:"顧問辦公室地址未設定",description:"此顧問尚未設定辦公室地址,請改選「指定地點」或稍後再試。"});if("指定地點"===P.locationChoice&&!P.customLocation.trim())return void F({variant:"destructive",title:"請輸入指定地點",description:"請提供詳細的諮詢地點以便顧問安排。"})}if(P.date&&P.time&&!el.includes(P.time))return void F({variant:"destructive",title:"時段已被預約",description:"此時段已無法預約,請重新選擇其他時段。"});if(ep&&("pending"===ep.status||"authorized"===ep.status)){let e=ep.date!==P.date,t=ep.time!==P.time;if(e||t)try{await m.yZ.cancelBooking(ep.id),F({title:"已取消舊預約",description:"已取消原預約,將建立新的預約。"}),eb()}catch(t){(0,C.vV)("取消舊預約失敗:",t);let e="無法取消舊預約,請稍後再試。";if(t instanceof N.g&&("permission-denied"===t.code?e="您沒有權限取消此預約。":"not-found"===t.code?e="找不到舊預約資料,將直接建立新預約。":"failed-precondition"===t.code&&(e="舊預約狀態已改變,無法取消。")),F({variant:"destructive",title:"取消舊預約失敗",description:e}),!(t instanceof N.g&&"not-found"===t.code))return}}let r=(B?.uid?await (0,D.L)(B.uid):null)||B?.displayName||B?.email?.split("@")[0]||"未命名用戶",n=u.jg.parse({userId:B?.uid,userEmail:B?.email,userDisplayName:r,advisorId:U.id,advisorName:U.name,advisorEmail:U.email||"",advisorFee:Number(U.fee||0),date:P.date,time:P.time,method:P.method,location:eA,topic:P.topic,note:P.note,status:"pending",...O&&{bookingContext:O}});if(!v.functions)throw Error("Firebase Functions 未初始化");let l=(0,g.httpsCallable)(v.functions,"createBookingAtomic"),o=await l({bookingData:n});if(!o.data.success)throw Error("預約建立失敗");let c={id:o.data.bookingId,...o.data.booking};
1if(et(e=>({...e,[n.date]:{...e[n.date]||{},[n.time]:!0}})),ey(c),G("consent"),F({title:"預約資料已建立",description:"請完成授權確認以進入付款流程。"}),B?.uid&&c)try{let e=await k.M.createChatRoom(B.uid,U.id,U.name,U.avatar??null,c.userDisplayName??r,c.userEmail??B.email??null),t=c.method??"",a=c.location?`,${c.location}`:"",i=`我已預約您的諮詢(${c.date} ${c.time}),${t}${a},${c.topic??""}。`;await S.s.sendMessage(e.id,B.uid,"user",c.userDisplayName??r,i)}catch(e){(0,C.vV)("建立聊天室或發送預設訊息失敗",e),F({variant:"destructive",title:"聊天室建立失敗",description:"您仍可從「聊天」手動開啟與顧問的對話。"})}}catch(t){(0,C.vV)("預約提交時發生錯誤:",t);let e="預約建立失敗,請稍後再試。";if(t instanceof b.G)e=t.issues[0]?.message||e;else if(t instanceof N.g){let a=t.code,i=t.message;e="failed-precondition"===a?i||"預約條件不符,請檢查顧問狀態或時段可用性。":"not-found"===a?i||"找不到顧問資料。":"permission-denied"===a?i||"沒有權限建立此預約。":"invalid-argument"===a?i||"預約資料格式錯誤。":i||e}else t instanceof Error&&(e=t.message||e);F({variant:"destructive",title:"建立預約失敗",description:e})}finally{X(!1)}},eL=async()=>{if(ep&&U&&B){if(!Y.personal||!Y.financial||!Y.privacy)return void F({variant:"destructive",title:"尚未完成授權",description:"請確認三項授權內容後再繼續。"});try{var e;let t;Q(!0);let a=JSON.stringify({advisorId:U.id,advisorName:U.name,userId:B.uid,clauses:eu.map(e=>e.summary)}),i=await h(a),s=await m.c$.addConsent({bookingId:ep.id,userId:B.uid,advisorId:U.id,userEmail:B.email||"",advisorEmail:U.email||"",personalDataAgreement:Y.personal,financialDataAgreement:Y.financial,financialDataEditAgreement:Y.financialEdit,privacyAgreement:Y.privacy,consentVersion:"2025-11-24",consentContentHash:i,acceptedAt:new Date().toISOString()}),r=new Date(`${ep.date}T${ep.time}:00`),n=new Date(r.getTime()+36e5),l=(e={title:`財務諮詢服務預約 - ${U.name}`,details:`諮詢主題:${ep.topic}
2注意事項:${ep.note||"無"}`,location:eA||"線上",start:r,end:n},t=new URLSearchParams({action:"TEMPLATE",text:e.title,details:e.details,dates:`${x(e.start)}/${x(e.end)}`}),e.location&&t.set("location",e.location),`https://calendar.google.com/calendar/render?${t.toString()}`),o=await m.yZ.updateBooking(ep.id,{consentId:s.id,calendarLink:l,status:"authorized"});ey(o),J(l),await eC(o)}catch(e){F({variant:"destructive",title:"授權失敗",description:e instanceof Error?e.message:"系統發生錯誤,請稍後再試。"})}finally{Q(!1)}}},e_=()=>(0,i.jsxs)(i.Fragment,{children:[M&&(0,i.jsxs)(n.HM,{className:"absolute right-4 top-4 roun
2ded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[(0,i.jsx)(w.A,{className:"h-4 w-4"}),(0,i.jsx)("span",{className:"sr-only",children:"Close"})]}),(0,i.jsxs)(n.c7,{children:[(0,i.jsx)(n.L3,{children:"預約顧問諮詢"}),(0,i.jsx)(n.rr,{children:"請確認顧問資訊後完成預約、授權與付款流程。"})]}),(0,i.jsx)(eo,{currentStep:V}),eg&&(0,i.jsx)(o.default,{className:"py-8",size:64}),!eg&&!U&&!ep&&(0,i.jsx)("div",{className:"py-8 text-center",children:(0,i.jsx)("p",{className:"text-sm text-muted-foreground",children:"無法載入顧問資料,請關閉對話框後重新選擇顧問。"})}),!eg&&U&&(0,i.jsxs)(i.Fragment,{children:["form"===V&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(K,{formState:P,onFormStateChange:e=>W(t=>({...t,...e})),availableTimeOptions:el,isSlotLoading:ea,minDate:es,maxDate:en,advisorOfficeAddress:U?.officeAddress,availableDates:ex,availableSlotsCount:ef}),(0,i.jsx)("div",{className:"sticky bottom-0 bg-background border-t pt-4 mt-6 -mx-4 sm:-mx-6 px-4 sm:px-6 pb-0",children:(0,i.jsxs)("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",children:[(0,i.jsx)(l.$,{variant:"outline",onClick:()=>a(!1),className:"w-full sm:w-auto",children:"取消"}),(0,i.jsx)(l.$,{onClick:eI,disabled:H,className:"w-full sm:w-auto",children:H?"提交中...":"下一步:授權"})]})})]}),"consent"===V&&(0,i.jsx)(er,{consentState:Y,onConsentStateChange:e=>q(t=>({...t,...e})),onConfirm:eL,onBack:()=>G("form"),isSubmitting:Z}),"summary"===V&&(0,i.jsxs)("div",{className:"space-y-4 py-4",children:[(0,i.jsxs)("div",{className:"rounded-lg border p-4 bg-muted/30 space-y-2",children:[(0,i.jsx)("h3",{className:"font-semibold",children:"預約摘要"}),(0,i.jsxs)("div",{className:"grid gap-2 text-sm text-muted-foreground",children:[(0,i.jsxs)("div",{className:"flex justify-between",children:[(0,i.jsx)("span",{children:"時間"}),(0,i.jsxs)("span",{children:[ep?.date," ",ep?.time]})]}),(0,i.jsxs)("div",{className:"flex justify-between",children:[(0,i.jsx)("span",{children:"諮詢方式"}),(0,i.jsx)("span",{children:ep?.method})]}),(0,i.jsxs)("div",{className:"flex justify-between",children:[(0,i.jsx)("span",{children:"主題"}),(0,i.jsx)("span",{children:ep?.topic})]}),(0,i.jsxs)("div",{className:"flex justify-between",children:[(0,i.jsx)("span",{children:"費用"}),(0,i.jsxs)("span",{children:["NT$ ",Number(U?.fee||0).toLocaleString()]})]})]})]}),z&&(0,i.jsx)(l.$,{asChild:!0,variant:"outline",className:"w-full",children:(0,i.jsxs)("a",{href:z,target:"_blank",rel:"noreferrer",children:[(0,i.jsx)(j.A,{className:"h-4 w-4 mr-2"}),"加入 Google 行事曆"]})})]})]}),!eg&&!U&&!ep&&(0,i.jsxs)("div",{className:"py-8 text-center space-y-4",children:[(0,i.jsx)("p",{className:"text-sm text-muted-foreground",children:"無法載入顧問資料,請關閉對話框後重新選擇顧問。"}),(0,i.jsx)(l.$,{variant:"outline",onClick:()=>a(!1),children:"關閉"})]})]});return E?(0,i.jsx)(i.Fragment,{children:e_()}):(0,i.jsx)(n.lG,{open:t,onOpenChange:a,children:(0,i.jsx)(n.Cf,{className:"w-[calc(100%-1.5rem)] sm:max-w-[640px] max-h-[90vh] overflow-y-auto overflow-x-hidden p-4 sm:p-6 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",asChild:!0,children:(0,i.jsx)("div",{children:(0,i.jsx)(ec.P.div,{initial:{opacity:0,x:100},animate:{opacity:1,x:0},transition:{duration:.3,delay:.3,ease:"easeInOut"},children:e_()})})})})}},57381:(e,t,a)=>{a.d(t,{n:()=>r});var i=a(31615),s=a(85084);function r(e={}){let{enabled:t=!0}=e,[a,n]=(0,i.useState)([]),[l,o]=(0,i.useState)(!1),[c,d]=(0,i.useState)(null);return(0,i.useEffect)(()=>{if(!t)return;let e=!1;return d(null),o(!0),s.advisorOperations.getAllAdvisors().then(t=>{e||n(t??[])}).catch(t=>{e||d(t instanceof Error?t:Error(String(t)))}).finally(()=>{e||o(!1)}),()=>{e=!0}},[t]),{advisors:a,isLoading:l,error:c}}},66592:(e,t,a)=>{a.d(t,{V:()=>c});var i=a(85047);a(31615);var s=a(13144),r=a(95513),n=a(51237),l=a(34961),o=a(21410);function c({className:e,classNames:t,showOutsideDays:a=!0,components:d,...m}){return(0,i.jsx)(n.h,{showOutsideDays:a,className:(0,l.cn)("p-3",e),components:{...d,Chevron:({...e})=>"left"===e.orientation?(0,i.jsx)(s.A,{className:"h-4 w-4"}):(0,i.jsx)(r.A,{className:"h-4 w-4"})}
2,classNames:{months:"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",month:"space-y-4",caption:"flex justify-center pt-1 relative items-center",caption_label:"text-sm font-medium",nav:"space-x-1 flex items-center",nav_button:(0,l.cn)((0,o.r)({variant:"outline"}),"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"),nav_button_previous:"absolute left-1",nav_button_next:"absolute right-1",month_grid:"w-full border-collapse table-fixed",weekdays:"w-full",weekday:"text-muted-foreground rounded-md h-9 font-normal text-[0.8rem] text-center align-middle w-[14.28%]",week:"w-full mt-0.5",day:"h-9 w-[14.28%] text-center text-sm p-0 relative align-middle [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",day_button:(0,l.cn)((0,o.r)({variant:"ghost"}),"h-9 w-9 p-0 font-normal aria-selected:opacity-100"),day_range_end:"day-range-end",day_selected:"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",day_today:"bg-accent text-accent-foreground",day_outside:"day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground",day_disabled:"text-muted-foreground opacity-50",day_range_middle:"aria-selected:bg-accent aria-selected:text-accent-foreground",day_hidden:"invisible",...t},...m})}c.displayName="Calendar"},74265:(e,t,a)=>{a.d(t,{X:()=>i});let i={ADVANCE_BOOKING_DAYS:7,BOOKING_WINDOW_DAYS:90,MIN_ADVANCE_BOOKING_DAYS:0,MIN_BOOKING_WINDOW_DAYS:7}},77405:(e,t,a)=>{a.d(t,{a:()=>s});var i=a(31615);function s(){let[e,t]=i.useState(void 0);return i.useEffect(()=>{let e=window.matchMedia("(max-width: 767px)"),a=()=>{t(window.innerWidth<768)};return e.addEventListener("change",a),t(window.innerWidth<768),()=>e.removeEventListener("change",a)},[]),!!e}},93674:(e,t,a)=>{a.d(t,{Bu:()=>s,L2:()=>r});let i={CFP:{id:"CFP",name:"認證理財規劃顧問",abbreviation:"CFP\xae",color:"bg-blue-600",textColor:"text-white",icon:"/certifications/cfp.svg"},RFP:{id:"RFP",name:"註冊財務規劃師",abbreviation:"RFP\xae",color:"bg-green-600",textColor:"text-white",icon:"/certifications/rfp.svg"},RFC:{id:"RFC",name:"註冊財務顧問",abbreviation:"RFC\xae",color:"bg-purple-600",textColor:"text-white",icon:"/certifications/rfc.svg"},CFA:{id:"CFA",name:"特許財務分析師",abbreviation:"CFA",color:"bg-amber-600",textColor:"text-white",icon:"/certifications/cfa.svg"},CWM:{id:"CWM",name:"認證財富管理師",abbreviation:"CWM",color:"bg-indigo-600",textColor:"text-white",icon:"/certifications/cwm.svg"},ChFC:{id:"ChFC",name:"特許財務顧問",abbreviation:"ChFC\xae",color:"bg-teal-600",textColor:"text-white",icon:"/certifications/chfc.svg"},CLU:{id:"CLU",name:"特許人壽保險師",abbreviation:"CLU\xae",color:"bg-red-600",textColor:"text-white",icon:"/certifications/clu.svg"},CPA:{id:"CPA",name:"會計師",abbreviation:"CPA",color:"bg-slate-600",textColor:"text-white",icon:"/certifications/cpa.svg"}};function s(e){return i[e.toUpperCase()]||null}function r(){return Object.values(i)}}}]);

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.