ConfigBlock.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import type { MouseEvent } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { Button, Collapse, Popover, Tag, Tooltip, message } from 'antd';
  4. import { CopyOutlined, DownloadOutlined, QrcodeOutlined } from '@ant-design/icons';
  5. import { ClipboardManager, FileManager } from '@/utils';
  6. import { QrPanel } from '@/pages/inbounds/qr';
  7. import './ConfigBlock.css';
  8. interface ConfigBlockProps {
  9. label: string;
  10. text: string;
  11. fileName: string;
  12. qrRemark?: string;
  13. showQr?: boolean;
  14. tagColor?: string;
  15. defaultOpen?: boolean;
  16. }
  17. export default function ConfigBlock({
  18. label,
  19. text,
  20. fileName,
  21. qrRemark = '',
  22. showQr = true,
  23. tagColor = 'gold',
  24. defaultOpen = false,
  25. }: ConfigBlockProps) {
  26. const { t } = useTranslation();
  27. const [messageApi, messageContextHolder] = message.useMessage();
  28. async function copy() {
  29. const ok = await ClipboardManager.copyText(text);
  30. if (ok) messageApi.success(t('copied'));
  31. }
  32. const actions = (
  33. /* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
  34. <div className="config-block-actions" onClick={(e: MouseEvent) => e.stopPropagation()}>
  35. <Tooltip title={t('copy')}>
  36. <Button size="small" icon={<CopyOutlined />} aria-label={t('copy')} onClick={copy} />
  37. </Tooltip>
  38. <Tooltip title={t('download')}>
  39. <Button
  40. size="small"
  41. icon={<DownloadOutlined />}
  42. aria-label={t('download')}
  43. onClick={() => FileManager.downloadTextFile(text, fileName)}
  44. />
  45. </Tooltip>
  46. {showQr && (
  47. <Popover
  48. trigger="click"
  49. placement="left"
  50. destroyOnHidden
  51. content={<QrPanel value={text} remark={qrRemark || label} size={220} />}
  52. >
  53. <Tooltip title={t('pages.clients.qrCode')}>
  54. <Button size="small" icon={<QrcodeOutlined />} aria-label={t('pages.clients.qrCode')} />
  55. </Tooltip>
  56. </Popover>
  57. )}
  58. </div>
  59. );
  60. return (
  61. <>
  62. {messageContextHolder}
  63. <Collapse
  64. className="config-block"
  65. collapsible="header"
  66. defaultActiveKey={defaultOpen ? ['cfg'] : []}
  67. items={[
  68. {
  69. key: 'cfg',
  70. label: (
  71. <Tag color={tagColor} style={{ margin: 0, fontWeight: 600, letterSpacing: '0.3px' }}>
  72. {label}
  73. </Tag>
  74. ),
  75. extra: actions,
  76. children: <code className="config-block-text">{text}</code>,
  77. },
  78. ]}
  79. />
  80. </>
  81. );
  82. }