import { useParams } from 'common' import Link from 'next/link' import { useRouter } from 'next/router' import { useState } from 'react' import { Alert, AlertDescription, AlertTitle, Button, Modal, WarningIcon } from 'ui' import { BackupsEmpty } from '../BackupsEmpty' import { BackupsStorageAlert } from '../BackupsStorageAlert' import type { Timezone } from './PITR.types' import { getClientTimezone } from './PITR.utils' import { PITRForm } from './PITRForm' import PITRStatus from './PITRStatus' import { FormHeader } from '@/components/ui/Forms/FormHeader' import { useBackupsQuery } from '@/data/database/backups-query' import { usePitrRestoreMutation } from '@/data/database/pitr-restore-mutation' import { useSetProjectStatus } from '@/data/projects/project-detail-query' import { useReadReplicasQuery } from '@/data/read-replicas/replicas-query' import { PROJECT_STATUS } from '@/lib/constants' export const PITRSelection = () => { const router = useRouter() const { ref } = useParams() const { data: backups } = useBackupsQuery({ projectRef: ref }) const { data: databases } = useReadReplicasQuery({ projectRef: ref }) const { setProjectStatus } = useSetProjectStatus() const [showConfiguration, setShowConfiguration] = useState(false) const [showConfirmation, setShowConfirmation] = useState(false) const [selectedTimezone, setSelectedTimezone] = useState(getClientTimezone()) const [selectedRecoveryPoint, setSelectedRecoveryPoint] = useState<{ recoveryTimeTargetUnix: number recoveryTimeString: string recoveryTimeStringUtc: string }>() const hasReadReplicas = (databases ?? []).length > 1 const { mutate: restoreFromPitr, isPending: isRestoring, isSuccess: isSuccessPITR, } = usePitrRestoreMutation({ onSuccess: (_, variables) => { setTimeout(() => { setShowConfirmation(false) setProjectStatus({ ref: variables.ref, status: PROJECT_STATUS.RESTORING }) router.push(`/project/${variables.ref}`) }, 3000) }, }) const { earliestPhysicalBackupDateUnix, latestPhysicalBackupDateUnix } = backups?.physicalBackupData ?? {} const hasNoBackupsAvailable = !earliestPhysicalBackupDateUnix || !latestPhysicalBackupDateUnix const onConfirmRestore = async () => { if (!ref) return console.error('Project ref is required') if (!selectedRecoveryPoint?.recoveryTimeTargetUnix) return console.error('Recovery time target unix is required') restoreFromPitr({ ref, recovery_time_target_unix: selectedRecoveryPoint.recoveryTimeTargetUnix, }) } return ( <> {hasNoBackupsAvailable ? ( ) : ( <> {hasReadReplicas && ( Unable to restore from PITR as project has read replicas enabled You will need to remove all read replicas first from your project's infrastructure settings prior to starting a PITR restore.
{/* [Joshen] Ideally we have some links to a docs to explain why so */}
)} {!showConfiguration ? ( setShowConfiguration(true)} /> ) : ( { setSelectedRecoveryPoint(recoveryPoint) setShowConfirmation(true) }} /> )} )} setShowConfirmation(false)} header="Point in time recovery review" customFooter={
} >

Your database will be restored to:

Local Time

{selectedRecoveryPoint?.recoveryTimeString}

(UTC+00:00)

{selectedRecoveryPoint?.recoveryTimeStringUtc}

This action cannot be undone, not canceled once started Any changes made to your database after this point in time will be lost. This includes any changes to your project's storage and authentication.

Restores may take from a few minutes up to several hours depending on the size of your database. During this period, your project will not be available, until the restoration is completed.

) }