diff --git a/app/(customer)/dashboard/(organization)/settings/page.tsx b/app/(customer)/dashboard/(organization)/settings/page.tsx index 7e731fee..63296858 100644 --- a/app/(customer)/dashboard/(organization)/settings/page.tsx +++ b/app/(customer)/dashboard/(organization)/settings/page.tsx @@ -1,89 +1,95 @@ -import {PageParams} from "@/types/next"; -import {Page, PageActions, PageContent, PageHeader, PageTitle} from "@/features/layout/page"; -import {currentUser} from "@/lib/auth/current-user"; -import {getActiveMember, getOrganization} from "@/lib/auth/auth"; -import {notFound} from "next/navigation"; -import {Metadata} from "next"; -import {OrganizationTabs} from "@/components/wrappers/dashboard/organization/tabs/organization-tabs"; -import {getOrganizationChannels} from "@/db/services/notification-channel"; -import {computeOrganizationPermissions} from "@/lib/acl/organization-acl"; -import {getOrganizationStorageChannels} from "@/db/services/storage-channel"; -import {DeleteOrganizationButton} from "@/components/wrappers/dashboard/organization/delete-organization-button"; -import {EditOrganizationDialog} from "@/features/organization/components/edit-organization.dialog"; -import {Button} from "@/components/ui/button"; -import {GearIcon} from "@radix-ui/react-icons"; -import {db} from "@/db"; -import {isNull} from "drizzle-orm"; +import { PageParams } from "@/types/next"; +import { + Page, + PageActions, + PageContent, + PageHeader, + PageTitle, +} from "@/features/layout/page"; +import { currentUser } from "@/lib/auth/current-user"; +import { getActiveMember, getOrganization } from "@/lib/auth/auth"; +import { notFound } from "next/navigation"; +import { Metadata } from "next"; +import { OrganizationTabs } from "@/components/wrappers/dashboard/organization/tabs/organization-tabs"; +import { getOrganizationChannels } from "@/db/services/notification-channel"; +import { computeOrganizationPermissions } from "@/lib/acl/organization-acl"; +import { getOrganizationStorageChannels } from "@/db/services/storage-channel"; +import { DeleteOrganizationButton } from "@/components/wrappers/dashboard/organization/delete-organization-button"; +import { EditOrganizationDialog } from "@/features/organization/components/edit-organization.dialog"; +import { db } from "@/db"; +import { isNull } from "drizzle-orm"; import * as drizzleDb from "@/db"; -import {eq} from "drizzle-orm"; +import { eq } from "drizzle-orm"; export const metadata: Metadata = { - title: "Settings", + title: "Settings", }; export default async function RoutePage(props: PageParams<{ slug: string }>) { - const organization = await getOrganization({}); - const user = await currentUser(); - const activeMember = await getActiveMember() + const organization = await getOrganization({}); + const user = await currentUser(); + const activeMember = await getActiveMember(); - if (!organization || !activeMember || !user) { - notFound(); - } + if (!organization || !activeMember || !user) { + notFound(); + } - const notificationChannels = await getOrganizationChannels(organization.id) - const storageChannels = await getOrganizationStorageChannels(organization.id) - const permissions = computeOrganizationPermissions(activeMember); + const notificationChannels = await getOrganizationChannels(organization.id); + const storageChannels = await getOrganizationStorageChannels(organization.id); + const permissions = computeOrganizationPermissions(activeMember); - const users = await db.query.user.findMany({ - where: (fields) => isNull(fields.deletedAt) - }); + const users = await db.query.user.findMany({ + where: (fields) => isNull(fields.deletedAt), + }); - const organizationWithMembers = await db.query.organization.findFirst({ - where: eq(drizzleDb.schemas.organization.id, organization.id), + const organizationWithMembers = await db.query.organization.findFirst({ + where: eq(drizzleDb.schemas.organization.id, organization.id), + with: { + members: { with: { - members: { - with: { - user: true - } - } - } - }); + user: true, + }, + }, + }, + }); - if (!organizationWithMembers) notFound(); + if (!organizationWithMembers) notFound(); - return ( - - - -
- Organization settings -
-
-
- {permissions.canManageSettings && organization.slug !== "default" && ( - - )} -
-
- {permissions.canManageDangerZone && organization.slug !== "default" && ( - - )} -
-
-
-
- - - -
- ) + return ( + + + +
Organization settings
+
+
+ {permissions.canManageSettings && + organization.slug !== "default" && ( + + )} +
+
+ {permissions.canManageDangerZone && + organization.slug !== "default" && ( + + )} +
+
+
+
+ + + +
+ ); } diff --git a/src/components/wrappers/dashboard/admin/channels/channels-section.tsx b/src/components/wrappers/dashboard/admin/channels/channels-section.tsx index 4e632d7e..70d47a21 100644 --- a/src/components/wrappers/dashboard/admin/channels/channels-section.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channels-section.tsx @@ -1,60 +1,65 @@ -"use client" -import {NotificationChannelWith} from "@/db/schema/09_notification-channel"; -import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination"; -import {useState} from "react"; -import {EmptyStatePlaceholder} from "@/components/wrappers/common/empty-state-placeholder"; -import {OrganizationWithMembers} from "@/db/schema/03_organization"; -import {StorageChannelWith} from "@/db/schema/12_storage-channel"; -import {ChannelCard} from "@/components/wrappers/dashboard/admin/channels/channel/channel-card/channel-card"; -import {ChannelAddEditModal} from "@/components/wrappers/dashboard/admin/channels/channel/channel-add-edit-modal"; -import {ChannelKind, getChannelTextBasedOnKind} from "@/components/wrappers/dashboard/admin/channels/helpers/common"; +"use client"; +import { NotificationChannelWith } from "@/db/schema/09_notification-channel"; +import { CardsWithPagination } from "@/components/wrappers/common/cards-with-pagination"; +import { useState } from "react"; +import { EmptyStatePlaceholder } from "@/components/wrappers/common/empty-state-placeholder"; +import { OrganizationWithMembers } from "@/db/schema/03_organization"; +import { StorageChannelWith } from "@/db/schema/12_storage-channel"; +import { ChannelCard } from "@/components/wrappers/dashboard/admin/channels/channel/channel-card/channel-card"; +import { ChannelAddEditModal } from "@/components/wrappers/dashboard/admin/channels/channel/channel-add-edit-modal"; +import { + ChannelKind, + getChannelTextBasedOnKind, +} from "@/components/wrappers/dashboard/admin/channels/helpers/common"; type ChannelsSectionProps = { - channels: NotificationChannelWith[] | StorageChannelWith[], - organizations: OrganizationWithMembers[], - kind: ChannelKind, - defaultStorageChannelId?: string | null | undefined -} + channels: NotificationChannelWith[] | StorageChannelWith[]; + organizations: OrganizationWithMembers[]; + kind: ChannelKind; + defaultStorageChannelId?: string | null | undefined; +}; export const ChannelsSection = ({ - organizations, - channels, - kind, - defaultStorageChannelId - }: ChannelsSectionProps) => { + organizations, + channels, + kind, + defaultStorageChannelId, +}: ChannelsSectionProps) => { + const [isAddModalOpen, setIsAddModalOpen] = useState(false); + const channelText = getChannelTextBasedOnKind(kind); + const hasChannels = channels.length > 0; - const [isAddModalOpen, setIsAddModalOpen] = useState(false); - const channelText = getChannelTextBasedOnKind(kind) - const hasChannels = channels.length > 0 - - - return ( + return ( +
+ + {hasChannels ? (
- - {hasChannels ? ( -
- -
- ) : ( - { - setIsAddModalOpen(true) - }} - className="h-full" - /> - )} +
- ); -} \ No newline at end of file + ) : ( + { + setIsAddModalOpen(true); + }} + className="h-full" + /> + )} +
+ ); +}; diff --git a/src/components/wrappers/dashboard/backup/backup-button/backup-button.tsx b/src/components/wrappers/dashboard/backup/backup-button/backup-button.tsx index 3ba0c5cd..3e68d313 100644 --- a/src/components/wrappers/dashboard/backup/backup-button/backup-button.tsx +++ b/src/components/wrappers/dashboard/backup/backup-button/backup-button.tsx @@ -1,49 +1,71 @@ "use client"; -import {useMutation, useQueryClient} from "@tanstack/react-query"; -import {useRouter} from "next/navigation"; -import {toast} from "sonner"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useRouter } from "next/navigation"; +import { toast } from "sonner"; -import {backupButtonAction} from "@/components/wrappers/dashboard/backup/backup-button/backup-button.action"; -import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading"; -import {Database, DatabaseZap} from "lucide-react"; -import {useIsMobile} from "@/hooks/use-mobile"; +import { backupButtonAction } from "@/components/wrappers/dashboard/backup/backup-button/backup-button.action"; +import { Check, DatabaseZap, X } from "lucide-react"; +import { useIsMobile } from "@/hooks/use-mobile"; +import { ButtonWithConfirm } from "@/components/wrappers/common/button/button-with-confirm"; export type BackupButtonProps = { - databaseId: string; - disable: boolean; + databaseId: string; + disable: boolean; }; export const BackupButton = (props: BackupButtonProps) => { - const queryClient = useQueryClient(); - const router = useRouter(); - const isMobile = useIsMobile() + const queryClient = useQueryClient(); + const router = useRouter(); + const isMobile = useIsMobile(); - const mutation = useMutation({ - mutationFn: async (databaseId: string) => { - const backup = await backupButtonAction(databaseId); - if (backup?.data?.success) { - toast.success(backup.data.actionSuccess?.message || "Backup created successfully!"); - queryClient.invalidateQueries({queryKey: ["database-data", props.databaseId]}); - router.refresh(); - } else { - toast.error(backup?.serverError || "Failed to create backup."); - } + const mutation = useMutation({ + mutationFn: async (databaseId: string) => { + const backup = await backupButtonAction(databaseId); + if (backup?.data?.success) { + toast.success( + backup.data.actionSuccess?.message || "Backup created successfully!", + ); + queryClient.invalidateQueries({ + queryKey: ["database-data", props.databaseId], + }); + router.refresh(); + } else { + toast.error(backup?.serverError || "Failed to create backup."); + } + }, + }); + const HandleAction = async () => { + await mutation.mutateAsync(props.databaseId); + }; + + return ( + , }, - }); - const HandleAction = async () => { - await mutation.mutateAsync(props.databaseId); - }; - - return ( - } - disabled={props.disable} - isPending={mutation.isPending} - size={"default"} - onClick={async () => { - await HandleAction(); - }} - >{isMobile ? "" : "Backup"} - ); + confirm: { + className: "w-full", + text: "Yes, create backup", + icon: , + variant: "default", + onClick: async () => { + await HandleAction(); + }, + }, + cancel: { + className: "w-full", + text: "No, cancel", + icon: , + variant: "outline", + }, + }} + isPending={mutation.isPending} + /> + ); }; diff --git a/src/components/wrappers/dashboard/projects/database/database-content.tsx b/src/components/wrappers/dashboard/projects/database/database-content.tsx index ad883f2e..22f0272b 100644 --- a/src/components/wrappers/dashboard/projects/database/database-content.tsx +++ b/src/components/wrappers/dashboard/projects/database/database-content.tsx @@ -1,144 +1,158 @@ -"use client" -import {DatabaseBackupActionsModal} from "@/components/wrappers/dashboard/database/backup/actions/backup-actions-modal"; -import {DatabaseTabs} from "@/components/wrappers/dashboard/projects/database/database-tabs"; -import {Setting} from "@/db/schema/01_setting"; -import {BackupWith, DatabaseWith, Restoration} from "@/db/schema/07_database"; -import {MemberWithUser} from "@/db/schema/03_organization"; -import {useBackupModal} from "@/components/wrappers/dashboard/database/backup/backup-modal-context"; -import {DatabaseKpi} from "@/components/wrappers/dashboard/projects/database/database-kpi"; -import {useQuery, useQueryClient} from "@tanstack/react-query"; -import {getDatabaseDataAction} from "@/components/wrappers/dashboard/database/backup/actions/get-data.action"; -import {PageContent, PageDescription, PageTitle} from "@/features/layout/page"; -import {capitalizeFirstLetter} from "@/utils/text"; -import {RetentionPolicySheet} from "@/components/wrappers/dashboard/database/retention-policy/retention-policy-sheet"; -import {CronButton} from "@/components/wrappers/dashboard/database/cron-button/cron-button"; -import {ChannelPoliciesModal} from "@/components/wrappers/dashboard/database/channels-policy/policy-modal"; -import {HardDrive, Megaphone} from "lucide-react"; -import {ImportModal} from "@/components/wrappers/dashboard/database/import/import-modal"; -import {BackupButton} from "@/components/wrappers/dashboard/backup/backup-button/backup-button"; - +"use client"; +import { DatabaseBackupActionsModal } from "@/components/wrappers/dashboard/database/backup/actions/backup-actions-modal"; +import { DatabaseTabs } from "@/components/wrappers/dashboard/projects/database/database-tabs"; +import { Setting } from "@/db/schema/01_setting"; +import { BackupWith, DatabaseWith, Restoration } from "@/db/schema/07_database"; +import { MemberWithUser } from "@/db/schema/03_organization"; +import { useBackupModal } from "@/components/wrappers/dashboard/database/backup/backup-modal-context"; +import { DatabaseKpi } from "@/components/wrappers/dashboard/projects/database/database-kpi"; +import { useQuery } from "@tanstack/react-query"; +import { getDatabaseDataAction } from "@/components/wrappers/dashboard/database/backup/actions/get-data.action"; +import { + PageContent, + PageDescription, + PageTitle, +} from "@/features/layout/page"; +import { capitalizeFirstLetter } from "@/utils/text"; +import { RetentionPolicySheet } from "@/components/wrappers/dashboard/database/retention-policy/retention-policy-sheet"; +import { CronButton } from "@/components/wrappers/dashboard/database/cron-button/cron-button"; +import { ChannelPoliciesModal } from "@/components/wrappers/dashboard/database/channels-policy/policy-modal"; +import { HardDrive, Megaphone } from "lucide-react"; +import { ImportModal } from "@/components/wrappers/dashboard/database/import/import-modal"; +import { BackupButton } from "@/components/wrappers/dashboard/backup/backup-button/backup-button"; export type DatabaseContentProps = { - settings: Setting, - backups: BackupWith[], - restorations: Restoration[], - isAlreadyRestore: boolean, - database: DatabaseWith, - activeMember: MemberWithUser, - totalBackups: number, - availableBackups: number, - successRate: number | null, - organizationId: string, - activeOrganizationChannels: any[], - activeOrganizationStorageChannels: any[] -} - + settings: Setting; + backups: BackupWith[]; + restorations: Restoration[]; + isAlreadyRestore: boolean; + database: DatabaseWith; + activeMember: MemberWithUser; + totalBackups: number; + availableBackups: number; + successRate: number | null; + organizationId: string; + activeOrganizationChannels: any[]; + activeOrganizationStorageChannels: any[]; +}; export const DatabaseContent = (props: DatabaseContentProps) => { - const {} = useBackupModal(); + const {} = useBackupModal(); - - const {data} = useQuery({ - queryKey: ["database-data", props.database.id], - queryFn: async () => { - const result = await getDatabaseDataAction({databaseId: props.database.id}); - return result?.data; - }, - initialData: { - // TODO : to be patched - // @ts-ignore - database: { - ...props.database, - project: props.database.project ?? null, - }, - backups: props.backups, - restorations: props.restorations, - activeOrganizationChannels: props.activeOrganizationChannels, - activeOrganizationStorageChannels: props.activeOrganizationStorageChannels, - stats: { - totalBackups: props.totalBackups, - availableBackups: props.availableBackups, - successRate: props.successRate - } - }, - staleTime: 0, - gcTime: 0, - refetchInterval: 1000, - }); - - const database = data?.database ?? props.database; - const backups = data?.backups ?? props.backups; - const restorations = data?.restorations ?? props.restorations; - const activeOrganizationChannels = data?.activeOrganizationChannels ?? props.activeOrganizationChannels; - const activeOrganizationStorageChannels = data?.activeOrganizationStorageChannels ?? props.activeOrganizationStorageChannels; - const stats = data?.stats ?? { + const { data } = useQuery({ + queryKey: ["database-data", props.database.id], + queryFn: async () => { + const result = await getDatabaseDataAction({ + databaseId: props.database.id, + }); + return result?.data; + }, + initialData: { + // TODO : to be patched + // @ts-ignore + database: { + ...props.database, + project: props.database.project ?? null, + }, + backups: props.backups, + restorations: props.restorations, + activeOrganizationChannels: props.activeOrganizationChannels, + activeOrganizationStorageChannels: + props.activeOrganizationStorageChannels, + stats: { totalBackups: props.totalBackups, availableBackups: props.availableBackups, - successRate: props.successRate - }; + successRate: props.successRate, + }, + }, + staleTime: 0, + gcTime: 0, + refetchInterval: 1000, + }); - const isAlreadyRestore = restorations.some((r) => r.status === "waiting"); - const isAlreadyBackup = backups.some((b) => b.status === "waiting" || b.status === "ongoing"); + const database = data?.database ?? props.database; + const backups = data?.backups ?? props.backups; + const restorations = data?.restorations ?? props.restorations; + const activeOrganizationChannels = + data?.activeOrganizationChannels ?? props.activeOrganizationChannels; + const activeOrganizationStorageChannels = + data?.activeOrganizationStorageChannels ?? + props.activeOrganizationStorageChannels; + const stats = data?.stats ?? { + totalBackups: props.totalBackups, + availableBackups: props.availableBackups, + successRate: props.successRate, + }; - const isMember = props.activeMember.role === "member"; + const isAlreadyRestore = restorations.some((r) => r.status === "waiting"); + const isAlreadyBackup = backups.some( + (b) => b.status === "waiting" || b.status === "ongoing", + ); - return ( - <> -
- -
- {capitalizeFirstLetter(database.name)} -
- {!isMember && ( -
-
- - - } - channels={activeOrganizationChannels} - organizationId={props.organizationId} - /> - } - kind={"storage"} - channels={activeOrganizationStorageChannels} - organizationId={props.organizationId} - /> - -
-
- -
-
- )} -
+ const isMember = props.activeMember.role === "member"; + + return ( + <> +
+ +
+ {capitalizeFirstLetter(database.name)} +
+ {!isMember && ( +
+
+ + + } + channels={activeOrganizationChannels} + organizationId={props.organizationId} + /> + } + kind={"storage"} + channels={activeOrganizationStorageChannels} + organizationId={props.organizationId} + /> + +
+
+ +
+ )} +
+
- {database.description && ( - {database.description} - )} + {database.description && ( + + {database.description} + + )} - - - - - - - ) -} \ No newline at end of file + + + + + + + ); +}; diff --git a/src/features/dashboard/restore/columns.tsx b/src/features/dashboard/restore/columns.tsx index 715bafde..9fd7432f 100644 --- a/src/features/dashboard/restore/columns.tsx +++ b/src/features/dashboard/restore/columns.tsx @@ -2,148 +2,183 @@ import { ColumnDef } from "@tanstack/react-table"; import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; -import {MoreHorizontal, Trash2} from "lucide-react"; +import { Check, MoreHorizontal, Trash2, X } from "lucide-react"; import { ReloadIcon } from "@radix-ui/react-icons"; import { StatusBadge } from "@/components/wrappers/common/status-badge"; -import {Restoration} from "@/db/schema/07_database"; -import {formatLocalizedDate} from "@/utils/date-formatting"; -import {useMutation, useQueryClient} from "@tanstack/react-query"; +import { Restoration } from "@/db/schema/07_database"; +import { formatLocalizedDate } from "@/utils/date-formatting"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { - deleteRestoreAction, - rerunRestorationAction + deleteRestoreAction, + rerunRestorationAction, } from "@/features/dashboard/restore/restore.action"; -import {toast} from "sonner"; -import {TooltipCustom} from "@/components/wrappers/common/tooltip-custom"; -import {MemberWithUser} from "@/db/schema/03_organization"; - +import { toast } from "sonner"; +import { TooltipCustom } from "@/components/wrappers/common/tooltip-custom"; +import { MemberWithUser } from "@/db/schema/03_organization"; +import { ButtonWithConfirm } from "@/components/wrappers/common/button/button-with-confirm"; export function restoreColumns( - isAlreadyRestore: boolean, - activeMember: MemberWithUser + isAlreadyRestore: boolean, + activeMember: MemberWithUser, ): ColumnDef[] { - return[ + return [ { - accessorKey: "id", - header: "Reference", + accessorKey: "id", + header: "Reference", }, { - accessorKey: "createdAt", - header: "Created At", - cell: ({ row }) => { - return formatLocalizedDate(row.getValue("createdAt")) - }, + accessorKey: "createdAt", + header: "Created At", + cell: ({ row }) => { + return formatLocalizedDate(row.getValue("createdAt")); + }, }, { - accessorKey: "status", - header: "Status", - cell: ({ row }) => { - return ; - }, + accessorKey: "status", + header: "Status", + cell: ({ row }) => { + return ; + }, }, { - id: "actions", - cell: ({ row }) => { - const status = row.getValue("status"); + id: "actions", + cell: ({ row }) => { + const status = row.getValue("status"); - const queryClient = useQueryClient(); - const rowData: Restoration = row.original; + const queryClient = useQueryClient(); + const rowData: Restoration = row.original; - - const mutationDeleteRestore = useMutation({ - mutationFn: async () => { - const restoration = await deleteRestoreAction({ - restorationId: rowData.id, - }); - // @ts-ignore - if (restoration.data.success) { - // @ts-ignore - toast.success(restoration.data.actionSuccess.message); - queryClient.invalidateQueries({queryKey: ["database-data", rowData.databaseId]}); - } else { - // @ts-ignore - toast.error(restoration.data.actionError.message); - } - }, + const mutationDeleteRestore = useMutation({ + mutationFn: async () => { + const restoration = await deleteRestoreAction({ + restorationId: rowData.id, }); - - const mutationRerunRestore = useMutation({ - mutationFn: async () => { - const restoration = await rerunRestorationAction({ - restorationId: rowData.id, - }); - // @ts-ignore - if (restoration.data.success) { - // @ts-ignore - toast.success(restoration.data.actionSuccess.message); - queryClient.invalidateQueries({queryKey: ["database-data", rowData.databaseId]}); - } else { - // @ts-ignore - toast.error(restoration.data.actionError.message); - } - }, - }); - - - - const handleDelete = async () => { - await mutationDeleteRestore.mutateAsync(); - }; - - const handleRerunRestore = async () => { - await mutationRerunRestore.mutateAsync(); - + // @ts-ignore + if (restoration.data.success) { + // @ts-ignore + toast.success(restoration.data.actionSuccess.message); + queryClient.invalidateQueries({ + queryKey: ["database-data", rowData.databaseId], + }); + } else { + // @ts-ignore + toast.error(restoration.data.actionError.message); } + }, + }); + const mutationRerunRestore = useMutation({ + mutationFn: async () => { + const restoration = await rerunRestorationAction({ + restorationId: rowData.id, + }); + // @ts-ignore + if (restoration.data.success) { + // @ts-ignore + toast.success(restoration.data.actionSuccess.message); + queryClient.invalidateQueries({ + queryKey: ["database-data", rowData.databaseId], + }); + } else { + // @ts-ignore + toast.error(restoration.data.actionError.message); + } + }, + }); - return ( - <> - {activeMember.role != "member" && ( - - - - - - Actions - {rowData.backupStorageId && ( - - { - await handleRerunRestore(); - }} - > - Rerun - - - )} - - { - await handleDelete(); - }} - > - Delete - - - - )} - - ); - }, + const handleDelete = async () => { + await mutationDeleteRestore.mutateAsync(); + }; + + const handleRerunRestore = async () => { + await mutationRerunRestore.mutateAsync(); + }; + + return ( + <> + {activeMember.role !== "member" && ( + + + + + + Actions + {rowData.backupStorageId && ( + + { + await handleRerunRestore(); + }} + > + Rerun + + + )} + + + + ), + disabled: status === "waiting", + className: + "text-red-500 hover:text-red-500 p-0 h-auto has-[>svg]:px-0", + }, + confirm: { + className: "w-full", + text: "Yes, delete", + icon: , + variant: "destructive", + onClick: async () => { + await handleDelete(); + }, + }, + cancel: { + className: "w-full", + text: "No, cancel", + icon: , + variant: "outline", + }, + }} + isPending={mutationDeleteRestore.isPending} + /> + + + + )} + + ); + }, }, -]; + ]; } -