DeleteBookmarkFolderModal.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import type { FC } from 'react';
  2. import { useCallback } from 'react';
  3. import { useTranslation } from 'next-i18next';
  4. import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
  5. import { FolderIcon } from '~/client/components/Icons/FolderIcon';
  6. import { deleteBookmarkFolder } from '~/client/util/bookmark-utils';
  7. import { toastError } from '~/client/util/toastr';
  8. import type { BookmarkFolderItems } from '~/interfaces/bookmark-info';
  9. import {
  10. useDeleteBookmarkFolderModalActions,
  11. useDeleteBookmarkFolderModalStatus,
  12. } from '~/states/ui/modal/delete-bookmark-folder';
  13. /**
  14. * DeleteBookmarkFolderModalSubstance - Presentation component (all logic here)
  15. */
  16. type DeleteBookmarkFolderModalSubstanceProps = {
  17. bookmarkFolder: BookmarkFolderItems;
  18. onDeleted?: (folderId: string) => void;
  19. closeModal: () => void;
  20. };
  21. const DeleteBookmarkFolderModalSubstance = ({
  22. bookmarkFolder,
  23. onDeleted,
  24. closeModal,
  25. }: DeleteBookmarkFolderModalSubstanceProps): React.JSX.Element => {
  26. const { t } = useTranslation();
  27. const deleteBookmark = useCallback(async () => {
  28. try {
  29. await deleteBookmarkFolder(bookmarkFolder._id);
  30. if (onDeleted != null) {
  31. onDeleted(bookmarkFolder._id);
  32. }
  33. closeModal();
  34. } catch (err) {
  35. toastError(err);
  36. }
  37. }, [bookmarkFolder, onDeleted, closeModal]);
  38. const onClickDeleteButton = useCallback(async () => {
  39. await deleteBookmark();
  40. }, [deleteBookmark]);
  41. return (
  42. <div>
  43. <ModalHeader tag="h4" toggle={closeModal} className="text-danger">
  44. <span className="material-symbols-outlined">delete</span>
  45. {t('bookmark_folder.delete_modal.modal_header_label')}
  46. </ModalHeader>
  47. <ModalBody>
  48. <div className="pb-1 text-break">
  49. <span className="form-label">
  50. {t('bookmark_folder.delete_modal.modal_body_description')}:
  51. </span>
  52. <br />
  53. <FolderIcon isOpen={false} /> {bookmarkFolder?.name}
  54. </div>
  55. {t('bookmark_folder.delete_modal.modal_body_alert')}
  56. </ModalBody>
  57. <ModalFooter>
  58. <button
  59. type="button"
  60. className="btn btn-danger"
  61. onClick={onClickDeleteButton}
  62. >
  63. <span className="material-symbols-outlined" aria-hidden="true">
  64. delete
  65. </span>
  66. {t('bookmark_folder.delete_modal.modal_footer_button')}
  67. </button>
  68. </ModalFooter>
  69. </div>
  70. );
  71. };
  72. /**
  73. * DeleteBookmarkFolderModal - Container component (lightweight, always rendered)
  74. */
  75. const DeleteBookmarkFolderModal: FC = () => {
  76. const { isOpened, bookmarkFolder, opts } =
  77. useDeleteBookmarkFolderModalStatus();
  78. const { close: closeModal } = useDeleteBookmarkFolderModalActions();
  79. return (
  80. <Modal
  81. size="md"
  82. isOpen={isOpened}
  83. toggle={closeModal}
  84. data-testid="page-delete-modal"
  85. className="grw-create-page"
  86. >
  87. {isOpened && bookmarkFolder != null && (
  88. <DeleteBookmarkFolderModalSubstance
  89. bookmarkFolder={bookmarkFolder}
  90. onDeleted={opts?.onDeleted}
  91. closeModal={closeModal}
  92. />
  93. )}
  94. </Modal>
  95. );
  96. };
  97. export { DeleteBookmarkFolderModal };