PageSourceSearch

https://titanfitness.com.au/assets/EvoltBooking-DJlo6VB-.js

js titanfitness.com.au collected 2026-10-04 03:00:47 UTC 19,902 bytes, 32 lines download raw bytes

1import{r as j,j as e,m as Y}from"./framer-motion-DzpjAbGD.js";import{B as D,C as ee,h as q,al as te,N as se}from"./index-B_A0VGFg.js";import{F as re}from"./Footer--mEcCldg.js";import{Q as ae}from"./QuickLinks-_FX8M6PC.js";import{d as ie,t as _,h as G,f as E}from"./format-Ojg0BgrM.js";import{i as z,s as H,e as R,b as C,a as $,C as oe}from"./isBefore-D_JHo9iG.js";import{a as ne}from"./addDays-DUAmeHtR.js";import{S as le}from"./skeleton-BnVQSA8m.js";import{supabase as J}from"./client-iCcUSwig.js";import{C as W}from"./clock-5_nx_Luq.js";import{u as Q,t as Z}from"./zod-BksOOjMN.js";import{I as P}from"./input-Ct9yRvT7.js";import{L as I}from"./label-DsxHOGBp.js";import{u as w}from"./index-8RmdXmPC.js";import{D as ce,a as me,b as de,c as he,d as ue}from"./dialog-DsHaumL3.js";import{L as xe}from"./lock-CfRIzwlz.js";import{L as K}from"./loader-circle-BkylcdcG.js";import{o as X,s as L}from"./types-DKmCoP0v.js";import{S as pe,a as fe}from"./shopify-B7dF7GzX.js";import{l as ge}from"./logFormError-sHxFbEWy.js";import{C as be}from"./calendar-CDNdBJxE.js";import{C as ye}from"./credit-card-DBRpfmRH.js";import{Z as je}from"./zap-BPEZ-Aps.js";import{A as Ne}from"./arrow-left-CNGdlALM.js";import"./titan-logo-Bzm_Gd6M.js";import"./phone-C3cv5a3t.js";import"./typography-BxBmlXUB.js";function ve(s){return ie(s,Date.now())}function we(s,h){const r=_(s.start),p=_(s.end);let l=+r>+p;const u=l?+r:+p,o=l?p:r;o.setHours(0,0,0,0);let y=1;const x=[];for(;+o<=u;)x.push(_(o)),o.setDate(o.getDate()+y),o.setHours(0,0,0,0);return l?x.reverse():x}function Se(s){return z(s,ve(s))}const Me=({onDateSelect:s,selectedDate:h})=>{const[r,p]=j.useState(new Date),l=G(new Date),u=ne(l,30),o=H(r),y=R(r),x=we({start:o,end:y}),a=o.getDay(),N=Array(a).fill(null),f=t=>{const n=G(t);return C(n,l)||C(u,n)},c=()=>{const t=$(r,-1);C(R(t),l)||p(t)},i=()=>{const t=$(r,1);C(u,H(t))||p(t)},T=!C(R($(r,-1)),l),S=!C(u,H($(r,1)));return e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold mb-6",children:"Select a Date"}),e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsx(D,{variant:"ghost",size:"icon",onClick:c,disabled:!T,children:e.jsx(oe,{className:"h-5 w-5"})}),e.jsx("h4",{className:"text-lg font-medium",children:E(r,"MMMM yyyy")}),e.jsx(D,{variant:"ghost",size:"icon",onClick:i,disabled:!S,children:e.jsx(ee,{className:"h-5 w-5"})})]}),e.jsx("div",{className:"grid grid-cols-7 gap-1 mb-2",children:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"].map(t=>e.jsx("div",{className:"text-center text-sm font-medium text-muted-foreground py-2",children:t},t))}),e.jsxs("div",{className:"grid grid-cols-7 gap-1",children:[N.map((t,n)=>e.jsx("div",{className:"aspect-square"},`empty-${n}`)),x.map(t=>{const n=f(t),m=h&&z(t,h),v=Se(t);return e.jsx("button",{onClick:()=>!n&&s(t),disabled:n,className:`
2                aspect-square flex items-center justify-center rounded-lg text-sm font-medium
3                transition-all
4                ${n?"text-muted-foreground/30 cursor-not-allowed":"hover:bg-primary/10 cursor-pointer"}
5                ${m?"bg-primary text-primary-foreground hover:bg-primary":""}
6                ${v&&!m?"ring-2 ring-primary ring-inset":""}
7              `,children:E(t,"d")},t.toISOString())})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4 text-center",children:"You can book up to 30 days in advance"})]})},Ee=({selectedDate:s,userType:h,onTimeSelect:r,selectedTime:p})=>{const[l,u]=j.useState([]),[o,y]=j.useState(!0),[x,a]=j.useState(null);j.useEffect(()=>{(async()=>{var n;if(h){y(!0),a(null);try{const m=E(s,"yyyy-MM-dd"),{data:v,error:d}=await J.functions.invoke("get-evolt-availability",{body:{startDate:m,endDate:m,userType:h}});if(d)throw d;(n=v==null?void 0:v.availability)!=null&&n[m]?u(v.availability[m]):u([])}catch(m){console.error("Error fetching availability:",m),a("Failed to load available times. Please try again.")}finally{y(!1)}}})()},[s,h]);const N=t=>{const[n,m]=t.split(":"),v=parseInt(n),d=v>=12?"PM":"AM";return`${v%12||12}:${m} ${d}`};if(o)return e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold mb-2",children:"Select a Time"}),e.jsx("p",{className:"text-muted-foreground mb-6",children:E(s,"EEEE, MMMM d, yyyy")}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3",children:Array(8).fill(0).map((t,n)=>e.jsx(le,{className:"h-16 rounded-lg"},n))})]});if(x)return e.jsxs("div",{className:"text-center py-8",children:[e.jsx("p",{className:"text-destructive mb-4",children:x}),e.jsx("button",{onClick:()=>window.location.reload(),className:"text-primary hover:underline",children:"Try again"})]});if(l.length===0)return e.jsxs("div",{className:"text-center py-8",children:[e.jsx(W,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),e.jsx("p",{className:"text-muted-foreground",children:"No time slots available for this date."})]});const f=l.filter(t=>parseInt(t.time.split(":")[0])<7),c=l.filter(t=>{const n=parseInt(t.time.split(":")[0]);return n>=7&&n<9}),i=l.filter(t=>parseInt(t.time.split(":")[0])>=9),T=()=>f.length===0?"":Math.min(...f.map(n=>parseInt(n.time.split(":")[0])))===5?"Early Morning (5:00 AM - 6:45 AM)":"Early Morning (6:00 AM - 6:45 AM)",S=(t,n)=>e.jsxs("div",{className:"mb-6",children:[e.jsx("h4",{className:"text-sm font-medium text-muted-foreground mb-3",children:n}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3",children:t.map(m=>e.jsxs("button",{onClick:()=>m.available&&r(m.time),disabled:!m.available,className:`
8              relative p-4 rounded-lg border-2 transition-all text-left
9              ${m.available?p===m.time?"border-primary bg-primary/10":"border-border hover:border-primary/50 cursor-pointer":"border-border/50 bg-muted/50 cursor-not-allowed"}
10            `,children:[e.jsx("div",{className:`font-semibold ${m.available?"":"text-muted-foreground"}`,children:N(m.time)}),m.available?e.jsx("div",{className:"text-xs text-green-600 mt-1",children:"Available"}):e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:"Booked"})]},m.time))})]});return e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold mb-2",children:"Select a Time"}),e.jsx("p",{className:"text-muted-foreground mb-6",children:E(s,"EEEE, MMMM d, yyyy")}),f.length>0&&S(f,T()),c.length>0&&S(c,"Morning (7:00 AM - 8:45 AM)"),i.length>0&&S(i,"Extended Hours")]})},ke=X({email:L().email("Invalid email address"),password:L().min(1,"Password is required")}
10),Ce=({open:s,onOpenChange:h,onSuccess:r})=>{const[p,l]=j.useState(!1),{signIn:u}=q(),{register:o,handleSubmit:y,formState:{errors:x},setError:a}=Q({resolver:Z(ke)}),N=async f=>{l(!0);try{const{error:c}=await u(f.email,f.password);if(c){const i=c.toLowerCase();i.includes("invalid email or password")||i.includes("credentials")?(w.error("Invalid email or password",{description:"Please check your login details and try again."}),a("email",{message:" "}),a("password",{message:"Invalid email or password"})):i.includes("no active membership")||i.includes("renew")?w.error("No active membership found",{description:"Your membership may have expired. Please contact Titan Fitness or purchase a new membership."}):i.includes("no membership found")||i.includes("purchase a membership")?w.error("No membership found",{description:"We couldn't find a membership with this email. Please sign up at Titan Fitness."}):i.includes("rate limit")||i.includes("too many")?w.error("Too many login attempts",{description:"Please wait a few minutes before trying again."}):i.includes("server")||i.includes("configuration")?w.error("Service temporarily unavailable",{description:"We're experiencing technical difficulties. Please try again later."}):i.includes("unable to connect")||i.includes("authentication service")?w.error("Connection error",{description:"Unable to reach the authentication service. Please check your internet connection."}):w.error("Login failed",{description:c});return}w.success("Membership verified!",{description:"You now have access to member pricing."}),r()}catch{w.error("Unexpected error",{description:"Something went wrong. Please try again later."})}finally{l(!1)}};return e.jsx(ce,{open:s,onOpenChange:h,children:e.jsxs(me,{className:"sm:max-w-md",children:[e.jsxs(de,{children:[e.jsxs(he,{className:"flex items-center gap-2",children:[e.jsx(xe,{className:"h-5 w-5 text-primary"}),"Verify Your Membership"]}),e.jsx(ue,{children:"Please sign in with your Titan Fitness member credentials to access member pricing."})]}),e.jsxs("form",{onSubmit:y(N),className:"space-y-4 mt-4",children:[e.jsxs("div",{children:[e.jsx(I,{htmlFor:"login-email",children:"Email Address"}),e.jsx(P,{id:"login-email",type:"email",...o("email"),placeholder:"[email protected]",className:"mt-1",autoComplete:"email"}),x.email&&e.jsx("p",{className:"text-sm text-destructive mt-1",children:x.email.message})]}),e.jsxs("div",{children:[e.jsx(I,{htmlFor:"login-password",children:"Password"}),e.jsx(P,{id:"login-password",type:"password",...o("password"),placeholder:"••••••••",className:"mt-1",autoComplete:"current-password"}),x.password&&e.jsx("p",{className:"text-sm text-destructive mt-1",children:x.password.message})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx(D,{type:"button",variant:"outline",onClick:()=>h(!1),className:"flex-1",children:"Cancel"}),e.jsx(D,{type:"submit",disabled:p,className:"flex-1",children:p?e.jsxs(e.Fragment,{children:[e.jsx(K,{className:"w-4 h-4 mr-2 animate-spin"}),"Verifying..."]}):"Verify Membership"})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground text-center mt-4",children:["Don't have a membership?"," ",e.jsx("a",{href:"/membership",className:"text-primary hover:underline",children:"Join Titan Fitness"})]})]})})},De=X({name:L().min(1,"Name is required").max(100),email:L().email("Invalid email address").max(255),phone:L().max(20).optional()}),Te=`
11  mutation cartCreate($input: CartInput!) {
12    cartCreate(input: $input) {
13      cart {
14        id
15        checkoutUrl
16      }
17      userErrors {
18        field
19        message
20      }
21    }
22  }
23`,Fe="gid://shopify/ProductVariant/50831878193430",Pe="gid://shopify/ProductVariant/50831878848790",Ie=({selectedDate:s,selectedTime:h,userType:r})=>{const[p,l]=j.useState(!1),[u,o]=j.useState(!1),[y,x]=j.useState(null),{member:a,isAuthenticated:N}=q(),{register:f,handleSubmit:c,formState:{errors:i}}=Q({resolver:Z(De),defaultValues:{name:a?`${a.firstName} ${a.lastName}`:"",email:(a==null?void 0:a.email)||""}}),T=d=>{const[b,g]=d.split(":"),M=parseInt(b),k=M>=12?"PM":"AM";return`${M%12||12}:${g} ${k}`},S=async()=>{var d,b,g,M,k,A;try{const O=await fetch(pe,{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":fe},body:JSON.stringify({query:Te,variables:{input:{lines:[{quantity:1,merchandiseId:r==="member"?Fe:Pe}]}}})});if(!O.ok)throw new Error(`Shopify checkout request failed (status ${O.status})`);const B=await O.json();if(((g=(b=(d=B.data)==null?void 0:d.cartCreate)==null?void 0:b.userErrors)==null?void 0:g.length)>0)throw new Error(B.data.cartCreate.userErrors[0].message);const U=(A=(k=(M=B.data)==null?void 0:M.cartCreate)==null?void 0:k.cart)==null?void 0:A.checkoutUrl;if(!U)throw new Error("No checkout URL returned from Shopify");const V=new URL(U);return V.hostname="shop.titanfitness.com.au",V.searchParams.set("channel","online_store"),V.toString()}catch(F){throw console.error("Error creating checkout:",F),new Error((F==null?void 0:F.message)||"Failed to create checkout")}},t=async(d,b)=>{l(!0);try{const{data:g,error:M}=await J.functions.invoke("create-evolt-booking",{body:{bookingDate:E(s,"yyyy-MM-dd"),bookingTime:h,customerName:d.name,customerEmail:d.email,customerPhone:d.phone||void 0,userType:r,pgmMemberId:b}});if(M||!(g!=null&&g.success))throw new Error((g==null?void 0:g.error)||"Failed to create booking");const k=await S();w.success("Redirecting to checkout..."),window.location.href=k}catch(g){console.error("Booking error:",g),await ge({formName:"EVOLT Booking",fields:{name:d.name,email:d.email,phone:d.phone,userType:r,pgmMemberId:b},error:g}),w.error(g.message||"Failed to process booking. Please try again.")}finally{l(!1)}},n=async d=>{var b;if(r==="member"&&!N){x(d),o(!0);return}await t(d,(b=a==null?void 0:a.id)==null?void 0:b.toString())},m=()=>{o(!1),y&&a&&t(y,a.id.toString())},v=r==="member"?"$50":"$60";return e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold mb-6",children:"Your Details"}),e.jsxs("div",{className:"bg-muted/50 rounded-lg p-4 mb-6",children:[e.jsx("h4",{className:"font-medium mb-3",children:"Booking Summary"}),e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(be,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{children:E(s,"EEEE, MMMM d, yyyy")})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{children:T(h)})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ye,{className:"h-4 w-4 text-muted-foreground"}),e.jsxs("span",{children:[r==="member"?"Member":"Non-Member"," - ",v]})]})]})]}),r==="member"&&e.jsx("div",{className:`rounded-lg p-4 mb-6 ${N?"bg-green-500/10 border border-green-500/20":"bg-yellow-500/10 border border-yellow-500/20"}`,children:N?e.jsxs("p",{className:"text-sm text-green-600",children:["✓ Logged in as ",a==null?void 0:a.firstName," ",a==null?void 0:a.lastName]}):e.jsx("p",{className:"text-sm text-yellow-600",children:"You'll need to verify your membership to continue."})}),e.jsxs("form",{onSubmit:c(n),className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(I,{htmlFor:"name",children:"Full Name *"}),e.jsx(P,{id:"name",...f("name"),placeholder:"John Smith",className:"mt-1"}),i.name&&e.jsx("p",{className:"text-sm text-destructive mt-1",children:i.name.message})]}),e.jsxs("div",{children:[e.jsx(I,{htmlFor:"email",children:"Email Address *"}),e.jsx(P,{id:"email",type:"email",...f("email"),placeholder:"[email protected]",className:"mt-1"}),i.email&&e.jsx("p",{className:"text-sm text-destructive mt-1",children:i.email.message})]}),e.jsxs("div",{children:[e.jsx(I,{htmlFor:"phone",children:"Phone Number (optional)"}),e.jsx(P,{id:"phone",type:"tel",...f("phone"),placeholder:"0412 345 678",className:"mt-1"})]}),e.jsx(D,{type:"submit",className:"w-full touch-manipulation",size:"lg",disabled:p,onClick:d=>{var b;(b=d.currentTarget.form)==null||b.requestSubmit()},children:p?e.jsxs(e.Fragment,{children:[e.jsx(K,{className:"w-4 h-4 mr-2 animate-spin"}),"Processing..."]}):e.jsx(e.Fragment,{children:r==="member"&&!N?"Verify Membership & Continue":`Proceed to Checkout - ${v}`})})]}),e.jsx(Ce,{open:u,onOpenChange:o,onSuccess:m})]})},nt=()=>{const[s,h]=j.useState("calendar"),[r,p]=j.useState(null),[l,u]=j.useState(null),[o,y]=j.useState(null),x=c=>{p(c),u(null),h("time")},a=c=>{u(c),h("form")},N=()=>{s==="time"?(h("calendar"),u(null)):s==="form"&&h("time")},f=c=>{y(c),(s==="time"||s==="form")&&(u(null),h("time"))};return e.jsxs(e.Fragment,{children:[e.jsxs(te,{children:[e.jsx("title",{children:"Book EVOLT 360 Body Scan | Titan Fitness Coogee"}),e.jsx("meta",{name:"description",content:"Book your EVOLT 360 body composition scan at Titan Fitness. Get detailed insights into your body composition including muscle mass, body fat, and more."})]}),e.jsx(se,{variant:"solid"}),e.jsxs("main",{className:"min-h-screen bg-background",children:[e.jsxs("section",{className:"relative pt-32 pb-16 md:pt-40 md:pb-20 overflow-hidden bg-[#0f1419]",children:[e.jsx("div",{className:"absolute inset-0 bg-gradient-to-b from-black/20 to-[#0f1419]"}),e.jsx("div",{className:"container mx-auto px-4 relative",children:e.jsxs(Y.div,{initial:{opacity:0,y:20}
23,animate:{opacity:1,y:0},className:"max-w-4xl mx-auto text-center",children:[e.jsxs("div",{className:"flex items-center justify-center gap-2 mb-4",children:[e.jsx(je,{className:"h-6 w-6 text-primary"}),e.jsx("span",{className:"text-primary font-semibold uppercase tracking-wide",children:"EVOLT 360"})]}),e.jsx("h1",{className:"text-5xl md:text-6xl lg:text-7xl font-display font-black mb-6 leading-tight tracking-tighter uppercase text-white",children:"Book Your Body Scan"}),e.jsx("p",{className:"text-lg md:text-xl text-white/80 max-w-2xl mx-auto",children:"Get detailed insights into your body composition including muscle mass, body fat percentage, visceral fat, and more with our state-of-the-art EVOLT 360 scanner."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4 mt-8",children:[e.jsxs("div",{className:"bg-primary/20 border border-primary/30 rounded-lg px-6 py-3",children:[e.jsx("span",{className:"text-sm text-white/70",children:"Members"}),e.jsx("p",{className:"text-2xl font-bold text-primary",children:"$50"})]}),e.jsxs("div",{className:"bg-white/10 border border-white/20 rounded-lg px-6 py-3",children:[e.jsx("span",{className:"text-sm text-white/70",children:"Non-Members"}),e.jsx("p",{className:"text-2xl font-bold text-white",children:"$60"})]})]})]})})]}),e.jsx("section",{className:"py-16 md:py-20",children:e.jsx("div",{className:"container mx-auto px-4",children:e.jsxs("div",{className:"max-w-5xl mx-auto",children:[e.jsx("div",{className:"flex items-center justify-center gap-4 mb-8",children:["calendar","time","form"].map((c,i)=>e.jsxs("div",{className:"flex items-center",children:[e.jsx("div",{className:`
24                      w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold
25                      ${s===c||["calendar","time","form"].indexOf(s)>i?"bg-primary text-primary-foreground":"bg-muted text-muted-foreground"}
26                    `,children:i+1}),e.jsx("span",{className:`ml-2 hidden sm:inline text-sm ${s===c?"text-foreground font-medium":"text-muted-foreground"}`,children:c==="calendar"?"Select Date":c==="time"?"Select Time":"Your Details"}),i<2&&e.jsx("div",{className:"w-12 h-0.5 bg-muted mx-4"})]},c))}),s!=="calendar"&&e.jsxs(D,{variant:"ghost",onClick:N,className:"mb-4",children:[e.jsx(Ne,{className:"w-4 h-4 mr-2"}),"Back"]}),e.jsxs("div",{className:"bg-card border border-border rounded-xl p-6 mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Are you a Titan Fitness member?"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsxs("button",{onClick:()=>f("member"),className:`
27                      flex-1 p-4 rounded-lg border-2 transition-all
28                      ${o==="member"?"border-primary bg-primary/10":"border-border hover:border-primary/50"}
29                    `,children:[e.jsx("div",{className:"font-semibold",children:"Yes, I'm a Member"}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"$50 per scan"})]}),e.jsxs("button",{onClick:()=>f("non-member"),className:`
30                      flex-1 p-4 rounded-lg border-2 transition-all
31                      ${o==="non-member"?"border-primary bg-primary/10":"border-border hover:border-primary/50"}
32                    `,children:[e.jsx("div",{className:"font-semibold",children:"No, I'm a Guest"}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"$60 per scan"})]})]})]}),o&&e.jsxs(Y.div,{initial:{opacity:0,x:20},animate:{opacity:1,x:0},exit:{opacity:0,x:-20},className:"bg-card border border-border rounded-xl p-6",children:[s==="calendar"&&e.jsx(Me,{onDateSelect:x,selectedDate:r}),s==="time"&&r&&e.jsx(Ee,{selectedDate:r,userType:o,onTimeSelect:a,selectedTime:l}),s==="form"&&r&&l&&e.jsx(Ie,{selectedDate:r,selectedTime:l,userType:o})]},s),!o&&e.jsx("div",{className:"bg-card border border-border rounded-xl p-12 text-center",children:e.jsx("p",{className:"text-muted-foreground",children:"Please select whether you're a member or guest to continue booking."})})]})})}),e.jsx(ae,{exclude:["/evolt-booking"]})]}),e.jsx(re,{})]})};export{nt as default};

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