CLASSROOMIO-T-115:Allow Landing page UI to use Org Landing page settings
CLASSROOMIO-T-115: Fetch data on server CLASSROOMIO-T-115: Add dynamic debug orgs, handle not found orgs, add 404 to public route CLASSROOMIO-T-115:Automacally add prefix to the footer input CLASSROOMIO-T-115:Implemented the video to also play youtube videos Merge branch 'CLASSROOMIO-T-115' of https://gitlab.com/thenextgreat/classroomio into CLASSROOMIO-T-115 CLASSROOMIO-T-115:Implemented the video to also play youtube videos CLASSROOMIO-T-115:Still woking on the landing page UI CLASSROOMIO-T-115: Some improvements CLASSROOMIO-T-115:Working on the landing page UI Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio Merge branch 'main' of https://gitlab.com/thenextgreat/classroomio CLASSROOMIO-T-27: Review Section for Instructors on landing page CLASSROOMIO-T-27: Remove unused variable Merge branch 'CLASSROOMIO-T-27' of https://gitlab.com/thenextgreat/classroomio into CLASSROOMIO-T-27 CLASSROOMIO-T-27: Complete reviews functionality CLASSROOMIO-T-27: Review Render Update CLASSROOMIO-T-27: - Resolved Feedbacks CLASSROOMIO-T-27: Fixed Ratings Data CLASSROOMIO-T-27: - Added Ratings Svg - Fixed avatar_url feedback CLASSROOMIO-T-27: Import Adjustment CLASSROOMIO-T-27: Code Review CLASSROOM-T-27: Added Add Review Functionality CLASSROOMIO-T-27: - Unresolved Review - Enhance Code Redability CLASSROOMIO-T-27: Completed the delete functionality CLASSROOMIO-T-27: Hide/Show functionality CLASSROOMIO-T-27: Double Quotation Update CLASSROOMIO-T-27: Testing toggle functinality CLASSROOMIO-T-27: Added the icons CLASSROOMIO-T-27: Completion of the hide/show functionality CLASSROOMIO-T-27: Display the store data on the review page for styling CLASSROOMIO-T-27: Styling of the review component & connecting it's data CLASSROOMIO-T-27: - Add ReviewsForm - Completion of the Reviews Form Structure/Styling CLASSROOMIO-T-27: Added a reviews modal CLASSROOMIO-T-27: Logic update for review section CLASSROOMIO-T-50: Logic for overlapping reviews CLASSROOMIO-T-27: - Completion of the structure & styling with mock data. - Addition of custom ratings assets CLASSROOMIO-T-27: - Review Section Code Structure - Import Profile Picture Assets Co-authored-by: Rotimi Best <[email protected]> Co-authored-by: Tunji Adeyemi <[email protected]> Co-authored-by: tunny17 <[email protected]> Merge-request: CLASSROOMIO-MR-22 Merged-by: Best Admin <[email protected]> CLASSROOMIO-T-62: Dark Mode Bug Fix CLASSROOMIO-T-62: Delete Unused class CLASSROOMIO-T-62: Dark Mode Bug Fix Co-authored-by: Tunji Adeyemi <[email protected]> Merge-request: CLASSROOMIO-MR-23 Merged-by: Best Admin <[email protected]> Co-authored-by: Ifeanyi Nwosu <[email protected]> Co-authored-by: Rotimi Best <[email protected]> Co-authored-by: Tunji Adeyemi <[email protected]> Co-authored-by: tunny17 <[email protected]> Merge-request: CLASSROOMIO-MR-53 Merged-by: Best Admin <[email protected]>
This commit is contained in:
committed by
Space Cloud
co-authored by
Rotimi Best
tunny17
Ifeanyi Nwosu
parent
a422f2f290
commit
a716c07cf5
@@ -9,9 +9,7 @@
|
||||
|
||||
<CopyCourseModal />
|
||||
|
||||
<div
|
||||
class="flex items-center justify-center lg:justify-start flex-wrap my-4 m-auto"
|
||||
>
|
||||
<div class="w-full cards-container my-4 m-auto">
|
||||
{#if $courseMetaDeta.isLoading}
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
@@ -35,8 +33,7 @@
|
||||
<CoursesEmptyIcon />
|
||||
<h3 class="dark:text-white text-2xl my-5">No Courses Created</h3>
|
||||
<p class="dark:text-white w-1/3 text-center">
|
||||
Share your knowledge with the world by creating engaging courses for
|
||||
your students.
|
||||
Share your knowledge with the world by creating engaging courses for your students.
|
||||
</p>
|
||||
</Box>
|
||||
{/each}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { writable } from 'svelte/store';
|
||||
|
||||
export const courses = writable([]);
|
||||
export const courseMetaDeta = writable({
|
||||
isLoading: false,
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
export const createCourseModal = writable({
|
||||
@@ -11,7 +11,7 @@ export const createCourseModal = writable({
|
||||
description: '',
|
||||
emails: '',
|
||||
tutors: '',
|
||||
students: '',
|
||||
students: ''
|
||||
});
|
||||
|
||||
export const copyCourseModalInitialState = {
|
||||
@@ -20,6 +20,6 @@ export const copyCourseModalInitialState = {
|
||||
id: '',
|
||||
title: '',
|
||||
isSaving: false,
|
||||
error: null,
|
||||
error: null
|
||||
};
|
||||
export const copyCourseModal = writable({ ...copyCourseModalInitialState });
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<script>
|
||||
import { SkeletonPlaceholder, SkeletonText } from 'carbon-components-svelte';
|
||||
import CardLoader from '$lib/components/Courses/components/Card/Loader.svelte';
|
||||
</script>
|
||||
|
||||
<section class="w-screen h-screen p-5">
|
||||
<!-- navbar -->
|
||||
<div class="flex items-center justify-between w-full rounded-md overflow-hidden">
|
||||
<SkeletonText style="width:80%; margin-right:10rem;border-radius:10px" />
|
||||
<div class="flex items-center justify-between w-[20%]">
|
||||
<SkeletonText style="width:2%; margin-right:1rem; border-radius:10px" />
|
||||
<SkeletonText style="width:2%; margin-right:1rem; border-radius:10px" />
|
||||
<SkeletonText style="width:2%; border-radius:10px" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- hero -->
|
||||
<div
|
||||
class="flex flex-row gap-5 items-start justify-center flex-wrap w-full my-8 rounded-md overflow-hidden"
|
||||
>
|
||||
<SkeletonPlaceholder style="width:100%; height:20rem" />
|
||||
</div>
|
||||
<!-- cards -->
|
||||
<div class="flex gap-5 items-center justify-center flex-wrap my-4 rounded-md overflow-hidden">
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
</div>
|
||||
</section>
|
||||
@@ -10,7 +10,7 @@
|
||||
import Phone from 'carbon-icons-svelte/lib/Phone.svelte';
|
||||
import Email from 'carbon-icons-svelte/lib/Email.svelte';
|
||||
import Rocket from 'carbon-icons-svelte/lib/Rocket.svelte';
|
||||
|
||||
import PageLoader from './PageLoader.svelte';
|
||||
import { orgLandingpageValidation } from '$lib/utils/functions/validator';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
@@ -27,8 +27,10 @@
|
||||
import { validateEmail } from '$lib/utils/functions/validateEmail';
|
||||
import TextArea from '$lib/components/Form/TextArea.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { landingPageSettings } from '$lib/components/Org/Settings/store';
|
||||
|
||||
export let orgSiteName = '';
|
||||
export let org = {};
|
||||
|
||||
let email: string | undefined;
|
||||
let isAdding = false;
|
||||
@@ -36,6 +38,7 @@
|
||||
let successContactSaved = false;
|
||||
let viewAll = false;
|
||||
let isContactSubmiting = false;
|
||||
let player;
|
||||
let contact = {
|
||||
name: '',
|
||||
email: '',
|
||||
@@ -43,36 +46,16 @@
|
||||
message: ''
|
||||
};
|
||||
let contactError = {};
|
||||
let video =
|
||||
'https://koxqonvbkeakwvmdegcf.supabase.co/storage/v1/object/public/avatars/course/About%20Best.mp4';
|
||||
|
||||
const supabase = getSupabase();
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
title: 'What sets your bootcamp apart from other online resources?',
|
||||
content:
|
||||
'Our bootcamp offers a structured and guided learning experience led by industry professionals who have a deep understanding of current web development trends and technologies. Unlike self-paced online tutorials, our program provides a hands-on, immersive environment with real-time feedback, personalized guidance, and the opportunity to work on practical projects that mirror real-world scenarios, preparing you for a successful career in web development.'
|
||||
},
|
||||
{
|
||||
title: 'Who is this bootcamp suitable for?',
|
||||
content:
|
||||
"Our web technologies bootcamp is suitable for individuals of all skill levels, from beginners with no prior coding experience to intermediate learners looking to enhance their web development capabilities. Whether you're a career changer, a recent graduate, or a professional aiming to upskill, our program is tailored to help you succeed."
|
||||
},
|
||||
{
|
||||
title: 'How is the bootcamp structured?',
|
||||
content:
|
||||
"Our web technologies bootcamp typically spans a [X]-week period and is divided into modules that cover different aspects of web development. Each module consists of lectures, hands-on coding exercises, projects, and collaborative activities. Our experienced instructors provide guidance and support, and you'll have access to a community of fellow learners to foster collaboration and knowledge sharing."
|
||||
}
|
||||
];
|
||||
|
||||
async function handleSubmit() {
|
||||
if (!email || !validateEmail(email)) return;
|
||||
isAdding = true;
|
||||
|
||||
const { error } = await supabase.from('organization_emaillist').insert({
|
||||
email,
|
||||
organization_id: $currentOrg.id
|
||||
organization_id: org.id
|
||||
});
|
||||
|
||||
if (error) {
|
||||
@@ -91,6 +74,7 @@
|
||||
isContactSubmiting = true;
|
||||
contactError = orgLandingpageValidation(contact);
|
||||
if (Object.keys(contactError).length) {
|
||||
isContactSubmiting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,11 +84,12 @@
|
||||
email: contact.email,
|
||||
phone: contact.phone,
|
||||
message: contact.message,
|
||||
organization_id: $currentOrg.id
|
||||
organization_id: org.id
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('Something went wrong', error, '\n\nContact', contact);
|
||||
isContactSubmiting = false;
|
||||
}
|
||||
|
||||
isContactSubmiting = false;
|
||||
@@ -116,10 +101,15 @@
|
||||
message: ''
|
||||
};
|
||||
}
|
||||
function isYouTubeLink(link: string) {
|
||||
const youtubeRegex =
|
||||
/^(https?:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
|
||||
|
||||
return youtubeRegex.test(link.trim());
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (!orgSiteName) return;
|
||||
|
||||
try {
|
||||
console.log('sitename', orgSiteName);
|
||||
$courseMetaDeta.isLoading = true;
|
||||
@@ -130,356 +120,442 @@
|
||||
console.log('error', error);
|
||||
}
|
||||
});
|
||||
function initPlyr(_player: any, _video: string | undefined) {
|
||||
if (!player) return;
|
||||
|
||||
// @ts-ignore
|
||||
const plyr = new Plyr('#player', { width: '400px', height: '300px', borderRadius: '10px' });
|
||||
// @ts-ignore
|
||||
window.player = plyr;
|
||||
}
|
||||
|
||||
// Use default data in store if user hasn't added their own content to landing page
|
||||
function setDefault(landingpage) {
|
||||
if (landingpage && Object.keys(landingpage).length) {
|
||||
$landingPageSettings = landingpage;
|
||||
}
|
||||
}
|
||||
|
||||
$: initPlyr(player, $landingPageSettings.header.video.link);
|
||||
$: setDefault(org.landingpage);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>
|
||||
{$currentOrg.name}'s Landing Page
|
||||
{!org.name ? '' : `${org.name}'s `}Landing Page
|
||||
</title>
|
||||
</svelte:head>
|
||||
|
||||
<main>
|
||||
<!-- Header Section -->
|
||||
<header id="header" class="banner w-full h-[80vh] mb-10 relative">
|
||||
<Navigation logo={$currentOrg.avatar_url} orgName={$currentOrg.name} disableSignup={true} />
|
||||
<div class="absolute h-[80vh] top-0 w-full opacity-80 z-10 bg-white" />
|
||||
{#if !org.landingpage}
|
||||
<PageLoader />
|
||||
{:else}
|
||||
<main>
|
||||
<!-- Header Section -->
|
||||
{#if $landingPageSettings.header.show}
|
||||
<header id="header" class="banner w-full h-[100vh] md:h-[90vh] mb-10 relative">
|
||||
<Navigation logo={org.avatar_url} orgName={org.name} disableSignup={true} />
|
||||
<div class="absolute h-[100vh] md:h-[90vh] top-0 w-full opacity-80 z-10 bg-white" />
|
||||
{#if $landingPageSettings.header.video.show}
|
||||
<div class="flex items-center justify-center md:h-full py-2">
|
||||
<div
|
||||
class="md:w-11/12 lg:w-5/6 w-full flex items-center justify-center md:justify-between flex-col-reverse md:flex-row z-20 relative"
|
||||
>
|
||||
<!-- Course Description -->
|
||||
<div class="md:w-2/5 w-11/12 py-10 flex flex-col items-center md:items-start mr-3">
|
||||
<p class=" text-primary-600 text-2xl font-semibold capitalize">
|
||||
{org.name}
|
||||
</p>
|
||||
<h1
|
||||
class="text-4xl md:text-5xl lg:text-6xl text-center md:text-start my-4 font-bold"
|
||||
>
|
||||
{$landingPageSettings.header.title} <br /><span class="text-primary-600"
|
||||
>{$landingPageSettings.header.titleHighlight}</span
|
||||
>
|
||||
</h1>
|
||||
<p class="text-md mb-3 md:mb-5 text-xl text-center md:text-start">
|
||||
{$landingPageSettings.header.subtitle}
|
||||
</p>
|
||||
|
||||
{#if video}
|
||||
<div class="flex items-center justify-center h-full">
|
||||
<div
|
||||
class="md:w-11/12 lg:w-5/6 w-full flex items-center justify-between flex-col-reverse md:flex-row z-20 relative"
|
||||
>
|
||||
<!-- Course Description -->
|
||||
<div class="md:w-2/5 w-11/12 py-10 flex flex-col items-start mr-3">
|
||||
<p class=" text-primary-600 text-2xl font-semibold">Coding Dojo</p>
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl my-4 font-bold">
|
||||
Web Developement Courses for <br /><span class="text-primary-600">Everyone</span>
|
||||
</h1>
|
||||
<p class="text-md mb-6 text-xl">
|
||||
Practical project-based courses that are easy to understand and straight to the point
|
||||
with NO FLUFF
|
||||
</p>
|
||||
|
||||
<PrimaryButton
|
||||
label="Start Learning Today"
|
||||
className="mt-5 px-10 w-fit"
|
||||
onClick={() => goto('#contact')}
|
||||
/>
|
||||
</div>
|
||||
<div class="w-4/6 md:w-1/2 md:max-w-[650px] flex">
|
||||
<video class="w-full rounded-xl" controls loop autoplay>
|
||||
<source src={video} type="video/mp4" />
|
||||
<!-- <source src="/path/to/video.webm" type="video/webm" /> -->
|
||||
<!-- Captions are optional -->
|
||||
<track kind="captions" />
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-full h-full flex items-center justify-center md:flex-row z-20 relative">
|
||||
<div class="max-w-[600px] mx-auto w-11/12 py-10 flex flex-col items-center">
|
||||
<p class=" text-primary-600 text-2xl font-semibold">Coding Dojo</p>
|
||||
<h1 class="text-4xl md:text-6xl text-center my-4 font-bold">
|
||||
Web Developement Courses for <br /><span class="text-primary-600">Everyone</span>
|
||||
</h1>
|
||||
<p class="text-md mb-6 text-center text-xl">
|
||||
Practical project-based courses that are easy to understand and straight to the point
|
||||
with NO FLUFF
|
||||
</p>
|
||||
|
||||
<PrimaryButton
|
||||
label="Start Learning Today"
|
||||
className="mt-5 px-10 w-fit"
|
||||
onClick={() => goto('#contact')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<!-- Our Story section -->
|
||||
<section id="aboutus" class="m-h-[400px] my-10 mx-auto max-w-6xl w-full">
|
||||
<div class="mx-4 flex items-center justify-between flex-col lg:flex-row">
|
||||
<div class="max-w-[600px] lg:w-2/5 mr-5 mb-5 lg:mb-0">
|
||||
<h2 class="text-6xl">Our Story</h2>
|
||||
<p class="mb-2">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Repudiandae, quaerat cum. Ullam
|
||||
similique quae dicta ipsum atque quam fugit iusto eligendi magni voluptatum aut,
|
||||
exercitationem deserunt vitae iste rem sunt! <br /> Lorem ipsum, dolor sit amet consectetur
|
||||
adipisicing elit. Maiores obcaecati veritatis tenetur in, nihil repellat quasi cumque sed molestias
|
||||
id reiciendis harum doloremque minus fugit quia cum dolores quas pariatur.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="image">
|
||||
<img
|
||||
src="images/org-landingpage-our-story.jpeg"
|
||||
alt="Our Story"
|
||||
class=" rounded-2xl w-[600px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Courses Section -->
|
||||
<section id="courses" transition:fade class="my-10 mx-auto max-w-6xl w-full">
|
||||
<div class="w-full">
|
||||
<div class="max-w-[500px] mx-auto w-11/12 py-10">
|
||||
<h1 class="text-5xl text-center my-4 font-bold">
|
||||
Explore our <span class="text-primary-600">Courses</span>
|
||||
</h1>
|
||||
<p class="text-md text-center">
|
||||
Find courses you will love from best teachers all over the world🌎.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-5 items-center justify-center flex-wrap my-4 mx-2">
|
||||
{#if $courseMetaDeta.isLoading}
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
{:else}
|
||||
{#each $courses.slice(0, viewAll ? $courses.length : 3) as courseData}
|
||||
<Card
|
||||
id={courseData.id}
|
||||
slug={courseData.slug}
|
||||
bannerImage={courseData.banner_image}
|
||||
title={courseData.title}
|
||||
description={courseData.description}
|
||||
role_id={courseData.role_id}
|
||||
isPublished={courseData.is_published}
|
||||
cost={courseData.cost}
|
||||
currency={courseData.currency}
|
||||
totalLessons={get(courseData, 'lessons[0].count', 0)}
|
||||
isOnLandingPage={true}
|
||||
/>
|
||||
{:else}
|
||||
<Box>
|
||||
<CoursesEmptyIcon />
|
||||
<h3 class="dark:text-white text-2xl my-5">No Course Published</h3>
|
||||
<p class="dark:text-white w-1/3 text-center">
|
||||
We've got great courses coming your way, stay tuned!!!
|
||||
</p>
|
||||
</Box>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if $courses.length > 3}
|
||||
<div class="w-full flex justify-center">
|
||||
<PrimaryButton
|
||||
variant={VARIANTS.OUTLINED}
|
||||
onClick={() => (viewAll = !viewAll)}
|
||||
label={viewAll ? 'View Less' : 'View All'}
|
||||
className="px-10 py-5 w-fit"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<!-- FAQ Section -->
|
||||
<section id="faq" transition:fade class="my-10 mx-auto max-w-[700px] w-full">
|
||||
<div class="py-10">
|
||||
<h1 class="text-5xl text-center my-4 font-bold">Frequently Asked Questions.</h1>
|
||||
</div>
|
||||
<div class="mx-2">
|
||||
<Accordion size="xl">
|
||||
{#each faqs as faq}
|
||||
<AccordionItem title={faq.title} class="text-3xl">
|
||||
<p class="text-lg">
|
||||
{faq.content}
|
||||
</p>
|
||||
</AccordionItem>
|
||||
{/each}
|
||||
</Accordion>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contact Section-->
|
||||
<section id="contact" transition:fade class="my-10 w-full bg-primary-50">
|
||||
<div class="mx-auto max-w-6xl w-full">
|
||||
<div class="max-w-[500px] mx-auto w-11/12 py-10">
|
||||
<h1 class="text-5xl text-center my-4 font-bold">
|
||||
Have you got any <span class="text-primary-600">Question?</span>
|
||||
</h1>
|
||||
<p class="text-md text-center">Reach out to us with any question you might have.</p>
|
||||
</div>
|
||||
<Grid class="max-w-[700px] pb-10">
|
||||
<!-- Contact Details -->
|
||||
<Row>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<LocationFilled size={32} />
|
||||
<p class="text-xs md:text-sm mt-3 max-w-[200px]">
|
||||
Ashwoodfield House Farm, Kidderminster Rd, Stourbridge, Kingswinford DY6 0AA
|
||||
</p>
|
||||
</Column>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<Phone size={32} />
|
||||
<p class="text-xs md:text-sm mt-3">+4407339904995</p>
|
||||
</Column>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<Email size={32} />
|
||||
<p class="text-xs md:text-sm mt-3">[email protected]</p>
|
||||
</Column>
|
||||
</Row>
|
||||
|
||||
<!-- Contact Form -->
|
||||
<div class="mt-8 bg-white p-7 rounded-lg">
|
||||
{#if successContactSaved}
|
||||
<div class="w-full flex items-center justify-center">
|
||||
Thank you for dropping a message, we will get back to you shortly
|
||||
</div>
|
||||
{:else}
|
||||
<form on:submit|preventDefault={handleContactSubmit}>
|
||||
<div class="w-full flex justify-between flex-col md:flex-row">
|
||||
<div class="w-full md:w-2/4 mr-5">
|
||||
<TextField
|
||||
label="Your Name"
|
||||
bind:value={contact.name}
|
||||
errorMessage={contactError.name}
|
||||
className="mb-5"
|
||||
labelClassName="font-bold"
|
||||
placeholder="Elon Musk"
|
||||
/>
|
||||
<TextField
|
||||
label="Your Email"
|
||||
bind:value={contact.email}
|
||||
errorMessage={contactError.email}
|
||||
className="text-xs font-normal mb-5"
|
||||
placeholder="[email protected]"
|
||||
/>
|
||||
<TextField
|
||||
label="Your Phone"
|
||||
bind:value={contact.phone}
|
||||
errorMessage={contactError.phone}
|
||||
className="text-xs font-normal mb-5"
|
||||
placeholder="+1194802480"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full md:w-2/4">
|
||||
<TextArea
|
||||
label="Your Message"
|
||||
bind:value={contact.message}
|
||||
errorMessage={contactError.message}
|
||||
rows="9"
|
||||
maxRows={15}
|
||||
placeholder="Your message here"
|
||||
/>
|
||||
</div>
|
||||
<PrimaryButton
|
||||
label={$landingPageSettings.header.action.label}
|
||||
className="mt-2 md:mt-5 px-10 w-fit"
|
||||
onClick={() => {
|
||||
$landingPageSettings.header.action.redirect &&
|
||||
goto($landingPageSettings.header.action.link);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="w-5/6 md:w-1/2 md:max-w-[650px] flex">
|
||||
{#if isYouTubeLink($landingPageSettings.header.video.link)}
|
||||
<div bind:this={player} id="player" style="width:100%; border-radius:12px">
|
||||
<iframe
|
||||
title="Header video"
|
||||
src={$landingPageSettings.header.video.link}
|
||||
allowfullscreen
|
||||
allowtransparency
|
||||
allow="autoplay"
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<video class="w-full rounded-xl" controls loop autoplay>
|
||||
<source src={$landingPageSettings.header.video.link} type="video/mp4" />
|
||||
<!-- <source src="/path/to/video.webm" type="video/webm" /> -->
|
||||
<!-- Captions are optional -->
|
||||
<track kind="captions" />
|
||||
</video>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-full h-full flex items-center justify-center md:flex-row z-20 relative">
|
||||
<div class="max-w-[600px] mx-auto w-11/12 py-10 flex flex-col items-center">
|
||||
<p class=" text-primary-600 text-2xl font-semibold capitalize">{org.name}</p>
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl text-center my-4 font-bold">
|
||||
{$landingPageSettings.header.title} <br /><span class="text-primary-600"
|
||||
>{$landingPageSettings.header.titleHighlight}</span
|
||||
>
|
||||
</h1>
|
||||
<p class="text-md mb-6 text-center text-xl">
|
||||
{$landingPageSettings.header.subtitle}
|
||||
</p>
|
||||
|
||||
<PrimaryButton
|
||||
className="w-full mx-auto mt-5 md:mt-0"
|
||||
type="submit"
|
||||
isLoading={isContactSubmiting}
|
||||
>
|
||||
<span class="mr-2 text-md">Submit</span>
|
||||
<Rocket size={24} />
|
||||
</PrimaryButton>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</Grid>
|
||||
</div>
|
||||
</section>
|
||||
label={$landingPageSettings.header.action.label}
|
||||
className="mt-5 px-10 w-fit"
|
||||
onClick={() => {
|
||||
$landingPageSettings.header.action.redirect &&
|
||||
goto($landingPageSettings.header.action.link);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
<!-- Waitlist Section -->
|
||||
<section id="waitlist" transition:fade class="my-10 mx-auto max-w-6xl w-[95%]">
|
||||
<div
|
||||
class="bg-primary-700 rounded-lg flex flex-col lg:flex-row lg:items-center px-4 md:px-10 py-14"
|
||||
>
|
||||
<div class="w-full md:w-[65%] md:mr-4">
|
||||
<h1 class="text-4xl font-bold mb-5 mt-0 text-white">Join our mailing list</h1>
|
||||
<p class="text-lg text-white">
|
||||
We are constantly releasing new courses and sharing them with our email list. Subscribe to
|
||||
get notified once we release a new course
|
||||
</p>
|
||||
</div>
|
||||
<form on:submit|preventDefault={handleSubmit} class="my-4 w-full md:w-fit">
|
||||
<div class="flex items-center flex-col sm:flex-row">
|
||||
{#if success}
|
||||
<p class="text-white">You have been added successfully. Thanks for subscribing.</p>
|
||||
{:else}
|
||||
<TextField
|
||||
bind:value={email}
|
||||
type="email"
|
||||
placeholder="Enter your email.."
|
||||
className="sm:mr-3 my-0 w-full md:w-fit"
|
||||
isRequired={true}
|
||||
isDisabled={isAdding}
|
||||
inputClassName="py-2"
|
||||
<!-- Our Story section -->
|
||||
{#if $landingPageSettings.aboutUs.show}
|
||||
<section id="aboutus" class="m-h-[400px] my-10 mx-auto max-w-6xl w-full">
|
||||
<div class="mx-4 flex items-center justify-evenly flex-col lg:flex-row">
|
||||
<div class="max-w-[600px] lg:w-2/5 mr-5 mb-5 lg:mb-0">
|
||||
<h2 class="text-4xl md:text-5xl lg:text-6xl">{$landingPageSettings.aboutUs.title}</h2>
|
||||
<p class="mb-2">
|
||||
{$landingPageSettings.aboutUs.content}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="image">
|
||||
<img
|
||||
src={$landingPageSettings.aboutUs.imageUrl}
|
||||
alt="Our Story"
|
||||
class=" rounded-2xl max-h-[450px]"
|
||||
/>
|
||||
<PrimaryButton
|
||||
className="my-1 w-full mt-2"
|
||||
variant={VARIANTS.CONTAINED_LIGHT}
|
||||
type="submit"
|
||||
isLoading={isAdding}>Subscribe</PrimaryButton
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<!-- Courses Section -->
|
||||
{#if $landingPageSettings.courses.show}
|
||||
<section id="courses" transition:fade class="my-10 mx-auto max-w-6xl w-full">
|
||||
<div class="w-full">
|
||||
<div class="max-w-[500px] mx-auto w-11/12 py-10">
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl text-center my-4 font-bold">
|
||||
{$landingPageSettings.courses.title}
|
||||
<span class="text-primary-600">{$landingPageSettings.courses.titleHighlight}</span>
|
||||
</h1>
|
||||
<p class="text-md text-center">
|
||||
{$landingPageSettings.courses.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cards-container my-4 mx-2">
|
||||
{#if $courseMetaDeta.isLoading}
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
<CardLoader />
|
||||
{:else}
|
||||
{#each $courses.slice(0, viewAll ? $courses.length : 3) as courseData}
|
||||
<Card
|
||||
id={courseData.id}
|
||||
slug={courseData.slug}
|
||||
bannerImage={courseData.banner_image}
|
||||
title={courseData.title}
|
||||
description={courseData.description}
|
||||
role_id={courseData.role_id}
|
||||
isPublished={courseData.is_published}
|
||||
cost={courseData.cost}
|
||||
currency={courseData.currency}
|
||||
totalLessons={get(courseData, 'lessons[0].count', 0)}
|
||||
isOnLandingPage={true}
|
||||
/>
|
||||
{:else}
|
||||
<Box>
|
||||
<CoursesEmptyIcon />
|
||||
<h3 class="dark:text-white text-2xl my-5">No Course Published</h3>
|
||||
<p class="dark:text-white w-1/3 text-center">
|
||||
We've got great courses coming your way, stay tuned!!!
|
||||
</p>
|
||||
</Box>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer Section -->
|
||||
<footer
|
||||
id="footer"
|
||||
class="flex justify-center flex-col mt-10 w-full px-5 py-10 md:py-3 border-b-0 border-r-0 border-t border-l-0 border-gray-300"
|
||||
>
|
||||
<ul class="flex w-11/12 items-center flex-col sm:flex-row">
|
||||
<div class="logo">
|
||||
<a
|
||||
href="/"
|
||||
title={`Go to ${$currentOrg.name} Home`}
|
||||
id="logo"
|
||||
data-hveid="8"
|
||||
class="flex items-center"
|
||||
{#if $courses.length > 3}
|
||||
<div class="w-full flex justify-center">
|
||||
<PrimaryButton
|
||||
variant={VARIANTS.OUTLINED}
|
||||
onClick={() => (viewAll = !viewAll)}
|
||||
label={viewAll ? 'View Less' : 'View All'}
|
||||
className="px-10 py-5 w-fit"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<!-- FAQ Section -->
|
||||
{#if $landingPageSettings.faq.show}
|
||||
<section id="faq" transition:fade class="my-10 mx-auto max-w-[700px] w-full">
|
||||
<div class="py-10">
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl text-center my-4 font-bold">
|
||||
{$landingPageSettings.faq.title}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="mx-2">
|
||||
<Accordion size="xl">
|
||||
{#each $landingPageSettings.faq.questions as faq}
|
||||
<AccordionItem title={faq.title} class="text-3xl">
|
||||
<p class="text-lg">
|
||||
{faq.content}
|
||||
</p>
|
||||
</AccordionItem>
|
||||
{/each}
|
||||
</Accordion>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<!-- Contact Section-->
|
||||
{#if $landingPageSettings.contact.show}
|
||||
<section id="contact" transition:fade class="my-10 w-full bg-primary-50">
|
||||
<div class="mx-auto max-w-6xl w-full">
|
||||
<div class="max-w-[500px] mx-auto w-11/12 py-10">
|
||||
<h1 class="text-4xl md:text-5xl lg:text-6xl text-center my-4 font-bold">
|
||||
{$landingPageSettings.contact.title}
|
||||
<span class="text-primary-600">{$landingPageSettings.contact.titleHighlight}</span>
|
||||
</h1>
|
||||
<p class="text-md text-center">{$landingPageSettings.contact.subtitle}</p>
|
||||
</div>
|
||||
<Grid class="max-w-[700px] pb-10">
|
||||
<!-- Contact Details -->
|
||||
<Row>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<LocationFilled size={32} />
|
||||
<p class="text-xs md:text-sm mt-3 max-w-[200px]">
|
||||
{$landingPageSettings.contact.address}
|
||||
</p>
|
||||
</Column>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<Phone size={32} />
|
||||
<p class="text-xs md:text-sm mt-3">{$landingPageSettings.contact.phone}</p>
|
||||
</Column>
|
||||
<Column
|
||||
class="flex items-center flex-col justify-center break-all text-center cursor-pointer hover:shadow-xl rounded-lg transition-all duration-500 py-2 mx-2"
|
||||
>
|
||||
<Email size={32} />
|
||||
<p class="text-xs md:text-sm mt-3">{$landingPageSettings.contact.email}</p>
|
||||
</Column>
|
||||
</Row>
|
||||
|
||||
<!-- Contact Form -->
|
||||
<div class="mt-8 bg-white p-7 rounded-lg">
|
||||
{#if successContactSaved}
|
||||
<div class="w-full flex items-center justify-center">
|
||||
Thank you for dropping a message, we will get back to you shortly
|
||||
</div>
|
||||
{:else}
|
||||
<form on:submit|preventDefault={handleContactSubmit}>
|
||||
<div class="w-full flex justify-between flex-col md:flex-row">
|
||||
<div class="w-full md:w-2/4 mr-5">
|
||||
<TextField
|
||||
label="Your Name"
|
||||
bind:value={contact.name}
|
||||
errorMessage={contactError.name}
|
||||
className="mb-5"
|
||||
labelClassName="font-bold"
|
||||
placeholder="Elon Musk"
|
||||
/>
|
||||
<TextField
|
||||
label="Your Email"
|
||||
bind:value={contact.email}
|
||||
errorMessage={contactError.email}
|
||||
className="text-xs font-normal mb-5"
|
||||
placeholder="[email protected]"
|
||||
/>
|
||||
<TextField
|
||||
label="Your Phone"
|
||||
bind:value={contact.phone}
|
||||
errorMessage={contactError.phone}
|
||||
className="text-xs font-normal mb-5"
|
||||
placeholder="+1194802480"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full md:w-2/4">
|
||||
<TextArea
|
||||
label="Your Message"
|
||||
bind:value={contact.message}
|
||||
errorMessage={contactError.message}
|
||||
rows="9"
|
||||
maxRows={15}
|
||||
placeholder="Your message here"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PrimaryButton
|
||||
className="w-full mx-auto mt-5 md:mt-0"
|
||||
type="submit"
|
||||
isLoading={isContactSubmiting}
|
||||
>
|
||||
<span class="mr-2 text-md">Submit</span>
|
||||
<Rocket size={24} />
|
||||
</PrimaryButton>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</Grid>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<!-- Waitlist Section -->
|
||||
{#if $landingPageSettings.mailinglist.show}
|
||||
<section id="waitlist" transition:fade class="my-10 mx-auto max-w-6xl w-[95%]">
|
||||
<div
|
||||
class="bg-primary-700 rounded-lg flex flex-col lg:flex-row lg:items-center px-4 md:px-10 py-14"
|
||||
>
|
||||
<img
|
||||
src={$currentOrg.avatar_url || '/logo-192.png'}
|
||||
alt={`${$currentOrg.name} logo`}
|
||||
class="rounded h-10 w-10 inline-block mx-auto"
|
||||
data-atf="1"
|
||||
/>
|
||||
<h3 class="text-black ml-3 text-xl">{$currentOrg.name}</h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="w-full md:w-[65%] md:mr-4">
|
||||
<h1 class="text-4xl font-bold mb-5 mt-0 text-white">
|
||||
{$landingPageSettings.mailinglist.title}
|
||||
</h1>
|
||||
<p class="text-lg text-white">
|
||||
{$landingPageSettings.mailinglist.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
<form on:submit|preventDefault={handleSubmit} class="my-4 w-full md:w-fit">
|
||||
<div class="flex items-center flex-col sm:flex-row">
|
||||
{#if success}
|
||||
<p class="text-white">You have been added successfully. Thanks for subscribing.</p>
|
||||
{:else}
|
||||
<TextField
|
||||
bind:value={email}
|
||||
type="email"
|
||||
placeholder="Enter your email.."
|
||||
className="sm:mr-3 my-0 w-full md:w-fit"
|
||||
isRequired={true}
|
||||
isDisabled={isAdding}
|
||||
inputClassName="py-2"
|
||||
/>
|
||||
<PrimaryButton
|
||||
className="my-1 w-full mt-2"
|
||||
variant={VARIANTS.CONTAINED_LIGHT}
|
||||
type="submit"
|
||||
isLoading={isAdding}>{$landingPageSettings.mailinglist.buttonLabel}</PrimaryButton
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<span class="flex-grow" />
|
||||
<!-- Footer Section -->
|
||||
|
||||
<div class="flex mt-5 sm:mt-0">
|
||||
<li class="mx-2">
|
||||
<a href="facebook.com" target="_blank" title="Facebook" id="logo-fb" data-hveid="8">
|
||||
<LogoFacebook size={24} />
|
||||
</a>
|
||||
</li>
|
||||
<li class="mx-2">
|
||||
<a href="twitter.com" target="_blank" title="Twitter" id="logo-tw" data-hveid="8">
|
||||
<LogoTwitter size={24} />
|
||||
</a>
|
||||
</li>
|
||||
<li class="mx-2">
|
||||
<a href="linkedin.com" target="_blank" title="Linkedin" id="logo-ln" data-hveid="8">
|
||||
<LogoLinkedin size={24} />
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<p class="text-center mt-5">
|
||||
Powered by
|
||||
<a class="text-primary-600 underline" href="https://classroomio.com" target="_blank"
|
||||
>ClassroomIO</a
|
||||
{#if $landingPageSettings.footer.show}
|
||||
<footer
|
||||
id="footer"
|
||||
class="flex justify-center flex-col mt-10 w-full px-5 py-10 md:py-3 border-b-0 border-r-0 border-t border-l-0 border-gray-300"
|
||||
>
|
||||
</p>
|
||||
</footer>
|
||||
</main>
|
||||
<ul class="flex w-11/12 items-center flex-col sm:flex-row">
|
||||
<div class="logo">
|
||||
<a
|
||||
href="/"
|
||||
title={`Go to ${org.name} Home`}
|
||||
id="logo"
|
||||
data-hveid="8"
|
||||
class="flex items-center"
|
||||
>
|
||||
<img
|
||||
src={org.avatar_url || '/logo-192.png'}
|
||||
alt={`${org.name} logo`}
|
||||
class="rounded h-10 w-10 inline-block mx-auto"
|
||||
data-atf="1"
|
||||
/>
|
||||
<h3 class="text-black ml-3 text-xl">{org.name}</h3>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<span class="flex-grow" />
|
||||
|
||||
<div class="flex mt-5 sm:mt-0">
|
||||
{#if $landingPageSettings.footer.facebook}
|
||||
<li class="mx-2">
|
||||
<a
|
||||
href={$landingPageSettings.footer.facebook}
|
||||
target="_blank"
|
||||
title="Facebook"
|
||||
id="logo-fb"
|
||||
data-hveid="8"
|
||||
>
|
||||
<LogoFacebook size={24} />
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
{#if $landingPageSettings.footer.twitter}
|
||||
<li class="mx-2">
|
||||
<a
|
||||
href={$landingPageSettings.footer.twitter}
|
||||
target="_blank"
|
||||
title="Twitter"
|
||||
id="logo-tw"
|
||||
data-hveid="8"
|
||||
>
|
||||
<LogoTwitter size={24} />
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
{#if $landingPageSettings.footer.linkedin}
|
||||
<li class="mx-2">
|
||||
<a
|
||||
href={$landingPageSettings.footer.linkedin}
|
||||
target="_blank"
|
||||
title="Linkedin"
|
||||
id="logo-ln"
|
||||
data-hveid="8"
|
||||
>
|
||||
<LogoLinkedin size={24} />
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
</div>
|
||||
</ul>
|
||||
<p class="text-center mt-5">
|
||||
Powered by
|
||||
<a class="text-primary-600 underline" href="https://classroomio.com" target="_blank"
|
||||
>ClassroomIO</a
|
||||
>
|
||||
</p>
|
||||
</footer>
|
||||
{/if}
|
||||
</main>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.banner {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import { FileUploader } from 'carbon-components-svelte';
|
||||
import { landingPageSettings } from './store';
|
||||
import type { OrgLandingPageJson } from './store';
|
||||
|
||||
let files: File[] = [];
|
||||
let imageBuffer: File;
|
||||
@@ -88,9 +89,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
const checkPrefix = (inputValue: string) => {
|
||||
if (!inputValue) return;
|
||||
|
||||
if (inputValue.trim() !== '') {
|
||||
if (!inputValue.startsWith('https://')) {
|
||||
inputValue = 'https://' + inputValue;
|
||||
}
|
||||
}
|
||||
return inputValue;
|
||||
};
|
||||
async function handleSave() {
|
||||
isSaving = true;
|
||||
|
||||
$landingPageSettings.footer.twitter = checkPrefix($landingPageSettings.footer.twitter);
|
||||
$landingPageSettings.footer.linkedin = checkPrefix($landingPageSettings.footer.linkedin);
|
||||
$landingPageSettings.footer.facebook = checkPrefix($landingPageSettings.footer.facebook);
|
||||
console.log($landingPageSettings.footer.twitter);
|
||||
const { data, error } = await supabase
|
||||
.from('organization')
|
||||
.update({ landingpage: $landingPageSettings })
|
||||
@@ -112,13 +126,13 @@
|
||||
isSaving = false;
|
||||
}
|
||||
|
||||
function setDefault(landingpage) {
|
||||
function setDefault(landingpage: OrgLandingPageJson) {
|
||||
if (landingpage && Object.keys(landingpage).length) {
|
||||
$landingPageSettings = landingpage;
|
||||
}
|
||||
}
|
||||
|
||||
$: setDefault($currentOrg.landingpage);
|
||||
$: setDefault($currentOrg?.landingpage);
|
||||
</script>
|
||||
|
||||
<Grid class="border-c rounded border-gray-200 w-full mt-5 relative">
|
||||
@@ -166,8 +180,8 @@
|
||||
bind:value={$landingPageSettings.header.action.link}
|
||||
/>
|
||||
<Toggle bind:toggled={$landingPageSettings.header.action.redirect} size="sm">
|
||||
<span slot="labelA" style="color: red">No redirect</span>
|
||||
<span slot="labelB" style="color: green">Redirect</span>
|
||||
<span slot="labelA" style="color: gray">No redirect</span>
|
||||
<span slot="labelB" style="color: gray">Redirect</span>
|
||||
</Toggle>
|
||||
</div>
|
||||
<SectionTitle>Video</SectionTitle>
|
||||
@@ -178,8 +192,8 @@
|
||||
bind:value={$landingPageSettings.header.video.link}
|
||||
/>
|
||||
<Toggle bind:toggled={$landingPageSettings.header.video.show} size="sm">
|
||||
<span slot="labelA" style="color: red">Hide Video</span>
|
||||
<span slot="labelB" style="color: green">Show Video</span>
|
||||
<span slot="labelA" style="color: gray">Hide Video</span>
|
||||
<span slot="labelB" style="color: gray">Show Video</span>
|
||||
</Toggle>
|
||||
</div>
|
||||
</Column>
|
||||
@@ -408,13 +422,18 @@
|
||||
bind:value={$landingPageSettings.footer.facebook}
|
||||
className="mb-5"
|
||||
/>
|
||||
<TextField
|
||||
<!-- <TextField
|
||||
label="Instagram"
|
||||
placeholder="Write your Instagram link here"
|
||||
className="mb-5"
|
||||
bind:value={$landingPageSettings.footer.instagram}
|
||||
/> -->
|
||||
<TextField
|
||||
label="Twitter"
|
||||
placeholder="Write your Twitter link here"
|
||||
className="mb-5"
|
||||
bind:value={$landingPageSettings.footer.twitter}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="Linkedin"
|
||||
placeholder="Write your Linkedin link here"
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface OrgLandingPageJson {
|
||||
footer: {
|
||||
facebook: string;
|
||||
instagram: string;
|
||||
twitter: string;
|
||||
linkedin: string;
|
||||
show: boolean;
|
||||
};
|
||||
@@ -72,8 +73,8 @@ export let landingPageSettings: Writable<OrgLandingPageJson> = writable({
|
||||
redirect: false
|
||||
},
|
||||
video: {
|
||||
show: false,
|
||||
link: 'https://youtube.com/sosf24lsfgs'
|
||||
show: true,
|
||||
link: 'https://www.youtube.com/watch?v=bbVZo4Yw7pI'
|
||||
},
|
||||
show: false
|
||||
},
|
||||
@@ -82,7 +83,7 @@ export let landingPageSettings: Writable<OrgLandingPageJson> = writable({
|
||||
content:
|
||||
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Repudiandae, quaerat cum. Ullam similique quae dicta ipsum atque quam fugit iusto eligendi magni voluptatum aut, exercitationem deserunt vitae iste rem sunt!\nLorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores obcaecati veritatis tenetur in, nihil repellat quasi cumque sed molestias id reiciendis harum doloremque minus fugit quia cum dolores quas pariatur.',
|
||||
imageUrl: '',
|
||||
show: true
|
||||
show: false
|
||||
},
|
||||
courses: {
|
||||
title: 'Explore our',
|
||||
@@ -133,6 +134,7 @@ export let landingPageSettings: Writable<OrgLandingPageJson> = writable({
|
||||
footer: {
|
||||
facebook: '#',
|
||||
instagram: '#',
|
||||
twitter: '#',
|
||||
linkedin: '#',
|
||||
show: true
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ export const PUBLIC_ROUTES = [
|
||||
ROUTE.FORGOT,
|
||||
ROUTE.RESET,
|
||||
`^${ROUTE.PAGES}/.*`,
|
||||
`^${ROUTE.COURSE}/.*`
|
||||
`^${ROUTE.COURSE}/.*`,
|
||||
'/404'
|
||||
];
|
||||
|
||||
export const ROUTES_TO_HIDE_NAV = [
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export function setTheme(theme: string) {
|
||||
// In case the default theme is added but another theme exists
|
||||
if (!theme && document.body.className.includes('theme-')) {
|
||||
const regex = /theme-[\w]+/gi;
|
||||
document.body.className = document.body.className.replace(regex, theme);
|
||||
return;
|
||||
}
|
||||
|
||||
// In case theme already exists in dom, don't add
|
||||
if (document.body.className.includes(theme)) return;
|
||||
|
||||
document.body.className = document.body.className.concat(' ', theme);
|
||||
}
|
||||
@@ -147,16 +147,6 @@ export async function getCourseBySiteName(siteName) {
|
||||
if (error) {
|
||||
return [];
|
||||
}
|
||||
const org = get(data, '[0].group.organization', {
|
||||
id: '',
|
||||
name: 'ClassroomIO',
|
||||
shortName: '',
|
||||
siteName: '',
|
||||
avatar_url: '/logo-192.png',
|
||||
landingpage: {},
|
||||
theme: ''
|
||||
});
|
||||
currentOrg.set(org);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ export const load = async ({ url, cookies }) => {
|
||||
org: {}
|
||||
};
|
||||
|
||||
const debugOrgLandingPage = cookies.get('debugOrgLandingPage');
|
||||
const _orgSiteName = cookies.get('_orgSiteName');
|
||||
const debugPlay = cookies.get('debugPlay');
|
||||
const debugMode = debugOrgLandingPage === 'true';
|
||||
console.log('debugOrgLandingPage', debugOrgLandingPage);
|
||||
const debugMode = _orgSiteName !== 'false';
|
||||
console.log('_orgSiteName', _orgSiteName);
|
||||
|
||||
const matches = url.host.match(/([a-z 0-9 \-]+).*classroomio[.]com/);
|
||||
const subdomain = matches?.[1] ?? '';
|
||||
@@ -32,8 +32,7 @@ export const load = async ({ url, cookies }) => {
|
||||
const answer = Array.isArray(matches) ? !!subdomain && subdomain !== 'www' : false;
|
||||
|
||||
response.isOrgSite = debugMode || answer;
|
||||
response.orgSiteName = debugMode ? 'codingdojo' : subdomain;
|
||||
|
||||
response.orgSiteName = debugMode ? _orgSiteName : subdomain;
|
||||
response.org = await getCurrentOrg(response.orgSiteName, true);
|
||||
} else if (subdomain === 'play' || debugPlay === 'true') {
|
||||
response.skipAuth = true;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
import { toggleBodyByTheme } from '$lib/utils/functions/app';
|
||||
import { appStore } from '$lib/utils/store/app';
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { setTheme } from '$lib/utils/functions/theme';
|
||||
|
||||
import '../app.postcss';
|
||||
|
||||
@@ -47,10 +48,6 @@
|
||||
setTimeout(() => set(currentPreloading), 250);
|
||||
});
|
||||
|
||||
function setTheme(theme) {
|
||||
document.body.className = document.body.className.concat(' ', theme);
|
||||
}
|
||||
|
||||
function setupSentry() {
|
||||
if (!dev) {
|
||||
Sentry.init({
|
||||
@@ -243,11 +240,15 @@
|
||||
|
||||
if (data.isOrgSite) {
|
||||
console.log('data', data);
|
||||
$appStore.orgSiteName = data.orgSiteName;
|
||||
$appStore.isOrgSite = data.isOrgSite;
|
||||
if (!data.org) {
|
||||
goto('/404');
|
||||
} else {
|
||||
$appStore.orgSiteName = data.orgSiteName;
|
||||
$appStore.isOrgSite = data.isOrgSite;
|
||||
|
||||
currentOrg.set(data.org);
|
||||
setTheme(data.org.theme);
|
||||
currentOrg.set(data.org);
|
||||
setTheme(data.org.theme);
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
@@ -273,7 +274,7 @@
|
||||
{#if data.skipAuth}
|
||||
<PlayQuiz />
|
||||
{:else if data.isOrgSite && !path}
|
||||
<OrgLandingPage orgSiteName={data.orgSiteName} />
|
||||
<OrgLandingPage orgSiteName={data.orgSiteName} org={data.org} />
|
||||
{:else}
|
||||
<main class="dark:bg-gray-800">
|
||||
{#if $navigating && $delayedPreloading}
|
||||
@@ -390,4 +391,14 @@
|
||||
linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.5)) !important;
|
||||
background-size: 50px auto, auto !important;
|
||||
}
|
||||
|
||||
:global(.cards-container) {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
column-gap: 12px;
|
||||
row-gap: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user