import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { Button, Input } from 'ui' import toast from 'react-hot-toast' import TextConfirmModal from 'ui-patterns/Dialogs/TextConfirmModal' import { CANCELLATION_REASONS } from 'components/interfaces/Billing/Billing.constants' import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' import { useSendDowngradeFeedbackMutation } from 'data/feedback/exit-survey-send' import { useProjectDeleteMutation } from 'data/projects/project-delete-mutation' import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query' import { useCheckPermissions, useSelectedOrganization } from 'hooks' export interface DeleteProjectButtonProps { type?: 'danger' | 'default' } const DeleteProjectButton = ({ type = 'danger' }: DeleteProjectButtonProps) => { const router = useRouter() const { project } = useProjectContext() const organization = useSelectedOrganization() const projectRef = project?.ref const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: organization?.slug }) const projectPlan = subscription?.plan?.id ?? 'free' const isFree = projectPlan === 'free' const [isOpen, setIsOpen] = useState(false) const [message, setMessage] = useState('') const [selectedReasons, setSelectedReasons] = useState([]) const { mutateAsync: deleteProject, isLoading: isDeleting } = useProjectDeleteMutation() const { mutateAsync: sendExitSurvey, isLoading: isSending } = useSendDowngradeFeedbackMutation() const isSubmitting = isDeleting || isSending useEffect(() => { if (isOpen) { setSelectedReasons([]) setMessage('') } }, [isOpen]) const canDeleteProject = useCheckPermissions(PermissionAction.UPDATE, 'projects', { resource: { project_id: project?.id, }, }) const toggle = () => { if (isSubmitting) return setIsOpen(!isOpen) } const onSelectCancellationReason = (reason: string) => { const existingSelection = selectedReasons.find((x) => x === reason) const updatedSelection = existingSelection === undefined ? selectedReasons.concat([reason]) : selectedReasons.filter((x) => x !== reason) setSelectedReasons(updatedSelection) } async function handleDeleteProject() { if (project === undefined) return if (!isFree && selectedReasons.length === 0) { return toast.error('Please select at least one reason for deleting your project') } try { await deleteProject({ projectRef: project.ref }) if (!isFree) { await sendExitSurvey({ projectRef, message, reasons: selectedReasons.reduce((a, b) => `${a}- ${b}\n`, ''), exitAction: 'delete', }) } toast.success(`Successfully deleted ${project.name}`) router.push(`/projects`) } finally { } } return ( <> {!canDeleteProject && (
You need additional permissions to delete this project
)}
{/* [Joshen] This is basically ExitSurvey.tsx, ideally we have one shared component but the one in ExitSurvey has a Form wrapped around it already. Will probably need some effort to refactor but leaving that for the future. */} {!isFree && ( <>

We're sad that you're leaving.

We always strive to improve Supabase as much as we can. Please let us know the reasons you are deleting your project so that we can improve in the future.

{CANCELLATION_REASONS.map((option) => { const active = selectedReasons.find((x) => x === option) return ( ) })}
setMessage(event.target.value)} />
)}
) } export default DeleteProjectButton