diff --git a/build/1.11.8/images/toggle-light-mode.8d7afd07.png b/build/1.11.8/images/toggle-light-mode.8d7afd07.png new file mode 100644 index 000000000..1ea6d7b09 Binary files /dev/null and b/build/1.11.8/images/toggle-light-mode.8d7afd07.png differ diff --git a/src/OnboardingSPA/components/AdminBar/index.js b/src/OnboardingSPA/components/AdminBar/index.js index efa6c8b4c..2d10e2804 100644 --- a/src/OnboardingSPA/components/AdminBar/index.js +++ b/src/OnboardingSPA/components/AdminBar/index.js @@ -1,7 +1,40 @@ +import { __ } from '@wordpress/i18n'; +import { Icon, wordpress } from '@wordpress/icons'; +import { useSelect } from '@wordpress/data'; +import { store as nfdOnboardingStore } from '../../../OnboardingSPA/store'; + const AdminBar = () => { + const { currentUserInfo } = useSelect( ( select ) => { + return { + currentUserInfo: + select( nfdOnboardingStore ).getCurrentUserDetails(), + }; + }, [] ); + + if ( ! currentUserInfo ) { + return null; + } + return (
- Admin Bar Goes Here +
+ + { __( 'WordPress', 'wp-module-onboarding' ) } +
+
+ + + { __( 'Howdy! ', 'wp-module-onboarding' ) } + { currentUserInfo.displayName } + + +
+ { +
+
); }; diff --git a/src/OnboardingSPA/components/AdminBar/stylesheet.scss b/src/OnboardingSPA/components/AdminBar/stylesheet.scss index c87ab6c6c..4768b72e5 100644 --- a/src/OnboardingSPA/components/AdminBar/stylesheet.scss +++ b/src/OnboardingSPA/components/AdminBar/stylesheet.scss @@ -1,3 +1,5 @@ +$light-grey : #a0a5aa; + .nfd-onboarding-header { &__admin-bar { @@ -6,7 +8,49 @@ width: 100%; color: var(--nfd-onboarding-admin-bar-color); margin: 0; - padding-left: 10px; - padding-top: 7px; + padding: 5px; + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; + + &__wplogo { + color: var(--nfd-onboarding-white); + font-size: 16px; + display: flex; + align-items: center; + + svg { + color: $light-grey; + fill: $light-grey; + } + + span { + margin-left: 15px; + } + } + + &__profile { + display: flex; + align-items: center; + + &__greeting { + color: $light-grey; + font-size: 16px; + margin-right: 5px; + } + + &__avatar { + height: 20px; + width: 20px; + display: inline-block; + + img { + width: 100%; + height: 100%; + object-fit: contain; + } + } + } } } diff --git a/src/OnboardingSPA/components/Header/components/SiteGenHeader/index.js b/src/OnboardingSPA/components/Header/components/SiteGenHeader/index.js index 2f0027111..db3390a10 100644 --- a/src/OnboardingSPA/components/Header/components/SiteGenHeader/index.js +++ b/src/OnboardingSPA/components/Header/components/SiteGenHeader/index.js @@ -34,7 +34,7 @@ const SiteGenHeader = () => { ); const currentStepIndex = findIndex( allSteps, { - path: currentStep.path, + path: currentStep?.path, } ); const progress = ( currentStepIndex / allSteps.length ) * 100; diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteBuild/index.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteBuild/index.js index 6384313b7..9681c3f9b 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteBuild/index.js +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteBuild/index.js @@ -2,6 +2,7 @@ import Header from '../../Header'; import Content from '../../Content'; import Drawer from '../../Drawer'; import Sidebar from '../../Sidebar'; +import ToggleDarkMode from '../../ToggleDarkMode'; import classNames from 'classnames'; import { useLocation } from 'react-router-dom'; import { setFlow } from '../../../utils/api/flow'; @@ -52,6 +53,8 @@ import { init as initializePlugins } from '../../../utils/api/plugins'; import { init as initializeThemes } from '../../../utils/api/themes'; import { trigger as cronTrigger } from '../../../utils/api/cronTrigger'; import { stepTheFork } from '../../../steps/TheFork/step'; +import { ThemeProvider } from '../../ThemeContextProvider'; +import themeToggleHOC from '../themeToggleHOC'; const SiteBuild = () => { const location = useLocation(); @@ -419,28 +422,39 @@ const SiteBuild = () => { handlePreviousStepTracking(); handleConditionalDesignStepsRoutes(); }, [ location.pathname, onboardingFlow ] ); + + const shouldApplyTheme = + currentStep === stepTheFork || + window.nfdOnboarding.currentFlow === 'sitegen'; + // wrapping the NewfoldInterfaceSkeleton with the HOC to make 'theme' available + const ThemedNewfoldInterfaceSkeleton = themeToggleHOC( + NewfoldInterfaceSkeleton, + 'nfd-onboarding-sitegen-dark', + 'nfd-onboarding-sitegen-light', + shouldApplyTheme + ); + return ( - } - drawer={ } - content={ } - sidebar={ } - /> + + } + drawer={ } + content={ } + sidebar={ } + footer={ shouldApplyTheme ? : null } + /> + ); }; diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js index 87e29e351..ac1433532 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js @@ -2,19 +2,28 @@ import NewfoldInterfaceSkeleton from '../index'; import Header from '../../Header'; import Content from '../../Content'; import Sidebar from '../../Sidebar'; -import classNames from 'classnames'; +import ToggleDarkMode from '../../ToggleDarkMode'; +import { ThemeProvider } from '../../ThemeContextProvider'; +import themeToggleHOC from '../themeToggleHOC'; + +// Wrapping the NewfoldInterfaceSkeleton with the HOC to make theme available +const ThemedNewfoldInterfaceSkeleton = themeToggleHOC( + NewfoldInterfaceSkeleton, + 'nfd-onboarding-sitegen-dark', + 'nfd-onboarding-sitegen-light' +); const SiteGen = () => { return ( - } - content={ } - sidebar={ } - /> + + } + content={ } + sidebar={ } + footer={ } + /> + ); }; diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/style.scss b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/style.scss index f6dfbae10..6e0dc17d4 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/style.scss +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/style.scss @@ -191,5 +191,9 @@ html.nfd-interface-interface-skeleton__html-container { background-image: var(--sitegen-background); background-repeat: no-repeat; background-size: cover; + + .nfd-interface-interface-skeleton__footer { + display: flex; + } } } diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/themeToggleHOC.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/themeToggleHOC.js new file mode 100644 index 000000000..1289c09b4 --- /dev/null +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/themeToggleHOC.js @@ -0,0 +1,26 @@ +import { useContext } from '@wordpress/element'; +import { ThemeContext } from '../ThemeContextProvider'; +import classNames from 'classnames'; +import { THEME_DARK } from '../../../constants'; + +const themeToggleHOC = ( + WrappedComponent, + darkClass, + lightClass, + shouldApplyTheme = true +) => { + return ( props ) => { + const { theme } = useContext( ThemeContext ); + const isDarkMode = theme === THEME_DARK; + const shouldApply = + shouldApplyTheme !== undefined ? shouldApplyTheme : true; + const className = classNames( props.className, { + [ darkClass ]: isDarkMode && shouldApply, + [ lightClass ]: ! isDarkMode && shouldApply, + } ); + + return ; + }; +}; + +export default themeToggleHOC; diff --git a/src/OnboardingSPA/components/ThemeContextProvider/index.js b/src/OnboardingSPA/components/ThemeContextProvider/index.js new file mode 100644 index 000000000..bf563887d --- /dev/null +++ b/src/OnboardingSPA/components/ThemeContextProvider/index.js @@ -0,0 +1,22 @@ +import { useState, createContext } from '@wordpress/element'; +import { THEME_DARK, THEME_LIGHT } from '../../../constants'; + +const ThemeContext = createContext(); + +const ThemeProvider = ( { children } ) => { + const [ theme, setTheme ] = useState( 'dark' ); + + const toggleTheme = () => { + setTheme( ( prevTheme ) => + prevTheme === THEME_DARK ? THEME_LIGHT : THEME_DARK + ); + }; + + return ( + + { children } + + ); +}; + +export { ThemeContext, ThemeProvider }; diff --git a/src/OnboardingSPA/components/ToggleDarkMode/contents.js b/src/OnboardingSPA/components/ToggleDarkMode/contents.js new file mode 100644 index 000000000..7049e53c2 --- /dev/null +++ b/src/OnboardingSPA/components/ToggleDarkMode/contents.js @@ -0,0 +1,9 @@ +import { __ } from '@wordpress/i18n'; + +const getContents = () => { + return { + label: __( 'Dark Mode', 'wp-module-onboarding' ), + }; +}; + +export default getContents; diff --git a/src/OnboardingSPA/components/ToggleDarkMode/index.js b/src/OnboardingSPA/components/ToggleDarkMode/index.js new file mode 100644 index 000000000..c24b16b92 --- /dev/null +++ b/src/OnboardingSPA/components/ToggleDarkMode/index.js @@ -0,0 +1,38 @@ +import { useContext } from '@wordpress/element'; +import { ThemeContext } from '../ThemeContextProvider'; +import classNames from 'classnames'; +import { THEME_DARK } from '../../../constants'; + +const ToggleDarkMode = () => { + const { theme, toggleTheme } = useContext( ThemeContext ); + const isDarkMode = theme === THEME_DARK; + const onChange = () => { + toggleTheme(); + }; + + return ( +
+
onChange() } + role="button" + onKeyDown={ ( event ) => { + if ( event.key === 'Enter' ) { + onChange(); + } + } } + tabIndex="0" + >
+
+ ); +}; + +export default ToggleDarkMode; diff --git a/src/OnboardingSPA/components/ToggleDarkMode/stylesheet.scss b/src/OnboardingSPA/components/ToggleDarkMode/stylesheet.scss new file mode 100644 index 000000000..7bc4870a3 --- /dev/null +++ b/src/OnboardingSPA/components/ToggleDarkMode/stylesheet.scss @@ -0,0 +1,21 @@ +.nfd-onboarding-toggle__theme { + position: absolute; + bottom: 25px; + left: 25px; + z-index: 1; + + &__button { + width: 60px; + height: 60px; + cursor: pointer; + + &__light { + animation: fadeIn 600ms ease-in-out; + background: var(--sitegen-toggle-theme-icon-light); + } + + &__dark { + background: var(--sitegen-toggle-theme-icon-dark); + } + } +} diff --git a/src/OnboardingSPA/static/icons/toggle-dark-mode.svg b/src/OnboardingSPA/static/icons/toggle-dark-mode.svg new file mode 100644 index 000000000..647bc05db --- /dev/null +++ b/src/OnboardingSPA/static/icons/toggle-dark-mode.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/OnboardingSPA/static/icons/toggle-light-mode.png b/src/OnboardingSPA/static/icons/toggle-light-mode.png new file mode 100644 index 000000000..1ea6d7b09 Binary files /dev/null and b/src/OnboardingSPA/static/icons/toggle-light-mode.png differ diff --git a/src/OnboardingSPA/store/selectors.js b/src/OnboardingSPA/store/selectors.js index f74172be4..f0f64886b 100644 --- a/src/OnboardingSPA/store/selectors.js +++ b/src/OnboardingSPA/store/selectors.js @@ -403,3 +403,14 @@ export function getExperienceLevel( state ) { export function getTopPriority( state ) { return state.data.flowData.data.topPriority.priority1; } + +/** + * Gets Current User Details like Display name and avatar URL + * + * @param {*} state + * @return {string} currentUserInfo + */ +export function getCurrentUserDetails( state ) { + const currentUserInfo = state.runtime.currentUserDetails; + return currentUserInfo; +} diff --git a/src/OnboardingSPA/styles/_branding.scss b/src/OnboardingSPA/styles/_branding.scss index 3f3ff7a55..bd3c59080 100644 --- a/src/OnboardingSPA/styles/_branding.scss +++ b/src/OnboardingSPA/styles/_branding.scss @@ -304,4 +304,14 @@ body { --nfd-onboarding-progress-bar-background: #353a40; --nfd-onboarding-progress-bar-fill: #0060f0; } + + .nfd-onboarding-sitegen-light { + --nfd-onboarding-admin-bar-background: #1d2327; + --nfd-onboarding-admin-bar-color: #c3c4c7; + --nfd-onboarding-navigation-back-background: rgba(54, 62, 68, 0.35); + --nfd-onboarding-primary: #000; + --nfd-onboarding-secondary: #fff; + --nfd-onboarding-progress-bar-background: #353a40; + --nfd-onboarding-progress-bar-fill: #0060f0; + } } diff --git a/src/OnboardingSPA/styles/_icons.scss b/src/OnboardingSPA/styles/_icons.scss index d37915591..f70a327f3 100644 --- a/src/OnboardingSPA/styles/_icons.scss +++ b/src/OnboardingSPA/styles/_icons.scss @@ -38,6 +38,8 @@ body { --site-features-comingsoon: url(../static/icons/site-features/comingsoon.svg); --sitegen-background: url(../static/images/sitegen-bg.png); - --sitegen-ai-animation: url(../static/images/sitegen-ai-animation.gif); --sitegen-ai-icon: url(../static/icons/sitegen-ai-icon.svg); + --sitegen-ai-animation: url(../static/images/sitegen-ai-animation.gif); + --sitegen-toggle-theme-icon-dark: url(../static/icons/toggle-dark-mode.svg); + --sitegen-toggle-theme-icon-light: url(../static/icons/toggle-light-mode.png); } diff --git a/src/OnboardingSPA/styles/app.scss b/src/OnboardingSPA/styles/app.scss index 671ad272c..41c94debd 100644 --- a/src/OnboardingSPA/styles/app.scss +++ b/src/OnboardingSPA/styles/app.scss @@ -47,6 +47,7 @@ @import "../components/ProgressBar/stylesheet"; @import "../components/Button/ButtonDark/stylesheet"; @import "../components/SiteGenPlaceholder/stylesheet"; +@import "../components/ToggleDarkMode/stylesheet"; @import "../components/Button/NextButtonSiteGen/stylesheet"; // CSS for Pages diff --git a/src/constants.js b/src/constants.js index 238d3911b..de747c40e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -65,6 +65,8 @@ export const CHAPTER_DESIGN = 'design'; export const CHAPTER_LAYOUT_AND_CONTENT = 'layout_and_content'; export const CHAPTER_FEATURES = 'features'; export const CHAPTER_SITEGEN = 'sitegen'; +export const THEME_DARK = 'dark'; +export const THEME_LIGHT = 'light'; /** * All views for the component.