{"version":3,"file":"enroll-now-button.DpQI8R0R.js","sources":["../../../src/lib/ab-testing-service.ts","../../../src/lib/cpe-experiment-utils.ts","../../../src/components/enroll-now-button.tsx"],"sourcesContent":["import Cookies from 'js-cookie'\n\n// Constants for experiment names\nexport const EXPERIMENT_CPE_SOUTH_CAROLINA = 'cpe_south_carolina'\nexport const EXPERIMENT_CPE_NEW_MEXICO = 'cpe_new_mexico'\n\ntype Experiment = {\n eventName: string\n experimentName: string\n variants: string[]\n splitCondition: number\n}\n\ntype ExperimentHandlerOptions = {\n experimentName: string\n expirationDays?: number\n}\n\n// Currently running experiments\nconst experiments: Experiment[] = [\n {\n eventName: 'sc_529_split',\n experimentName: EXPERIMENT_CPE_SOUTH_CAROLINA,\n variants: ['redirect', 'cpe'],\n\t\tsplitCondition: 100.0 // 100% will see the control (A), 0% will see the variant (B)\n },\n {\n eventName: 'nm_529_split',\n experimentName: EXPERIMENT_CPE_NEW_MEXICO,\n variants: ['redirect', 'cpe'],\n splitCondition: 0.0 // 0% will see the control (A), 100% will see the variant (B)\n }\n]\n\n/**\n * Assigns an experiment variant, tracks the event, and sets the cookie if necessary.\n **/\nexport function handleExperiment({ experimentName, expirationDays = 365 }: ExperimentHandlerOptions): string | null {\n const experiment = findExperimentByName(experimentName)\n\n if (!experiment) {\n console.error(`Experiment \"${experimentName}\" not found`)\n return null\n }\n\n return assignVariantAndFireEvent({ experiment, expirationDays })\n}\n\n/**\n * Finds an experiment by its name.\n */\nfunction findExperimentByName(experimentName: string): Experiment | undefined {\n return experiments.find(experiment => experiment.experimentName === experimentName)\n}\n\n/**\n * Assigns a variant to the experiment based on the split condition, tracks the event, and sets the cookie.\n */\nfunction assignVariantAndFireEvent({ experiment, expirationDays }: {\n experiment: Experiment\n expirationDays: number\n}): string {\n const { variants, splitCondition, experimentName, eventName } = experiment\n const storedVariant = getVariantNameFromCookie(experimentName)\n\n if (storedVariant) {\n console.log(`Already stored variant ${storedVariant} for experiment ${experimentName}`)\n return storedVariant\n }\n\n const randomValue = Math.random()\n let cumulativeProbability = 0\n\n const splitConditions = [splitCondition, 1 - splitCondition]\n\n for (let i = 0;i < variants.length;i++) {\n cumulativeProbability += splitConditions[i]\n if (randomValue < cumulativeProbability) {\n const variant = variants[i]\n const cookieName = computeCookieName(experimentName)\n const domain = document.location.hostname === 'localhost' ? 'localhost' : `.${document.location.hostname}`\n const path = '/'\n\n Cookies.set(cookieName, variant, { expires: expirationDays, domain, path })\n\n const root = window as any\n root && root.gtag('event', eventName, { exp_name: experimentName, group: variant })\n window.heap && window.heap.track(eventName, { exp_name: experimentName, group: variant })\n\n console.log(\n `Cookie set and event fired for variant ${variant} and experiment ${experimentName}`\n )\n\n return variant\n }\n }\n\n throw new Error('Failed to assign variant')\n}\n\n/**\n * Retrieves the experiment variant from the cookie.\n */\nfunction getVariantNameFromCookie(experimentName: string): string | undefined {\n return Cookies.get(computeCookieName(experimentName))\n}\n\n/**\n * Computes the name of the cookie for the experiment.\n */\nfunction computeCookieName(experimentName: string): string {\n return `${experimentName}_experiment`\n}","import { EXPERIMENT_CPE_NEW_MEXICO, EXPERIMENT_CPE_SOUTH_CAROLINA, handleExperiment } from './ab-testing-service'\nimport { getEnrollmentSessionStartPath } from '@modules/enrollment/helpers'\n\nconst SC_FUTURE_SCHOLAR_PLAN_ID = 68\nconst NM_THE_EDUCATION_PLAN_PLAN_ID = 36\n\nconst PLAN_ID_TO_EXPERIMENT_NAME_MAP = {\n [SC_FUTURE_SCHOLAR_PLAN_ID]: EXPERIMENT_CPE_SOUTH_CAROLINA,\n [NM_THE_EDUCATION_PLAN_PLAN_ID]: EXPERIMENT_CPE_NEW_MEXICO\n}\n\nconst PLAN_ID_TO_URL_MAP = {\n [SC_FUTURE_SCHOLAR_PLAN_ID]: getEnrollmentSessionStartPath('ScFutureScholar'),\n [NM_THE_EDUCATION_PLAN_PLAN_ID]: getEnrollmentSessionStartPath('NmTheEducationPlan')\n}\n\n/**\n * Get the variant for the CPE experiment\n */\nconst DEFAULT_VARIANT = 'redirect'\nexport function getCpeExperimentVariant(experimentName: string): string {\n try {\n const variant = handleExperiment({ experimentName })\n\n return variant || DEFAULT_VARIANT\n } catch (error) {\n console.error(`Error running AB Experiment: ${experimentName}`, error)\n return DEFAULT_VARIANT\n }\n}\n\nexport function getExperimentNameForPlanId(planId: number): string | null {\n return PLAN_ID_TO_EXPERIMENT_NAME_MAP[planId as keyof typeof PLAN_ID_TO_EXPERIMENT_NAME_MAP]\n}\n\nexport function getUrlToCPEIfConditionsAreMet(cpeVariant: string, planId: number): string | null {\n if (cpeVariant === 'cpe' && PLAN_ID_TO_URL_MAP[planId as keyof typeof PLAN_ID_TO_URL_MAP]) {\n return PLAN_ID_TO_URL_MAP[planId as keyof typeof PLAN_ID_TO_URL_MAP]\n }\n return null\n}\n","import { useState, useEffect } from 'react'\nimport { LinkButton } from '@components/ui/link-button'\nimport type { ContextPlacement } from '@lib/analytics.d'\nimport { cn } from '@lib/utils'\nimport { getCpeExperimentVariant, getUrlToCPEIfConditionsAreMet, getExperimentNameForPlanId } from '@lib/cpe-experiment-utils'\n\nconst NC_529_PLAN_ID = 39\n\nexport interface EnrollNowButtonPlan {\n id: number\n name: string\n has_enroll_now: boolean\n enroll_now_url: string\n tracking_pixel_url: string\n state_object: {\n id?: string\n name: string\n slug?: string\n }\n}\n\n// The backend does not return the click source reliably, so we need to patch it in the frontend.\nconst patchEnrollNowUrl = (url: string, clickSource?: string) => {\n if (url && clickSource) {\n return url.replace(/(&|\\?)click_source=[^&]*/, '$1click_source=' + clickSource)\n }\n\n return url\n}\n\nexport const EnrollNowButton = ({\n plan,\n contextPlacement,\n className,\n clickSource,\n noCpe,\n text = 'Enroll Now',\n buttonVariant = 'default',\n size = 'default'\n}: {\n plan: EnrollNowButtonPlan\n contextPlacement: ContextPlacement\n className?: string\n clickSource?: string\n noCpe?: boolean\n text?: string\n buttonVariant?: 'default' | 'outline' | 'link'\n size?: 'default' | 'lg'\n}) => {\n const {\n state_object: { name: stateName },\n enroll_now_url,\n id,\n name,\n has_enroll_now,\n tracking_pixel_url\n } = plan\n\n const [enrollNowUrl, setEnrollNowUrl] = useState(enroll_now_url)\n const [userTarget, setUserTarget] = useState('plan_site')\n\n useEffect(() => {\n const experimentName = getExperimentNameForPlanId(id)\n if (!noCpe && experimentName) {\n const variant = getCpeExperimentVariant(experimentName)\n const url = getUrlToCPEIfConditionsAreMet(variant, id)\n if (url) {\n setEnrollNowUrl(url)\n setUserTarget('cpe')\n }\n }\n }, [])\n\n return (\n {\n const fbq = window?.fbq\n if (fbq) {\n fbq('track', 'Purchase', {\n content_ids: [id],\n content_name: name,\n content_type: 'plan',\n value: id === NC_529_PLAN_ID ? 7.5 : 0.0,\n currency: 'USD'\n })\n }\n }}\n >\n {text}\n {tracking_pixel_url && (\n \n )}\n \n )\n}\n"],"names":["EXPERIMENT_CPE_SOUTH_CAROLINA","EXPERIMENT_CPE_NEW_MEXICO","experiments","handleExperiment","experimentName","expirationDays","experiment","findExperimentByName","assignVariantAndFireEvent","variants","splitCondition","eventName","storedVariant","getVariantNameFromCookie","randomValue","cumulativeProbability","splitConditions","i","variant","cookieName","computeCookieName","domain","Cookies","root","SC_FUTURE_SCHOLAR_PLAN_ID","NM_THE_EDUCATION_PLAN_PLAN_ID","PLAN_ID_TO_EXPERIMENT_NAME_MAP","PLAN_ID_TO_URL_MAP","getEnrollmentSessionStartPath","DEFAULT_VARIANT","getCpeExperimentVariant","error","getExperimentNameForPlanId","planId","getUrlToCPEIfConditionsAreMet","cpeVariant","NC_529_PLAN_ID","patchEnrollNowUrl","url","clickSource","EnrollNowButton","plan","contextPlacement","className","noCpe","text","buttonVariant","size","stateName","enroll_now_url","id","name","has_enroll_now","tracking_pixel_url","enrollNowUrl","setEnrollNowUrl","useState","userTarget","setUserTarget","useEffect","jsxs","LinkButton","cn","fbq","jsx"],"mappings":"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"}