import * as Sentry from '@sentry/nextjs' import { useFlag } from 'common' import { Loader2 } from 'lucide-react' import Link from 'next/link' import { useCallback, useReducer } from 'react' import { toast } from 'sonner' import { Button, cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui' import { IncidentAdmonition } from './IncidentAdmonition' import { Success } from './Success' import type { ExtendedSupportCategories } from './Support.constants' import { SupportAssistantSuccessCard } from './SupportAssistantSuccessCard' import { createInitialSupportFormState, supportFormReducer } from './SupportForm.state' import { NO_PROJECT_MARKER, type SupportFormUrlKeys } from './SupportForm.utils' import { SupportFormV3 } from './SupportFormV3' import { useSupportForm } from './useSupportForm' import { useIncidentStatusQuery } from '@/data/platform/incident-status-query' import { useStateTransition } from '@/hooks/misc/useStateTransition' import { useTrack } from '@/lib/telemetry/track' function useSupportFormTelemetry() { const track = useTrack() return useCallback( ({ projectRef, orgSlug, category, }: { projectRef: string | undefined orgSlug: string | undefined category: ExtendedSupportCategories }) => track( 'support_ticket_submitted', { ticketCategory: category }, { project: projectRef, organization: orgSlug } ), [track] ) } interface SupportFormProps { initialParams?: Partial } export function SupportForm({ initialParams }: SupportFormProps) { const [state, dispatch] = useReducer(supportFormReducer, undefined, createInitialSupportFormState) const { form, initialError, projectRef } = useSupportForm(dispatch, initialParams) const showSupportAssistantFollowUp = useFlag('supportAssistantFollowUp') === true const { data: allStatusPageEvents, isPending: isIncidentsPending, isError: isIncidentsError, } = useIncidentStatusQuery() const { incidents = [] } = allStatusPageEvents ?? {} const hasActiveIncidents = !isIncidentsPending && !isIncidentsError && incidents && incidents.length > 0 const sendTelemetry = useSupportFormTelemetry() useStateTransition(state, 'submitting', 'success', (_, curr) => { toast.success('Support request sent. Thank you!') sendTelemetry({ projectRef: curr.sentProjectRef, orgSlug: curr.sentOrgSlug, category: curr.sentCategory, }) }) useStateTransition(state, 'submitting', 'error', (_, curr) => { toast.error(`Failed to submit support ticket: ${curr.message}`) if (curr.code !== 429) { Sentry.captureMessage(`Failed to submit Support Form: ${curr.message}`) } dispatch({ type: 'RETURN_TO_EDITING' }) }) const successState = state.type === 'success' ? state : null const showAssistantSuccessCard = showSupportAssistantFollowUp && successState !== null && successState.submittedRequest.projectRef !== undefined && successState.submittedRequest.projectRef !== NO_PROJECT_MARKER return (
{successState ? (
{showAssistantSuccessCard && ( )}
) : ( )}
) } export function SupportFormStatusButton() { const { data: allStatusPageEvents, isPending: isLoading, isError } = useIncidentStatusQuery() const { incidents = [], maintenanceEvents = [] } = allStatusPageEvents ?? {} const isMaintenance = maintenanceEvents.length > 0 const isIncident = incidents.length > 0 return ( Check the Supabase status page ) }