diff --git a/apps/studio/components/layouts/Tabs/NewTab.tsx b/apps/studio/components/layouts/Tabs/NewTab.tsx index ac75688def390..76acb8c3c3550 100644 --- a/apps/studio/components/layouts/Tabs/NewTab.tsx +++ b/apps/studio/components/layouts/Tabs/NewTab.tsx @@ -1,13 +1,12 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' -import dayjs from 'dayjs' import { partition } from 'lodash' import { Table2 } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' -import { useEffect, useMemo, useRef, useState } from 'react' +import { useEffect, useState } from 'react' import { toast } from 'sonner' -import { useParams } from 'common' +import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { SQL_TEMPLATES } from 'components/interfaces/SQLEditor/SQLEditor.queries' import { createSqlSnippetSkeletonV2 } from 'components/interfaces/SQLEditor/SQLEditor.utils' import { QuickstartAIWidget } from 'components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableQuickstart/QuickstartAIWidget' @@ -15,6 +14,7 @@ import { QuickstartTemplatesWidget } from 'components/interfaces/TableGridEditor import { QuickstartVariant } from 'components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableQuickstart/types' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' +import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject' @@ -43,7 +43,6 @@ import { SIDEBAR_KEYS } from '../ProjectLayout/LayoutSidebar/LayoutSidebarProvid import { ActionCard } from './ActionCard' import { RecentItems } from './RecentItems' -const NEW_PROJECT_THRESHOLD_DAYS = 7 const TABLE_QUICKSTART_FLAG = 'tableQuickstart' const ASSISTANT_QUICKSTART_MESSAGES = { @@ -70,7 +69,10 @@ export function NewTab() { const [isCreatingChat, setIsCreatingChat] = useState(false) const [templates] = partition(SQL_TEMPLATES, { type: 'template' }) const [quickstarts] = partition(SQL_TEMPLATES, { type: 'quickstart' }) - const hasTrackedExposure = useRef(false) + const [hasTrackedExposure, setHasTrackedExposure] = useLocalStorageQuery( + LOCAL_STORAGE_KEYS.TABLE_QUICKSTART_EXPOSURE_TRACKED(String(profile?.id ?? 'anonymous')), + false + ) const { mutate: sendEvent } = useSendEventMutation() const track = useTrack() @@ -93,14 +95,8 @@ export function NewTab() { TABLE_QUICKSTART_FLAG ) - const isNewProject = useMemo(() => { - if (!project?.inserted_at) return false - return dayjs().diff(dayjs(project.inserted_at), 'day') < NEW_PROJECT_THRESHOLD_DAYS - }, [project?.inserted_at]) - const activeQuickstartVariant = editor !== 'sql' && - isNewProject && tableQuickstartVariant && tableQuickstartVariant !== QuickstartVariant.CONTROL ? tableQuickstartVariant @@ -108,18 +104,24 @@ export function NewTab() { const shouldTrackExposure = editor !== 'sql' && - isNewProject && + !!profile?.id && tableQuickstartVariant !== false && tableQuickstartVariant !== undefined useEffect(() => { - if (shouldTrackExposure && !hasTrackedExposure.current) { - hasTrackedExposure.current = true + if (shouldTrackExposure && !hasTrackedExposure) { + setHasTrackedExposure(true) track('table_quickstart_opened', { variant: tableQuickstartVariant, }) } - }, [shouldTrackExposure, tableQuickstartVariant, track]) + }, [ + shouldTrackExposure, + hasTrackedExposure, + setHasTrackedExposure, + tableQuickstartVariant, + track, + ]) const handleOpenAssistant = () => { if (isCreatingChat) return diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts index 8783b1906901c..a44fe3ed50f0c 100644 --- a/packages/common/constants/local-storage.ts +++ b/packages/common/constants/local-storage.ts @@ -117,8 +117,9 @@ export const LOCAL_STORAGE_KEYS = { */ BLOG_VIEW: 'supabase-blog-view', - // Used to track if user has dismissed table editor quickstart prompt - TABLE_QUICKSTART_DISMISSED: 'table-quickstart-dismissed', + // Used to track if user has been exposed to table quickstart experiment (prevents duplicate exposure events) + TABLE_QUICKSTART_EXPOSURE_TRACKED: (userId: string) => + `table-quickstart-exposure-tracked-${userId}`, } as const export type LocalStorageKey = (typeof LOCAL_STORAGE_KEYS)[keyof typeof LOCAL_STORAGE_KEYS] @@ -140,7 +141,6 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [ LOCAL_STORAGE_KEYS.AI_ASSISTANT_MCP_OPT_IN, LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0, LOCAL_STORAGE_KEYS.LINTER_SHOW_FOOTER, - LOCAL_STORAGE_KEYS.TABLE_QUICKSTART_DISMISSED, ] export function clearLocalStorage() {