Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100-year-plan: Embed Calendly Widget Popup #95291

Merged
merged 31 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9c5c3ea
Create Calendly modal component
bogiii Oct 7, 2024
ecd2a23
Extend calendly widget to support customisation
bogiii Oct 7, 2024
3f595ce
Integrate Calendly widget into Modal component
bogiii Oct 7, 2024
27272ec
Define content and details styles
bogiii Oct 8, 2024
df06702
Fix iframe container overflow style
bogiii Oct 8, 2024
f3c6504
Add mobile view support
bogiii Oct 8, 2024
d9d83a9
Translate strings
bogiii Oct 9, 2024
9ce5a55
Customize modal close button to match the design
bogiii Oct 9, 2024
08c51ef
Initial popup widget instead of inline embed
bogiii Oct 10, 2024
dab4954
Integrate Calendly popup embed solution
bogiii Oct 10, 2024
6497d59
Remove unnecessary custom style
bogiii Oct 10, 2024
3f41ea6
Adjust style for mobile views
bogiii Oct 10, 2024
6df2762
Update calendly ID
bogiii Oct 10, 2024
b8cb2f1
Update calendly config id
bogiii Oct 10, 2024
623c5f6
Update flow to redirect on thank-you page
bogiii Oct 10, 2024
1195ef9
Update wrapper step to support hiding sidebar
bogiii Oct 10, 2024
1abae9b
Extend VideoLoader component to support hidding wrapper contianer
bogiii Oct 11, 2024
512f257
Match thank you step design
bogiii Oct 11, 2024
b942f5a
Remove button's box shadow
bogiii Oct 11, 2024
0ab5d07
Close opened popup in the cleanup function
bogiii Oct 11, 2024
7610c5a
Improve UX when user scheduled meeting
bogiii Oct 11, 2024
9b2b0dd
Hide gdpr banner
bogiii Oct 11, 2024
bf1802c
Change Calendly primary color
bogiii Oct 11, 2024
5c1d6a0
Typo: Add missing column
bogiii Oct 11, 2024
96c4590
Create use-calendly-widget hook
bogiii Oct 11, 2024
bdea1d9
Replace Calendly component with a new hook solution
bogiii Oct 11, 2024
5dd8540
Add missing button margin
bogiii Oct 11, 2024
749eff9
Remove unused way of calendly integration
bogiii Oct 11, 2024
0317bad
Fix typo in path of calendly widget logic
bogiii Oct 11, 2024
d1aae3c
Delete obsolete schedule appointment modal solution
bogiii Oct 11, 2024
1ec04e9
Delete obsolete schedule appointment step solution
bogiii Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/assets/images/icons/close-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 14 additions & 4 deletions client/components/hundred-year-loader-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const DESKTOP_EARTH_LOOP_URL = 'https://wpcom.files.wordpress.com/2023/09/earth-
type LoaderProps = {
isMobile: boolean;
loadingText: TranslateResult;
hideVideoContainer?: boolean;
};

