mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 13:49:09 +03:00
Implements a growth engineering experiment to improve new user onboarding by providing AI-powered and template-based table creation options. Features: - AI prompt interface for describing app requirements - Pre-built templates for common app types (social media, e-commerce, blog, etc.) - Seamless integration with existing table editor - State management using Valtio for reliable data flow - PostHog feature flag controlled (tableQuickstart) Technical implementation: - Uses Valtio proxy-based state management instead of sessionStorage - Properly handles quickstart flow to prevent race conditions - Integrates with TableEditor via useQuickstartData hook - Cleans up state appropriately to prevent panel re-opening issues - Full TypeScript support with proper type definitions The experiment aims to reduce time-to-value for new users by providing smart defaults and reducing the SQL knowledge barrier for initial setup.
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
import { ArrowLeft } from 'lucide-react'
|
|
import { Button_Shadcn_ } from 'ui'
|
|
import { TemplateSelector } from './TemplateSelector'
|
|
import { AiPromptInput } from './AiPromptInput'
|
|
import { TablePicker } from './TablePicker'
|
|
import { GETTING_STARTED_WIDGET_COPY } from './constants'
|
|
import { useQuickstart } from './useQuickstart'
|
|
import { GetStartedHero } from 'components/interfaces/Home/NewProjectPanel/GetStartedHero'
|
|
|
|
interface TableQuickstartProps {
|
|
variant?: 'ai' | 'templates'
|
|
}
|
|
|
|
export const TableQuickstart = ({ variant = 'ai' }: TableQuickstartProps = {}) => {
|
|
const {
|
|
currentStep,
|
|
candidates,
|
|
loading,
|
|
error,
|
|
userInput,
|
|
isGenerating,
|
|
onTablesReady,
|
|
handleAiGenerate,
|
|
handleSelectTable,
|
|
handleBack,
|
|
} = useQuickstart()
|
|
|
|
return (
|
|
<div className="grid grid-cols-12 gap-4">
|
|
<div className="col-span-12 flex flex-col justify-center space-y-8 lg:col-span-7">
|
|
<div className="space-y-2">
|
|
<h2>{GETTING_STARTED_WIDGET_COPY[variant]?.title}</h2>
|
|
<p className="text-base text-foreground-light">
|
|
{GETTING_STARTED_WIDGET_COPY[variant]?.description}
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
{/* Step 1: User input or selection screen */}
|
|
{currentStep === 'input' && variant === 'ai' && (
|
|
<AiPromptInput onGenerate={handleAiGenerate} isLoading={isGenerating} />
|
|
)}
|
|
|
|
{currentStep === 'input' && variant === 'templates' && (
|
|
<TemplateSelector onSelect={onTablesReady} />
|
|
)}
|
|
|
|
{/* Step 2: Table preview grid */}
|
|
{currentStep === 'preview' && (
|
|
<div className="space-y-4">
|
|
<div className="flex items-center justify-start">
|
|
<Button_Shadcn_
|
|
type="button"
|
|
size="sm"
|
|
onClick={handleBack}
|
|
className="inline-flex items-center gap-1 hover:no-underline"
|
|
disabled={loading}
|
|
variant="ghost"
|
|
>
|
|
<ArrowLeft className="h-3 w-3" />
|
|
<span>Back</span>
|
|
</Button_Shadcn_>
|
|
|
|
<p className="text-sm text-muted-foreground">
|
|
{variant === 'ai'
|
|
? `Select a table for "${userInput}" to customize in the table editor`
|
|
: 'Select a table to get started'}
|
|
</p>
|
|
</div>
|
|
|
|
<TablePicker
|
|
tables={candidates}
|
|
onSelectTable={handleSelectTable}
|
|
loading={loading}
|
|
/>
|
|
|
|
{error && <div className="text-sm text-destructive text-center mt-3">{error}</div>}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="col-span-12 lg:col-span-5">
|
|
<GetStartedHero />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|