diff --git a/packages/core/admin/admin/src/assets/images/big-logo-home.png b/packages/core/admin/admin/src/assets/images/big-logo-home.png new file mode 100644 index 0000000000..d611ed8b8a Binary files /dev/null and b/packages/core/admin/admin/src/assets/images/big-logo-home.png differ diff --git a/packages/core/admin/admin/src/assets/images/hot-air-balloon.png b/packages/core/admin/admin/src/assets/images/hot-air-balloon.png new file mode 100644 index 0000000000..9d2c49e704 Binary files /dev/null and b/packages/core/admin/admin/src/assets/images/hot-air-balloon.png differ diff --git a/packages/core/admin/admin/src/assets/images/upgrade-details.png b/packages/core/admin/admin/src/assets/images/upgrade-details.png new file mode 100644 index 0000000000..45d0dd8f7e Binary files /dev/null and b/packages/core/admin/admin/src/assets/images/upgrade-details.png differ diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal /index.js b/packages/core/admin/admin/src/components/UpgradePlanModal /index.js new file mode 100644 index 0000000000..54da903ed4 --- /dev/null +++ b/packages/core/admin/admin/src/components/UpgradePlanModal /index.js @@ -0,0 +1,126 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import styled from 'styled-components'; +import { useIntl } from 'react-intl'; +import { Portal } from '@strapi/parts/Portal'; +import { FocusTrap } from '@strapi/parts/FocusTrap'; +import { IconButton } from '@strapi/parts/IconButton'; +import { LinkButton } from '@strapi/parts/LinkButton'; +import { Box } from '@strapi/parts/Box'; +import { Row } from '@strapi/parts/Row'; +import { Text, H1 } from '@strapi/parts/Text'; +import { Stack } from '@strapi/parts/Stack'; +import ExternalLink from '@strapi/icons/ExternalLink'; +import CloseAlertIcon from '@strapi/icons/CloseAlertIcon'; +import { setHexOpacity, useLockScroll } from '@strapi/helper-plugin'; +import AirBalloon from '../../assets/images/hot-air-balloon.png'; +import BigArrow from '../../assets/images/upgrade-details.png'; + +const UpgradeWrapper = styled.div` + position: absolute; + z-index: 3; + inset: 0; + background: ${({ theme }) => setHexOpacity(theme.colors.neutral800, 0.2)}; + padding: 0 ${({ theme }) => theme.spaces[8]}; +`; + +const UpgradeContainer = styled(Row)` + position: relative; + max-width: ${830 / 16}rem; + height: ${415 / 16}rem; + margin: 0 auto; + overflow: hidden; + margin-top: 10%; + padding-left: ${64 / 16}rem; + + img:first-of-type { + position: absolute; + right: 0; + top: 0; + max-width: ${360 / 16}rem; + } + + img:not(:first-of-type) { + width: ${130 / 16}rem; + margin-left: 12%; + margin-right: ${20 / 16}rem; + z-index: 0; + } +`; + +const TextBold = styled(Text)` + font-weight: 700; +`; + +const StackFlexStart = styled(Stack)` + align-items: flex-start; + max-width: ${400 / 16}rem; + z-index: 0; +`; + +const CloseButtonContainer = styled(Box)` + position: absolute; + right: ${({ theme }) => theme.spaces[4]}; + top: ${({ theme }) => theme.spaces[4]}; +`; + +const UpgradePlanModal = ({ onClose, isOpen }) => { + useLockScroll(isOpen); + const { formatMessage } = useIntl(); + + if (!isOpen) { + return null; + } + + return ( + + + + + air-balloon + + } /> + + + + {formatMessage({ + id: 'app.components.UpgradePlanModal.text-ce', + defaultMessage: 'COMMUNITY EDITION', + })} + + +

+ {formatMessage({ + id: 'app.components.UpgradePlanModal.limit-reached', + defaultMessage: 'You have reached the limit', + })} +

+ + {formatMessage({ + id: 'app.components.UpgradePlanModal.text-power', + defaultMessage: + 'Unlock the full power of Strapi by upgrading your plan to the Enterprise Edition', + })} + +
+ }> + {formatMessage({ + id: 'app.components.UpgradePlanModal.button', + defaultMessage: 'Learn more', + })} + +
+ upgrade-arrow +
+
+
+
+ ); +}; + +UpgradePlanModal.propTypes = { + onClose: PropTypes.func.isRequired, + isOpen: PropTypes.bool.isRequired, +}; + +export default UpgradePlanModal; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal /tests/index.test.js b/packages/core/admin/admin/src/components/UpgradePlanModal /tests/index.test.js new file mode 100644 index 0000000000..1ad2d47659 --- /dev/null +++ b/packages/core/admin/admin/src/components/UpgradePlanModal /tests/index.test.js @@ -0,0 +1,63 @@ +import React from 'react'; +import { render, screen, waitFor } from '@testing-library/react'; +import { IntlProvider } from 'react-intl'; +import { ThemeProvider, lightTheme } from '@strapi/parts'; +import UpgradePlanModal from '../index'; + +const App = ( + + + + + +); + +describe('UpgradePlanModal', () => { + it('renders and matches the snapshot', async () => { + const { + container: { firstChild }, + } = render(App); + + expect(firstChild).toMatchInlineSnapshot(` + .c0 { + border: 0; + -webkit-clip: rect(0 0 0 0); + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + } + +
+

+

+

+ `); + }); + + it('renders and matches the snapshot', async () => { + render(App); + + await waitFor(() => { + expect(screen.getByText('You have reached the limit')).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/arrow.png b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/arrow.png deleted file mode 100644 index 9b714890b5..0000000000 Binary files a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/arrow.png and /dev/null differ diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/index.js deleted file mode 100644 index ce3a889796..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Arrow/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import styled from 'styled-components'; -import logo from './arrow.png'; - -const Img = styled.img` - position: absolute; - top: 130px; - right: 195px; - height: 82px; -`; - -Img.defaultProps = { - alt: 'arrow', - src: logo, -}; - -export default Img; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Download/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Download/index.js deleted file mode 100644 index 1a214925f4..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Download/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import styled from 'styled-components'; - -const Download = styled(FontAwesomeIcon)` - margin-left: 10px; - transform: rotate(-45deg); -`; - -Download.defaultProps = { - icon: 'arrow-right', -}; - -export default Download; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/Wrapper.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/Wrapper.js deleted file mode 100644 index 998d72a49c..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/Wrapper.js +++ /dev/null @@ -1,12 +0,0 @@ -import styled from 'styled-components'; - -const Wrapper = styled.div` - height: 25px; - max-width: fit-content; - padding: 0 15px; - background: rgba(0, 126, 255, 0.08); - border: 1px solid rgba(0, 126, 255, 0.24); - border-radius: 2px; -`; - -export default Wrapper; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/index.js deleted file mode 100644 index 41c2ce0409..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Option/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Text } from '@buffetjs/core'; -import { useIntl } from 'react-intl'; -import Wrapper from './Wrapper'; - -const Option = () => { - const { formatMessage } = useIntl(); - - return ( - - - {formatMessage({ id: 'app.components.UpgradePlanModal.text-ce' })} - - - ); -}; - -export default Option; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/balloon.png b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/balloon.png deleted file mode 100644 index df4dac9914..0000000000 Binary files a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/balloon.png and /dev/null differ diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/index.js deleted file mode 100644 index 7ee97288e2..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/Wrapper/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import styled from 'styled-components'; -import Balloon from './balloon.png'; - -const Wrapper = styled.div` - height: 390px; - width: 100%; - padding-top: 89px; - padding-left: 65px; - background-image: url(${Balloon}); - background-size: contain; - background-position: right; -`; - -export default Wrapper; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/components/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/components/index.js deleted file mode 100644 index ca839250ae..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/components/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export { default as Arrow } from './Arrow'; -export { default as Download } from './Download'; -export { default as Option } from './Option'; -export { default as Wrapper } from './Wrapper'; diff --git a/packages/core/admin/admin/src/components/UpgradePlanModal/index.js b/packages/core/admin/admin/src/components/UpgradePlanModal/index.js deleted file mode 100644 index a0efbb4f8b..0000000000 --- a/packages/core/admin/admin/src/components/UpgradePlanModal/index.js +++ /dev/null @@ -1,91 +0,0 @@ -/* eslint-disable jsx-a11y/anchor-has-content */ -/* eslint-disable jsx-a11y/control-has-associated-label */ -import React, { useRef } from 'react'; -import PropTypes from 'prop-types'; -import { Button, Padded, Text } from '@buffetjs/core'; -import { Modal } from '@strapi/helper-plugin'; -import { useIntl } from 'react-intl'; -import { Arrow, Download, Option, Wrapper } from './components'; - -const UpgradePlanModal = ({ isOpen, onToggle }) => { - const ref = useRef(); - const { formatMessage } = useIntl(); - - const handleClick = () => { - ref.current.click(); - }; - - return ( - - - - - - - - - - ); -}; - -UpgradePlanModal.defaultProps = { - isOpen: false, - onToggle: () => {}, -}; - -UpgradePlanModal.propTypes = { - isOpen: PropTypes.bool, - onToggle: PropTypes.func, -}; - -export default UpgradePlanModal; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js index 8fe3fe627b..58882235f2 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/index.js @@ -20,7 +20,7 @@ import { useIntl } from 'react-intl'; import { useHistory } from 'react-router'; import RoleRow from './components/RoleRow'; import EmptyRole from './components/EmptyRole'; -import UpgradePlanModal from '../../../../../components/UpgradePlanModal'; +import UpgradePlanModal from '../../../../../components/UpgradePlanModal '; import { useRolesList } from '../../../../../hooks'; const useSortedRoles = () => { @@ -186,7 +186,7 @@ const RoleListPage = () => { {!rowCount && !isLoading && } - + ); }; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/tests/index.test.js index 0fdf7acc43..0ee121cf2f 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/tests/index.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/Roles/ListPage/tests/index.test.js @@ -400,10 +400,6 @@ describe('', () => { border: none; } - .c37 { - font-family: Lato; - } -
', () => { -
`); }); diff --git a/packages/core/admin/admin/src/translations/en.json b/packages/core/admin/admin/src/translations/en.json index c8467c3356..eab837af3c 100644 --- a/packages/core/admin/admin/src/translations/en.json +++ b/packages/core/admin/admin/src/translations/en.json @@ -279,11 +279,11 @@ "app.components.PluginCard.compatible": "Compatible with your app", "app.components.PluginCard.compatibleCommunity": "Compatible with the community", "app.components.PluginCard.more-details": "More details", - "app.components.UpgradePlanModal.button": "LEARN MORE", + "app.components.UpgradePlanModal.button": "Learn more", "app.components.UpgradePlanModal.limit-reached": "You have reached the limit", - "app.components.UpgradePlanModal.text-ce": "Community Edition", + "app.components.UpgradePlanModal.text-ce": "COMMUNITY EDITION", "app.components.UpgradePlanModal.text-ee": "Enterprise Edition", - "app.components.UpgradePlanModal.text-power": "Unlock the full power", + "app.components.UpgradePlanModal.text-power": "Unlock the full power of Strapi by upgrading your plan to the Enterprise Edition", "app.components.UpgradePlanModal.text-strapi": "of Strapi by upgrading your plan to the", "app.components.Users.MagicLink.connect": "Send this link to the user for them to connect.", "app.components.Users.MagicLink.connect.sso": "Send this link to the user, the first login can be made via a SSO provider", diff --git a/packages/core/helper-plugin/lib/src/hooks/useLockScroll/index.js b/packages/core/helper-plugin/lib/src/hooks/useLockScroll/index.js new file mode 100644 index 0000000000..cb736b3a83 --- /dev/null +++ b/packages/core/helper-plugin/lib/src/hooks/useLockScroll/index.js @@ -0,0 +1,15 @@ +import { useEffect } from 'react'; + +const useLockScroll = lockScroll => { + useEffect(() => { + if (lockScroll) { + document.body.classList.add('lock-body-scroll'); + } + + return () => { + document.body.classList.remove('lock-body-scroll'); + }; + }, [lockScroll]); +}; + +export default useLockScroll; diff --git a/packages/core/helper-plugin/lib/src/hooks/useLockScroll/useLockScroll.stories.mdx b/packages/core/helper-plugin/lib/src/hooks/useLockScroll/useLockScroll.stories.mdx new file mode 100644 index 0000000000..f86cfd8fca --- /dev/null +++ b/packages/core/helper-plugin/lib/src/hooks/useLockScroll/useLockScroll.stories.mdx @@ -0,0 +1,36 @@ + + +import { Meta } from '@storybook/addon-docs'; + + + +# useLockScroll + +This hook is used in order to display a notification in the admin panel. + +## Usage + +``` +import { useLockScroll } from '@strapi/helper-plugin'; + +const Modal = ({ onToggle, isOpen }) => { + // boolean required to activate locked scroll when modal is open + useLockScroll(isOpen); + + if (!isOpen) { + return null; + } + + return ( + + + + + Content of the modal + + + + + ); +}; +``` diff --git a/packages/core/helper-plugin/lib/src/index.js b/packages/core/helper-plugin/lib/src/index.js index 3ec222f021..3963c0eb07 100644 --- a/packages/core/helper-plugin/lib/src/index.js +++ b/packages/core/helper-plugin/lib/src/index.js @@ -127,6 +127,7 @@ export { default as useRBACProvider } from './hooks/useRBACProvider'; export { default as useRBAC } from './hooks/useRBAC'; export { default as usePersistentState } from './hooks/usePersistentState'; export { default as useFocusWhenNavigate } from './hooks/useFocusWhenNavigate'; +export { default as useLockScroll } from './hooks/useLockScroll'; // Providers export { default as LibraryProvider } from './providers/LibraryProvider'; @@ -164,6 +165,9 @@ export { default as prefixPluginTranslations } from './old/utils/prefixPluginTra export { default as pxToRem } from './utils/pxToRem'; export { default as to } from './utils/await-to-js'; +// NEW UTILS +export { default as setHexOpacity } from './utils/setHexOpacity'; + // SVGS export { default as LayoutIcon } from './old/svgs/Layout'; export { default as ClearIcon } from './old/svgs/Clear'; diff --git a/packages/core/helper-plugin/lib/src/utils/setHexOpacity/index.js b/packages/core/helper-plugin/lib/src/utils/setHexOpacity/index.js new file mode 100644 index 0000000000..ee6d647d5e --- /dev/null +++ b/packages/core/helper-plugin/lib/src/utils/setHexOpacity/index.js @@ -0,0 +1,6 @@ +const setHexOpacity = (hex, alpha) => + `${hex}${Math.floor(alpha * 255) + .toString(16) + .padStart(2, 0)}`; + +export default setHexOpacity; diff --git a/packages/core/helper-plugin/lib/src/utils/setHexOpacity/setHexOpacity.stories.mdx b/packages/core/helper-plugin/lib/src/utils/setHexOpacity/setHexOpacity.stories.mdx new file mode 100644 index 0000000000..da9ac3d045 --- /dev/null +++ b/packages/core/helper-plugin/lib/src/utils/setHexOpacity/setHexOpacity.stories.mdx @@ -0,0 +1,23 @@ + + +import { Meta } from '@storybook/addon-docs'; + + + +# setHexOpacity + +This hook is used in order to display a notification in the admin panel. + +## Usage + +``` +import { setHexOpacity } from '@strapi/helper-plugin'; + +const BoxCustom = styled.div` + // using strapi theme hex + background: ${({ theme }) => setHexOpacity(theme.colors.neutral800, 0.2)}; + + // using hex + background: setHexOpacity('#12100E', 0.2)}; +`; +```