PluginProbe
Code Snippets / 3.10.2
Code Snippets v3.10.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / common / Toolbar.tsx

Toolbar.tsx in Code Snippets 3.10.2, at js/components/common/Toolbar.tsx

199 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __, _x } from '@wordpress/i18n'
2 import classnames from 'classnames'
3 import React, { useMemo, useState } from 'react'
4 import { isLicensed, shouldShowUpsell } from '../../utils/screen'
5 import { buildUrl } from '../../utils/urls'
6 import { BlueprintIcon } from './icons/BlueprintIcon'
7 import { CommunityIcon } from './icons/CommunityIcon'
8 import { LibraryIcon } from './icons/LibraryIcon'
9 import { SettingsIcon } from './icons/SettingsIcon'
10 import { SnippetsIcon } from './icons/SnippetsIcon'
11 import { UpsellDialog } from './UpsellDialog'
12 import type { SVGProps } from 'react'
13
14 export const SUBPAGES = ['snippets', 'blueprints', 'cloud-community', 'cloud-library'] as const
15
16 const searchParams = new URLSearchParams(window.location.search)
17
18 interface UpperNavItemProps {
19 name: string
20 url: string
21 label: string
22 }
23
24 const UpperNavItem = ({ name, url, label }: UpperNavItemProps) => {
25 const pageSlug = useMemo(() => new URL(url).searchParams.get('page'), [url])
26
27 const isActive = !searchParams.get('subpage') && searchParams.get('page') === pageSlug
28
29 return (
30 <li>
31 <a
32 href={url}
33 className={classnames(`${name}-link`, { 'active-link': isActive })}
34 {...!pageSlug && { target: '_blank', rel: 'noopener noreferrer' }}
35 >
36 {label}
37 </a>
38 </li>
39 )
40 }
41 const UpperNavItems = () =>
42 <>
43 <UpperNavItem
44 name="docs"
45 url="https://codesnippets.pro/docs"
46 label={__('Docs', 'code-snippets')}
47 />
48
49 <UpperNavItem
50 name="cloud"
51 url="https://codesnippets.cloud/"
52 label={__('Cloud Dashboard', 'code-snippets')}
53 />
54
55 {window.CODE_SNIPPETS?.urls.welcome && (
56 <UpperNavItem
57 name="welcome"
58 url={window.CODE_SNIPPETS.urls.welcome}
59 label={__("What's New", 'code-snippets')}
60 />)}
61
62 {window.CODE_SNIPPETS?.urls.import && (
63 <UpperNavItem
64 name="import-snippets"
65 url={window.CODE_SNIPPETS.urls.import}
66 label={_x('Import', 'snippets', 'code-snippets')}
67 />)}
68
69 </>
70
71 const MoreNav = () =>
72 <li className="toolbar-more-item">
73 <details className="toolbar-more-menu">
74 <summary>
75 {__('More', 'code-snippets')}
76 <span className="dashicons dashicons-arrow-down-alt2" aria-hidden="true"></span>
77 </summary>
78 <ul>
79 <UpperNavItems />
80 </ul>
81 </details>
82 </li>
83
84 const UpperNav: React.FC = () => {
85 const [isUpsellDialogOpen, setIsUpsellDialogOpen] = useState(false)
86
87 return (
88 <div className="code-snippets-toolbar-upper">
89 <div className="logo">
90 <img
91 src={`${window.CODE_SNIPPETS?.urls.plugin}/assets/icon.svg`}
92 alt={__('Code Snippets logo', 'code-snippets')}
93 aria-hidden="true"
94 />
95
96 <div>{__('Code Snippets', 'code-snippets')}</div>
97 </div>
98
99 <nav aria-label={__('Main links', 'code-snippets')}>
100 <ul>
101 <UpperNavItems />
102 <MoreNav />
103
104 {shouldShowUpsell() && (
105 <li className="toolbar-upgrade-item">
106 <a
107 className="button button-large button-secondary"
108 href="https://codesnippets.pro/pricing/"
109 target="_blank" rel="noopener noreferrer"
110 onClick={event => {
111 event.preventDefault()
112 setIsUpsellDialogOpen(true)
113 }}
114 >
115 {__('Upgrade to Pro', 'code-snippets')}
116 </a>
117 </li>)}
118 </ul>
119 </nav>
120
121 <UpsellDialog isOpen={isUpsellDialogOpen} setIsOpen={setIsUpsellDialogOpen} />
122 </div>
123 )
124 }
125
126 interface SubpageItemProps {
127 subpage: typeof SUBPAGES[number]
128 label: string
129 Icon: React.FC<SVGProps<SVGSVGElement>>
130 isPro?: boolean
131 }
132
133 const SubpageItem: React.FC<SubpageItemProps> = ({ subpage, label, Icon, isPro }) =>
134 <li>
135 <a
136 href={buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: subpage })}
137 className={classnames(`${subpage}-link`, { 'active-link': subpage === searchParams.get('subpage') })}
138 >
139 <Icon aria-hidden="true" />
140 <span className="toolbar-nav-label">{label}</span>
141 {isPro && !isLicensed() && <span className="pro-chip">{__('Pro', 'code-snippets')}</span>}
142 </a>
143 </li>
144
145 const LowerNav = () =>
146 <div className="code-snippets-toolbar-lower">
147 <nav aria-label={__('Main features', 'code-snippets')}>
148 <ul>
149 <SubpageItem
150 subpage="snippets"
151 label={__('Snippets', 'code-snippets')}
152 Icon={SnippetsIcon}
153 />
154
155 {isLicensed() && (
156 <SubpageItem
157 subpage="blueprints"
158 label={__('Blueprints', 'code-snippets')}
159 Icon={BlueprintIcon}
160 />)}
161
162 <SubpageItem
163 subpage="cloud-community"
164 label={__('Cloud Community', 'code-snippets')}
165 Icon={CommunityIcon}
166 />
167
168 <SubpageItem
169 subpage="cloud-library"
170 label={__('Cloud Library', 'code-snippets')}
171 Icon={LibraryIcon}
172 isPro
173 />
174
175 {!isLicensed() && (
176 <SubpageItem
177 subpage="blueprints"
178 label={__('Blueprints', 'code-snippets')}
179 Icon={BlueprintIcon}
180 isPro
181 />)}
182
183 {window.CODE_SNIPPETS?.urls.settings && (
184 <li className="toolbar-end-item">
185 <a href={window.CODE_SNIPPETS.urls.settings} className="settings-link">
186 <SettingsIcon aria-hidden="true" />
187 <span className="toolbar-nav-label">{__('Settings', 'code-snippets')}</span>
188 </a>
189 </li>)}
190 </ul>
191 </nav>
192 </div>
193
194 export const Toolbar = () =>
195 <div className="code-snippets-toolbar">
196 <UpperNav />
197 <LowerNav />
198 </div>
199