index.jsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import React, { useContext } from 'react';
  16. import { Banner } from '@douyinfe/semi-ui';
  17. import CardPro from '../../common/ui/CardPro';
  18. import SubscriptionsTable from './SubscriptionsTable';
  19. import SubscriptionsActions from './SubscriptionsActions';
  20. import SubscriptionsDescription from './SubscriptionsDescription';
  21. import AddEditSubscriptionModal from './modals/AddEditSubscriptionModal';
  22. import { useSubscriptionsData } from '../../../hooks/subscriptions/useSubscriptionsData';
  23. import { useIsMobile } from '../../../hooks/common/useIsMobile';
  24. import { createCardProPagination } from '../../../helpers/utils';
  25. import { StatusContext } from '../../../context/Status';
  26. const SubscriptionsPage = () => {
  27. const subscriptionsData = useSubscriptionsData();
  28. const isMobile = useIsMobile();
  29. const [statusState] = useContext(StatusContext);
  30. const enableEpay = !!statusState?.status?.enable_online_topup;
  31. const {
  32. showEdit,
  33. editingPlan,
  34. sheetPlacement,
  35. closeEdit,
  36. refresh,
  37. openCreate,
  38. compactMode,
  39. setCompactMode,
  40. t,
  41. } = subscriptionsData;
  42. return (
  43. <>
  44. <AddEditSubscriptionModal
  45. visible={showEdit}
  46. handleClose={closeEdit}
  47. editingPlan={editingPlan}
  48. placement={sheetPlacement}
  49. refresh={refresh}
  50. t={t}
  51. />
  52. <CardPro
  53. type='type1'
  54. descriptionArea={
  55. <SubscriptionsDescription
  56. compactMode={compactMode}
  57. setCompactMode={setCompactMode}
  58. t={t}
  59. />
  60. }
  61. actionsArea={
  62. <div className='flex flex-col md:flex-row justify-between items-start md:items-center gap-2 w-full'>
  63. {/* Mobile: actions first; Desktop: actions left */}
  64. <div className='order-1 md:order-0 w-full md:w-auto'>
  65. <SubscriptionsActions openCreate={openCreate} t={t} />
  66. </div>
  67. <Banner
  68. type='info'
  69. description={t('Stripe/Creem 需在第三方平台创建商品并填入 ID')}
  70. closeIcon={null}
  71. // Mobile: banner below; Desktop: banner right
  72. className='!rounded-lg order-2 md:order-1'
  73. style={{ maxWidth: '100%' }}
  74. />
  75. </div>
  76. }
  77. paginationArea={createCardProPagination({
  78. currentPage: subscriptionsData.activePage,
  79. pageSize: subscriptionsData.pageSize,
  80. total: subscriptionsData.planCount,
  81. onPageChange: subscriptionsData.handlePageChange,
  82. onPageSizeChange: subscriptionsData.handlePageSizeChange,
  83. isMobile,
  84. t: subscriptionsData.t,
  85. })}
  86. t={t}
  87. >
  88. <SubscriptionsTable {...subscriptionsData} enableEpay={enableEpay} />
  89. </CardPro>
  90. </>
  91. );
  92. };
  93. export default SubscriptionsPage;