@lockerverse/react 0.2.126-dev.1 → 0.2.127-dev.1

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.
@@ -17,6 +17,8 @@ type LockerverseAuctionItemProps = {
17
17
  itemId: string;
18
18
  /** Host navigation; the SDK does not depend on a router. */
19
19
  onBack?: (() => void) | undefined;
20
+ /** Item URL for a fresh page visit from the completed result. */
21
+ returnToItemHref?: string | undefined;
20
22
  /** Disable host navigation/reset while submitting or resolving an uncertain operation.
21
23
  * This callback can run after unmount when a sent request resolves. */
22
24
  onInteractionLockChange?: (locked: boolean) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"auction-item.d.ts","names":[],"sources":["../src/auction-item-types.ts","../src/lockerverse-auction-item.tsx"],"mappings":";;;;;KAaY;EACV;EACA;EACA,MAAM;EACN,SAAS,YAAY;EACrB,SAAS;EACT,YAAY;;KAGF;EACV,SAAS;EACT,QAAQ;EACR;;EAEA;;;EAGA,2BAA2B;EAC3B;EACA;EACA,QAAQ;EACR,QAAQ;EACR,eAAe;;EAEf,kBAAkB,QAAQ;;EAE1B,sBAAsB,QAAQ;EAC9B,4BACE,UAAU;EAEZ,eAAe;;EAEf,iBAAiB;;;;iBC0XH,uBAAuB,OAAO,8CAA2B,IAAA"}
