← All changes
|
js/components/ManageMenu/CommunityCloud/CommunityCloud.tsx
+67
-49
4.0.0-beta.1
→
trunk
View file →
| @@ -1,67 +1,85 @@ | ||
| 1 | 1 | import React, { useState } from 'react' |
| 2 | -import { __ } from '@wordpress/i18n' | |
| 3 | -import classnames from 'classnames' | |
| 2 | +import { __, sprintf } from '@wordpress/i18n' | |
| 4 | 3 | import { WithRestAPIContext } from '../../../hooks/useRestAPI' |
| 4 | +import { useSnippetView } from '../../../hooks/useSnippetView' | |
| 5 | 5 | import { isLicensed } from '../../../utils/screen' |
| 6 | -import { buildUrl, fetchQueryParam, updateQueryParams } from '../../../utils/urls' | |
| 7 | -import { UpsellDialog } from '../../common/UpsellDialog' | |
| 8 | -import { WithCloudSearchContext } from './WithCloudSearchContext' | |
| 6 | +import { updateQueryParams } from '../../../utils/urls' | |
| 7 | +import { ScreenMetaSlot } from '../../common/ScreenMetaSlot' | |
| 8 | +import { SubnavTabs, getTabFromQuery } from '../../common/SubnavTabs' | |
| 9 | +import { WithCloudSnippetDownloadsContext } from '../../common/cloud/WithCloudSnippetDownloadsContext' | |
| 10 | +import { UpsellPage } from '../../common/UpsellDialog' | |
| 11 | +import { WithCloudSearchContext, useCloudSearch } from './WithCloudSearchContext' | |
| 9 | 12 | import { CloudSearch } from './CloudSearch' |
| 13 | +import type { SubnavTab } from '../../common/SubnavTabs' | |
| 10 | 14 | |
| 11 | -const TABS = ['snippets', 'bundles'] as const | |
| 12 | -type TabName = typeof TABS[number] | |
| 15 | +const TAB_QUERY_PARAM = 'tab' | |
| 13 | 16 | |
| 14 | -const TAB_LABELS: Record<TabName, string> = { | |
| 15 | - snippets: __('Code Snippets', 'code-snippets'), | |
| 16 | - bundles: __('Bundles', 'code-snippets') | |
| 17 | -} | |
| 17 | +const TABS: SubnavTab<'snippets' | 'bundles'>[] = [ | |
| 18 | + { | |
| 19 | + name: 'snippets', | |
| 20 | + label: __('Snippets', 'code-snippets') | |
| 21 | + }, | |
| 22 | + { | |
| 23 | + name: 'bundles', | |
| 24 | + label: __('Bundles', 'code-snippets'), | |
| 25 | + pro: true | |
| 26 | + } | |
| 27 | +] | |
| 18 | 28 | |
| 19 | -const PRO_TABS: TabName[] = ['bundles'] | |
| 29 | +const CommunityCloudInner = () => { | |
| 30 | + const [currentTab, setCurrentTab] = useState(() => getTabFromQuery(TABS, TAB_QUERY_PARAM)) | |
| 31 | + const { snippetView, setSnippetView } = useSnippetView() | |
| 32 | + const { searchResults } = useCloudSearch() | |
| 20 | 33 | |
| 21 | -export const CommunityCloud = () => { | |
| 22 | - const [currentTab, setCurrentTab] = useState(() => fetchQueryParam('tab') as TabName | null ?? TABS[0]) | |
| 23 | - const [isUpsellDialogOpen, setIsUpsellDialogOpen] = useState(false) | |
| 24 | - | |
| 25 | 34 | return ( |
| 26 | 35 | <> |
| 27 | - <h2>{__('Community Cloud', 'code-snippets')}</h2> | |
| 36 | + <SubnavTabs | |
| 37 | + className="community-cloud-nav" | |
| 38 | + ariaLabel={__('Community Cloud types', 'code-snippets')} | |
| 39 | + tabs={TABS} | |
| 40 | + getTabCount={tab => 'snippets' === tab.name ? searchResults?.totalItems : undefined} | |
| 41 | + currentTab={currentTab} | |
| 42 | + setCurrentTab={tab => { | |
| 43 | + updateQueryParams({ [TAB_QUERY_PARAM]: tab.name }) | |
| 44 | + setCurrentTab(tab) | |
| 45 | + }} | |
| 46 | + /> | |
| 28 | 47 | |
| 29 | - <hr className="wp-header-end" /> | |
| 48 | + <ScreenMetaSlot hidden={'bundles' === currentTab.name} /> | |
| 30 | 49 | |
| 31 | - <nav | |
| 32 | - className="nav-tab-wrapper community-cloud-tabs" | |
| 33 | - aria-label={__('Community Cloud types', 'code-snippets')} | |
| 34 | - > | |
| 35 | - {TABS.map(tab => | |
| 36 | - <a | |
| 37 | - key={tab} | |
| 38 | - href={buildUrl(window.location.href, { type: tab })} | |
| 39 | - className={classnames('nav-tab', `${tab}-tab`, { 'nav-tab-active': tab === currentTab })} | |
| 40 | - aria-current={tab === currentTab ? 'page' : undefined} | |
| 41 | - onClick={event => { | |
| 42 | - event.preventDefault() | |
| 50 | + {(!currentTab.pro || isLicensed()) && ( | |
| 51 | + <> | |
| 52 | + <div className="snippets-page-header"> | |
| 53 | + <h1>{ | |
| 54 | + // translators: %s: label of the currently selected community cloud tab. | |
| 55 | + sprintf(__('Community Cloud: %s', 'code-snippets'), currentTab.label)}</h1> | |
| 56 | + </div> | |
| 43 | 57 | |
| 44 | - if (PRO_TABS.includes(tab) && !isLicensed()) { | |
| 45 | - setIsUpsellDialogOpen(true) | |
| 46 | - } else { | |
| 47 | - updateQueryParams({ tab }) | |
| 48 | - setCurrentTab(tab) | |
| 49 | - } | |
| 50 | - }} | |
| 51 | - > | |
| 52 | - {TAB_LABELS[tab]} | |
| 53 | - {PRO_TABS.includes(tab) && !isLicensed() && <span className="pro-chip">{__('Pro', 'code-snippets')}</span>} | |
| 54 | - </a>)} | |
| 55 | - </nav> | |
| 58 | + <hr className="wp-header-end" /> | |
| 56 | 59 | |
| 57 | - {'snippets' === currentTab && ( | |
| 58 | - <WithRestAPIContext> | |
| 59 | - <WithCloudSearchContext> | |
| 60 | - <CloudSearch /> | |
| 61 | - </WithCloudSearchContext> | |
| 62 | - </WithRestAPIContext>)} | |
| 60 | + <p className="snippets-page-description"> | |
| 61 | + {__('Search the community cloud and download user-shared snippets directly to your site.', 'code-snippets')} | |
| 62 | + </p> | |
| 63 | + </>)} | |
| 63 | 64 | |
| 64 | - <UpsellDialog isOpen={isUpsellDialogOpen} setIsOpen={setIsUpsellDialogOpen} /> | |
| 65 | + {(() => { | |
| 66 | + switch (currentTab.name) { | |
| 67 | + case 'snippets': | |
| 68 | + return <CloudSearch snippetView={snippetView} setSnippetView={setSnippetView} /> | |
| 69 | + | |
| 70 | + case 'bundles': | |
| 71 | + return <UpsellPage /> | |
| 72 | + } | |
| 73 | + })()} | |
| 65 | 74 | </> |
| 66 | 75 | ) |
| 67 | 76 | } |
| 77 | + | |
| 78 | +export const CommunityCloud = () => | |
| 79 | + <WithRestAPIContext> | |
| 80 | + <WithCloudSnippetDownloadsContext> | |
| 81 | + <WithCloudSearchContext> | |
| 82 | + <CommunityCloudInner /> | |
| 83 | + </WithCloudSearchContext> | |
| 84 | + </WithCloudSnippetDownloadsContext> | |
| 85 | + </WithRestAPIContext> | |