From 2538db4786bd36ebd675b0b10446ccded19bdc97 Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Thu, 10 Apr 2025 17:55:18 +0100 Subject: [PATCH] Implement course demo page (#8477) * Add course demo button * Read sample button on page * GA event for buy button * Add isTesting link --- .../AuthenticationFlow/CourseLoginPopup.tsx | 6 +- src/components/SQLCourse/BuyButton.tsx | 115 ++++++++++++------ 2 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/components/AuthenticationFlow/CourseLoginPopup.tsx b/src/components/AuthenticationFlow/CourseLoginPopup.tsx index 8eeaf9a8a..0a6c7a20c 100644 --- a/src/components/AuthenticationFlow/CourseLoginPopup.tsx +++ b/src/components/AuthenticationFlow/CourseLoginPopup.tsx @@ -12,6 +12,7 @@ type CourseLoginPopupProps = { }; export const CHECKOUT_AFTER_LOGIN_KEY = 'checkoutAfterLogin'; +export const SAMPLE_AFTER_LOGIN_KEY = 'sampleAfterLogin'; export function CourseLoginPopup(props: CourseLoginPopupProps) { const { onClose: parentOnClose, checkoutAfterLogin = true } = props; @@ -27,6 +28,7 @@ export function CourseLoginPopup(props: CourseLoginPopupProps) { // if user didn't login and closed the popup, we remove the checkoutAfterLogin flag // so that login from other buttons on course page will trigger purchase localStorage.removeItem(CHECKOUT_AFTER_LOGIN_KEY); + localStorage.removeItem(SAMPLE_AFTER_LOGIN_KEY); parentOnClose(); } @@ -40,7 +42,7 @@ export function CourseLoginPopup(props: CourseLoginPopupProps) { if (emailNature) { const emailHeader = (
-

+

{emailNature === 'login' ? 'Login to your account' : 'Create an account'} @@ -80,7 +82,7 @@ export function CourseLoginPopup(props: CourseLoginPopupProps) { return (

-

+

Create or login to Enroll

diff --git a/src/components/SQLCourse/BuyButton.tsx b/src/components/SQLCourse/BuyButton.tsx index 21088e286..7ae410f01 100644 --- a/src/components/SQLCourse/BuyButton.tsx +++ b/src/components/SQLCourse/BuyButton.tsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from '@tanstack/react-query'; -import { ArrowRightIcon, Play } from 'lucide-react'; +import { ArrowRightIcon, MousePointerClick, Play } from 'lucide-react'; import { useEffect, useState } from 'react'; import { cn } from '../../lib/classname'; import { @@ -10,12 +10,14 @@ import { import { coursePriceOptions } from '../../queries/billing'; import { courseProgressOptions } from '../../queries/course-progress'; import { queryClient } from '../../stores/query-client'; -import { CourseLoginPopup } from '../AuthenticationFlow/CourseLoginPopup'; +import { + CourseLoginPopup, + SAMPLE_AFTER_LOGIN_KEY, +} from '../AuthenticationFlow/CourseLoginPopup'; import { useToast } from '../../hooks/use-toast'; import { httpPost } from '../../lib/query-http'; import { deleteUrlParam, getUrlParams } from '../../lib/browser'; import { VideoModal } from '../VideoModal'; -import { showLoginPopup } from '../../lib/popup'; export const SQL_COURSE_SLUG = 'sql'; @@ -40,6 +42,8 @@ export function BuyButton(props: BuyButtonProps) { const [isVideoModalOpen, setIsVideoModalOpen] = useState(false); const toast = useToast(); + const isTesting = getUrlParams()['testing'] === '1'; + const { data: coursePricing, isLoading: isLoadingCourse } = useQuery( coursePriceOptions({ courseSlug: SQL_COURSE_SLUG }), queryClient, @@ -96,7 +100,13 @@ export function BuyButton(props: BuyButtonProps) { useEffect(() => { const urlParams = getUrlParams(); const shouldTriggerPurchase = urlParams[COURSE_PURCHASE_PARAM] === '1'; - if (shouldTriggerPurchase) { + const shouldTriggerSample = + localStorage.getItem(SAMPLE_AFTER_LOGIN_KEY) === '1'; + + if (shouldTriggerSample) { + localStorage.removeItem(SAMPLE_AFTER_LOGIN_KEY); + window.location.href = `${import.meta.env.PUBLIC_COURSE_APP_URL}/${SQL_COURSE_SLUG}`; + } else if (shouldTriggerPurchase) { deleteUrlParam(COURSE_PURCHASE_PARAM); initPurchase(); } @@ -163,6 +173,24 @@ export function BuyButton(props: BuyButtonProps) { initPurchase(); } + function onReadSampleClick() { + if (!isLoggedIn()) { + localStorage.setItem(SAMPLE_AFTER_LOGIN_KEY, '1'); + setIsLoginPopupOpen(true); + return; + } + + window?.fireEvent({ + action: `${SQL_COURSE_SLUG}_demo_started`, + category: 'course', + label: `${SQL_COURSE_SLUG} Course Demo Started`, + }); + + setTimeout(() => { + window.location.href = `${import.meta.env.PUBLIC_COURSE_APP_URL}/${SQL_COURSE_SLUG}`; + }, 200); + } + const courseLoginPopup = isLoginPopupOpen && ( setIsLoginPopupOpen(false)} /> ); @@ -177,43 +205,56 @@ export function BuyButton(props: BuyButtonProps) { onClose={() => setIsVideoModalOpen(false)} /> )} - + {isTesting &&!isLoadingPricing && !isAlreadyEnrolled && ( + )} - +

{!isLoadingPricing && ( - + Lifetime access ·{' '}