Files
classroomio/apps/dashboard/src/lib/components/Org/Settings/LandingpageSettings.svelte
T
Rotimi Best 41e29014ef feat: 🚀 😃 convert repo into a monorepo 🚀 😃 (#51)
* Merge main into turbo-monrepo

* feat: rename apps

* feat: remove supbase videos and serve all from project

* feat: move supabase to root

* feat: update README

* docs: update link
2023-11-25 21:56:02 +00:00

504 lines
16 KiB
Svelte

<script lang="ts">
import { Grid, Row, Column, RadioButtonGroup, RadioButton } from 'carbon-components-svelte';
import TrashCan from 'carbon-icons-svelte/lib/TrashCan.svelte';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import Save from 'carbon-icons-svelte/lib/Save.svelte';
import IconButton from '$lib/components/IconButton/index.svelte';
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import SectionTitle from '../SectionTitle.svelte';
import { Toggle } from 'carbon-components-svelte';
import TextField from '$lib/components/Form/TextField.svelte';
import TextArea from '$lib/components/Form/TextArea.svelte';
import { currentOrg } from '$lib/utils/store/org';
import { getSupabase } from '$lib/utils/functions/supabase';
import { snackbar } from '$lib/components/Snackbar/store';
import { landingPageSettings } from './store';
import type { OrgLandingPageJson } from './store';
import UploadWidget from '$lib/components/UploadWidget/index.svelte';
import { handleOpenWidget } from '$lib/components/CourseLandingPage/store';
let isSaving = false;
let creatingNewQuestion = false;
let widgetKey = '';
const banner = [
{ value: 'video', label: 'Video' },
{ value: 'image', label: 'Image' }
];
const supabase = getSupabase();
let newQuestion = {
title: '',
content: ''
};
function widgetControl(key: string) {
widgetKey = key;
$handleOpenWidget.open = true;
}
function createNewFaq() {
newQuestion = {
title: '',
content: ''
};
creatingNewQuestion = true;
}
function saveNewFAQ() {
if (newQuestion.title !== '' && newQuestion.content !== '') {
$landingPageSettings.faq.questions = [
...$landingPageSettings.faq.questions,
{
id: new Date().getTime(),
title: newQuestion.title,
content: newQuestion.content
}
];
creatingNewQuestion = false;
}
}
function cancelNewFAQ() {
creatingNewQuestion = false;
}
function deleteFaq(id: number) {
let faqs = $landingPageSettings.faq.questions;
const filteredFaq = faqs.filter((faq) => faq.id !== id);
$landingPageSettings.faq.questions = filteredFaq;
}
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) || '';
const { error } = await supabase
.from('organization')
.update({ landingpage: $landingPageSettings })
.match({ id: $currentOrg.id });
if (error) {
const message = error?.message || 'Please try again';
snackbar.error(`Update failed: ${message}`);
} else {
$currentOrg.landingpage = $landingPageSettings;
snackbar.success();
}
isSaving = false;
}
function setDefault(landingpage: OrgLandingPageJson) {
if (landingpage && Object.keys(landingpage).length) {
// Added new key, support backward compatibility
if (!landingpage?.header?.banner) {
landingpage.header.banner = $landingPageSettings.header.banner;
}
$landingPageSettings = {
...landingpage
};
}
}
$: setDefault($currentOrg?.landingpage as OrgLandingPageJson);
</script>
<Grid class="border-c rounded border-gray-200 w-full mt-5 relative">
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}>
<SectionTitle>Landing Page</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.header.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8} class="mt-4 lg:mt-0">
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.header.title}
className="w-full mb-5"
/>
<TextField
label="Title-Highlight"
placeholder="Write your titlehighlight here"
className="w-full mb-5"
bind:value={$landingPageSettings.header.titleHighlight}
/>
<TextArea
label="Subtitle"
labelClassName="font-light"
placeholder="Write your subtitle here"
className="w-full mb-5"
bind:value={$landingPageSettings.header.subtitle}
isAIEnabled={true}
/>
<SectionTitle>Actions</SectionTitle>
<TextField
label="Label"
placeholder="Write your label here"
className="w-full mt-3 mb-5"
bind:value={$landingPageSettings.header.action.label}
/>
<div class="gap-2 mb-5">
<TextField
label="Link"
placeholder="Write your link here"
bind:value={$landingPageSettings.header.action.link}
/>
<Toggle bind:toggled={$landingPageSettings.header.action.redirect} size="sm">
<span slot="labelA" style="color: gray">No redirect</span>
<span slot="labelB" style="color: gray">Redirect</span>
</Toggle>
</div>
<div />
<RadioButtonGroup
legendText="Banner Type"
bind:selected={$landingPageSettings.header.banner.type}
class="mt-10 mb-5"
>
{#each banner as item}
<RadioButton value={item.value} labelText={item.label} />
{/each}
</RadioButtonGroup>
{#if $landingPageSettings.header.banner.type === 'video'}
<div class="gap-2 mt-3 mb-5">
<TextField
label="Link"
placeholder="Write your video link here"
bind:value={$landingPageSettings.header.banner.video}
/>
</div>
{:else}
<PrimaryButton
variant={VARIANTS.OUTLINED}
label="Select Image"
className="mt-3"
onClick={() => widgetControl('banner')}
/>
{/if}
{#if $landingPageSettings.header.banner.image && $landingPageSettings.header.banner.type === 'image'}
<img
alt="bannerImage"
src={$landingPageSettings.header.banner.image}
class="mt-2 rounded-md w-full"
/>
{/if}
<Toggle bind:toggled={$landingPageSettings.header.banner.show} size="sm">
<span slot="labelA" style="color: gray">Hide banner</span>
<span slot="labelB" style="color: gray">Show banner</span>
</Toggle>
{#if $handleOpenWidget.open && widgetKey === 'banner'}
<UploadWidget bind:imageURL={$landingPageSettings.header.banner.image} />
{/if}
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}
><SectionTitle>About</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.aboutUs.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle></Column
>
<Column sm={8} md={8} lg={8} class="mt-4 lg:mt-0">
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.aboutUs.title}
className="mb-5"
/>
<TextArea
label="Content"
labelClassName="font-light"
placeholder="Write your Content here"
className="mb-5"
bind:value={$landingPageSettings.aboutUs.content}
isAIEnabled={true}
/>
<div>
<p class="font-bold">Upload an image</p>
<PrimaryButton
variant={VARIANTS.OUTLINED}
label="Select Image"
className="mt-3"
onClick={() => widgetControl('about-us')}
/>
{#if $landingPageSettings.aboutUs.imageUrl}
<img
alt="About us"
src={$landingPageSettings.aboutUs.imageUrl}
class="mt-2 rounded-md w-full"
/>
{/if}
{#if $handleOpenWidget.open && widgetKey === 'about-us'}
<UploadWidget bind:imageURL={$landingPageSettings.aboutUs.imageUrl} />
{/if}
</div>
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}
><SectionTitle>Courses</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.courses.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8} class="mt-4 lg:mt-0">
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.courses.title}
/>
<TextField
label="Title-Highlight"
placeholder="Write your title highlight here"
bind:value={$landingPageSettings.courses.titleHighlight}
/>
<TextArea
label="Subtitle"
labelClassName="font-light"
placeholder="Write your subtitle here"
bind:value={$landingPageSettings.courses.subtitle}
isAIEnabled={true}
/>
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}
><SectionTitle>Frequently Asked Questions</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.faq.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8}>
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.faq.title}
className="mb-5"
/>
{#each $landingPageSettings.faq.questions as item (item.id)}
<div class="mb-3">
<TextField
label="Question"
placeholder="Write your question here"
bind:value={item.title}
className="mb-5"
/>
<TextArea
label="Answer"
labelClassName="font-light"
placeholder="Write your answer here"
bind:value={item.content}
className="mb-5"
isAIEnabled={true}
/>
<IconButton onClick={() => deleteFaq(item.id)}>
<TrashCan size={24} class="fill-red-700" />
</IconButton>
</div>
{/each}
{#if creatingNewQuestion}
<TextField
label="Question"
placeholder="Write your question here"
bind:value={newQuestion.title}
className="mb-5"
/>
<TextArea
label="Answer"
labelClassName="font-light"
placeholder="Write your answer here"
bind:value={newQuestion.content}
className="mb-5"
isAIEnabled={true}
/>
<div class="flex items-center gap-2">
<PrimaryButton variant={VARIANTS.OUTLINED} label="Save" onClick={saveNewFAQ} />
<PrimaryButton variant={VARIANTS.OUTLINED} label="Cancel" onClick={cancelNewFAQ} />
</div>
{:else}
<PrimaryButton variant={VARIANTS.OUTLINED} label="Add New Faq" onClick={createNewFaq} />
{/if}
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}
><SectionTitle>Contact us</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.contact.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8}>
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.contact.title}
className="mb-5"
/>
<TextField
label="Title-highlight"
labelClassName="font-light"
placeholder="Write your title highlight here"
className="mb-5"
bind:value={$landingPageSettings.contact.titleHighlight}
/>
<TextArea
label="Subtitle"
labelClassName="font-light"
placeholder="Write your subtitle here"
className="mt-3 mb-5"
bind:value={$landingPageSettings.contact.subtitle}
isAIEnabled={true}
/>
<TextField
label="Phone number"
placeholder="Write your phone number here"
className="mt-3 mb-5"
bind:value={$landingPageSettings.contact.phone}
/>
<TextField
label="Email"
placeholder="Write your email here"
className="mt-3 mb-5"
bind:value={$landingPageSettings.contact.email}
/>
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7 border-bottom-c">
<Column sm={4} md={4} lg={4}
><SectionTitle>Mailing List</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.mailinglist.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8} class="mt-4 lg:mt-0">
<TextField
label="Title"
placeholder="Write your title here"
bind:value={$landingPageSettings.mailinglist.title}
className="mb-5"
/>
<TextArea
label="Subtitle"
labelClassName="font-light"
placeholder="Write your subtitle here"
className="mb-5"
bind:value={$landingPageSettings.mailinglist.subtitle}
isAIEnabled={true}
/>
<TextField
label="Button-label"
placeholder="Write your label here"
className="mb-5"
bind:value={$landingPageSettings.mailinglist.buttonLabel}
/>
</Column>
</Row>
<Row class="flex lg:flex-row flex-col py-7">
<Column sm={4} md={4} lg={4}
><SectionTitle>Footer</SectionTitle>
<Toggle bind:toggled={$landingPageSettings.footer.show} size="sm">
<span slot="labelA" style="color: gray">Hide section</span>
<span slot="labelB" style="color: gray">Show section</span>
</Toggle>
</Column>
<Column sm={8} md={8} lg={8} class="mt-4 lg:mt-0">
<TextField
label="Facebook"
placeholder="Write your Facebook link here"
bind:value={$landingPageSettings.footer.facebook}
className="mb-5"
/>
<!-- <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"
className="mb-5"
bind:value={$landingPageSettings.footer.linkedin}
/>
</Column>
</Row>
<div class="sticky desktop float-right bottom-12 mr-2 z-[120]">
<PrimaryButton
label="Save Changes"
isLoading={isSaving}
isDisabled={isSaving}
onClick={handleSave}
/>
</div>
</Grid>
<div
class="absolute
mobile right-6 bottom-8 z-[120]"
>
<span>
<IconButton onClick={handleSave} disabled={isSaving}>
<Save size={40} class=" bg-blue-700 p-1 rounded-full" />
</IconButton>
</span>
</div>
<style>
@media screen and (min-width: 769px) {
.desktop {
display: block;
}
.mobile {
display: none;
}
}
@media screen and (max-width: 768px) {
.desktop {
display: none;
}
.mobile {
display: flex;
}
}
</style>