index.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 'use client'
  2. import React, { useEffect, useRef, useState } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import {
  5. RiQrCodeLine,
  6. } from '@remixicon/react'
  7. import { QRCodeCanvas as QRCode } from 'qrcode.react'
  8. import ActionButton from '@/app/components/base/action-button'
  9. import Tooltip from '@/app/components/base/tooltip'
  10. type Props = {
  11. content: string
  12. }
  13. const prefixEmbedded = 'appOverview.overview.appInfo.qrcode.title'
  14. const ShareQRCode = ({ content }: Props) => {
  15. const { t } = useTranslation()
  16. const [isShow, setIsShow] = useState<boolean>(false)
  17. const qrCodeRef = useRef<HTMLDivElement>(null)
  18. const toggleQRCode = (event: React.MouseEvent) => {
  19. event.stopPropagation()
  20. setIsShow(prev => !prev)
  21. }
  22. useEffect(() => {
  23. const handleClickOutside = (event: MouseEvent) => {
  24. if (qrCodeRef.current && !qrCodeRef.current.contains(event.target as Node))
  25. setIsShow(false)
  26. }
  27. if (isShow)
  28. document.addEventListener('click', handleClickOutside)
  29. return () => {
  30. document.removeEventListener('click', handleClickOutside)
  31. }
  32. }, [isShow])
  33. const downloadQR = () => {
  34. const canvas = document.getElementsByTagName('canvas')[0]
  35. const link = document.createElement('a')
  36. link.download = 'qrcode.png'
  37. link.href = canvas.toDataURL()
  38. link.click()
  39. }
  40. const handlePanelClick = (event: React.MouseEvent) => {
  41. event.stopPropagation()
  42. }
  43. return (
  44. <Tooltip
  45. popupContent={t(`${prefixEmbedded}`) || ''}
  46. >
  47. <div className='relative w-6 h-6' onClick={toggleQRCode}>
  48. <ActionButton>
  49. <RiQrCodeLine className='w-4 h-4' />
  50. </ActionButton>
  51. {isShow && (
  52. <div
  53. ref={qrCodeRef}
  54. className='absolute top-8 -right-8 z-10 w-[232px] flex flex-col items-center bg-components-panel-bg shadow-xs rounded-lg p-4'
  55. onClick={handlePanelClick}
  56. >
  57. <QRCode size={160} value={content} className='mb-2' />
  58. <div className='flex items-center system-xs-regular'>
  59. <div className='text-text-tertiary'>{t('appOverview.overview.appInfo.qrcode.scan')}</div>
  60. <div className='text-text-tertiary'>·</div>
  61. <div className='text-text-accent-secondary cursor-pointer' onClick={downloadQR}>{t('appOverview.overview.appInfo.qrcode.download')}</div>
  62. </div>
  63. </div>
  64. )}
  65. </div>
  66. </Tooltip>
  67. )
  68. }
  69. export default ShareQRCode