CLASSROOMIO-T-180:Made the card stay at the bottom of the Landingpage

CLASSROOMIO-T-180: Subtle improvements

Merge branch 'CLASSROOMIO-T-180' of https://gitlab.com/thenextgreat/classroomio into CLASSROOMIO-T-180

CLASSROOMIO-T-180:Used a single component for the card

CLASSROOMIO-T-180:Used a single component for the card

CLASSROOMIO-T-180:Fixed a bug in the intersection observer

CLASSROOMIO-T-180:Fixed a bug in the intersection observer

CLASSROOMIO-T-180:Made the card stay at the bottom

CLASSROOMIO-T-180:Used a single component for the card

CLASSROOMIO-T-180:Used a single component for the card

CLASSROOMIO-T-180:Fixed a bug in the intersection observer

CLASSROOMIO-T-180:Fixed a bug in the intersection observer

Merge branch 'main' into CLASSROOMIO-T-180

CLASSROOMIO-T-180:Made the card stay at the bottom


Co-authored-by: Ifeanyi Nwosu <ifeanyi@digdippa.com>
Co-authored-by: Rotimi Best <rotimiibitoyeemma@gmail.com>


Merge-request: CLASSROOMIO-MR-79
Merged-by: Best Admin <best@digdippa.com>
This commit is contained in:
emmanuel
2023-09-26 11:08:24 +00:00
committed by Space Cloud
co-authored by Rotimi Best
parent 07b92fbe92
commit ce2b12c417
4 changed files with 147 additions and 48 deletions
@@ -147,7 +147,7 @@
<aside <aside
class={`${ class={`${
show ? '-translate-x-[100%] fixed md:absolute z-[50]' : 'translate-x-0 fixed md:relative z-[50]' show ? '-translate-x-[100%] fixed md:absolute z-[50]' : 'translate-x-0 fixed md:relative z-[50]'
}left-0 transition w-[350px] min-w-[300px] bg-gray-100 dark:bg-neutral-800 h-full border border-l-0 border-t-0 border-b-0 border-r-1`} }left-0 z-[50] transition w-[90vw] min-w-[300px] max-w-[350px] bg-gray-100 dark:bg-neutral-800 h-full border border-l-0 border-t-0 border-b-0 border-r-1`}
> >
<div class="toggler rounded-full shadow-lg absolute"> <div class="toggler rounded-full shadow-lg absolute">
<IconButton <IconButton
@@ -0,0 +1,19 @@
export function observeIntersection(node, callback, options = {}) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
callback(true);
} else {
callback(false);
}
});
}, options);
observer.observe(node);
return {
destroy() {
observer.unobserve(node);
}
};
}
@@ -14,6 +14,7 @@
export let editMode = false; export let editMode = false;
export let courseData: Course; export let courseData: Course;
export let startCoursePayment = false; export let startCoursePayment = false;
export let mobile = false;
let calculatedCost = 0; let calculatedCost = 0;
let discount = 0; let discount = 0;
@@ -63,48 +64,89 @@
/> />
<!-- Pricing Details --> <!-- Pricing Details -->
<aside {#if mobile}
class="{className} price-container lg:sticky {editMode <div
? 'lg:top-0' 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"
: 'lg:top-10'} lg:shadow-2xl lg:rounded-lg m-h-fit bg-neutral-800" >
> <aside
<div class="p-10"> class="price-container sticky lg:hidden {editMode
<!-- Pricing --> ? 'lg:bottom-2'
<div class="mb-6"> : 'lg:top-10'} lg:shadow-2xl lg:rounded-lg m-h-fit bg-gray-50 dark:bg-neutral-800 z-0 {className}"
<p class="dark:text-white font-medium text-lg"> >
{formatter?.format(calculatedCost) || calculatedCost} <div class="flex items-center justify-center gap-3 px-3 py-3">
{#if isFree} <!-- Pricing -->
<span class="text-sm">(Free)</span> <div class=" text-center">
{/if} <p class="dark:text-white font-medium text-sm flex items-center gap-1">
</p> {formatter?.format(calculatedCost) || calculatedCost}
{#if courseData?.metadata?.showDiscount} {#if isFree}
<p class="dark:text-white font-light text-sm text-gray-500"> <span class="text-xs">(Free)</span>
{discount}% Discount. {/if}
<span class="line-through" </p>
>{formatter?.format(courseData?.cost || 0) || courseData.cost}</span {#if courseData?.metadata?.showDiscount}
> <p class="dark:text-white font-light text-sm text-gray-500">
</p> {discount}% Discount.
{/if} <span class="line-through"
</div> >{formatter?.format(courseData?.cost || 0) || courseData.cost}</span
>
</p>
{/if}
</div>
<!-- Call To Action Buttons --> <!-- Call To Action Buttons -->
<div class="flex flex-col w-full items-center"> <div class="flex flex-col w-full h-full items-center">
<PrimaryButton <PrimaryButton
label={isFree ? 'Join Course' : 'Buy Now'} label={isFree ? 'Join Course' : 'Buy Now'}
className="w-full sm:w-full py-3 mb-3" className="w-full sm:w-full h-[40px]"
onClick={handleJoinCourse} onClick={handleJoinCourse}
/> />
<p class="dark:text-white font-light text-sm text-gray-500">Early bird offer. Buy ASAP</p> </div>
</div> </div>
</aside>
</div> </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">
<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}
</div>
<!-- Gift Container --> <!-- Call To Action Buttons -->
{#if courseData?.metadata?.reward?.show} <div class="flex flex-col w-full items-center">
<div class="p-10 flex items-center flex-col border-t border-b border-gray-300"> <PrimaryButton
{@html get(courseData, 'metadata.reward.description', '')} label={isFree ? 'Join Course' : 'Buy Now'}
className="w-full sm:w-full py-3 mb-3"
onClick={handleJoinCourse}
/>
<p class="dark:text-white font-light text-sm text-gray-500">Early bird offer. Buy ASAP</p>
</div>
</div> </div>
{/if}
</aside> <!-- 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"> <style lang="scss">
.banner { .banner {
@@ -141,18 +183,30 @@
} }
.price-container { .price-container {
width: 405px; width: 90%;
min-width: 330px; max-width: 405px;
height: fit-content; height: fit-content;
} }
@media screen and (max-width: 1024px) { @media screen and (min-width: 768px) {
.price-container {
width: 50%;
height: fit-content;
}
}
@media screen and (min-width: 1024px) {
.price-container { .price-container {
width: 350px; width: 350px;
min-width: 250px; min-width: 250px;
} }
} }
@media screen and (min-width: 1280px) {
.price-container {
width: 405px;
min-width: 330px;
height: fit-content;
}
}
.course-content { .course-content {
max-width: 608px; max-width: 608px;
} }
@@ -1,7 +1,8 @@
<script lang="ts"> <script lang="ts">
// import paystack from 'paystack'; // import paystack from 'paystack';
import get from 'lodash/get'; import get from 'lodash/get';
import { onMount } from 'svelte'; import { observeIntersection } from './components/IntersectionObserver';
import { onMount, onDestroy } from 'svelte';
import pluralize from 'pluralize'; import pluralize from 'pluralize';
import { page } from '$app/stores'; import { page } from '$app/stores';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -42,6 +43,8 @@
let averageRating = 0; let averageRating = 0;
let totalRatings = 0; let totalRatings = 0;
let startCoursePayment = false; let startCoursePayment = false;
let isVisible = false;
let observer;
// initialize the expandDescription array with 'false' values for each review. // initialize the expandDescription array with 'false' values for each review.
let expandDescription = Array(reviews.length).fill(false); let expandDescription = Array(reviews.length).fill(false);
@@ -75,6 +78,14 @@
onMount(() => { onMount(() => {
window.onhashchange = locationHashChanged; window.onhashchange = locationHashChanged;
const targetNode = document.querySelector('.target-component');
observer = observeIntersection(targetNode, (inView) => {
isVisible = inView;
});
});
onDestroy(() => {
observer?.destroy();
}); });
$: video = get(courseData, 'metadata.videoUrl'); $: video = get(courseData, 'metadata.videoUrl');
@@ -110,7 +121,7 @@
</p> </p>
<PrimaryButton <PrimaryButton
label="Start Course" label="Start Course"
className="px-6 py-5 mt-6 sm:w-fit" className="px-6 py-5 mt-6 sm:w-fit hidden md:block"
onClick={() => { onClick={() => {
startCoursePayment = true; startCoursePayment = true;
}} }}
@@ -162,11 +173,12 @@
<!-- Body --> <!-- Body -->
<div class="bg-white dark:bg-black w-full"> <div class="bg-white dark:bg-black w-full">
<div <div
class="py-8 lg:w-11/12 w-full m-2 lg:m-auto flex flex-col-reverse lg:flex-row items-center lg:items-start justify-between max-w-[1200px]" class="lg:py-8 lg:w-11/12 w-full mx-0 my-2 lg:m-auto flex flex-col-reverse lg:flex-row items-center lg:items-start justify-between max-w-[1200px]"
> >
<!-- Course Details --> <!-- Course Details -->
<div class="course-content w-full p-3 lg:w-10/12 lg:mr-10"> <div class="course-content w-full p-3 lg:w-10/12 lg:mr-10">
<!-- Navigation --> <!-- Navigation -->
<nav <nav
class="flex items-center border-b border-gray-300 py-3 sticky top-0 {!editMode && class="flex items-center border-b border-gray-300 py-3 sticky top-0 {!editMode &&
'lg:top-11'} bg-white dark:bg-neutral-800" 'lg:top-11'} bg-white dark:bg-neutral-800"
@@ -175,7 +187,7 @@
<a <a
href="{$page.url.pathname}{navItem.key}" href="{$page.url.pathname}{navItem.key}"
class="{navItem.key === activeNav && class="{navItem.key === activeNav &&
'active text-primary-700'} rounded-lg px-2 mr-6 text-slate-700 font-normal hover:bg-neutral-600 hover:text-slate-900 dark:text-white" 'active text-primary-700'} rounded-lg px-2 mr-6 text-slate-700 font-normal hover:bg-neutral-600 hover:text-slate-900 dark:text-white z-0"
> >
{navItem.label} {navItem.label}
</a> </a>
@@ -416,8 +428,22 @@
</div> </div>
<!-- Pricing Details --> <!-- Pricing Details -->
<PricingSection {courseData} {editMode} bind:startCoursePayment /> <PricingSection
{courseData}
{editMode}
bind:startCoursePayment
className="target-component"
/>
</div> </div>
{#if !isVisible}
<PricingSection
{courseData}
{editMode}
bind:startCoursePayment
mobile={true}
className="w-full"
/>
{/if}
</div> </div>
</div> </div>