NoticeModal.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import React, { useEffect, useState } from 'react';
  2. import { Button, Modal, Empty } from '@douyinfe/semi-ui';
  3. import { useTranslation } from 'react-i18next';
  4. import { API, showError } from '../helpers';
  5. import { marked } from 'marked';
  6. import { IllustrationNoContent, IllustrationNoContentDark } from '@douyinfe/semi-illustrations';
  7. const NoticeModal = ({ visible, onClose, isMobile }) => {
  8. const { t } = useTranslation();
  9. const [noticeContent, setNoticeContent] = useState('');
  10. const [loading, setLoading] = useState(false);
  11. const handleCloseTodayNotice = () => {
  12. const today = new Date().toDateString();
  13. localStorage.setItem('notice_close_date', today);
  14. onClose();
  15. };
  16. const displayNotice = async () => {
  17. setLoading(true);
  18. try {
  19. const res = await API.get('/api/notice');
  20. const { success, message, data } = res.data;
  21. if (success) {
  22. if (data !== '') {
  23. const htmlNotice = marked.parse(data);
  24. setNoticeContent(htmlNotice);
  25. } else {
  26. setNoticeContent('');
  27. }
  28. } else {
  29. showError(message);
  30. }
  31. } catch (error) {
  32. showError(error.message);
  33. } finally {
  34. setLoading(false);
  35. }
  36. };
  37. useEffect(() => {
  38. if (visible) {
  39. displayNotice();
  40. }
  41. }, [visible]);
  42. const renderContent = () => {
  43. if (loading) {
  44. return <div className="py-12"><Empty description={t('加载中...')} /></div>;
  45. }
  46. if (!noticeContent) {
  47. return (
  48. <div className="py-12">
  49. <Empty
  50. image={<IllustrationNoContent style={{ width: 150, height: 150 }} />}
  51. darkModeImage={<IllustrationNoContentDark style={{ width: 150, height: 150 }} />}
  52. description={t('暂无公告')}
  53. />
  54. </div>
  55. );
  56. }
  57. return (
  58. <div
  59. dangerouslySetInnerHTML={{ __html: noticeContent }}
  60. className="max-h-[60vh] overflow-y-auto pr-2"
  61. style={{
  62. scrollbarWidth: 'thin',
  63. scrollbarColor: 'var(--semi-color-tertiary) transparent'
  64. }}
  65. />
  66. );
  67. };
  68. return (
  69. <Modal
  70. title={t('系统公告')}
  71. visible={visible}
  72. onCancel={onClose}
  73. footer={(
  74. <div className="flex justify-end">
  75. <Button type='secondary' className='!rounded-full' onClick={handleCloseTodayNotice}>{t('今日关闭')}</Button>
  76. <Button type="primary" className='!rounded-full' onClick={onClose}>{t('关闭公告')}</Button>
  77. </div>
  78. )}
  79. size={isMobile ? 'full-width' : 'large'}
  80. >
  81. {renderContent()}
  82. </Modal>
  83. );
  84. };
  85. export default NoticeModal;