fix: preserve landing page section content when toggled off (#838)

* preserve section content when toggled off

* Update types.ts

* Remove comment on LandingPageLinks enabled property

Removed comment about the default visibility of the section.

---------

Co-authored-by: Rotimi Best <best@classroomio.com>
This commit is contained in:
Victor Jack
2026-08-11 14:31:58 +01:00
committed by GitHub
co-authored by Rotimi Best
parent 0dc32b5210
commit 6537613000
12 changed files with 102 additions and 101 deletions
@@ -125,6 +125,7 @@ type LegacyLandingPageJson = {
footerText?: string;
theme?: OrgLandingPageTheme;
embed?: {
enabled?: boolean;
title?: string;
description?: string;
code?: string;
@@ -138,6 +139,7 @@ type LegacyLandingPageJson = {
sandbox?: string;
};
callout?: {
enabled?: boolean;
heading?: string;
description?: string;
action?: {
@@ -413,6 +415,7 @@ function normalizeCallout(callout: NonNullable<LegacyLandingPageJson['callout']>
}
return {
enabled: callout.enabled !== false,
heading,
description: normalizeText(callout.description, ''),
action: {
@@ -468,6 +471,7 @@ function normalizeLinks(raw: unknown): OrgLandingPageLinks | undefined {
const classicLearnMoreLabel = normalizeText(raw.classicLearnMoreLabel, '');
return {
enabled: raw.enabled !== false,
heading,
description: description || undefined,
boldVisitLabel: boldVisitLabel || undefined,
@@ -541,6 +545,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
footer: resolveFooterConfig(landingPage),
embed: landingPage.embed
? {
enabled: landingPage.embed.enabled !== false,
title: normalizeText(landingPage.embed.title, 'Section title'),
description: normalizeText(landingPage.embed.description, ''),
code: normalizeEmbedCode(landingPage.embed),
@@ -587,6 +592,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
footer: resolveFooterConfig(landingPage),
embed: landingPage.embed
? {
enabled: landingPage.embed.enabled !== false,
title: normalizeText(landingPage.embed.title, 'Section title'),
description: normalizeText(landingPage.embed.description, ''),
code: normalizeEmbedCode(landingPage.embed)
@@ -624,6 +630,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
footer: resolveFooterConfig(landingPage),
embed: landingPage.embed
? {
enabled: landingPage.embed.enabled !== false,
title: normalizeText(landingPage.embed.title, 'Section title'),
description: normalizeText(landingPage.embed.description, ''),
code: normalizeEmbedCode(landingPage.embed),
@@ -33,6 +33,7 @@
}
const callout: OrgLandingPageCallout = {
enabled: true,
heading: t.get('settings.landing_page.editor.callout.heading_default'),
description: '',
action: {
@@ -51,16 +52,7 @@
}
function setCalloutEnabled(enabled: boolean) {
if (!enabled) {
settings = {
...settings,
callout: undefined
};
markDirty();
return;
}
setter(ensureCallout(), 'callout');
setter({ ...ensureCallout(), enabled }, 'callout');
}
</script>
@@ -71,13 +63,13 @@
<div class="space-y-6">
<Field.Field orientation="horizontal">
<Switch
checked={Boolean(settings.callout)}
checked={settings.callout?.enabled ?? false}
onCheckedChange={(checked) => setCalloutEnabled(checked === true)}
/>
<Field.Label>{$t('settings.landing_page.editor.callout.toggle')}</Field.Label>
</Field.Field>
{#if settings.callout}
{#if settings.callout?.enabled}
<Field.Field>
<div class="flex items-center justify-between">
<Field.Label>{$t('settings.landing_page.editor.callout.heading')}</Field.Label>
@@ -34,6 +34,7 @@
}
const embed = {
enabled: true,
title: t.get('settings.landing_page.editor.embed.title'),
description: '',
code: '',
@@ -50,16 +51,7 @@
}
function setEmbedEnabled(enabled: boolean) {
if (!enabled) {
settings = {
...settings,
embed: undefined
};
markDirty();
return;
}
setter(ensureEmbed(), 'embed');
setter({ ...ensureEmbed(), enabled }, 'embed');
}
function updateSecondaryAction(label: string, href: string) {
@@ -83,63 +75,68 @@
<div class="space-y-6">
<Field.Field orientation="horizontal">
<Switch checked={Boolean(settings.embed)} onCheckedChange={(checked) => setEmbedEnabled(checked === true)} />
<Switch
checked={settings.embed?.enabled ?? false}
onCheckedChange={(checked) => setEmbedEnabled(checked === true)}
/>
<Field.Label>{$t('settings.landing_page.editor.embed.toggle')}</Field.Label>
</Field.Field>
{#if settings.embed}
<Field.Field>
<div class="flex items-center justify-between">
<Field.Label>{$t('settings.landing_page.editor.embed.title')}</Field.Label>
<AIGenerateButton
context="the embed section title on an organization's course platform landing page"
onInsert={(text) => setter(text, 'embed.title')}
{#if settings.embed?.enabled}
<div class="pb-5">
<Field.Field>
<div class="flex items-center justify-between">
<Field.Label>{$t('settings.landing_page.editor.embed.title')}</Field.Label>
<AIGenerateButton
context="the embed section title on an organization's course platform landing page"
onInsert={(text) => setter(text, 'embed.title')}
/>
</div>
<Input
value={settings.embed.title}
placeholder={$t('settings.landing_page.editor.embed.title_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.title')}
/>
</div>
<Input
value={settings.embed.title}
placeholder={$t('settings.landing_page.editor.embed.title_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.title')}
/>
</Field.Field>
</Field.Field>
<Field.Field class="min-w-0">
<div class="flex items-center justify-between">
<Field.Label>{$t('settings.landing_page.editor.embed.description')}</Field.Label>
<AIGenerateButton
context="the embed section description on an organization's course platform landing page"
onInsert={(text) => setter(text, 'embed.description')}
<Field.Field class="min-w-0">
<div class="flex items-center justify-between">
<Field.Label>{$t('settings.landing_page.editor.embed.description')}</Field.Label>
<AIGenerateButton
context="the embed section description on an organization's course platform landing page"
onInsert={(text) => setter(text, 'embed.description')}
/>
</div>
<Textarea
class="ui:[field-sizing:fixed] ui:min-w-0 ui:w-full ui:max-w-full ui:box-border ui:resize-y ui:break-all ui:overflow-x-auto"
value={settings.embed.description ?? ''}
placeholder={$t('settings.landing_page.editor.embed.description_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.description')}
/>
</div>
<Textarea
class="ui:[field-sizing:fixed] ui:min-w-0 ui:w-full ui:max-w-full ui:box-border ui:resize-y ui:break-all ui:overflow-x-auto"
value={settings.embed.description ?? ''}
placeholder={$t('settings.landing_page.editor.embed.description_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.description')}
/>
</Field.Field>
</Field.Field>
<Field.Field class="min-w-0">
<Field.Label>{$t('settings.landing_page.editor.embed.code')}</Field.Label>
<Field.Description>{$t('settings.landing_page.editor.embed.code_description')}</Field.Description>
<Textarea
class="ui:[field-sizing:fixed] ui:min-w-0 ui:w-full ui:max-w-full ui:box-border ui:resize-y ui:break-all ui:overflow-x-auto"
value={settings.embed.code}
placeholder={$t('settings.landing_page.editor.embed.code_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.code')}
/>
</Field.Field>
<Field.Field class="min-w-0">
<Field.Label>{$t('settings.landing_page.editor.embed.code')}</Field.Label>
<Field.Description>{$t('settings.landing_page.editor.embed.code_description')}</Field.Description>
<Textarea
class="ui:[field-sizing:fixed] ui:min-w-0 ui:w-full ui:max-w-full ui:box-border ui:resize-y ui:break-all ui:overflow-x-auto"
value={settings.embed.code}
placeholder={$t('settings.landing_page.editor.embed.code_placeholder')}
oninput={(event) => setter(event.currentTarget.value, 'embed.code')}
/>
</Field.Field>
<ButtonLinkFields
label={settings.embed.secondaryAction?.label ?? ''}
href={settings.embed.secondaryAction?.href ?? ''}
labelFieldLabel={$t('settings.landing_page.editor.embed.secondary_label')}
hrefFieldLabel={$t('settings.landing_page.editor.embed.secondary_href')}
labelPlaceholder={$t('settings.landing_page.editor.embed.secondary_label')}
hrefPlaceholder={$t('settings.landing_page.editor.embed.secondary_href')}
onLabelInput={(value) => updateSecondaryAction(value, settings.embed.secondaryAction?.href ?? '')}
onHrefInput={(value) => updateSecondaryAction(settings.embed.secondaryAction?.label ?? '', value)}
/>
<ButtonLinkFields
label={settings.embed.secondaryAction?.label ?? ''}
href={settings.embed.secondaryAction?.href ?? ''}
labelFieldLabel={$t('settings.landing_page.editor.embed.secondary_label')}
hrefFieldLabel={$t('settings.landing_page.editor.embed.secondary_href')}
labelPlaceholder={$t('settings.landing_page.editor.embed.secondary_label')}
hrefPlaceholder={$t('settings.landing_page.editor.embed.secondary_href')}
onLabelInput={(value) => updateSecondaryAction(value, settings.embed.secondaryAction?.href ?? '')}
onHrefInput={(value) => updateSecondaryAction(settings.embed.secondaryAction?.label ?? '', value)}
/>
</div>
{/if}
</div>
</Field.Set>
@@ -54,6 +54,7 @@
}
const links: NonNullable<OrgLandingPageJson['links']> = {
enabled: true,
heading: t.get('settings.landing_page.editor.links.heading_default'),
description: '',
boldVisitLabel: t.get('settings.landing_page.editor.links.bold_visit_default'),
@@ -90,16 +91,11 @@
}
function setLinksEnabled(enabled: boolean) {
if (!enabled) {
settings = {
...settings,
links: undefined
};
markDirty();
return;
}
ensureLinks();
settings = {
...settings,
links: { ...ensureLinks(), enabled }
};
markDirty();
}
function addCard() {
@@ -137,11 +133,14 @@
<div class="space-y-6">
<Field.Field orientation="horizontal">
<Switch checked={Boolean(settings.links)} onCheckedChange={(checked) => setLinksEnabled(checked === true)} />
<Switch
checked={settings.links?.enabled ?? false}
onCheckedChange={(checked) => setLinksEnabled(checked === true)}
/>
<Field.Label>{$t('settings.landing_page.editor.links.toggle')}</Field.Label>
</Field.Field>
{#if settings.links}
{#if settings.links?.enabled}
<Field.Field>
<Field.Label>{$t('settings.landing_page.editor.links.heading')}</Field.Label>
<Input
@@ -50,6 +50,7 @@ export type OrgLandingPageFooterConfig = {
};
export interface OrgLandingPageEmbed {
enabled: boolean;
title: string;
description?: string;
code: string;
@@ -60,6 +61,7 @@ export interface OrgLandingPageEmbed {
}
export interface OrgLandingPageCallout {
enabled: boolean;
heading: string;
description: string;
action: {
@@ -88,6 +90,7 @@ export interface OrgLandingPageLinkCard {
}
export interface OrgLandingPageLinks {
enabled: boolean;
heading: string;
description?: string;
boldVisitLabel?: string;