diff --git a/includes/RestApi/SettingsController.php b/includes/RestApi/SettingsController.php index a59456c11..68aca0ac6 100644 --- a/includes/RestApi/SettingsController.php +++ b/includes/RestApi/SettingsController.php @@ -112,6 +112,49 @@ public function register_routes() { ), ) ); + + \register_rest_route( + $this->namespace, + $this->rest_base . '/coming-soon', + array( + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'set_coming_soon' ), + 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ), + 'args' => $this->set_coming_soon_params(), + ), + ) + ); + } + + /** + * Set query params for coming soon route. + * + * @return array + */ + public function set_coming_soon_params() { + return array( + 'comingSoon' => array( + 'type' => 'boolean', + 'required' => true, + ), + ); + } + /** + * Endpoint to set Coming Soon for a website. + * + * @param \WP_REST_Request $request Request model. + * + * @return \WP_REST_Response|\WP_Error + */ + public function set_coming_soon( \WP_REST_Request $request ) { + + $new_value = ( $request->get_param( 'comingSoon' ) ) ? 'true' : 'false'; + update_option( 'nfd_coming_soon', $new_value ); + return new \WP_REST_Response( + array(), + 200 + ); } /** diff --git a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/index.js b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/index.js index 219154607..0198951f5 100644 --- a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/index.js +++ b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/index.js @@ -25,6 +25,7 @@ const CheckboxItem = ( { callback, tabIndex = 0, isSelectedDefault, + fullWidth = false, className = 'checkbox-item', } ) => { const [ showDescription, setShowDescription ] = useState( false ); @@ -44,7 +45,9 @@ const CheckboxItem = ( {
-
{ desc }
+
+ { desc } +
) }
diff --git a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/stylesheet.scss b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/stylesheet.scss index f63bad775..1ad7d0281 100644 --- a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/stylesheet.scss +++ b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxItem/stylesheet.scss @@ -13,6 +13,14 @@ width: clamp(15rem, 25vw, 35rem); box-shadow: 0 2px 8px 2px rgba(204, 204, 204, 0.175295); + &--full-width { + width: clamp(15rem, 53.5vw, 74rem); + + @media (max-width: #{ ($break-medium) }) { + width: clamp(15rem, 25vw, 35rem); + } + } + &-container { display: flex; align-items: center; @@ -125,5 +133,13 @@ border-right: 1px solid rgba(var(--nfd-onboarding-highlighted--rgb), 0.1); border-bottom: 1px solid rgba(var(--nfd-onboarding-highlighted--rgb), 0.1); box-shadow: 0 11px 8px -3px rgba(var(--nfd-onboarding-highlighted--rgb), 0.37); + + &--full-width { + width: clamp(15rem, 53.5vw, 74rem); + + @media (max-width: #{ ($break-medium) }) { + width: clamp(15rem, 25vw, 35rem); + } + } } } diff --git a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxList/stylesheet.scss b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxList/stylesheet.scss index dd42eaf97..8a2c84037 100644 --- a/src/OnboardingSPA/components/CheckboxTemplate/CheckboxList/stylesheet.scss +++ b/src/OnboardingSPA/components/CheckboxTemplate/CheckboxList/stylesheet.scss @@ -1,16 +1,18 @@ .checkbox-list { - display: flex; - justify-content: center; - align-items: flex-start; + display: flex; + justify-content: center; + align-items: flex-start; - @media (max-width: #{ ($break-xlarge) }) { - flex-direction: column; - } + @media (max-width: #{ ($break-medium) }) { + flex-direction: column; + justify-content: center; + align-items: center; + } - &-col { - display: flex; - align-items: center; - flex-direction: column; - justify-content: center; - } -} \ No newline at end of file + &-col { + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + } +} diff --git a/src/OnboardingSPA/components/ComingSoon/contents.js b/src/OnboardingSPA/components/ComingSoon/contents.js new file mode 100644 index 000000000..fb161e1ec --- /dev/null +++ b/src/OnboardingSPA/components/ComingSoon/contents.js @@ -0,0 +1,27 @@ +import { __, sprintf } from '@wordpress/i18n'; + +import { translations } from '../../utils/locales/translations'; + +const getContents = () => { + return { + title: __( 'Coming Soon', 'wp-module-onboarding' ), + subtitle: sprintf( + /* translators: %s: site or store */ + __( + 'Keep your %s private until you click launch', + 'wp-module-onboarding' + ), + translations( 'site' ) + ), + desc: sprintf( + /* translators: %s: site or store */ + __( + "We'll show a placeholder page to logged-out visitors while you build your %s.", + 'wp-module-onboarding' + ), + translations( 'site' ) + ), + }; +}; + +export default getContents; diff --git a/src/OnboardingSPA/components/ComingSoon/index.js b/src/OnboardingSPA/components/ComingSoon/index.js new file mode 100644 index 000000000..5ec136ca4 --- /dev/null +++ b/src/OnboardingSPA/components/ComingSoon/index.js @@ -0,0 +1,40 @@ +import { useSelect, useDispatch } from '@wordpress/data'; + +import getContents from './contents'; +import { CheckboxItem } from '../CheckboxTemplate'; +import { store as nfdOnboardingStore } from '../../store'; + +const ComingSoon = () => { + const content = getContents(); + + const { currentData } = useSelect( ( select ) => { + return { + currentData: + select( nfdOnboardingStore ).getCurrentOnboardingData(), + }; + }, [] ); + + const { setCurrentOnboardingData } = useDispatch( nfdOnboardingStore ); + + async function handleComingSoon( name, selection ) { + currentData.data.comingSoon = selection; + setCurrentOnboardingData( currentData ); + } + + return ( +
+ +
+ ); +}; + +export default ComingSoon; diff --git a/src/OnboardingSPA/components/ComingSoon/stylesheet.scss b/src/OnboardingSPA/components/ComingSoon/stylesheet.scss new file mode 100644 index 000000000..2862abd27 --- /dev/null +++ b/src/OnboardingSPA/components/ComingSoon/stylesheet.scss @@ -0,0 +1,8 @@ +.coming_soon { + + &__wrapper { + width: 100%; + display: flex; + justify-content: center; + } +} diff --git a/src/OnboardingSPA/components/ExitToWordPress/index.js b/src/OnboardingSPA/components/ExitToWordPress/index.js index 4b36f6d6b..5fcb7b943 100644 --- a/src/OnboardingSPA/components/ExitToWordPress/index.js +++ b/src/OnboardingSPA/components/ExitToWordPress/index.js @@ -20,6 +20,7 @@ import { CATEGORY, } from '../../utils/analytics/hiive/constants'; import { activateInitialPlugins } from '../../utils/api/plugins'; +import { setComingSoon } from '../../utils/api/comingSoon'; /** * Self-contained button and confirmation modal for exiting Onboarding page. @@ -101,6 +102,7 @@ const ExitToWordPress = ( { } } setFlow( currentData ); + setComingSoon( currentData?.data?.comingSoon ); } activateInitialPlugins(); trackOnboardingEvent( diff --git a/src/OnboardingSPA/components/Loaders/Chapter/Interstitial/index.js b/src/OnboardingSPA/components/Loaders/Chapter/Interstitial/index.js index d59bc65bf..e157cafea 100644 --- a/src/OnboardingSPA/components/Loaders/Chapter/Interstitial/index.js +++ b/src/OnboardingSPA/components/Loaders/Chapter/Interstitial/index.js @@ -18,6 +18,7 @@ import { import { pluginDashboardPage } from '../../../../../constants'; import { setFlow } from '../../../../utils/api/flow'; import { ACTION_ONBOARDING_COMPLETE } from '../../../../utils/analytics/hiive/constants'; +import { setComingSoon } from '../../../../utils/api/comingSoon'; const ChapterInterstitialLoader = () => { const [ countdown, setCountdown ] = useState( 15 ); @@ -29,6 +30,7 @@ const ChapterInterstitialLoader = () => { if ( currentData ) { currentData.isComplete = new Date().getTime(); setFlow( currentData ); + setComingSoon( currentData?.data?.comingSoon ); } activateInitialPlugins(); diff --git a/src/OnboardingSPA/static/icons/site-features/comingsoon.svg b/src/OnboardingSPA/static/icons/site-features/comingsoon.svg new file mode 100644 index 000000000..9fb2dd985 --- /dev/null +++ b/src/OnboardingSPA/static/icons/site-features/comingsoon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/OnboardingSPA/steps/Complete/index.js b/src/OnboardingSPA/steps/Complete/index.js index 51f964852..bd0489fad 100644 --- a/src/OnboardingSPA/steps/Complete/index.js +++ b/src/OnboardingSPA/steps/Complete/index.js @@ -9,6 +9,7 @@ import { StepLoader } from '../../components/Loaders'; import { StepErrorState } from '../../components/ErrorState'; import { THEME_STATUS_INIT } from '../../../constants'; import { DesignStateHandler } from '../../components/StateHandlers'; +import { setComingSoon } from '../../utils/api/comingSoon'; const StepComplete = () => { const { @@ -22,18 +23,26 @@ const StepComplete = () => { const navigate = useNavigate(); const [ isError, setIsError ] = useState( false ); - const { nextStep, brandName, isQueueEmpty } = useSelect( ( select ) => { - return { - nextStep: select( nfdOnboardingStore ).getNextStep(), - brandName: select( nfdOnboardingStore ).getNewfoldBrandName(), - isQueueEmpty: select( nfdOnboardingStore ).isQueueEmpty(), - }; - }, [] ); + const { nextStep, brandName, isQueueEmpty, currentData } = useSelect( + ( select ) => { + return { + nextStep: select( nfdOnboardingStore ).getNextStep(), + brandName: select( nfdOnboardingStore ).getNewfoldBrandName(), + isQueueEmpty: select( nfdOnboardingStore ).isQueueEmpty(), + currentData: + select( nfdOnboardingStore ).getCurrentOnboardingData(), + }; + }, + [] + ); const contents = getContents( brandName ); const checkFlowComplete = async () => { - await Promise.all( [ completeFlowRequest() ] ).then( ( values ) => + await Promise.all( [ + completeFlowRequest(), + setComingSoon( currentData?.data?.comingSoon ), + ] ).then( ( values ) => values.forEach( ( value ) => { // If any Request returns False then Show Error if ( ! value ) { diff --git a/src/OnboardingSPA/steps/SiteFeatures/index.js b/src/OnboardingSPA/steps/SiteFeatures/index.js index 0bb792eef..a8265e459 100644 --- a/src/OnboardingSPA/steps/SiteFeatures/index.js +++ b/src/OnboardingSPA/steps/SiteFeatures/index.js @@ -12,6 +12,7 @@ import HeadingWithSubHeading from '../../components/HeadingWithSubHeading'; import CheckboxList from '../../components/CheckboxTemplate/CheckboxList'; import { CheckboxListSkeleton } from '../../components/CheckboxTemplate'; import getContents from './contents'; +import ComingSoon from '../../components/ComingSoon'; const StepSiteFeatures = () => { const isLargeViewport = useViewportMatch( 'medium' ); @@ -91,7 +92,7 @@ const StepSiteFeatures = () => { return ( -
+
{ customItemsList={ customPluginsList } /> ) } + { customPluginsList && } ); }; diff --git a/src/OnboardingSPA/steps/SiteFeatures/stylesheet.scss b/src/OnboardingSPA/steps/SiteFeatures/stylesheet.scss new file mode 100644 index 000000000..fae8868d7 --- /dev/null +++ b/src/OnboardingSPA/steps/SiteFeatures/stylesheet.scss @@ -0,0 +1,7 @@ +.site-features__heading { + margin: 100px; + + @media (max-width: #{ ($break-medium) }) { + margin: 0; + } +} diff --git a/src/OnboardingSPA/styles/_icons.scss b/src/OnboardingSPA/styles/_icons.scss index 909fd890e..31501c2a6 100644 --- a/src/OnboardingSPA/styles/_icons.scss +++ b/src/OnboardingSPA/styles/_icons.scss @@ -35,4 +35,5 @@ body { --site-features-security: url(../static/icons/site-features/security.svg); --site-features-share: url(../static/icons/site-features/share.svg); --site-features-wishlist: url(../static/icons/site-features/wishlist.svg); + --site-features-comingsoon: url(../static/icons/site-features/comingsoon.svg); } diff --git a/src/OnboardingSPA/styles/app.scss b/src/OnboardingSPA/styles/app.scss index 46be806fe..412effedf 100644 --- a/src/OnboardingSPA/styles/app.scss +++ b/src/OnboardingSPA/styles/app.scss @@ -42,6 +42,7 @@ @import "../components/NewfoldInterfaceSkeleton/style"; @import "../components/Loaders/Chapter/Interstitial/stylesheet"; @import "../components/Grid/stylesheet"; +@import "../components/ComingSoon/stylesheet"; // CSS for Pages @import "../steps/BasicInfo/stylesheet"; @@ -55,6 +56,7 @@ @import "../steps/SitePages/stylesheet"; @import "../steps/DesignTypography/stylesheet"; @import "../steps/DesignHeaderMenu/stylesheet"; +@import "../steps/SiteFeatures/stylesheet"; .nfd-onboarding-container { display: flex; diff --git a/src/OnboardingSPA/utils/api/comingSoon.js b/src/OnboardingSPA/utils/api/comingSoon.js new file mode 100644 index 000000000..4c1d13b73 --- /dev/null +++ b/src/OnboardingSPA/utils/api/comingSoon.js @@ -0,0 +1,16 @@ +import { onboardingRestURL } from './common'; +import { resolve } from './resolve'; + +import apiFetch from '@wordpress/api-fetch'; + +export async function setComingSoon( comingSoon ) { + return await resolve( + apiFetch( { + url: onboardingRestURL( 'settings/coming-soon' ), + method: 'POST', + data: { + comingSoon, + }, + } ).then() + ); +}