import { sendSearchEvent } from '@/features/event-tracking/search-events' import OLButton from '@/features/ui/components/ol/ol-button' import OLTooltip from '@/features/ui/components/ol/ol-tooltip' import { useLayoutContext } from '@/shared/context/layout-context' import { closeSearchPanel, SearchQuery } from '@codemirror/search' import { forwardRef, memo, Ref, useCallback, useEffect, useRef } from 'react' import { useCodeMirrorViewContext } from './codemirror-context' import MaterialIcon from '@/shared/components/material-icon' import { useTranslation } from 'react-i18next' import { Overlay, Popover } from 'react-bootstrap' import Close from '@/shared/components/close' import useTutorial from '@/shared/hooks/promotions/use-tutorial' import { useEditorContext } from '@/shared/context/editor-context' import getMeta from '@/utils/meta' import { useIsNewEditorEnabled } from '@/features/ide-redesign/utils/new-editor-utils' import { useRailContext } from '@/features/ide-redesign/contexts/rail-context' const PROMOTION_SIGNUP_CUT_OFF_DATE = new Date('2025-04-22T00:00:00Z') export const FullProjectSearchButton = ({ query }: { query: SearchQuery }) => { const view = useCodeMirrorViewContext() const { t } = useTranslation() const { setProjectSearchIsOpen } = useLayoutContext() const newEditor = useIsNewEditorEnabled() const { openTab } = useRailContext() const ref = useRef(null) const { inactiveTutorials } = useEditorContext() const hasCompletedTutorial = inactiveTutorials.includes( 'full-project-search-promo' ) const { showPopup, tryShowingPopup, hideUntilReload, completeTutorial } = useTutorial('full-project-search-promo', { name: 'full-project-search-promotion', }) let isEligibleForPromotion = true const signUpDateString = getMeta('ol-user')?.signUpDate if (!signUpDateString) { isEligibleForPromotion = false } else { const signupDate = new Date(signUpDateString) if (signupDate > PROMOTION_SIGNUP_CUT_OFF_DATE) { isEligibleForPromotion = false } } const openFullProjectSearch = useCallback(() => { if (newEditor) { openTab('full-project-search') } else { setProjectSearchIsOpen(true) } closeSearchPanel(view) window.setTimeout(() => { window.dispatchEvent( new CustomEvent('editor:full-project-search', { detail: query }) ) }, 200) }, [setProjectSearchIsOpen, query, view, newEditor, openTab]) const onClick = useCallback(() => { sendSearchEvent('search-open', { searchType: 'full-project', method: 'button', location: 'search-form', }) openFullProjectSearch() if (!hasCompletedTutorial && isEligibleForPromotion) { completeTutorial({ action: 'complete', event: 'promo-click' }) } }, [ completeTutorial, openFullProjectSearch, hasCompletedTutorial, isEligibleForPromotion, ]) return ( <> {!hasCompletedTutorial && isEligibleForPromotion && ( )} ) } type PromotionOverlayProps = { showPopup: boolean tryShowingPopup: () => void completeTutorial: (event: { action: 'complete' event: 'promo-dismiss' }) => void hideUntilReload: () => void } const PromotionOverlay = forwardRef( function PromotionOverlay( props: PromotionOverlayProps, ref: Ref ) { if (typeof ref === 'function' || !ref?.current) { return null } return } ) const PromotionContent = memo(function PromotionContent({ showPopup, tryShowingPopup, completeTutorial, hideUntilReload, target, }: PromotionOverlayProps & { target: HTMLButtonElement }) { const { t } = useTranslation() useEffect(() => { tryShowingPopup() }, [tryShowingPopup]) const onHide = useCallback(() => { hideUntilReload() }, [hideUntilReload]) const onClose = useCallback(() => { completeTutorial({ action: 'complete', event: 'promo-dismiss', }) }, [completeTutorial]) return ( {t('now_you_can_search_your_whole_project_not_just_this_file')} ) })