1
+ {"version":3,"file":"auction-item.d.ts","names":[],"sources":["../src/auction-item-types.ts","../src/lockerverse-auction-item.tsx"],"mappings":";;;;;KAaY;EACV;EACA;EACA,MAAM;EACN,SAAS,YAAY;EACrB,SAAS;EACT,YAAY;;KAGF;EACV,SAAS;EACT,QAAQ;EACR;;EAEA;;EAEA;;;EAGA,2BAA2B;EAC3B;EACA;EACA,QAAQ;EACR,QAAQ;EACR,eAAe;;EAEf,kBAAkB,QAAQ;;EAE1B,sBAAsB,QAAQ;EAC9B,4BACE,UAAU;EAEZ,eAAe;;EAEf,iBAAiB;;;;iBC4XH,uBAAuB,OAAO,8CAA2B,IAAA"}
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,i as n,n as r,r as i,s as a,t as o}from"./use-auction-boundary.js";import{d as s,f as c,i as l,m as u,n as d,r as f,t as p}from"./host-callback.js";import{i as m,n as h,t as g}from"./stripe-loader.js";import{t as _}from"./auction-result2.js";import{ArrowRight as v,ChevronDown as y,ChevronLeft as b,ChevronRight as x,Clock3 as S,Gavel as C,Pause as w,Play as ee,ShieldCheck as T,TimerReset as E,X as D}from"lucide-react";import{useCallback as O,useEffect as k,useId as A,useMemo as j,useRef as M,useState as N}from"react";import{Fragment as P,jsx as F,jsxs as I}from"react/jsx-runtime";import{LockerverseSdkError as L,calculateLockerverseAuctionPricing as R,getLockerverseAuctionMinimumBid as z}from"@lockerverse/sdk/auctions";import{AddressElement as B,Elements as V,PaymentElement as H,useElements as te,useStripe as U}from"@stripe/react-stripe-js";import{Dialog as W}from"@base-ui/react/dialog";import G from"embla-carousel-autoplay";import K from"embla-carousel-react";function q(e){return{business:{name:`Lockerverse`},fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},terms:{applePay:e?`auto`:`never`,auBecsDebit:`never`,bancontact:`never`,card:`always`,cashapp:`never`,googlePay:`never`,ideal:`never`,paypal:e?`auto`:`never`,sepaDebit:`never`,sofort:`never`,usBankAccount:`never`},wallets:{applePay:e?`auto`:`never`,googlePay:`never`}}}function ne(e){let{isPurchase:t,item:r,pricing:i,id:a}=e;return I(`form`,{className:`lockerverse-auctions__checkout`,noValidate:!0,onSubmit:e.onSubmit,children:[I(`div`,{className:`lockerverse-auctions__checkout-header`,children:[I(`div`,{className:`lockerverse-auctions__checkout-navigation`,children:[F(`button`,{"aria-label":`Back`,className:`lockerverse-auctions__checkout-back`,disabled:!e.onBack,onClick:e.onBack,type:`button`,children:F(b,{"aria-hidden":`true`,size:20})}),I(`div`,{children:[F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:`Step 2 of 2`}),F(`p`,{children:t?`Secure checkout`:`Secure payment method`})]})]}),F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:e.communityName}),F(`h2`,{children:t?`Finalize your purchase.`:`Finalize your bid authorization.`}),F(`p`,{className:`lockerverse-auctions__checkout-summary`,children:t?I(P,{children:[`Pay `,F(`strong`,{children:n(i.totalCents)}),` for`,` `,e.quantity,` `,e.quantity===1?`item`:`items`,` of`,` `,F(`strong`,{children:r.name}),`. Your card is charged immediately once checkout succeeds.`]}):I(P,{children:[`Authorize a payment method for your bid of`,` `,F(`strong`,{children:n(i.subtotalCents)}),` on`,` `,F(`strong`,{children:r.name}),`. Your card is only charged if this bid wins the item.`]})}),r.collectShippingAddress&&I(`div`,{className:`lockerverse-auctions__checkout-physical`,children:[F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:`Physical item`}),F(`p`,{children:`This item requires a delivery address. Billing details are used by default, and you can switch to a separate delivery address below if needed.`})]})]}),I(`div`,{className:`lockerverse-auctions__checkout-body`,children:[e.showFields&&I(`fieldset`,{disabled:e.locked,children:[I(`div`,{className:`lockerverse-auctions__checkout-contact`,children:[F(c,{error:e.contactErrors.email,id:`${a}-email`,label:`Email`,name:`email`,onChange:t=>e.onEmailChange(t.target.value),required:!0,value:e.email}),F(u,{error:e.contactErrors.phone,id:`${a}-phone`,label:`Phone`,children:F(d,{country:e.phoneCountry,error:e.contactErrors.phone,errorId:`${a}-phone-error`,id:`${a}-phone`,name:`phone`,onChange:e.onPhoneChange,required:!0,value:e.phone})})]}),I(`section`,{"aria-label":`Payment Information`,className:`lockerverse-auctions__checkout-section`,children:[I(`div`,{className:`lockerverse-auctions__checkout-section-heading`,children:[F(`h3`,{children:`Payment Information`}),F(`p`,{children:t?`Processed securely and charged immediately for this purchase.`:`Stored securely and charged only if your bid finishes on top.`})]}),F(H,{onLoadError:e.onPaymentLoadError,options:q(t)})]}),I(`section`,{"aria-label":`Billing Details`,className:`lockerverse-auctions__checkout-section`,children:[F(`h3`,{children:`Billing Details`}),F(B,{onChange:e.onBillingChange,options:{mode:`billing`}}),F(`p`,{children:t?`Use your full name here. We use the email and phone above for purchase confirmation and fulfillment updates.`:`Use the bidder's full name here. We use the email and phone above to contact you if this bid is outbid or wins.`})]}),r.collectShippingAddress&&I(`section`,{"aria-label":`Delivery Details`,className:`lockerverse-auctions__checkout-section`,children:[I(`label`,{className:`lockerverse-auctions__checkout-checkbox lockerverse-auctions__checkout-delivery`,htmlFor:`${a}-delivery-same-as-billing`,children:[F(s,{checked:e.sameAsBilling,id:`${a}-delivery-same-as-billing`,onChange:t=>e.onSameAsBillingChange(t.target.checked)}),I(`span`,{children:[F(`strong`,{children:`Delivery address is the same as billing`}),F(`span`,{children:`Leave this on for the fastest flow. Turn it off only if the delivery address should differ from the billing details above.`})]})]}),!e.sameAsBilling&&I(P,{children:[F(`h3`,{children:`Delivery Address`}),F(B,{onChange:e.onShippingChange,options:{mode:`shipping`}})]})]}),e.serviceFeeEnabled&&F(J,{...e})]}),e.message&&F(`p`,{"aria-live":`polite`,className:`lockerverse-auctions__notice`,role:`status`,children:e.message}),!e.isTerminal&&I(`div`,{className:`lockerverse-auctions__checkout-footer`,children:[I(`p`,{children:[t?`By continuing, you agree to be charged for this purchase.`:`By continuing, you agree to have this payment method stored for item settlement if your bid is the winning offer.`,r.collectShippingAddress?` Your delivery details are stored with the ${t?`order`:`bid`} so the seller can fulfill the item after payment.`:``]}),I(`button`,{className:`lockerverse-auctions__button lockerverse-auctions__checkout-submit`,disabled:e.submitDisabled,type:`submit`,children:[e.buttonText,F(v,{"aria-hidden":`true`,size:16})]})]})]})]})}function J(e){let{isPurchase:t,pricing:r}=e;return F(`section`,{"aria-label":`Processing fees`,className:`lockerverse-auctions__checkout-section`,children:e.onIncludeServiceFeeChange?I(`label`,{className:`lockerverse-auctions__checkout-checkbox`,htmlFor:`${e.id}-service-fee`,children:[F(s,{checked:e.includeServiceFee,id:`${e.id}-service-fee`,onChange:t=>e.onIncludeServiceFeeChange?.(t.target.checked)}),I(`span`,{children:[I(`strong`,{children:[t?`Add`:`If I win, add`,` `,n(e.serviceFeeCents),` to help cover processing fees`]}),I(`span`,{children:[t?`Total`:`Total if I win`,`:`,` `,n(r.totalCents)]})]})]}):I(`p`,{children:[t?`Total`:`Total if I win`,`:`,` `,n(r.totalCents)]})})}function Y(e,t,n){return R(e,t.saleMode===`buy_now`?(t.buyNowPriceAmount??0)*n.quantity:n.amount,n.includeServiceFee)}function re(t,n,r){if(e(t,n)!==`active`)return`This item is not accepting bids or purchases.`;if(n.saleMode===`hybrid`)return`This item type is not supported for checkout.`;if(n.saleMode===`buy_now`){if(n.isSoldOut||n.availableQuantity===0)return`This item is sold out.`;if(!(n.buyNowPriceAmount&&Number.isSafeInteger(r.quantity))||r.quantity<1||n.availableQuantity!==null&&r.quantity>n.availableQuantity)return`Select an available quantity.`}else if(!Number.isSafeInteger(r.amount)||r.amount%100!=0||r.amount<z(n))return`Enter a whole-dollar bid at or above the minimum bid.`;return null}function ie(e,t,n,r,i){return e.payment?.publishableKey!==t.payment?.publishableKey||e.payment?.connectedAccountId!==t.payment?.connectedAccountId||e.serviceFeeEnabled!==t.serviceFeeEnabled||n.saleMode!==r.saleMode||n.collectShippingAddress!==r.collectShippingAddress||JSON.stringify(Y(e,n,i))!==JSON.stringify(Y(t,r,i))}function ae(e){return{expectedServiceFeeCents:e.serviceFeeCents,expectedSubtotalCents:e.subtotalCents,expectedTotalCents:e.totalCents}}async function oe({stripe:e,elements:t,email:n,phone:r,billing:i,shipping:a,collectShippingAddress:o}){if(!(i?.complete&&i.value.name.trim()))throw Error(`Complete your billing name and address.`);if(o&&!(a?.complete&&a.value.name.trim()))throw Error(`Complete your shipping name and address.`);let s=await t.submit();if(s.error)throw Error(s.error.message??`Check your payment details.`);let c=await e.createConfirmationToken({elements:t,params:{payment_method_data:{allow_redisplay:`always`,billing_details:{address:i.value.address,email:n,name:i.value.name,phone:r}},return_url:window.location.href,...o&&a?{shipping:{address:a.value.address,name:a.value.name,phone:r}}:void 0}});if(c.error||!c.confirmationToken)throw Error(c.error?.message??`Unable to prepare payment details.`);return c.confirmationToken.id}async function se(e,t){if(!t.requiresAction)return;if(!t.clientSecret)throw Error(`Payment confirmation is incomplete. Check its status before trying again.`);let n=await e.handleNextAction({clientSecret:t.clientSecret});if(n.error)throw Error(n.error.message??`Payment confirmation is incomplete.`)}function ce(e,t,n){return e===`busy`?n?`Processing...`:`Authorizing...`:e===`retry`?`Retry original purchase`:t?`Check purchase status`:n?`Buy Now`:`Authorize Bid`}function X(e){let{auction:t,item:n,selection:r,client:i,onReview:a,onBack:o}=e,s=U(),c=te(),u=A(),[d,h]=N(e.contact?.email??``),[g,_]=N(e.contact?.phone??``),[v,y]=N(()=>l(e.contact?.phone??``)),[b,x]=N({}),[S,C]=N(!0),[w,ee]=N(null),[T,E]=N(null),[D,O]=N(e.resumePurchase??null),[j,P]=N(e.resumePurchase?`pending`:`ready`),[I,R]=N(null),z=M(e.resumePurchase?.submission.clientRequestId??null),B=j===`complete`||j===`uncertain`,V=M(!1),H=M(!0),W=M(e);W.current=e;let G=M(!1);function K(e){H.current&&P(e),p(W.current.onInteractionLockChange,e!==`ready`&&e!==`complete`)}function q(e){H.current&&R(e)}function J(e){K(e===`bid`?`uncertain`:`pending`),q(e===`bid`?`We could not confirm your bid. Do not submit another bid until you check your email or contact the auction organizer.`:`We could not confirm the purchase result. Check its status using the same purchase request.`),G.current||(G.current=!0,p(W.current.onUncertain,e))}k(()=>(H.current=!0,()=>{H.current=!1}),[]);let X=!!(D??e.resumePurchase)||n.saleMode===`buy_now`,Z=D?.pricing??e.resumePurchase?.pricing??Y(t,n,r),le=D?.payment??e.resumePurchase?.payment??t.payment;function Q(e){H.current&&O(e),p(W.current.onPurchaseRecoveryChange,e)}function ue(e){e.status===`paid`?(z.current=null,Q(null),K(`complete`),p(W.current.onResult,{kind:`purchase`,purchaseId:e.purchaseId,quantity:e.quantity,serviceFeeCents:e.serviceFeeCents,status:`paid`,subtotalCents:e.subtotalCents,totalCents:e.totalCents,unitAmountCents:e.subtotalCents/e.quantity}),G.current||(G.current=!0,p(W.current.onPurchaseComplete,e))):e.status===`pending_payment`?(K(`pending`),q(`Your purchase is pending. Check its status before making another payment.`)):(z.current=null,Q(null),K(`ready`),q(`This purchase is ${e.status.replaceAll(`_`,` `)}. You can start a new purchase.`))}function de(){let e=f(g,v),t=m({email:d,phone:e},!0);return x(t.errors),t.value?{email:t.value.email,phone:e}:(document.getElementById(`${u}-${t.errors.email?`email`:`phone`}`)?.focus(),null)}async function fe(e){if(!e)throw Error(`Check the contact fields below.`);if(!(s&&c&&t.payment))throw Error(`Payment details are still loading.`);let o=await i.load(t.slug);if(!H.current)return null;let l=o.items.find(e=>e.id===n.id);if(!l)return a(o,`This item is no longer available.`),null;let u=re(o,l,r);if(u||ie(t,o,n,l,r))return a(o,u??`The checkout details changed. Review them before continuing.`),null;let d=await oe({billing:w,collectShippingAddress:n.collectShippingAddress,elements:c,email:e.email,phone:e.phone,shipping:S?w:T,stripe:s});return H.current?{confirmationToken:d,email:e.email,includeServiceFee:r.includeServiceFee,phone:e.phone,...ae(Z)}:null}async function pe(e){let a=await i.createBid(t.slug,n.id,{...e,amount:r.amount});if(a.requiresAction){if(!(H.current&&s)){J(`bid`);return}await se(s,a)}K(`complete`),p(W.current.onResult,{amountCents:a.subtotalCents,kind:`bid`}),G.current||(G.current=!0,p(W.current.onBidSubmitted,a))}async function $(e,r){if(e.requiresAction){if(!(H.current&&s)){J(`purchase`);return}await se(s,e);let a=await i.getPurchaseStatus(t.slug,n.id,r.submission.clientRequestId);a?ue(a):(K(`pending`),q(`Payment status is not available yet. Check again shortly.`));return}ue(e),!H.current&&e.status===`pending_payment`&&J(`purchase`)}async function me(e){let r=await i.getPurchaseStatus(t.slug,n.id,e.submission.clientRequestId);if(r)await $(r,e);else{if(!H.current){J(`purchase`);return}K(`retry`),q(`No purchase is recorded yet. You can retry the original purchase with the same request ID.`)}}async function he(e,r){let a=await i.getPurchaseStatus(t.slug,n.id,r.submission.clientRequestId);if(a){await $(a,r);return}Q(null),K(`ready`),q(`The purchase was rejected. Review the item and payment details before trying again. (${e.status??`validation`})`)}async function ge(e,t,n,r){let i=t&&(!(e instanceof L)||e.recoveryRecommended);if(q(e instanceof Error?e.message:`Unable to complete this request.`),X&&n){if(!r&&e instanceof L&&!e.recoveryRecommended)try{await he(e,n);return}catch{}J(`purchase`)}else i?J(`bid`):K(`ready`)}function _e(){return z.current??=globalThis.crypto.randomUUID(),z.current}function ve(){return H.current?!0:(D||(Q(null),K(`ready`)),!1)}async function ye(e,r){if(r){await me(e);return}ve()&&await $(await i.createPurchase(t.slug,n.id,e.submission),e)}let be=s&&c&&le;function xe(){if(V.current||B)return null;if(!be)return q(`Payment details are still loading.`),null;let e=D?null:de();return D||e?{checkoutPayment:be,contact:e,retryOriginal:j===`retry`}:null}async function Se(e){e.preventDefault();let i=xe();if(!i)return;let{contact:a,checkoutPayment:o,retryOriginal:s}=i;V.current=!0,G.current=!1,K(`busy`),q(null);let c=!1,l=D;try{if(!l){let e=await fe(a);if(!(e&&H.current)){K(`ready`);return}if(!X){c=!0,await pe(e);return}l=Object.freeze({auctionId:t.id,item:n,itemId:n.id,payment:Object.freeze({...o}),pricing:Z,submission:Object.freeze({...e,clientRequestId:_e(),paymentMethodTypes:Object.freeze([`card`]),quantity:r.quantity})}),Q(l)}c=!0,await ye(l,!!D&&!s)}catch(e){await ge(e,c,l,D!==null&&!s)}finally{V.current=!1}}let Ce=ce(j,D!==null,X),we=j!==`ready`;return F(ne,{buttonText:Ce,communityName:e.communityName??t.name,contactErrors:b,email:d,id:u,includeServiceFee:r.includeServiceFee,isPurchase:X,isTerminal:B,item:n,locked:we,message:I,onBack:j===`ready`?o:void 0,onBillingChange:ee,onEmailChange:t=>{h(t),e.onContactChange?.({email:t,phone:f(g,v)})},onIncludeServiceFeeChange:e.onIncludeServiceFeeChange,onPaymentLoadError:()=>q(`Unable to load payment form.`),onPhoneChange:({value:t,country:n})=>{_(t),y(n),e.onContactChange?.({email:d,phone:f(t,n)})},onSameAsBillingChange:C,onShippingChange:E,onSubmit:Se,phone:g,phoneCountry:v,pricing:Z,quantity:r.quantity,sameAsBilling:S,serviceFeeCents:D?Z.serviceFeeCents:Y(t,n,{...r,includeServiceFee:t.serviceFeeEnabled}).serviceFeeCents,serviceFeeEnabled:t.serviceFeeEnabled,showFields:!(D||B),submitDisabled:j===`busy`||!s||!c})}const Z=6e3;function le(e,t){let n=M(Z),r=M(null),[i,a]=N(Z),o=j(()=>G({delay:i,playOnInit:!1,stopOnFocusIn:!1,stopOnInteraction:!0,stopOnMouseEnter:!1}),[i]),[s,c]=K({duration:t?0:25,loop:!0},[o]),l=O(()=>{r.current&&(r.current.style.transform=`scaleX(${1-n.current/Z})`)},[]),u=O(()=>{let e=o.timeUntilNext();e!==null&&(n.current=Math.max(1,Math.min(Z,e))),o.stop(),l()},[o,l]),d=O(()=>{n.current=Z,a(Z),o.reset(),l()},[o,l]);return k(()=>{c&&(e?i===n.current?o.play():a(n.current):u())},[c,e,o,i,a,n,u]),k(()=>{if(!c)return;let t=0,r=()=>{let i=o.timeUntilNext();!e||i===null||(n.current=Math.max(0,Math.min(Z,i)),l(),t=requestAnimationFrame(r))},i=()=>{cancelAnimationFrame(t),e&&(t=requestAnimationFrame(r))},a=()=>cancelAnimationFrame(t),s=()=>{e&&o.play()};return c.on(`select`,d).on(`reInit`,s).on(`autoplay:timerset`,i).on(`autoplay:timerstopped`,a),l(),i(),()=>{a(),c.off(`select`,d).off(`reInit`,s).off(`autoplay:timerset`,i).off(`autoplay:timerstopped`,a)}},[c,o,e,n,d,l]),{embla:c,freeze:u,progressRef:r,reset:d,viewportRef:s}}function Q({photos:e,name:t,selected:n,paused:i=!1,photoButtonRef:a,onSelect:o,onExpand:s}){let c=M(null),l=M(null),u=M([]),[d,f]=N(!0),[p,m]=N(!1),[h,g]=N(!1),[_,v]=N(!1),[y,S]=N(!1),{ref:C,visible:T}=r(),[E,D]=N(!1),[O,A]=N(!0),j=M(null),L=`lockerverse-auction-gallery__control ${O||E||h?`is-visible`:``}`,R=()=>{j.current&&clearTimeout(j.current),j.current=setTimeout(()=>D(!1),2e3)},z=e=>{if(e.pointerType!==`mouse`){A(!0);return}D(!0),j.current&&clearTimeout(j.current),e.target instanceof Element&&e.target.closest(`[data-gallery-control]`)||R()};k(()=>{let e=window.matchMedia(`(hover: none), (pointer: coarse)`),t=()=>A(e.matches);return t(),e.addEventListener(`change`,t),()=>{e.removeEventListener(`change`,t),clearTimeout(j.current??void 0)}},[]);let B=!(i||d||p||h||_||y)&&T,V=e.length,H=V?(n%V+V)%V:0,{viewportRef:te,embla:U,progressRef:W,freeze:G,reset:K}=le(B&&V>1,d);k(()=>{let e=window.matchMedia(`(prefers-reduced-motion: reduce)`),t=()=>f(e.matches);return t(),e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]),k(()=>{if(!U)return;let e=()=>o(U.selectedScrollSnap());return U.on(`select`,e).on(`reInit`,e),()=>{U.off(`select`,e).off(`reInit`,e)}},[U,o]),k(()=>{U&&U.selectedScrollSnap()!==H&&U.scrollTo(H,!0)},[U,H]),k(()=>{let e=()=>{document.hidden&&G()},t=()=>S(!1);return e(),document.addEventListener(`visibilitychange`,e,!0),window.addEventListener(`pointerup`,t),window.addEventListener(`pointercancel`,t),()=>{document.removeEventListener(`visibilitychange`,e,!0),window.removeEventListener(`pointerup`,t),window.removeEventListener(`pointercancel`,t)}},[G]);let q=e=>{U?.scrollTo((e+V)%V,d),K()};return k(()=>{let e=l.current;l.current=null,e&&document.activeElement===e&&C.current?.querySelector(`.lockerverse-auction-gallery__photo[tabindex="0"]`)?.focus({preventScroll:!0})},[H,C]),k(()=>{let e=c.current,t=u.current[H];if(!(e&&t))return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect();r.left<n.left?e.scrollLeft-=n.left-r.left:r.right>n.right&&(e.scrollLeft+=r.right-n.right)},[H,V]),I(`section`,{"aria-label":`${t} photos`,className:`lockerverse-auction-gallery`,onBlurCapture:e=>{e.currentTarget.contains(e.relatedTarget)||g(!1)},onFocusCapture:e=>g(e.target.matches(`:focus-visible`)),onKeyDown:e=>{V<2||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),e.target instanceof HTMLButtonElement&&e.target.classList.contains(`lockerverse-auction-gallery__photo`)&&(l.current=e.target),q(H+(e.key===`ArrowRight`?1:-1)))},onPointerEnter:e=>{e.pointerType===`mouse`&&m(!0)},onPointerLeave:e=>{e.pointerType===`mouse`&&m(!1)},ref:C,children:[V?I(`div`,{className:`lockerverse-auction-gallery__stage`,onPointerEnter:z,onPointerLeave:R,onPointerMove:z,children:[F(`div`,{className:`lockerverse-auction-gallery__viewport`,onPointerDownCapture:()=>{G(),S(!0)},ref:te,children:F(`div`,{className:`lockerverse-auction-gallery__track`,children:e.map((e,n)=>F(`div`,{"aria-hidden":n!==H,className:`lockerverse-auction-gallery__slide`,children:F(`button`,{"aria-label":`View photo ${n+1} of ${t} at full size`,className:`lockerverse-auction-gallery__photo`,onClick:()=>{s(n)},ref:n===H?a:void 0,tabIndex:n===H?0:-1,type:`button`,children:F(`img`,{alt:`${t}, ${n+1} of ${V}`,className:`lockerverse-auction-gallery__image`,draggable:!1,height:900,loading:n===0||n===H||n===(H+1)%V?`eager`:`lazy`,sizes:`(max-width: 1280px) 100vw, 45vw`,src:e,width:1200})})},`${e}-${n}`))})}),V>1&&!d&&I(`div`,{className:`lockerverse-auction-gallery__rotation`,children:[F(`div`,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__progress-track`,children:F(`div`,{className:`lockerverse-auction-gallery__progress`,ref:W,style:{transform:`scaleX(0)`}})}),F(`button`,{"aria-label":_?`Play photo rotation`:`Pause photo rotation`,className:`lockerverse-auction-gallery__play ${L}`,"data-gallery-control":!0,onClick:()=>v(e=>!e),title:_?`Play photo rotation`:`Pause photo rotation`,type:`button`,children:F(_?ee:w,{"aria-hidden":`true`,size:13})})]}),V>1&&I(P,{children:[F(`button`,{"aria-label":`Previous photo`,className:`lockerverse-auction-gallery__previous ${L}`,"data-gallery-control":!0,onClick:()=>q(H-1),type:`button`,children:F(b,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__chevron`})}),F(`button`,{"aria-label":`Next photo`,className:`lockerverse-auction-gallery__next ${L}`,"data-gallery-control":!0,onClick:()=>q(H+1),type:`button`,children:F(x,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__chevron`})})]})]}):F(`div`,{className:`lockerverse-auction-gallery__empty`,children:`No photo available`}),V>1&&F(`section`,{"aria-label":`Choose a photo`,className:`lockerverse-auction-gallery__strip`,ref:c,children:F(`div`,{className:`lockerverse-auction-gallery__thumbnails`,children:e.map((e,t)=>F(`button`,{"aria-label":`Show photo ${t+1} of ${V}`,"aria-pressed":H===t,className:`lockerverse-auction-gallery__thumbnail ${H===t?`is-selected`:``}`,onClick:()=>q(t),ref:e=>{u.current[t]=e},type:`button`,children:F(`img`,{alt:``,className:`lockerverse-auction-gallery__thumbnail-image`,height:66,sizes:`88px`,src:e,width:88})},`${e}-${t}`))})})]})}function ue({images:e,fallbackImage:t,name:n}){let r=[...new Set(e.filter(Boolean))];!r.length&&t&&r.push(t);let[i,a]=N(0),[o,s]=N(!1),c=M(null),l=M(null),u=r.length,d=u?(i%u+u)%u:0;return I(P,{children:[F(Q,{name:n,onExpand:e=>{a(e),s(!0)},onSelect:a,paused:o,photoButtonRef:c,photos:r,selected:d}),u>0&&F(W.Root,{onOpenChange:s,open:o,children:I(W.Portal,{children:[F(W.Backdrop,{className:`lockerverse-auction-gallery__backdrop`}),I(W.Popup,{"aria-describedby":void 0,className:`lockerverse-auction-gallery__viewer`,finalFocus:c,onKeyDown:e=>{u<2||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),a((d+(e.key===`ArrowRight`?1:-1)+u)%u))},children:[I(W.Title,{className:`lockerverse-auction-gallery__sr-only`,children:[n,` · Photo `,d+1,` of `,u]}),I(`div`,{className:`lockerverse-auction-gallery__full-image`,onTouchCancel:()=>{l.current=null},onTouchEnd:e=>{let t=l.current;l.current=null;let n=e.changedTouches.item(0);if(!(t&&n)||u<2)return;let r=n.clientX-t.x,i=n.clientY-t.y;Math.abs(r)>=45&&Math.abs(r)>Math.abs(i)*1.3&&a((d+(r<0?1:-1)+u)%u)},onTouchMove:e=>{e.touches.length!==1&&(l.current=null)},onTouchStart:e=>{let t=e.touches.item(0);l.current=e.touches.length===1&&t?{x:t.clientX,y:t.clientY}:null},children:[F(`img`,{alt:`${n}, ${d+1} of ${u}`,height:900,src:r[d],width:1200}),o&&u>1&&F(`img`,{alt:``,"aria-hidden":`true`,className:`lockerverse-auction-gallery__preload`,height:900,loading:`eager`,src:r[(d+1)%u],width:1200})]}),F(W.Close,{"aria-label":`Close photo viewer`,className:`lockerverse-auction-gallery__viewer-close`,children:F(D,{"aria-hidden":`true`,size:22})}),u>1&&I(P,{children:[F(`button`,{"aria-label":`Previous photo`,className:`lockerverse-auction-gallery__viewer-previous`,onClick:()=>a((d-1+u)%u),type:`button`,children:F(b,{"aria-hidden":`true`,size:28})}),F(`button`,{"aria-label":`Next photo`,className:`lockerverse-auction-gallery__viewer-next`,onClick:()=>a((d+1)%u),type:`button`,children:F(x,{"aria-hidden":`true`,size:28})})]})]})]})})]})}function de(e){return F(e===`Buy Now`?T:e===`Available`||e===`Increment`?E:C,{"aria-hidden":`true`,size:16})}function fe(e,t){return e.saleMode===`buy_now`?[[`Buy Now`,n(e.buyNowPriceAmount??0)],[`Available`,e.availableQuantity===null?`Available`:String(e.availableQuantity)]]:t===`finished`?[[`Final bid`,e.maxBidAmount?n(e.maxBidAmount):`No bids`]]:[[`Current bid`,n(e.maxBidAmount??0)],[`Floor`,n(e.minBidAmount??0)],[`Increment`,n(e.bidIncrementAmount??100)]]}function pe({auction:r,item:a}){o(a.startAt??r.startAt,a.endAt??r.endAt);let[s,c]=N(!1),l=A(),u=e(r,a),d={active:`Closes`,draft:`Opens`,finished:`Closed`}[u],f=i(r,u,a),p=a.saleMode===`buy_now`,m=(a.description??``).trim().length>240,h=fe(a,u);return I(`section`,{className:`lockerverse-auctions__item-summary`,children:[F(ue,{fallbackImage:a.image??r.configuration.image??r.community?.banner??r.community?.thumbnail??null,images:a.images,name:a.name}),I(`div`,{className:`lockerverse-auctions__item-copy`,children:[F(`h2`,{children:a.name}),a.description?I(`div`,{className:`lockerverse-auctions__item-description`,children:[F(t,{className:!s&&m?`lockerverse-auctions__description-clamped`:void 0,description:a.description,id:l}),m?I(`button`,{"aria-controls":l,"aria-expanded":s,className:`lockerverse-auctions__description-toggle`,onClick:()=>c(!s),type:`button`,children:[s?`Hide description`:`Read full description`,` `,F(y,{"aria-hidden":`true`,size:16,style:{transform:s?`rotate(180deg)`:void 0}})]}):null]}):null,I(`dl`,{className:`lockerverse-auctions__stat-panel`,children:[h.map(([e,t])=>I(`div`,{className:`lockerverse-auctions__stat-row`,children:[I(`dt`,{children:[de(e),e]}),F(`dd`,{children:t})]},e)),I(`div`,{className:`lockerverse-auctions__stat-row`,children:[I(`dt`,{children:[F(S,{"aria-hidden":`true`,size:16}),d]}),F(`dd`,{className:`lockerverse-auctions__stat-date`,children:f})]}),!p&&u===`finished`?I(`div`,{className:`lockerverse-auctions__stat-footer`,children:[I(`div`,{children:[F(`dt`,{children:`Floor`}),F(`dd`,{children:n(a.minBidAmount??0)})]}),I(`div`,{children:[F(`dt`,{children:`Bid increment`}),F(`dd`,{children:n(a.bidIncrementAmount??100)})]})]}):null]})]})]})}const $=/^\d+$/;function me(e,t){return $.test(e)&&Number.isSafeInteger(Number(e)*t)?`Total: ${n(Number(e)*t)}`:`Enter a whole-number quantity.`}function he(e,t,n){return String(e?t?t.quantity:1:t?t.amount/100:n)}function ge(e,t){return a(e)?`This item is sold out.`:t===`draft`?`This item is not open yet.`:t===`finished`?e.saleMode===`buy_now`?`Purchases are closed for this item.`:`Bidding is closed for this item.`:`This item is not available.`}function _e(e,t,n){return a(t)?`All available quantities have been purchased.`:n===`draft`?`This item opens ${i(e,`draft`,t)}.`:t.saleMode===`buy_now`?`This item is no longer available to purchase.`:`Bidding has closed for this item.`}function ve(e,t,n,r){return{amount:t?0:Number(r)*100,includeServiceFee:n?n.includeServiceFee:e.serviceFeeEnabled&&e.serviceFeeDefaultChecked,quantity:t?Number(r):1}}function ye({auction:t,item:r,initialSelection:i,onContinue:s,onError:c,onBack:l}){let u=r.saleMode===`buy_now`,d=Math.ceil(z(r)/100),[f,p]=N(he(u,i,d)),[m,h]=N(null),g=A();o(r.startAt??t.startAt,r.endAt??t.endAt);let _=e(t,r),y=_===`active`&&!a(r)&&r.saleMode!==`hybrid`;function b(e){if(e.preventDefault(),!$.test(f)){h(u?`Enter a whole-number quantity.`:`Enter a whole-dollar bid amount.`);return}let n=ve(t,u,i,f),a=re(t,r,n);if(a){h(a),c(a);return}try{Y(t,r,n)}catch{h(`Enter a valid amount or quantity.`);return}s(n)}return y?I(`form`,{className:`lockerverse-auctions__selection`,onSubmit:b,children:[F(be,{buyNow:u,item:r,minimum:d}),I(`div`,{className:`lockerverse-auctions__selection-body`,children:[I(`label`,{className:`lockerverse-auctions__field`,htmlFor:g,children:[u?`Quantity`:`Your bid amount`,I(`span`,{className:`lockerverse-auctions__amount-control`,children:[u?null:F(`span`,{"aria-hidden":`true`,children:`$`}),F(`input`,{"aria-describedby":`${g}-help`,"aria-invalid":!!m,autoComplete:`off`,id:g,inputMode:`numeric`,onChange:e=>{p(e.target.value),h(null)},placeholder:u?`1`:String(d),required:!0,value:f})]})]}),m?F(`p`,{role:`alert`,children:m}):null,F(`p`,{id:`${g}-help`,children:u?me(f,r.buyNowPriceAmount??0):`Enter a whole-dollar bid of at least ${n(d*100)}. Bid increment: ${n(r.bidIncrementAmount??100)}.`}),I(`div`,{className:`lockerverse-auctions__selection-footer`,children:[F(`p`,{children:u?`Continuing moves you into secure checkout where your payment is processed immediately.`:`Continuing moves you into the secure payment step where your card is stored for settlement only if your bid wins.`}),I(`button`,{className:`lockerverse-auctions__button`,disabled:!t.payment,type:`submit`,children:[u?`Continue to Checkout`:`Continue to Payment`,` `,F(v,{"aria-hidden":`true`,size:16})]})]}),t.payment?null:F(`p`,{role:`alert`,children:`Payments are not configured for this auction.`})]})]}):I(`div`,{className:`lockerverse-auctions__selection lockerverse-auctions__read-only`,children:[F(`p`,{className:`lockerverse-auctions__eyebrow`,children:`Item status`}),F(`h3`,{children:ge(r,_)}),F(`p`,{children:_e(t,r,_)}),l?I(`button`,{className:`lockerverse-auctions__button`,onClick:l,type:`button`,children:[`Browse auction items `,F(v,{"aria-hidden":`true`,size:16})]}):null]})}function be({item:e,buyNow:t,minimum:r}){return I(`div`,{className:`lockerverse-auctions__selection-header`,children:[F(`p`,{className:`lockerverse-auctions__eyebrow`,children:`Step 1 of 2`}),F(`h3`,{children:t?`Buy this item now.`:`Place your bid.`}),F(`p`,{children:t?`Choose how many you want, then complete the secure checkout.`:`Enter the bid amount you want to place for this item. You are only charged if this bid wins after bidding closes.`}),I(`p`,{children:[t?`Price: `:`Minimum qualifying bid: `,F(`strong`,{children:n(t?e.buyNowPriceAmount??0:r*100)})]}),t&&e.availableQuantity!==null?I(`p`,{children:[e.availableQuantity,` available`]}):null,e.collectShippingAddress?F(`p`,{children:`The next step will also collect a delivery address for seller fulfillment.`}):null]})}function xe(e){let{auction:t,item:n,selection:r,theme:i=`dark`,stripeLoader:a=g,style:o,onBack:s,resumePurchase:c}=e,[l,u]=N(null),[d,f]=N(!1),[p,m]=N(0),_=h(e.appearanceRoot,i,o,e.interactionLocked),v=c?.payment??t.payment;if(k(()=>{let e=!0;if(!v){f(!0);return}return Promise.resolve().then(()=>a(v.publishableKey,v.connectedAccountId?{stripeAccount:v.connectedAccountId}:void 0)).then(t=>{e&&(u(t),f(!t))},()=>{e&&f(!0)}),()=>{e=!1}},[v,a,p]),d)return I(`div`,{children:[F(`p`,{role:`alert`,children:`Payment details could not load.`}),c?null:F(`button`,{onClick:s,type:`button`,children:`Back to item`}),F(`button`,{onClick:()=>{f(!1),u(null),m(e=>e+1)},type:`button`,children:`Try again`})]});if(!(l&&_))return I(`div`,{children:[F(`p`,{role:`status`,children:`Loading secure payment details…`}),c?null:F(`button`,{onClick:s,type:`button`,children:`Back to item`})]});let y={mode:`setup`,setupFutureUsage:`off_session`};c?y={amount:c.pricing.totalCents,currency:`usd`,mode:`payment`}:n.saleMode===`buy_now`&&(y={amount:Y(t,n,r).totalCents,currency:`usd`,mode:`payment`});let b={...y,appearance:_,currency:`usd`,paymentMethodTypes:[`card`],syncAddressCheckbox:`none`};return F(V,{options:b,stripe:l,children:F(X,{...e})})}function Se({buyNow:e}){return I(`div`,{className:`lockerverse-auctions__progress`,children:[I(`span`,{children:[F(e?T:C,{"aria-hidden":`true`,size:16}),e?`Choose quantity`:`Place bid`]}),I(`span`,{children:[F(T,{"aria-hidden":`true`,size:16}),e?`Pay securely`:`Secure card`]}),I(`span`,{children:[F(E,{"aria-hidden":`true`,size:16}),e?`Get confirmation`:`Wait for close`]})]})}function Ce(e){let{auction:t,item:n,outcome:r}=e;return F(_,{auctionName:t.name,className:e.className,closesAtLabel:i(t,`active`,n),communityName:e.communityName??t.community?.name,focusHeading:!0,imageUrl:n.image??n.images[0]??t.configuration.image??void 0,itemName:n.name,outcome:r,primaryAction:e.onBack?{label:`View auction items`,onClick:e.onBack}:void 0,style:{"--lockerverse-accent":t.community?.color??`#6f8f6d`,...e.style},theme:e.theme})}function we(t){let{auction:n,itemId:r,resumePurchase:i,className:a,theme:s=`dark`,style:c}=t,l=M(null),[u,d]=N(n),f=M(n),m=u.items.find(e=>e.id===r)??i?.item;o(m?.startAt??u.startAt,m?.endAt??u.endAt);let[h,g]=N(()=>i?{amount:0,includeServiceFee:i.submission.includeServiceFee??!1,quantity:i.submission.quantity}:null),[_,y]=N(!!i),x=M(!0),S=M(t);S.current=t;let C=M(null),w=O(e=>{x.current&&y(e),C.current!==e&&(C.current=e,p(S.current.onInteractionLockChange,e))},[]),ee=!!i;k(()=>(x.current=!0,w(ee),()=>{x.current=!1}),[ee,w]);let[T,E]=N({email:``,phone:``}),[D,A]=N(!!i),[j,P]=N(null),[L,R]=N(null);k(()=>{!(D||_||i)&&f.current!==n&&(f.current=n,d(n))},[n,D,_,i]);function z(e,t){w(!1),f.current=S.current.auction,d(e),g(null),A(!1),P(t)}function B(e){P(null),g(e),A(!0)}return m?L?F(Ce,{...t,auction:u,item:m,outcome:L}):I(`section`,{className:[`lockerverse-auctions`,a].filter(Boolean).join(` `),"data-lockerverse-theme":s,ref:l,style:{"--lockerverse-accent":u.community?.color??`#6f8f6d`,...c},children:[t.onBack&&!_?I(`button`,{className:`lockerverse-auctions__back`,onClick:t.onBack,type:`button`,children:[F(b,{"aria-hidden":`true`,size:16}),` All items`]}):null,I(`div`,{className:`lockerverse-auctions__detail`,children:[F(pe,{auction:u,item:m}),I(`div`,{className:`lockerverse-auctions__transaction`,children:[e(u,m)===`active`?F(Se,{buyNow:m.saleMode===`buy_now`}):null,j?F(`p`,{className:`lockerverse-auctions__notice`,role:`alert`,children:j}):null,D&&h?F(xe,{...t,appearanceRoot:l,auction:u,communityName:t.communityName??u.community?.name,contact:T,interactionLocked:_,item:m,onBack:()=>A(!1),onContactChange:E,onIncludeServiceFeeChange:e=>g(t=>t&&{...t,includeServiceFee:u.serviceFeeEnabled&&e}),onInteractionLockChange:w,onResult:R,onReview:z,selection:h}):F(ye,{auction:u,initialSelection:h,item:m,onBack:t.onBack,onContinue:B,onError:P}),t.onBack&&!_?I(`button`,{className:`lockerverse-auctions__footer-back`,onClick:t.onBack,type:`button`,children:[`Back to auction items `,F(v,{"aria-hidden":`true`,size:16})]}):null]})]})]}):I(`div`,{children:[F(`p`,{role:`alert`,children:`This auction item is no longer available.`}),t.onBack?F(`button`,{onClick:t.onBack,type:`button`,children:`Back to auction items`}):null]})}function Te(e){let t=M({auctionId:e.auction.id,client:e.client,itemId:e.itemId});if(t.current.client!==e.client||t.current.auctionId!==e.auction.id||t.current.itemId!==e.itemId)throw TypeError(`Auction item identity cannot change. Remount with a new React key.`);if(e.resumePurchase&&(e.resumePurchase.auctionId!==e.auction.id||e.resumePurchase.itemId!==e.itemId||e.resumePurchase.item.id!==e.itemId||e.resumePurchase.item.auctionId!==e.auction.id))throw TypeError(`The purchase recovery record belongs to a different auction item.`);return F(we,{...e})}export{Te as LockerverseAuctionItem};
1
+ import{a as e,c as t,i as n,n as r,r as i,s as a,t as o}from"./use-auction-boundary.js";import{d as s,f as c,i as l,m as u,n as d,r as f,t as p}from"./host-callback.js";import{i as m,n as h,t as g}from"./stripe-loader.js";import{t as _}from"./auction-result2.js";import{ArrowRight as v,ChevronDown as y,ChevronLeft as b,ChevronRight as x,Clock3 as S,Gavel as C,Pause as w,Play as ee,ShieldCheck as T,TimerReset as E,X as D}from"lucide-react";import{useCallback as O,useEffect as k,useId as A,useMemo as j,useRef as M,useState as N}from"react";import{Fragment as P,jsx as F,jsxs as I}from"react/jsx-runtime";import{LockerverseSdkError as L,calculateLockerverseAuctionPricing as R,getLockerverseAuctionMinimumBid as z}from"@lockerverse/sdk/auctions";import{AddressElement as B,Elements as V,PaymentElement as H,useElements as te,useStripe as U}from"@stripe/react-stripe-js";import{Dialog as W}from"@base-ui/react/dialog";import G from"embla-carousel-autoplay";import K from"embla-carousel-react";function q(e){return{business:{name:`Lockerverse`},fields:{billingDetails:{address:`never`,email:`never`,name:`never`,phone:`never`}},terms:{applePay:e?`auto`:`never`,auBecsDebit:`never`,bancontact:`never`,card:`always`,cashapp:`never`,googlePay:`never`,ideal:`never`,paypal:e?`auto`:`never`,sepaDebit:`never`,sofort:`never`,usBankAccount:`never`},wallets:{applePay:e?`auto`:`never`,googlePay:`never`}}}function ne(e){let{isPurchase:t,item:r,pricing:i,id:a}=e;return I(`form`,{className:`lockerverse-auctions__checkout`,noValidate:!0,onSubmit:e.onSubmit,children:[I(`div`,{className:`lockerverse-auctions__checkout-header`,children:[I(`div`,{className:`lockerverse-auctions__checkout-navigation`,children:[F(`button`,{"aria-label":`Back`,className:`lockerverse-auctions__checkout-back`,disabled:!e.onBack,onClick:e.onBack,type:`button`,children:F(b,{"aria-hidden":`true`,size:20})}),I(`div`,{children:[F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:`Step 2 of 2`}),F(`p`,{children:t?`Secure checkout`:`Secure payment method`})]})]}),F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:e.communityName}),F(`h2`,{children:t?`Finalize your purchase.`:`Finalize your bid authorization.`}),F(`p`,{className:`lockerverse-auctions__checkout-summary`,children:t?I(P,{children:[`Pay `,F(`strong`,{children:n(i.totalCents)}),` for`,` `,e.quantity,` `,e.quantity===1?`item`:`items`,` of`,` `,F(`strong`,{children:r.name}),`. Your card is charged immediately once checkout succeeds.`]}):I(P,{children:[`Authorize a payment method for your bid of`,` `,F(`strong`,{children:n(i.subtotalCents)}),` on`,` `,F(`strong`,{children:r.name}),`. Your card is only charged if this bid wins the item.`]})}),r.collectShippingAddress&&I(`div`,{className:`lockerverse-auctions__checkout-physical`,children:[F(`p`,{className:`lockerverse-auctions__checkout-eyebrow`,children:`Physical item`}),F(`p`,{children:`This item requires a delivery address. Billing details are used by default, and you can switch to a separate delivery address below if needed.`})]})]}),I(`div`,{className:`lockerverse-auctions__checkout-body`,children:[e.showFields&&I(`fieldset`,{disabled:e.locked,children:[I(`div`,{className:`lockerverse-auctions__checkout-contact`,children:[F(c,{error:e.contactErrors.email,id:`${a}-email`,label:`Email`,name:`email`,onChange:t=>e.onEmailChange(t.target.value),required:!0,value:e.email}),F(u,{error:e.contactErrors.phone,id:`${a}-phone`,label:`Phone`,children:F(d,{country:e.phoneCountry,error:e.contactErrors.phone,errorId:`${a}-phone-error`,id:`${a}-phone`,name:`phone`,onChange:e.onPhoneChange,required:!0,value:e.phone})})]}),I(`section`,{"aria-label":`Payment Information`,className:`lockerverse-auctions__checkout-section`,children:[I(`div`,{className:`lockerverse-auctions__checkout-section-heading`,children:[F(`h3`,{children:`Payment Information`}),F(`p`,{children:t?`Processed securely and charged immediately for this purchase.`:`Stored securely and charged only if your bid finishes on top.`})]}),F(H,{onLoadError:e.onPaymentLoadError,options:q(t)})]}),I(`section`,{"aria-label":`Billing Details`,className:`lockerverse-auctions__checkout-section`,children:[F(`h3`,{children:`Billing Details`}),F(B,{onChange:e.onBillingChange,options:{mode:`billing`}}),F(`p`,{children:t?`Use your full name here. We use the email and phone above for purchase confirmation and fulfillment updates.`:`Use the bidder's full name here. We use the email and phone above to contact you if this bid is outbid or wins.`})]}),r.collectShippingAddress&&I(`section`,{"aria-label":`Delivery Details`,className:`lockerverse-auctions__checkout-section`,children:[I(`label`,{className:`lockerverse-auctions__checkout-checkbox lockerverse-auctions__checkout-delivery`,htmlFor:`${a}-delivery-same-as-billing`,children:[F(s,{checked:e.sameAsBilling,id:`${a}-delivery-same-as-billing`,onChange:t=>e.onSameAsBillingChange(t.target.checked)}),I(`span`,{children:[F(`strong`,{children:`Delivery address is the same as billing`}),F(`span`,{children:`Leave this on for the fastest flow. Turn it off only if the delivery address should differ from the billing details above.`})]})]}),!e.sameAsBilling&&I(P,{children:[F(`h3`,{children:`Delivery Address`}),F(B,{onChange:e.onShippingChange,options:{mode:`shipping`}})]})]}),e.serviceFeeEnabled&&F(J,{...e})]}),e.message&&F(`p`,{"aria-live":`polite`,className:`lockerverse-auctions__notice`,role:`status`,children:e.message}),!e.isTerminal&&I(`div`,{className:`lockerverse-auctions__checkout-footer`,children:[I(`p`,{children:[t?`By continuing, you agree to be charged for this purchase.`:`By continuing, you agree to have this payment method stored for item settlement if your bid is the winning offer.`,r.collectShippingAddress?` Your delivery details are stored with the ${t?`order`:`bid`} so the seller can fulfill the item after payment.`:``]}),I(`button`,{className:`lockerverse-auctions__button lockerverse-auctions__checkout-submit`,disabled:e.submitDisabled,type:`submit`,children:[e.buttonText,F(v,{"aria-hidden":`true`,size:16})]})]})]})]})}function J(e){let{isPurchase:t,pricing:r}=e;return F(`section`,{"aria-label":`Processing fees`,className:`lockerverse-auctions__checkout-section`,children:e.onIncludeServiceFeeChange?I(`label`,{className:`lockerverse-auctions__checkout-checkbox`,htmlFor:`${e.id}-service-fee`,children:[F(s,{checked:e.includeServiceFee,id:`${e.id}-service-fee`,onChange:t=>e.onIncludeServiceFeeChange?.(t.target.checked)}),I(`span`,{children:[I(`strong`,{children:[t?`Add`:`If I win, add`,` `,n(e.serviceFeeCents),` to help cover processing fees`]}),I(`span`,{children:[t?`Total`:`Total if I win`,`:`,` `,n(r.totalCents)]})]})]}):I(`p`,{children:[t?`Total`:`Total if I win`,`:`,` `,n(r.totalCents)]})})}function Y(e,t,n){return R(e,t.saleMode===`buy_now`?(t.buyNowPriceAmount??0)*n.quantity:n.amount,n.includeServiceFee)}function re(t,n,r){if(e(t,n)!==`active`)return`This item is not accepting bids or purchases.`;if(n.saleMode===`hybrid`)return`This item type is not supported for checkout.`;if(n.saleMode===`buy_now`){if(n.isSoldOut||n.availableQuantity===0)return`This item is sold out.`;if(!(n.buyNowPriceAmount&&Number.isSafeInteger(r.quantity))||r.quantity<1||n.availableQuantity!==null&&r.quantity>n.availableQuantity)return`Select an available quantity.`}else if(!Number.isSafeInteger(r.amount)||r.amount%100!=0||r.amount<z(n))return`Enter a whole-dollar bid at or above the minimum bid.`;return null}function ie(e,t,n,r,i){return e.payment?.publishableKey!==t.payment?.publishableKey||e.payment?.connectedAccountId!==t.payment?.connectedAccountId||e.serviceFeeEnabled!==t.serviceFeeEnabled||n.saleMode!==r.saleMode||n.collectShippingAddress!==r.collectShippingAddress||JSON.stringify(Y(e,n,i))!==JSON.stringify(Y(t,r,i))}function ae(e){return{expectedServiceFeeCents:e.serviceFeeCents,expectedSubtotalCents:e.subtotalCents,expectedTotalCents:e.totalCents}}async function oe({stripe:e,elements:t,email:n,phone:r,billing:i,shipping:a,collectShippingAddress:o}){if(!(i?.complete&&i.value.name.trim()))throw Error(`Complete your billing name and address.`);if(o&&!(a?.complete&&a.value.name.trim()))throw Error(`Complete your shipping name and address.`);let s=await t.submit();if(s.error)throw Error(s.error.message??`Check your payment details.`);let c=await e.createConfirmationToken({elements:t,params:{payment_method_data:{allow_redisplay:`always`,billing_details:{address:i.value.address,email:n,name:i.value.name,phone:r}},return_url:window.location.href,...o&&a?{shipping:{address:a.value.address,name:a.value.name,phone:r}}:void 0}});if(c.error||!c.confirmationToken)throw Error(c.error?.message??`Unable to prepare payment details.`);return c.confirmationToken.id}async function se(e,t){if(!t.requiresAction)return;if(!t.clientSecret)throw Error(`Payment confirmation is incomplete. Check its status before trying again.`);let n=await e.handleNextAction({clientSecret:t.clientSecret});if(n.error)throw Error(n.error.message??`Payment confirmation is incomplete.`)}function ce(e,t,n){return e===`busy`?n?`Processing...`:`Authorizing...`:e===`retry`?`Retry original purchase`:t?`Check purchase status`:n?`Buy Now`:`Authorize Bid`}function X(e){let{auction:t,item:n,selection:r,client:i,onReview:a,onBack:o}=e,s=U(),c=te(),u=A(),[d,h]=N(e.contact?.email??``),[g,_]=N(e.contact?.phone??``),[v,y]=N(()=>l(e.contact?.phone??``)),[b,x]=N({}),[S,C]=N(!0),[w,ee]=N(null),[T,E]=N(null),[D,O]=N(e.resumePurchase??null),[j,P]=N(e.resumePurchase?`pending`:`ready`),[I,R]=N(null),z=M(e.resumePurchase?.submission.clientRequestId??null),B=j===`complete`||j===`uncertain`,V=M(!1),H=M(!0),W=M(e);W.current=e;let G=M(!1);function K(e){H.current&&P(e),p(W.current.onInteractionLockChange,e!==`ready`&&e!==`complete`)}function q(e){H.current&&R(e)}function J(e){K(e===`bid`?`uncertain`:`pending`),q(e===`bid`?`We could not confirm your bid. Do not submit another bid until you check your email or contact the auction organizer.`:`We could not confirm the purchase result. Check its status using the same purchase request.`),G.current||(G.current=!0,p(W.current.onUncertain,e))}k(()=>(H.current=!0,()=>{H.current=!1}),[]);let X=!!(D??e.resumePurchase)||n.saleMode===`buy_now`,Z=D?.pricing??e.resumePurchase?.pricing??Y(t,n,r),le=D?.payment??e.resumePurchase?.payment??t.payment;function Q(e){H.current&&O(e),p(W.current.onPurchaseRecoveryChange,e)}function ue(e){e.status===`paid`?(z.current=null,Q(null),K(`complete`),p(W.current.onResult,{kind:`purchase`,purchaseId:e.purchaseId,quantity:e.quantity,serviceFeeCents:e.serviceFeeCents,status:`paid`,subtotalCents:e.subtotalCents,totalCents:e.totalCents,unitAmountCents:e.subtotalCents/e.quantity}),G.current||(G.current=!0,p(W.current.onPurchaseComplete,e))):e.status===`pending_payment`?(K(`pending`),q(`Your purchase is pending. Check its status before making another payment.`)):(z.current=null,Q(null),K(`ready`),q(`This purchase is ${e.status.replaceAll(`_`,` `)}. You can start a new purchase.`))}function de(){let e=f(g,v),t=m({email:d,phone:e},!0);return x(t.errors),t.value?{email:t.value.email,phone:e}:(document.getElementById(`${u}-${t.errors.email?`email`:`phone`}`)?.focus(),null)}async function fe(e){if(!e)throw Error(`Check the contact fields below.`);if(!(s&&c&&t.payment))throw Error(`Payment details are still loading.`);let o=await i.load(t.slug);if(!H.current)return null;let l=o.items.find(e=>e.id===n.id);if(!l)return a(o,`This item is no longer available.`),null;let u=re(o,l,r);if(u||ie(t,o,n,l,r))return a(o,u??`The checkout details changed. Review them before continuing.`),null;let d=await oe({billing:w,collectShippingAddress:n.collectShippingAddress,elements:c,email:e.email,phone:e.phone,shipping:S?w:T,stripe:s});return H.current?{confirmationToken:d,email:e.email,includeServiceFee:r.includeServiceFee,phone:e.phone,...ae(Z)}:null}async function pe(e){let a=await i.createBid(t.slug,n.id,{...e,amount:r.amount});if(a.requiresAction){if(!(H.current&&s)){J(`bid`);return}await se(s,a)}K(`complete`),p(W.current.onResult,{amountCents:a.subtotalCents,kind:`bid`}),G.current||(G.current=!0,p(W.current.onBidSubmitted,a))}async function $(e,r){if(e.requiresAction){if(!(H.current&&s)){J(`purchase`);return}await se(s,e);let a=await i.getPurchaseStatus(t.slug,n.id,r.submission.clientRequestId);a?ue(a):(K(`pending`),q(`Payment status is not available yet. Check again shortly.`));return}ue(e),!H.current&&e.status===`pending_payment`&&J(`purchase`)}async function me(e){let r=await i.getPurchaseStatus(t.slug,n.id,e.submission.clientRequestId);if(r)await $(r,e);else{if(!H.current){J(`purchase`);return}K(`retry`),q(`No purchase is recorded yet. You can retry the original purchase with the same request ID.`)}}async function he(e,r){let a=await i.getPurchaseStatus(t.slug,n.id,r.submission.clientRequestId);if(a){await $(a,r);return}Q(null),K(`ready`),q(`The purchase was rejected. Review the item and payment details before trying again. (${e.status??`validation`})`)}async function ge(e,t,n,r){let i=t&&(!(e instanceof L)||e.recoveryRecommended);if(q(e instanceof Error?e.message:`Unable to complete this request.`),X&&n){if(!r&&e instanceof L&&!e.recoveryRecommended)try{await he(e,n);return}catch{}J(`purchase`)}else i?J(`bid`):K(`ready`)}function _e(){return z.current??=globalThis.crypto.randomUUID(),z.current}function ve(){return H.current?!0:(D||(Q(null),K(`ready`)),!1)}async function ye(e,r){if(r){await me(e);return}ve()&&await $(await i.createPurchase(t.slug,n.id,e.submission),e)}let be=s&&c&&le;function xe(){if(V.current||B)return null;if(!be)return q(`Payment details are still loading.`),null;let e=D?null:de();return D||e?{checkoutPayment:be,contact:e,retryOriginal:j===`retry`}:null}async function Se(e){e.preventDefault();let i=xe();if(!i)return;let{contact:a,checkoutPayment:o,retryOriginal:s}=i;V.current=!0,G.current=!1,K(`busy`),q(null);let c=!1,l=D;try{if(!l){let e=await fe(a);if(!(e&&H.current)){K(`ready`);return}if(!X){c=!0,await pe(e);return}l=Object.freeze({auctionId:t.id,item:n,itemId:n.id,payment:Object.freeze({...o}),pricing:Z,submission:Object.freeze({...e,clientRequestId:_e(),paymentMethodTypes:Object.freeze([`card`]),quantity:r.quantity})}),Q(l)}c=!0,await ye(l,!!D&&!s)}catch(e){await ge(e,c,l,D!==null&&!s)}finally{V.current=!1}}let Ce=ce(j,D!==null,X),we=j!==`ready`;return F(ne,{buttonText:Ce,communityName:e.communityName??t.name,contactErrors:b,email:d,id:u,includeServiceFee:r.includeServiceFee,isPurchase:X,isTerminal:B,item:n,locked:we,message:I,onBack:j===`ready`?o:void 0,onBillingChange:ee,onEmailChange:t=>{h(t),e.onContactChange?.({email:t,phone:f(g,v)})},onIncludeServiceFeeChange:e.onIncludeServiceFeeChange,onPaymentLoadError:()=>q(`Unable to load payment form.`),onPhoneChange:({value:t,country:n})=>{_(t),y(n),e.onContactChange?.({email:d,phone:f(t,n)})},onSameAsBillingChange:C,onShippingChange:E,onSubmit:Se,phone:g,phoneCountry:v,pricing:Z,quantity:r.quantity,sameAsBilling:S,serviceFeeCents:D?Z.serviceFeeCents:Y(t,n,{...r,includeServiceFee:t.serviceFeeEnabled}).serviceFeeCents,serviceFeeEnabled:t.serviceFeeEnabled,showFields:!(D||B),submitDisabled:j===`busy`||!s||!c})}const Z=6e3;function le(e,t){let n=M(Z),r=M(null),[i,a]=N(Z),o=j(()=>G({delay:i,playOnInit:!1,stopOnFocusIn:!1,stopOnInteraction:!0,stopOnMouseEnter:!1}),[i]),[s,c]=K({duration:t?0:25,loop:!0},[o]),l=O(()=>{r.current&&(r.current.style.transform=`scaleX(${1-n.current/Z})`)},[]),u=O(()=>{let e=o.timeUntilNext();e!==null&&(n.current=Math.max(1,Math.min(Z,e))),o.stop(),l()},[o,l]),d=O(()=>{n.current=Z,a(Z),o.reset(),l()},[o,l]);return k(()=>{c&&(e?i===n.current?o.play():a(n.current):u())},[c,e,o,i,a,n,u]),k(()=>{if(!c)return;let t=0,r=()=>{let i=o.timeUntilNext();!e||i===null||(n.current=Math.max(0,Math.min(Z,i)),l(),t=requestAnimationFrame(r))},i=()=>{cancelAnimationFrame(t),e&&(t=requestAnimationFrame(r))},a=()=>cancelAnimationFrame(t),s=()=>{e&&o.play()};return c.on(`select`,d).on(`reInit`,s).on(`autoplay:timerset`,i).on(`autoplay:timerstopped`,a),l(),i(),()=>{a(),c.off(`select`,d).off(`reInit`,s).off(`autoplay:timerset`,i).off(`autoplay:timerstopped`,a)}},[c,o,e,n,d,l]),{embla:c,freeze:u,progressRef:r,reset:d,viewportRef:s}}function Q({photos:e,name:t,selected:n,paused:i=!1,photoButtonRef:a,onSelect:o,onExpand:s}){let c=M(null),l=M(null),u=M([]),[d,f]=N(!0),[p,m]=N(!1),[h,g]=N(!1),[_,v]=N(!1),[y,S]=N(!1),{ref:C,visible:T}=r(),[E,D]=N(!1),[O,A]=N(!0),j=M(null),L=`lockerverse-auction-gallery__control ${O||E||h?`is-visible`:``}`,R=()=>{j.current&&clearTimeout(j.current),j.current=setTimeout(()=>D(!1),2e3)},z=e=>{if(e.pointerType!==`mouse`){A(!0);return}D(!0),j.current&&clearTimeout(j.current),e.target instanceof Element&&e.target.closest(`[data-gallery-control]`)||R()};k(()=>{let e=window.matchMedia(`(hover: none), (pointer: coarse)`),t=()=>A(e.matches);return t(),e.addEventListener(`change`,t),()=>{e.removeEventListener(`change`,t),clearTimeout(j.current??void 0)}},[]);let B=!(i||d||p||h||_||y)&&T,V=e.length,H=V?(n%V+V)%V:0,{viewportRef:te,embla:U,progressRef:W,freeze:G,reset:K}=le(B&&V>1,d);k(()=>{let e=window.matchMedia(`(prefers-reduced-motion: reduce)`),t=()=>f(e.matches);return t(),e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]),k(()=>{if(!U)return;let e=()=>o(U.selectedScrollSnap());return U.on(`select`,e).on(`reInit`,e),()=>{U.off(`select`,e).off(`reInit`,e)}},[U,o]),k(()=>{U&&U.selectedScrollSnap()!==H&&U.scrollTo(H,!0)},[U,H]),k(()=>{let e=()=>{document.hidden&&G()},t=()=>S(!1);return e(),document.addEventListener(`visibilitychange`,e,!0),window.addEventListener(`pointerup`,t),window.addEventListener(`pointercancel`,t),()=>{document.removeEventListener(`visibilitychange`,e,!0),window.removeEventListener(`pointerup`,t),window.removeEventListener(`pointercancel`,t)}},[G]);let q=e=>{U?.scrollTo((e+V)%V,d),K()};return k(()=>{let e=l.current;l.current=null,e&&document.activeElement===e&&C.current?.querySelector(`.lockerverse-auction-gallery__photo[tabindex="0"]`)?.focus({preventScroll:!0})},[H,C]),k(()=>{let e=c.current,t=u.current[H];if(!(e&&t))return;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect();r.left<n.left?e.scrollLeft-=n.left-r.left:r.right>n.right&&(e.scrollLeft+=r.right-n.right)},[H,V]),I(`section`,{"aria-label":`${t} photos`,className:`lockerverse-auction-gallery`,onBlurCapture:e=>{e.currentTarget.contains(e.relatedTarget)||g(!1)},onFocusCapture:e=>g(e.target.matches(`:focus-visible`)),onKeyDown:e=>{V<2||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),e.target instanceof HTMLButtonElement&&e.target.classList.contains(`lockerverse-auction-gallery__photo`)&&(l.current=e.target),q(H+(e.key===`ArrowRight`?1:-1)))},onPointerEnter:e=>{e.pointerType===`mouse`&&m(!0)},onPointerLeave:e=>{e.pointerType===`mouse`&&m(!1)},ref:C,children:[V?I(`div`,{className:`lockerverse-auction-gallery__stage`,onPointerEnter:z,onPointerLeave:R,onPointerMove:z,children:[F(`div`,{className:`lockerverse-auction-gallery__viewport`,onPointerDownCapture:()=>{G(),S(!0)},ref:te,children:F(`div`,{className:`lockerverse-auction-gallery__track`,children:e.map((e,n)=>F(`div`,{"aria-hidden":n!==H,className:`lockerverse-auction-gallery__slide`,children:F(`button`,{"aria-label":`View photo ${n+1} of ${t} at full size`,className:`lockerverse-auction-gallery__photo`,onClick:()=>{s(n)},ref:n===H?a:void 0,tabIndex:n===H?0:-1,type:`button`,children:F(`img`,{alt:`${t}, ${n+1} of ${V}`,className:`lockerverse-auction-gallery__image`,draggable:!1,height:900,loading:n===0||n===H||n===(H+1)%V?`eager`:`lazy`,sizes:`(max-width: 1280px) 100vw, 45vw`,src:e,width:1200})})},`${e}-${n}`))})}),V>1&&!d&&I(`div`,{className:`lockerverse-auction-gallery__rotation`,children:[F(`div`,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__progress-track`,children:F(`div`,{className:`lockerverse-auction-gallery__progress`,ref:W,style:{transform:`scaleX(0)`}})}),F(`button`,{"aria-label":_?`Play photo rotation`:`Pause photo rotation`,className:`lockerverse-auction-gallery__play ${L}`,"data-gallery-control":!0,onClick:()=>v(e=>!e),title:_?`Play photo rotation`:`Pause photo rotation`,type:`button`,children:F(_?ee:w,{"aria-hidden":`true`,size:13})})]}),V>1&&I(P,{children:[F(`button`,{"aria-label":`Previous photo`,className:`lockerverse-auction-gallery__previous ${L}`,"data-gallery-control":!0,onClick:()=>q(H-1),type:`button`,children:F(b,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__chevron`})}),F(`button`,{"aria-label":`Next photo`,className:`lockerverse-auction-gallery__next ${L}`,"data-gallery-control":!0,onClick:()=>q(H+1),type:`button`,children:F(x,{"aria-hidden":`true`,className:`lockerverse-auction-gallery__chevron`})})]})]}):F(`div`,{className:`lockerverse-auction-gallery__empty`,children:`No photo available`}),V>1&&F(`section`,{"aria-label":`Choose a photo`,className:`lockerverse-auction-gallery__strip`,ref:c,children:F(`div`,{className:`lockerverse-auction-gallery__thumbnails`,children:e.map((e,t)=>F(`button`,{"aria-label":`Show photo ${t+1} of ${V}`,"aria-pressed":H===t,className:`lockerverse-auction-gallery__thumbnail ${H===t?`is-selected`:``}`,onClick:()=>q(t),ref:e=>{u.current[t]=e},type:`button`,children:F(`img`,{alt:``,className:`lockerverse-auction-gallery__thumbnail-image`,height:66,sizes:`88px`,src:e,width:88})},`${e}-${t}`))})})]})}function ue({images:e,fallbackImage:t,name:n}){let r=[...new Set(e.filter(Boolean))];!r.length&&t&&r.push(t);let[i,a]=N(0),[o,s]=N(!1),c=M(null),l=M(null),u=r.length,d=u?(i%u+u)%u:0;return I(P,{children:[F(Q,{name:n,onExpand:e=>{a(e),s(!0)},onSelect:a,paused:o,photoButtonRef:c,photos:r,selected:d}),u>0&&F(W.Root,{onOpenChange:s,open:o,children:I(W.Portal,{children:[F(W.Backdrop,{className:`lockerverse-auction-gallery__backdrop`}),I(W.Popup,{"aria-describedby":void 0,className:`lockerverse-auction-gallery__viewer`,finalFocus:c,onKeyDown:e=>{u<2||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),a((d+(e.key===`ArrowRight`?1:-1)+u)%u))},children:[I(W.Title,{className:`lockerverse-auction-gallery__sr-only`,children:[n,` · Photo `,d+1,` of `,u]}),I(`div`,{className:`lockerverse-auction-gallery__full-image`,onTouchCancel:()=>{l.current=null},onTouchEnd:e=>{let t=l.current;l.current=null;let n=e.changedTouches.item(0);if(!(t&&n)||u<2)return;let r=n.clientX-t.x,i=n.clientY-t.y;Math.abs(r)>=45&&Math.abs(r)>Math.abs(i)*1.3&&a((d+(r<0?1:-1)+u)%u)},onTouchMove:e=>{e.touches.length!==1&&(l.current=null)},onTouchStart:e=>{let t=e.touches.item(0);l.current=e.touches.length===1&&t?{x:t.clientX,y:t.clientY}:null},children:[F(`img`,{alt:`${n}, ${d+1} of ${u}`,height:900,src:r[d],width:1200}),o&&u>1&&F(`img`,{alt:``,"aria-hidden":`true`,className:`lockerverse-auction-gallery__preload`,height:900,loading:`eager`,src:r[(d+1)%u],width:1200})]}),F(W.Close,{"aria-label":`Close photo viewer`,className:`lockerverse-auction-gallery__viewer-close`,children:F(D,{"aria-hidden":`true`,size:22})}),u>1&&I(P,{children:[F(`button`,{"aria-label":`Previous photo`,className:`lockerverse-auction-gallery__viewer-previous`,onClick:()=>a((d-1+u)%u),type:`button`,children:F(b,{"aria-hidden":`true`,size:28})}),F(`button`,{"aria-label":`Next photo`,className:`lockerverse-auction-gallery__viewer-next`,onClick:()=>a((d+1)%u),type:`button`,children:F(x,{"aria-hidden":`true`,size:28})})]})]})]})})]})}function de(e){return F(e===`Buy Now`?T:e===`Available`||e===`Increment`?E:C,{"aria-hidden":`true`,size:16})}function fe(e,t){return e.saleMode===`buy_now`?[[`Buy Now`,n(e.buyNowPriceAmount??0)],[`Available`,e.availableQuantity===null?`Available`:String(e.availableQuantity)]]:t===`finished`?[[`Final bid`,e.maxBidAmount?n(e.maxBidAmount):`No bids`]]:[[`Current bid`,n(e.maxBidAmount??0)],[`Floor`,n(e.minBidAmount??0)],[`Increment`,n(e.bidIncrementAmount??100)]]}function pe({auction:r,item:a}){o(a.startAt??r.startAt,a.endAt??r.endAt);let[s,c]=N(!1),l=A(),u=e(r,a),d={active:`Closes`,draft:`Opens`,finished:`Closed`}[u],f=i(r,u,a),p=a.saleMode===`buy_now`,m=(a.description??``).trim().length>240,h=fe(a,u);return I(`section`,{className:`lockerverse-auctions__item-summary`,children:[F(ue,{fallbackImage:a.image??r.configuration.image??r.community?.banner??r.community?.thumbnail??null,images:a.images,name:a.name}),I(`div`,{className:`lockerverse-auctions__item-copy`,children:[F(`h2`,{children:a.name}),a.description?I(`div`,{className:`lockerverse-auctions__item-description`,children:[F(t,{className:!s&&m?`lockerverse-auctions__description-clamped`:void 0,description:a.description,id:l}),m?I(`button`,{"aria-controls":l,"aria-expanded":s,className:`lockerverse-auctions__description-toggle`,onClick:()=>c(!s),type:`button`,children:[s?`Hide description`:`Read full description`,` `,F(y,{"aria-hidden":`true`,size:16,style:{transform:s?`rotate(180deg)`:void 0}})]}):null]}):null,I(`dl`,{className:`lockerverse-auctions__stat-panel`,children:[h.map(([e,t])=>I(`div`,{className:`lockerverse-auctions__stat-row`,children:[I(`dt`,{children:[de(e),e]}),F(`dd`,{children:t})]},e)),I(`div`,{className:`lockerverse-auctions__stat-row`,children:[I(`dt`,{children:[F(S,{"aria-hidden":`true`,size:16}),d]}),F(`dd`,{className:`lockerverse-auctions__stat-date`,children:f})]}),!p&&u===`finished`?I(`div`,{className:`lockerverse-auctions__stat-footer`,children:[I(`div`,{children:[F(`dt`,{children:`Floor`}),F(`dd`,{children:n(a.minBidAmount??0)})]}),I(`div`,{children:[F(`dt`,{children:`Bid increment`}),F(`dd`,{children:n(a.bidIncrementAmount??100)})]})]}):null]})]})]})}const $=/^\d+$/;function me(e,t){return $.test(e)&&Number.isSafeInteger(Number(e)*t)?`Total: ${n(Number(e)*t)}`:`Enter a whole-number quantity.`}function he(e,t,n){return String(e?t?t.quantity:1:t?t.amount/100:n)}function ge(e,t){return a(e)?`This item is sold out.`:t===`draft`?`This item is not open yet.`:t===`finished`?e.saleMode===`buy_now`?`Purchases are closed for this item.`:`Bidding is closed for this item.`:`This item is not available.`}function _e(e,t,n){return a(t)?`All available quantities have been purchased.`:n===`draft`?`This item opens ${i(e,`draft`,t)}.`:t.saleMode===`buy_now`?`This item is no longer available to purchase.`:`Bidding has closed for this item.`}function ve(e,t,n,r){return{amount:t?0:Number(r)*100,includeServiceFee:n?n.includeServiceFee:e.serviceFeeEnabled&&e.serviceFeeDefaultChecked,quantity:t?Number(r):1}}function ye({auction:t,item:r,initialSelection:i,onContinue:s,onError:c,onBack:l}){let u=r.saleMode===`buy_now`,d=Math.ceil(z(r)/100),[f,p]=N(he(u,i,d)),[m,h]=N(null),g=A();o(r.startAt??t.startAt,r.endAt??t.endAt);let _=e(t,r),y=_===`active`&&!a(r)&&r.saleMode!==`hybrid`;function b(e){if(e.preventDefault(),!$.test(f)){h(u?`Enter a whole-number quantity.`:`Enter a whole-dollar bid amount.`);return}let n=ve(t,u,i,f),a=re(t,r,n);if(a){h(a),c(a);return}try{Y(t,r,n)}catch{h(`Enter a valid amount or quantity.`);return}s(n)}return y?I(`form`,{className:`lockerverse-auctions__selection`,onSubmit:b,children:[F(be,{buyNow:u,item:r,minimum:d}),I(`div`,{className:`lockerverse-auctions__selection-body`,children:[I(`label`,{className:`lockerverse-auctions__field`,htmlFor:g,children:[u?`Quantity`:`Your bid amount`,I(`span`,{className:`lockerverse-auctions__amount-control`,children:[u?null:F(`span`,{"aria-hidden":`true`,children:`$`}),F(`input`,{"aria-describedby":`${g}-help`,"aria-invalid":!!m,autoComplete:`off`,id:g,inputMode:`numeric`,onChange:e=>{p(e.target.value),h(null)},placeholder:u?`1`:String(d),required:!0,value:f})]})]}),m?F(`p`,{role:`alert`,children:m}):null,F(`p`,{id:`${g}-help`,children:u?me(f,r.buyNowPriceAmount??0):`Enter a whole-dollar bid of at least ${n(d*100)}. Bid increment: ${n(r.bidIncrementAmount??100)}.`}),I(`div`,{className:`lockerverse-auctions__selection-footer`,children:[F(`p`,{children:u?`Continuing moves you into secure checkout where your payment is processed immediately.`:`Continuing moves you into the secure payment step where your card is stored for settlement only if your bid wins.`}),I(`button`,{className:`lockerverse-auctions__button`,disabled:!t.payment,type:`submit`,children:[u?`Continue to Checkout`:`Continue to Payment`,` `,F(v,{"aria-hidden":`true`,size:16})]})]}),t.payment?null:F(`p`,{role:`alert`,children:`Payments are not configured for this auction.`})]})]}):I(`div`,{className:`lockerverse-auctions__selection lockerverse-auctions__read-only`,children:[F(`p`,{className:`lockerverse-auctions__eyebrow`,children:`Item status`}),F(`h3`,{children:ge(r,_)}),F(`p`,{children:_e(t,r,_)}),l?I(`button`,{className:`lockerverse-auctions__button`,onClick:l,type:`button`,children:[`Browse auction items `,F(v,{"aria-hidden":`true`,size:16})]}):null]})}function be({item:e,buyNow:t,minimum:r}){return I(`div`,{className:`lockerverse-auctions__selection-header`,children:[F(`p`,{className:`lockerverse-auctions__eyebrow`,children:`Step 1 of 2`}),F(`h3`,{children:t?`Buy this item now.`:`Place your bid.`}),F(`p`,{children:t?`Choose how many you want, then complete the secure checkout.`:`Enter the bid amount you want to place for this item. You are only charged if this bid wins after bidding closes.`}),I(`p`,{children:[t?`Price: `:`Minimum qualifying bid: `,F(`strong`,{children:n(t?e.buyNowPriceAmount??0:r*100)})]}),t&&e.availableQuantity!==null?I(`p`,{children:[e.availableQuantity,` available`]}):null,e.collectShippingAddress?F(`p`,{children:`The next step will also collect a delivery address for seller fulfillment.`}):null]})}function xe(e){let{auction:t,item:n,selection:r,theme:i=`dark`,stripeLoader:a=g,style:o,onBack:s,resumePurchase:c}=e,[l,u]=N(null),[d,f]=N(!1),[p,m]=N(0),_=h(e.appearanceRoot,i,o,e.interactionLocked),v=c?.payment??t.payment;if(k(()=>{let e=!0;if(!v){f(!0);return}return Promise.resolve().then(()=>a(v.publishableKey,v.connectedAccountId?{stripeAccount:v.connectedAccountId}:void 0)).then(t=>{e&&(u(t),f(!t))},()=>{e&&f(!0)}),()=>{e=!1}},[v,a,p]),d)return I(`div`,{children:[F(`p`,{role:`alert`,children:`Payment details could not load.`}),c?null:F(`button`,{onClick:s,type:`button`,children:`Back to item`}),F(`button`,{onClick:()=>{f(!1),u(null),m(e=>e+1)},type:`button`,children:`Try again`})]});if(!(l&&_))return I(`div`,{children:[F(`p`,{role:`status`,children:`Loading secure payment details…`}),c?null:F(`button`,{onClick:s,type:`button`,children:`Back to item`})]});let y={mode:`setup`,setupFutureUsage:`off_session`};c?y={amount:c.pricing.totalCents,currency:`usd`,mode:`payment`}:n.saleMode===`buy_now`&&(y={amount:Y(t,n,r).totalCents,currency:`usd`,mode:`payment`});let b={...y,appearance:_,currency:`usd`,paymentMethodTypes:[`card`],syncAddressCheckbox:`none`};return F(V,{options:b,stripe:l,children:F(X,{...e})})}function Se({buyNow:e}){return I(`div`,{className:`lockerverse-auctions__progress`,children:[I(`span`,{children:[F(e?T:C,{"aria-hidden":`true`,size:16}),e?`Choose quantity`:`Place bid`]}),I(`span`,{children:[F(T,{"aria-hidden":`true`,size:16}),e?`Pay securely`:`Secure card`]}),I(`span`,{children:[F(E,{"aria-hidden":`true`,size:16}),e?`Get confirmation`:`Wait for close`]})]})}function Ce(e){let{auction:t,item:n,outcome:r}=e,a=e.onBack?{label:`View auction items`,onClick:e.onBack}:void 0;return F(_,{auctionName:t.name,className:e.className,closesAtLabel:i(t,`active`,n),communityName:e.communityName??t.community?.name,focusHeading:!0,imageUrl:n.image??n.images[0]??t.configuration.image??void 0,itemName:n.name,outcome:r,primaryAction:e.returnToItemHref?{href:e.returnToItemHref,label:`Return to item`}:a,secondaryAction:e.returnToItemHref?a:void 0,style:{"--lockerverse-accent":t.community?.color??`#6f8f6d`,...e.style},theme:e.theme})}function we(t){let{auction:n,itemId:r,resumePurchase:i,className:a,theme:s=`dark`,style:c}=t,l=M(null),[u,d]=N(n),f=M(n),m=u.items.find(e=>e.id===r)??i?.item;o(m?.startAt??u.startAt,m?.endAt??u.endAt);let[h,g]=N(()=>i?{amount:0,includeServiceFee:i.submission.includeServiceFee??!1,quantity:i.submission.quantity}:null),[_,y]=N(!!i),x=M(!0),S=M(t);S.current=t;let C=M(null),w=O(e=>{x.current&&y(e),C.current!==e&&(C.current=e,p(S.current.onInteractionLockChange,e))},[]),ee=!!i;k(()=>(x.current=!0,w(ee),()=>{x.current=!1}),[ee,w]);let[T,E]=N({email:``,phone:``}),[D,A]=N(!!i),[j,P]=N(null),[L,R]=N(null);k(()=>{!(D||_||i)&&f.current!==n&&(f.current=n,d(n))},[n,D,_,i]);function z(e,t){w(!1),f.current=S.current.auction,d(e),g(null),A(!1),P(t)}function B(e){P(null),g(e),A(!0)}return m?L?F(Ce,{...t,auction:u,item:m,outcome:L}):I(`section`,{className:[`lockerverse-auctions`,a].filter(Boolean).join(` `),"data-lockerverse-theme":s,ref:l,style:{"--lockerverse-accent":u.community?.color??`#6f8f6d`,...c},children:[t.onBack&&!_?I(`button`,{className:`lockerverse-auctions__back`,onClick:t.onBack,type:`button`,children:[F(b,{"aria-hidden":`true`,size:16}),` All items`]}):null,I(`div`,{className:`lockerverse-auctions__detail`,children:[F(pe,{auction:u,item:m}),I(`div`,{className:`lockerverse-auctions__transaction`,children:[e(u,m)===`active`?F(Se,{buyNow:m.saleMode===`buy_now`}):null,j?F(`p`,{className:`lockerverse-auctions__notice`,role:`alert`,children:j}):null,D&&h?F(xe,{...t,appearanceRoot:l,auction:u,communityName:t.communityName??u.community?.name,contact:T,interactionLocked:_,item:m,onBack:()=>A(!1),onContactChange:E,onIncludeServiceFeeChange:e=>g(t=>t&&{...t,includeServiceFee:u.serviceFeeEnabled&&e}),onInteractionLockChange:w,onResult:R,onReview:z,selection:h}):F(ye,{auction:u,initialSelection:h,item:m,onBack:t.onBack,onContinue:B,onError:P}),t.onBack&&!_?I(`button`,{className:`lockerverse-auctions__footer-back`,onClick:t.onBack,type:`button`,children:[`Back to auction items `,F(v,{"aria-hidden":`true`,size:16})]}):null]})]})]}):I(`div`,{children:[F(`p`,{role:`alert`,children:`This auction item is no longer available.`}),t.onBack?F(`button`,{onClick:t.onBack,type:`button`,children:`Back to auction items`}):null]})}function Te(e){let t=M({auctionId:e.auction.id,client:e.client,itemId:e.itemId});if(t.current.client!==e.client||t.current.auctionId!==e.auction.id||t.current.itemId!==e.itemId)throw TypeError(`Auction item identity cannot change. Remount with a new React key.`);if(e.resumePurchase&&(e.resumePurchase.auctionId!==e.auction.id||e.resumePurchase.itemId!==e.itemId||e.resumePurchase.item.id!==e.itemId||e.resumePurchase.item.auctionId!==e.auction.id))throw TypeError(`The purchase recovery record belongs to a different auction item.`);return F(we,{...e})}export{Te as LockerverseAuctionItem};
2
2
  //# sourceMappingURL=auction-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auction-item.js","names":["formatMoney","Close","formatMoney","formatMoney"],"sources":["../src/auction-checkout-view.tsx","../src/auction-payment.ts","../src/auction-checkout.tsx","../src/use-auction-autoplay.ts","../src/auction-photo-filmstrip.tsx","../src/auction-gallery.tsx","../src/auction-item-details.tsx","../src/auction-item-selection.tsx","../src/lockerverse-auction-item.tsx"],"sourcesContent":["import type {\n LockerverseAuctionItem,\n LockerverseAuctionPricing,\n} from \"@lockerverse/sdk/auctions\";\nimport { AddressElement, PaymentElement } from \"@stripe/react-stripe-js\";\nimport type {\n StripeAddressElementChangeEvent,\n StripePaymentElementOptions,\n} from \"@stripe/stripe-js\";\nimport { ArrowRight, ChevronLeft } from \"lucide-react\";\nimport type { FormEventHandler } from \"react\";\nimport { formatAuctionMoney as formatMoney } from \"./auction-display.ts\";\nimport { Checkbox, EmailField, FormField } from \"./form-field.tsx\";\nimport type { PhoneInputValue } from \"./phone-field.tsx\";\nimport { PhoneInput } from \"./phone-field.tsx\";\n\ntype AuctionCheckoutViewProps = {\n buttonText: string;\n communityName: string;\n email: string;\n contactErrors: { email?: string; phone?: string };\n phoneCountry: string;\n id: string;\n includeServiceFee: boolean;\n isPurchase: boolean;\n isTerminal: boolean;\n item: LockerverseAuctionItem;\n locked: boolean;\n message: string | null;\n onBack?: (() => void) | undefined;\n onBillingChange: (event: StripeAddressElementChangeEvent) => void;\n onEmailChange: (value: string) => void;\n onIncludeServiceFeeChange?: ((value: boolean) => void) | undefined;\n onPaymentLoadError: () => void;\n onPhoneChange: (value: PhoneInputValue) => void;\n onSameAsBillingChange: (value: boolean) => void;\n onShippingChange: (event: StripeAddressElementChangeEvent) => void;\n onSubmit: FormEventHandler<HTMLFormElement>;\n phone: string;\n pricing: LockerverseAuctionPricing;\n quantity: number;\n sameAsBilling: boolean;\n serviceFeeCents: number;\n serviceFeeEnabled: boolean;\n showFields: boolean;\n submitDisabled: boolean;\n};\n\nfunction getPaymentOptions(isPurchase: boolean): StripePaymentElementOptions {\n return {\n business: { name: \"Lockerverse\" },\n fields: {\n billingDetails: {\n address: \"never\",\n email: \"never\",\n name: \"never\",\n phone: \"never\",\n },\n },\n terms: {\n applePay: isPurchase ? \"auto\" : \"never\",\n auBecsDebit: \"never\",\n bancontact: \"never\",\n card: \"always\",\n cashapp: \"never\",\n googlePay: \"never\",\n ideal: \"never\",\n paypal: isPurchase ? \"auto\" : \"never\",\n sepaDebit: \"never\",\n sofort: \"never\",\n usBankAccount: \"never\",\n },\n wallets: { applePay: isPurchase ? \"auto\" : \"never\", googlePay: \"never\" },\n };\n}\n\nexport function AuctionCheckoutView(props: AuctionCheckoutViewProps) {\n const { isPurchase, item, pricing, id } = props;\n return (\n <form\n className=\"lockerverse-auctions__checkout\"\n noValidate\n onSubmit={props.onSubmit}\n >\n <div className=\"lockerverse-auctions__checkout-header\">\n <div className=\"lockerverse-auctions__checkout-navigation\">\n <button\n aria-label=\"Back\"\n className=\"lockerverse-auctions__checkout-back\"\n disabled={!props.onBack}\n onClick={props.onBack}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={20} />\n </button>\n <div>\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n Step 2 of 2\n </p>\n <p>{isPurchase ? \"Secure checkout\" : \"Secure payment method\"}</p>\n </div>\n </div>\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n {props.communityName}\n </p>\n <h2>\n {isPurchase\n ? \"Finalize your purchase.\"\n : \"Finalize your bid authorization.\"}\n </h2>\n <p className=\"lockerverse-auctions__checkout-summary\">\n {isPurchase ? (\n <>\n Pay <strong>{formatMoney(pricing.totalCents)}</strong> for{\" \"}\n {props.quantity} {props.quantity === 1 ? \"item\" : \"items\"} of{\" \"}\n <strong>{item.name}</strong>. Your card is charged immediately\n once checkout succeeds.\n </>\n ) : (\n <>\n Authorize a payment method for your bid of{\" \"}\n <strong>{formatMoney(pricing.subtotalCents)}</strong> on{\" \"}\n <strong>{item.name}</strong>. Your card is only charged if this\n bid wins the item.\n </>\n )}\n </p>\n {item.collectShippingAddress && (\n <div className=\"lockerverse-auctions__checkout-physical\">\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n Physical item\n </p>\n <p>\n This item requires a delivery address. Billing details are used by\n default, and you can switch to a separate delivery address below\n if needed.\n </p>\n </div>\n )}\n </div>\n <div className=\"lockerverse-auctions__checkout-body\">\n {props.showFields && (\n <fieldset disabled={props.locked}>\n <div className=\"lockerverse-auctions__checkout-contact\">\n <EmailField\n error={props.contactErrors.email}\n id={`${id}-email`}\n label=\"Email\"\n name=\"email\"\n onChange={(event) => props.onEmailChange(event.target.value)}\n required\n value={props.email}\n />\n <FormField\n error={props.contactErrors.phone}\n id={`${id}-phone`}\n label=\"Phone\"\n >\n <PhoneInput\n country={props.phoneCountry}\n error={props.contactErrors.phone}\n errorId={`${id}-phone-error`}\n id={`${id}-phone`}\n name=\"phone\"\n onChange={props.onPhoneChange}\n required\n value={props.phone}\n />\n </FormField>\n </div>\n <section\n aria-label=\"Payment Information\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <div className=\"lockerverse-auctions__checkout-section-heading\">\n <h3>Payment Information</h3>\n <p>\n {isPurchase\n ? \"Processed securely and charged immediately for this purchase.\"\n : \"Stored securely and charged only if your bid finishes on top.\"}\n </p>\n </div>\n <PaymentElement\n onLoadError={props.onPaymentLoadError}\n options={getPaymentOptions(isPurchase)}\n />\n </section>\n <section\n aria-label=\"Billing Details\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <h3>Billing Details</h3>\n <AddressElement\n onChange={props.onBillingChange}\n options={{ mode: \"billing\" }}\n />\n <p>\n {isPurchase\n ? \"Use your full name here. We use the email and phone above for purchase confirmation and fulfillment updates.\"\n : \"Use the bidder's full name here. We use the email and phone above to contact you if this bid is outbid or wins.\"}\n </p>\n </section>\n {item.collectShippingAddress && (\n <section\n aria-label=\"Delivery Details\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <label\n className=\"lockerverse-auctions__checkout-checkbox lockerverse-auctions__checkout-delivery\"\n htmlFor={`${id}-delivery-same-as-billing`}\n >\n <Checkbox\n checked={props.sameAsBilling}\n id={`${id}-delivery-same-as-billing`}\n onChange={(event) =>\n props.onSameAsBillingChange(event.target.checked)\n }\n />\n <span>\n <strong>Delivery address is the same as billing</strong>\n <span>\n Leave this on for the fastest flow. Turn it off only if\n the delivery address should differ from the billing\n details above.\n </span>\n </span>\n </label>\n {!props.sameAsBilling && (\n <>\n <h3>Delivery Address</h3>\n <AddressElement\n onChange={props.onShippingChange}\n options={{ mode: \"shipping\" }}\n />\n </>\n )}\n </section>\n )}\n {props.serviceFeeEnabled && <CheckoutServiceFee {...props} />}\n </fieldset>\n )}\n {props.message && (\n <p\n aria-live=\"polite\"\n className=\"lockerverse-auctions__notice\"\n role=\"status\"\n >\n {props.message}\n </p>\n )}\n {!props.isTerminal && (\n <div className=\"lockerverse-auctions__checkout-footer\">\n <p>\n {isPurchase\n ? \"By continuing, you agree to be charged for this purchase.\"\n : \"By continuing, you agree to have this payment method stored for item settlement if your bid is the winning offer.\"}\n {item.collectShippingAddress\n ? ` Your delivery details are stored with the ${isPurchase ? \"order\" : \"bid\"} so the seller can fulfill the item after payment.`\n : \"\"}\n </p>\n <button\n className=\"lockerverse-auctions__button lockerverse-auctions__checkout-submit\"\n disabled={props.submitDisabled}\n type=\"submit\"\n >\n {props.buttonText}\n <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n </div>\n )}\n </div>\n </form>\n );\n}\n\nfunction CheckoutServiceFee(props: AuctionCheckoutViewProps) {\n const { isPurchase, pricing } = props;\n return (\n <section\n aria-label=\"Processing fees\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n {props.onIncludeServiceFeeChange ? (\n <label\n className=\"lockerverse-auctions__checkout-checkbox\"\n htmlFor={`${props.id}-service-fee`}\n >\n <Checkbox\n checked={props.includeServiceFee}\n id={`${props.id}-service-fee`}\n onChange={(event) =>\n props.onIncludeServiceFeeChange?.(event.target.checked)\n }\n />\n <span>\n <strong>\n {isPurchase ? \"Add\" : \"If I win, add\"}{\" \"}\n {formatMoney(props.serviceFeeCents)} to help cover processing fees\n </strong>\n <span>\n {isPurchase ? \"Total\" : \"Total if I win\"}:{\" \"}\n {formatMoney(pricing.totalCents)}\n </span>\n </span>\n </label>\n ) : (\n <p>\n {isPurchase ? \"Total\" : \"Total if I win\"}:{\" \"}\n {formatMoney(pricing.totalCents)}\n </p>\n )}\n </section>\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionBidResult,\n LockerverseAuctionItem,\n LockerverseAuctionPricing,\n} from \"@lockerverse/sdk/auctions\";\nimport {\n calculateLockerverseAuctionPricing,\n getLockerverseAuctionMinimumBid,\n} from \"@lockerverse/sdk/auctions\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport { getAuctionDisplayStatus } from \"./auction-display.ts\";\n\nexport type AuctionSelection = {\n amount: number;\n quantity: number;\n includeServiceFee: boolean;\n};\n\nexport function getAuctionSelectionPricing(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n return calculateLockerverseAuctionPricing(\n auction,\n item.saleMode === \"buy_now\"\n ? (item.buyNowPriceAmount ?? 0) * selection.quantity\n : selection.amount,\n selection.includeServiceFee\n );\n}\n\nexport function getAuctionSelectionError(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n if (getAuctionDisplayStatus(auction, item) !== \"active\") {\n return \"This item is not accepting bids or purchases.\";\n }\n if (item.saleMode === \"hybrid\") {\n return \"This item type is not supported for checkout.\";\n }\n if (item.saleMode === \"buy_now\") {\n if (item.isSoldOut || item.availableQuantity === 0) {\n return \"This item is sold out.\";\n }\n if (\n !(item.buyNowPriceAmount && Number.isSafeInteger(selection.quantity)) ||\n selection.quantity < 1 ||\n (item.availableQuantity !== null &&\n selection.quantity > item.availableQuantity)\n ) {\n return \"Select an available quantity.\";\n }\n } else if (\n !Number.isSafeInteger(selection.amount) ||\n selection.amount % 100 !== 0 ||\n selection.amount < getLockerverseAuctionMinimumBid(item)\n ) {\n return \"Enter a whole-dollar bid at or above the minimum bid.\";\n }\n return null;\n}\n\nexport function hasAuctionCheckoutChanged(\n previous: LockerverseAuction,\n current: LockerverseAuction,\n item: LockerverseAuctionItem,\n nextItem: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n return (\n previous.payment?.publishableKey !== current.payment?.publishableKey ||\n previous.payment?.connectedAccountId !==\n current.payment?.connectedAccountId ||\n previous.serviceFeeEnabled !== current.serviceFeeEnabled ||\n item.saleMode !== nextItem.saleMode ||\n item.collectShippingAddress !== nextItem.collectShippingAddress ||\n JSON.stringify(getAuctionSelectionPricing(previous, item, selection)) !==\n JSON.stringify(getAuctionSelectionPricing(current, nextItem, selection))\n );\n}\n\nexport function auctionExpectedPricing(pricing: LockerverseAuctionPricing) {\n return {\n expectedServiceFeeCents: pricing.serviceFeeCents,\n expectedSubtotalCents: pricing.subtotalCents,\n expectedTotalCents: pricing.totalCents,\n };\n}\n\nexport async function createAuctionConfirmationToken({\n stripe,\n elements,\n email,\n phone,\n billing,\n shipping,\n collectShippingAddress,\n}: {\n stripe: Stripe;\n elements: StripeElements;\n email: string;\n phone: string;\n billing: StripeAddressElementChangeEvent | null;\n shipping: StripeAddressElementChangeEvent | null;\n collectShippingAddress: boolean;\n}) {\n if (!(billing?.complete && billing.value.name.trim())) {\n throw new Error(\"Complete your billing name and address.\");\n }\n if (\n collectShippingAddress &&\n !(shipping?.complete && shipping.value.name.trim())\n ) {\n throw new Error(\"Complete your shipping name and address.\");\n }\n const submitted = await elements.submit();\n if (submitted.error) {\n throw new Error(submitted.error.message ?? \"Check your payment details.\");\n }\n const result = await stripe.createConfirmationToken({\n elements,\n params: {\n payment_method_data: {\n allow_redisplay: \"always\",\n billing_details: {\n address: billing.value.address,\n email,\n name: billing.value.name,\n phone,\n },\n },\n return_url: window.location.href,\n ...(collectShippingAddress && shipping\n ? {\n shipping: {\n address: shipping.value.address,\n name: shipping.value.name,\n phone,\n },\n }\n : undefined),\n },\n });\n if (result.error || !result.confirmationToken) {\n throw new Error(\n result.error?.message ?? \"Unable to prepare payment details.\"\n );\n }\n return result.confirmationToken.id;\n}\n\nexport async function completeAuctionAction(\n stripe: Stripe,\n result: LockerverseAuctionBidResult\n) {\n if (!result.requiresAction) {\n return;\n }\n if (!result.clientSecret) {\n throw new Error(\n \"Payment confirmation is incomplete. Check its status before trying again.\"\n );\n }\n const action = await stripe.handleNextAction({\n clientSecret: result.clientSecret,\n });\n if (action.error) {\n throw new Error(\n action.error.message ?? \"Payment confirmation is incomplete.\"\n );\n }\n}\n","// biome-ignore-all lint/suspicious/noUnnecessaryConditions: React refs change in effect cleanup and event handlers outside this static control flow.\nimport {\n type LockerverseAuction,\n type LockerverseAuctionItem,\n type LockerverseAuctionPurchaseResult,\n LockerverseSdkError,\n} from \"@lockerverse/sdk/auctions\";\nimport { useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport type { StripeAddressElementChangeEvent } from \"@stripe/stripe-js\";\nimport { type FormEvent, useEffect, useId, useRef, useState } from \"react\";\nimport { AuctionCheckoutView } from \"./auction-checkout-view.tsx\";\nimport type {\n LockerverseAuctionItemProps,\n LockerverseAuctionPurchaseRecovery,\n} from \"./auction-item-types.ts\";\nimport {\n type AuctionSelection,\n auctionExpectedPricing,\n completeAuctionAction,\n createAuctionConfirmationToken,\n getAuctionSelectionError,\n getAuctionSelectionPricing,\n hasAuctionCheckoutChanged,\n} from \"./auction-payment.ts\";\nimport type { LockerverseAuctionOutcome } from \"./auction-result.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { type ContactErrors, validateContact } from \"./payment-validation.ts\";\nimport { getInternationalPhone, resolvePhoneCountry } from \"./phone.ts\";\n\ntype AuctionCheckoutProps = LockerverseAuctionItemProps & {\n item: LockerverseAuctionItem;\n selection: AuctionSelection;\n onReview: (auction: LockerverseAuction, message: string) => void;\n onBack: () => void;\n contact?: { email: string; phone: string };\n onContactChange?: (contact: { email: string; phone: string }) => void;\n onIncludeServiceFeeChange?: (value: boolean) => void;\n onInteractionLockChange?: (locked: boolean) => void;\n onResult: (outcome: LockerverseAuctionOutcome) => void;\n};\n\ntype CheckoutState =\n | \"ready\"\n | \"busy\"\n | \"pending\"\n | \"retry\"\n | \"complete\"\n | \"uncertain\";\n\nfunction getSubmitLabel(\n state: CheckoutState,\n hasRecovery: boolean,\n isPurchase: boolean\n) {\n if (state === \"busy\") {\n return isPurchase ? \"Processing...\" : \"Authorizing...\";\n }\n if (state === \"retry\") {\n return \"Retry original purchase\";\n }\n if (hasRecovery) {\n return \"Check purchase status\";\n }\n return isPurchase ? \"Buy Now\" : \"Authorize Bid\";\n}\n\nexport function AuctionCheckout(props: AuctionCheckoutProps) {\n const { auction, item, selection, client, onReview, onBack } = props;\n const stripe = useStripe();\n const elements = useElements();\n const id = useId();\n const [email, setEmail] = useState(props.contact?.email ?? \"\");\n const [phone, setPhone] = useState(props.contact?.phone ?? \"\");\n const [phoneCountry, setPhoneCountry] = useState<string>(() =>\n resolvePhoneCountry(props.contact?.phone ?? \"\")\n );\n const [contactErrors, setContactErrors] = useState<ContactErrors>({});\n const [sameAsBilling, setSameAsBilling] = useState(true);\n const [billing, setBilling] =\n useState<StripeAddressElementChangeEvent | null>(null);\n const [shipping, setShipping] =\n useState<StripeAddressElementChangeEvent | null>(null);\n const [recovery, setRecovery] = useState(props.resumePurchase ?? null);\n const [state, setState] = useState<CheckoutState>(\n props.resumePurchase ? \"pending\" : \"ready\"\n );\n const [message, setMessage] = useState<string | null>(null);\n const purchaseRequestId = useRef<string | null>(\n props.resumePurchase?.submission.clientRequestId ?? null\n );\n const isTerminal = state === \"complete\" || state === \"uncertain\";\n const busy = useRef<boolean>(false);\n const mounted = useRef<boolean>(true);\n const callbacks = useRef(props);\n callbacks.current = props;\n const outcomeReported = useRef(false);\n\n function transition(next: CheckoutState) {\n if (mounted.current) {\n setState(next);\n }\n notifyHostCallback(\n callbacks.current.onInteractionLockChange,\n next !== \"ready\" && next !== \"complete\"\n );\n }\n function showMessage(value: string | null) {\n if (mounted.current) {\n setMessage(value);\n }\n }\n function reportUncertain(kind: \"bid\" | \"purchase\") {\n transition(kind === \"bid\" ? \"uncertain\" : \"pending\");\n showMessage(\n kind === \"bid\"\n ? \"We could not confirm your bid. Do not submit another bid until you check your email or contact the auction organizer.\"\n : \"We could not confirm the purchase result. Check its status using the same purchase request.\"\n );\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onUncertain, kind);\n }\n }\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const isPurchase =\n Boolean(recovery ?? props.resumePurchase) || item.saleMode === \"buy_now\";\n const pricing =\n recovery?.pricing ??\n props.resumePurchase?.pricing ??\n getAuctionSelectionPricing(auction, item, selection);\n\n const payment =\n recovery?.payment ?? props.resumePurchase?.payment ?? auction.payment;\n\n function rememberPurchase(value: LockerverseAuctionPurchaseRecovery | null) {\n if (mounted.current) {\n setRecovery(value);\n }\n notifyHostCallback(callbacks.current.onPurchaseRecoveryChange, value);\n }\n\n function finishPurchase(result: LockerverseAuctionPurchaseResult) {\n if (result.status === \"paid\") {\n purchaseRequestId.current = null;\n rememberPurchase(null);\n transition(\"complete\");\n notifyHostCallback(callbacks.current.onResult, {\n kind: \"purchase\",\n purchaseId: result.purchaseId,\n quantity: result.quantity,\n serviceFeeCents: result.serviceFeeCents,\n status: \"paid\",\n subtotalCents: result.subtotalCents,\n totalCents: result.totalCents,\n unitAmountCents: result.subtotalCents / result.quantity,\n });\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onPurchaseComplete, result);\n }\n } else if (result.status === \"pending_payment\") {\n transition(\"pending\");\n showMessage(\n \"Your purchase is pending. Check its status before making another payment.\"\n );\n } else {\n purchaseRequestId.current = null;\n rememberPurchase(null);\n transition(\"ready\");\n showMessage(\n `This purchase is ${result.status.replaceAll(\"_\", \" \")}. You can start a new purchase.`\n );\n }\n }\n\n function readContact() {\n const phoneNumber = getInternationalPhone(phone, phoneCountry);\n const contact = validateContact({ email, phone: phoneNumber }, true);\n setContactErrors(contact.errors);\n if (!contact.value) {\n document\n .getElementById(`${id}-${contact.errors.email ? \"email\" : \"phone\"}`)\n ?.focus();\n return null;\n }\n return { email: contact.value.email, phone: phoneNumber };\n }\n\n async function prepareSubmission(\n contact: { email: string; phone: string } | null\n ) {\n if (!contact) {\n throw new Error(\"Check the contact fields below.\");\n }\n if (!(stripe && elements && auction.payment)) {\n throw new Error(\"Payment details are still loading.\");\n }\n const current = await client.load(auction.slug);\n if (!mounted.current) {\n return null;\n }\n const currentItem = current.items.find(\n (candidate) => candidate.id === item.id\n );\n if (!currentItem) {\n onReview(current, \"This item is no longer available.\");\n return null;\n }\n const selectionError = getAuctionSelectionError(\n current,\n currentItem,\n selection\n );\n if (\n selectionError ||\n hasAuctionCheckoutChanged(auction, current, item, currentItem, selection)\n ) {\n onReview(\n current,\n selectionError ??\n \"The checkout details changed. Review them before continuing.\"\n );\n return null;\n }\n const confirmationToken = await createAuctionConfirmationToken({\n billing,\n collectShippingAddress: item.collectShippingAddress,\n elements,\n email: contact.email,\n phone: contact.phone,\n shipping: sameAsBilling ? billing : shipping,\n stripe,\n });\n if (!mounted.current) {\n return null;\n }\n return {\n confirmationToken,\n email: contact.email,\n includeServiceFee: selection.includeServiceFee,\n phone: contact.phone,\n ...auctionExpectedPricing(pricing),\n };\n }\n\n async function sendBid(\n submission: NonNullable<Awaited<ReturnType<typeof prepareSubmission>>>\n ) {\n const result = await client.createBid(auction.slug, item.id, {\n ...submission,\n amount: selection.amount,\n });\n if (result.requiresAction) {\n if (!(mounted.current && stripe)) {\n reportUncertain(\"bid\");\n return;\n }\n await completeAuctionAction(stripe, result);\n }\n transition(\"complete\");\n notifyHostCallback(callbacks.current.onResult, {\n amountCents: result.subtotalCents,\n kind: \"bid\",\n });\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onBidSubmitted, result);\n }\n }\n\n async function resolvePurchase(\n result: LockerverseAuctionPurchaseResult,\n active: LockerverseAuctionPurchaseRecovery\n ) {\n if (result.requiresAction) {\n if (!(mounted.current && stripe)) {\n reportUncertain(\"purchase\");\n return;\n }\n await completeAuctionAction(stripe, result);\n const updated = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (updated) {\n finishPurchase(updated);\n } else {\n transition(\"pending\");\n showMessage(\n \"Payment status is not available yet. Check again shortly.\"\n );\n }\n return;\n }\n finishPurchase(result);\n if (!mounted.current && result.status === \"pending_payment\") {\n reportUncertain(\"purchase\");\n }\n }\n\n async function checkPurchase(active: LockerverseAuctionPurchaseRecovery) {\n const result = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (result) {\n await resolvePurchase(result, active);\n } else {\n if (!mounted.current) {\n reportUncertain(\"purchase\");\n return;\n }\n transition(\"retry\");\n showMessage(\n \"No purchase is recorded yet. You can retry the original purchase with the same request ID.\"\n );\n }\n }\n\n async function clearRejectedPurchase(\n error: LockerverseSdkError,\n active: LockerverseAuctionPurchaseRecovery\n ) {\n const result = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (result) {\n await resolvePurchase(result, active);\n return;\n }\n rememberPurchase(null);\n transition(\"ready\");\n showMessage(\n `The purchase was rejected. Review the item and payment details before trying again. (${error.status ?? \"validation\"})`\n );\n }\n\n async function handleFailure<Failure>(\n error: Failure,\n requestSent: boolean,\n active: LockerverseAuctionPurchaseRecovery | null,\n wasRecovery: boolean\n ) {\n const uncertain =\n requestSent &&\n (!(error instanceof LockerverseSdkError) || error.recoveryRecommended);\n showMessage(\n error instanceof Error\n ? error.message\n : \"Unable to complete this request.\"\n );\n if (isPurchase && active) {\n if (\n !wasRecovery &&\n error instanceof LockerverseSdkError &&\n !error.recoveryRecommended\n ) {\n try {\n await clearRejectedPurchase(error, active);\n return;\n } catch {\n /* Keep the original request when status cannot be established. */\n }\n }\n reportUncertain(\"purchase\");\n } else if (uncertain) {\n reportUncertain(\"bid\");\n } else {\n transition(\"ready\");\n }\n }\n\n function getPurchaseRequestId() {\n purchaseRequestId.current ??= globalThis.crypto.randomUUID();\n return purchaseRequestId.current;\n }\n\n function canSendPurchase() {\n if (mounted.current) {\n return true;\n }\n if (!recovery) {\n rememberPurchase(null);\n transition(\"ready\");\n }\n return false;\n }\n\n async function sendOrCheckPurchase(\n active: LockerverseAuctionPurchaseRecovery,\n statusOnly: boolean\n ) {\n if (statusOnly) {\n await checkPurchase(active);\n return;\n }\n if (!canSendPurchase()) {\n return;\n }\n const result = await client.createPurchase(\n auction.slug,\n item.id,\n active.submission\n );\n await resolvePurchase(result, active);\n }\n\n const checkoutPayment = stripe && elements && payment;\n\n function startSubmission() {\n if (busy.current || isTerminal) {\n return null;\n }\n if (!checkoutPayment) {\n showMessage(\"Payment details are still loading.\");\n return null;\n }\n const contact = recovery ? null : readContact();\n if (!(recovery || contact)) {\n return null;\n }\n return { checkoutPayment, contact, retryOriginal: state === \"retry\" };\n }\n\n async function submit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const start = startSubmission();\n if (!start) {\n return;\n }\n const { contact, checkoutPayment: readyPayment, retryOriginal } = start;\n busy.current = true;\n outcomeReported.current = false;\n transition(\"busy\");\n showMessage(null);\n let requestSent = false;\n let activeRecovery = recovery;\n try {\n if (!activeRecovery) {\n const submission = await prepareSubmission(contact);\n if (!(submission && mounted.current)) {\n transition(\"ready\");\n return;\n }\n if (!isPurchase) {\n requestSent = true;\n await sendBid(submission);\n return;\n }\n activeRecovery = Object.freeze({\n auctionId: auction.id,\n item,\n itemId: item.id,\n payment: Object.freeze({ ...readyPayment }),\n pricing,\n submission: Object.freeze({\n ...submission,\n clientRequestId: getPurchaseRequestId(),\n paymentMethodTypes: Object.freeze([\"card\"] as const),\n quantity: selection.quantity,\n }),\n });\n rememberPurchase(activeRecovery);\n }\n requestSent = true;\n await sendOrCheckPurchase(\n activeRecovery,\n Boolean(recovery) && !retryOriginal\n );\n } catch (error) {\n await handleFailure(\n error,\n requestSent,\n activeRecovery,\n recovery !== null && !retryOriginal\n );\n } finally {\n busy.current = false;\n }\n }\n\n const buttonText = getSubmitLabel(state, recovery !== null, isPurchase);\n\n const locked = state !== \"ready\";\n return (\n <AuctionCheckoutView\n buttonText={buttonText}\n communityName={props.communityName ?? auction.name}\n contactErrors={contactErrors}\n email={email}\n id={id}\n includeServiceFee={selection.includeServiceFee}\n isPurchase={isPurchase}\n isTerminal={isTerminal}\n item={item}\n locked={locked}\n message={message}\n onBack={state === \"ready\" ? onBack : undefined}\n onBillingChange={setBilling}\n onEmailChange={(value) => {\n setEmail(value);\n props.onContactChange?.({\n email: value,\n phone: getInternationalPhone(phone, phoneCountry),\n });\n }}\n onIncludeServiceFeeChange={props.onIncludeServiceFeeChange}\n onPaymentLoadError={() => showMessage(\"Unable to load payment form.\")}\n onPhoneChange={({ value, country }) => {\n setPhone(value);\n setPhoneCountry(country);\n props.onContactChange?.({\n email,\n phone: getInternationalPhone(value, country),\n });\n }}\n onSameAsBillingChange={setSameAsBilling}\n onShippingChange={setShipping}\n onSubmit={submit}\n phone={phone}\n phoneCountry={phoneCountry}\n pricing={pricing}\n quantity={selection.quantity}\n sameAsBilling={sameAsBilling}\n serviceFeeCents={\n recovery\n ? pricing.serviceFeeCents\n : getAuctionSelectionPricing(auction, item, {\n ...selection,\n includeServiceFee: auction.serviceFeeEnabled,\n }).serviceFeeCents\n }\n serviceFeeEnabled={auction.serviceFeeEnabled}\n showFields={!(recovery || isTerminal)}\n submitDisabled={state === \"busy\" || !stripe || !elements}\n />\n );\n}\n","import Autoplay from \"embla-carousel-autoplay\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nconst PHOTO_DELAY = 6000;\n\n// Embla 8 has stop(), but no pause(). Resume with the saved delay, then restore\n// the full delay on selection. Embla remains the only owner of the slide timer.\nexport function useAuctionAutoplay(enabled: boolean, reducedMotion: boolean) {\n const remaining = useRef(PHOTO_DELAY);\n const progressRef = useRef<HTMLDivElement>(null);\n const [cycleDelay, setCycleDelay] = useState(PHOTO_DELAY);\n const autoplay = useMemo(\n () =>\n Autoplay({\n delay: cycleDelay,\n playOnInit: false,\n stopOnFocusIn: false,\n stopOnInteraction: true,\n stopOnMouseEnter: false,\n }),\n [cycleDelay]\n );\n\n const [viewportRef, embla] = useEmblaCarousel(\n { duration: reducedMotion ? 0 : 25, loop: true },\n [autoplay]\n );\n\n const draw = useCallback(() => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns this ref in the filmstrip component.\n if (progressRef.current) {\n progressRef.current.style.transform = `scaleX(${1 - remaining.current / PHOTO_DELAY})`;\n }\n }, []);\n\n const freeze = useCallback(() => {\n const left = autoplay.timeUntilNext();\n if (left !== null) {\n remaining.current = Math.max(1, Math.min(PHOTO_DELAY, left));\n }\n autoplay.stop();\n draw();\n }, [autoplay, draw]);\n\n const reset = useCallback(() => {\n remaining.current = PHOTO_DELAY;\n setCycleDelay(PHOTO_DELAY);\n autoplay.reset();\n draw();\n }, [autoplay, draw]);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n if (!enabled) {\n freeze();\n } else if (cycleDelay === remaining.current) {\n autoplay.play();\n } else {\n setCycleDelay(remaining.current);\n }\n }, [embla, enabled, autoplay, cycleDelay, setCycleDelay, remaining, freeze]);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n let frame = 0;\n const update = () => {\n const left = autoplay.timeUntilNext();\n if (!enabled || left === null) {\n return;\n }\n remaining.current = Math.max(0, Math.min(PHOTO_DELAY, left));\n draw();\n frame = requestAnimationFrame(update);\n };\n const start = () => {\n cancelAnimationFrame(frame);\n if (enabled) {\n frame = requestAnimationFrame(update);\n }\n };\n const stop = () => cancelAnimationFrame(frame);\n const reinitialize = () => {\n if (enabled) {\n autoplay.play();\n }\n };\n embla\n .on(\"select\", reset)\n .on(\"reInit\", reinitialize)\n .on(\"autoplay:timerset\", start)\n .on(\"autoplay:timerstopped\", stop);\n draw();\n start();\n return () => {\n stop();\n embla\n .off(\"select\", reset)\n .off(\"reInit\", reinitialize)\n .off(\"autoplay:timerset\", start)\n .off(\"autoplay:timerstopped\", stop);\n };\n }, [embla, autoplay, enabled, remaining, reset, draw]);\n return { embla, freeze, progressRef, reset, viewportRef };\n}\n","import { ChevronLeft, ChevronRight, Pause, Play } from \"lucide-react\";\nimport {\n type PointerEvent,\n type Ref,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAuctionAutoplay } from \"./use-auction-autoplay\";\nimport { useAuctionVisibility } from \"./use-auction-visibility\";\n\ntype FilmstripProps = {\n photos: string[];\n name: string;\n selected: number;\n paused?: boolean;\n photoButtonRef: Ref<HTMLButtonElement>;\n onSelect: (index: number) => void;\n onExpand: (index: number) => void;\n};\n\nexport function AuctionPhotoFilmstrip({\n photos,\n name,\n selected,\n paused = false,\n photoButtonRef,\n onSelect,\n onExpand,\n}: FilmstripProps) {\n const stripRef = useRef<HTMLDivElement>(null);\n const keyboardPhoto = useRef<HTMLButtonElement | null>(null);\n const thumbnailRefs = useRef<(HTMLButtonElement | null)[]>([]);\n const [reducedMotion, setReducedMotion] = useState(true);\n const [hovered, setHovered] = useState(false);\n const [keyboardFocused, setKeyboardFocused] = useState(false);\n const [userPaused, setUserPaused] = useState(false);\n const [dragging, setDragging] = useState(false);\n const { ref: galleryRef, visible } = useAuctionVisibility<HTMLElement>();\n const [controlsActive, setControlsActive] = useState(false);\n const [touchControls, setTouchControls] = useState(true);\n const hideControlsTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const controlsVisible = touchControls || controlsActive || keyboardFocused;\n const controlsFade = `lockerverse-auction-gallery__control ${controlsVisible ? \"is-visible\" : \"\"}`;\n\n const scheduleControlsHide = () => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The timer ref is assigned after pointer activity.\n if (hideControlsTimer.current) {\n clearTimeout(hideControlsTimer.current);\n }\n hideControlsTimer.current = setTimeout(\n () => setControlsActive(false),\n 2000\n );\n };\n const showControls = (event: PointerEvent<HTMLDivElement>) => {\n if (event.pointerType !== \"mouse\") {\n setTouchControls(true);\n return;\n }\n setControlsActive(true);\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The timer ref is assigned after pointer activity.\n if (hideControlsTimer.current) {\n clearTimeout(hideControlsTimer.current);\n }\n if (\n !(\n event.target instanceof Element &&\n event.target.closest(\"[data-gallery-control]\")\n )\n ) {\n scheduleControlsHide();\n }\n };\n\n useEffect(() => {\n const preference = window.matchMedia(\"(hover: none), (pointer: coarse)\");\n const update = () => setTouchControls(preference.matches);\n update();\n preference.addEventListener(\"change\", update);\n return () => {\n preference.removeEventListener(\"change\", update);\n clearTimeout(hideControlsTimer.current ?? undefined);\n };\n }, []);\n\n const autoplayEnabled =\n !(\n paused ||\n reducedMotion ||\n hovered ||\n keyboardFocused ||\n userPaused ||\n dragging\n ) && visible;\n const count = photos.length;\n const current = count ? ((selected % count) + count) % count : 0;\n const { viewportRef, embla, progressRef, freeze, reset } = useAuctionAutoplay(\n autoplayEnabled && count > 1,\n reducedMotion\n );\n\n useEffect(() => {\n const preference = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const update = () => setReducedMotion(preference.matches);\n update();\n preference.addEventListener(\"change\", update);\n return () => preference.removeEventListener(\"change\", update);\n }, []);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n const select = () => onSelect(embla.selectedScrollSnap());\n embla.on(\"select\", select).on(\"reInit\", select);\n return () => {\n embla.off(\"select\", select).off(\"reInit\", select);\n };\n }, [embla, onSelect]);\n\n useEffect(() => {\n if (embla && embla.selectedScrollSnap() !== current) {\n embla.scrollTo(current, true);\n }\n }, [embla, current]);\n\n useEffect(() => {\n const updateVisibility = () => {\n if (document.hidden) {\n freeze();\n }\n };\n const release = () => setDragging(false);\n updateVisibility();\n document.addEventListener(\"visibilitychange\", updateVisibility, true);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"pointercancel\", release);\n return () => {\n document.removeEventListener(\"visibilitychange\", updateVisibility, true);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"pointercancel\", release);\n };\n }, [freeze]);\n\n const selectPhoto = (next: number) => {\n embla?.scrollTo((next + count) % count, reducedMotion);\n reset();\n };\n\n useEffect(() => {\n const previousPhoto = keyboardPhoto.current;\n keyboardPhoto.current = null;\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Keyboard events assign this ref before the selected photo changes.\n if (previousPhoto && document.activeElement === previousPhoto) {\n galleryRef.current\n ?.querySelector<HTMLButtonElement>(\n '.lockerverse-auction-gallery__photo[tabindex=\"0\"]'\n )\n ?.focus({ preventScroll: true });\n }\n }, [current, galleryRef]);\n\n useEffect(() => {\n const strip = stripRef.current;\n const thumbnail = thumbnailRefs.current[current];\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns the element ref after mounting.\n if (!(strip && thumbnail)) {\n return;\n }\n const stripBounds = strip.getBoundingClientRect();\n const photoBounds = thumbnail.getBoundingClientRect();\n if (photoBounds.left < stripBounds.left) {\n strip.scrollLeft -= stripBounds.left - photoBounds.left;\n } else if (photoBounds.right > stripBounds.right) {\n strip.scrollLeft += photoBounds.right - stripBounds.right;\n }\n }, [current, count]);\n\n return (\n // biome-ignore lint/a11y/noNoninteractiveElementInteractions: The gallery handles keys from its focusable photo and navigation buttons.\n <section\n aria-label={`${name} photos`}\n className=\"lockerverse-auction-gallery\"\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n setKeyboardFocused(false);\n }\n }}\n onFocusCapture={(event) =>\n setKeyboardFocused(event.target.matches(\":focus-visible\"))\n }\n onKeyDown={(event) => {\n if (\n count < 2 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n ) {\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault();\n if (\n event.target instanceof HTMLButtonElement &&\n event.target.classList.contains(\n \"lockerverse-auction-gallery__photo\"\n )\n ) {\n keyboardPhoto.current = event.target;\n }\n selectPhoto(current + (event.key === \"ArrowRight\" ? 1 : -1));\n }\n }}\n onPointerEnter={(event) => {\n if (event.pointerType === \"mouse\") {\n setHovered(true);\n }\n }}\n onPointerLeave={(event) => {\n if (event.pointerType === \"mouse\") {\n setHovered(false);\n }\n }}\n ref={galleryRef}\n >\n {count ? (\n <div\n className=\"lockerverse-auction-gallery__stage\"\n onPointerEnter={showControls}\n onPointerLeave={scheduleControlsHide}\n onPointerMove={showControls}\n >\n <div\n className=\"lockerverse-auction-gallery__viewport\"\n onPointerDownCapture={() => {\n freeze();\n setDragging(true);\n }}\n ref={viewportRef}\n >\n <div className=\"lockerverse-auction-gallery__track\">\n {photos.map((photo, photoIndex) => (\n <div\n aria-hidden={photoIndex !== current}\n className=\"lockerverse-auction-gallery__slide\"\n key={`${photo}-${photoIndex}`}\n >\n <button\n aria-label={`View photo ${photoIndex + 1} of ${name} at full size`}\n className=\"lockerverse-auction-gallery__photo\"\n onClick={() => {\n onExpand(photoIndex);\n }}\n ref={photoIndex === current ? photoButtonRef : undefined}\n tabIndex={photoIndex === current ? 0 : -1}\n type=\"button\"\n >\n <img\n alt={`${name}, ${photoIndex + 1} of ${count}`}\n className=\"lockerverse-auction-gallery__image\"\n draggable={false}\n height={900}\n loading={\n photoIndex === 0 ||\n photoIndex === current ||\n photoIndex === (current + 1) % count\n ? \"eager\"\n : \"lazy\"\n }\n sizes=\"(max-width: 1280px) 100vw, 45vw\"\n src={photo}\n width={1200}\n />\n </button>\n </div>\n ))}\n </div>\n </div>\n {count > 1 && !reducedMotion && (\n <div className=\"lockerverse-auction-gallery__rotation\">\n <div\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__progress-track\"\n >\n <div\n className=\"lockerverse-auction-gallery__progress\"\n ref={progressRef}\n style={{ transform: \"scaleX(0)\" }}\n />\n </div>\n <button\n aria-label={\n userPaused ? \"Play photo rotation\" : \"Pause photo rotation\"\n }\n className={`lockerverse-auction-gallery__play ${controlsFade}`}\n data-gallery-control\n onClick={() => setUserPaused((value) => !value)}\n title={\n userPaused ? \"Play photo rotation\" : \"Pause photo rotation\"\n }\n type=\"button\"\n >\n {userPaused ? (\n <Play aria-hidden=\"true\" size={13} />\n ) : (\n <Pause aria-hidden=\"true\" size={13} />\n )}\n </button>\n </div>\n )}\n {count > 1 && (\n <>\n <button\n aria-label=\"Previous photo\"\n className={`lockerverse-auction-gallery__previous ${controlsFade}`}\n data-gallery-control\n onClick={() => selectPhoto(current - 1)}\n type=\"button\"\n >\n <ChevronLeft\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__chevron\"\n />\n </button>\n <button\n aria-label=\"Next photo\"\n className={`lockerverse-auction-gallery__next ${controlsFade}`}\n data-gallery-control\n onClick={() => selectPhoto(current + 1)}\n type=\"button\"\n >\n <ChevronRight\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__chevron\"\n />\n </button>\n </>\n )}\n </div>\n ) : (\n <div className=\"lockerverse-auction-gallery__empty\">\n No photo available\n </div>\n )}\n {count > 1 && (\n <section\n aria-label=\"Choose a photo\"\n className=\"lockerverse-auction-gallery__strip\"\n ref={stripRef}\n >\n <div className=\"lockerverse-auction-gallery__thumbnails\">\n {photos.map((photo, photoIndex) => (\n <button\n aria-label={`Show photo ${photoIndex + 1} of ${count}`}\n aria-pressed={current === photoIndex}\n className={`lockerverse-auction-gallery__thumbnail ${current === photoIndex ? \"is-selected\" : \"\"}`}\n key={`${photo}-${photoIndex}`}\n onClick={() => selectPhoto(photoIndex)}\n ref={(element) => {\n thumbnailRefs.current[photoIndex] = element;\n }}\n type=\"button\"\n >\n <img\n alt=\"\"\n className=\"lockerverse-auction-gallery__thumbnail-image\"\n height={66}\n sizes=\"88px\"\n src={photo}\n width={88}\n />\n </button>\n ))}\n </div>\n </section>\n )}\n </section>\n );\n}\n","import { Dialog } from \"@base-ui/react/dialog\";\nimport { ChevronLeft, ChevronRight, X as Close } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { AuctionPhotoFilmstrip } from \"./auction-photo-filmstrip\";\n\nexport function AuctionGallery({\n images,\n fallbackImage,\n name,\n}: {\n images: readonly string[];\n fallbackImage?: string | null;\n name: string;\n}) {\n const photos = [...new Set(images.filter(Boolean))];\n if (!photos.length && fallbackImage) {\n photos.push(fallbackImage);\n }\n const [index, setIndex] = useState(0);\n const [open, setOpen] = useState(false);\n const opener = useRef<HTMLButtonElement | null>(null);\n const swipeStart = useRef<{ x: number; y: number } | null>(null);\n const count = photos.length;\n const selected = count ? ((index % count) + count) % count : 0;\n\n return (\n <>\n <AuctionPhotoFilmstrip\n name={name}\n onExpand={(next) => {\n setIndex(next);\n setOpen(true);\n }}\n onSelect={setIndex}\n paused={open}\n photoButtonRef={opener}\n photos={photos}\n selected={selected}\n />\n {count > 0 && (\n <Dialog.Root onOpenChange={setOpen} open={open}>\n <Dialog.Portal>\n <Dialog.Backdrop className=\"lockerverse-auction-gallery__backdrop\" />\n <Dialog.Popup\n aria-describedby={undefined}\n className=\"lockerverse-auction-gallery__viewer\"\n finalFocus={opener}\n onKeyDown={(event) => {\n if (\n count < 2 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n ) {\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault();\n setIndex(\n (selected + (event.key === \"ArrowRight\" ? 1 : -1) + count) %\n count\n );\n }\n }}\n >\n <Dialog.Title className=\"lockerverse-auction-gallery__sr-only\">\n {name} · Photo {selected + 1} of {count}\n </Dialog.Title>\n <div\n className=\"lockerverse-auction-gallery__full-image\"\n onTouchCancel={() => {\n swipeStart.current = null;\n }}\n onTouchEnd={(event) => {\n const start = swipeStart.current;\n swipeStart.current = null;\n const end = event.changedTouches.item(0);\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Touch start assigns the shared ref before this event.\n if (!(start && end) || count < 2) {\n return;\n }\n const dx = end.clientX - start.x;\n const dy = end.clientY - start.y;\n if (Math.abs(dx) >= 45 && Math.abs(dx) > Math.abs(dy) * 1.3) {\n setIndex((selected + (dx < 0 ? 1 : -1) + count) % count);\n }\n }}\n onTouchMove={(event) => {\n if (event.touches.length !== 1) {\n swipeStart.current = null;\n }\n }}\n onTouchStart={(event) => {\n const touch = event.touches.item(0);\n swipeStart.current =\n event.touches.length === 1 && touch\n ? { x: touch.clientX, y: touch.clientY }\n : null;\n }}\n >\n <img\n alt={`${name}, ${selected + 1} of ${count}`}\n height={900}\n src={photos[selected]}\n width={1200}\n />\n {open && count > 1 && (\n <img\n alt=\"\"\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__preload\"\n height={900}\n loading=\"eager\"\n src={photos[(selected + 1) % count]}\n width={1200}\n />\n )}\n </div>\n <Dialog.Close\n aria-label=\"Close photo viewer\"\n className=\"lockerverse-auction-gallery__viewer-close\"\n >\n <Close aria-hidden=\"true\" size={22} />\n </Dialog.Close>\n {count > 1 && (\n <>\n <button\n aria-label=\"Previous photo\"\n className=\"lockerverse-auction-gallery__viewer-previous\"\n onClick={() => setIndex((selected - 1 + count) % count)}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={28} />\n </button>\n <button\n aria-label=\"Next photo\"\n className=\"lockerverse-auction-gallery__viewer-next\"\n onClick={() => setIndex((selected + 1) % count)}\n type=\"button\"\n >\n <ChevronRight aria-hidden=\"true\" size={28} />\n </button>\n </>\n )}\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n )}\n </>\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionItem,\n LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport {\n ChevronDown,\n Clock3,\n Gavel,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport { useId, useState } from \"react\";\nimport { AuctionDescription } from \"./auction-description.tsx\";\nimport {\n formatAuctionBoundary,\n formatAuctionMoney as formatMoney,\n getAuctionDisplayStatus,\n} from \"./auction-display.ts\";\nimport { AuctionGallery } from \"./auction-gallery.tsx\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nfunction metricIcon(label: string | undefined) {\n if (label === \"Buy Now\") {\n return <ShieldCheck aria-hidden=\"true\" size={16} />;\n }\n if (label === \"Available\" || label === \"Increment\") {\n return <TimerReset aria-hidden=\"true\" size={16} />;\n }\n return <Gavel aria-hidden=\"true\" size={16} />;\n}\nfunction itemMetrics(\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (item.saleMode === \"buy_now\") {\n return [\n [\"Buy Now\", formatMoney(item.buyNowPriceAmount ?? 0)],\n [\n \"Available\",\n item.availableQuantity === null\n ? \"Available\"\n : String(item.availableQuantity),\n ],\n ];\n }\n if (status === \"finished\") {\n return [\n [\n \"Final bid\",\n item.maxBidAmount ? formatMoney(item.maxBidAmount) : \"No bids\",\n ],\n ];\n }\n return [\n [\"Current bid\", formatMoney(item.maxBidAmount ?? 0)],\n [\"Floor\", formatMoney(item.minBidAmount ?? 0)],\n [\"Increment\", formatMoney(item.bidIncrementAmount ?? 100)],\n ];\n}\nexport function AuctionItemDetails({\n auction,\n item,\n}: {\n auction: LockerverseAuction;\n item: LockerverseAuctionItem;\n}) {\n useAuctionBoundary(\n item.startAt ?? auction.startAt,\n item.endAt ?? auction.endAt\n );\n const [expanded, setExpanded] = useState(false);\n const descriptionId = useId();\n const status = getAuctionDisplayStatus(auction, item);\n const boundaryLabel = {\n active: \"Closes\",\n draft: \"Opens\",\n finished: \"Closed\",\n }[status];\n const boundary = formatAuctionBoundary(auction, status, item);\n const buyNow = item.saleMode === \"buy_now\";\n const longDescription = (item.description ?? \"\").trim().length > 240;\n const metrics = itemMetrics(item, status);\n return (\n <section className=\"lockerverse-auctions__item-summary\">\n <AuctionGallery\n fallbackImage={\n item.image ??\n auction.configuration.image ??\n auction.community?.banner ??\n auction.community?.thumbnail ??\n null\n }\n images={item.images}\n name={item.name}\n />\n <div className=\"lockerverse-auctions__item-copy\">\n <h2>{item.name}</h2>\n {item.description ? (\n <div className=\"lockerverse-auctions__item-description\">\n <AuctionDescription\n className={\n !expanded && longDescription\n ? \"lockerverse-auctions__description-clamped\"\n : undefined\n }\n description={item.description}\n id={descriptionId}\n />\n {longDescription ? (\n <button\n aria-controls={descriptionId}\n aria-expanded={expanded}\n className=\"lockerverse-auctions__description-toggle\"\n onClick={() => setExpanded(!expanded)}\n type=\"button\"\n >\n {expanded ? \"Hide description\" : \"Read full description\"}{\" \"}\n <ChevronDown\n aria-hidden=\"true\"\n size={16}\n style={{ transform: expanded ? \"rotate(180deg)\" : undefined }}\n />\n </button>\n ) : null}\n </div>\n ) : null}\n <dl className=\"lockerverse-auctions__stat-panel\">\n {metrics.map(([label, value]) => (\n <div className=\"lockerverse-auctions__stat-row\" key={label}>\n <dt>\n {metricIcon(label)}\n {label}\n </dt>\n <dd>{value}</dd>\n </div>\n ))}\n <div className=\"lockerverse-auctions__stat-row\">\n <dt>\n <Clock3 aria-hidden=\"true\" size={16} />\n {boundaryLabel}\n </dt>\n <dd className=\"lockerverse-auctions__stat-date\">{boundary}</dd>\n </div>\n {!buyNow && status === \"finished\" ? (\n <div className=\"lockerverse-auctions__stat-footer\">\n <div>\n <dt>Floor</dt>\n <dd>{formatMoney(item.minBidAmount ?? 0)}</dd>\n </div>\n <div>\n <dt>Bid increment</dt>\n <dd>{formatMoney(item.bidIncrementAmount ?? 100)}</dd>\n </div>\n </div>\n ) : null}\n </dl>\n </div>\n </section>\n );\n}\n","import {\n getLockerverseAuctionMinimumBid,\n type LockerverseAuction,\n type LockerverseAuctionItem,\n type LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport { ArrowRight } from \"lucide-react\";\nimport { type FormEvent, useId, useState } from \"react\";\nimport {\n formatAuctionBoundary,\n formatAuctionMoney as formatMoney,\n getAuctionDisplayStatus,\n isAuctionItemSoldOut,\n} from \"./auction-display.ts\";\nimport {\n type AuctionSelection,\n getAuctionSelectionError,\n getAuctionSelectionPricing,\n} from \"./auction-payment.ts\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nconst WHOLE_NUMBER = /^\\d+$/;\n\ntype SelectionProps = {\n auction: LockerverseAuction;\n item: LockerverseAuctionItem;\n initialSelection: AuctionSelection | null;\n onContinue: (selection: AuctionSelection) => void;\n onError: (message: string) => void;\n onBack?: (() => void) | undefined;\n};\n\nfunction quantitySummary(value: string, amount: number) {\n if (\n !(WHOLE_NUMBER.test(value) && Number.isSafeInteger(Number(value) * amount))\n ) {\n return \"Enter a whole-number quantity.\";\n }\n return `Total: ${formatMoney(Number(value) * amount)}`;\n}\nfunction selectionInitialValue(\n buyNow: boolean,\n initial: AuctionSelection | null,\n minimum: number\n) {\n if (buyNow) {\n return String(initial ? initial.quantity : 1);\n }\n return String(initial ? initial.amount / 100 : minimum);\n}\nfunction readOnlyTitle(\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (isAuctionItemSoldOut(item)) {\n return \"This item is sold out.\";\n }\n if (status === \"draft\") {\n return \"This item is not open yet.\";\n }\n if (status === \"finished\") {\n return item.saleMode === \"buy_now\"\n ? \"Purchases are closed for this item.\"\n : \"Bidding is closed for this item.\";\n }\n return \"This item is not available.\";\n}\nfunction readOnlyDescription(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (isAuctionItemSoldOut(item)) {\n return \"All available quantities have been purchased.\";\n }\n if (status === \"draft\") {\n return `This item opens ${formatAuctionBoundary(auction, \"draft\", item)}.`;\n }\n return item.saleMode === \"buy_now\"\n ? \"This item is no longer available to purchase.\"\n : \"Bidding has closed for this item.\";\n}\nfunction selectionFromInput(\n auction: LockerverseAuction,\n buyNow: boolean,\n initialSelection: AuctionSelection | null,\n value: string\n): AuctionSelection {\n return {\n amount: buyNow ? 0 : Number(value) * 100,\n includeServiceFee: initialSelection\n ? initialSelection.includeServiceFee\n : auction.serviceFeeEnabled && auction.serviceFeeDefaultChecked,\n quantity: buyNow ? Number(value) : 1,\n };\n}\nexport function AuctionItemSelection({\n auction,\n item,\n initialSelection,\n onContinue,\n onError,\n onBack,\n}: SelectionProps) {\n const buyNow = item.saleMode === \"buy_now\";\n const minimum = Math.ceil(getLockerverseAuctionMinimumBid(item) / 100);\n const [value, setValue] = useState(\n selectionInitialValue(buyNow, initialSelection, minimum)\n );\n const [error, setError] = useState<string | null>(null);\n const id = useId();\n useAuctionBoundary(\n item.startAt ?? auction.startAt,\n item.endAt ?? auction.endAt\n );\n const status = getAuctionDisplayStatus(auction, item);\n const open =\n status === \"active\" &&\n !isAuctionItemSoldOut(item) &&\n item.saleMode !== \"hybrid\";\n function continueToPayment(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!WHOLE_NUMBER.test(value)) {\n setError(\n buyNow\n ? \"Enter a whole-number quantity.\"\n : \"Enter a whole-dollar bid amount.\"\n );\n return;\n }\n const selection = selectionFromInput(\n auction,\n buyNow,\n initialSelection,\n value\n );\n const message = getAuctionSelectionError(auction, item, selection);\n if (message) {\n setError(message);\n onError(message);\n return;\n }\n try {\n getAuctionSelectionPricing(auction, item, selection);\n } catch {\n setError(\"Enter a valid amount or quantity.\");\n return;\n }\n onContinue(selection);\n }\n if (!open) {\n return (\n <div className=\"lockerverse-auctions__selection lockerverse-auctions__read-only\">\n <p className=\"lockerverse-auctions__eyebrow\">Item status</p>\n <h3>{readOnlyTitle(item, status)}</h3>\n <p>{readOnlyDescription(auction, item, status)}</p>\n {onBack ? (\n <button\n className=\"lockerverse-auctions__button\"\n onClick={onBack}\n type=\"button\"\n >\n Browse auction items <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n ) : null}\n </div>\n );\n }\n return (\n <form\n className=\"lockerverse-auctions__selection\"\n onSubmit={continueToPayment}\n >\n <SelectionHeader buyNow={buyNow} item={item} minimum={minimum} />\n <div className=\"lockerverse-auctions__selection-body\">\n <label className=\"lockerverse-auctions__field\" htmlFor={id}>\n {buyNow ? \"Quantity\" : \"Your bid amount\"}\n <span className=\"lockerverse-auctions__amount-control\">\n {buyNow ? null : <span aria-hidden=\"true\">$</span>}\n <input\n aria-describedby={`${id}-help`}\n aria-invalid={Boolean(error)}\n autoComplete=\"off\"\n id={id}\n inputMode=\"numeric\"\n onChange={(event) => {\n setValue(event.target.value);\n setError(null);\n }}\n placeholder={buyNow ? \"1\" : String(minimum)}\n required\n value={value}\n />\n </span>\n </label>\n {error ? <p role=\"alert\">{error}</p> : null}\n <p id={`${id}-help`}>\n {buyNow\n ? quantitySummary(value, item.buyNowPriceAmount ?? 0)\n : `Enter a whole-dollar bid of at least ${formatMoney(minimum * 100)}. Bid increment: ${formatMoney(item.bidIncrementAmount ?? 100)}.`}\n </p>\n <div className=\"lockerverse-auctions__selection-footer\">\n <p>\n {buyNow\n ? \"Continuing moves you into secure checkout where your payment is processed immediately.\"\n : \"Continuing moves you into the secure payment step where your card is stored for settlement only if your bid wins.\"}\n </p>\n <button\n className=\"lockerverse-auctions__button\"\n disabled={!auction.payment}\n type=\"submit\"\n >\n {buyNow ? \"Continue to Checkout\" : \"Continue to Payment\"}{\" \"}\n <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n </div>\n {auction.payment ? null : (\n <p role=\"alert\">Payments are not configured for this auction.</p>\n )}\n </div>\n </form>\n );\n}\n\nfunction SelectionHeader({\n item,\n buyNow,\n minimum,\n}: {\n item: LockerverseAuctionItem;\n buyNow: boolean;\n minimum: number;\n}) {\n return (\n <div className=\"lockerverse-auctions__selection-header\">\n <p className=\"lockerverse-auctions__eyebrow\">Step 1 of 2</p>\n <h3>{buyNow ? \"Buy this item now.\" : \"Place your bid.\"}</h3>\n <p>\n {buyNow\n ? \"Choose how many you want, then complete the secure checkout.\"\n : \"Enter the bid amount you want to place for this item. You are only charged if this bid wins after bidding closes.\"}\n </p>\n <p>\n {buyNow ? \"Price: \" : \"Minimum qualifying bid: \"}\n <strong>\n {formatMoney(buyNow ? (item.buyNowPriceAmount ?? 0) : minimum * 100)}\n </strong>\n </p>\n {buyNow && item.availableQuantity !== null ? (\n <p>{item.availableQuantity} available</p>\n ) : null}\n {item.collectShippingAddress ? (\n <p>\n The next step will also collect a delivery address for seller\n fulfillment.\n </p>\n ) : null}\n </div>\n );\n}\n","import type {\n LockerverseAuctionItem as AuctionItem,\n LockerverseAuction,\n} from \"@lockerverse/sdk/auctions\";\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport type {\n StripeElementsOptions,\n StripeElementsOptionsMode,\n} from \"@stripe/stripe-js\";\nimport {\n ArrowRight,\n ChevronLeft,\n Gavel,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { AuctionCheckout } from \"./auction-checkout.tsx\";\nimport {\n formatAuctionBoundary,\n getAuctionDisplayStatus,\n} from \"./auction-display.ts\";\nimport { AuctionItemDetails } from \"./auction-item-details.tsx\";\nimport { AuctionItemSelection } from \"./auction-item-selection.tsx\";\nimport type { LockerverseAuctionItemProps } from \"./auction-item-types.ts\";\nimport {\n type AuctionSelection,\n getAuctionSelectionPricing,\n} from \"./auction-payment.ts\";\nimport {\n type LockerverseAuctionOutcome,\n LockerverseAuctionResult,\n} from \"./auction-result.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { useStripeAppearance } from \"./stripe-appearance.ts\";\nimport { defaultLockerverseStripeLoader } from \"./stripe-loader.ts\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nfunction AuctionPayment(\n props: LockerverseAuctionItemProps & {\n appearanceRoot: RefObject<HTMLElement | null>;\n interactionLocked: boolean;\n item: AuctionItem;\n selection: AuctionSelection;\n onReview: (auction: LockerverseAuction, message: string) => void;\n onBack: () => void;\n contact: { email: string; phone: string };\n onContactChange: (contact: { email: string; phone: string }) => void;\n onIncludeServiceFeeChange: (value: boolean) => void;\n onInteractionLockChange: (locked: boolean) => void;\n onResult: (outcome: LockerverseAuctionOutcome) => void;\n }\n) {\n const {\n auction,\n item,\n selection,\n theme = \"dark\",\n stripeLoader = defaultLockerverseStripeLoader,\n style,\n onBack,\n resumePurchase,\n } = props;\n const [stripe, setStripe] =\n useState<Awaited<ReturnType<typeof defaultLockerverseStripeLoader>>>(null);\n const [failed, setFailed] = useState(false);\n const [revision, setRevision] = useState(0);\n const appearance = useStripeAppearance(\n props.appearanceRoot,\n theme,\n style,\n props.interactionLocked\n );\n const payment = resumePurchase?.payment ?? auction.payment;\n useEffect(() => {\n let active = true;\n if (!payment) {\n setFailed(true);\n return;\n }\n Promise.resolve()\n .then(() =>\n stripeLoader(\n payment.publishableKey,\n payment.connectedAccountId\n ? { stripeAccount: payment.connectedAccountId }\n : undefined\n )\n )\n .then(\n (loaded) => {\n if (active) {\n setStripe(loaded);\n setFailed(!loaded);\n }\n },\n () => {\n if (active) {\n setFailed(true);\n }\n }\n );\n return () => {\n active = false;\n };\n }, [payment, stripeLoader, revision]);\n if (failed) {\n return (\n <div>\n <p role=\"alert\">Payment details could not load.</p>\n {resumePurchase ? null : (\n <button onClick={onBack} type=\"button\">\n Back to item\n </button>\n )}\n <button\n onClick={() => {\n setFailed(false);\n setStripe(null);\n setRevision((value) => value + 1);\n }}\n type=\"button\"\n >\n Try again\n </button>\n </div>\n );\n }\n if (!(stripe && appearance)) {\n return (\n <div>\n <p role=\"status\">Loading secure payment details…</p>\n {resumePurchase ? null : (\n <button onClick={onBack} type=\"button\">\n Back to item\n </button>\n )}\n </div>\n );\n }\n let paymentOptions: StripeElementsOptionsMode = {\n mode: \"setup\",\n setupFutureUsage: \"off_session\",\n };\n if (resumePurchase) {\n paymentOptions = {\n amount: resumePurchase.pricing.totalCents,\n currency: \"usd\",\n mode: \"payment\",\n };\n } else if (item.saleMode === \"buy_now\") {\n paymentOptions = {\n amount: getAuctionSelectionPricing(auction, item, selection).totalCents,\n currency: \"usd\",\n mode: \"payment\",\n };\n }\n const options: StripeElementsOptions = {\n ...paymentOptions,\n appearance,\n currency: \"usd\",\n paymentMethodTypes: [\"card\"],\n syncAddressCheckbox: \"none\",\n };\n return (\n <Elements options={options} stripe={stripe}>\n <AuctionCheckout {...props} />\n </Elements>\n );\n}\n\nfunction AuctionProgress({ buyNow }: { buyNow: boolean }) {\n return (\n <div className=\"lockerverse-auctions__progress\">\n <span>\n {buyNow ? (\n <ShieldCheck aria-hidden=\"true\" size={16} />\n ) : (\n <Gavel aria-hidden=\"true\" size={16} />\n )}\n {buyNow ? \"Choose quantity\" : \"Place bid\"}\n </span>\n <span>\n <ShieldCheck aria-hidden=\"true\" size={16} />\n {buyNow ? \"Pay securely\" : \"Secure card\"}\n </span>\n <span>\n <TimerReset aria-hidden=\"true\" size={16} />\n {buyNow ? \"Get confirmation\" : \"Wait for close\"}\n </span>\n </div>\n );\n}\n\nfunction AuctionItemResult(\n props: LockerverseAuctionItemProps & {\n item: AuctionItem;\n outcome: LockerverseAuctionOutcome;\n }\n) {\n const { auction, item, outcome } = props;\n return (\n <LockerverseAuctionResult\n auctionName={auction.name}\n className={props.className}\n closesAtLabel={formatAuctionBoundary(auction, \"active\", item)}\n communityName={props.communityName ?? auction.community?.name}\n focusHeading\n imageUrl={\n item.image ?? item.images[0] ?? auction.configuration.image ?? undefined\n }\n itemName={item.name}\n outcome={outcome}\n primaryAction={\n props.onBack\n ? { label: \"View auction items\", onClick: props.onBack }\n : undefined\n }\n style={{\n \"--lockerverse-accent\": auction.community?.color ?? \"#6f8f6d\",\n ...props.style,\n }}\n theme={props.theme}\n />\n );\n}\n\nfunction AuctionItemView(props: LockerverseAuctionItemProps) {\n const {\n auction: initialAuction,\n itemId,\n resumePurchase,\n className,\n theme = \"dark\",\n style,\n } = props;\n const appearanceRoot = useRef<HTMLElement | null>(null);\n const [auction, setAuction] = useState(initialAuction);\n const acceptedHost = useRef(initialAuction);\n const item =\n auction.items.find((candidate) => candidate.id === itemId) ??\n resumePurchase?.item;\n useAuctionBoundary(\n item?.startAt ?? auction.startAt,\n item?.endAt ?? auction.endAt\n );\n const [selection, setSelection] = useState<AuctionSelection | null>(() =>\n resumePurchase\n ? {\n amount: 0,\n includeServiceFee:\n resumePurchase.submission.includeServiceFee ?? false,\n quantity: resumePurchase.submission.quantity,\n }\n : null\n );\n const [interactionLocked, setInteractionLocked] = useState(\n Boolean(resumePurchase)\n );\n const viewMounted = useRef<boolean>(true);\n const hostCallbacks = useRef(props);\n hostCallbacks.current = props;\n const reportedLock = useRef<boolean | null>(null);\n const updateInteractionLock = useCallback((locked: boolean) => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Effect cleanup changes this ref outside the callback.\n if (viewMounted.current) {\n setInteractionLocked(locked);\n }\n if (reportedLock.current !== locked) {\n reportedLock.current = locked;\n notifyHostCallback(hostCallbacks.current.onInteractionLockChange, locked);\n }\n }, []);\n const hasRecovery = Boolean(resumePurchase);\n useEffect(() => {\n viewMounted.current = true;\n updateInteractionLock(hasRecovery);\n return () => {\n viewMounted.current = false;\n };\n }, [hasRecovery, updateInteractionLock]);\n const [contact, setContact] = useState({ email: \"\", phone: \"\" });\n const [paying, setPaying] = useState(Boolean(resumePurchase));\n const [notice, setNotice] = useState<string | null>(null);\n const [outcome, setOutcome] = useState<LockerverseAuctionOutcome | null>(\n null\n );\n\n useEffect(() => {\n if (\n !(paying || interactionLocked || resumePurchase) &&\n acceptedHost.current !== initialAuction\n ) {\n acceptedHost.current = initialAuction;\n setAuction(initialAuction);\n }\n }, [initialAuction, paying, interactionLocked, resumePurchase]);\n\n function review(current: LockerverseAuction, message: string) {\n updateInteractionLock(false);\n // The checkout just fetched this snapshot. Do not restore an older host\n // snapshot that arrived while payment was open; accept its next refresh.\n acceptedHost.current = hostCallbacks.current.auction;\n setAuction(current);\n setSelection(null);\n setPaying(false);\n setNotice(message);\n }\n function continueToPayment(next: AuctionSelection) {\n setNotice(null);\n setSelection(next);\n setPaying(true);\n }\n if (!item) {\n return (\n <div>\n <p role=\"alert\">This auction item is no longer available.</p>\n {props.onBack ? (\n <button onClick={props.onBack} type=\"button\">\n Back to auction items\n </button>\n ) : null}\n </div>\n );\n }\n if (outcome) {\n return (\n <AuctionItemResult\n {...props}\n auction={auction}\n item={item}\n outcome={outcome}\n />\n );\n }\n return (\n <section\n className={[\"lockerverse-auctions\", className].filter(Boolean).join(\" \")}\n data-lockerverse-theme={theme}\n ref={appearanceRoot}\n style={{\n \"--lockerverse-accent\": auction.community?.color ?? \"#6f8f6d\",\n ...style,\n }}\n >\n {props.onBack && !interactionLocked ? (\n <button\n className=\"lockerverse-auctions__back\"\n onClick={props.onBack}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={16} /> All items\n </button>\n ) : null}\n <div className=\"lockerverse-auctions__detail\">\n <AuctionItemDetails auction={auction} item={item} />\n <div className=\"lockerverse-auctions__transaction\">\n {getAuctionDisplayStatus(auction, item) === \"active\" ? (\n <AuctionProgress buyNow={item.saleMode === \"buy_now\"} />\n ) : null}\n {notice ? (\n <p className=\"lockerverse-auctions__notice\" role=\"alert\">\n {notice}\n </p>\n ) : null}\n {paying && selection ? (\n <AuctionPayment\n {...props}\n appearanceRoot={appearanceRoot}\n auction={auction}\n communityName={props.communityName ?? auction.community?.name}\n contact={contact}\n interactionLocked={interactionLocked}\n item={item}\n onBack={() => setPaying(false)}\n onContactChange={setContact}\n onIncludeServiceFeeChange={(includeServiceFee) =>\n setSelection((current) =>\n current\n ? {\n ...current,\n includeServiceFee:\n auction.serviceFeeEnabled && includeServiceFee,\n }\n : current\n )\n }\n onInteractionLockChange={updateInteractionLock}\n onResult={setOutcome}\n onReview={review}\n selection={selection}\n />\n ) : (\n <AuctionItemSelection\n auction={auction}\n initialSelection={selection}\n item={item}\n onBack={props.onBack}\n onContinue={continueToPayment}\n onError={setNotice}\n />\n )}\n {props.onBack && !interactionLocked ? (\n <button\n className=\"lockerverse-auctions__footer-back\"\n onClick={props.onBack}\n type=\"button\"\n >\n Back to auction items <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n ) : null}\n </div>\n </div>\n </section>\n );\n}\n\nexport function LockerverseAuctionItem(props: LockerverseAuctionItemProps) {\n const identity = useRef({\n auctionId: props.auction.id,\n client: props.client,\n itemId: props.itemId,\n });\n if (\n identity.current.client !== props.client ||\n identity.current.auctionId !== props.auction.id ||\n identity.current.itemId !== props.itemId\n ) {\n throw new TypeError(\n \"Auction item identity cannot change. Remount with a new React key.\"\n );\n }\n if (\n props.resumePurchase &&\n (props.resumePurchase.auctionId !== props.auction.id ||\n props.resumePurchase.itemId !== props.itemId ||\n props.resumePurchase.item.id !== props.itemId ||\n props.resumePurchase.item.auctionId !== props.auction.id)\n ) {\n throw new TypeError(\n \"The purchase recovery record belongs to a different auction item.\"\n );\n }\n // Keep the view mounted when a refreshed host snapshot removes the item.\n // Its transaction snapshot remains authoritative until it is safe to leave.\n return <AuctionItemView {...props} />;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"auction-item.js","names":["formatMoney","Close","formatMoney","formatMoney"],"sources":["../src/auction-checkout-view.tsx","../src/auction-payment.ts","../src/auction-checkout.tsx","../src/use-auction-autoplay.ts","../src/auction-photo-filmstrip.tsx","../src/auction-gallery.tsx","../src/auction-item-details.tsx","../src/auction-item-selection.tsx","../src/lockerverse-auction-item.tsx"],"sourcesContent":["import type {\n LockerverseAuctionItem,\n LockerverseAuctionPricing,\n} from \"@lockerverse/sdk/auctions\";\nimport { AddressElement, PaymentElement } from \"@stripe/react-stripe-js\";\nimport type {\n StripeAddressElementChangeEvent,\n StripePaymentElementOptions,\n} from \"@stripe/stripe-js\";\nimport { ArrowRight, ChevronLeft } from \"lucide-react\";\nimport type { FormEventHandler } from \"react\";\nimport { formatAuctionMoney as formatMoney } from \"./auction-display.ts\";\nimport { Checkbox, EmailField, FormField } from \"./form-field.tsx\";\nimport type { PhoneInputValue } from \"./phone-field.tsx\";\nimport { PhoneInput } from \"./phone-field.tsx\";\n\ntype AuctionCheckoutViewProps = {\n buttonText: string;\n communityName: string;\n email: string;\n contactErrors: { email?: string; phone?: string };\n phoneCountry: string;\n id: string;\n includeServiceFee: boolean;\n isPurchase: boolean;\n isTerminal: boolean;\n item: LockerverseAuctionItem;\n locked: boolean;\n message: string | null;\n onBack?: (() => void) | undefined;\n onBillingChange: (event: StripeAddressElementChangeEvent) => void;\n onEmailChange: (value: string) => void;\n onIncludeServiceFeeChange?: ((value: boolean) => void) | undefined;\n onPaymentLoadError: () => void;\n onPhoneChange: (value: PhoneInputValue) => void;\n onSameAsBillingChange: (value: boolean) => void;\n onShippingChange: (event: StripeAddressElementChangeEvent) => void;\n onSubmit: FormEventHandler<HTMLFormElement>;\n phone: string;\n pricing: LockerverseAuctionPricing;\n quantity: number;\n sameAsBilling: boolean;\n serviceFeeCents: number;\n serviceFeeEnabled: boolean;\n showFields: boolean;\n submitDisabled: boolean;\n};\n\nfunction getPaymentOptions(isPurchase: boolean): StripePaymentElementOptions {\n return {\n business: { name: \"Lockerverse\" },\n fields: {\n billingDetails: {\n address: \"never\",\n email: \"never\",\n name: \"never\",\n phone: \"never\",\n },\n },\n terms: {\n applePay: isPurchase ? \"auto\" : \"never\",\n auBecsDebit: \"never\",\n bancontact: \"never\",\n card: \"always\",\n cashapp: \"never\",\n googlePay: \"never\",\n ideal: \"never\",\n paypal: isPurchase ? \"auto\" : \"never\",\n sepaDebit: \"never\",\n sofort: \"never\",\n usBankAccount: \"never\",\n },\n wallets: { applePay: isPurchase ? \"auto\" : \"never\", googlePay: \"never\" },\n };\n}\n\nexport function AuctionCheckoutView(props: AuctionCheckoutViewProps) {\n const { isPurchase, item, pricing, id } = props;\n return (\n <form\n className=\"lockerverse-auctions__checkout\"\n noValidate\n onSubmit={props.onSubmit}\n >\n <div className=\"lockerverse-auctions__checkout-header\">\n <div className=\"lockerverse-auctions__checkout-navigation\">\n <button\n aria-label=\"Back\"\n className=\"lockerverse-auctions__checkout-back\"\n disabled={!props.onBack}\n onClick={props.onBack}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={20} />\n </button>\n <div>\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n Step 2 of 2\n </p>\n <p>{isPurchase ? \"Secure checkout\" : \"Secure payment method\"}</p>\n </div>\n </div>\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n {props.communityName}\n </p>\n <h2>\n {isPurchase\n ? \"Finalize your purchase.\"\n : \"Finalize your bid authorization.\"}\n </h2>\n <p className=\"lockerverse-auctions__checkout-summary\">\n {isPurchase ? (\n <>\n Pay <strong>{formatMoney(pricing.totalCents)}</strong> for{\" \"}\n {props.quantity} {props.quantity === 1 ? \"item\" : \"items\"} of{\" \"}\n <strong>{item.name}</strong>. Your card is charged immediately\n once checkout succeeds.\n </>\n ) : (\n <>\n Authorize a payment method for your bid of{\" \"}\n <strong>{formatMoney(pricing.subtotalCents)}</strong> on{\" \"}\n <strong>{item.name}</strong>. Your card is only charged if this\n bid wins the item.\n </>\n )}\n </p>\n {item.collectShippingAddress && (\n <div className=\"lockerverse-auctions__checkout-physical\">\n <p className=\"lockerverse-auctions__checkout-eyebrow\">\n Physical item\n </p>\n <p>\n This item requires a delivery address. Billing details are used by\n default, and you can switch to a separate delivery address below\n if needed.\n </p>\n </div>\n )}\n </div>\n <div className=\"lockerverse-auctions__checkout-body\">\n {props.showFields && (\n <fieldset disabled={props.locked}>\n <div className=\"lockerverse-auctions__checkout-contact\">\n <EmailField\n error={props.contactErrors.email}\n id={`${id}-email`}\n label=\"Email\"\n name=\"email\"\n onChange={(event) => props.onEmailChange(event.target.value)}\n required\n value={props.email}\n />\n <FormField\n error={props.contactErrors.phone}\n id={`${id}-phone`}\n label=\"Phone\"\n >\n <PhoneInput\n country={props.phoneCountry}\n error={props.contactErrors.phone}\n errorId={`${id}-phone-error`}\n id={`${id}-phone`}\n name=\"phone\"\n onChange={props.onPhoneChange}\n required\n value={props.phone}\n />\n </FormField>\n </div>\n <section\n aria-label=\"Payment Information\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <div className=\"lockerverse-auctions__checkout-section-heading\">\n <h3>Payment Information</h3>\n <p>\n {isPurchase\n ? \"Processed securely and charged immediately for this purchase.\"\n : \"Stored securely and charged only if your bid finishes on top.\"}\n </p>\n </div>\n <PaymentElement\n onLoadError={props.onPaymentLoadError}\n options={getPaymentOptions(isPurchase)}\n />\n </section>\n <section\n aria-label=\"Billing Details\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <h3>Billing Details</h3>\n <AddressElement\n onChange={props.onBillingChange}\n options={{ mode: \"billing\" }}\n />\n <p>\n {isPurchase\n ? \"Use your full name here. We use the email and phone above for purchase confirmation and fulfillment updates.\"\n : \"Use the bidder's full name here. We use the email and phone above to contact you if this bid is outbid or wins.\"}\n </p>\n </section>\n {item.collectShippingAddress && (\n <section\n aria-label=\"Delivery Details\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n <label\n className=\"lockerverse-auctions__checkout-checkbox lockerverse-auctions__checkout-delivery\"\n htmlFor={`${id}-delivery-same-as-billing`}\n >\n <Checkbox\n checked={props.sameAsBilling}\n id={`${id}-delivery-same-as-billing`}\n onChange={(event) =>\n props.onSameAsBillingChange(event.target.checked)\n }\n />\n <span>\n <strong>Delivery address is the same as billing</strong>\n <span>\n Leave this on for the fastest flow. Turn it off only if\n the delivery address should differ from the billing\n details above.\n </span>\n </span>\n </label>\n {!props.sameAsBilling && (\n <>\n <h3>Delivery Address</h3>\n <AddressElement\n onChange={props.onShippingChange}\n options={{ mode: \"shipping\" }}\n />\n </>\n )}\n </section>\n )}\n {props.serviceFeeEnabled && <CheckoutServiceFee {...props} />}\n </fieldset>\n )}\n {props.message && (\n <p\n aria-live=\"polite\"\n className=\"lockerverse-auctions__notice\"\n role=\"status\"\n >\n {props.message}\n </p>\n )}\n {!props.isTerminal && (\n <div className=\"lockerverse-auctions__checkout-footer\">\n <p>\n {isPurchase\n ? \"By continuing, you agree to be charged for this purchase.\"\n : \"By continuing, you agree to have this payment method stored for item settlement if your bid is the winning offer.\"}\n {item.collectShippingAddress\n ? ` Your delivery details are stored with the ${isPurchase ? \"order\" : \"bid\"} so the seller can fulfill the item after payment.`\n : \"\"}\n </p>\n <button\n className=\"lockerverse-auctions__button lockerverse-auctions__checkout-submit\"\n disabled={props.submitDisabled}\n type=\"submit\"\n >\n {props.buttonText}\n <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n </div>\n )}\n </div>\n </form>\n );\n}\n\nfunction CheckoutServiceFee(props: AuctionCheckoutViewProps) {\n const { isPurchase, pricing } = props;\n return (\n <section\n aria-label=\"Processing fees\"\n className=\"lockerverse-auctions__checkout-section\"\n >\n {props.onIncludeServiceFeeChange ? (\n <label\n className=\"lockerverse-auctions__checkout-checkbox\"\n htmlFor={`${props.id}-service-fee`}\n >\n <Checkbox\n checked={props.includeServiceFee}\n id={`${props.id}-service-fee`}\n onChange={(event) =>\n props.onIncludeServiceFeeChange?.(event.target.checked)\n }\n />\n <span>\n <strong>\n {isPurchase ? \"Add\" : \"If I win, add\"}{\" \"}\n {formatMoney(props.serviceFeeCents)} to help cover processing fees\n </strong>\n <span>\n {isPurchase ? \"Total\" : \"Total if I win\"}:{\" \"}\n {formatMoney(pricing.totalCents)}\n </span>\n </span>\n </label>\n ) : (\n <p>\n {isPurchase ? \"Total\" : \"Total if I win\"}:{\" \"}\n {formatMoney(pricing.totalCents)}\n </p>\n )}\n </section>\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionBidResult,\n LockerverseAuctionItem,\n LockerverseAuctionPricing,\n} from \"@lockerverse/sdk/auctions\";\nimport {\n calculateLockerverseAuctionPricing,\n getLockerverseAuctionMinimumBid,\n} from \"@lockerverse/sdk/auctions\";\nimport type {\n Stripe,\n StripeAddressElementChangeEvent,\n StripeElements,\n} from \"@stripe/stripe-js\";\nimport { getAuctionDisplayStatus } from \"./auction-display.ts\";\n\nexport type AuctionSelection = {\n amount: number;\n quantity: number;\n includeServiceFee: boolean;\n};\n\nexport function getAuctionSelectionPricing(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n return calculateLockerverseAuctionPricing(\n auction,\n item.saleMode === \"buy_now\"\n ? (item.buyNowPriceAmount ?? 0) * selection.quantity\n : selection.amount,\n selection.includeServiceFee\n );\n}\n\nexport function getAuctionSelectionError(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n if (getAuctionDisplayStatus(auction, item) !== \"active\") {\n return \"This item is not accepting bids or purchases.\";\n }\n if (item.saleMode === \"hybrid\") {\n return \"This item type is not supported for checkout.\";\n }\n if (item.saleMode === \"buy_now\") {\n if (item.isSoldOut || item.availableQuantity === 0) {\n return \"This item is sold out.\";\n }\n if (\n !(item.buyNowPriceAmount && Number.isSafeInteger(selection.quantity)) ||\n selection.quantity < 1 ||\n (item.availableQuantity !== null &&\n selection.quantity > item.availableQuantity)\n ) {\n return \"Select an available quantity.\";\n }\n } else if (\n !Number.isSafeInteger(selection.amount) ||\n selection.amount % 100 !== 0 ||\n selection.amount < getLockerverseAuctionMinimumBid(item)\n ) {\n return \"Enter a whole-dollar bid at or above the minimum bid.\";\n }\n return null;\n}\n\nexport function hasAuctionCheckoutChanged(\n previous: LockerverseAuction,\n current: LockerverseAuction,\n item: LockerverseAuctionItem,\n nextItem: LockerverseAuctionItem,\n selection: AuctionSelection\n) {\n return (\n previous.payment?.publishableKey !== current.payment?.publishableKey ||\n previous.payment?.connectedAccountId !==\n current.payment?.connectedAccountId ||\n previous.serviceFeeEnabled !== current.serviceFeeEnabled ||\n item.saleMode !== nextItem.saleMode ||\n item.collectShippingAddress !== nextItem.collectShippingAddress ||\n JSON.stringify(getAuctionSelectionPricing(previous, item, selection)) !==\n JSON.stringify(getAuctionSelectionPricing(current, nextItem, selection))\n );\n}\n\nexport function auctionExpectedPricing(pricing: LockerverseAuctionPricing) {\n return {\n expectedServiceFeeCents: pricing.serviceFeeCents,\n expectedSubtotalCents: pricing.subtotalCents,\n expectedTotalCents: pricing.totalCents,\n };\n}\n\nexport async function createAuctionConfirmationToken({\n stripe,\n elements,\n email,\n phone,\n billing,\n shipping,\n collectShippingAddress,\n}: {\n stripe: Stripe;\n elements: StripeElements;\n email: string;\n phone: string;\n billing: StripeAddressElementChangeEvent | null;\n shipping: StripeAddressElementChangeEvent | null;\n collectShippingAddress: boolean;\n}) {\n if (!(billing?.complete && billing.value.name.trim())) {\n throw new Error(\"Complete your billing name and address.\");\n }\n if (\n collectShippingAddress &&\n !(shipping?.complete && shipping.value.name.trim())\n ) {\n throw new Error(\"Complete your shipping name and address.\");\n }\n const submitted = await elements.submit();\n if (submitted.error) {\n throw new Error(submitted.error.message ?? \"Check your payment details.\");\n }\n const result = await stripe.createConfirmationToken({\n elements,\n params: {\n payment_method_data: {\n allow_redisplay: \"always\",\n billing_details: {\n address: billing.value.address,\n email,\n name: billing.value.name,\n phone,\n },\n },\n return_url: window.location.href,\n ...(collectShippingAddress && shipping\n ? {\n shipping: {\n address: shipping.value.address,\n name: shipping.value.name,\n phone,\n },\n }\n : undefined),\n },\n });\n if (result.error || !result.confirmationToken) {\n throw new Error(\n result.error?.message ?? \"Unable to prepare payment details.\"\n );\n }\n return result.confirmationToken.id;\n}\n\nexport async function completeAuctionAction(\n stripe: Stripe,\n result: LockerverseAuctionBidResult\n) {\n if (!result.requiresAction) {\n return;\n }\n if (!result.clientSecret) {\n throw new Error(\n \"Payment confirmation is incomplete. Check its status before trying again.\"\n );\n }\n const action = await stripe.handleNextAction({\n clientSecret: result.clientSecret,\n });\n if (action.error) {\n throw new Error(\n action.error.message ?? \"Payment confirmation is incomplete.\"\n );\n }\n}\n","// biome-ignore-all lint/suspicious/noUnnecessaryConditions: React refs change in effect cleanup and event handlers outside this static control flow.\nimport {\n type LockerverseAuction,\n type LockerverseAuctionItem,\n type LockerverseAuctionPurchaseResult,\n LockerverseSdkError,\n} from \"@lockerverse/sdk/auctions\";\nimport { useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport type { StripeAddressElementChangeEvent } from \"@stripe/stripe-js\";\nimport { type FormEvent, useEffect, useId, useRef, useState } from \"react\";\nimport { AuctionCheckoutView } from \"./auction-checkout-view.tsx\";\nimport type {\n LockerverseAuctionItemProps,\n LockerverseAuctionPurchaseRecovery,\n} from \"./auction-item-types.ts\";\nimport {\n type AuctionSelection,\n auctionExpectedPricing,\n completeAuctionAction,\n createAuctionConfirmationToken,\n getAuctionSelectionError,\n getAuctionSelectionPricing,\n hasAuctionCheckoutChanged,\n} from \"./auction-payment.ts\";\nimport type { LockerverseAuctionOutcome } from \"./auction-result.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { type ContactErrors, validateContact } from \"./payment-validation.ts\";\nimport { getInternationalPhone, resolvePhoneCountry } from \"./phone.ts\";\n\ntype AuctionCheckoutProps = LockerverseAuctionItemProps & {\n item: LockerverseAuctionItem;\n selection: AuctionSelection;\n onReview: (auction: LockerverseAuction, message: string) => void;\n onBack: () => void;\n contact?: { email: string; phone: string };\n onContactChange?: (contact: { email: string; phone: string }) => void;\n onIncludeServiceFeeChange?: (value: boolean) => void;\n onInteractionLockChange?: (locked: boolean) => void;\n onResult: (outcome: LockerverseAuctionOutcome) => void;\n};\n\ntype CheckoutState =\n | \"ready\"\n | \"busy\"\n | \"pending\"\n | \"retry\"\n | \"complete\"\n | \"uncertain\";\n\nfunction getSubmitLabel(\n state: CheckoutState,\n hasRecovery: boolean,\n isPurchase: boolean\n) {\n if (state === \"busy\") {\n return isPurchase ? \"Processing...\" : \"Authorizing...\";\n }\n if (state === \"retry\") {\n return \"Retry original purchase\";\n }\n if (hasRecovery) {\n return \"Check purchase status\";\n }\n return isPurchase ? \"Buy Now\" : \"Authorize Bid\";\n}\n\nexport function AuctionCheckout(props: AuctionCheckoutProps) {\n const { auction, item, selection, client, onReview, onBack } = props;\n const stripe = useStripe();\n const elements = useElements();\n const id = useId();\n const [email, setEmail] = useState(props.contact?.email ?? \"\");\n const [phone, setPhone] = useState(props.contact?.phone ?? \"\");\n const [phoneCountry, setPhoneCountry] = useState<string>(() =>\n resolvePhoneCountry(props.contact?.phone ?? \"\")\n );\n const [contactErrors, setContactErrors] = useState<ContactErrors>({});\n const [sameAsBilling, setSameAsBilling] = useState(true);\n const [billing, setBilling] =\n useState<StripeAddressElementChangeEvent | null>(null);\n const [shipping, setShipping] =\n useState<StripeAddressElementChangeEvent | null>(null);\n const [recovery, setRecovery] = useState(props.resumePurchase ?? null);\n const [state, setState] = useState<CheckoutState>(\n props.resumePurchase ? \"pending\" : \"ready\"\n );\n const [message, setMessage] = useState<string | null>(null);\n const purchaseRequestId = useRef<string | null>(\n props.resumePurchase?.submission.clientRequestId ?? null\n );\n const isTerminal = state === \"complete\" || state === \"uncertain\";\n const busy = useRef<boolean>(false);\n const mounted = useRef<boolean>(true);\n const callbacks = useRef(props);\n callbacks.current = props;\n const outcomeReported = useRef(false);\n\n function transition(next: CheckoutState) {\n if (mounted.current) {\n setState(next);\n }\n notifyHostCallback(\n callbacks.current.onInteractionLockChange,\n next !== \"ready\" && next !== \"complete\"\n );\n }\n function showMessage(value: string | null) {\n if (mounted.current) {\n setMessage(value);\n }\n }\n function reportUncertain(kind: \"bid\" | \"purchase\") {\n transition(kind === \"bid\" ? \"uncertain\" : \"pending\");\n showMessage(\n kind === \"bid\"\n ? \"We could not confirm your bid. Do not submit another bid until you check your email or contact the auction organizer.\"\n : \"We could not confirm the purchase result. Check its status using the same purchase request.\"\n );\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onUncertain, kind);\n }\n }\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const isPurchase =\n Boolean(recovery ?? props.resumePurchase) || item.saleMode === \"buy_now\";\n const pricing =\n recovery?.pricing ??\n props.resumePurchase?.pricing ??\n getAuctionSelectionPricing(auction, item, selection);\n\n const payment =\n recovery?.payment ?? props.resumePurchase?.payment ?? auction.payment;\n\n function rememberPurchase(value: LockerverseAuctionPurchaseRecovery | null) {\n if (mounted.current) {\n setRecovery(value);\n }\n notifyHostCallback(callbacks.current.onPurchaseRecoveryChange, value);\n }\n\n function finishPurchase(result: LockerverseAuctionPurchaseResult) {\n if (result.status === \"paid\") {\n purchaseRequestId.current = null;\n rememberPurchase(null);\n transition(\"complete\");\n notifyHostCallback(callbacks.current.onResult, {\n kind: \"purchase\",\n purchaseId: result.purchaseId,\n quantity: result.quantity,\n serviceFeeCents: result.serviceFeeCents,\n status: \"paid\",\n subtotalCents: result.subtotalCents,\n totalCents: result.totalCents,\n unitAmountCents: result.subtotalCents / result.quantity,\n });\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onPurchaseComplete, result);\n }\n } else if (result.status === \"pending_payment\") {\n transition(\"pending\");\n showMessage(\n \"Your purchase is pending. Check its status before making another payment.\"\n );\n } else {\n purchaseRequestId.current = null;\n rememberPurchase(null);\n transition(\"ready\");\n showMessage(\n `This purchase is ${result.status.replaceAll(\"_\", \" \")}. You can start a new purchase.`\n );\n }\n }\n\n function readContact() {\n const phoneNumber = getInternationalPhone(phone, phoneCountry);\n const contact = validateContact({ email, phone: phoneNumber }, true);\n setContactErrors(contact.errors);\n if (!contact.value) {\n document\n .getElementById(`${id}-${contact.errors.email ? \"email\" : \"phone\"}`)\n ?.focus();\n return null;\n }\n return { email: contact.value.email, phone: phoneNumber };\n }\n\n async function prepareSubmission(\n contact: { email: string; phone: string } | null\n ) {\n if (!contact) {\n throw new Error(\"Check the contact fields below.\");\n }\n if (!(stripe && elements && auction.payment)) {\n throw new Error(\"Payment details are still loading.\");\n }\n const current = await client.load(auction.slug);\n if (!mounted.current) {\n return null;\n }\n const currentItem = current.items.find(\n (candidate) => candidate.id === item.id\n );\n if (!currentItem) {\n onReview(current, \"This item is no longer available.\");\n return null;\n }\n const selectionError = getAuctionSelectionError(\n current,\n currentItem,\n selection\n );\n if (\n selectionError ||\n hasAuctionCheckoutChanged(auction, current, item, currentItem, selection)\n ) {\n onReview(\n current,\n selectionError ??\n \"The checkout details changed. Review them before continuing.\"\n );\n return null;\n }\n const confirmationToken = await createAuctionConfirmationToken({\n billing,\n collectShippingAddress: item.collectShippingAddress,\n elements,\n email: contact.email,\n phone: contact.phone,\n shipping: sameAsBilling ? billing : shipping,\n stripe,\n });\n if (!mounted.current) {\n return null;\n }\n return {\n confirmationToken,\n email: contact.email,\n includeServiceFee: selection.includeServiceFee,\n phone: contact.phone,\n ...auctionExpectedPricing(pricing),\n };\n }\n\n async function sendBid(\n submission: NonNullable<Awaited<ReturnType<typeof prepareSubmission>>>\n ) {\n const result = await client.createBid(auction.slug, item.id, {\n ...submission,\n amount: selection.amount,\n });\n if (result.requiresAction) {\n if (!(mounted.current && stripe)) {\n reportUncertain(\"bid\");\n return;\n }\n await completeAuctionAction(stripe, result);\n }\n transition(\"complete\");\n notifyHostCallback(callbacks.current.onResult, {\n amountCents: result.subtotalCents,\n kind: \"bid\",\n });\n if (!outcomeReported.current) {\n outcomeReported.current = true;\n notifyHostCallback(callbacks.current.onBidSubmitted, result);\n }\n }\n\n async function resolvePurchase(\n result: LockerverseAuctionPurchaseResult,\n active: LockerverseAuctionPurchaseRecovery\n ) {\n if (result.requiresAction) {\n if (!(mounted.current && stripe)) {\n reportUncertain(\"purchase\");\n return;\n }\n await completeAuctionAction(stripe, result);\n const updated = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (updated) {\n finishPurchase(updated);\n } else {\n transition(\"pending\");\n showMessage(\n \"Payment status is not available yet. Check again shortly.\"\n );\n }\n return;\n }\n finishPurchase(result);\n if (!mounted.current && result.status === \"pending_payment\") {\n reportUncertain(\"purchase\");\n }\n }\n\n async function checkPurchase(active: LockerverseAuctionPurchaseRecovery) {\n const result = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (result) {\n await resolvePurchase(result, active);\n } else {\n if (!mounted.current) {\n reportUncertain(\"purchase\");\n return;\n }\n transition(\"retry\");\n showMessage(\n \"No purchase is recorded yet. You can retry the original purchase with the same request ID.\"\n );\n }\n }\n\n async function clearRejectedPurchase(\n error: LockerverseSdkError,\n active: LockerverseAuctionPurchaseRecovery\n ) {\n const result = await client.getPurchaseStatus(\n auction.slug,\n item.id,\n active.submission.clientRequestId\n );\n if (result) {\n await resolvePurchase(result, active);\n return;\n }\n rememberPurchase(null);\n transition(\"ready\");\n showMessage(\n `The purchase was rejected. Review the item and payment details before trying again. (${error.status ?? \"validation\"})`\n );\n }\n\n async function handleFailure<Failure>(\n error: Failure,\n requestSent: boolean,\n active: LockerverseAuctionPurchaseRecovery | null,\n wasRecovery: boolean\n ) {\n const uncertain =\n requestSent &&\n (!(error instanceof LockerverseSdkError) || error.recoveryRecommended);\n showMessage(\n error instanceof Error\n ? error.message\n : \"Unable to complete this request.\"\n );\n if (isPurchase && active) {\n if (\n !wasRecovery &&\n error instanceof LockerverseSdkError &&\n !error.recoveryRecommended\n ) {\n try {\n await clearRejectedPurchase(error, active);\n return;\n } catch {\n /* Keep the original request when status cannot be established. */\n }\n }\n reportUncertain(\"purchase\");\n } else if (uncertain) {\n reportUncertain(\"bid\");\n } else {\n transition(\"ready\");\n }\n }\n\n function getPurchaseRequestId() {\n purchaseRequestId.current ??= globalThis.crypto.randomUUID();\n return purchaseRequestId.current;\n }\n\n function canSendPurchase() {\n if (mounted.current) {\n return true;\n }\n if (!recovery) {\n rememberPurchase(null);\n transition(\"ready\");\n }\n return false;\n }\n\n async function sendOrCheckPurchase(\n active: LockerverseAuctionPurchaseRecovery,\n statusOnly: boolean\n ) {\n if (statusOnly) {\n await checkPurchase(active);\n return;\n }\n if (!canSendPurchase()) {\n return;\n }\n const result = await client.createPurchase(\n auction.slug,\n item.id,\n active.submission\n );\n await resolvePurchase(result, active);\n }\n\n const checkoutPayment = stripe && elements && payment;\n\n function startSubmission() {\n if (busy.current || isTerminal) {\n return null;\n }\n if (!checkoutPayment) {\n showMessage(\"Payment details are still loading.\");\n return null;\n }\n const contact = recovery ? null : readContact();\n if (!(recovery || contact)) {\n return null;\n }\n return { checkoutPayment, contact, retryOriginal: state === \"retry\" };\n }\n\n async function submit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n const start = startSubmission();\n if (!start) {\n return;\n }\n const { contact, checkoutPayment: readyPayment, retryOriginal } = start;\n busy.current = true;\n outcomeReported.current = false;\n transition(\"busy\");\n showMessage(null);\n let requestSent = false;\n let activeRecovery = recovery;\n try {\n if (!activeRecovery) {\n const submission = await prepareSubmission(contact);\n if (!(submission && mounted.current)) {\n transition(\"ready\");\n return;\n }\n if (!isPurchase) {\n requestSent = true;\n await sendBid(submission);\n return;\n }\n activeRecovery = Object.freeze({\n auctionId: auction.id,\n item,\n itemId: item.id,\n payment: Object.freeze({ ...readyPayment }),\n pricing,\n submission: Object.freeze({\n ...submission,\n clientRequestId: getPurchaseRequestId(),\n paymentMethodTypes: Object.freeze([\"card\"] as const),\n quantity: selection.quantity,\n }),\n });\n rememberPurchase(activeRecovery);\n }\n requestSent = true;\n await sendOrCheckPurchase(\n activeRecovery,\n Boolean(recovery) && !retryOriginal\n );\n } catch (error) {\n await handleFailure(\n error,\n requestSent,\n activeRecovery,\n recovery !== null && !retryOriginal\n );\n } finally {\n busy.current = false;\n }\n }\n\n const buttonText = getSubmitLabel(state, recovery !== null, isPurchase);\n\n const locked = state !== \"ready\";\n return (\n <AuctionCheckoutView\n buttonText={buttonText}\n communityName={props.communityName ?? auction.name}\n contactErrors={contactErrors}\n email={email}\n id={id}\n includeServiceFee={selection.includeServiceFee}\n isPurchase={isPurchase}\n isTerminal={isTerminal}\n item={item}\n locked={locked}\n message={message}\n onBack={state === \"ready\" ? onBack : undefined}\n onBillingChange={setBilling}\n onEmailChange={(value) => {\n setEmail(value);\n props.onContactChange?.({\n email: value,\n phone: getInternationalPhone(phone, phoneCountry),\n });\n }}\n onIncludeServiceFeeChange={props.onIncludeServiceFeeChange}\n onPaymentLoadError={() => showMessage(\"Unable to load payment form.\")}\n onPhoneChange={({ value, country }) => {\n setPhone(value);\n setPhoneCountry(country);\n props.onContactChange?.({\n email,\n phone: getInternationalPhone(value, country),\n });\n }}\n onSameAsBillingChange={setSameAsBilling}\n onShippingChange={setShipping}\n onSubmit={submit}\n phone={phone}\n phoneCountry={phoneCountry}\n pricing={pricing}\n quantity={selection.quantity}\n sameAsBilling={sameAsBilling}\n serviceFeeCents={\n recovery\n ? pricing.serviceFeeCents\n : getAuctionSelectionPricing(auction, item, {\n ...selection,\n includeServiceFee: auction.serviceFeeEnabled,\n }).serviceFeeCents\n }\n serviceFeeEnabled={auction.serviceFeeEnabled}\n showFields={!(recovery || isTerminal)}\n submitDisabled={state === \"busy\" || !stripe || !elements}\n />\n );\n}\n","import Autoplay from \"embla-carousel-autoplay\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nconst PHOTO_DELAY = 6000;\n\n// Embla 8 has stop(), but no pause(). Resume with the saved delay, then restore\n// the full delay on selection. Embla remains the only owner of the slide timer.\nexport function useAuctionAutoplay(enabled: boolean, reducedMotion: boolean) {\n const remaining = useRef(PHOTO_DELAY);\n const progressRef = useRef<HTMLDivElement>(null);\n const [cycleDelay, setCycleDelay] = useState(PHOTO_DELAY);\n const autoplay = useMemo(\n () =>\n Autoplay({\n delay: cycleDelay,\n playOnInit: false,\n stopOnFocusIn: false,\n stopOnInteraction: true,\n stopOnMouseEnter: false,\n }),\n [cycleDelay]\n );\n\n const [viewportRef, embla] = useEmblaCarousel(\n { duration: reducedMotion ? 0 : 25, loop: true },\n [autoplay]\n );\n\n const draw = useCallback(() => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns this ref in the filmstrip component.\n if (progressRef.current) {\n progressRef.current.style.transform = `scaleX(${1 - remaining.current / PHOTO_DELAY})`;\n }\n }, []);\n\n const freeze = useCallback(() => {\n const left = autoplay.timeUntilNext();\n if (left !== null) {\n remaining.current = Math.max(1, Math.min(PHOTO_DELAY, left));\n }\n autoplay.stop();\n draw();\n }, [autoplay, draw]);\n\n const reset = useCallback(() => {\n remaining.current = PHOTO_DELAY;\n setCycleDelay(PHOTO_DELAY);\n autoplay.reset();\n draw();\n }, [autoplay, draw]);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n if (!enabled) {\n freeze();\n } else if (cycleDelay === remaining.current) {\n autoplay.play();\n } else {\n setCycleDelay(remaining.current);\n }\n }, [embla, enabled, autoplay, cycleDelay, setCycleDelay, remaining, freeze]);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n let frame = 0;\n const update = () => {\n const left = autoplay.timeUntilNext();\n if (!enabled || left === null) {\n return;\n }\n remaining.current = Math.max(0, Math.min(PHOTO_DELAY, left));\n draw();\n frame = requestAnimationFrame(update);\n };\n const start = () => {\n cancelAnimationFrame(frame);\n if (enabled) {\n frame = requestAnimationFrame(update);\n }\n };\n const stop = () => cancelAnimationFrame(frame);\n const reinitialize = () => {\n if (enabled) {\n autoplay.play();\n }\n };\n embla\n .on(\"select\", reset)\n .on(\"reInit\", reinitialize)\n .on(\"autoplay:timerset\", start)\n .on(\"autoplay:timerstopped\", stop);\n draw();\n start();\n return () => {\n stop();\n embla\n .off(\"select\", reset)\n .off(\"reInit\", reinitialize)\n .off(\"autoplay:timerset\", start)\n .off(\"autoplay:timerstopped\", stop);\n };\n }, [embla, autoplay, enabled, remaining, reset, draw]);\n return { embla, freeze, progressRef, reset, viewportRef };\n}\n","import { ChevronLeft, ChevronRight, Pause, Play } from \"lucide-react\";\nimport {\n type PointerEvent,\n type Ref,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useAuctionAutoplay } from \"./use-auction-autoplay\";\nimport { useAuctionVisibility } from \"./use-auction-visibility\";\n\ntype FilmstripProps = {\n photos: string[];\n name: string;\n selected: number;\n paused?: boolean;\n photoButtonRef: Ref<HTMLButtonElement>;\n onSelect: (index: number) => void;\n onExpand: (index: number) => void;\n};\n\nexport function AuctionPhotoFilmstrip({\n photos,\n name,\n selected,\n paused = false,\n photoButtonRef,\n onSelect,\n onExpand,\n}: FilmstripProps) {\n const stripRef = useRef<HTMLDivElement>(null);\n const keyboardPhoto = useRef<HTMLButtonElement | null>(null);\n const thumbnailRefs = useRef<(HTMLButtonElement | null)[]>([]);\n const [reducedMotion, setReducedMotion] = useState(true);\n const [hovered, setHovered] = useState(false);\n const [keyboardFocused, setKeyboardFocused] = useState(false);\n const [userPaused, setUserPaused] = useState(false);\n const [dragging, setDragging] = useState(false);\n const { ref: galleryRef, visible } = useAuctionVisibility<HTMLElement>();\n const [controlsActive, setControlsActive] = useState(false);\n const [touchControls, setTouchControls] = useState(true);\n const hideControlsTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const controlsVisible = touchControls || controlsActive || keyboardFocused;\n const controlsFade = `lockerverse-auction-gallery__control ${controlsVisible ? \"is-visible\" : \"\"}`;\n\n const scheduleControlsHide = () => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The timer ref is assigned after pointer activity.\n if (hideControlsTimer.current) {\n clearTimeout(hideControlsTimer.current);\n }\n hideControlsTimer.current = setTimeout(\n () => setControlsActive(false),\n 2000\n );\n };\n const showControls = (event: PointerEvent<HTMLDivElement>) => {\n if (event.pointerType !== \"mouse\") {\n setTouchControls(true);\n return;\n }\n setControlsActive(true);\n // biome-ignore lint/suspicious/noUnnecessaryConditions: The timer ref is assigned after pointer activity.\n if (hideControlsTimer.current) {\n clearTimeout(hideControlsTimer.current);\n }\n if (\n !(\n event.target instanceof Element &&\n event.target.closest(\"[data-gallery-control]\")\n )\n ) {\n scheduleControlsHide();\n }\n };\n\n useEffect(() => {\n const preference = window.matchMedia(\"(hover: none), (pointer: coarse)\");\n const update = () => setTouchControls(preference.matches);\n update();\n preference.addEventListener(\"change\", update);\n return () => {\n preference.removeEventListener(\"change\", update);\n clearTimeout(hideControlsTimer.current ?? undefined);\n };\n }, []);\n\n const autoplayEnabled =\n !(\n paused ||\n reducedMotion ||\n hovered ||\n keyboardFocused ||\n userPaused ||\n dragging\n ) && visible;\n const count = photos.length;\n const current = count ? ((selected % count) + count) % count : 0;\n const { viewportRef, embla, progressRef, freeze, reset } = useAuctionAutoplay(\n autoplayEnabled && count > 1,\n reducedMotion\n );\n\n useEffect(() => {\n const preference = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n const update = () => setReducedMotion(preference.matches);\n update();\n preference.addEventListener(\"change\", update);\n return () => preference.removeEventListener(\"change\", update);\n }, []);\n\n useEffect(() => {\n if (!embla) {\n return;\n }\n const select = () => onSelect(embla.selectedScrollSnap());\n embla.on(\"select\", select).on(\"reInit\", select);\n return () => {\n embla.off(\"select\", select).off(\"reInit\", select);\n };\n }, [embla, onSelect]);\n\n useEffect(() => {\n if (embla && embla.selectedScrollSnap() !== current) {\n embla.scrollTo(current, true);\n }\n }, [embla, current]);\n\n useEffect(() => {\n const updateVisibility = () => {\n if (document.hidden) {\n freeze();\n }\n };\n const release = () => setDragging(false);\n updateVisibility();\n document.addEventListener(\"visibilitychange\", updateVisibility, true);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"pointercancel\", release);\n return () => {\n document.removeEventListener(\"visibilitychange\", updateVisibility, true);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"pointercancel\", release);\n };\n }, [freeze]);\n\n const selectPhoto = (next: number) => {\n embla?.scrollTo((next + count) % count, reducedMotion);\n reset();\n };\n\n useEffect(() => {\n const previousPhoto = keyboardPhoto.current;\n keyboardPhoto.current = null;\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Keyboard events assign this ref before the selected photo changes.\n if (previousPhoto && document.activeElement === previousPhoto) {\n galleryRef.current\n ?.querySelector<HTMLButtonElement>(\n '.lockerverse-auction-gallery__photo[tabindex=\"0\"]'\n )\n ?.focus({ preventScroll: true });\n }\n }, [current, galleryRef]);\n\n useEffect(() => {\n const strip = stripRef.current;\n const thumbnail = thumbnailRefs.current[current];\n // biome-ignore lint/suspicious/noUnnecessaryConditions: React assigns the element ref after mounting.\n if (!(strip && thumbnail)) {\n return;\n }\n const stripBounds = strip.getBoundingClientRect();\n const photoBounds = thumbnail.getBoundingClientRect();\n if (photoBounds.left < stripBounds.left) {\n strip.scrollLeft -= stripBounds.left - photoBounds.left;\n } else if (photoBounds.right > stripBounds.right) {\n strip.scrollLeft += photoBounds.right - stripBounds.right;\n }\n }, [current, count]);\n\n return (\n // biome-ignore lint/a11y/noNoninteractiveElementInteractions: The gallery handles keys from its focusable photo and navigation buttons.\n <section\n aria-label={`${name} photos`}\n className=\"lockerverse-auction-gallery\"\n onBlurCapture={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n setKeyboardFocused(false);\n }\n }}\n onFocusCapture={(event) =>\n setKeyboardFocused(event.target.matches(\":focus-visible\"))\n }\n onKeyDown={(event) => {\n if (\n count < 2 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n ) {\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault();\n if (\n event.target instanceof HTMLButtonElement &&\n event.target.classList.contains(\n \"lockerverse-auction-gallery__photo\"\n )\n ) {\n keyboardPhoto.current = event.target;\n }\n selectPhoto(current + (event.key === \"ArrowRight\" ? 1 : -1));\n }\n }}\n onPointerEnter={(event) => {\n if (event.pointerType === \"mouse\") {\n setHovered(true);\n }\n }}\n onPointerLeave={(event) => {\n if (event.pointerType === \"mouse\") {\n setHovered(false);\n }\n }}\n ref={galleryRef}\n >\n {count ? (\n <div\n className=\"lockerverse-auction-gallery__stage\"\n onPointerEnter={showControls}\n onPointerLeave={scheduleControlsHide}\n onPointerMove={showControls}\n >\n <div\n className=\"lockerverse-auction-gallery__viewport\"\n onPointerDownCapture={() => {\n freeze();\n setDragging(true);\n }}\n ref={viewportRef}\n >\n <div className=\"lockerverse-auction-gallery__track\">\n {photos.map((photo, photoIndex) => (\n <div\n aria-hidden={photoIndex !== current}\n className=\"lockerverse-auction-gallery__slide\"\n key={`${photo}-${photoIndex}`}\n >\n <button\n aria-label={`View photo ${photoIndex + 1} of ${name} at full size`}\n className=\"lockerverse-auction-gallery__photo\"\n onClick={() => {\n onExpand(photoIndex);\n }}\n ref={photoIndex === current ? photoButtonRef : undefined}\n tabIndex={photoIndex === current ? 0 : -1}\n type=\"button\"\n >\n <img\n alt={`${name}, ${photoIndex + 1} of ${count}`}\n className=\"lockerverse-auction-gallery__image\"\n draggable={false}\n height={900}\n loading={\n photoIndex === 0 ||\n photoIndex === current ||\n photoIndex === (current + 1) % count\n ? \"eager\"\n : \"lazy\"\n }\n sizes=\"(max-width: 1280px) 100vw, 45vw\"\n src={photo}\n width={1200}\n />\n </button>\n </div>\n ))}\n </div>\n </div>\n {count > 1 && !reducedMotion && (\n <div className=\"lockerverse-auction-gallery__rotation\">\n <div\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__progress-track\"\n >\n <div\n className=\"lockerverse-auction-gallery__progress\"\n ref={progressRef}\n style={{ transform: \"scaleX(0)\" }}\n />\n </div>\n <button\n aria-label={\n userPaused ? \"Play photo rotation\" : \"Pause photo rotation\"\n }\n className={`lockerverse-auction-gallery__play ${controlsFade}`}\n data-gallery-control\n onClick={() => setUserPaused((value) => !value)}\n title={\n userPaused ? \"Play photo rotation\" : \"Pause photo rotation\"\n }\n type=\"button\"\n >\n {userPaused ? (\n <Play aria-hidden=\"true\" size={13} />\n ) : (\n <Pause aria-hidden=\"true\" size={13} />\n )}\n </button>\n </div>\n )}\n {count > 1 && (\n <>\n <button\n aria-label=\"Previous photo\"\n className={`lockerverse-auction-gallery__previous ${controlsFade}`}\n data-gallery-control\n onClick={() => selectPhoto(current - 1)}\n type=\"button\"\n >\n <ChevronLeft\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__chevron\"\n />\n </button>\n <button\n aria-label=\"Next photo\"\n className={`lockerverse-auction-gallery__next ${controlsFade}`}\n data-gallery-control\n onClick={() => selectPhoto(current + 1)}\n type=\"button\"\n >\n <ChevronRight\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__chevron\"\n />\n </button>\n </>\n )}\n </div>\n ) : (\n <div className=\"lockerverse-auction-gallery__empty\">\n No photo available\n </div>\n )}\n {count > 1 && (\n <section\n aria-label=\"Choose a photo\"\n className=\"lockerverse-auction-gallery__strip\"\n ref={stripRef}\n >\n <div className=\"lockerverse-auction-gallery__thumbnails\">\n {photos.map((photo, photoIndex) => (\n <button\n aria-label={`Show photo ${photoIndex + 1} of ${count}`}\n aria-pressed={current === photoIndex}\n className={`lockerverse-auction-gallery__thumbnail ${current === photoIndex ? \"is-selected\" : \"\"}`}\n key={`${photo}-${photoIndex}`}\n onClick={() => selectPhoto(photoIndex)}\n ref={(element) => {\n thumbnailRefs.current[photoIndex] = element;\n }}\n type=\"button\"\n >\n <img\n alt=\"\"\n className=\"lockerverse-auction-gallery__thumbnail-image\"\n height={66}\n sizes=\"88px\"\n src={photo}\n width={88}\n />\n </button>\n ))}\n </div>\n </section>\n )}\n </section>\n );\n}\n","import { Dialog } from \"@base-ui/react/dialog\";\nimport { ChevronLeft, ChevronRight, X as Close } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { AuctionPhotoFilmstrip } from \"./auction-photo-filmstrip\";\n\nexport function AuctionGallery({\n images,\n fallbackImage,\n name,\n}: {\n images: readonly string[];\n fallbackImage?: string | null;\n name: string;\n}) {\n const photos = [...new Set(images.filter(Boolean))];\n if (!photos.length && fallbackImage) {\n photos.push(fallbackImage);\n }\n const [index, setIndex] = useState(0);\n const [open, setOpen] = useState(false);\n const opener = useRef<HTMLButtonElement | null>(null);\n const swipeStart = useRef<{ x: number; y: number } | null>(null);\n const count = photos.length;\n const selected = count ? ((index % count) + count) % count : 0;\n\n return (\n <>\n <AuctionPhotoFilmstrip\n name={name}\n onExpand={(next) => {\n setIndex(next);\n setOpen(true);\n }}\n onSelect={setIndex}\n paused={open}\n photoButtonRef={opener}\n photos={photos}\n selected={selected}\n />\n {count > 0 && (\n <Dialog.Root onOpenChange={setOpen} open={open}>\n <Dialog.Portal>\n <Dialog.Backdrop className=\"lockerverse-auction-gallery__backdrop\" />\n <Dialog.Popup\n aria-describedby={undefined}\n className=\"lockerverse-auction-gallery__viewer\"\n finalFocus={opener}\n onKeyDown={(event) => {\n if (\n count < 2 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n ) {\n return;\n }\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault();\n setIndex(\n (selected + (event.key === \"ArrowRight\" ? 1 : -1) + count) %\n count\n );\n }\n }}\n >\n <Dialog.Title className=\"lockerverse-auction-gallery__sr-only\">\n {name} · Photo {selected + 1} of {count}\n </Dialog.Title>\n <div\n className=\"lockerverse-auction-gallery__full-image\"\n onTouchCancel={() => {\n swipeStart.current = null;\n }}\n onTouchEnd={(event) => {\n const start = swipeStart.current;\n swipeStart.current = null;\n const end = event.changedTouches.item(0);\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Touch start assigns the shared ref before this event.\n if (!(start && end) || count < 2) {\n return;\n }\n const dx = end.clientX - start.x;\n const dy = end.clientY - start.y;\n if (Math.abs(dx) >= 45 && Math.abs(dx) > Math.abs(dy) * 1.3) {\n setIndex((selected + (dx < 0 ? 1 : -1) + count) % count);\n }\n }}\n onTouchMove={(event) => {\n if (event.touches.length !== 1) {\n swipeStart.current = null;\n }\n }}\n onTouchStart={(event) => {\n const touch = event.touches.item(0);\n swipeStart.current =\n event.touches.length === 1 && touch\n ? { x: touch.clientX, y: touch.clientY }\n : null;\n }}\n >\n <img\n alt={`${name}, ${selected + 1} of ${count}`}\n height={900}\n src={photos[selected]}\n width={1200}\n />\n {open && count > 1 && (\n <img\n alt=\"\"\n aria-hidden=\"true\"\n className=\"lockerverse-auction-gallery__preload\"\n height={900}\n loading=\"eager\"\n src={photos[(selected + 1) % count]}\n width={1200}\n />\n )}\n </div>\n <Dialog.Close\n aria-label=\"Close photo viewer\"\n className=\"lockerverse-auction-gallery__viewer-close\"\n >\n <Close aria-hidden=\"true\" size={22} />\n </Dialog.Close>\n {count > 1 && (\n <>\n <button\n aria-label=\"Previous photo\"\n className=\"lockerverse-auction-gallery__viewer-previous\"\n onClick={() => setIndex((selected - 1 + count) % count)}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={28} />\n </button>\n <button\n aria-label=\"Next photo\"\n className=\"lockerverse-auction-gallery__viewer-next\"\n onClick={() => setIndex((selected + 1) % count)}\n type=\"button\"\n >\n <ChevronRight aria-hidden=\"true\" size={28} />\n </button>\n </>\n )}\n </Dialog.Popup>\n </Dialog.Portal>\n </Dialog.Root>\n )}\n </>\n );\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionItem,\n LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport {\n ChevronDown,\n Clock3,\n Gavel,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport { useId, useState } from \"react\";\nimport { AuctionDescription } from \"./auction-description.tsx\";\nimport {\n formatAuctionBoundary,\n formatAuctionMoney as formatMoney,\n getAuctionDisplayStatus,\n} from \"./auction-display.ts\";\nimport { AuctionGallery } from \"./auction-gallery.tsx\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nfunction metricIcon(label: string | undefined) {\n if (label === \"Buy Now\") {\n return <ShieldCheck aria-hidden=\"true\" size={16} />;\n }\n if (label === \"Available\" || label === \"Increment\") {\n return <TimerReset aria-hidden=\"true\" size={16} />;\n }\n return <Gavel aria-hidden=\"true\" size={16} />;\n}\nfunction itemMetrics(\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (item.saleMode === \"buy_now\") {\n return [\n [\"Buy Now\", formatMoney(item.buyNowPriceAmount ?? 0)],\n [\n \"Available\",\n item.availableQuantity === null\n ? \"Available\"\n : String(item.availableQuantity),\n ],\n ];\n }\n if (status === \"finished\") {\n return [\n [\n \"Final bid\",\n item.maxBidAmount ? formatMoney(item.maxBidAmount) : \"No bids\",\n ],\n ];\n }\n return [\n [\"Current bid\", formatMoney(item.maxBidAmount ?? 0)],\n [\"Floor\", formatMoney(item.minBidAmount ?? 0)],\n [\"Increment\", formatMoney(item.bidIncrementAmount ?? 100)],\n ];\n}\nexport function AuctionItemDetails({\n auction,\n item,\n}: {\n auction: LockerverseAuction;\n item: LockerverseAuctionItem;\n}) {\n useAuctionBoundary(\n item.startAt ?? auction.startAt,\n item.endAt ?? auction.endAt\n );\n const [expanded, setExpanded] = useState(false);\n const descriptionId = useId();\n const status = getAuctionDisplayStatus(auction, item);\n const boundaryLabel = {\n active: \"Closes\",\n draft: \"Opens\",\n finished: \"Closed\",\n }[status];\n const boundary = formatAuctionBoundary(auction, status, item);\n const buyNow = item.saleMode === \"buy_now\";\n const longDescription = (item.description ?? \"\").trim().length > 240;\n const metrics = itemMetrics(item, status);\n return (\n <section className=\"lockerverse-auctions__item-summary\">\n <AuctionGallery\n fallbackImage={\n item.image ??\n auction.configuration.image ??\n auction.community?.banner ??\n auction.community?.thumbnail ??\n null\n }\n images={item.images}\n name={item.name}\n />\n <div className=\"lockerverse-auctions__item-copy\">\n <h2>{item.name}</h2>\n {item.description ? (\n <div className=\"lockerverse-auctions__item-description\">\n <AuctionDescription\n className={\n !expanded && longDescription\n ? \"lockerverse-auctions__description-clamped\"\n : undefined\n }\n description={item.description}\n id={descriptionId}\n />\n {longDescription ? (\n <button\n aria-controls={descriptionId}\n aria-expanded={expanded}\n className=\"lockerverse-auctions__description-toggle\"\n onClick={() => setExpanded(!expanded)}\n type=\"button\"\n >\n {expanded ? \"Hide description\" : \"Read full description\"}{\" \"}\n <ChevronDown\n aria-hidden=\"true\"\n size={16}\n style={{ transform: expanded ? \"rotate(180deg)\" : undefined }}\n />\n </button>\n ) : null}\n </div>\n ) : null}\n <dl className=\"lockerverse-auctions__stat-panel\">\n {metrics.map(([label, value]) => (\n <div className=\"lockerverse-auctions__stat-row\" key={label}>\n <dt>\n {metricIcon(label)}\n {label}\n </dt>\n <dd>{value}</dd>\n </div>\n ))}\n <div className=\"lockerverse-auctions__stat-row\">\n <dt>\n <Clock3 aria-hidden=\"true\" size={16} />\n {boundaryLabel}\n </dt>\n <dd className=\"lockerverse-auctions__stat-date\">{boundary}</dd>\n </div>\n {!buyNow && status === \"finished\" ? (\n <div className=\"lockerverse-auctions__stat-footer\">\n <div>\n <dt>Floor</dt>\n <dd>{formatMoney(item.minBidAmount ?? 0)}</dd>\n </div>\n <div>\n <dt>Bid increment</dt>\n <dd>{formatMoney(item.bidIncrementAmount ?? 100)}</dd>\n </div>\n </div>\n ) : null}\n </dl>\n </div>\n </section>\n );\n}\n","import {\n getLockerverseAuctionMinimumBid,\n type LockerverseAuction,\n type LockerverseAuctionItem,\n type LockerverseAuctionStatus,\n} from \"@lockerverse/sdk/auctions\";\nimport { ArrowRight } from \"lucide-react\";\nimport { type FormEvent, useId, useState } from \"react\";\nimport {\n formatAuctionBoundary,\n formatAuctionMoney as formatMoney,\n getAuctionDisplayStatus,\n isAuctionItemSoldOut,\n} from \"./auction-display.ts\";\nimport {\n type AuctionSelection,\n getAuctionSelectionError,\n getAuctionSelectionPricing,\n} from \"./auction-payment.ts\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nconst WHOLE_NUMBER = /^\\d+$/;\n\ntype SelectionProps = {\n auction: LockerverseAuction;\n item: LockerverseAuctionItem;\n initialSelection: AuctionSelection | null;\n onContinue: (selection: AuctionSelection) => void;\n onError: (message: string) => void;\n onBack?: (() => void) | undefined;\n};\n\nfunction quantitySummary(value: string, amount: number) {\n if (\n !(WHOLE_NUMBER.test(value) && Number.isSafeInteger(Number(value) * amount))\n ) {\n return \"Enter a whole-number quantity.\";\n }\n return `Total: ${formatMoney(Number(value) * amount)}`;\n}\nfunction selectionInitialValue(\n buyNow: boolean,\n initial: AuctionSelection | null,\n minimum: number\n) {\n if (buyNow) {\n return String(initial ? initial.quantity : 1);\n }\n return String(initial ? initial.amount / 100 : minimum);\n}\nfunction readOnlyTitle(\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (isAuctionItemSoldOut(item)) {\n return \"This item is sold out.\";\n }\n if (status === \"draft\") {\n return \"This item is not open yet.\";\n }\n if (status === \"finished\") {\n return item.saleMode === \"buy_now\"\n ? \"Purchases are closed for this item.\"\n : \"Bidding is closed for this item.\";\n }\n return \"This item is not available.\";\n}\nfunction readOnlyDescription(\n auction: LockerverseAuction,\n item: LockerverseAuctionItem,\n status: LockerverseAuctionStatus\n) {\n if (isAuctionItemSoldOut(item)) {\n return \"All available quantities have been purchased.\";\n }\n if (status === \"draft\") {\n return `This item opens ${formatAuctionBoundary(auction, \"draft\", item)}.`;\n }\n return item.saleMode === \"buy_now\"\n ? \"This item is no longer available to purchase.\"\n : \"Bidding has closed for this item.\";\n}\nfunction selectionFromInput(\n auction: LockerverseAuction,\n buyNow: boolean,\n initialSelection: AuctionSelection | null,\n value: string\n): AuctionSelection {\n return {\n amount: buyNow ? 0 : Number(value) * 100,\n includeServiceFee: initialSelection\n ? initialSelection.includeServiceFee\n : auction.serviceFeeEnabled && auction.serviceFeeDefaultChecked,\n quantity: buyNow ? Number(value) : 1,\n };\n}\nexport function AuctionItemSelection({\n auction,\n item,\n initialSelection,\n onContinue,\n onError,\n onBack,\n}: SelectionProps) {\n const buyNow = item.saleMode === \"buy_now\";\n const minimum = Math.ceil(getLockerverseAuctionMinimumBid(item) / 100);\n const [value, setValue] = useState(\n selectionInitialValue(buyNow, initialSelection, minimum)\n );\n const [error, setError] = useState<string | null>(null);\n const id = useId();\n useAuctionBoundary(\n item.startAt ?? auction.startAt,\n item.endAt ?? auction.endAt\n );\n const status = getAuctionDisplayStatus(auction, item);\n const open =\n status === \"active\" &&\n !isAuctionItemSoldOut(item) &&\n item.saleMode !== \"hybrid\";\n function continueToPayment(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (!WHOLE_NUMBER.test(value)) {\n setError(\n buyNow\n ? \"Enter a whole-number quantity.\"\n : \"Enter a whole-dollar bid amount.\"\n );\n return;\n }\n const selection = selectionFromInput(\n auction,\n buyNow,\n initialSelection,\n value\n );\n const message = getAuctionSelectionError(auction, item, selection);\n if (message) {\n setError(message);\n onError(message);\n return;\n }\n try {\n getAuctionSelectionPricing(auction, item, selection);\n } catch {\n setError(\"Enter a valid amount or quantity.\");\n return;\n }\n onContinue(selection);\n }\n if (!open) {\n return (\n <div className=\"lockerverse-auctions__selection lockerverse-auctions__read-only\">\n <p className=\"lockerverse-auctions__eyebrow\">Item status</p>\n <h3>{readOnlyTitle(item, status)}</h3>\n <p>{readOnlyDescription(auction, item, status)}</p>\n {onBack ? (\n <button\n className=\"lockerverse-auctions__button\"\n onClick={onBack}\n type=\"button\"\n >\n Browse auction items <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n ) : null}\n </div>\n );\n }\n return (\n <form\n className=\"lockerverse-auctions__selection\"\n onSubmit={continueToPayment}\n >\n <SelectionHeader buyNow={buyNow} item={item} minimum={minimum} />\n <div className=\"lockerverse-auctions__selection-body\">\n <label className=\"lockerverse-auctions__field\" htmlFor={id}>\n {buyNow ? \"Quantity\" : \"Your bid amount\"}\n <span className=\"lockerverse-auctions__amount-control\">\n {buyNow ? null : <span aria-hidden=\"true\">$</span>}\n <input\n aria-describedby={`${id}-help`}\n aria-invalid={Boolean(error)}\n autoComplete=\"off\"\n id={id}\n inputMode=\"numeric\"\n onChange={(event) => {\n setValue(event.target.value);\n setError(null);\n }}\n placeholder={buyNow ? \"1\" : String(minimum)}\n required\n value={value}\n />\n </span>\n </label>\n {error ? <p role=\"alert\">{error}</p> : null}\n <p id={`${id}-help`}>\n {buyNow\n ? quantitySummary(value, item.buyNowPriceAmount ?? 0)\n : `Enter a whole-dollar bid of at least ${formatMoney(minimum * 100)}. Bid increment: ${formatMoney(item.bidIncrementAmount ?? 100)}.`}\n </p>\n <div className=\"lockerverse-auctions__selection-footer\">\n <p>\n {buyNow\n ? \"Continuing moves you into secure checkout where your payment is processed immediately.\"\n : \"Continuing moves you into the secure payment step where your card is stored for settlement only if your bid wins.\"}\n </p>\n <button\n className=\"lockerverse-auctions__button\"\n disabled={!auction.payment}\n type=\"submit\"\n >\n {buyNow ? \"Continue to Checkout\" : \"Continue to Payment\"}{\" \"}\n <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n </div>\n {auction.payment ? null : (\n <p role=\"alert\">Payments are not configured for this auction.</p>\n )}\n </div>\n </form>\n );\n}\n\nfunction SelectionHeader({\n item,\n buyNow,\n minimum,\n}: {\n item: LockerverseAuctionItem;\n buyNow: boolean;\n minimum: number;\n}) {\n return (\n <div className=\"lockerverse-auctions__selection-header\">\n <p className=\"lockerverse-auctions__eyebrow\">Step 1 of 2</p>\n <h3>{buyNow ? \"Buy this item now.\" : \"Place your bid.\"}</h3>\n <p>\n {buyNow\n ? \"Choose how many you want, then complete the secure checkout.\"\n : \"Enter the bid amount you want to place for this item. You are only charged if this bid wins after bidding closes.\"}\n </p>\n <p>\n {buyNow ? \"Price: \" : \"Minimum qualifying bid: \"}\n <strong>\n {formatMoney(buyNow ? (item.buyNowPriceAmount ?? 0) : minimum * 100)}\n </strong>\n </p>\n {buyNow && item.availableQuantity !== null ? (\n <p>{item.availableQuantity} available</p>\n ) : null}\n {item.collectShippingAddress ? (\n <p>\n The next step will also collect a delivery address for seller\n fulfillment.\n </p>\n ) : null}\n </div>\n );\n}\n","import type {\n LockerverseAuctionItem as AuctionItem,\n LockerverseAuction,\n} from \"@lockerverse/sdk/auctions\";\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport type {\n StripeElementsOptions,\n StripeElementsOptionsMode,\n} from \"@stripe/stripe-js\";\nimport {\n ArrowRight,\n ChevronLeft,\n Gavel,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { AuctionCheckout } from \"./auction-checkout.tsx\";\nimport {\n formatAuctionBoundary,\n getAuctionDisplayStatus,\n} from \"./auction-display.ts\";\nimport { AuctionItemDetails } from \"./auction-item-details.tsx\";\nimport { AuctionItemSelection } from \"./auction-item-selection.tsx\";\nimport type { LockerverseAuctionItemProps } from \"./auction-item-types.ts\";\nimport {\n type AuctionSelection,\n getAuctionSelectionPricing,\n} from \"./auction-payment.ts\";\nimport {\n type LockerverseAuctionOutcome,\n LockerverseAuctionResult,\n} from \"./auction-result.tsx\";\nimport { notifyHostCallback } from \"./host-callback.ts\";\nimport { useStripeAppearance } from \"./stripe-appearance.ts\";\nimport { defaultLockerverseStripeLoader } from \"./stripe-loader.ts\";\nimport { useAuctionBoundary } from \"./use-auction-boundary.ts\";\n\nfunction AuctionPayment(\n props: LockerverseAuctionItemProps & {\n appearanceRoot: RefObject<HTMLElement | null>;\n interactionLocked: boolean;\n item: AuctionItem;\n selection: AuctionSelection;\n onReview: (auction: LockerverseAuction, message: string) => void;\n onBack: () => void;\n contact: { email: string; phone: string };\n onContactChange: (contact: { email: string; phone: string }) => void;\n onIncludeServiceFeeChange: (value: boolean) => void;\n onInteractionLockChange: (locked: boolean) => void;\n onResult: (outcome: LockerverseAuctionOutcome) => void;\n }\n) {\n const {\n auction,\n item,\n selection,\n theme = \"dark\",\n stripeLoader = defaultLockerverseStripeLoader,\n style,\n onBack,\n resumePurchase,\n } = props;\n const [stripe, setStripe] =\n useState<Awaited<ReturnType<typeof defaultLockerverseStripeLoader>>>(null);\n const [failed, setFailed] = useState(false);\n const [revision, setRevision] = useState(0);\n const appearance = useStripeAppearance(\n props.appearanceRoot,\n theme,\n style,\n props.interactionLocked\n );\n const payment = resumePurchase?.payment ?? auction.payment;\n useEffect(() => {\n let active = true;\n if (!payment) {\n setFailed(true);\n return;\n }\n Promise.resolve()\n .then(() =>\n stripeLoader(\n payment.publishableKey,\n payment.connectedAccountId\n ? { stripeAccount: payment.connectedAccountId }\n : undefined\n )\n )\n .then(\n (loaded) => {\n if (active) {\n setStripe(loaded);\n setFailed(!loaded);\n }\n },\n () => {\n if (active) {\n setFailed(true);\n }\n }\n );\n return () => {\n active = false;\n };\n }, [payment, stripeLoader, revision]);\n if (failed) {\n return (\n <div>\n <p role=\"alert\">Payment details could not load.</p>\n {resumePurchase ? null : (\n <button onClick={onBack} type=\"button\">\n Back to item\n </button>\n )}\n <button\n onClick={() => {\n setFailed(false);\n setStripe(null);\n setRevision((value) => value + 1);\n }}\n type=\"button\"\n >\n Try again\n </button>\n </div>\n );\n }\n if (!(stripe && appearance)) {\n return (\n <div>\n <p role=\"status\">Loading secure payment details…</p>\n {resumePurchase ? null : (\n <button onClick={onBack} type=\"button\">\n Back to item\n </button>\n )}\n </div>\n );\n }\n let paymentOptions: StripeElementsOptionsMode = {\n mode: \"setup\",\n setupFutureUsage: \"off_session\",\n };\n if (resumePurchase) {\n paymentOptions = {\n amount: resumePurchase.pricing.totalCents,\n currency: \"usd\",\n mode: \"payment\",\n };\n } else if (item.saleMode === \"buy_now\") {\n paymentOptions = {\n amount: getAuctionSelectionPricing(auction, item, selection).totalCents,\n currency: \"usd\",\n mode: \"payment\",\n };\n }\n const options: StripeElementsOptions = {\n ...paymentOptions,\n appearance,\n currency: \"usd\",\n paymentMethodTypes: [\"card\"],\n syncAddressCheckbox: \"none\",\n };\n return (\n <Elements options={options} stripe={stripe}>\n <AuctionCheckout {...props} />\n </Elements>\n );\n}\n\nfunction AuctionProgress({ buyNow }: { buyNow: boolean }) {\n return (\n <div className=\"lockerverse-auctions__progress\">\n <span>\n {buyNow ? (\n <ShieldCheck aria-hidden=\"true\" size={16} />\n ) : (\n <Gavel aria-hidden=\"true\" size={16} />\n )}\n {buyNow ? \"Choose quantity\" : \"Place bid\"}\n </span>\n <span>\n <ShieldCheck aria-hidden=\"true\" size={16} />\n {buyNow ? \"Pay securely\" : \"Secure card\"}\n </span>\n <span>\n <TimerReset aria-hidden=\"true\" size={16} />\n {buyNow ? \"Get confirmation\" : \"Wait for close\"}\n </span>\n </div>\n );\n}\n\nfunction AuctionItemResult(\n props: LockerverseAuctionItemProps & {\n item: AuctionItem;\n outcome: LockerverseAuctionOutcome;\n }\n) {\n const { auction, item, outcome } = props;\n const auctionAction = props.onBack\n ? { label: \"View auction items\", onClick: props.onBack }\n : undefined;\n return (\n <LockerverseAuctionResult\n auctionName={auction.name}\n className={props.className}\n closesAtLabel={formatAuctionBoundary(auction, \"active\", item)}\n communityName={props.communityName ?? auction.community?.name}\n focusHeading\n imageUrl={\n item.image ?? item.images[0] ?? auction.configuration.image ?? undefined\n }\n itemName={item.name}\n outcome={outcome}\n primaryAction={\n props.returnToItemHref\n ? { href: props.returnToItemHref, label: \"Return to item\" }\n : auctionAction\n }\n secondaryAction={props.returnToItemHref ? auctionAction : undefined}\n style={{\n \"--lockerverse-accent\": auction.community?.color ?? \"#6f8f6d\",\n ...props.style,\n }}\n theme={props.theme}\n />\n );\n}\n\nfunction AuctionItemView(props: LockerverseAuctionItemProps) {\n const {\n auction: initialAuction,\n itemId,\n resumePurchase,\n className,\n theme = \"dark\",\n style,\n } = props;\n const appearanceRoot = useRef<HTMLElement | null>(null);\n const [auction, setAuction] = useState(initialAuction);\n const acceptedHost = useRef(initialAuction);\n const item =\n auction.items.find((candidate) => candidate.id === itemId) ??\n resumePurchase?.item;\n useAuctionBoundary(\n item?.startAt ?? auction.startAt,\n item?.endAt ?? auction.endAt\n );\n const [selection, setSelection] = useState<AuctionSelection | null>(() =>\n resumePurchase\n ? {\n amount: 0,\n includeServiceFee:\n resumePurchase.submission.includeServiceFee ?? false,\n quantity: resumePurchase.submission.quantity,\n }\n : null\n );\n const [interactionLocked, setInteractionLocked] = useState(\n Boolean(resumePurchase)\n );\n const viewMounted = useRef<boolean>(true);\n const hostCallbacks = useRef(props);\n hostCallbacks.current = props;\n const reportedLock = useRef<boolean | null>(null);\n const updateInteractionLock = useCallback((locked: boolean) => {\n // biome-ignore lint/suspicious/noUnnecessaryConditions: Effect cleanup changes this ref outside the callback.\n if (viewMounted.current) {\n setInteractionLocked(locked);\n }\n if (reportedLock.current !== locked) {\n reportedLock.current = locked;\n notifyHostCallback(hostCallbacks.current.onInteractionLockChange, locked);\n }\n }, []);\n const hasRecovery = Boolean(resumePurchase);\n useEffect(() => {\n viewMounted.current = true;\n updateInteractionLock(hasRecovery);\n return () => {\n viewMounted.current = false;\n };\n }, [hasRecovery, updateInteractionLock]);\n const [contact, setContact] = useState({ email: \"\", phone: \"\" });\n const [paying, setPaying] = useState(Boolean(resumePurchase));\n const [notice, setNotice] = useState<string | null>(null);\n const [outcome, setOutcome] = useState<LockerverseAuctionOutcome | null>(\n null\n );\n\n useEffect(() => {\n if (\n !(paying || interactionLocked || resumePurchase) &&\n acceptedHost.current !== initialAuction\n ) {\n acceptedHost.current = initialAuction;\n setAuction(initialAuction);\n }\n }, [initialAuction, paying, interactionLocked, resumePurchase]);\n\n function review(current: LockerverseAuction, message: string) {\n updateInteractionLock(false);\n // The checkout just fetched this snapshot. Do not restore an older host\n // snapshot that arrived while payment was open; accept its next refresh.\n acceptedHost.current = hostCallbacks.current.auction;\n setAuction(current);\n setSelection(null);\n setPaying(false);\n setNotice(message);\n }\n function continueToPayment(next: AuctionSelection) {\n setNotice(null);\n setSelection(next);\n setPaying(true);\n }\n if (!item) {\n return (\n <div>\n <p role=\"alert\">This auction item is no longer available.</p>\n {props.onBack ? (\n <button onClick={props.onBack} type=\"button\">\n Back to auction items\n </button>\n ) : null}\n </div>\n );\n }\n if (outcome) {\n return (\n <AuctionItemResult\n {...props}\n auction={auction}\n item={item}\n outcome={outcome}\n />\n );\n }\n return (\n <section\n className={[\"lockerverse-auctions\", className].filter(Boolean).join(\" \")}\n data-lockerverse-theme={theme}\n ref={appearanceRoot}\n style={{\n \"--lockerverse-accent\": auction.community?.color ?? \"#6f8f6d\",\n ...style,\n }}\n >\n {props.onBack && !interactionLocked ? (\n <button\n className=\"lockerverse-auctions__back\"\n onClick={props.onBack}\n type=\"button\"\n >\n <ChevronLeft aria-hidden=\"true\" size={16} /> All items\n </button>\n ) : null}\n <div className=\"lockerverse-auctions__detail\">\n <AuctionItemDetails auction={auction} item={item} />\n <div className=\"lockerverse-auctions__transaction\">\n {getAuctionDisplayStatus(auction, item) === \"active\" ? (\n <AuctionProgress buyNow={item.saleMode === \"buy_now\"} />\n ) : null}\n {notice ? (\n <p className=\"lockerverse-auctions__notice\" role=\"alert\">\n {notice}\n </p>\n ) : null}\n {paying && selection ? (\n <AuctionPayment\n {...props}\n appearanceRoot={appearanceRoot}\n auction={auction}\n communityName={props.communityName ?? auction.community?.name}\n contact={contact}\n interactionLocked={interactionLocked}\n item={item}\n onBack={() => setPaying(false)}\n onContactChange={setContact}\n onIncludeServiceFeeChange={(includeServiceFee) =>\n setSelection((current) =>\n current\n ? {\n ...current,\n includeServiceFee:\n auction.serviceFeeEnabled && includeServiceFee,\n }\n : current\n )\n }\n onInteractionLockChange={updateInteractionLock}\n onResult={setOutcome}\n onReview={review}\n selection={selection}\n />\n ) : (\n <AuctionItemSelection\n auction={auction}\n initialSelection={selection}\n item={item}\n onBack={props.onBack}\n onContinue={continueToPayment}\n onError={setNotice}\n />\n )}\n {props.onBack && !interactionLocked ? (\n <button\n className=\"lockerverse-auctions__footer-back\"\n onClick={props.onBack}\n type=\"button\"\n >\n Back to auction items <ArrowRight aria-hidden=\"true\" size={16} />\n </button>\n ) : null}\n </div>\n </div>\n </section>\n );\n}\n\nexport function LockerverseAuctionItem(props: LockerverseAuctionItemProps) {\n const identity = useRef({\n auctionId: props.auction.id,\n client: props.client,\n itemId: props.itemId,\n });\n if (\n identity.current.client !== props.client ||\n identity.current.auctionId !== props.auction.id ||\n identity.current.itemId !== props.itemId\n ) {\n throw new TypeError(\n \"Auction item identity cannot change. Remount with a new React key.\"\n );\n }\n if (\n props.resumePurchase &&\n (props.resumePurchase.auctionId !== props.auction.id ||\n props.resumePurchase.itemId !== props.itemId ||\n props.resumePurchase.item.id !== props.itemId ||\n props.resumePurchase.item.auctionId !== props.auction.id)\n ) {\n throw new TypeError(\n \"The purchase recovery record belongs to a different auction item.\"\n );\n }\n // Keep the view mounted when a refreshed host snapshot removes the item.\n // Its transaction snapshot remains authoritative until it is safe to leave.\n return <AuctionItemView {...props} />;\n}\n"],"mappings":"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"}
