PluginProbe ʕ •ᴥ•ʔ
Starter Sites & Templates by Neve / trunk
Starter Sites & Templates by Neve vtrunk
1.4.0 1.3.0 1.2.29 1.2.28 1.2.6 1.2.7 1.2.8 1.2.9 trunk 1.0.10 1.0.11 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.27 1.1.28 1.1.29 1.1.3 1.1.30 1.1.31 1.1.32 1.1.33 1.1.34 1.1.35 1.1.36 1.1.37 1.1.38 1.1.39 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.3 1.2.4 1.2.5
templates-patterns-collection / assets / src / Components / Header.js
templates-patterns-collection / assets / src / Components Last commit date
CloudLibrary 1 year ago Settings 1 year ago StarterSites 3 years ago App.js 2 years ago Card.js 3 years ago CategoriesTabs.js 3 years ago CategorySelector.js 2 years ago CustomTooltip.js 3 years ago DocNotice.js 2 years ago EditorSelector.js 2 years ago EditorTabs.js 4 years ago Header.js 2 years ago Icon.js 2 years ago ImportModal.js 1 year ago ImportModalError.js 2 years ago ImportModalMock.js 4 years ago ImportModalNote.js 4 years ago ImportStepper.js 1 year ago InstallModal.js 1 year ago License.js 2 years ago LicensePanelContext.js 3 years ago Loading.js 4 years ago Main.js 1 year ago Migration.js 4 years ago NewTCNotice.js 1 year ago Notification.js 4 years ago OnboardingContent.js 4 years ago PreviewFrame.js 3 years ago Search.js 2 years ago StarterSiteCard.js 3 years ago
Header.js
217 lines
1 /* global tiobDash, localStorage */
2 import { withSelect, withDispatch } from '@wordpress/data';
3 import { useEffect, useState, useContext } from '@wordpress/element';
4 import { Button, Icon } from '@wordpress/components';
5 import { compose } from '@wordpress/compose';
6 import { update, cloud, close } from '@wordpress/icons';
7 import { __ } from '@wordpress/i18n';
8
9 import Logo, { NeveIcon } from './Icon';
10 import classnames from 'classnames';
11 import { v4 as uuidv4 } from 'uuid';
12 import { addUrlHash, getTabHash } from '../utils/common';
13 import License from './License';
14 import { LicensePanelContext } from './LicensePanelContext';
15
16 const TabNavigation = ( {
17 setCurrentTab,
18 currentTab,
19 isFetching,
20 license,
21 } ) => {
22 const buttons = {};
23
24 if ( ! tiobDash.hideStarterSites ) {
25 buttons.starterSites = __( 'Starter Sites', 'templates-patterns-collection' );
26 buttons.pageTemplates = __( 'Page Templates', 'templates-patterns-collection' );
27 }
28
29 if ( ! tiobDash.hideMyLibrary ) {
30 buttons.library = __( 'My Library', 'templates-patterns-collection' );
31 }
32 buttons.settings = __( 'Settings', 'templates-patterns-collection' );
33
34 const [ isSyncing, setSyncing ] = useState( false );
35 const { isLicenseOpen, setLicenseOpen } = useContext( LicensePanelContext );
36 const isValid = 'valid' === license?.valid || 'valid' === license?.license;
37
38 const sync = () => {
39 setSyncing( true );
40 localStorage.setItem( 'tpcCacheBuster', uuidv4() );
41 const nextTab = currentTab;
42 setCurrentTab( null );
43 setTimeout( () => {
44 setCurrentTab( nextTab );
45 setSyncing( false );
46 }, 100 );
47 };
48
49 const onHashChanged = () => {
50 const hash = getTabHash( buttons );
51 if ( null === hash ) {
52 return;
53 }
54
55 let menu = document.getElementById( 'toplevel_page_neve-welcome' );
56 if ( ! menu ) {
57 menu = document.getElementById( 'menu-appearance' );
58 }
59 const tiobMenu = document.getElementById( 'toplevel_page_tiob-plugin' );
60
61 const lookupHashList = [ '#pageTemplates', '#settings' ];
62 const itemHashList = lookupHashList.map( ( itemHash ) => {
63 return {
64 hash: itemHash,
65 item: menu.querySelector( `a[href="themes.php?page=tiob-starter-sites${ itemHash }"]` )
66 || menu.querySelector( `a[href="admin.php?page=tiob-starter-sites${ itemHash }"]` )
67 || tiobMenu.querySelector( `a[href="admin.php?page=tiob-plugin${ itemHash }"]` ),
68 }
69 } );
70
71 const hasAllItemsDefined = itemHashList.reduce( ( acc, link ) => { return ( link?.item ) ? ++acc : acc }, 0 ) === itemHashList.length;
72
73 // The logic here is to ensure the sidebar menu items appear as active when the user navigates to a page via the URL hash (through react).
74 if ( hasAllItemsDefined ) {
75 for ( let i in itemHashList ) {
76 const link = itemHashList[ i ];
77 if ( link.hash.replace('#', '') === hash ) {
78 let siblings = link.item.parentElement.parentElement.children;
79 for ( let child of siblings ) {
80 child.classList.remove( 'current' );
81 }
82 link.item.parentElement.classList.add( 'current' );
83 }
84 }
85 }
86 setCurrentTab( hash );
87 };
88
89 useEffect( () => {
90 onHashChanged();
91 window.addEventListener( 'hashchange', onHashChanged );
92 }, [] );
93
94 return (
95 <div className="header-nav">
96 { currentTab !== 'starterSites' && currentTab !== 'settings' && ! tiobDash.hideMyLibrary && (
97 <Button
98 icon={ update }
99 onClick={ sync }
100 label={ __(
101 'Re-sync Library',
102 'templates-patterns-collection'
103 ) }
104 className={ classnames( 'is-icon-btn', {
105 'is-loading': isSyncing,
106 } ) }
107 disabled={ isFetching || isSyncing }
108 data-content={ __(
109 'Sync',
110 'templates-patterns-collection'
111 ) }
112 />
113 ) }
114 </div>
115 );
116 };
117
118 const BrandTitle = ( currentTab ) => {
119
120 let showNeveIcon = false;
121 if ( [ 'starterSites', 'pageTemplates' ].includes( currentTab.currentTab ) && ! tiobDash.brandedTheme ) {
122 showNeveIcon = true;
123 }
124
125 let title = __( 'Templates Cloud', 'templates-patterns-collection' );
126 switch ( currentTab.currentTab ) {
127 case 'starterSites':
128 title = __( 'Starter Sites', 'templates-patterns-collection' );
129 break;
130 case 'pageTemplates':
131 title = __( 'Page Templates', 'templates-patterns-collection' );
132 break;
133 case 'library':
134 title = __( 'My Library', 'templates-patterns-collection' );
135 break;
136 case 'settings':
137 title = __( 'Settings', 'templates-patterns-collection' );
138 break;
139 }
140
141 return (
142 <h2>
143 { showNeveIcon && (
144 <Icon icon={ NeveIcon } />
145 ) }
146 { ! showNeveIcon && (
147 <Icon icon={ Logo } />
148 ) }
149 <span>
150 { title }
151 </span>
152 </h2>
153 );
154 };
155
156 const Header = ( {
157 isOnboarding,
158 cancelOnboarding,
159 setCurrentTab,
160 currentTab,
161 license,
162 } ) => {
163 return (
164 <div className="ob-head">
165 { ! isOnboarding && (
166 <>
167 <div className="header-container">
168 <BrandTitle currentTab={ currentTab } />
169 <TabNavigation
170 setCurrentTab={ setCurrentTab }
171 currentTab={ currentTab }
172 license={ license }
173 />
174 </div>
175 </>
176 ) }
177 { isOnboarding && (
178 <Button
179 className="close-onboarding"
180 isLink
181 icon="no-alt"
182 onClick={ cancelOnboarding }
183 />
184 ) }
185 </div>
186 );
187 };
188
189 export default compose(
190 withDispatch( ( dispatch ) => {
191 const { setOnboardingState, setCurrentTab, setFetching } = dispatch(
192 'neve-onboarding'
193 );
194 return {
195 cancelOnboarding: () => {
196 setOnboardingState( false );
197 },
198 setCurrentTab,
199 setFetching,
200 };
201 } ),
202 withSelect( ( select ) => {
203 const {
204 getOnboardingStatus,
205 getCurrentTab,
206 getFetching,
207 getLicense,
208 } = select( 'neve-onboarding' );
209 return {
210 isOnboarding: getOnboardingStatus(),
211 currentTab: getCurrentTab(),
212 isFetching: getFetching(),
213 license: getLicense(),
214 };
215 } )
216 )( Header );
217