"use client"; import type React from "react"; import { useState } from "react"; import { cx } from "../lib/utils"; import { OnboardingButton } from "../primitives/onboarding-button"; import { OnboardingLabel } from "../primitives/onboarding-label"; import { OnboardingSelect, OnboardingSelectContent, OnboardingSelectGroup, OnboardingSelectItem, OnboardingSelectTrigger, OnboardingSelectValue, } from "../primitives/onboarding-select"; export interface DropdownOption { value: string; label: string; disabled?: boolean; } export interface DropdownOptionGroup { label: string; options: DropdownOption[]; } export interface DropdownField { /** Unique identifier for the field */ id: string; /** Label displayed above the dropdown */ label: string; /** Placeholder text when no value selected */ placeholder?: string; /** Optional description/helper text */ description?: string; /** Whether the field is required */ required?: boolean; /** Options (flat array or grouped) */ options: DropdownOption[] | DropdownOptionGroup[]; /** Default value */ defaultValue?: string; } export interface DropdownSelectStepProps { /** Title displayed at the top of the step */ title?: string; /** Description text below the title */ description?: string; /** Array of dropdown fields */ fields: DropdownField[]; /** Called when any value changes */ onValuesChange?: (values: Record) => void; /** Called when the user submits the form */ onSubmit: (values: Record) => void | Promise; /** Text for the submit button */ submitText?: string; /** Text shown while submitting */ loadingText?: string; /** Optional back button config */ backButton?: { text: string; onClick: () => void; }; } function isGroupedOptions( options: DropdownOption[] | DropdownOptionGroup[], ): options is DropdownOptionGroup[] { return options.length > 0 && "options" in options[0]; } export function DropdownSelectStep({ title = "Select your preferences", description = "Please make your selections below.", fields, onValuesChange, onSubmit, submitText = "Continue", loadingText = "Submitting...", backButton, }: DropdownSelectStepProps) { const [values, setValues] = useState>(() => { const initial: Record = {}; fields.forEach((field) => { initial[field.id] = field.defaultValue ?? ""; }); return initial; }); const [loading, setLoading] = useState(false); const handleChange = (fieldId: string, value: string) => { const newValues = { ...values, [fieldId]: value }; setValues(newValues); onValuesChange?.(newValues); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { await onSubmit(values); } finally { setLoading(false); } }; const isValid = fields.every((field) => { if (field.required && !values[field.id]) return false; return true; }); return (

{title}

{description}

{fields.map((field, index) => (
{field.label} {field.required && ( * )} {field.description && (

{field.description}

)} handleChange(field.id, value)} > {isGroupedOptions(field.options) ? field.options.map((group) => ( {group.label} {group.options.map((option) => ( {option.label} ))} )) : field.options.map((option) => ( {option.label} ))}
))}
{backButton && ( {backButton.text} )} {loading ? loadingText : submitText}
); }