@@ -106,6 +106,14 @@
106
106
  .lockerverse-auction-result__eyebrow {
107
107
  font-size: 0.85em;
108
108
  }
109
+ .lockerverse-auction-result .lockerverse-auction-result__receipt-title {
110
+ font-size: var(
111
+ --lockerverse-auction-result-receipt-title-size,
112
+ var(--lockerverse-auction-subheading-size, 30px)
113
+ );
114
+ font-weight: 600;
115
+ line-height: 1.2;
116
+ }
109
117
  .lockerverse-auction-result__details {
110
118
  margin: 24px 0;
111
119
  border-block: 1px solid var(--lockerverse-border);
@@ -136,14 +144,32 @@
136
144
  }
137
145
  .lockerverse-auction-result__steps {
138
146
  display: grid;
139
- gap: 16px;
140
- padding-left: 20px;
147
+ padding: 0;
141
148
  margin: 0;
142
149
  line-height: 1.7;
143
150
  color: var(--lockerverse-muted);
151
+ list-style: none;
144
152
  }
145
153
  .lockerverse-auction-result__steps li {
146
- padding-left: 8px;
154
+ display: grid;
155
+ grid-template-columns: 24px minmax(0, 1fr);
156
+ gap: 24px;
157
+ padding-block: 20px;
158
+ }
159
+ .lockerverse-auction-result__steps li:first-child {
160
+ padding-top: 0;
161
+ }
162
+ .lockerverse-auction-result__steps li:last-child {
163
+ padding-bottom: 0;
164
+ }
165
+ .lockerverse-auction-result__steps li + li {
166
+ border-top: 1px solid var(--lockerverse-border);
167
+ }
168
+ .lockerverse-auction-result__step-number {
169
+ padding-top: 4px;
170
+ font-size: 0.8em;
171
+ font-variant-numeric: tabular-nums;
172
+ letter-spacing: 0.2em;
147
173
  }
