diff --git a/.vscode/settings.json b/.vscode/settings.json index 8dce37f62..ef16de1a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "digmathon", "digmo", "dont", + "drilldowns", "hotspot", "leaderboard", "precommit", diff --git a/public/images/promotion/early-access/collapsedContainerBackground.svg b/public/images/promotion/early-access/collapsedContainerBackground.svg new file mode 100644 index 000000000..e16c8423b --- /dev/null +++ b/public/images/promotion/early-access/collapsedContainerBackground.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/images/promotion/early-access/promotionLogo.svg b/public/images/promotion/early-access/promotionLogo.svg new file mode 100644 index 000000000..d276c21fe --- /dev/null +++ b/public/images/promotion/early-access/promotionLogo.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/promotion/early-access/registrationPromoLogo.svg b/public/images/promotion/early-access/registrationPromoLogo.svg new file mode 100644 index 000000000..dfaaf5c8c --- /dev/null +++ b/public/images/promotion/early-access/registrationPromoLogo.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/promotion/early-access/registrationPromoSuccess_dark.svg b/public/images/promotion/early-access/registrationPromoSuccess_dark.svg new file mode 100644 index 000000000..fd97848ad --- /dev/null +++ b/public/images/promotion/early-access/registrationPromoSuccess_dark.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/promotion/early-access/registrationPromoSuccess_light.svg b/public/images/promotion/early-access/registrationPromoSuccess_light.svg new file mode 100644 index 000000000..0fea2dc33 --- /dev/null +++ b/public/images/promotion/early-access/registrationPromoSuccess_light.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/promotion/collapsedContainerBackground.svg b/public/images/promotion/udemy/collapsedContainerBackground.svg similarity index 100% rename from public/images/promotion/collapsedContainerBackground.svg rename to public/images/promotion/udemy/collapsedContainerBackground.svg diff --git a/public/images/promotion/collapsedContainerEllipseShadow.svg b/public/images/promotion/udemy/collapsedContainerEllipseShadow.svg similarity index 100% rename from public/images/promotion/collapsedContainerEllipseShadow.svg rename to public/images/promotion/udemy/collapsedContainerEllipseShadow.svg diff --git a/public/images/promotion/promotionLogo.svg b/public/images/promotion/udemy/promotionLogo.svg similarity index 100% rename from public/images/promotion/promotionLogo.svg rename to public/images/promotion/udemy/promotionLogo.svg diff --git a/public/images/promotion/promotionLogoWithShadow.svg b/public/images/promotion/udemy/promotionLogoWithShadow.svg similarity index 100% rename from public/images/promotion/promotionLogoWithShadow.svg rename to public/images/promotion/udemy/promotionLogoWithShadow.svg diff --git a/public/images/promotion/registrationPromoLogo_dark.svg b/public/images/promotion/udemy/registrationPromoLogo_dark.svg similarity index 100% rename from public/images/promotion/registrationPromoLogo_dark.svg rename to public/images/promotion/udemy/registrationPromoLogo_dark.svg diff --git a/public/images/promotion/registrationPromoLogo_light.svg b/public/images/promotion/udemy/registrationPromoLogo_light.svg similarity index 100% rename from public/images/promotion/registrationPromoLogo_light.svg rename to public/images/promotion/udemy/registrationPromoLogo_light.svg diff --git a/public/images/promotion/registrationPromoSuccess_dark.svg b/public/images/promotion/udemy/registrationPromoSuccess_dark.svg similarity index 100% rename from public/images/promotion/registrationPromoSuccess_dark.svg rename to public/images/promotion/udemy/registrationPromoSuccess_dark.svg diff --git a/public/images/promotion/registrationPromoSuccess_light.svg b/public/images/promotion/udemy/registrationPromoSuccess_light.svg similarity index 100% rename from public/images/promotion/registrationPromoSuccess_light.svg rename to public/images/promotion/udemy/registrationPromoSuccess_light.svg diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/index.tsx b/src/components/Insights/InsightsCatalog/PromotionCard/index.tsx deleted file mode 100644 index dcedab471..000000000 --- a/src/components/Insights/InsightsCatalog/PromotionCard/index.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { useState } from "react"; -import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; -import { Link } from "../../../common/Link"; -import { CrossIcon } from "../../../common/icons/CrossIcon"; -import { trackingEvents } from "../../tracking"; -import { PromotionTag } from "./PromotionTag"; -import * as s from "./styles"; -import { PromotionCardProps } from "./types"; - -export const PromotionCard = ({ onAccept, onDiscard }: PromotionCardProps) => { - const [expanded, setExpanded] = useState(false); - - const handleDontShowButtonClick = () => { - onDiscard(); - }; - - const handleAccessCourseButtonClick = () => { - onAccept(); - }; - - const handleCollapseClick = () => { - sendUserActionTrackingEvent( - trackingEvents.PROMOTION_CLOSE_EXPANDED_VIEW_BUTTON_CLICKED - ); - setExpanded(false); - }; - - const handleExpandClick = () => { - sendUserActionTrackingEvent( - trackingEvents.PROMOTION_OPEN_EXPANDED_VIEW_BUTTON_CLICKED - ); - setExpanded(true); - }; - - if (!expanded) { - return ( - - - - - - - - - - Get our Udemy course FREE - - See more - - - ); - } - - return ( - - - - - - - - - - - - - Learn how to get more out of Digma - issues - - - - - - - - - - - ); -}; diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/types.ts b/src/components/Insights/InsightsCatalog/PromotionCard/types.ts deleted file mode 100644 index 1ccc27bb3..000000000 --- a/src/components/Insights/InsightsCatalog/PromotionCard/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface ContainersProps { - $expanded: boolean; -} - -export interface PromotionCardProps { - onDiscard: () => void; - onAccept: () => void; -} diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/EarlyAccessPromotionCard.stories.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/EarlyAccessPromotionCard.stories.tsx new file mode 100644 index 000000000..9bcf827a9 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/EarlyAccessPromotionCard.stories.tsx @@ -0,0 +1,21 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { EarlyAccessPromotionCard } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: + "Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard", + component: EarlyAccessPromotionCard, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: {} +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/index.tsx new file mode 100644 index 000000000..0e2288112 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/index.tsx @@ -0,0 +1,41 @@ +import { PromoText, PromoTextBold } from "../../../styles"; +import { Right } from "../styles"; +import * as s from "./styles"; +import { EarlyAccessPromotionCardProps } from "./types"; + +export const EarlyAccessPromotionCard = ({ + onAccept, + onDiscard +}: EarlyAccessPromotionCardProps) => { + return ( + + Get Digma features early access + + } + collapsedBackground={ + + + + } + background={ + + } + > + + Register to get early + access to Digma + capabilities + + + ); +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/styles.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/styles.ts new file mode 100644 index 000000000..1635d8b67 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/styles.ts @@ -0,0 +1,11 @@ +import styled from "styled-components"; +import { PromotionCard } from ".."; +import { Description } from "../styles"; + +export const StyledDescription = styled(Description)` + height: 91px; +`; + +export const StyledPromotionCard = styled(PromotionCard)` + padding: 16px; +`; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/types.ts new file mode 100644 index 000000000..c1a58c329 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/EarlyAccessPromotionCard/types.ts @@ -0,0 +1,4 @@ +export interface EarlyAccessPromotionCardProps { + onDiscard: () => void; + onAccept: () => void; +} diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionCard.stories.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionCard.stories.tsx similarity index 88% rename from src/components/Insights/InsightsCatalog/PromotionCard/PromotionCard.stories.tsx rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionCard.stories.tsx index b56439e0d..fe426718a 100644 --- a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionCard.stories.tsx +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionCard.stories.tsx @@ -3,7 +3,7 @@ import { PromotionCard } from "."; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Insights/InsightsCatalog/PromotionCard", + title: "Insights/InsightsCatalog/PromotionSection/PromotionCard", component: PromotionCard, parameters: { // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/PromotionTag.stories.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/PromotionTag.stories.tsx similarity index 86% rename from src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/PromotionTag.stories.tsx rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/PromotionTag.stories.tsx index 326b40af8..5fd3424ab 100644 --- a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/PromotionTag.stories.tsx +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/PromotionTag.stories.tsx @@ -3,7 +3,7 @@ import { PromotionTag } from "."; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta: Meta = { - title: "Insights/InsightsCatalog/PromotionCard/PromotionTag", + title: "Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag", component: PromotionTag, parameters: { // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/index.tsx similarity index 77% rename from src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/index.tsx rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/index.tsx index b337b0ef8..0b15b56a3 100644 --- a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/index.tsx +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/index.tsx @@ -1,4 +1,4 @@ -import { AffectIcon } from "../../../../common/icons/12px/AffectIcon"; +import { AffectIcon } from "../../../../../common/icons/12px/AffectIcon"; import * as s from "./styles"; export const PromotionTag = () => { diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/styles.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/styles.ts similarity index 88% rename from src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/styles.ts rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/styles.ts index eb8770910..525d7b802 100644 --- a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/styles.ts +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/styles.ts @@ -1,5 +1,5 @@ import styled from "styled-components"; -import { caption2BoldTypography } from "../../../../common/App/typographies"; +import { caption2BoldTypography } from "../../../../../common/App/typographies"; export const Container = styled.div` width: fit-content; diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/types.ts similarity index 100% rename from src/components/Insights/InsightsCatalog/PromotionCard/PromotionTag/types.ts rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/PromotionTag/types.ts diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/UdemyCoursePromotionCard.stories.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/UdemyCoursePromotionCard.stories.tsx new file mode 100644 index 000000000..0aabb1318 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/UdemyCoursePromotionCard.stories.tsx @@ -0,0 +1,21 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { UdemyCoursePromotionCard } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: + "Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard", + component: UdemyCoursePromotionCard, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: {} +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/index.tsx new file mode 100644 index 000000000..214b3816b --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/index.tsx @@ -0,0 +1,55 @@ +import { PromotionCard } from ".."; +import { PromoText, PromoTextBold } from "../../../styles"; +import { PromotionTag } from "../PromotionTag"; +import { Centered, Description, Right } from "../styles"; +import * as s from "./styles"; +import { UdemyCoursePromotionCardProps } from "./types"; + +const UdemyPromotionCollapsedBackground = () => ( + <> + + + + + + + +); + +const UdemyPromotionBackground = () => ( + <> + + + + + +); + +export const UdemyCoursePromotionCard = ({ + onAccept, + onDiscard +}: UdemyCoursePromotionCardProps) => { + return ( + + Get our Udemy course FREE + + } + collapsedBackground={} + background={} + > + + + Learn how to get more out of Digma + issues + + + ); +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/styles.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/styles.ts new file mode 100644 index 000000000..09c95f1cc --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/styles.ts @@ -0,0 +1,12 @@ +import styled, { keyframes } from "styled-components"; + +const blurAnimation = keyframes` + 0% { opacity: 0; } + 100% { opacity: 1; } +`; + +export const AnimatedPromotionBackground = styled.div` + position: absolute; + top: 0; + animation: 1s ${blurAnimation} linear infinite alternate; +`; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/types.ts new file mode 100644 index 000000000..10d504886 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/UdemyCoursePromotionCard/types.ts @@ -0,0 +1,4 @@ +export interface UdemyCoursePromotionCardProps { + onDiscard: () => void; + onAccept: () => void; +} diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/index.tsx new file mode 100644 index 000000000..1560a56c6 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/index.tsx @@ -0,0 +1,90 @@ +import { ForwardedRef, forwardRef, useState } from "react"; +import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent"; +import { Link } from "../../../../common/Link"; +import { CrossIcon } from "../../../../common/icons/CrossIcon"; +import { trackingEvents } from "../../../tracking"; +import * as s from "./styles"; +import { PromotionCardProps } from "./types"; + +const PromotionCardComponent = ( + { + onAccept, + onDiscard, + acceptBtnText, + children, + title, + background, + collapsedBackground, + className, + scope + }: PromotionCardProps, + ref: ForwardedRef +) => { + const [expanded, setExpanded] = useState(false); + + const handleDontShowButtonClick = () => { + onDiscard(); + }; + + const handleAcceptPromotionButtonClick = () => { + onAccept(); + }; + + const handleCollapseClick = () => { + sendUserActionTrackingEvent( + trackingEvents.PROMOTION_CLOSE_EXPANDED_VIEW_BUTTON_CLICKED, + { scope } + ); + setExpanded(false); + }; + + const handleExpandClick = () => { + sendUserActionTrackingEvent( + trackingEvents.PROMOTION_OPEN_EXPANDED_VIEW_BUTTON_CLICKED, + { scope } + ); + setExpanded(true); + }; + + if (!expanded) { + return ( + + {collapsedBackground} + + {title} + See more + + + ); + } + + return ( + + {background} + + + {children} + + + + + + + + + ); +}; + +export const PromotionCard = forwardRef(PromotionCardComponent); diff --git a/src/components/Insights/InsightsCatalog/PromotionCard/styles.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/styles.ts similarity index 79% rename from src/components/Insights/InsightsCatalog/PromotionCard/styles.ts rename to src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/styles.ts index 524f5fce0..6ca41acb1 100644 --- a/src/components/Insights/InsightsCatalog/PromotionCard/styles.ts +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/styles.ts @@ -1,9 +1,7 @@ import styled, { keyframes } from "styled-components"; -import { - bodySemiboldTypography, - subheadingSemiboldTypography -} from "../../../common/App/typographies"; -import { Button } from "../../../common/v3/Button"; +import { subheadingSemiboldTypography } from "../../../../common/App/typographies"; +import { Button } from "../../../../common/v3/Button"; +import { NewIconButton } from "../../../../common/v3/NewIconButton"; export const CollapsedContainer = styled.div` display: flex; @@ -17,16 +15,7 @@ export const CollapsedContainer = styled.div` position: relative; `; -export const PromoText = styled.span` - ${bodySemiboldTypography} -`; - -export const PromoTextBold = styled.span` - ${bodySemiboldTypography}; - color: ${({ theme }) => theme.colors.v3.text.link}; -`; - -export const CrossButton = styled(Button)` +export const CrossButton = styled(NewIconButton)` padding: 0; position: absolute; right: 16px; @@ -117,17 +106,17 @@ export const Holder = styled.div` width: 100%; `; +export const CollapsedHolder = styled(Holder)` + display: flex; + justify-content: space-between; +`; + export const Background = styled.div` position: absolute; top: 0; height: 100%; `; -export const CollapsedHolder = styled(Holder)` - display: flex; - justify-content: space-between; -`; - export const Right = styled(Background)` right: 0; overflow: hidden; @@ -138,14 +127,3 @@ export const Centered = styled(Background)` position: absolute; overflow: hidden; `; - -const blurAnimation = keyframes` - 0% { opacity: 0; } - 100% { opacity: 1; } -`; - -export const AnimatedPromotionBackground = styled.div` - position: absolute; - top: 0; - animation: 1s ${blurAnimation} linear infinite alternate; -`; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/types.ts new file mode 100644 index 000000000..04708b103 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/PromotionCard/types.ts @@ -0,0 +1,17 @@ +import { ReactNode } from "react"; + +export interface ContainersProps { + $expanded: boolean; +} + +export interface PromotionCardProps { + onDiscard: () => void; + onAccept: () => void; + acceptBtnText: string; + children: ReactNode; + title: ReactNode; + background: ReactNode; + collapsedBackground: ReactNode; + className?: string; + scope: string; +} diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/EarlyAccessPromotion/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/EarlyAccessPromotion/index.tsx new file mode 100644 index 000000000..61e7fb91e --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/EarlyAccessPromotion/index.tsx @@ -0,0 +1,109 @@ +import { useState } from "react"; +import { createPortal } from "react-dom"; +import { sendUserActionTrackingEvent } from "../../../../../../utils/actions/sendUserActionTrackingEvent"; +import { CancelConfirmation } from "../../../../../common/CancelConfirmation"; +import { MAIN_CONTAINER_ID } from "../../../../../Main"; +import { EarlyAccessRegistrationCard } from "../../../../../Main/RegistrationCard/EarlyAccessRegistrationCard"; +import { MainOverlay } from "../../../../../Main/styles"; +import { trackingEvents as mainTrackingEvents } from "../../../../../Main/tracking"; +import { EarlyAccessPromotionCard } from "../../PromotionCard/EarlyAccessPromotionCard"; +import { PromotionProps } from "../types"; + +export const EarlyAccessPromotion = ({ + onDiscard, + onAccept, + isVisible +}: PromotionProps) => { + const [showDiscardConfirmation, setShowDiscardConfirmation] = useState(false); + const [showRegistration, setShowRegistration] = useState(false); + + const mainContainer = document.getElementById(MAIN_CONTAINER_ID); + + const handleRegistrationComplete = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_REGISTRATION_FORM_SUBMITTED + ); + onAccept(); + }; + + const handleRegistrationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_REGISTRATION_CLOSE_BUTTON_CLICKED + ); + setShowRegistration(false); + }; + + const handlePromotionAccept = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_REGISTRATION_FORM_OPENED + ); + setShowRegistration(true); + }; + + const handlePromotionDiscard = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_DISCARDED + ); + setShowDiscardConfirmation(true); + }; + + const handleConfirmationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED + ); + setShowDiscardConfirmation(false); + }; + + const handleCancelConfirmationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED + ); + setShowDiscardConfirmation(false); + }; + + const handleCancelConfirmationAccept = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.EARLY_ACCESS_PROMOTION_CANCEL_CONFIRMATION_ACCEPT_CLICKED + ); + onDiscard(); + setShowDiscardConfirmation(false); + }; + + return ( + <> + {isVisible && ( + + )} + + {mainContainer && + createPortal( + , + mainContainer + )} + + {mainContainer && + showDiscardConfirmation && + createPortal( + + + , + mainContainer + )} + + ); +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/UdemyPromotion/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/UdemyPromotion/index.tsx new file mode 100644 index 000000000..d5cd8d7fc --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/UdemyPromotion/index.tsx @@ -0,0 +1,105 @@ +import { useState } from "react"; +import { createPortal } from "react-dom"; +import { sendUserActionTrackingEvent } from "../../../../../../utils/actions/sendUserActionTrackingEvent"; +import { CancelConfirmation } from "../../../../../common/CancelConfirmation"; +import { MAIN_CONTAINER_ID } from "../../../../../Main"; +import { UdemyRegistrationCard } from "../../../../../Main/RegistrationCard/UdemyRegistrationCard"; +import { MainOverlay } from "../../../../../Main/styles"; +import { trackingEvents as mainTrackingEvents } from "../../../../../Main/tracking"; +import { UdemyCoursePromotionCard } from "../../PromotionCard/UdemyCoursePromotionCard"; +import { PromotionProps } from "../types"; + +export const UdemyPromotion = ({ + onDiscard, + onAccept, + isVisible +}: PromotionProps) => { + const [showDiscardConfirmation, setShowDiscardConfirmation] = useState(false); + const [showRegistration, setShowRegistration] = useState(false); + + const mainContainer = document.getElementById(MAIN_CONTAINER_ID); + const handleRegistrationComplete = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_REGISTRATION_FORM_SUBMITTED + ); + onAccept(); + }; + + const handleRegistrationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_REGISTRATION_CLOSE_BUTTON_CLICKED + ); + setShowRegistration(false); + }; + + const handlePromotionAccept = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_REGISTRATION_FORM_OPENED + ); + setShowRegistration(true); + }; + + const handlePromotionDiscard = () => { + sendUserActionTrackingEvent(mainTrackingEvents.PROMOTION_DISCARDED); + setShowDiscardConfirmation(true); + }; + + const handleConfirmationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED + ); + setShowDiscardConfirmation(false); + }; + + const handleCancelConfirmationClose = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED + ); + setShowDiscardConfirmation(false); + }; + + const handleCancelConfirmationAccept = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_ACCEPT_CLICKED + ); + onDiscard(); + setShowDiscardConfirmation(false); + }; + return ( + <> + {isVisible && ( + + )} + + {mainContainer && + createPortal( + , + mainContainer + )} + + {mainContainer && + showDiscardConfirmation && + createPortal( + + + , + mainContainer + )} + + ); +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/types.ts new file mode 100644 index 000000000..f6a140c56 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/Promotions/types.ts @@ -0,0 +1,5 @@ +export interface PromotionProps { + onDiscard: () => void; + onAccept: () => void; + isVisible: boolean; +} diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/index.tsx b/src/components/Insights/InsightsCatalog/PromotionSection/index.tsx new file mode 100644 index 000000000..2efb9a3ed --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/index.tsx @@ -0,0 +1,155 @@ +import { useEffect, useState } from "react"; +import { actions as globalActions } from "../../../../actions"; +import { dispatcher } from "../../../../dispatcher"; +import { usePersistence } from "../../../../hooks/usePersistence"; +import { PLUGIN_EVENTS } from "../../../../pluginEvents"; +import { SendPluginEventPayload } from "../../../../types"; +import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; +import { trackingEvents as mainTrackingEvents } from "../../../Main/tracking"; +import { ToolbarRow } from "../styles"; +import { EarlyAccessPromotion } from "./Promotions/EarlyAccessPromotion"; +import { UdemyPromotion } from "./Promotions/UdemyPromotion"; +import { EarlyAccessPromotionDetails, PromotionType } from "./types"; + +const EARLY_ACCESS_PROMOTION_PERSISTENCE_KEY = "EARLY_ACCESS_PROMOTION"; + +const PROMOTION_PERSISTENCE_KEY = "PROMOTION"; +const PROMOTION_COMPLETED_PERSISTENCE_KEY = "PROMOTION_COMPLETED"; +const PROMOTION_INTERVAL_DAYS = 30; +const INTERVAL_BETWEEN_PROMOTIONS_DAYS = 1; + +const isPromotionEnabled = (dismissalDate: number | null | undefined) => { + return dateReachesInterval(PROMOTION_INTERVAL_DAYS, dismissalDate); +}; + +const dateReachesInterval = ( + days: number, + dismissalDate: number | null | undefined +) => { + const interval = days * 24 * 60 * 60 * 1000; // in milliseconds + return !dismissalDate || Math.abs(dismissalDate - Date.now()) > interval; +}; + +export const PromotionSection = () => { + const [showPromotion, setShowPromotion] = useState("udemy"); + + const [earlyAccessPromotionDetails, setEarlyAccessPromotionDetails] = + usePersistence( + EARLY_ACCESS_PROMOTION_PERSISTENCE_KEY, + "application" + ); + + const [udemyPromotionCompleted, setUdemyPromotionCompleted] = + usePersistence(PROMOTION_COMPLETED_PERSISTENCE_KEY, "application"); + const [udemyDismissalDate, setUdemyDismissalDate] = usePersistence( + PROMOTION_PERSISTENCE_KEY, + "application" + ); + + useEffect(() => { + const handlePluginEvent = (data: unknown) => { + const { name } = data as SendPluginEventPayload; + + if (name !== PLUGIN_EVENTS.SHOW_EARLY_ACCESS_PROMOTION) { + return; + } + + if (earlyAccessPromotionDetails?.completionDate) { + return; + } + + if ( + earlyAccessPromotionDetails?.dismissalDate && + !isPromotionEnabled(earlyAccessPromotionDetails.dismissalDate) + ) { + return; + } + + setShowPromotion("early-access"); + }; + + dispatcher.addActionListener( + globalActions.SEND_PLUGIN_EVENT, + handlePluginEvent + ); + + return () => { + dispatcher.removeActionListener( + globalActions.SEND_PLUGIN_EVENT, + handlePluginEvent + ); + }; + }, [ + earlyAccessPromotionDetails?.completionDate, + earlyAccessPromotionDetails?.dismissalDate, + setShowPromotion + ]); + + const handleUdemyRegistrationComplete = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_REGISTRATION_FORM_SUBMITTED, + { source: showPromotion } + ); + setUdemyPromotionCompleted(true); + }; + + const handleEarlyAccessRegistrationComplete = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_REGISTRATION_FORM_SUBMITTED, + { source: showPromotion } + ); + setEarlyAccessPromotionDetails({ + ...earlyAccessPromotionDetails, + isCompleted: true, + completionDate: Date.now() + }); + }; + + const handleCancelConfirmationAccept = () => { + sendUserActionTrackingEvent( + mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_ACCEPT_CLICKED, + { source: showPromotion } + ); + + if (showPromotion === "udemy") { + setUdemyDismissalDate(Date.now()); + } else if (showPromotion === "early-access") { + setEarlyAccessPromotionDetails({ + isCompleted: false, + dismissalDate: Date.now() + }); + } + }; + + const isUdemyPromotionVisible = + !udemyPromotionCompleted && + isPromotionEnabled(udemyDismissalDate) && + showPromotion === "udemy" && + (!earlyAccessPromotionDetails?.isCompleted || + (earlyAccessPromotionDetails.isCompleted && + dateReachesInterval( + INTERVAL_BETWEEN_PROMOTIONS_DAYS, + earlyAccessPromotionDetails.completionDate + ))); + + const isEarlyAccessPromotionIsVisible = + !earlyAccessPromotionDetails?.isCompleted && + showPromotion === "early-access" && + isPromotionEnabled(earlyAccessPromotionDetails?.dismissalDate); + + return ( + + + + + + ); +}; diff --git a/src/components/Insights/InsightsCatalog/PromotionSection/types.ts b/src/components/Insights/InsightsCatalog/PromotionSection/types.ts new file mode 100644 index 000000000..c28c35717 --- /dev/null +++ b/src/components/Insights/InsightsCatalog/PromotionSection/types.ts @@ -0,0 +1,7 @@ +export type PromotionType = "udemy" | "early-access"; + +export interface EarlyAccessPromotionDetails { + dismissalDate?: number; + isCompleted: boolean; + completionDate?: number; +} diff --git a/src/components/Insights/InsightsCatalog/index.tsx b/src/components/Insights/InsightsCatalog/index.tsx index f2a70effc..849df8784 100644 --- a/src/components/Insights/InsightsCatalog/index.tsx +++ b/src/components/Insights/InsightsCatalog/index.tsx @@ -1,9 +1,7 @@ import { useEffect, useState } from "react"; -import { createPortal } from "react-dom"; import { useTheme } from "styled-components"; import { getFeatureFlagValue } from "../../../featureFlags"; import { useDebounce } from "../../../hooks/useDebounce"; -import { usePersistence } from "../../../hooks/usePersistence"; import { usePrevious } from "../../../hooks/usePrevious"; import { useConfigSelector } from "../../../store/config/useConfigSelector"; import { useInsightsSelector } from "../../../store/insights/useInsightsSelector"; @@ -13,11 +11,6 @@ import { isUndefined } from "../../../typeGuards/isUndefined"; import { FeatureFlag } from "../../../types"; import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActionTrackingEvent"; import { formatUnit } from "../../../utils/formatUnit"; -import { MAIN_CONTAINER_ID } from "../../Main"; -import { RegistrationCard } from "../../Main/RegistrationCard"; -import { MainOverlay } from "../../Main/styles"; -import { trackingEvents as mainTrackingEvents } from "../../Main/tracking"; -import { CancelConfirmation } from "../../common/CancelConfirmation"; import { Pagination } from "../../common/Pagination"; import { SearchInput } from "../../common/SearchInput"; import { SortingSelector } from "../../common/SortingSelector"; @@ -36,7 +29,7 @@ import { SelectorEnvironment } from "./EnvironmentSelector/types"; import { FilterButton } from "./FilterButton"; import { FilterPanel } from "./FilterPanel"; import { InsightsPage } from "./InsightsPage"; -import { PromotionCard } from "./PromotionCard"; +import { PromotionSection } from "./PromotionSection"; import * as s from "./styles"; import { InsightFilterType, @@ -51,17 +44,6 @@ const PAGE_SIZE = 10; const isShowUnreadOnly = (filters: InsightFilterType[]) => filters.length === 1 && filters[0] === "unread"; -const PROMOTION_PERSISTENCE_KEY = "PROMOTION"; -const PROMOTION_COMPLETED_PERSISTENCE_KEY = "PROMOTION_COMPLETED"; - -const isPromotionEnabled = (dismissalDate: number | null | undefined) => { - const PROMOTION_INTERVAL = 30 * 24 * 60 * 60 * 1000; // in milliseconds - - return ( - !dismissalDate || Math.abs(dismissalDate - Date.now()) > PROMOTION_INTERVAL - ); -}; - export const InsightsCatalog = ({ onJiraTicketCreate, onRefresh @@ -113,17 +95,8 @@ export const InsightsCatalog = ({ const previousIsMarkingAllAsReadInProgress = usePrevious( isMarkingAllAsReadInProgress ); - const [showRegistration, setShowRegistration] = useState(false); - const [showDiscardConfirmation, setShowDiscardConfirmation] = useState(false); const [isFiltersToolbarVisible, setIsFiltersToolbarVisible] = useState(false); - const [dismissalDate, setDismissalDate] = usePersistence( - PROMOTION_PERSISTENCE_KEY, - "application" - ); - const [promotionCompleted, setPromotionCompleted] = usePersistence( - PROMOTION_COMPLETED_PERSISTENCE_KEY, - "application" - ); + const isServicesFilterEnabled = !scopeSpanCodeObjectId; const appliedFilterCount = @@ -141,55 +114,8 @@ export const InsightsCatalog = ({ ? insightStats?.spanEnvironments ?? [] : environments?.map((x) => ({ environment: x })) ?? []; - const handleRegistrationComplete = () => { - sendUserActionTrackingEvent( - mainTrackingEvents.PROMOTION_REGISTRATION_FORM_SUBMITTED - ); - setPromotionCompleted(true); - }; - - const handleRegistrationClose = () => { - sendUserActionTrackingEvent( - mainTrackingEvents.PROMOTION_REGISTRATION_CLOSE_BUTTON_CLICKED - ); - setShowRegistration(false); - }; - - const handleCancelConfirmationClose = () => { - sendUserActionTrackingEvent( - mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED - ); - setShowDiscardConfirmation(false); - }; - - const handleCancelConfirmationAccept = () => { - sendUserActionTrackingEvent( - mainTrackingEvents.PROMOTION_CANCEL_CONFIRMATION_ACCEPT_CLICKED - ); - setDismissalDate(Date.now()); - setShowDiscardConfirmation(false); - }; - - const handleConfirmationClose = () => { - setShowDiscardConfirmation(false); - }; - - const handlePromotionAccept = () => { - sendUserActionTrackingEvent( - mainTrackingEvents.PROMOTION_REGISTRATION_FORM_OPENED - ); - setShowRegistration(true); - }; - - const handlePromotionDiscard = () => { - sendUserActionTrackingEvent(mainTrackingEvents.PROMOTION_DISCARDED); - setShowDiscardConfirmation(true); - }; - const isIssuesView = insightViewType === "Issues"; - const isPromotionVisible = - isIssuesView && !promotionCompleted && isPromotionEnabled(dismissalDate); const isDismissalViewModeButtonVisible = isIssuesView && (isUndefined(dismissedCount) || dismissedCount > 0); // isUndefined - check for backward compatibility, always show when BE does not return this counter const isMarkingAsReadOptionsEnabled = @@ -206,7 +132,6 @@ export const InsightsCatalog = ({ backendInfo, FeatureFlag.ARE_ISSUES_FILTERS_ENABLED ); - const mainContainer = document.getElementById(MAIN_CONTAINER_ID); const handleRefreshButtonClick = () => { sendUserActionTrackingEvent(trackingEvents.REFRESH_BUTTON_CLICKED, { @@ -331,14 +256,7 @@ export const InsightsCatalog = ({ )} - {isPromotionVisible && ( - - - - )} + {isIssuesView && } {mode === ViewMode.All ? ( <> {filters.length === 1 && ( @@ -429,31 +347,6 @@ export const InsightsCatalog = ({ /> )} - {mainContainer && - showDiscardConfirmation && - createPortal( - - - , - mainContainer - )} - {mainContainer && - createPortal( - , - mainContainer - )} ); }; diff --git a/src/components/Insights/InsightsCatalog/styles.ts b/src/components/Insights/InsightsCatalog/styles.ts index d710c9c8b..ff3fb3a27 100644 --- a/src/components/Insights/InsightsCatalog/styles.ts +++ b/src/components/Insights/InsightsCatalog/styles.ts @@ -1,6 +1,8 @@ import styled from "styled-components"; import { + bodySemiboldTypography, caption1RegularTypography, + subheadingSemiboldTypography, subscriptMediumTypography, subscriptRegularTypography } from "../../common/App/typographies"; @@ -116,3 +118,21 @@ export const ToolbarButtonsContainer = styled.div` align-items: center; margin-left: auto; `; + +export const Description = styled.span` + ${subheadingSemiboldTypography} + + display:flex; + flex-direction: column; + width: 167px; + color: ${({ theme }) => theme.colors.v3.text.primary}; +`; + +export const PromoText = styled.span` + ${bodySemiboldTypography} +`; + +export const PromoTextBold = styled.span` + ${bodySemiboldTypography}; + color: ${({ theme }) => theme.colors.v3.text.link}; +`; diff --git a/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/EarlyAccessRegistrationCard.stories.tsx b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/EarlyAccessRegistrationCard.stories.tsx new file mode 100644 index 000000000..5532a0430 --- /dev/null +++ b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/EarlyAccessRegistrationCard.stories.tsx @@ -0,0 +1,18 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { EarlyAccessRegistrationCard } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Main/RegistrationCard/EarlyAccessRegistrationCard", + component: EarlyAccessRegistrationCard, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/index.tsx b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/index.tsx new file mode 100644 index 000000000..f100e1372 --- /dev/null +++ b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/index.tsx @@ -0,0 +1,36 @@ +import { RegistrationCard } from ".."; +import { SuccessRegistrationImage } from "../Images/SuccessRegistrationImage"; +import * as s from "./styles"; +import { EarlyAccessRegistrationCardPros } from "./types"; + +export const EarlyAccessRegistrationCard = ({ + onClose, + onComplete, + className, + show +}: EarlyAccessRegistrationCardPros) => { + return ( + + } + icon={ + + } + details={ + + Access to Digma exclusive features + We have launched an innovator program to give you early access to new + features, issues detection, UI drilldowns, and more. Sign up before to + get into the list. + + } + /> + ); +}; diff --git a/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/styles.ts b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/styles.ts new file mode 100644 index 000000000..5bfc281d7 --- /dev/null +++ b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/styles.ts @@ -0,0 +1,20 @@ +import styled from "styled-components"; +import { + subheadingSemiboldTypography, + subscriptRegularTypography +} from "../../../common/App/typographies"; + +export const Description = styled.div` + ${subscriptRegularTypography} + + color: ${({ theme }) => theme.colors.v3.text.secondary}; + text-align: center; + display: flex; + flex-direction: column; +`; + +export const Title = styled.div` + ${subheadingSemiboldTypography} + color: ${({ theme }) => theme.colors.v3.text.primary}; + padding: 12px 0; +`; diff --git a/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/types.ts b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/types.ts new file mode 100644 index 000000000..2938017e3 --- /dev/null +++ b/src/components/Main/RegistrationCard/EarlyAccessRegistrationCard/types.ts @@ -0,0 +1,6 @@ +export interface EarlyAccessRegistrationCardPros { + onClose: () => void; + onComplete: () => void; + className?: string; + show?: boolean; +} diff --git a/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage.tsx b/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage.tsx deleted file mode 100644 index 0a3588f2e..000000000 --- a/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { useTheme } from "styled-components"; -import { getThemeKind } from "../../../common/App/styles"; - -export const SuccessRegistrationImage = () => { - const theme = useTheme(); - const themeKind = getThemeKind(theme); - - return ( - - ); -}; diff --git a/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/index.tsx b/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/index.tsx new file mode 100644 index 000000000..11f3c2d2d --- /dev/null +++ b/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/index.tsx @@ -0,0 +1,12 @@ +import { useTheme } from "styled-components"; +import { getThemeKind } from "../../../../common/App/styles"; +import { SuccessRegistrationImageProps } from "./types"; + +export const SuccessRegistrationImage = ({ + basePath +}: SuccessRegistrationImageProps) => { + const theme = useTheme(); + const themeKind = getThemeKind(theme); + + return ; +}; diff --git a/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/types.ts b/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/types.ts new file mode 100644 index 000000000..966bc5e7e --- /dev/null +++ b/src/components/Main/RegistrationCard/Images/SuccessRegistrationImage/types.ts @@ -0,0 +1,3 @@ +export interface SuccessRegistrationImageProps { + basePath: string; +} diff --git a/src/components/Main/RegistrationCard/SuccessRegistration/index.tsx b/src/components/Main/RegistrationCard/SuccessRegistration/index.tsx index ab1f16c01..d58cf65af 100644 --- a/src/components/Main/RegistrationCard/SuccessRegistration/index.tsx +++ b/src/components/Main/RegistrationCard/SuccessRegistration/index.tsx @@ -1,10 +1,10 @@ -import { SuccessRegistrationImage } from "../Images/SuccessRegistrationImage"; import * as s from "./styles"; +import { SuccessRegistrationProps } from "./types"; -export const SuccessRegistration = () => { +export const SuccessRegistration = ({ image }: SuccessRegistrationProps) => { return ( - + {image} Email sent! diff --git a/src/components/Main/RegistrationCard/SuccessRegistration/types.ts b/src/components/Main/RegistrationCard/SuccessRegistration/types.ts new file mode 100644 index 000000000..cbb32d681 --- /dev/null +++ b/src/components/Main/RegistrationCard/SuccessRegistration/types.ts @@ -0,0 +1,5 @@ +import { ReactNode } from "react"; + +export interface SuccessRegistrationProps { + image: ReactNode; +} diff --git a/src/components/Main/RegistrationCard/Images/RegistrationPromoImage.tsx b/src/components/Main/RegistrationCard/UdemyRegistrationCard/Images/RegistrationPromoImage.tsx similarity index 54% rename from src/components/Main/RegistrationCard/Images/RegistrationPromoImage.tsx rename to src/components/Main/RegistrationCard/UdemyRegistrationCard/Images/RegistrationPromoImage.tsx index 186d34fa8..7556dc18b 100644 --- a/src/components/Main/RegistrationCard/Images/RegistrationPromoImage.tsx +++ b/src/components/Main/RegistrationCard/UdemyRegistrationCard/Images/RegistrationPromoImage.tsx @@ -1,11 +1,13 @@ import { useTheme } from "styled-components"; -import { getThemeKind } from "../../../common/App/styles"; +import { getThemeKind } from "../../../../common/App/styles"; export const RegistrationPromoImage = () => { const theme = useTheme(); const themeKind = getThemeKind(theme); return ( - + ); }; diff --git a/src/components/Main/RegistrationCard/UdemyRegistrationCard/UdemyRegistrationCard.stories.tsx b/src/components/Main/RegistrationCard/UdemyRegistrationCard/UdemyRegistrationCard.stories.tsx new file mode 100644 index 000000000..e7983856a --- /dev/null +++ b/src/components/Main/RegistrationCard/UdemyRegistrationCard/UdemyRegistrationCard.stories.tsx @@ -0,0 +1,18 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { UdemyRegistrationCard } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Main/RegistrationCard/UdemyRegistrationCard", + component: UdemyRegistrationCard, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/src/components/Main/RegistrationCard/UdemyRegistrationCard/index.tsx b/src/components/Main/RegistrationCard/UdemyRegistrationCard/index.tsx new file mode 100644 index 000000000..c550797c7 --- /dev/null +++ b/src/components/Main/RegistrationCard/UdemyRegistrationCard/index.tsx @@ -0,0 +1,32 @@ +import { RegistrationCard } from ".."; +import { SuccessRegistrationImage } from "../Images/SuccessRegistrationImage"; +import { RegistrationPromoImage } from "./Images/RegistrationPromoImage"; +import * as s from "./styles"; +import { UdemyRegistrationCardProps } from "./types"; + +export const UdemyRegistrationCard = ({ + onClose, + onComplete, + className, + show +}: UdemyRegistrationCardProps) => { + return ( + + } + scope={"promotion"} + icon={} + details={ + + Enter your email address below, and we will send you instructions to + access the exclusive Digma course on Udemy + + } + /> + ); +}; diff --git a/src/components/Main/RegistrationCard/UdemyRegistrationCard/styles.ts b/src/components/Main/RegistrationCard/UdemyRegistrationCard/styles.ts new file mode 100644 index 000000000..afcd3021b --- /dev/null +++ b/src/components/Main/RegistrationCard/UdemyRegistrationCard/styles.ts @@ -0,0 +1,9 @@ +import styled from "styled-components"; +import { subscriptRegularTypography } from "../../../common/App/typographies"; + +export const Description = styled.div` + ${subscriptRegularTypography} + + color: ${({ theme }) => theme.colors.v3.text.secondary}; + text-align: center; +`; diff --git a/src/components/Main/RegistrationCard/UdemyRegistrationCard/types.ts b/src/components/Main/RegistrationCard/UdemyRegistrationCard/types.ts new file mode 100644 index 000000000..3b194b686 --- /dev/null +++ b/src/components/Main/RegistrationCard/UdemyRegistrationCard/types.ts @@ -0,0 +1,6 @@ +export interface UdemyRegistrationCardProps { + onClose: () => void; + onComplete: () => void; + className?: string; + show?: boolean; +} diff --git a/src/components/Main/RegistrationCard/index.tsx b/src/components/Main/RegistrationCard/index.tsx index e78b38d09..2cfad3563 100644 --- a/src/components/Main/RegistrationCard/index.tsx +++ b/src/components/Main/RegistrationCard/index.tsx @@ -6,9 +6,8 @@ import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActi import { SlackLogoIcon } from "../../common/icons/16px/SlackLogoIcon"; import { CrossIcon } from "../../common/icons/CrossIcon"; import { trackingEvents } from "../tracking"; -import { RegistrationPromoImage } from "./Images/RegistrationPromoImage"; -import { SuccessRegistration } from "./SuccessRegistration"; import * as s from "./styles"; +import { SuccessRegistration } from "./SuccessRegistration"; import { RegistrationCardProps } from "./types"; const TRANSITION_CLASS_NAME = "registration-card"; @@ -18,7 +17,12 @@ export const RegistrationCard = ({ onClose, onComplete, className, - show + show, + icon, + details, + submitBtnText, + successLogo, + scope }: RegistrationCardProps) => { const [showOverlay, setShowOverlay] = useState(false); const [isFormCompleted, setIsFormCompleted] = useState(false); @@ -71,30 +75,26 @@ export const RegistrationCard = ({ ref={registrationCardRef} > {!isFormCompleted ? ( <> -
- -
+
{icon}
- - Enter your email address below, and we will send you - instructions to access the exclusive Digma course on Udemy - + {details} ) : ( - + )} diff --git a/src/components/Main/RegistrationCard/styles.ts b/src/components/Main/RegistrationCard/styles.ts index 6a3ed2445..94b459f57 100644 --- a/src/components/Main/RegistrationCard/styles.ts +++ b/src/components/Main/RegistrationCard/styles.ts @@ -1,13 +1,10 @@ import styled, { css } from "styled-components"; import { LAYERS } from "../../common/App/styles"; -import { - bodyMediumTypography, - subscriptRegularTypography -} from "../../common/App/typographies"; +import { bodyMediumTypography } from "../../common/App/typographies"; import { Overlay } from "../../common/Overlay"; import { RegisterForm } from "../../common/RegisterForm"; -import { Button } from "../../common/v3/Button"; import { Link } from "../../common/v3/Link"; +import { NewIconButton } from "../../common/v3/NewIconButton"; import { AnimatedRegistrationCardProps, StyledOverlayProps } from "./types"; export const Container = styled.div` @@ -43,20 +40,13 @@ export const Container = styled.div` }}; `; -export const CrossButton = styled(Button)` +export const CrossButton = styled(NewIconButton)` padding: 0; position: absolute; top: 16px; right: 9px; `; -export const Description = styled.div` - ${subscriptRegularTypography} - - color: ${({ theme }) => theme.colors.v3.text.secondary}; - text-align: center; -`; - export const FormContainer = styled.div` max-width: 308px; display: flex; diff --git a/src/components/Main/RegistrationCard/types.ts b/src/components/Main/RegistrationCard/types.ts index be173c6bc..757b117ce 100644 --- a/src/components/Main/RegistrationCard/types.ts +++ b/src/components/Main/RegistrationCard/types.ts @@ -1,8 +1,15 @@ +import { ReactNode } from "react"; + export interface RegistrationCardProps { onClose: () => void; onComplete: () => void; className?: string; show?: boolean; + icon: ReactNode; + details: ReactNode; + submitBtnText?: string; + successLogo: ReactNode; + scope: string; } export interface AnimatedRegistrationCardProps { diff --git a/src/components/Main/tracking.ts b/src/components/Main/tracking.ts index bad164eef..9460b1692 100644 --- a/src/components/Main/tracking.ts +++ b/src/components/Main/tracking.ts @@ -20,7 +20,19 @@ export const trackingEvents = addPrefix( LOGIN_SCREEN_VIEWED: "login screen viewed", SCOPE_BAR_EXPAND_BUTTON_CLICKED: "span info expand button clicked", SCOPE_BAR_COLLAPSE_BUTTON_CLICKED: "scope bar collapse button clicked", - SPAN_INFO_COLLAPSE_BUTTON_CLICKED: "span info collapse button clicked" + SPAN_INFO_COLLAPSE_BUTTON_CLICKED: "span info collapse button clicked", + + EARLY_ACCESS_PROMOTION_REGISTRATION_FORM_SUBMITTED: + "early access promotion registration form submitted", + EARLY_ACCESS_PROMOTION_REGISTRATION_CLOSE_BUTTON_CLICKED: + "early access promotion registration close button clicked", + EARLY_ACCESS_PROMOTION_REGISTRATION_FORM_OPENED: + "early access promotion registration form opened", + EARLY_ACCESS_PROMOTION_DISCARDED: "early access promotion discarded", + EARLY_ACCESS_PROMOTION_CANCEL_CONFIRMATION_CLOSE_CLICKED: + "early access promotion cancel confirmation close clicked", + EARLY_ACCESS_PROMOTION_CANCEL_CONFIRMATION_ACCEPT_CLICKED: + "early access promotion cancel confirmation accept clicked" }, " " ); diff --git a/src/pluginEvents.ts b/src/pluginEvents.ts index 5e7678ee6..9274656b3 100644 --- a/src/pluginEvents.ts +++ b/src/pluginEvents.ts @@ -4,5 +4,6 @@ export const PLUGIN_EVENTS = { FIRST_ISSUE_NOTIFICATION_LINK_CLICK: "first issue notification link click", FIRST_IMPORTANT_ISSUE_NOTIFICATION_LINK_CLICK: "first important issue notification link click", - FIRST_ASSET_NOTIFICATION_LINK_CLICK: "first asset notification link click" + FIRST_ASSET_NOTIFICATION_LINK_CLICK: "first asset notification link click", + SHOW_EARLY_ACCESS_PROMOTION: "SHOW_EARLY_ACCESS_PROMOTION" };