{"version":3,"file":"AddToOrder.CJSYdBpw.mjs","names":["useState","loadStripe","_Fragment"],"sources":["https:/framerusercontent.com/modules/wDzlni5Q6k8p3xHug1cx/uERWiCO5NHuSXnNx08Rh/AddToOrder.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from\"react/jsx-runtime\";import{useState}from\"react\";import{loadStripe}from\"@stripe/stripe-js\";// @ts-ignore — Framer provides this at runtime\nimport{addPropertyControls,ControlType}from\"framer\";import{useUpsellStore}from\"https://framerusercontent.com/modules/EjsWQMeQbYXeu6MyNlM1/MDwpB7IzrnCXsZ6NvFH2/UpsellStore.js\";function reportUpsellPurchase(intent,details={}){try{const medvi=window.medvi;if(typeof medvi!==\"function\")return;// Only a settled charge is revenue. \"processing\" is a real payment in\n// flight and would have to be reconciled server-side to know how it ended.\nif(!intent||intent.status!==\"succeeded\")return;const parts=window.location.pathname.split(\"/\").filter(Boolean);const at=parts.indexOf(\"upsells\");const tail=at===-1?parts.slice(-1):parts.slice(at+1);// The whole tail, not the last segment: nested upsell folders repeat\n// their leaf names, so a last-segment slug would report two different\n// offers under one step id.\nconst page=(tail.join(\"_\")||\"unknown\").toLowerCase().replace(/[^a-z0-9]+/g,\"_\").slice(0,40);const key=\"medvi_upsell_sent_\"+(intent.id||`${details.priceId??\"\"}_${intent.amount??\"\"}`);try{if(window.localStorage.getItem(key))return;window.localStorage.setItem(key,\"1\");}catch{}medvi(\"track\",\"funnel_step\",{step_id:`upsell_${page}_purchase`,step_index:102,funnel_name:\"upsell\"});medvi(\"track\",\"purchase\",{kind:\"upsell\",page,price_id:details.priceId??null,medication:details.medication??null,amount:typeof intent.amount===\"number\"?intent.amount/100:null,currency:(intent.currency||\"usd\").toUpperCase(),source:\"stripe\",payment_intent:intent.id??null});// Same sale into Plausible, as its own `Upsell` revenue goal - a separate\n// goal from `Purchase` so the initial-sale total stays readable without\n// custom properties. It sits after the dedupe above, so a retry after a\n// declined card cannot count twice, and it stays silent when the script is\n// absent or the intent carried no amount.\nconst plausible=window.plausible;if(typeof plausible===\"function\"&&typeof intent.amount===\"number\"&&intent.amount>0){plausible(\"Upsell\",{revenue:{currency:(intent.currency||\"usd\").toUpperCase(),amount:intent.amount/100}});}}catch{// Tracking must never surface on a page that is taking money.\n}}const BASE_URL=\"https://quadhook.medvi.org\";const STRIPE_PUBLISHABLE_KEY=\"pk_live_51QSLPP2euyA8TPKhnsLjsRFvCmKSfA812MmXw79H9EKIaebWZUkBmFdSo3hqoBsV0Pm8q6VIeur7wS67d5z64Su800kYexHjk5\";// \"pk_test_51RnQqGGaogCc5kLtER5YJNooQB6OWftsK7GLCev68Bhrnq5HsOWHP2bSXZJ3rzZqw8l6aRARItRnJoLj3CdWjjd1002rgzkJxI\"\nfunction getProgramType(value){const match=value?.match(/upsell-(glp|serm|nad)/);return match?match[1]:null;}export default function AddToOrder(props){const{priceId,medication,buttonText,returnUrlPath}=props;const[store,setStore]=useUpsellStore();const[error,setError]=useState(null);const handleUpsell=async()=>{if(store.isProcessing)return;// already locked\nif(!priceId){setError(\"No price selected.\");return;}const params=new URLSearchParams(window.location.search);const customerId=params.get(\"customer_id\");if(!customerId){setError(\"Something went wrong. Please try again.\");return;}params.set(\"price\",priceId);if(medication){params.set(\"medication\",medication);}const returnUrl=`${BASE_URL}/${returnUrlPath}?${params.toString()}`;setStore({isProcessing:true});setError(null);// Stays true only when the payment is navigating away or still settling.\n// Every other exit releases the lock in `finally`, so a failed payment\n// can never leave the buy and \"No Thanks\" buttons permanently disabled.\nlet keepLocked=false;try{const program=getProgramType(returnUrlPath);const coupon=params.get(\"whowantsacoupon\");const prepareRes=await fetch(`${BASE_URL}/v1/stripe/upsell-prepare`,{method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:JSON.stringify({customer_id:customerId,price:priceId,program,whowantsacoupon:coupon})});const prepareJson=await prepareRes.json().catch(()=>({}));if(!prepareRes.ok){const msg=prepareJson?.message||prepareJson?.errors?.price?.[0]||prepareJson?.errors?.customer_id?.[0]||`Could not start payment (${prepareRes.status})`;setError(msg);return;}if(!prepareJson?.success||!prepareJson?.data?.clientSecret){setError(prepareJson?.message||\"Invalid response from server (no client secret).\");return;}const stripe=await loadStripe(STRIPE_PUBLISHABLE_KEY);if(!stripe){setError(\"Could not load Stripe.\");return;}const{error:confirmError,paymentIntent}=await stripe.confirmPayment({clientSecret:prepareJson.data.clientSecret,confirmParams:{return_url:returnUrl},redirect:\"if_required\"});if(confirmError){setError(confirmError.message??\"Payment failed.\");return;}// No redirect (e.g. no 3DS challenge): finish on quadhook yourself.\n// \"succeeded\" is the happy path. Anything else here is still a real\n// payment in flight (e.g. \"processing\" on a delayed method), so send\n// the customer on rather than leaving the page frozen, and report the\n// true status so the backend does not fulfil an unsettled charge.\nif(paymentIntent){// Report the sale here, where the real charged amount exists.\n// Nothing downstream can see it: the redirect leaves for the\n// hook domain, and a settled charge never returns to the page.\nreportUpsellPurchase(paymentIntent,{priceId,medication});const done=new URL(returnUrl);done.searchParams.set(\"payment_intent\",paymentIntent.id);done.searchParams.set(\"redirect_status\",paymentIntent.status===\"succeeded\"?\"succeeded\":\"pending\");keepLocked=true;window.location.href=done.toString();return;}// No error and no payment intent came back: nothing to act on.\nsetError(\"Something went wrong. Please try again.\");}catch(err){const message=err instanceof Error?err.message:\"Unexpected error\";setError(message);}finally{if(!keepLocked)setStore({isProcessing:false});}};return /*#__PURE__*/_jsxs(_Fragment,{children:[/*#__PURE__*/_jsx(\"button\",{type:\"button\",onClick:()=>void handleUpsell(),disabled:store.isProcessing,style:{fontFamily:\"'Red Hat Text', 'Red Hat Text Placeholder', sans-serif\",fontSize:\"16px\",backgroundColor:store.isProcessing?\"rgba(0, 117, 41, 0.5)\":\"rgb(0, 117, 41)\",color:\"white\",fontWeight:600,width:\"100%\",height:\"100%\",display:\"flex\",flex:1,flexDirection:\"row\",alignItems:\"center\",justifyContent:\"center\",gap:\"8px\",borderRadius:\"9999px\",paddingLeft:\"24px\",paddingRight:\"24px\",paddingTop:\"12px\",paddingBottom:\"12px\",cursor:store.isProcessing?\"not-allowed\":\"pointer\",border:\"none\",opacity:store.isProcessing?.5:1},children:store.isProcessing?\"Processing...\":buttonText}),error&&/*#__PURE__*/_jsx(\"p\",{style:{marginTop:\"8px\",textAlign:\"center\",fontSize:\"14px\",color:\"rgb(239, 68, 68)\"},children:error})]});}addPropertyControls(AddToOrder,{priceId:{type:ControlType.String,title:\"Price ID\"},medication:{type:ControlType.String,title:\"Medication\"},buttonText:{type:ControlType.String,title:\"Button Text\",defaultValue:\"Add to Order\"},returnUrlPath:{type:ControlType.String,title:\"Return Url Path\",defaultValue:\"upsell-glp\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"AddToOrder\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./AddToOrder.map"],"mappings":"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"}