DeleteBookmarkFolderModal.tsx 3.0 KB

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