| 1 |
import React, { useEffect, useMemo, useRef, useState } from 'react' |
| 2 |
import { __ } from '@wordpress/i18n' |
| 3 |
import { getSnippetType } from '../../../utils/snippets/snippets' |
| 4 |
import { ListTable } from '../../common/ListTable' |
| 5 |
import { ScreenMetaSlot } from '../../common/ScreenMetaSlot' |
| 6 |
import { DemoCallout } from '../../common/demo/DemoCallout' |
| 7 |
import { DemoPageHeader } from '../../common/demo/DemoPageHeader' |
| 8 |
import { DemoSpotlight } from '../../common/demo/DemoSpotlight' |
| 9 |
import { DemoUpsell } from '../../common/demo/DemoUpsell' |
| 10 |
import { PreviewModal } from '../../common/snippets/SnippetPreviewModal' |
| 11 |
import { cloudLibraryDemoColumns } from './cloudLibraryDemoColumns' |
| 12 |
import { getCallout } from './callouts' |
| 13 |
import { FEATURED_SNIPPET_ID, getDemoCloudSnippets } from './demoCloudSnippets' |
| 14 |
import { useCloudLibraryDemo } from './useCloudLibraryDemo' |
| 15 |
import type { CloudSnippetSchema } from '../../../types/schema/CloudSnippetSchema' |
| 16 |
import type { DemoStage } from './types' |
| 17 |
|
| 18 |
const FEATURED_ROW = '.cloud-library-snippets tbody tr.demo-featured-row' |
| 19 |
|
| 20 |
/** The part of the page each step is talking about. */ |
| 21 |
const STAGE_SPOTLIGHTS: Partial<Record<DemoStage, { target: string, padding?: number }>> = { |
| 22 |
library: { target: '.cloud-library-snippets', padding: 6 }, |
| 23 |
preview: { target: `${FEATURED_ROW} .demo-preview-button`, padding: 6 }, |
| 24 |
download: { target: `${FEATURED_ROW} .demo-action-button`, padding: 6 }, |
| 25 |
synced: { target: FEATURED_ROW, padding: 4 } |
| 26 |
} |
| 27 |
|
| 28 |
const STAGE_ANNOUNCEMENTS: Partial<Record<DemoStage, string>> = { |
| 29 |
library: __('Showing the snippets saved in your cloud.', 'code-snippets'), |
| 30 |
preview: __('Previewing the snippet code.', 'code-snippets'), |
| 31 |
download: __('Downloading the snippet to your site.', 'code-snippets'), |
| 32 |
synced: __('The snippet is now synced with your cloud.', 'code-snippets'), |
| 33 |
finished: __('Demo complete.', 'code-snippets') |
| 34 |
} |
| 35 |
|
| 36 |
// eslint-disable-next-line max-lines-per-function -- the page reads as one sequence. |
| 37 |
export const CloudLibraryDemo: React.FC = () => { |
| 38 |
const { stage, hasStarted, isFinished, reducedMotion, play, skip, replay } = useCloudLibraryDemo() |
| 39 |
|
| 40 |
const snippets = useMemo(getDemoCloudSnippets, []) |
| 41 |
const [preview, setPreview] = useState<CloudSnippetSchema>() |
| 42 |
|
| 43 |
const featured = snippets.find(snippet => FEATURED_SNIPPET_ID === snippet.id) |
| 44 |
|
| 45 |
// The walkthrough opens the preview itself, and closes it again before it |
| 46 |
// moves on to the download. |
| 47 |
useEffect(() => { |
| 48 |
setPreview('preview' === stage ? featured : undefined) |
| 49 |
}, [featured, stage]) |
| 50 |
|
| 51 |
const upsellRef = useRef<HTMLDivElement>(null) |
| 52 |
|
| 53 |
useEffect(() => { |
| 54 |
if (isFinished) { |
| 55 |
upsellRef.current?.scrollIntoView({ |
| 56 |
behavior: reducedMotion ? 'auto' : 'smooth', |
| 57 |
block: 'end' |
| 58 |
}) |
| 59 |
} |
| 60 |
}, [isFinished, reducedMotion]) |
| 61 |
|
| 62 |
return ( |
| 63 |
<> |
| 64 |
<ScreenMetaSlot /> |
| 65 |
|
| 66 |
<DemoPageHeader |
| 67 |
title={__('Cloud Library', 'code-snippets')} |
| 68 |
description={__('A guided walkthrough of the Pro Cloud Library. Press play and watch a snippet move from your cloud onto this site.', 'code-snippets')} |
| 69 |
hasStarted={hasStarted} |
| 70 |
isFinished={isFinished} |
| 71 |
onPlay={play} |
| 72 |
onSkip={skip} |
| 73 |
onReplay={replay} |
| 74 |
/> |
| 75 |
|
| 76 |
<div className="cloud-library-demo"> |
| 77 |
<div className="screen-reader-text" aria-live="polite">{STAGE_ANNOUNCEMENTS[stage]}</div> |
| 78 |
|
| 79 |
<DemoCallout callout={getCallout(stage)} /> |
| 80 |
|
| 81 |
<DemoSpotlight {...STAGE_SPOTLIGHTS[stage]} /> |
| 82 |
|
| 83 |
<div className="cloud-library-snippets snippets-list-view"> |
| 84 |
<ListTable |
| 85 |
fixed |
| 86 |
striped |
| 87 |
items={snippets} |
| 88 |
columns={cloudLibraryDemoColumns({ stage, onPreview: setPreview })} |
| 89 |
getKey={snippet => snippet.id} |
| 90 |
rowClassName={snippet => FEATURED_SNIPPET_ID === snippet.id ? 'demo-featured-row' : ''} |
| 91 |
/> |
| 92 |
</div> |
| 93 |
|
| 94 |
{isFinished && <div ref={upsellRef} className="cloud-library-demo__closing"> |
| 95 |
<DemoUpsell |
| 96 |
title={__('That was a demo — your cloud travels with you', 'code-snippets')} |
| 97 |
onReplay={replay} |
| 98 |
> |
| 99 |
<p>{__('The whole walkthrough was scripted and ran inside this plugin. These snippets are examples, and nothing was downloaded or saved.', 'code-snippets')}</p> |
| 100 |
<p>{__('With Code Snippets Pro your Cloud Library is available on every site you connect, so a snippet written once can be reused everywhere and kept in sync.', 'code-snippets')}</p> |
| 101 |
</DemoUpsell> |
| 102 |
</div>} |
| 103 |
|
| 104 |
{preview && <PreviewModal |
| 105 |
title={preview.name} |
| 106 |
code={preview.code} |
| 107 |
type={getSnippetType(preview)} |
| 108 |
onRequestClose={() => setPreview(undefined)} |
| 109 |
/>} |
| 110 |
</div> |
| 111 |
</> |
| 112 |
) |
| 113 |
} |
| 114 |
|