diff --git a/src/components/dashboard/PagesManagerBatchSelectActionTab.tsx b/src/components/dashboard/PagesManagerBatchSelectActionTab.tsx index d9a844b4..c78e09c7 100644 --- a/src/components/dashboard/PagesManagerBatchSelectActionTab.tsx +++ b/src/components/dashboard/PagesManagerBatchSelectActionTab.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "next-i18next" import { useRouter } from "next/router" -import React from "react" +import React, { useState } from "react" import toast from "react-hot-toast" import type { Note, Notes } from "unidata.js" @@ -12,6 +12,8 @@ import { APP_NAME } from "~/lib/env" import { delStorage, getStorage, setStorage } from "~/lib/storage" import { useCreateOrUpdatePage, useDeletePage } from "~/queries/page" +import { DeleteConfirmationModal } from "./DeleteConfirmationModal" + export const PagesManagerBatchSelectActionTab: React.FC<{ isPost: boolean isNotxLogContent: boolean @@ -136,61 +138,77 @@ export const PagesManagerBatchSelectActionTab: React.FC<{ { text: "Delete", onClick: async () => { - // Start message - const toastId = toast.loading("Deleting...") - - // Find all selected - const selectedPages: Note[] = [] - pages.data?.pages.map((page) => - page.list?.map((page) => { - if (batchSelected.includes(page.id)) { - selectedPages.push(page) - } - }), - ) - - // Delete all // TODO: use multicall to optimize - try { - await Promise.all( - selectedPages.map((page) => { - if (!page.metadata) { - // Is draft - delStorage(`draft-${subdomain}-${page.id}`) - } else { - // Is Note - return deletePage.mutateAsync({ - site: subdomain, - id: page.id, - }) - } - }), - ) - - toast.success(t("Deleted!"), { - id: toastId, - }) - } catch (e) { - toast.error(t("Fail to Deleted."), { - // It should be "Failed to delete.", but the translation key is that so :shrug: - id: toastId, - }) - } - - // Refresh site data - await Promise.all([ - queryClient.refetchQueries(["getPagesBySite", subdomain]), - ...selectedPages.map((page) => - queryClient.refetchQueries(["getPage", page.id]), - ), - ]) - - // Unselect all - setBatchSelected([]) + setDeleteConfirmModalOpen(true) }, }, ] - return + const [deleteConfirmModalOpen, setDeleteConfirmModalOpen] = + useState(false) + const onDelete = async () => { + // Start message + const toastId = toast.loading("Deleting...") + + // Find all selected + const selectedPages: Note[] = [] + pages.data?.pages.map((page) => + page.list?.map((page) => { + if (batchSelected.includes(page.id)) { + selectedPages.push(page) + } + }), + ) + + // Delete all // TODO: use multicall to optimize + try { + await Promise.all( + selectedPages.map((page) => { + if (!page.metadata) { + // Is draft + delStorage(`draft-${subdomain}-${page.id}`) + } else { + // Is Note + return deletePage.mutateAsync({ + site: subdomain, + id: page.id, + }) + } + }), + ) + + toast.success(t("Deleted!"), { + id: toastId, + }) + } catch (e) { + toast.error(t("Fail to Deleted."), { + // It should be "Failed to delete.", but the translation key is that so :shrug: + id: toastId, + }) + } + + // Refresh site data + await Promise.all([ + queryClient.refetchQueries(["getPagesBySite", subdomain]), + ...selectedPages.map((page) => + queryClient.refetchQueries(["getPage", page.id]), + ), + ]) + + // Unselect all + setBatchSelected([]) + } + + return ( + <> + + + + ) } export default PagesManagerBatchSelectActionTab diff --git a/src/components/dashboard/PagesManagerMenu.tsx b/src/components/dashboard/PagesManagerMenu.tsx index 067428f6..33912e29 100644 --- a/src/components/dashboard/PagesManagerMenu.tsx +++ b/src/components/dashboard/PagesManagerMenu.tsx @@ -14,6 +14,8 @@ import { delStorage, getStorage, setStorage } from "~/lib/storage" import { useCreateOrUpdatePage, useDeletePage } from "~/queries/page" import { useGetSite } from "~/queries/site" +import { DeleteConfirmationModal } from "./DeleteConfirmationModal" + const usePageEditLink = (page: { id: string }, isPost: boolean) => { const router = useRouter() const subdomain = router.query.subdomain as string @@ -167,24 +169,7 @@ export const PagesManagerMenu: FC<{ text: "Delete", icon: , onClick() { - if (!page.metadata) { - const toastId = toast.loading("Deleting...") - delStorage(`draft-${subdomain}-${page.id}`) - Promise.all([ - queryClient.refetchQueries(["getPagesBySite", subdomain]), - queryClient.refetchQueries(["getPage", page.id]), - ]).then(() => { - toast.success("Deleted!", { - id: toastId, - }) - }) - } else { - setDeleteToastId(toast.loading("Deleting...")) - deletePage.mutate({ - site: subdomain, - id: page.id, - }) - } + setDeleteConfirmModalOpen(true) }, }, ] @@ -199,26 +184,57 @@ export const PagesManagerMenu: FC<{ } }, []) + const [deleteConfirmModalOpen, setDeleteConfirmModalOpen] = + useState(false) + const onDelete = () => { + if (!page.metadata) { + const toastId = toast.loading("Deleting...") + delStorage(`draft-${subdomain}-${page.id}`) + Promise.all([ + queryClient.refetchQueries(["getPagesBySite", subdomain]), + queryClient.refetchQueries(["getPage", page.id]), + ]).then(() => { + toast.success("Deleted!", { + id: toastId, + }) + }) + } else { + setDeleteToastId(toast.loading("Deleting...")) + deletePage.mutate({ + site: subdomain, + id: page.id, + }) + } + } + return ( - - {items.map((item) => { - return ( - - - - ) - })} - + <> + + {items.map((item) => { + return ( + + + + ) + })} + + + ) } diff --git a/src/components/dashboard/PublishButton.tsx b/src/components/dashboard/PublishButton.tsx index b832350e..73d05ea7 100644 --- a/src/components/dashboard/PublishButton.tsx +++ b/src/components/dashboard/PublishButton.tsx @@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from "react" import useOnClickOutside from "use-onclickoutside" import { Button, ButtonGroup } from "../ui/Button" +import { DeleteConfirmationModal } from "./DeleteConfirmationModal" export const PublishButton: React.FC<{ save: (published: boolean) => void @@ -10,7 +11,8 @@ export const PublishButton: React.FC<{ isSaving: boolean isDisabled: boolean twitterShareUrl?: string -}> = ({ save, published, isSaving, isDisabled, twitterShareUrl }) => { + isPost: boolean +}> = ({ save, published, isSaving, isDisabled, twitterShareUrl, isPost }) => { const [showDropdown, setShowDropdown] = useState(false) const dropdownRef = useRef(null) const triggerRef = useRef(null) @@ -27,6 +29,9 @@ export const PublishButton: React.FC<{ } }, [isSaving]) + const [deleteConfirmModalOpen, setDeleteConfirmModalOpen] = + useState(false) + return (
@@ -69,7 +74,7 @@ export const PublishButton: React.FC<{
)} + { + save(false) + }} + isPost={isPost} + /> ) } diff --git a/src/pages/dashboard/[subdomain]/editor.tsx b/src/pages/dashboard/[subdomain]/editor.tsx index 2c2070b4..987a54e6 100644 --- a/src/pages/dashboard/[subdomain]/editor.tsx +++ b/src/pages/dashboard/[subdomain]/editor.tsx @@ -563,6 +563,7 @@ export default function SubdomainEditor() { visibility !== PageVisibilityEnum.Modified && visibility !== PageVisibilityEnum.Draft } + isPost={isPost} /> )}