Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

249 строки
8.9 KiB

  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, { useEffect, useState, useMemo, useContext } from 'react';
  16. import { useTranslation } from 'react-i18next';
  17. import { Typography } from '@douyinfe/semi-ui';
  18. import { getFooterHTML, getLogo, getSystemName } from '../../helpers';
  19. import { StatusContext } from '../../context/Status';
  20. const FooterBar = () => {
  21. const { t } = useTranslation();
  22. const [footer, setFooter] = useState(getFooterHTML());
  23. const systemName = getSystemName();
  24. const logo = getLogo();
  25. const [statusState] = useContext(StatusContext);
  26. const isDemoSiteMode = statusState?.status?.demo_site_enabled || false;
  27. const loadFooter = () => {
  28. let footer_html = localStorage.getItem('footer_html');
  29. if (footer_html) {
  30. setFooter(footer_html);
  31. }
  32. };
  33. const currentYear = new Date().getFullYear();
  34. const customFooter = useMemo(
  35. () => (
  36. <footer className='relative h-auto py-16 px-6 md:px-24 w-full flex flex-col items-center justify-between overflow-hidden'>
  37. <div className='absolute hidden md:block top-[204px] left-[-100px] w-[151px] h-[151px] rounded-full bg-[#FFD166]'></div>
  38. <div className='absolute md:hidden bottom-[20px] left-[-50px] w-[80px] h-[80px] rounded-full bg-[#FFD166] opacity-60'></div>
  39. {isDemoSiteMode && (
  40. <div className='flex flex-col md:flex-row justify-between w-full max-w-[1110px] mb-10 gap-8'>
  41. <div className='flex-shrink-0'>
  42. <img
  43. src={logo}
  44. alt={systemName}
  45. className='w-16 h-16 rounded-full bg-gray-800 p-1.5 object-contain'
  46. />
  47. </div>
  48. <div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-8 w-full'>
  49. <div className='text-left'>
  50. <p className='!text-semi-color-text-0 font-semibold mb-5'>
  51. {t('关于我们')}
  52. </p>
  53. <div className='flex flex-col gap-4'>
  54. <a
  55. href='https://docs.newapi.pro/wiki/project-introduction/'
  56. target='_blank'
  57. rel='noopener noreferrer'
  58. className='!text-semi-color-text-1'
  59. >
  60. {t('关于项目')}
  61. </a>
  62. <a
  63. href='https://docs.newapi.pro/support/community-interaction/'
  64. target='_blank'
  65. rel='noopener noreferrer'
  66. className='!text-semi-color-text-1'
  67. >
  68. {t('联系我们')}
  69. </a>
  70. <a
  71. href='https://docs.newapi.pro/wiki/features-introduction/'
  72. target='_blank'
  73. rel='noopener noreferrer'
  74. className='!text-semi-color-text-1'
  75. >
  76. {t('功能特性')}
  77. </a>
  78. </div>
  79. </div>
  80. <div className='text-left'>
  81. <p className='!text-semi-color-text-0 font-semibold mb-5'>
  82. {t('文档')}
  83. </p>
  84. <div className='flex flex-col gap-4'>
  85. <a
  86. href='https://docs.newapi.pro/getting-started/'
  87. target='_blank'
  88. rel='noopener noreferrer'
  89. className='!text-semi-color-text-1'
  90. >
  91. {t('快速开始')}
  92. </a>
  93. <a
  94. href='https://docs.newapi.pro/installation/'
  95. target='_blank'
  96. rel='noopener noreferrer'
  97. className='!text-semi-color-text-1'
  98. >
  99. {t('安装指南')}
  100. </a>
  101. <a
  102. href='https://docs.newapi.pro/api/'
  103. target='_blank'
  104. rel='noopener noreferrer'
  105. className='!text-semi-color-text-1'
  106. >
  107. {t('API 文档')}
  108. </a>
  109. </div>
  110. </div>
  111. <div className='text-left'>
  112. <p className='!text-semi-color-text-0 font-semibold mb-5'>
  113. {t('相关项目')}
  114. </p>
  115. <div className='flex flex-col gap-4'>
  116. <a
  117. href='https://github.com/songquanpeng/one-api'
  118. target='_blank'
  119. rel='noopener noreferrer'
  120. className='!text-semi-color-text-1'
  121. >
  122. One API
  123. </a>
  124. <a
  125. href='https://github.com/novicezk/midjourney-proxy'
  126. target='_blank'
  127. rel='noopener noreferrer'
  128. className='!text-semi-color-text-1'
  129. >
  130. Midjourney-Proxy
  131. </a>
  132. <a
  133. href='https://github.com/Calcium-Ion/neko-api-key-tool'
  134. target='_blank'
  135. rel='noopener noreferrer'
  136. className='!text-semi-color-text-1'
  137. >
  138. neko-api-key-tool
  139. </a>
  140. </div>
  141. </div>
  142. <div className='text-left'>
  143. <p className='!text-semi-color-text-0 font-semibold mb-5'>
  144. {t('友情链接')}
  145. </p>
  146. <div className='flex flex-col gap-4'>
  147. <a
  148. href='https://github.com/Calcium-Ion/new-api-horizon'
  149. target='_blank'
  150. rel='noopener noreferrer'
  151. className='!text-semi-color-text-1'
  152. >
  153. new-api-horizon
  154. </a>
  155. <a
  156. href='https://github.com/coaidev/coai'
  157. target='_blank'
  158. rel='noopener noreferrer'
  159. className='!text-semi-color-text-1'
  160. >
  161. CoAI
  162. </a>
  163. <a
  164. href='https://www.gpt-load.com/'
  165. target='_blank'
  166. rel='noopener noreferrer'
  167. className='!text-semi-color-text-1'
  168. >
  169. GPT-Load
  170. </a>
  171. </div>
  172. </div>
  173. </div>
  174. </div>
  175. )}
  176. {/*<div className='flex flex-col md:flex-row items-center justify-between w-full max-w-[1110px] gap-6'>*/}
  177. {/* <div className='flex flex-wrap items-center gap-2'>*/}
  178. {/* <Typography.Text className='text-sm !text-semi-color-text-1'>*/}
  179. {/* © {currentYear} {systemName}. {t('版权所有')}*/}
  180. {/* </Typography.Text>*/}
  181. {/* </div>*/}
  182. {/* <div className='text-sm'>*/}
  183. {/* <span className='!text-semi-color-text-1'>*/}
  184. {/* {t('设计与开发由')}{' '}*/}
  185. {/* </span>*/}
  186. {/* <a*/}
  187. {/* href='https://github.com/QuantumNous/new-api'*/}
  188. {/* target='_blank'*/}
  189. {/* rel='noopener noreferrer'*/}
  190. {/* className='!text-semi-color-primary font-medium'*/}
  191. {/* >*/}
  192. {/* New API*/}
  193. {/* </a>*/}
  194. {/* </div>*/}
  195. {/*</div>*/}
  196. </footer>
  197. ),
  198. [logo, systemName, t, currentYear, isDemoSiteMode],
  199. );
  200. useEffect(() => {
  201. loadFooter();
  202. }, []);
  203. return (
  204. <div className='w-full'>
  205. {footer ? (
  206. <div className='relative'>
  207. <div
  208. className='custom-footer'
  209. dangerouslySetInnerHTML={{ __html: footer }}
  210. ></div>
  211. <div className='absolute bottom-2 right-4 text-xs !text-semi-color-text-2 opacity-70'>
  212. <span>{t('设计与开发由')} </span>
  213. <a
  214. href='https://github.com/QuantumNous/new-api'
  215. target='_blank'
  216. rel='noopener noreferrer'
  217. className='!text-semi-color-primary font-medium'
  218. >
  219. New API
  220. </a>
  221. </div>
  222. </div>
  223. ) : (
  224. customFooter
  225. )}
  226. </div>
  227. );
  228. };
  229. export default FooterBar;