import { Check, ChevronLeft, ChevronRight } from 'lucide-react' import Image from 'next/image' import Link from 'next/link' import { useEffect, useState } from 'react' import { BASE_PATH } from 'lib/constants' import { Badge, Button, Card, CardContent, cn, IconDiscord } from 'ui' import { GettingStartedAction, GettingStartedStep } from './GettingStarted.types' // Determine action type for tracking const getActionType = (action: GettingStartedAction): 'primary' | 'ai_assist' | 'external_link' => { // Check if it's an AI assist action (has AiIconAnimation or "Do it for me"/"Generate" labels) if ( action.label?.toLowerCase().includes('do it for me') || action.label?.toLowerCase().includes('generate') || action.label?.toLowerCase().includes('create policies for me') ) { return 'ai_assist' } // Check if it's an external link (href that doesn't start with /project/) if (action.href && !action.href.startsWith('/project/')) { return 'external_link' } return 'primary' } export interface GettingStartedProps { steps: GettingStartedStep[] onStepClick: ({ stepIndex, stepTitle, actionType, wasCompleted, }: { stepIndex: number stepTitle: string actionType: 'primary' | 'ai_assist' | 'external_link' wasCompleted: boolean }) => void } export function GettingStarted({ steps, onStepClick }: GettingStartedProps) { const allStepsComplete = steps.length > 0 && steps.every((step) => step.status === 'complete') const [activeStepKey, setActiveStepKey] = useState(null) useEffect(() => { if (steps.length === 0) { setActiveStepKey(null) return } // Check if the current active step key is still valid in the new steps array const isActiveStepValid = activeStepKey && steps.some((step) => step.key === activeStepKey) // If no step is selected or the active step is no longer valid (e.g., after tab switch) if (!isActiveStepValid) { // If all steps are complete, don't select any step if (allStepsComplete) { setActiveStepKey(null) } else { // Select the first incomplete step, or the first step if all are complete const firstIncompleteStep = steps.find((step) => step.status !== 'complete') setActiveStepKey(firstIncompleteStep?.key ?? steps[0]?.key ?? null) } } }, [steps, allStepsComplete, activeStepKey]) const activeStep = activeStepKey ? steps.find((step) => step.key === activeStepKey) : null const activeStepIndex = activeStep ? steps.findIndex((step) => step.key === activeStep.key) : -1 const previousStep = activeStepIndex > 0 ? steps[activeStepIndex - 1] : null const nextStep = activeStepIndex > -1 && activeStepIndex < steps.length - 1 ? steps[activeStepIndex + 1] : null const handleSelectPrevious = () => { if (previousStep) { setActiveStepKey(previousStep.key) } } const handleSelectNext = () => { if (nextStep) { setActiveStepKey(nextStep.key) } } const showCongratulations = allStepsComplete && !activeStep return (
{showCongratulations ? (

All steps complete

Drop into our Discord community to share your progress and learn from fellow developers.

) : ( <>
{activeStepIndex + 1}
{activeStep?.image ? ( {activeStep.title} ) : (
Supabase Grafana Supabase Grafana
)}
{activeStep && ( <>

{activeStep.title}

{activeStep.status}

{activeStep.description}

{activeStep.actions.map((action, i) => { if (action.component) { return
{action.component}
} const actionType = getActionType(action) if (action.href) { return ( ) } return ( ) })}
)}
)}
) }