PageSourceSearch

https://harbor-os.com/assets/GiftCardsPage-D5egITIZ.js

js harbor-os.com collected 2026-10-02 01:32:05 UTC 7,176 bytes, 1 lines download raw bytes

1import{by as H,r as a,g as I,i as P,j as e,bM as $,bA as A,bN as V}from"./vendor-B3bqREfz.js";import{n as q,u as U,T as L,o as O,p as d,r as o,C as m,a as v,b as C,d as x,I as r,s as Q,B as b,g as K,f as N}from"./index-BHZdkTHk.js";import{T as J}from"./textarea-BFtGXtJd.js";import{b as Y}from"./auth-url-CN_iq7Nz.js";const z=[2500,5e3,1e4,25e3,5e4];function se(){var R;const{user:n}=q(),{toast:i}=U(),B=H(),[l,y]=a.useState(5e3),[t,u]=a.useState(""),[k,w]=a.useState(""),[S,T]=a.useState(""),[G,X]=a.useState(""),[h,E]=a.useState(""),[p,M]=a.useState(""),[c,F]=a.useState(null),{data:j=[]}=I({queryKey:["/api/gift-cards/mine"],enabled:!!n}),g=P({mutationFn:()=>N("POST","/api/gift-cards/purchase",{amountCents:t?Math.round(parseFloat(t)*100):l,recipientEmail:k||void 0,recipientName:S||void 0,message:G||void 0}).then(s=>s.json()),onSuccess:s=>{B.invalidateQueries({queryKey:["/api/gift-cards/mine"]}),i({title:"Gift Card Created!",description:`Code: ${s.code}`}),w(""),T(""),X(""),u("")},onError:()=>i({title:"Error",description:"Failed to create gift card.",variant:"destructive"})}),f=P({mutationFn:()=>N("POST","/api/gift-cards/redeem",{code:h}).then(s=>s.json()),onSuccess:s=>{i({title:"Gift Card Redeemed!",description:`$${(s.valueCents/100).toFixed(2)} added to your account.`}),E("")},onError:()=>i({title:"Invalid Code",description:"This gift card is not valid or already redeemed.",variant:"destructive"})}),D=async()=>{try{const s=await N("GET",`/api/gift-cards/check/${p}`);F(await s.json())}catch{F(null),i({title:"Not Found",description:"Gift card not found.",variant:"destructive"})}};return e.jsxs("div",{className:"max-w-3xl mx-auto px-4 py-8",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx($,{className:"h-8 w-8 text-purple-600"}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Gift Cards"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Give the gift of marine expertise"})]})]}),e.jsxs(L,{defaultValue:"purchase",children:[e.jsxs(O,{className:"mb-6",children:[e.jsx(d,{value:"purchase",children:"Purchase"}),e.jsx(d,{value:"redeem",children:"Redeem"}),e.jsx(d,{value:"check",children:"Check Balance"}),n&&e.jsxs(d,{value:"mine",children:["My Gift Cards (",j.length,")"]})]}),e.jsx(o,{value:"purchase",children:e.jsxs(m,{children:[e.jsx(v,{children:e.jsx(C,{children:"Purchase a Gift Card"})}),e.jsxs(x,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-2 block",children:"Select Amount"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[z.map(s=>e.jsxs("button",{onClick:()=>{y(s),u("")},className:`px-4 py-2 rounded-lg border text-sm font-medium transition-colors ${l===s&&!t?"bg-purple-600 text-white border-purple-600":"hover:border-purple-400"}`,children:["$",(s/100).toFixed(0)]},s)),e.jsx(r,{placeholder:"Custom $",type:"number",min:5,value:t,onChange:s=>{u(s.target.value)},className:"w-28",onFocus:()=>y(0)})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Recipient Email (optional)"}),e.jsx(r,{placeholder:"[email protected]",value:k,onChange:s=>w(s.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Recipient Name (optional)"}),e.jsx(r,{placeholder:"Jane Doe",value:S,onChange:s=>T(s.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Personal Message (optional)"}),e.jsx(J,{placeholder:"Happy Birthday! Enjoy your consultation...",value:G,onChange:s=>X(s.target.value),rows:3})]}),e.jsxs("div",{className:"p-3 bg-purple-50 rounded-lg text-sm",children:[e.jsxs("p",{className:"font-medium text-purple-700",children:["You'll receive: $",((t?Math.round(parseFloat(t)*100):l)/100).toFixed(2)," Gift Card"]}),e.jsxs("p",{className:"text-purple-600 text-xs mt-1",children:["Valid for 1 year · Redeemable for any ",((R=Q())==null?void 0:R.name)||"Harbor Shoppers"," service"]})]}),e.jsxs(b,{className:"w-full bg-purple-600 hover:bg-purple-700",disabled:g.isPending,onClick:()=>g.mutate(),children:[e.jsx($,{className:"h-4 w-4 mr-2"}),g.isPending?"Processing...":`Purchase Gift Card · $${((t?Math.round(parseFloat(t||"0")*100):l)/100).toFixed(2)}`]})]})]})}),e.jsx(o,{value:"redeem",children:e.jsxs(m,{children:[e.jsx(v,{children:e.jsx(C,{children:"Redeem a Gift Card"})}),e.jsxs(x,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-sm font-medium mb-1 block",children:"Gift Card Code"}),e.jsx(r,{placeholder:"HS-XXXX-XXXX",value:h,onChange:s=>E(s.target.value.toUpperCase()),className:"font-mono tracking-widest"})]}),e.jsxs(b,{className:"w-full",disabled:!h||f.isPending||!n,onClick:()=>f.mutate(),children:[e.jsx(A,{className:"h-4 w-4 mr-2"}),f.isPending?"Redeeming...":"Redeem Gift Card"]}),!n&&e.jsxs("p",{className:"text-sm text-muted-foreground text-center",children:["Please ",e.jsx("a",{href:Y(),className:"text-blue-600 underline",children:"sign in"})," to redeem a gift card."]})]})]})}),e.jsx(o,{value:"check",children:e.jsxs(m,{children:[e.jsx(v,{children:e.jsx(C,{children:"Check Balance"})}),e.jsxs(x,{className:"space-y-4",children:[e.jsx(r,{placeholder:"HS-XXXX-XXXX",value:p,onChange:s=>M(s.target.value.toUpperCase()),className:"font-mono tracking-widest"}),e.jsx(b,{variant:"outline",className:"w-full",disabled:!p,onClick:D,children:"Check Balance"}),c&&e.jsxs("div",{className:"p-4 bg-green-50 rounded-lg",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(A,{className:"h-5 w-5 text-green-500"}),e.jsx("span",{className:"font-semibold text-green-700",children:"Valid Gift Card"})]}),e.jsxs("p",{className:"text-2xl font-bold text-green-700",children:["$",(c.remainingValueCents/100).toFixed(2)]}),e.jsx("p",{className:"text-sm text-green-600",children:"Remaining balance"}),c.expiresAt&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Expires ",new Date(c.expiresAt).toLocaleDateString()]})]})]})]})}),n&&e.jsx(o,{value:"mine",children:e.jsxs("div",{className:"space-y-3",children:[j.length===0&&e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No gift cards purchased yet."}),j.map(s=>e.jsx(m,{children:e.jsxs(x,{className:"flex items-center justify-between pt-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono font-medium",children:s.code}),e.jsx("button",{onClick:()=>{navigator.clipboard.writeText(s.code),i({title:"Copied!"})},children:e.jsx(V,{className:"h-3.5 w-3.5 text-muted-foreground"})})]}),s.recipientEmail&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["To: ",s.recipientEmail]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:new Date(s.createdAt).toLocaleDateString()})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("p",{className:"text-lg font-bold",children:["$",(s.remainingValueCents/100).toFixed(2)]}),e.jsx(K,{variant:s.status==="active"?"secondary":"outline",className:"text-xs",children:s.status})]})]})},s.id))]})})]})]})}export{se 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.