-
Notifications
You must be signed in to change notification settings - Fork 898
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
364 add the integration card for google site kit #21946
base: trunk
Are you sure you want to change the base?
Changes from all commits
3d0ba21
a1918eb
cf89cd7
ac117dc
54f73a6
30c5303
efd5482
b052c0b
6ffb2ba
38c1090
65a6732
4230698
be33a54
657eccc
4c3bbdd
5a78940
f4b4f44
47076c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
import { __, sprintf } from "@wordpress/i18n"; | ||
import { CheckIcon, XIcon } from "@heroicons/react/solid"; | ||
import { createInterpolateElement, useCallback } from "@wordpress/element"; | ||
import PropTypes from "prop-types"; | ||
import { SimpleIntegration } from "./simple-integration"; | ||
import { ReactComponent as SiteKitLogo } from "../../images/site-kit-logo.svg"; | ||
import { useToggleState } from "@yoast/ui-library"; | ||
import { SiteKitConsentModal } from "../shared-admin/components"; | ||
|
||
const integration = { | ||
name: "Site Kit by Google", | ||
claim: createInterpolateElement( | ||
sprintf( | ||
/* translators: 1: bold open tag; 2: Site Kit by Google; 3: bold close tag. */ | ||
__( "Get valuable insights with %1$s%2$s%3$s", "wordpress-seo" ), | ||
"<strong>", | ||
"Site Kit by Google", | ||
"</strong>" | ||
), { | ||
strong: <strong />, | ||
} | ||
), | ||
learnMoreLink: "https://yoa.st/integrations-google-site-kit", | ||
logoLink: "https://yoa.st/integrations-google-site-kit", | ||
slug: "google-site-kit", | ||
description: __( "View traffic and search rankings on your dashboard by connecting your Google account.", "wordpress-seo" ), | ||
isPremium: false, | ||
isNew: false, | ||
isMultisiteAvailable: false, | ||
logo: SiteKitLogo, | ||
}; | ||
|
||
const buttonProps = { | ||
install: { | ||
children: sprintf( | ||
/* translators: 1: Site Kit by Google */ | ||
__( "Install %1$s", "wordpress-seo" ), | ||
"Site Kit by Google" | ||
), | ||
as: "a", | ||
href: "/wp-admin/plugin-install.php?s=google%2520site%2520kit&tab=search&type=term", | ||
}, | ||
activate: { | ||
children: sprintf( | ||
/* translators: 1: Site Kit by Google */ | ||
__( "Activate %1$s", "wordpress-seo" ), | ||
"Site Kit by Google" | ||
), | ||
as: "a", | ||
href: "/wp-admin/plugins.php", | ||
}, | ||
setup: { | ||
children: sprintf( | ||
/* translators: 1: Site Kit by Google */ | ||
__( "Set up %1$s", "wordpress-seo" ), | ||
"Site Kit by Google" | ||
), | ||
as: "a", | ||
href: "/wp-admin/admin.php?page=googlesitekit-splash", | ||
}, | ||
connect: { | ||
children: sprintf( | ||
/* translators: 1: Site Kit by Google */ | ||
__( "Connect %1$s", "wordpress-seo" ), | ||
"Site Kit by Google" | ||
), | ||
as: "button", | ||
}, | ||
disconnect: { | ||
children: __( "Disconnect", "wordpress-seo" ), | ||
as: "button", | ||
variant: "secondary", | ||
}, | ||
}; | ||
|
||
/** | ||
* The NotConnected component. | ||
* | ||
* @param {boolean} isConnected Whether the integration is connected. | ||
* @param {boolean} afterSetup Whether the integration has been set up. | ||
* @param {boolean} isActive Whether the integration is active. | ||
* | ||
* @returns {JSX.Element} The NotConnected component. | ||
*/ | ||
const NotConnected = ( { isConnected, afterSetup, isActive } ) => { | ||
return ( ! isConnected || ! afterSetup ) && isActive && <> | ||
<span className="yst-text-slate-700 yst-font-medium"> | ||
{ __( "Not connected", "wordpress-seo" ) } | ||
</span> | ||
<XIcon | ||
className="yst-h-5 yst-w-5 yst-text-red-500 yst-flex-shrink-0" | ||
/> | ||
</>; | ||
}; | ||
|
||
NotConnected.propTypes = { | ||
isConnected: PropTypes.bool.isRequired, | ||
afterSetup: PropTypes.bool.isRequired, | ||
isActive: PropTypes.bool.isRequired, | ||
}; | ||
|
||
/** | ||
* Plugin not detected. | ||
* | ||
* @param {boolean} isActive Whether the integration is active. | ||
* @param {boolean} isInstalled Whether the integration is installed. | ||
* | ||
* @returns {JSX.Element} The PluginNotDetected component. | ||
*/ | ||
const PluginNotDetected = ( { isActive, isInstalled } ) => { | ||
return ( ! isActive || ! isInstalled ) && <> | ||
<span className="yst-text-slate-700 yst-font-medium"> | ||
{ __( "Plugin not detected", "wordpress-seo" ) } | ||
</span> | ||
<XIcon | ||
className="yst-h-5 yst-w-5 yst-text-red-500 yst-flex-shrink-0" | ||
/> | ||
</>; | ||
}; | ||
|
||
PluginNotDetected.propTypes = { | ||
isActive: PropTypes.bool.isRequired, | ||
isInstalled: PropTypes.bool.isRequired, | ||
}; | ||
|
||
/** | ||
* The successfully Connected component. | ||
* | ||
* @param {boolean} isActive Whether the integration is active. | ||
* @param {boolean} afterSetup Whether the integration has been set up. | ||
* @param {boolean} isConnected Whether the integration is connected. | ||
* | ||
* @returns {JSX.Element} The SuccessfullyConnected component. | ||
*/ | ||
const SuccessfullyConnected = ( { isActive, afterSetup, isConnected } ) => { | ||
return isActive && afterSetup && isConnected && <> | ||
<span className="yst-text-slate-700 yst-font-medium"> | ||
{ __( "Successfully connected", "wordpress-seo" ) } | ||
</span> | ||
<CheckIcon | ||
className="yst-h-5 yst-w-5 yst-text-green-400 yst-flex-shrink-0" | ||
/> | ||
</>; | ||
}; | ||
|
||
SuccessfullyConnected.propTypes = { | ||
isActive: PropTypes.bool.isRequired, | ||
afterSetup: PropTypes.bool.isRequired, | ||
isConnected: PropTypes.bool.isRequired, | ||
}; | ||
|
||
/** | ||
* The Site Kit integration component. | ||
* | ||
* @param {boolean} isActive Whether the integration is active. | ||
* @param {boolean} afterSetup Whether the integration has been set up. | ||
* @param {boolean} isInstalled Whether the integration is installed. | ||
* @param {boolean} isConnected Whether the integration is connected. | ||
* | ||
* @returns {WPElement} The Site Kit integration component. | ||
*/ | ||
export const GoogleSiteKitIntegration = ( { isActive, afterSetup, isInstalled, isConnected } ) => { | ||
const [ isModalOpen, toggleModal ] = useToggleState( false ); | ||
|
||
const getButtonProps = useCallback( () => { | ||
switch ( true ) { | ||
case ( ! isInstalled ): | ||
return buttonProps.install; | ||
case ( ! isActive ): | ||
return buttonProps.activate; | ||
case ( ! afterSetup ): | ||
return buttonProps.setup; | ||
case ( ! isConnected ): | ||
return { ...buttonProps.connect, onClick: toggleModal }; | ||
case ( isConnected ): | ||
return buttonProps.disconnect; | ||
} | ||
}, [ isInstalled, isActive, afterSetup, isConnected ] ); | ||
|
||
return ( | ||
<> | ||
<SimpleIntegration | ||
integration={ integration } | ||
isActive={ isInstalled && isActive } | ||
button={ { | ||
className: "yst-mt-6 yst-w-full", | ||
id: "google-site-kit-button", | ||
...getButtonProps( isInstalled, isActive, afterSetup, isConnected ), | ||
} } | ||
> | ||
<SuccessfullyConnected isActive={ isActive } afterSetup={ afterSetup } isConnected={ isConnected } /> | ||
<NotConnected isConnected={ isConnected } afterSetup={ afterSetup } isActive={ isActive } /> | ||
<PluginNotDetected isActive={ isActive } isInstalled={ isInstalled } /> | ||
</SimpleIntegration> | ||
<SiteKitConsentModal isOpen={ isModalOpen } onClose={ toggleModal } /> | ||
</> | ||
); | ||
}; | ||
|
||
GoogleSiteKitIntegration.propTypes = { | ||
isActive: PropTypes.bool.isRequired, | ||
afterSetup: PropTypes.bool.isRequired, | ||
isInstalled: PropTypes.bool.isRequired, | ||
isConnected: PropTypes.bool.isRequired, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,10 +13,11 @@ import { getIsFreeIntegrationOrPremiumAvailable } from "./helper"; | |
* @param {object} integration The integration. | ||
* @param {boolean} isActive The integration state. | ||
* @param {wp.Element} children The child components. | ||
* @param {object} button The button component props. | ||
* | ||
* @returns {WPElement} A card representing an integration. | ||
*/ | ||
export const SimpleIntegration = ( { integration, isActive, children } ) => { | ||
export const SimpleIntegration = ( { integration, isActive, children, button } ) => { | ||
const IntegrationLogo = integration.logo; | ||
|
||
return ( | ||
|
@@ -59,7 +60,7 @@ export const SimpleIntegration = ( { integration, isActive, children } ) => { | |
className="yst-flex yst-items-center yst-mt-3 yst-no-underline yst-font-medium" | ||
target="_blank" | ||
> | ||
Learn more | ||
{ __( "Learn more", "wordpress-seo" ) } | ||
<span className="yst-sr-only"> | ||
{ | ||
/* translators: Hidden accessibility text. */ | ||
|
@@ -68,11 +69,13 @@ export const SimpleIntegration = ( { integration, isActive, children } ) => { | |
</span> | ||
<ArrowSmRightIcon className="yst-h-4 yst-w-4 yst-ms-1 yst-icon-rtl" /> | ||
</Link> } | ||
|
||
{ button && <Button { ...button } /> } | ||
Comment on lines
+72
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Getting less simple by the commit 🙈 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🙃 Any suggestions? |
||
</div> | ||
</Card.Content> | ||
<Card.Footer> | ||
{ ! getIsFreeIntegrationOrPremiumAvailable( integration ) && <Button | ||
id={ `${ integration.name }-upsell-button` } | ||
id={ `${ integration.slug }-upsell-button` } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might this have consequences for automated tests? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, got an approval from Natalia. |
||
type="button" | ||
as="a" | ||
href={ integration.upsellLink } | ||
|
@@ -121,9 +124,11 @@ SimpleIntegration.propTypes = { | |
PropTypes.node, | ||
PropTypes.arrayOf( PropTypes.node ), | ||
] ), | ||
button: PropTypes.object, | ||
}; | ||
|
||
SimpleIntegration.defaultProps = { | ||
isActive: true, | ||
children: [], | ||
button: null, | ||
}; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You expect this to be reused in the dashboard? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Modal } from "@yoast/ui-library"; | ||
import { __ } from "@wordpress/i18n"; | ||
import { PropTypes } from "prop-types"; | ||
|
||
/** | ||
* The Site Kit consent modal component. | ||
* | ||
* @param {boolean} isOpen Whether the modal is open. | ||
* @param {Function} onClose Callback to close the modal. | ||
* | ||
* @returns {JSX.Element} The Site Kit consent modal component. | ||
*/ | ||
export const SiteKitConsentModal = ( { isOpen, onClose } ) => { | ||
return ( | ||
<Modal | ||
isOpen={ isOpen } | ||
onClose={ onClose } | ||
> | ||
<Modal.Panel> | ||
<Modal.Title>{ __( "Connect Site Kit by Google", "wordpress-seo" ) }</Modal.Title> | ||
<Modal.Description> | ||
{ __( "Connect your Google account to view traffic and search rankings on your dashboard.", "wordpress-seo" ) } | ||
</Modal.Description> | ||
</Modal.Panel> | ||
</Modal> | ||
); | ||
}; | ||
|
||
SiteKitConsentModal.propTypes = { | ||
isOpen: PropTypes.bool, | ||
onClose: PropTypes.func, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not translated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the cards names are translated, so I guess we should translate all the rest (or some)?