mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-27 22:49:56 -05:00
Refactored theme demo selector functionality (#18541)
refs https://github.com/TryGhost/Product/issues/3999 Refactored the theme demo functionality to remove the hard-coded reference to the source theme and enable the functionality for any theme.
This commit is contained in:
parent
81d2fa09da
commit
9a18d43ea6
5 changed files with 67 additions and 22 deletions
|
@ -4,8 +4,9 @@ import {DefaultHeaderTypes} from '../../utils/unsplash/UnsplashTypes';
|
||||||
import {ZapierTemplate} from '../settings/advanced/integrations/ZapierModal';
|
import {ZapierTemplate} from '../settings/advanced/integrations/ZapierModal';
|
||||||
|
|
||||||
export type ThemeVariant = {
|
export type ThemeVariant = {
|
||||||
image: string;
|
|
||||||
category: string;
|
category: string;
|
||||||
|
previewUrl: string;
|
||||||
|
image: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OfficialTheme = {
|
export type OfficialTheme = {
|
||||||
|
|
|
@ -12,8 +12,9 @@ const hasVariants = (theme: OfficialTheme) => theme.variants && theme.variants.l
|
||||||
|
|
||||||
const getAllVariants = (theme: OfficialTheme) : ThemeVariant[] => {
|
const getAllVariants = (theme: OfficialTheme) : ThemeVariant[] => {
|
||||||
const variants = [{
|
const variants = [{
|
||||||
image: theme.image,
|
category: theme.category,
|
||||||
category: theme.category
|
previewUrl: theme.previewUrl,
|
||||||
|
image: theme.image
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (theme.variants && theme.variants.length > 0) {
|
if (theme.variants && theme.variants.length > 0) {
|
||||||
|
|
|
@ -8,14 +8,26 @@ import NiceModal from '@ebay/nice-modal-react';
|
||||||
import PageHeader from '../../../../admin-x-ds/global/layout/PageHeader';
|
import PageHeader from '../../../../admin-x-ds/global/layout/PageHeader';
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import Select, {SelectOption} from '../../../../admin-x-ds/global/form/Select';
|
import Select, {SelectOption} from '../../../../admin-x-ds/global/form/Select';
|
||||||
import {OfficialTheme} from '../../../providers/ServiceProvider';
|
import {OfficialTheme, ThemeVariant} from '../../../providers/ServiceProvider';
|
||||||
import {Theme} from '../../../../api/themes';
|
import {Theme} from '../../../../api/themes';
|
||||||
|
|
||||||
const sourceDemos = [
|
const hasVariants = (theme: OfficialTheme) => theme.variants && theme.variants.length > 0;
|
||||||
{label: 'News', value: 'news', url: 'https://source.ghost.io'},
|
|
||||||
{label: 'Magazine', value: 'magazine', url: 'https://source-magazine.ghost.io'},
|
const getAllVariants = (theme: OfficialTheme) : ThemeVariant[] => {
|
||||||
{label: 'Newsletter', value: 'newsletter', url: 'https://source-newsletter.ghost.io'}
|
const variants = [{
|
||||||
];
|
image: theme.image,
|
||||||
|
category: theme.category,
|
||||||
|
previewUrl: theme.previewUrl
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (theme.variants && theme.variants.length > 0) {
|
||||||
|
variants.push(...theme.variants);
|
||||||
|
}
|
||||||
|
|
||||||
|
return variants;
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateVariantOptionValue = (variant: ThemeVariant) => variant.category.toLowerCase();
|
||||||
|
|
||||||
const ThemePreview: React.FC<{
|
const ThemePreview: React.FC<{
|
||||||
selectedTheme?: OfficialTheme;
|
selectedTheme?: OfficialTheme;
|
||||||
|
@ -33,12 +45,29 @@ const ThemePreview: React.FC<{
|
||||||
onInstall
|
onInstall
|
||||||
}) => {
|
}) => {
|
||||||
const [previewMode, setPreviewMode] = useState('desktop');
|
const [previewMode, setPreviewMode] = useState('desktop');
|
||||||
const [currentSourceDemo, setCurrentSourceDemo] = useState<SelectOption>(sourceDemos[0]);
|
const [selectedVariant, setSelectedVariant] = useState<SelectOption | undefined>(undefined);
|
||||||
|
|
||||||
if (!selectedTheme) {
|
if (!selectedTheme) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previewUrl = selectedTheme.previewUrl;
|
||||||
|
|
||||||
|
const variantOptions = getAllVariants(selectedTheme).map((variant) => {
|
||||||
|
return {
|
||||||
|
label: variant.category,
|
||||||
|
value: generateVariantOptionValue(variant)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasVariants(selectedTheme)) {
|
||||||
|
if (selectedVariant === undefined) {
|
||||||
|
setSelectedVariant(variantOptions[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
previewUrl = getAllVariants(selectedTheme).find(variant => generateVariantOptionValue(variant) === selectedVariant?.value)?.previewUrl || previewUrl;
|
||||||
|
}
|
||||||
|
|
||||||
let installButtonLabel = `Install ${selectedTheme.name}`;
|
let installButtonLabel = `Install ${selectedTheme.name}`;
|
||||||
|
|
||||||
if (isInstalling) {
|
if (isInstalling) {
|
||||||
|
@ -87,7 +116,7 @@ const ThemePreview: React.FC<{
|
||||||
backIcon
|
backIcon
|
||||||
onBack={onBack}
|
onBack={onBack}
|
||||||
/>
|
/>
|
||||||
{selectedTheme.name === 'Source' ?
|
{hasVariants(selectedTheme) ?
|
||||||
<>
|
<>
|
||||||
<span className='hidden md:!visible md:!block'>–</span>
|
<span className='hidden md:!visible md:!block'>–</span>
|
||||||
<Select
|
<Select
|
||||||
|
@ -95,12 +124,10 @@ const ThemePreview: React.FC<{
|
||||||
containerClassName='text-sm font-bold'
|
containerClassName='text-sm font-bold'
|
||||||
controlClasses={{menu: 'w-24'}}
|
controlClasses={{menu: 'w-24'}}
|
||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
options={sourceDemos}
|
options={variantOptions}
|
||||||
selectedOption={currentSourceDemo}
|
selectedOption={selectedVariant}
|
||||||
onSelect={(option) => {
|
onSelect={(option) => {
|
||||||
if (option) {
|
setSelectedVariant(option || undefined);
|
||||||
setCurrentSourceDemo(option);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</> : null
|
</> : null
|
||||||
|
@ -147,7 +174,7 @@ const ThemePreview: React.FC<{
|
||||||
<DesktopChrome>
|
<DesktopChrome>
|
||||||
<iframe
|
<iframe
|
||||||
className='h-full w-full'
|
className='h-full w-full'
|
||||||
src={selectedTheme.name !== 'Source' ? selectedTheme?.previewUrl : sourceDemos.find(demo => demo.label === currentSourceDemo.label)?.url}
|
src={previewUrl}
|
||||||
title='Theme preview'
|
title='Theme preview'
|
||||||
/>
|
/>
|
||||||
</DesktopChrome>
|
</DesktopChrome>
|
||||||
|
@ -155,7 +182,7 @@ const ThemePreview: React.FC<{
|
||||||
<MobileChrome>
|
<MobileChrome>
|
||||||
<iframe
|
<iframe
|
||||||
className='h-full w-full'
|
className='h-full w-full'
|
||||||
src={selectedTheme.name !== 'Source' ? selectedTheme?.previewUrl : sourceDemos.find(demo => demo.label === currentSourceDemo.label)?.url}
|
src={previewUrl}
|
||||||
title='Theme preview'
|
title='Theme preview'
|
||||||
/>
|
/>
|
||||||
</MobileChrome>
|
</MobileChrome>
|
||||||
|
|
|
@ -19,8 +19,16 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||||
ref: 'default',
|
ref: 'default',
|
||||||
image: 'assets/img/themes/Source.png',
|
image: 'assets/img/themes/Source.png',
|
||||||
variants: [
|
variants: [
|
||||||
{image: 'assets/img/themes/Source-Magazine.png', category: 'Magazine'},
|
{
|
||||||
{image: 'assets/img/themes/Source-Newsletter.png', category: 'Newsletter'}
|
category: 'Magazine',
|
||||||
|
previewUrl: 'https://source-magazine.ghost.io/',
|
||||||
|
image: 'assets/img/themes/Source-Magazine.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'Newsletter',
|
||||||
|
previewUrl: 'https://source-newsletter.ghost.io/',
|
||||||
|
image: 'assets/img/themes/Source-Newsletter.png'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
name: 'Casper',
|
name: 'Casper',
|
||||||
|
|
|
@ -18,8 +18,16 @@ const officialThemes = [{
|
||||||
ref: 'default',
|
ref: 'default',
|
||||||
image: 'assets/img/themes/Source.png',
|
image: 'assets/img/themes/Source.png',
|
||||||
variants: [
|
variants: [
|
||||||
{image: 'assets/img/themes/Source-Magazine.png', category: 'Magazine'},
|
{
|
||||||
{image: 'assets/img/themes/Source-Newsletter.png', category: 'Newsletter'}
|
category: 'Magazine',
|
||||||
|
previewUrl: 'https://source-magazine.ghost.io/',
|
||||||
|
image: 'assets/img/themes/Source-Magazine.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: 'Newsletter',
|
||||||
|
previewUrl: 'https://source-newsletter.ghost.io/',
|
||||||
|
image: 'assets/img/themes/Source-Newsletter.png'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
name: 'Casper',
|
name: 'Casper',
|
||||||
|
|
Loading…
Add table
Reference in a new issue