import { useMutation, useQuery } from '@tanstack/react-query'; import { ArrowRightIcon, Play } from 'lucide-react'; import { useEffect, useState } from 'react'; import { cn } from '../../lib/classname'; import { COURSE_PURCHASE_PARAM, COURSE_PURCHASE_SUCCESS_PARAM, isLoggedIn, } from '../../lib/jwt'; import { coursePriceOptions } from '../../queries/billing'; import { courseProgressOptions } from '../../queries/course-progress'; import { queryClient } from '../../stores/query-client'; import { CourseLoginPopup } 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'; type CreateCheckoutSessionBody = { courseId: string; success?: string; cancel?: string; }; type CreateCheckoutSessionResponse = { checkoutUrl: string; }; type BuyButtonProps = { variant?: 'main' | 'floating' | 'top-nav'; }; export function BuyButton(props: BuyButtonProps) { const { variant = 'main' } = props; const [isLoginPopupOpen, setIsLoginPopupOpen] = useState(false); const [isVideoModalOpen, setIsVideoModalOpen] = useState(false); const toast = useToast(); const { data: coursePricing, isLoading: isLoadingCourse } = useQuery( coursePriceOptions({ courseSlug: SQL_COURSE_SLUG }), queryClient, ); const { data: courseProgress, isLoading: isLoadingCourseProgress } = useQuery( courseProgressOptions(SQL_COURSE_SLUG), queryClient, ); const { mutate: createCheckoutSession, isPending: isCreatingCheckoutSession, } = useMutation( { mutationFn: (body: CreateCheckoutSessionBody) => { return httpPost( '/v1-create-checkout-session', body, ); }, onMutate: () => { toast.loading('Creating checkout session...'); }, onSuccess: (data) => { if (!window.gtag) { window.location.href = data.checkoutUrl; return; } window?.fireEvent({ action: `${SQL_COURSE_SLUG}_begin_checkout`, category: 'course', label: `${SQL_COURSE_SLUG} Course Checkout Started`, callback: () => { window.location.href = data.checkoutUrl; }, }); // Hacky way to make sure that we redirect in case // GA was blocked or not able to redirect the user. setTimeout(() => { window.location.href = data.checkoutUrl; }, 3000); }, onError: (error) => { console.error(error); toast.error(error?.message || 'Failed to create checkout session'); }, }, queryClient, ); useEffect(() => { const urlParams = getUrlParams(); const shouldTriggerPurchase = urlParams[COURSE_PURCHASE_PARAM] === '1'; if (shouldTriggerPurchase) { deleteUrlParam(COURSE_PURCHASE_PARAM); initPurchase(); } }, []); useEffect(() => { const urlParams = getUrlParams(); const param = urlParams?.[COURSE_PURCHASE_SUCCESS_PARAM]; if (!param) { return; } const success = param === '1'; if (success) { window?.fireEvent({ action: `${SQL_COURSE_SLUG}_purchase_complete`, category: 'course', label: `${SQL_COURSE_SLUG} Course Purchase Completed`, }); } else { window?.fireEvent({ action: `${SQL_COURSE_SLUG}_purchase_canceled`, category: 'course', label: `${SQL_COURSE_SLUG} Course Purchase Canceled`, }); } deleteUrlParam(COURSE_PURCHASE_SUCCESS_PARAM); }, []); const isLoadingPricing = isLoadingCourse || !coursePricing || isLoadingCourseProgress || isCreatingCheckoutSession; const isAlreadyEnrolled = !!courseProgress?.enrolledAt; function initPurchase() { if (!isLoggedIn()) { setIsLoginPopupOpen(true); return; } createCheckoutSession({ courseId: SQL_COURSE_SLUG, success: `/courses/${SQL_COURSE_SLUG}?${COURSE_PURCHASE_SUCCESS_PARAM}=1`, cancel: `/courses/${SQL_COURSE_SLUG}?${COURSE_PURCHASE_SUCCESS_PARAM}=0`, }); } function onBuyClick() { if (!isLoggedIn()) { setIsLoginPopupOpen(true); return; } const hasEnrolled = !!courseProgress?.enrolledAt; if (hasEnrolled) { window.location.href = `${import.meta.env.PUBLIC_COURSE_APP_URL}/${SQL_COURSE_SLUG}`; return; } initPurchase(); } const courseLoginPopup = isLoginPopupOpen && ( setIsLoginPopupOpen(false)} /> ); if (variant === 'main') { return (
{courseLoginPopup} {isVideoModalOpen && ( setIsVideoModalOpen(false)} /> )} {!isLoadingPricing && ( Lifetime access ·{' '} )}
); } if (variant === 'top-nav') { return ( ); } return (
{courseLoginPopup} {!isLoadingPricing && !isAlreadyEnrolled && ( Lifetime access · Free updates )}
); }