import {Fragment, useCallback, useContext, useEffect} from 'react'; import styled from '@emotion/styled'; import type {MotionProps} from 'framer-motion'; import {motion} from 'framer-motion'; import OnboardingInstall from 'sentry-images/spot/onboarding-install.svg'; import OnboardingSetup from 'sentry-images/spot/onboarding-setup.svg'; import {openInviteMembersModal} from 'sentry/actionCreators/modal'; import {Button} from 'sentry/components/button'; import Link from 'sentry/components/links/link'; import {OnboardingContext} from 'sentry/components/onboarding/onboardingContext'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {trackAnalytics} from 'sentry/utils/analytics'; import testableTransition from 'sentry/utils/testableTransition'; import useOrganization from 'sentry/utils/useOrganization'; import FallingError from 'sentry/views/onboarding/components/fallingError'; import WelcomeBackground from 'sentry/views/onboarding/components/welcomeBackground'; import type {StepProps} from './types'; const fadeAway: MotionProps = { variants: { initial: {opacity: 0}, animate: {opacity: 1, filter: 'blur(0px)'}, exit: {opacity: 0, filter: 'blur(1px)'}, }, transition: testableTransition({duration: 0.8}), }; type TextWrapperProps = { cta: React.ReactNode; src: string; subText: React.ReactNode; title: React.ReactNode; }; function InnerAction({title, subText, cta, src}: TextWrapperProps) { return ( {title} {subText} {cta} ); } function TargetedOnboardingWelcome(props: StepProps) { const organization = useOrganization(); const onboardingContext = useContext(OnboardingContext); const source = 'targeted_onboarding'; useEffect(() => { trackAnalytics('growth.onboarding_start_onboarding', { organization, source, }); if (onboardingContext.data.selectedSDK) { // At this point the selectedSDK shall be undefined but just in case, cleaning this up here too onboardingContext.setData({...onboardingContext.data, selectedSDK: undefined}); } }, [organization, onboardingContext]); const handleComplete = useCallback(() => { trackAnalytics('growth.onboarding_clicked_instrument_app', { organization, source, }); props.onComplete(); }, [organization, source, props]); const handleSkipOnboarding = useCallback(() => { trackAnalytics('growth.onboarding_clicked_skip', { organization, source, }); }, [organization, source]); return ( {({fallingError, fallCount, isFalling}) => ( {t('Welcome to Sentry')} {t( 'Your code is probably broken. Maybe not. Find out for sure. Get started below.' )} {t('Start')} {(fallCount === 0 || isFalling) && ( {fallingError} )} } /> {t('friends')}} )} src={OnboardingSetup} cta={ { openInviteMembersModal({source}); }} priority="primary" > {t('Invite Team')} } /> {t("Gee, I've used Sentry before.")}
{t('Skip onboarding.')}
)}
); } export default TargetedOnboardingWelcome; const PositionedFallingError = styled('span')` display: block; position: absolute; right: 0px; top: 30px; `; const Wrapper = styled(motion.div)` position: relative; margin-top: auto; margin-bottom: auto; max-width: 400px; display: flex; flex-direction: column; align-items: center; text-align: center; margin-left: auto; margin-right: auto; h1 { font-size: 42px; } `; const ActionItem = styled(motion.div)` min-height: 120px; border-radius: ${space(0.5)}; padding: ${space(2)}; margin-bottom: ${space(2)}; justify-content: space-around; border: 1px solid ${p => p.theme.gray200}; @media (min-width: ${p => p.theme.breakpoints.small}) { display: grid; grid-template-columns: 125px auto 125px; width: 680px; align-items: center; } @media (max-width: ${p => p.theme.breakpoints.small}) { display: flex; flex-direction: column; } `; const TextWrapper = styled('div')` text-align: left; margin: auto ${space(3)}; min-height: 70px; @media (max-width: ${p => p.theme.breakpoints.small}) { text-align: center; margin: ${space(1)} ${space(1)}; margin-top: ${space(3)}; } `; const Strike = styled('span')` text-decoration: line-through; `; const ActionTitle = styled('h5')` font-weight: 900; margin: 0 0 ${space(0.5)}; color: ${p => p.theme.gray400}; `; const SubText = styled('span')` font-weight: 400; color: ${p => p.theme.gray400}; `; const SubHeaderText = styled(motion.h6)` color: ${p => p.theme.gray300}; `; const ButtonWrapper = styled('div')` margin: ${space(1)}; position: relative; `; const ActionImage = styled('img')` height: 100px; `; const ButtonWithFill = styled(Button)` width: 100%; position: relative; z-index: 1; `;