Files
classroomio/src/lib/components/CourseLandingPage/components/PricingSection.svelte
T

240 lines
6.8 KiB
Svelte
Raw Normal View History

<script lang="ts">
2023-09-15 08:26:26 +01:00
import get from 'lodash/get';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import getCurrencyFormatter from '$lib/utils/functions/getCurrencyFormatter';
import { isCourseFree } from '$lib/utils/functions/course';
2023-09-15 08:26:26 +01:00
import { getStudentInviteLink } from '$lib/utils/functions/course';
import { currentOrg } from '$lib/utils/store/org';
import { goto } from '$app/navigation';
import PaymentModal from './PaymentModal.svelte';
import type { Course } from '$lib/utils/types';
import { ROLE } from '$lib/utils/constants/roles';
export let className = '';
export let editMode = false;
2023-09-15 08:26:26 +01:00
export let courseData: Course;
export let startCoursePayment = false;
export let mobile = false;
let calculatedCost = 0;
let discount = 0;
let formatter: Intl.NumberFormat | undefined;
let isFree = false;
2023-09-26 23:29:50 +01:00
function calcDisc(percent: number, cost: number, showDiscount: boolean) {
if (!percent || !showDiscount) return cost;
2023-09-04 09:09:09 +00:00
const discountAmount = (percent / 100) * cost;
const discountedPrice = cost - discountAmount;
return Math.round(discountedPrice);
}
function handleJoinCourse() {
if (editMode) return;
if (isFree) {
2023-09-15 08:26:26 +01:00
const link = getStudentInviteLink(courseData, $currentOrg.siteName);
goto(link);
} else {
2023-09-15 08:26:26 +01:00
startCoursePayment = true;
}
}
function setFormatter(currency: string | undefined) {
if (!currency) return;
formatter = getCurrencyFormatter(currency);
}
2023-09-15 08:26:26 +01:00
function getTeacherEmail(group: Course['group']) {
const firstTutor = group?.members?.find((m) => m.role_id === ROLE.TUTOR);
return firstTutor?.profile?.email || '';
}
$: setFormatter(courseData.currency);
2023-09-26 23:29:50 +01:00
$: discount = get(courseData, 'metadata.discount', 0);
2023-10-30 04:52:00 +00:00
$: calculatedCost = calcDisc(discount, courseData.cost || 0, !!courseData.metadata.showDiscount);
$: isFree = isCourseFree(calculatedCost);
</script>
2023-09-15 08:26:26 +01:00
<PaymentModal
bind:open={startCoursePayment}
paymentLink={get(courseData, 'metadata.paymentLink', '')}
courseName={courseData.title}
teacherEmail={getTeacherEmail(courseData.group)}
/>
<!-- Pricing Details -->
{#if mobile}
<div
class="sticky w-full flex items-center justify-center transition duration-300 h-fit bottom-0 lg:hidden bg-gray-50 dark:bg-neutral-800"
>
<aside
class="price-container sticky lg:hidden {editMode
? 'lg:bottom-2'
: 'lg:top-10'} lg:shadow-2xl lg:rounded-lg m-h-fit bg-gray-50 dark:bg-neutral-800 z-0 {className}"
>
<div class="flex items-center justify-center gap-3 px-3 py-3">
<!-- Pricing -->
<div class=" text-center">
2023-10-30 04:52:00 +00:00
{#if courseData?.metadata?.allowNewStudent}
<p class="dark:text-white font-medium text-sm flex items-center gap-1">
{formatter?.format(calculatedCost) || calculatedCost}
{#if isFree}
<span class="text-xs">(Free)</span>
{/if}
</p>
{#if courseData?.metadata?.showDiscount}
<p class="dark:text-white font-light text-sm text-gray-500">
{discount}% Discount.
<span class="line-through"
>{formatter?.format(courseData?.cost || 0) || courseData.cost}</span
>
</p>
{/if}
2023-10-30 04:52:00 +00:00
{:else}
<p class="dark:text-white text-lg">
This course is currently not accepting new students.
</p>
{/if}
</div>
<!-- Call To Action Buttons -->
<div class="flex flex-col w-full h-full items-center">
<PrimaryButton
2023-11-04 17:53:59 +00:00
label={isFree ? 'Enroll Now' : 'Buy Now'}
className="w-full sm:w-full h-[40px]"
onClick={handleJoinCourse}
2023-10-30 04:52:00 +00:00
isDisabled={!courseData.metadata.allowNewStudent}
/>
</div>
</div>
</aside>
</div>
{:else}
<aside
class="price-container lg:sticky {editMode
? 'lg:top-0'
: 'lg:top-10'} lg:shadow-2xl lg:rounded-lg m-h-fit dark:bg-neutral-800 {className}"
>
<div class="p-2 lg:p-10">
<!-- Pricing -->
<div class="mb-6">
2023-10-30 04:52:00 +00:00
{#if courseData?.metadata?.allowNewStudent}
<p class="dark:text-white font-medium text-lg">
{formatter?.format(calculatedCost) || calculatedCost}
{#if isFree}
<span class="text-sm">(Free)</span>
{/if}
</p>
{#if courseData?.metadata?.showDiscount}
<p class="dark:text-white font-light text-sm text-gray-500">
{discount}% Discount.
<span class="line-through"
>{formatter?.format(courseData?.cost || 0) || courseData.cost}</span
>
</p>
{/if}
2023-10-30 04:52:00 +00:00
{:else}
<p class="dark:text-white text-lg">
This course is currently not accepting new students.
</p>
{/if}
</div>
<!-- Call To Action Buttons -->
<div class="flex flex-col w-full items-center">
<PrimaryButton
2023-11-04 17:53:59 +00:00
label={isFree ? 'Enroll Now' : 'Buy Now'}
className="w-full sm:w-full py-3 mb-3"
onClick={handleJoinCourse}
2023-10-30 04:52:00 +00:00
isDisabled={!courseData.metadata.allowNewStudent}
/>
2023-10-30 04:52:00 +00:00
{#if courseData?.metadata?.showDiscount && courseData.metadata.allowNewStudent}
<p class="dark:text-white font-light text-sm text-gray-500">Early bird offer. Buy ASAP</p>
{/if}
</div>
</div>
<!-- Gift Container -->
{#if courseData?.metadata?.reward?.show}
<div class="p-10 flex items-center flex-col border-t border-b border-gray-300">
{@html get(courseData, 'metadata.reward.description', '')}
</div>
{/if}
</aside>
{/if}
<style lang="scss">
.banner {
background-color: #040f2d;
min-height: 472px;
}
.author {
color: #7888b7;
}
.banner-image {
max-width: 559px;
}
.backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
.active {
position: relative;
display: inline-block;
}
.active::after {
position: absolute;
content: '';
width: 100%;
height: 3px;
background-color: var(--main-primary-color);
display: block;
bottom: -14px;
left: 0px;
}
.price-container {
width: 90%;
max-width: 405px;
height: fit-content;
}
@media screen and (min-width: 768px) {
.price-container {
width: 50%;
height: fit-content;
}
}
@media screen and (min-width: 1024px) {
.price-container {
width: 350px;
min-width: 250px;
}
}
@media screen and (min-width: 1280px) {
.price-container {
width: 405px;
min-width: 330px;
height: fit-content;
}
}
.course-content {
max-width: 608px;
}
:global(.list ul li) {
margin-left: 1rem;
list-style-type: disc;
}
:global(.plyr) {
width: 100% !important;
}
</style>