From e69790fd17a5edee36f1e80bb1ee11d9ca6eb30c Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 23 Feb 2023 15:07:11 +0800 Subject: [PATCH] feat(console): early bird gift (#3177) --- packages/console/src/assets/images/gift.svg | 14 ++++++ .../EarlyBirdGift/GiftModal/index.module.scss | 16 +++++++ .../EarlyBirdGift/GiftModal/index.tsx | 43 ++++++++++++++++++ .../cloud/components/EarlyBirdGift/index.tsx | 31 +++++++++++++ .../components/Reservation/index.module.scss | 31 +++++++++++++ .../cloud/components/Reservation/index.tsx | 45 +++++++++++++++++++ packages/console/src/cloud/constants/index.ts | 1 + .../cloud/pages/Congrats/index.module.scss | 29 ------------ .../src/cloud/pages/Congrats/index.tsx | 31 +++---------- .../components/CardTitle/index.module.scss | 3 ++ .../src/components/CardTitle/index.tsx | 13 +++++- .../src/components/ModalLayout/index.tsx | 4 +- .../AppLayout/components/Topbar/index.tsx | 3 ++ .../de/translation/admin-console/cloud.ts | 8 ++++ .../en/translation/admin-console/cloud.ts | 8 ++++ .../fr/translation/admin-console/cloud.ts | 8 ++++ .../ko/translation/admin-console/cloud.ts | 8 ++++ .../pt-br/translation/admin-console/cloud.ts | 8 ++++ .../pt-pt/translation/admin-console/cloud.ts | 8 ++++ .../tr-tr/translation/admin-console/cloud.ts | 8 ++++ .../zh-cn/translation/admin-console/cloud.ts | 8 ++++ 21 files changed, 271 insertions(+), 57 deletions(-) create mode 100644 packages/console/src/assets/images/gift.svg create mode 100644 packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.module.scss create mode 100644 packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.tsx create mode 100644 packages/console/src/cloud/components/EarlyBirdGift/index.tsx create mode 100644 packages/console/src/cloud/components/Reservation/index.module.scss create mode 100644 packages/console/src/cloud/components/Reservation/index.tsx create mode 100644 packages/console/src/cloud/constants/index.ts diff --git a/packages/console/src/assets/images/gift.svg b/packages/console/src/assets/images/gift.svg new file mode 100644 index 000000000..a02004b54 --- /dev/null +++ b/packages/console/src/assets/images/gift.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.module.scss b/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.module.scss new file mode 100644 index 000000000..d86cc7cb7 --- /dev/null +++ b/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.module.scss @@ -0,0 +1,16 @@ +@use '@/scss/underscore' as _; + +.title { + white-space: normal; +} + +.content { + margin-top: _.unit(-5); + + .description { + font: var(--font-body-2); + color: var(--color-text-secondary); + margin-bottom: _.unit(6); + } +} + diff --git a/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.tsx b/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.tsx new file mode 100644 index 000000000..ab3c69c2a --- /dev/null +++ b/packages/console/src/cloud/components/EarlyBirdGift/GiftModal/index.tsx @@ -0,0 +1,43 @@ +import { useTranslation } from 'react-i18next'; +import ReactModal from 'react-modal'; + +import ModalLayout from '@/components/ModalLayout'; +import * as modalStyles from '@/scss/modal.module.scss'; + +import Reservation from '../../Reservation'; +import * as styles from './index.module.scss'; + +type Props = { + isOpen: boolean; + onClose: () => void; +}; + +const GiftModal = ({ isOpen, onClose }: Props) => { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + + return ( + + +
{t('cloud.gift.description')}
+ +
+
+ ); +}; + +export default GiftModal; diff --git a/packages/console/src/cloud/components/EarlyBirdGift/index.tsx b/packages/console/src/cloud/components/EarlyBirdGift/index.tsx new file mode 100644 index 000000000..c77f0979b --- /dev/null +++ b/packages/console/src/cloud/components/EarlyBirdGift/index.tsx @@ -0,0 +1,31 @@ +import { useState } from 'react'; + +import Gift from '@/assets/images/gift.svg'; +import IconButton from '@/components/IconButton'; + +import GiftModal from './GiftModal'; + +const EarlyBirdGift = () => { + const [isGiftOpen, setIsGiftOpen] = useState(false); + + return ( + <> + { + setIsGiftOpen(true); + }} + > + + + { + setIsGiftOpen(false); + }} + /> + + ); +}; + +export default EarlyBirdGift; diff --git a/packages/console/src/cloud/components/Reservation/index.module.scss b/packages/console/src/cloud/components/Reservation/index.module.scss new file mode 100644 index 000000000..6fb5afbae --- /dev/null +++ b/packages/console/src/cloud/components/Reservation/index.module.scss @@ -0,0 +1,31 @@ +@use '@/scss/underscore' as _; + +.reservation { + width: 100%; + padding: _.unit(3) _.unit(4); + border: 1px solid var(--color-divider); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: space-between; + + .reservationInfo { + display: flex; + align-items: center; + + .reservationIcon { + margin-right: _.unit(4); + flex-shrink: 0; + } + + .reservationTitle { + font: var(--font-title-3); + } + + .reservationDescription { + font: var(--font-body-2); + color: var(--color-text-secondary); + padding-right: _.unit(4); + } + } +} diff --git a/packages/console/src/cloud/components/Reservation/index.tsx b/packages/console/src/cloud/components/Reservation/index.tsx new file mode 100644 index 000000000..664161732 --- /dev/null +++ b/packages/console/src/cloud/components/Reservation/index.tsx @@ -0,0 +1,45 @@ +import type { AdminConsoleKey } from '@logto/phrases'; +import { useTranslation } from 'react-i18next'; + +import Calendar from '@/assets/images/calendar.svg'; +import { reservationLink } from '@/cloud/constants'; +import Button from '@/components/Button'; +import { buildUrl } from '@/utils/url'; + +import * as styles from './index.module.scss'; + +type Props = { + title: AdminConsoleKey; + description: AdminConsoleKey; + reservationButtonTitle: AdminConsoleKey; +}; + +const Reservation = ({ title, description, reservationButtonTitle }: Props) => { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + + return ( +
+
+ +
+
{t(title)}
+
{t(description)}
+
+
+
+ ); +}; + +export default Reservation; diff --git a/packages/console/src/cloud/constants/index.ts b/packages/console/src/cloud/constants/index.ts new file mode 100644 index 000000000..ece6bf4f6 --- /dev/null +++ b/packages/console/src/cloud/constants/index.ts @@ -0,0 +1 @@ +export const reservationLink = 'https://calendly.com/logto/30min'; diff --git a/packages/console/src/cloud/pages/Congrats/index.module.scss b/packages/console/src/cloud/pages/Congrats/index.module.scss index 7b719ec5e..a712f035a 100644 --- a/packages/console/src/cloud/pages/Congrats/index.module.scss +++ b/packages/console/src/cloud/pages/Congrats/index.module.scss @@ -24,32 +24,3 @@ width: 100%; margin: _.unit(8) 0; } - -.reservation { - width: 100%; - padding: _.unit(3) _.unit(4); - border: 1px solid var(--color-divider); - border-radius: 8px; - display: flex; - align-items: center; - justify-content: space-between; - - .reservationInfo { - display: flex; - align-items: center; - - .reservationIcon { - margin-right: _.unit(4); - flex-shrink: 0; - } - - .reservationTitle { - font: var(--font-title-3); - } - - .reservationDescription { - font: var(--font-body-2); - color: var(--color-text-secondary); - } - } -} diff --git a/packages/console/src/cloud/pages/Congrats/index.tsx b/packages/console/src/cloud/pages/Congrats/index.tsx index 1f036efee..0465b6b47 100644 --- a/packages/console/src/cloud/pages/Congrats/index.tsx +++ b/packages/console/src/cloud/pages/Congrats/index.tsx @@ -4,15 +4,14 @@ import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import AirPlay from '@/assets/images/air-play.svg'; -import Calendar from '@/assets/images/calendar.svg'; import GetStarted from '@/assets/images/get-started.svg'; import ActionBar from '@/cloud/components/ActionBar'; +import Reservation from '@/cloud/components/Reservation'; import * as pageLayout from '@/cloud/scss/layout.module.scss'; import Button from '@/components/Button'; import Divider from '@/components/Divider'; import OverlayScrollbar from '@/components/OverlayScrollbar'; import { AppEndpointsContext } from '@/containers/AppEndpointsProvider'; -import { buildUrl } from '@/utils/url'; import { CloudPage } from '../../types'; import { getCloudPagePathname } from '../../utils'; @@ -49,29 +48,11 @@ const Congrats = () => { }} /> -
-
- -
-
{t('cloud.congrats.reserve_title')}
-
- {t('cloud.congrats.reserve_description')} -
-
-
-
+ diff --git a/packages/console/src/components/CardTitle/index.module.scss b/packages/console/src/components/CardTitle/index.module.scss index 5d78d857f..fe55b57cf 100644 --- a/packages/console/src/components/CardTitle/index.module.scss +++ b/packages/console/src/components/CardTitle/index.module.scss @@ -5,6 +5,9 @@ .title { color: var(--color-text); + } + + .titleEllipsis { @include _.text-ellipsis; } diff --git a/packages/console/src/components/CardTitle/index.tsx b/packages/console/src/components/CardTitle/index.tsx index 5e7c78065..aeb8d4319 100644 --- a/packages/console/src/components/CardTitle/index.tsx +++ b/packages/console/src/components/CardTitle/index.tsx @@ -10,18 +10,27 @@ type Props = { title: AdminConsoleKey | ReactElement; subtitle?: AdminConsoleKey | ReactElement; size?: 'small' | 'medium' | 'large'; + isWordWrapEnabled?: boolean; className?: string; }; /** * Always use this component to render CardTitle, with built-in i18n support. */ -const CardTitle = ({ title, subtitle, size = 'large', className }: Props) => { +const CardTitle = ({ + title, + subtitle, + size = 'large', + isWordWrapEnabled = false, + className, +}: Props) => { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); return (
-
{typeof title === 'string' ? t(title) : title}
+
+ {typeof title === 'string' ? t(title) : title} +
{subtitle && (
{typeof subtitle === 'string' ? t(subtitle) : subtitle} diff --git a/packages/console/src/components/ModalLayout/index.tsx b/packages/console/src/components/ModalLayout/index.tsx index 9000f9d66..710dc5295 100644 --- a/packages/console/src/components/ModalLayout/index.tsx +++ b/packages/console/src/components/ModalLayout/index.tsx @@ -18,6 +18,7 @@ type Props = { onClose?: () => void; className?: string; size?: 'medium' | 'large' | 'xlarge'; + isTitleWordWrapEnabled?: boolean; }; const ModalLayout = ({ @@ -28,11 +29,12 @@ const ModalLayout = ({ onClose, className, size = 'medium', + isTitleWordWrapEnabled = false, }: Props) => { return (
- + {onClose && ( { diff --git a/packages/console/src/containers/AppLayout/components/Topbar/index.tsx b/packages/console/src/containers/AppLayout/components/Topbar/index.tsx index 0478b5e7c..bcc4ccd27 100644 --- a/packages/console/src/containers/AppLayout/components/Topbar/index.tsx +++ b/packages/console/src/containers/AppLayout/components/Topbar/index.tsx @@ -2,7 +2,9 @@ import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import Logo from '@/assets/images/logo.svg'; +import EarlyBirdGift from '@/cloud/components/EarlyBirdGift'; import Spacer from '@/components/Spacer'; +import { isCloud } from '@/consts/cloud'; import GetStartedProgress from '@/pages/GetStarted/components/GetStartedProgress'; import UserInfo from '../UserInfo'; @@ -22,6 +24,7 @@ const Topbar = ({ className }: Props) => {
{t('title')}
+ {isCloud && }
); diff --git a/packages/phrases/src/locales/de/translation/admin-console/cloud.ts b/packages/phrases/src/locales/de/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/en/translation/admin-console/cloud.ts b/packages/phrases/src/locales/en/translation/admin-console/cloud.ts index 13dbacd0b..a259ee09a 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', enter_admin_console: 'Enter Admin Console', }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', + description: 'Book a one-on-one session with our team for early credit and use case sharing.', + reserve_title: 'Reserve your time with Logto team', + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', + book_button: 'Book', + }, }; export default cloud; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts b/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts b/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts index ee770cdec..a9f30732a 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/cloud.ts @@ -59,6 +59,14 @@ const cloud = { discord_link: 'discord channel', // UNTRANSLATED enter_admin_console: 'Enter Admin Console', // UNTRANSLATED }, + gift: { + title: 'Secure early credit for Logto SaaS join the front-runners now !', // UNTRANSLATED + description: 'Book a one-on-one session with our team for early credit and use case sharing.', // UNTRANSLATED + reserve_title: 'Reserve your time with Logto team', // UNTRANSLATED + reserve_description: + 'You can also save the calendar link. We’re always available to assist you.', // UNTRANSLATED + book_button: 'Book', // UNTRANSLATED + }, }; export default cloud;