overleaf/services/web/frontend/js/features/onboarding/components/onboarding-video-tour-modal.tsx
M Fahru f7131b720b Implement onboarding video tour split test (#11889)
* Implement onboarding video tour split test:

- Add split test infrastructure
- Create new `OnboardingVideoTourModal` component
- Place the component inside the editor pug template with a split test

* add event segmentation for `onboarding-video-tour-close-button-click` event:

1. video: `first` | `second`
2. firstVideoWatchingTimeInSecond: total time watching first video
2. secondVideoWatchingTimeInSecond: total time watching second video (0 if skipped)

* add event segmentation for:

1.  `onboarding-video-tour-dismiss-button-click`
2. `onboarding-video-tour-next-button-click`
3. `onboarding-video-tour-done-button-click`

with these key/value:

1. firstVideoWatchingTimeInSecond: total time watching first video
2. secondVideoWatchingTimeInSecond: total time watching second video (0 if skipped/not watched yet)

* Use contentful to host video assets

GitOrigin-RevId: 27a6f38d15d7a03b07455e216dda63d99983ca80
2023-03-02 09:05:43 +00:00

75 lines
2.4 KiB
TypeScript

import { memo, useCallback, useEffect, useRef, useState } from 'react'
import { Modal } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import AccessibleModal from '../../../shared/components/accessible-modal'
import customLocalStorage from '../../../infrastructure/local-storage'
import { sendMB } from '../../../infrastructure/event-tracking'
import OnboardingVideoTourModalBody from './onboarding-video-tour-modal-body'
import type { OnboardingVideoStep } from '../utils/onboarding-video-step'
import OnboardingVideoTourModalFooter from './onboarding-video-tour-modal-footer'
import { calculateWatchingTimeInSecond } from '../utils/watching-time'
import type { Nullable } from '../../../../../types/utils'
type OnboardingVideoTourModalProps = {
show: boolean
closeModal: () => void
}
function OnboardingVideoTourModal({
show,
closeModal,
}: OnboardingVideoTourModalProps) {
const { t } = useTranslation()
const [step, setStep] = useState<OnboardingVideoStep>('first')
const startTimeWatchedFirstVideo = useRef(Date.now())
const startTimeWatchedSecondVideo = useRef<Nullable<number>>(null)
const handleClickCloseButton = useCallback(() => {
customLocalStorage.setItem(
'has_dismissed_onboarding_video_tour_modal',
true
)
const { firstVideoWatchingTimeInSecond, secondVideoWatchingTimeInSecond } =
calculateWatchingTimeInSecond(
startTimeWatchedFirstVideo.current,
startTimeWatchedSecondVideo.current
)
sendMB('onboarding-video-tour-close-button-click', {
video: step,
firstVideoWatchingTimeInSecond,
secondVideoWatchingTimeInSecond,
})
closeModal()
}, [closeModal, step])
useEffect(() => {
if (step === 'second') {
startTimeWatchedSecondVideo.current = Date.now()
}
}, [step])
return (
<AccessibleModal
onHide={handleClickCloseButton}
show={show}
backdrop="static"
>
<Modal.Header closeButton>
<Modal.Title>{t('welcome_to_your_first_project')}</Modal.Title>
</Modal.Header>
<OnboardingVideoTourModalBody step={step} />
<OnboardingVideoTourModalFooter
step={step}
setStep={setStep}
closeModal={closeModal}
startTimeWatchedFirstVideo={startTimeWatchedFirstVideo}
startTimeWatchedSecondVideo={startTimeWatchedSecondVideo}
/>
</AccessibleModal>
)
}
export default memo(OnboardingVideoTourModal)