const FullPageContainer = styled.div< { isMobile: boolean } >`
Expand Down Expand Up @@ -51,7 +52,7 @@ export const VideoPreload = memo( ( { isMobile }: { isMobile: boolean } ) =>
)
);

function VideoLoader( { isMobile, loadingText }: LoaderProps ) {
function VideoLoader( { isMobile, loadingText, hideVideoContainer }: LoaderProps ) {
const videoObject = useRef< HTMLVideoElement | null >( null );

const FullPageVideoContainer = styled( FullPageContainer )< { isMobile: boolean } >`
Expand All @@ -65,8 +66,9 @@ function VideoLoader( { isMobile, loadingText }: LoaderProps ) {
opacity: 25%;
}
`;
return (
<FullPageVideoContainer isMobile={ isMobile }>

const videoElement = (
<>
{ isMobile ? (
<video
ref={ videoObject }
Expand All @@ -92,7 +94,15 @@ function VideoLoader( { isMobile, loadingText }: LoaderProps ) {
loop
/>
) }
<h1 className="wp-brand-font">{ loadingText }</h1>
</>
);

return hideVideoContainer ? (
videoElement
) : (
<FullPageVideoContainer isMobile={ isMobile }>
{ videoElement }
{ !! loadingText && <h1 className="wp-brand-font">{ loadingText }</h1> }
</FullPageVideoContainer>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HundredYearLoaderView component has been updated to support rendering video without a container so we can reuse it in different contexts.

);
}
Expand Down
11 changes: 2 additions & 9 deletions client/landing/stepper/declarative-flow/hundred-year-plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ const HundredYearPlanFlow: Flow = {
asyncComponent: () =>
import( './internals/steps-repository/hundred-year-plan-diy-or-difm' ),
},
{
slug: 'schedule-appointment',
asyncComponent: () =>
import( './internals/steps-repository/hundred-year-plan-schedule-appointment' ),
},
{
slug: 'thank-you',
asyncComponent: () =>
Expand Down Expand Up @@ -127,11 +122,9 @@ const HundredYearPlanFlow: Flow = {
case 'diy-or-difm':
if ( 'diy' === providedDependencies?.diyOrDifmChoice ) {
return navigate( hasSite ? 'new-or-existing-site' : 'setup' );
} else if ( providedDependencies?.nextStep === 'thank-you' ) {
return navigate( 'thank-you' );
}
// TODO: add VIP flow
return navigate( 'schedule-appointment' );
ouikhuan marked this conversation as resolved.
Show resolved Hide resolved
case 'schedule-appointment':
return navigate( 'thank-you' );
case 'new-or-existing-site':
if ( 'new-site' === providedDependencies?.newExistingSiteChoice ) {
return navigate( 'setup' );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useCallback, useEffect } from 'react';

const CALENDLY_SCRIPT_URL = 'https://assets.calendly.com/assets/external/widget.js';

declare global {
interface Window {
Calendly: any;
}
}

type CalendlyPrefillData = {
name?: string;
email?: string;
// Add other prefill fields as needed
};

type CalendlyProps = {
url: string;
id?: string;
prefill?: CalendlyPrefillData;
hideLandingPageDetails?: boolean;
hideEventTypeDetails?: boolean;
hideGdprBanner?: boolean;
onSchedule?: () => void;
onCalendlyViewed?: () => void;
};

function isCalendlyEvent( e: MessageEvent ): boolean {
return (
e.origin === 'https://calendly.com' && e.data.event && e.data.event.indexOf( 'calendly.' ) === 0
);
}

export function useCalendlyWidget( props: CalendlyProps ) {
const {
url,
prefill,
hideLandingPageDetails,
hideEventTypeDetails,
hideGdprBanner,
onSchedule,
onCalendlyViewed,
} = props;

/**
* Load the Calendly <script>
*/
const loadCalendlyScript = useCallback( () => {
// Check if the script is already loaded
if ( ! document.querySelector( `script[src="${ CALENDLY_SCRIPT_URL }"]` ) ) {
const script = document.createElement( 'script' );
script.src = CALENDLY_SCRIPT_URL;
script.async = true;
document.body.appendChild( script );
}
}, [ CALENDLY_SCRIPT_URL ] );

/**
* Remove the Calendly <script>
*/
const removeCalendlyScript = useCallback( () => {
const existingScript = document.querySelector( `script[src="${ CALENDLY_SCRIPT_URL }"]` );
existingScript?.remove();
}, [ CALENDLY_SCRIPT_URL ] );

/**
* Load the Calendly <script> on mount and remove it on unmount
*/
useEffect( () => {
loadCalendlyScript();
return removeCalendlyScript;
}, [ url ] );

/**
* Listen for Calendly events
*/
useEffect( () => {
const handleMessage = ( e: MessageEvent ) => {
if ( isCalendlyEvent( e ) && e.data.event === 'calendly.event_scheduled' ) {
onSchedule?.();
} else if ( isCalendlyEvent( e ) && e.data.event === 'calendly.event_type_viewed' ) {
onCalendlyViewed?.();
}
};

window.addEventListener( 'message', handleMessage );
return () => window.removeEventListener( 'message', handleMessage );
}, [ onSchedule, onCalendlyViewed ] );

/**
* Open the Calendly popup widget
*/
const openCalendlyPopup = useCallback( () => {
const queryParams = new URLSearchParams();

queryParams.set( 'primary_color', '000000' );
queryParams.set( 'hide_gdpr_banner', hideGdprBanner ? '1' : '0' );
queryParams.set( 'hide_event_type_details', hideEventTypeDetails ? '1' : '0' );
queryParams.set( 'hide_landing_page_details', hideLandingPageDetails ? '1' : '0' );

window?.Calendly?.initPopupWidget( {
url: `https://calendly.com/${ url }?${ queryParams.toString() }`,
prefill: prefill || {},
utm: {},
} );
}, [ url, prefill, hideLandingPageDetails, hideEventTypeDetails, hideGdprBanner ] );

/**
* Close the Calendly popup widget
*/
const closeCalendlyPopup = useCallback( () => {
window?.Calendly?.closePopupWidget();
}, [ url ] );

return {
openCalendlyPopup,
closeCalendlyPopup,
};
}

This file was deleted.

This file was deleted.

Loading
Loading