1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-09-02 13:52:46 +02:00

feat: add ai tutor gtags (#8656)

* feat: add ai tutor gtags

* fix: price id condition check
This commit is contained in:
Arik Chakma
2025-05-16 03:53:34 +06:00
committed by GitHub
parent 2867e25f2c
commit 6e1e334406
4 changed files with 76 additions and 14 deletions

View File

@@ -62,8 +62,8 @@ export function UpdatePlanConfirmation(props: UpdatePlanConfirmationProps) {
<h3 className="text-xl font-bold text-black">Subscription Update</h3> <h3 className="text-xl font-bold text-black">Subscription Update</h3>
<p className="mt-2 text-balance text-gray-600"> <p className="mt-2 text-balance text-gray-600">
Your plan will be updated to the{' '} Your plan will be updated to the{' '}
<b className="text-black">{planDetails.interval}</b> plan, and will <b className="text-black">{planDetails.interval}</b> plan, and will be
be charged{' '} charged{' '}
<b className="text-black"> <b className="text-black">
${selectedPrice.amount}/{selectedPrice.interval} ${selectedPrice.amount}/{selectedPrice.interval}
</b> </b>
@@ -72,21 +72,21 @@ export function UpdatePlanConfirmation(props: UpdatePlanConfirmationProps) {
<div className="mt-6 grid grid-cols-2 gap-3"> <div className="mt-6 grid grid-cols-2 gap-3">
<button <button
className="rounded-md border border-gray-200 py-2 text-sm font-semibold hover:bg-gray-50 transition-colors disabled:opacity-50" className="rounded-md border border-gray-200 py-2 text-sm font-semibold transition-colors hover:bg-gray-50 disabled:opacity-50"
onClick={onCancel} onClick={onCancel}
disabled={isPending} disabled={isPending}
> >
Cancel Cancel
</button> </button>
<button <button
className="flex items-center justify-center rounded-md bg-purple-600 py-2 text-sm font-semibold text-white hover:bg-purple-500 transition-colors disabled:opacity-50" className="flex items-center justify-center rounded-md bg-purple-600 py-2 text-sm font-semibold text-white transition-colors hover:bg-purple-500 disabled:opacity-50"
disabled={isPending} disabled={isPending}
onClick={() => { onClick={() => {
updatePlan({ priceId: selectedPrice.priceId }); updatePlan({ priceId: selectedPrice.priceId });
}} }}
> >
{isPending && ( {isPending && (
<Loader2Icon className="size-4 animate-spin stroke-[2.5] mr-2" /> <Loader2Icon className="mr-2 size-4 animate-spin stroke-[2.5]" />
)} )}
{!isPending && 'Confirm'} {!isPending && 'Confirm'}
</button> </button>

View File

@@ -136,6 +136,14 @@ export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
setSelectedPlan(currentPlan.interval); setSelectedPlan(currentPlan.interval);
}, [currentPlan]); }, [currentPlan]);
useEffect(() => {
window?.fireEvent({
action: 'tutor_pricing',
category: 'ai_tutor',
label: 'Clicked Upgrade to Pro',
});
}, []);
if (!user) { if (!user) {
return null; return null;
} }
@@ -262,18 +270,35 @@ export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
} }
onClick={() => { onClick={() => {
setSelectedPlan(plan.interval); setSelectedPlan(plan.interval);
if (!currentPlanPriceId) { if (!currentPlanPriceId) {
const currentUrlPath = window.location.pathname; const currentUrlPath = window.location.pathname;
const encodedCurrentUrlPath = encodeURIComponent( const encodedCurrentUrlPath =
currentUrlPath, encodeURIComponent(currentUrlPath);
);
const successPage = `/thank-you?next=${encodedCurrentUrlPath}&s=1`; const successPage = `/thank-you?next=${encodedCurrentUrlPath}&s=1`;
createCheckoutSession({ window?.fireEvent({
priceId: plan.priceId, action: 'tutor_checkout',
success: success || successPage, category: 'ai_tutor',
cancel: cancel || `${currentUrlPath}?s=0`, label: 'Checkout Started',
}); });
createCheckoutSession(
{
priceId: plan.priceId,
success: success || successPage,
cancel: cancel || `${currentUrlPath}?s=0`,
},
{
onSuccess: () => {
window?.fireEvent({
action: `tutor_checkout_${plan.interval === 'month' ? 'mo' : 'an'}`,
category: 'ai_tutor',
label: `${plan.interval} Plan Checkout Started`,
});
},
},
);
return; return;
} }
setIsUpdatingPlan(true); setIsUpdatingPlan(true);

View File

@@ -30,11 +30,40 @@ export function VerifyUpgrade(props: VerifyUpgradeProps) {
userBillingDetails.status === 'active' && userBillingDetails.status === 'active' &&
(newPriceId ? userBillingDetails.priceId === newPriceId : true) (newPriceId ? userBillingDetails.priceId === newPriceId : true)
) { ) {
if (!newPriceId) {
// it means that the user is subscribing for the first time
// not changing the plan
window?.fireEvent({
action: `tutor_purchase_${userBillingDetails.interval === 'month' ? 'mo' : 'an'}`,
category: 'ai_tutor',
label: `${userBillingDetails.interval} Plan Purchased`,
});
}
deleteUrlParam('s'); deleteUrlParam('s');
window.location.reload(); window.location.reload();
} }
}, [userBillingDetails]); }, [userBillingDetails]);
useEffect(() => {
// it means that the user is changing the plan
// not subscribing for the first time
if (newPriceId) {
return;
}
window?.fireEvent({
action: 'tutor_purchase',
category: 'ai_tutor',
label: 'Subscription Activated',
});
window?.fireEvent({
action: 'tutor_ty',
category: 'ai_tutor',
label: 'Thank You Page Visited',
});
}, [newPriceId]);
return ( return (
<Modal <Modal
// it's an unique modal, so we don't need to close it // it's an unique modal, so we don't need to close it
@@ -47,11 +76,11 @@ export function VerifyUpgrade(props: VerifyUpgradeProps) {
<h3 className="text-xl font-bold text-black">Subscription Activated</h3> <h3 className="text-xl font-bold text-black">Subscription Activated</h3>
</div> </div>
<p className="mt-2 text-balance text-center text-gray-600"> <p className="mt-2 text-center text-balance text-gray-600">
Your subscription has been activated successfully. Your subscription has been activated successfully.
</p> </p>
<p className="mt-4 text-balance text-center text-gray-600"> <p className="mt-4 text-center text-balance text-gray-600">
It might take a minute for the changes to reflect. We will{' '} It might take a minute for the changes to reflect. We will{' '}
<b className="text-black">reload</b> the page for you. <b className="text-black">reload</b> the page for you.
</p> </p>

View File

@@ -51,6 +51,14 @@ export function AICourse(props: AICourseProps) {
setCustomInstructions(fineTuneData.customInstructions); setCustomInstructions(fineTuneData.customInstructions);
}, []); }, []);
useEffect(() => {
window?.fireEvent({
action: 'tutor_user',
category: 'ai_tutor',
label: 'Visited AI Course Page',
});
}, []);
const handleKeyDown = (e: React.KeyboardEvent) => { const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && keyword.trim()) { if (e.key === 'Enter' && keyword.trim()) {
onSubmit(); onSubmit();