148
174
  @container (max-width: 800px) {
149
175
  .lockerverse-auction-result__layout {
@@ -1,2 +1,2 @@
1
- import{t as e}from"./format-money.js";import{ArrowRight as t,BadgeCheck as n,FileText as r,ShieldCheck as i,TimerReset as a}from"lucide-react";import{useEffect as o,useId as s,useRef as c}from"react";import{Fragment as l,jsx as u,jsxs as d}from"react/jsx-runtime";function f({action:e,secondary:n=!1}){let r=`lockerverse-auction-result__action${n?` lockerverse-auction-result__action--secondary`:``}`,i=d(l,{children:[e.label,n?null:u(t,{"aria-hidden":`true`,size:18})]});return e.href?u(`a`,{className:r,href:e.href,onClick:e.onClick,children:i}):u(`button`,{className:r,onClick:e.onClick,type:`button`,children:i})}const p={bid:{assurance:`A bid is not a purchase. Payment is collected only if you win at settlement.`,assuranceTitle:`Bid authorization saved`,badge:`Bid submitted`,description:`Your bid and payment method are recorded. You have not been charged for this bid.`,next:`Other bidders can still place bids until the item closes.`,nextTitle:`Follow the auction`,receiptLabel:`Bid summary`,steps:[`Your bid is recorded. This does not confirm that you have won.`,`Your saved payment method can be charged if you win at settlement.`,`Watch your email for bid updates and return to the item to check its status.`],title:`Bid received`},purchase:{assurance:`This receipt shows the amount paid for your purchase.`,assuranceTitle:`Payment processed`,badge:`Purchase confirmed`,description:`Your payment is confirmed and your purchase is recorded.`,next:`The community handles delivery or collection for this item.`,nextTitle:`Next steps`,receiptLabel:`Purchase receipt`,steps:[`Your payment is complete and your purchase is recorded.`,`The community can review your buyer and delivery details.`,`Keep your receipt number. Contact the community if you need help with your order.`],title:`Purchase complete`},receipt:{assurance:`The amounts below are the recorded purchase amounts, not proof of payment.`,assuranceTitle:`Recorded purchase`,badge:`Purchase details`,description:`Payment status is not confirmed on this page.`,next:`Contact the community if you need to confirm your payment or order status.`,nextTitle:`Next steps`,receiptLabel:`Purchase receipt`,steps:[`These are the recorded purchase details. They do not confirm payment.`,`Check your purchase confirmation for the payment result.`,`Contact the community with your receipt number if you need help.`],title:`Purchase details`}};function m({outcome:t,auctionName:n,communityName:r,closesAtLabel:i}){let a=[];return t.kind===`bid`?t.amountCents!==void 0&&a.push([`Bid amount`,e(t.amountCents)]):(a.push([`Unit price`,e(t.unitAmountCents)],[`Quantity`,String(t.quantity)],[`Subtotal`,e(t.subtotalCents)]),t.serviceFeeCents>0&&a.push([`Service fee`,e(t.serviceFeeCents)]),a.push([t.kind===`purchase`?`Total paid`:`Total`,e(t.totalCents)],[`Receipt`,t.purchaseId])),n&&a.push([`Auction`,n]),r&&a.push([`Community`,r]),i&&a.push([`Closes`,i]),a}function h(e){let{outcome:t,itemName:l,imageUrl:h,communityName:g,primaryAction:_,secondaryAction:v,className:y,theme:b=`dark`,style:x}=e,S=s(),C=c(null);o(()=>{e.focusHeading&&C.current?.focus()},[e.focusHeading]);let w=p[t.kind],T=t.kind===`receipt`?r:n,E=t.kind===`receipt`?r:i,D=m(e);return u(`section`,{"aria-labelledby":S,className:[`lockerverse-auctions lockerverse-auction-result`,y].filter(Boolean).join(` `),"data-lockerverse-theme":b,style:x,children:d(`div`,{className:`lockerverse-auction-result__layout`,children:[d(`div`,{className:`lockerverse-auction-result__summary`,children:[d(`span`,{className:`lockerverse-auction-result__badge`,children:[u(T,{"aria-hidden":`true`,size:18}),w.badge]}),g?u(`p`,{className:`lockerverse-auction-result__community`,children:g}):null,d(`h2`,{className:`lockerverse-auction-result__title`,id:S,ref:C,tabIndex:e.focusHeading?-1:void 0,children:[w.title,` for `,l,`.`]}),u(`p`,{className:`lockerverse-auction-result__description`,children:w.description}),d(`div`,{className:`lockerverse-auction-result__assurance`,children:[u(E,{"aria-hidden":`true`,size:22}),d(`div`,{children:[u(`strong`,{children:w.assuranceTitle}),u(`p`,{children:w.assurance})]})]}),d(`div`,{className:`lockerverse-auction-result__assurance`,children:[u(a,{"aria-hidden":`true`,size:22}),d(`div`,{children:[u(`strong`,{children:w.nextTitle}),u(`p`,{children:w.next})]})]}),_||v?d(`div`,{className:`lockerverse-auction-result__actions`,children:[_?u(f,{action:_}):null,v?u(f,{action:v,secondary:!0}):null]}):null]}),d(`aside`,{"aria-label":w.receiptLabel,className:`lockerverse-auction-result__receipt`,children:[h?u(`img`,{alt:l,className:`lockerverse-auction-result__image`,height:300,src:h,width:420}):null,d(`div`,{className:`lockerverse-auction-result__receipt-body`,children:[u(`p`,{className:`lockerverse-auction-result__eyebrow`,children:w.receiptLabel}),u(`h3`,{children:l}),u(`dl`,{className:`lockerverse-auction-result__details`,children:D.map(([e,t])=>d(`div`,{children:[u(`dt`,{children:e}),u(`dd`,{children:t})]},e))}),u(`h4`,{children:`What happens next`}),u(`ol`,{className:`lockerverse-auction-result__steps`,children:w.steps.map(e=>u(`li`,{children:e},e))})]})]})]})})}export{h as t};
1
+ import{t as e}from"./format-money.js";import{ArrowRight as t,BadgeCheck as n,FileText as r,ShieldCheck as i,TimerReset as a}from"lucide-react";import{useEffect as o,useId as s,useRef as c}from"react";import{Fragment as l,jsx as u,jsxs as d}from"react/jsx-runtime";function f({action:e,secondary:n=!1}){let r=`lockerverse-auction-result__action${n?` lockerverse-auction-result__action--secondary`:``}`,i=d(l,{children:[e.label,n?null:u(t,{"aria-hidden":`true`,size:18})]});return e.href?u(`a`,{className:r,href:e.href,onClick:e.onClick,children:i}):u(`button`,{className:r,onClick:e.onClick,type:`button`,children:i})}const p={bid:{assurance:`A bid is not a purchase. Payment is collected only if you win at settlement.`,assuranceTitle:`Bid authorization saved`,badge:`Bid submitted`,description:`Your bid and payment method are recorded. You have not been charged for this bid.`,next:`Other bidders can still place bids until the item closes.`,nextTitle:`Follow the auction`,receiptLabel:`Bid summary`,steps:[`Your bid is recorded. This does not confirm that you have won.`,`Your saved payment method can be charged if you win at settlement.`,`Watch your email for bid updates and return to the item to check its status.`],title:`Bid received`},purchase:{assurance:`This receipt shows the amount paid for your purchase.`,assuranceTitle:`Payment processed`,badge:`Purchase confirmed`,description:`Your payment is confirmed and your purchase is recorded.`,next:`The community handles delivery or collection for this item.`,nextTitle:`Next steps`,receiptLabel:`Purchase receipt`,steps:[`Your payment is complete and your purchase is recorded.`,`The community can review your buyer and delivery details.`,`Keep your receipt number. Contact the community if you need help with your order.`],title:`Purchase complete`},receipt:{assurance:`The amounts below are the recorded purchase amounts, not proof of payment.`,assuranceTitle:`Recorded purchase`,badge:`Purchase details`,description:`Payment status is not confirmed on this page.`,next:`Contact the community if you need to confirm your payment or order status.`,nextTitle:`Next steps`,receiptLabel:`Purchase receipt`,steps:[`These are the recorded purchase details. They do not confirm payment.`,`Check your purchase confirmation for the payment result.`,`Contact the community with your receipt number if you need help.`],title:`Purchase details`}};function m({outcome:t,auctionName:n,communityName:r,closesAtLabel:i}){let a=[];return t.kind===`bid`?t.amountCents!==void 0&&a.push([`Bid amount`,e(t.amountCents)]):(a.push([`Unit price`,e(t.unitAmountCents)],[`Quantity`,String(t.quantity)],[`Subtotal`,e(t.subtotalCents)]),t.serviceFeeCents>0&&a.push([`Service fee`,e(t.serviceFeeCents)]),a.push([t.kind===`purchase`?`Total paid`:`Total`,e(t.totalCents)],[`Receipt`,t.purchaseId])),n&&a.push([`Auction`,n]),r&&a.push([`Community`,r]),i&&a.push([`Closes`,i]),a}function h(e){let{outcome:t,itemName:l,imageUrl:h,communityName:g,primaryAction:_,secondaryAction:v,className:y,theme:b=`dark`,style:x}=e,S=s(),C=c(null);o(()=>{e.focusHeading&&C.current?.focus()},[e.focusHeading]);let w=p[t.kind],T=t.kind===`receipt`?r:n,E=t.kind===`receipt`?r:i,D=m(e);return u(`section`,{"aria-labelledby":S,className:[`lockerverse-auctions lockerverse-auction-result`,y].filter(Boolean).join(` `),"data-lockerverse-theme":b,style:x,children:d(`div`,{className:`lockerverse-auction-result__layout`,children:[d(`div`,{className:`lockerverse-auction-result__summary`,children:[d(`span`,{className:`lockerverse-auction-result__badge`,children:[u(T,{"aria-hidden":`true`,size:18}),w.badge]}),g?u(`p`,{className:`lockerverse-auction-result__community`,children:g}):null,d(`h2`,{className:`lockerverse-auction-result__title`,id:S,ref:C,tabIndex:e.focusHeading?-1:void 0,children:[w.title,` for `,l,`.`]}),u(`p`,{className:`lockerverse-auction-result__description`,children:w.description}),d(`div`,{className:`lockerverse-auction-result__assurance`,children:[u(E,{"aria-hidden":`true`,size:22}),d(`div`,{children:[u(`strong`,{children:w.assuranceTitle}),u(`p`,{children:w.assurance})]})]}),d(`div`,{className:`lockerverse-auction-result__assurance`,children:[u(a,{"aria-hidden":`true`,size:22}),d(`div`,{children:[u(`strong`,{children:w.nextTitle}),u(`p`,{children:w.next})]})]}),_||v?d(`div`,{className:`lockerverse-auction-result__actions`,children:[_?u(f,{action:_}):null,v?u(f,{action:v,secondary:!0}):null]}):null]}),d(`aside`,{"aria-label":w.receiptLabel,className:`lockerverse-auction-result__receipt`,children:[h?u(`img`,{alt:l,className:`lockerverse-auction-result__image`,height:300,src:h,width:420}):null,d(`div`,{className:`lockerverse-auction-result__receipt-body`,children:[u(`p`,{className:`lockerverse-auction-result__eyebrow`,children:w.receiptLabel}),u(`h3`,{className:`lockerverse-auction-result__receipt-title`,children:l}),u(`dl`,{className:`lockerverse-auction-result__details`,children:D.map(([e,t])=>d(`div`,{children:[u(`dt`,{children:e}),u(`dd`,{children:t})]},e))}),u(`h4`,{children:`What happens next`}),u(`ol`,{className:`lockerverse-auction-result__steps`,role:`list`,children:w.steps.map((e,t)=>d(`li`,{children:[u(`span`,{"aria-hidden":`true`,className:`lockerverse-auction-result__step-number`,children:String(t+1).padStart(2,`0`)}),u(`span`,{children:e})]},e))})]})]})]})})}export{h as t};
2
2
  //# sourceMappingURL=auction-result2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auction-result2.js","names":[],"sources":["../src/auction-result.tsx"],"sourcesContent":["import {\n ArrowRight,\n BadgeCheck,\n FileText,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport { useEffect, useId, useRef } from \"react\";\nimport { formatMoney } from \"./format-money.ts\";\nimport type { LockerverseStyle, LockerverseTheme } from \"./theme.ts\";\n\ntype AuctionPurchaseDetails = {\n purchaseId: string;\n unitAmountCents: number;\n quantity: number;\n subtotalCents: number;\n serviceFeeCents: number;\n totalCents: number;\n};\n\nexport type LockerverseAuctionOutcome =\n | { kind: \"bid\"; amountCents?: number }\n | (AuctionPurchaseDetails & {\n kind: \"purchase\";\n /** Use only after the server confirms payment. Receipt amounts alone are not proof. */\n status: \"paid\";\n })\n | (AuctionPurchaseDetails & { kind: \"receipt\" });\n\nexport type LockerverseAuctionResultAction = {\n label: string;\n href?: string;\n onClick?: () => void;\n};\n\nexport type LockerverseAuctionResultProps = {\n outcome: LockerverseAuctionOutcome;\n itemName: string;\n imageUrl?: string | undefined;\n auctionName?: string | undefined;\n communityName?: string | undefined;\n closesAtLabel?: string | undefined;\n primaryAction?: LockerverseAuctionResultAction | undefined;\n secondaryAction?: LockerverseAuctionResultAction | undefined;\n className?: string | undefined;\n theme?: LockerverseTheme | undefined;\n style?: LockerverseStyle | undefined;\n /** Focus the result after an inline checkout completes. Defaults to false. */\n focusHeading?: boolean | undefined;\n};\n\nfunction ResultAction({\n action,\n secondary = false,\n}: {\n action: LockerverseAuctionResultAction;\n secondary?: boolean;\n}) {\n const className = `lockerverse-auction-result__action${secondary ? \" lockerverse-auction-result__action--secondary\" : \"\"}`;\n const content = (\n <>\n {action.label}\n {secondary ? null : <ArrowRight aria-hidden=\"true\" size={18} />}\n </>\n );\n return action.href ? (\n <a className={className} href={action.href} onClick={action.onClick}>\n {content}\n </a>\n ) : (\n <button className={className} onClick={action.onClick} type=\"button\">\n {content}\n </button>\n );\n}\n\nconst outcomeCopy = {\n bid: {\n assurance:\n \"A bid is not a purchase. Payment is collected only if you win at settlement.\",\n assuranceTitle: \"Bid authorization saved\",\n badge: \"Bid submitted\",\n description:\n \"Your bid and payment method are recorded. You have not been charged for this bid.\",\n next: \"Other bidders can still place bids until the item closes.\",\n nextTitle: \"Follow the auction\",\n receiptLabel: \"Bid summary\",\n steps: [\n \"Your bid is recorded. This does not confirm that you have won.\",\n \"Your saved payment method can be charged if you win at settlement.\",\n \"Watch your email for bid updates and return to the item to check its status.\",\n ],\n title: \"Bid received\",\n },\n purchase: {\n assurance: \"This receipt shows the amount paid for your purchase.\",\n assuranceTitle: \"Payment processed\",\n badge: \"Purchase confirmed\",\n description: \"Your payment is confirmed and your purchase is recorded.\",\n next: \"The community handles delivery or collection for this item.\",\n nextTitle: \"Next steps\",\n receiptLabel: \"Purchase receipt\",\n steps: [\n \"Your payment is complete and your purchase is recorded.\",\n \"The community can review your buyer and delivery details.\",\n \"Keep your receipt number. Contact the community if you need help with your order.\",\n ],\n title: \"Purchase complete\",\n },\n receipt: {\n assurance:\n \"The amounts below are the recorded purchase amounts, not proof of payment.\",\n assuranceTitle: \"Recorded purchase\",\n badge: \"Purchase details\",\n description: \"Payment status is not confirmed on this page.\",\n next: \"Contact the community if you need to confirm your payment or order status.\",\n nextTitle: \"Next steps\",\n receiptLabel: \"Purchase receipt\",\n steps: [\n \"These are the recorded purchase details. They do not confirm payment.\",\n \"Check your purchase confirmation for the payment result.\",\n \"Contact the community with your receipt number if you need help.\",\n ],\n title: \"Purchase details\",\n },\n};\n\nfunction getResultDetails({\n outcome,\n auctionName,\n communityName,\n closesAtLabel,\n}: LockerverseAuctionResultProps) {\n const details: [string, string][] = [];\n if (outcome.kind === \"bid\") {\n if (outcome.amountCents !== undefined) {\n details.push([\"Bid amount\", formatMoney(outcome.amountCents)]);\n }\n } else {\n details.push(\n [\"Unit price\", formatMoney(outcome.unitAmountCents)],\n [\"Quantity\", String(outcome.quantity)],\n [\"Subtotal\", formatMoney(outcome.subtotalCents)]\n );\n if (outcome.serviceFeeCents > 0) {\n details.push([\"Service fee\", formatMoney(outcome.serviceFeeCents)]);\n }\n details.push(\n [\n outcome.kind === \"purchase\" ? \"Total paid\" : \"Total\",\n formatMoney(outcome.totalCents),\n ],\n [\"Receipt\", outcome.purchaseId]\n );\n }\n if (auctionName) {\n details.push([\"Auction\", auctionName]);\n }\n if (communityName) {\n details.push([\"Community\", communityName]);\n }\n if (closesAtLabel) {\n details.push([\"Closes\", closesAtLabel]);\n }\n return details;\n}\n\n/** Shared result view. Hosts must provide a verified outcome or a neutral receipt. */\nexport function LockerverseAuctionResult(props: LockerverseAuctionResultProps) {\n const {\n outcome,\n itemName,\n imageUrl,\n communityName,\n primaryAction,\n secondaryAction,\n className,\n theme = \"dark\",\n style,\n } = props;\n const titleId = useId();\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => {\n if (props.focusHeading) {\n headingRef.current?.focus();\n }\n }, [props.focusHeading]);\n const copy = outcomeCopy[outcome.kind];\n const StatusIcon = outcome.kind === \"receipt\" ? FileText : BadgeCheck;\n const AssuranceIcon = outcome.kind === \"receipt\" ? FileText : ShieldCheck;\n const details = getResultDetails(props);\n return (\n <section\n aria-labelledby={titleId}\n className={[\"lockerverse-auctions lockerverse-auction-result\", className]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={style}\n >\n <div className=\"lockerverse-auction-result__layout\">\n <div className=\"lockerverse-auction-result__summary\">\n <span className=\"lockerverse-auction-result__badge\">\n <StatusIcon aria-hidden=\"true\" size={18} />\n {copy.badge}\n </span>\n {communityName ? (\n <p className=\"lockerverse-auction-result__community\">\n {communityName}\n </p>\n ) : null}\n <h2\n className=\"lockerverse-auction-result__title\"\n id={titleId}\n ref={headingRef}\n tabIndex={props.focusHeading ? -1 : undefined}\n >\n {copy.title} for {itemName}.\n </h2>\n <p className=\"lockerverse-auction-result__description\">\n {copy.description}\n </p>\n <div className=\"lockerverse-auction-result__assurance\">\n <AssuranceIcon aria-hidden=\"true\" size={22} />\n <div>\n <strong>{copy.assuranceTitle}</strong>\n <p>{copy.assurance}</p>\n </div>\n </div>\n <div className=\"lockerverse-auction-result__assurance\">\n <TimerReset aria-hidden=\"true\" size={22} />\n <div>\n <strong>{copy.nextTitle}</strong>\n <p>{copy.next}</p>\n </div>\n </div>\n {primaryAction || secondaryAction ? (\n <div className=\"lockerverse-auction-result__actions\">\n {primaryAction ? <ResultAction action={primaryAction} /> : null}\n {secondaryAction ? (\n <ResultAction action={secondaryAction} secondary />\n ) : null}\n </div>\n ) : null}\n </div>\n <aside\n aria-label={copy.receiptLabel}\n className=\"lockerverse-auction-result__receipt\"\n >\n {imageUrl ? (\n <img\n alt={itemName}\n className=\"lockerverse-auction-result__image\"\n height={300}\n src={imageUrl}\n width={420}\n />\n ) : null}\n <div className=\"lockerverse-auction-result__receipt-body\">\n <p className=\"lockerverse-auction-result__eyebrow\">\n {copy.receiptLabel}\n </p>\n <h3>{itemName}</h3>\n <dl className=\"lockerverse-auction-result__details\">\n {details.map(([label, value]) => (\n <div key={label}>\n <dt>{label}</dt>\n <dd>{value}</dd>\n </div>\n ))}\n </dl>\n <h4>What happens next</h4>\n <ol className=\"lockerverse-auction-result__steps\">\n {copy.steps.map((step) => (\n <li key={step}>{step}</li>\n ))}\n </ol>\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"],"mappings":"wQAmDA,SAAS,EAAa,CACpB,SACA,YAAY,IAIX,CACD,IAAM,EAAY,qCAAqC,EAAY,iDAAmD,KAChH,EACJ,EAAA,EAAA,CAAA,SAAA,CACG,EAAO,MACP,EAAY,KAAO,EAAC,EAAD,CAAY,cAAY,OAAO,KAAM,EAAK,CAAA,CAC9D,CAAA,CAAA,EAEJ,OAAO,EAAO,KACZ,EAAC,IAAD,CAAc,YAAW,KAAM,EAAO,KAAM,QAAS,EAAO,QACzD,SAAA,CACA,CAAA,EAEH,EAAC,SAAD,CAAmB,YAAW,QAAS,EAAO,QAAS,KAAK,SACzD,SAAA,CACK,CAAA,CAEZ,CAEA,MAAM,EAAc,CAClB,IAAK,CACH,UACE,+EACF,eAAgB,0BAChB,MAAO,gBACP,YACE,oFACF,KAAM,4DACN,UAAW,qBACX,aAAc,cACd,MAAO,CACL,iEACA,qEACA,8EACF,EACA,MAAO,cACT,EACA,SAAU,CACR,UAAW,wDACX,eAAgB,oBAChB,MAAO,qBACP,YAAa,2DACb,KAAM,8DACN,UAAW,aACX,aAAc,mBACd,MAAO,CACL,0DACA,4DACA,mFACF,EACA,MAAO,mBACT,EACA,QAAS,CACP,UACE,6EACF,eAAgB,oBAChB,MAAO,mBACP,YAAa,gDACb,KAAM,6EACN,UAAW,aACX,aAAc,mBACd,MAAO,CACL,wEACA,2DACA,kEACF,EACA,MAAO,kBACT,CACF,EAEA,SAAS,EAAiB,CACxB,UACA,cACA,gBACA,iBACgC,CAChC,IAAM,EAA8B,CAAC,EA+BrC,OA9BI,EAAQ,OAAS,MACf,EAAQ,cAAgB,IAAA,IAC1B,EAAQ,KAAK,CAAC,aAAc,EAAY,EAAQ,WAAW,CAAC,CAAC,GAG/D,EAAQ,KACN,CAAC,aAAc,EAAY,EAAQ,eAAe,CAAC,EACnD,CAAC,WAAY,OAAO,EAAQ,QAAQ,CAAC,EACrC,CAAC,WAAY,EAAY,EAAQ,aAAa,CAAC,CACjD,EACI,EAAQ,gBAAkB,GAC5B,EAAQ,KAAK,CAAC,cAAe,EAAY,EAAQ,eAAe,CAAC,CAAC,EAEpE,EAAQ,KACN,CACE,EAAQ,OAAS,WAAa,aAAe,QAC7C,EAAY,EAAQ,UAAU,CAChC,EACA,CAAC,UAAW,EAAQ,UAAU,CAChC,GAEE,GACF,EAAQ,KAAK,CAAC,UAAW,CAAW,CAAC,EAEnC,GACF,EAAQ,KAAK,CAAC,YAAa,CAAa,CAAC,EAEvC,GACF,EAAQ,KAAK,CAAC,SAAU,CAAa,CAAC,EAEjC,CACT,CAGA,SAAgB,EAAyB,EAAsC,CAC7E,GAAM,CACJ,UACA,WACA,WACA,gBACA,gBACA,kBACA,YACA,QAAQ,OACR,SACE,EACE,EAAU,EAAM,EAChB,EAAa,EAA2B,IAAI,EAClD,MAAgB,CACV,EAAM,cACR,EAAW,SAAS,MAAM,CAE9B,EAAG,CAAC,EAAM,YAAY,CAAC,EACvB,IAAM,EAAO,EAAY,EAAQ,MAC3B,EAAa,EAAQ,OAAS,UAAY,EAAW,EACrD,EAAgB,EAAQ,OAAS,UAAY,EAAW,EACxD,EAAU,EAAiB,CAAK,EACtC,OACE,EAAC,UAAD,CACE,kBAAiB,EACjB,UAAW,CAAC,kDAAmD,CAAS,CAAC,CACtE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EACX,yBAAwB,EACjB,QAEP,SAAA,EAAC,MAAD,CAAK,UAAU,qCAAf,SAAA,CACE,EAAC,MAAD,CAAK,UAAU,sCAAf,SAAA,CACE,EAAC,OAAD,CAAM,UAAU,oCAAhB,SAAA,CACE,EAAC,EAAD,CAAY,cAAY,OAAO,KAAM,EAAK,CAAA,EACzC,EAAK,KACF,IACL,EACC,EAAC,IAAD,CAAG,UAAU,wCACV,SAAA,CACA,CAAA,EACD,KACJ,EAAC,KAAD,CACE,UAAU,oCACV,GAAI,EACJ,IAAK,EACL,SAAU,EAAM,aAAe,GAAK,IAAA,GAJtC,SAAA,CAMG,EAAK,MAAM,QAAM,EAAS,GACzB,IACJ,EAAC,IAAD,CAAG,UAAU,0CACV,SAAA,EAAK,WACL,CAAA,EACH,EAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,CACE,EAAC,EAAD,CAAe,cAAY,OAAO,KAAM,EAAK,CAAA,EAC7C,EAAC,MAAD,CAAA,SAAA,CACE,EAAC,SAAD,CAAA,SAAS,EAAK,cAAuB,CAAA,EACrC,EAAC,IAAD,CAAA,SAAI,EAAK,SAAa,CAAA,CACnB,CAAA,CAAA,CACF,IACL,EAAC,MAAD,CAAK,UAAU,wCAAf,SAAA,CACE,EAAC,EAAD,CAAY,cAAY,OAAO,KAAM,EAAK,CAAA,EAC1C,EAAC,MAAD,CAAA,SAAA,CACE,EAAC,SAAD,CAAA,SAAS,EAAK,SAAkB,CAAA,EAChC,EAAC,IAAD,CAAA,SAAI,EAAK,IAAQ,CAAA,CACd,CAAA,CAAA,CACF,IACJ,GAAiB,EAChB,EAAC,MAAD,CAAK,UAAU,sCAAf,SAAA,CACG,EAAgB,EAAC,EAAD,CAAc,OAAQ,CAAgB,CAAA,EAAI,KAC1D,EACC,EAAC,EAAD,CAAc,OAAQ,EAAiB,UAAA,EAAW,CAAA,EAChD,IACD,CACH,CAAA,EAAA,IACD,CACL,CAAA,EAAA,EAAC,QAAD,CACE,aAAY,EAAK,aACjB,UAAU,sCAFZ,SAAA,CAIG,EACC,EAAC,MAAD,CACE,IAAK,EACL,UAAU,oCACV,OAAQ,IACR,IAAK,EACL,MAAO,GACR,CAAA,EACC,KACJ,EAAC,MAAD,CAAK,UAAU,2CAAf,SAAA,CACE,EAAC,IAAD,CAAG,UAAU,sCACV,SAAA,EAAK,YACL,CAAA,EACH,EAAC,KAAD,CAAA,SAAK,CAAa,CAAA,EAClB,EAAC,KAAD,CAAI,UAAU,sCACX,SAAA,EAAQ,KAAK,CAAC,EAAO,KACpB,EAAC,MAAD,CAAA,SAAA,CACE,EAAC,KAAD,CAAA,SAAK,CAAU,CAAA,EACf,EAAC,KAAD,CAAA,SAAK,CAAU,CAAA,CACZ,CAAA,EAHK,CAGL,CACN,CACC,CAAA,EACJ,EAAC,KAAD,CAAA,SAAI,mBAAqB,CAAA,EACzB,EAAC,KAAD,CAAI,UAAU,oCACX,SAAA,EAAK,MAAM,IAAK,GACf,EAAC,KAAD,CAAA,SAAgB,CAAS,EAAhB,CAAgB,CAC1B,CACC,CAAA,CACD,CACA,CAAA,CAAA,CACJ,CAAA,CAAA,GACE,CAAA,CAEb"}
1
+ {"version":3,"file":"auction-result2.js","names":[],"sources":["../src/auction-result.tsx"],"sourcesContent":["import {\n ArrowRight,\n BadgeCheck,\n FileText,\n ShieldCheck,\n TimerReset,\n} from \"lucide-react\";\nimport { useEffect, useId, useRef } from \"react\";\nimport { formatMoney } from \"./format-money.ts\";\nimport type { LockerverseStyle, LockerverseTheme } from \"./theme.ts\";\n\ntype AuctionPurchaseDetails = {\n purchaseId: string;\n unitAmountCents: number;\n quantity: number;\n subtotalCents: number;\n serviceFeeCents: number;\n totalCents: number;\n};\n\nexport type LockerverseAuctionOutcome =\n | { kind: \"bid\"; amountCents?: number }\n | (AuctionPurchaseDetails & {\n kind: \"purchase\";\n /** Use only after the server confirms payment. Receipt amounts alone are not proof. */\n status: \"paid\";\n })\n | (AuctionPurchaseDetails & { kind: \"receipt\" });\n\nexport type LockerverseAuctionResultAction = {\n label: string;\n href?: string;\n onClick?: () => void;\n};\n\nexport type LockerverseAuctionResultProps = {\n outcome: LockerverseAuctionOutcome;\n itemName: string;\n imageUrl?: string | undefined;\n auctionName?: string | undefined;\n communityName?: string | undefined;\n closesAtLabel?: string | undefined;\n primaryAction?: LockerverseAuctionResultAction | undefined;\n secondaryAction?: LockerverseAuctionResultAction | undefined;\n className?: string | undefined;\n theme?: LockerverseTheme | undefined;\n style?: LockerverseStyle | undefined;\n /** Focus the result after an inline checkout completes. Defaults to false. */\n focusHeading?: boolean | undefined;\n};\n\nfunction ResultAction({\n action,\n secondary = false,\n}: {\n action: LockerverseAuctionResultAction;\n secondary?: boolean;\n}) {\n const className = `lockerverse-auction-result__action${secondary ? \" lockerverse-auction-result__action--secondary\" : \"\"}`;\n const content = (\n <>\n {action.label}\n {secondary ? null : <ArrowRight aria-hidden=\"true\" size={18} />}\n </>\n );\n return action.href ? (\n <a className={className} href={action.href} onClick={action.onClick}>\n {content}\n </a>\n ) : (\n <button className={className} onClick={action.onClick} type=\"button\">\n {content}\n </button>\n );\n}\n\nconst outcomeCopy = {\n bid: {\n assurance:\n \"A bid is not a purchase. Payment is collected only if you win at settlement.\",\n assuranceTitle: \"Bid authorization saved\",\n badge: \"Bid submitted\",\n description:\n \"Your bid and payment method are recorded. You have not been charged for this bid.\",\n next: \"Other bidders can still place bids until the item closes.\",\n nextTitle: \"Follow the auction\",\n receiptLabel: \"Bid summary\",\n steps: [\n \"Your bid is recorded. This does not confirm that you have won.\",\n \"Your saved payment method can be charged if you win at settlement.\",\n \"Watch your email for bid updates and return to the item to check its status.\",\n ],\n title: \"Bid received\",\n },\n purchase: {\n assurance: \"This receipt shows the amount paid for your purchase.\",\n assuranceTitle: \"Payment processed\",\n badge: \"Purchase confirmed\",\n description: \"Your payment is confirmed and your purchase is recorded.\",\n next: \"The community handles delivery or collection for this item.\",\n nextTitle: \"Next steps\",\n receiptLabel: \"Purchase receipt\",\n steps: [\n \"Your payment is complete and your purchase is recorded.\",\n \"The community can review your buyer and delivery details.\",\n \"Keep your receipt number. Contact the community if you need help with your order.\",\n ],\n title: \"Purchase complete\",\n },\n receipt: {\n assurance:\n \"The amounts below are the recorded purchase amounts, not proof of payment.\",\n assuranceTitle: \"Recorded purchase\",\n badge: \"Purchase details\",\n description: \"Payment status is not confirmed on this page.\",\n next: \"Contact the community if you need to confirm your payment or order status.\",\n nextTitle: \"Next steps\",\n receiptLabel: \"Purchase receipt\",\n steps: [\n \"These are the recorded purchase details. They do not confirm payment.\",\n \"Check your purchase confirmation for the payment result.\",\n \"Contact the community with your receipt number if you need help.\",\n ],\n title: \"Purchase details\",\n },\n};\n\nfunction getResultDetails({\n outcome,\n auctionName,\n communityName,\n closesAtLabel,\n}: LockerverseAuctionResultProps) {\n const details: [string, string][] = [];\n if (outcome.kind === \"bid\") {\n if (outcome.amountCents !== undefined) {\n details.push([\"Bid amount\", formatMoney(outcome.amountCents)]);\n }\n } else {\n details.push(\n [\"Unit price\", formatMoney(outcome.unitAmountCents)],\n [\"Quantity\", String(outcome.quantity)],\n [\"Subtotal\", formatMoney(outcome.subtotalCents)]\n );\n if (outcome.serviceFeeCents > 0) {\n details.push([\"Service fee\", formatMoney(outcome.serviceFeeCents)]);\n }\n details.push(\n [\n outcome.kind === \"purchase\" ? \"Total paid\" : \"Total\",\n formatMoney(outcome.totalCents),\n ],\n [\"Receipt\", outcome.purchaseId]\n );\n }\n if (auctionName) {\n details.push([\"Auction\", auctionName]);\n }\n if (communityName) {\n details.push([\"Community\", communityName]);\n }\n if (closesAtLabel) {\n details.push([\"Closes\", closesAtLabel]);\n }\n return details;\n}\n\n/** Shared result view. Hosts must provide a verified outcome or a neutral receipt. */\nexport function LockerverseAuctionResult(props: LockerverseAuctionResultProps) {\n const {\n outcome,\n itemName,\n imageUrl,\n communityName,\n primaryAction,\n secondaryAction,\n className,\n theme = \"dark\",\n style,\n } = props;\n const titleId = useId();\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => {\n if (props.focusHeading) {\n headingRef.current?.focus();\n }\n }, [props.focusHeading]);\n const copy = outcomeCopy[outcome.kind];\n const StatusIcon = outcome.kind === \"receipt\" ? FileText : BadgeCheck;\n const AssuranceIcon = outcome.kind === \"receipt\" ? FileText : ShieldCheck;\n const details = getResultDetails(props);\n return (\n <section\n aria-labelledby={titleId}\n className={[\"lockerverse-auctions lockerverse-auction-result\", className]\n .filter(Boolean)\n .join(\" \")}\n data-lockerverse-theme={theme}\n style={style}\n >\n <div className=\"lockerverse-auction-result__layout\">\n <div className=\"lockerverse-auction-result__summary\">\n <span className=\"lockerverse-auction-result__badge\">\n <StatusIcon aria-hidden=\"true\" size={18} />\n {copy.badge}\n </span>\n {communityName ? (\n <p className=\"lockerverse-auction-result__community\">\n {communityName}\n </p>\n ) : null}\n <h2\n className=\"lockerverse-auction-result__title\"\n id={titleId}\n ref={headingRef}\n tabIndex={props.focusHeading ? -1 : undefined}\n >\n {copy.title} for {itemName}.\n </h2>\n <p className=\"lockerverse-auction-result__description\">\n {copy.description}\n </p>\n <div className=\"lockerverse-auction-result__assurance\">\n <AssuranceIcon aria-hidden=\"true\" size={22} />\n <div>\n <strong>{copy.assuranceTitle}</strong>\n <p>{copy.assurance}</p>\n </div>\n </div>\n <div className=\"lockerverse-auction-result__assurance\">\n <TimerReset aria-hidden=\"true\" size={22} />\n <div>\n <strong>{copy.nextTitle}</strong>\n <p>{copy.next}</p>\n </div>\n </div>\n {primaryAction || secondaryAction ? (\n <div className=\"lockerverse-auction-result__actions\">\n {primaryAction ? <ResultAction action={primaryAction} /> : null}\n {secondaryAction ? (\n <ResultAction action={secondaryAction} secondary />\n ) : null}\n </div>\n ) : null}\n </div>\n <aside\n aria-label={copy.receiptLabel}\n className=\"lockerverse-auction-result__receipt\"\n >\n {imageUrl ? (\n <img\n alt={itemName}\n className=\"lockerverse-auction-result__image\"\n height={300}\n src={imageUrl}\n width={420}\n />\n ) : null}\n <div className=\"lockerverse-auction-result__receipt-body\">\n <p className=\"lockerverse-auction-result__eyebrow\">\n {copy.receiptLabel}\n </p>\n <h3 className=\"lockerverse-auction-result__receipt-title\">\n {itemName}\n </h3>\n <dl className=\"lockerverse-auction-result__details\">\n {details.map(([label, value]) => (\n <div key={label}>\n <dt>{label}</dt>\n <dd>{value}</dd>\n </div>\n ))}\n </dl>\n <h4>What happens next</h4>\n {/* biome-ignore lint/a11y/noRedundantRoles: Keep list semantics in Safari when visual markers replace list-style. */}\n <ol className=\"lockerverse-auction-result__steps\" role=\"list\">\n {copy.steps.map((step, index) => (\n <li key={step}>\n <span\n aria-hidden=\"true\"\n className=\"lockerverse-auction-result__step-number\"\n >\n {String(index + 1).padStart(2, \"0\")}\n </span>\n <span>{step}</span>\n </li>\n ))}\n </ol>\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"],"mappings":"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"}
package/dist/theme.d.ts CHANGED
@@ -17,6 +17,7 @@ type LockerverseStyle = CSSProperties & {
17
17
  "--lockerverse-auction-card-title-size"?: string;
18
18
  "--lockerverse-auction-item-title-size"?: string;
19
19
  "--lockerverse-auction-result-title-size"?: string;
20
+ "--lockerverse-auction-result-receipt-title-size"?: string;
20
21
  "--lockerverse-auction-date-size"?: string;
21
22
  "--lockerverse-auction-date-transform"?: string;
22
23
  "--lockerverse-auction-date-letter-spacing"?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","names":[],"sources":["../src/theme.ts"],"mappings":";;KAEY;KAEA,mBAAmB;EAC7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}
1
+ {"version":3,"file":"theme.d.ts","names":[],"sources":["../src/theme.ts"],"mappings":";;KAEY;KAEA,mBAAmB;EAC7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lockerverse/react",
3
- "version": "0.2.126-dev.1",
3
+ "version": "0.2.127-dev.1",
4
4
  "description": "Tree-shakable React payment and signup UI for Lockerverse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -127,7 +127,7 @@
127
127
  "embla-carousel-react": "8.6.0",
128
128
  "lucide-react": "0.536.0",
129
129
  "valibot": "1.4.2",
130
- "@lockerverse/sdk": "0.2.126-dev.1"
130
+ "@lockerverse/sdk": "0.2.127-dev.1"
131
131
  },
132
132
  "devDependencies": {
133
133
  "@size-limit/file": "13.0.3",