parent
586e8a8251
commit
7e4e2b4b62
5 changed files with 5 additions and 175 deletions
@ -1,95 +0,0 @@ |
||||
import { useEffect, useState } from 'react'; |
||||
import { Loader2 } from 'lucide-react'; |
||||
import { useMutation, useQuery } from '@tanstack/react-query'; |
||||
import { billingDetailsOptions } from '../../queries/billing'; |
||||
import { queryClient } from '../../stores/query-client'; |
||||
import { Modal } from '../Modal'; |
||||
import { httpPost } from '../../lib/query-http'; |
||||
import { useToast } from '../../hooks/use-toast'; |
||||
|
||||
type UpgradeAndEnrollProps = { |
||||
courseSlug: string; |
||||
}; |
||||
|
||||
export function UpgradeAndEnroll(props: UpgradeAndEnrollProps) { |
||||
const { courseSlug } = props; |
||||
|
||||
const { data: userBillingDetails, isFetching } = useQuery( |
||||
{ |
||||
...billingDetailsOptions(), |
||||
refetchInterval: 1000, |
||||
}, |
||||
queryClient, |
||||
); |
||||
|
||||
const toast = useToast(); |
||||
const [isEnrolled, setIsEnrolled] = useState(false); |
||||
|
||||
const { mutate: enroll, isPending: isEnrolling } = useMutation( |
||||
{ |
||||
mutationFn: () => { |
||||
return httpPost(`/v1-enroll-course/${courseSlug}`, {}); |
||||
}, |
||||
onSuccess: () => { |
||||
setIsEnrolled(true); |
||||
const courseUrl = `${import.meta.env.PUBLIC_COURSE_APP_URL}/${courseSlug}`; |
||||
window.location.href = courseUrl; |
||||
}, |
||||
onError: (error) => { |
||||
console.error(error); |
||||
toast.error(error?.message || 'Failed to enroll'); |
||||
}, |
||||
onMutate: () => { |
||||
queryClient.cancelQueries(billingDetailsOptions()); |
||||
}, |
||||
}, |
||||
queryClient, |
||||
); |
||||
|
||||
useEffect(() => { |
||||
if (!userBillingDetails || isEnrolling) { |
||||
return; |
||||
} |
||||
|
||||
if (userBillingDetails.status === 'active' && !isEnrolled) { |
||||
enroll(); |
||||
} |
||||
}, [userBillingDetails, isEnrolling, isEnrolled]); |
||||
|
||||
return ( |
||||
<Modal |
||||
// it's an unique modal, so we don't need to close it
|
||||
// user can close it by refreshing the page
|
||||
onClose={() => {}} |
||||
bodyClassName="rounded-xl bg-white p-6" |
||||
> |
||||
<div className="flex items-center justify-between gap-2"> |
||||
<h3 className="text-xl font-bold">Activated & Enrolling</h3> |
||||
|
||||
{isFetching && ( |
||||
<div className="flex animate-pulse items-center gap-2"> |
||||
<Loader2 className="h-4 w-4 animate-spin stroke-[2.5px] text-gray-500" /> |
||||
<span className="text-gray-500">Refreshing</span> |
||||
</div> |
||||
)} |
||||
</div> |
||||
<p className="mt-2 text-balance text-gray-500"> |
||||
Your subscription has been activated successfully, we are enrolling you |
||||
to the course. |
||||
</p> |
||||
|
||||
<p className="mt-4 text-balance text-gray-500"> |
||||
It might take a few minutes for the changes to reflect. We will{' '} |
||||
<b className="text-gray-600">reload</b> the page for you. |
||||
</p> |
||||
|
||||
<p className="mt-4 text-gray-500"> |
||||
If it takes longer than expected, please{' '} |
||||
<a className="text-blue-500 underline underline-offset-2 hover:text-blue-300"> |
||||
contact us |
||||
</a> |
||||
. |
||||
</p> |
||||
</Modal> |
||||
); |
||||
} |
@ -1,75 +0,0 @@ |
||||
import { useEffect, useState } from 'react'; |
||||
import { Loader2 } from 'lucide-react'; |
||||
import { useMutation, useQuery } from '@tanstack/react-query'; |
||||
import { billingDetailsOptions } from '../../queries/billing'; |
||||
import { queryClient } from '../../stores/query-client'; |
||||
import { Modal } from '../Modal'; |
||||
import { httpPost } from '../../lib/query-http'; |
||||
import { useToast } from '../../hooks/use-toast'; |
||||
import { courseProgressOptions } from '../../queries/course-progress'; |
||||
import { isLoggedIn } from '../../lib/jwt'; |
||||
import { deleteUrlParam } from '../../lib/browser'; |
||||
|
||||
type VerifyEnrollmentProps = { |
||||
courseSlug: string; |
||||
}; |
||||
|
||||
export function VerifyEnrollment(props: VerifyEnrollmentProps) { |
||||
const { courseSlug } = props; |
||||
|
||||
const { data: courseProgress, isFetching } = useQuery( |
||||
{ |
||||
...courseProgressOptions(courseSlug), |
||||
enabled: !!isLoggedIn(), |
||||
refetchInterval: 1000, |
||||
}, |
||||
queryClient, |
||||
); |
||||
|
||||
const toast = useToast(); |
||||
|
||||
useEffect(() => { |
||||
if (!courseProgress) { |
||||
return; |
||||
} |
||||
|
||||
if (courseProgress.startedAt) { |
||||
deleteUrlParam('e'); |
||||
window.location.reload(); |
||||
} |
||||
}, [courseProgress]); |
||||
|
||||
return ( |
||||
<Modal |
||||
// it's an unique modal, so we don't need to close it
|
||||
// user can close it by refreshing the page
|
||||
onClose={() => {}} |
||||
bodyClassName="rounded-xl bg-white p-6" |
||||
> |
||||
<div className="flex items-center justify-between gap-2"> |
||||
<h3 className="text-xl font-bold">Enrolling</h3> |
||||
|
||||
<div className="flex animate-pulse items-center gap-2"> |
||||
<Loader2 className="h-4 w-4 animate-spin stroke-[2.5px] text-gray-500" /> |
||||
<span className="text-gray-500">Refreshing</span> |
||||
</div> |
||||
</div> |
||||
<p className="mt-2 text-balance text-gray-500"> |
||||
We are enrolling you to the course. Please wait. |
||||
</p> |
||||
|
||||
<p className="mt-4 text-balance text-gray-500"> |
||||
It might take a few minutes for the changes to reflect. We will{' '} |
||||
<b className="text-gray-600">reload</b> the page for you. |
||||
</p> |
||||
|
||||
<p className="mt-4 text-gray-500"> |
||||
If it takes longer than expected, please{' '} |
||||
<a className="text-blue-500 underline underline-offset-2 hover:text-blue-300"> |
||||
contact us |
||||
</a> |
||||
. |
||||
</p> |
||||
</Modal> |
||||
); |
||||
} |
Loading…
Reference in new issue