ShareModal.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import * as React from 'react';
  2. import { Icon } from './ui/Icon';
  3. import { useTranslation } from '../hooks/useI18n';
  4. interface ShareModalProps {
  5. pageSlug: string;
  6. onClose: () => void;
  7. }
  8. const QRCode: React.FC<{ url: string }> = ({ url }) => {
  9. const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(url)}`;
  10. return <img src={qrUrl} alt="QR Code" className="w-32 h-32 rounded-lg" />
  11. };
  12. const ShareModal: React.FC<ShareModalProps> = ({ pageSlug, onClose }) => {
  13. const { t } = useTranslation();
  14. const [copiedLink, setCopiedLink] = React.useState<string | null>(null);
  15. const baseUrl = `${window.location.origin}${window.location.pathname.replace(/\/$/, '')}`;
  16. const pcUrl = `${baseUrl}?page=${pageSlug}&view=pc`;
  17. const mobileUrl = `${baseUrl}?page=${pageSlug}&view=mobile`;
  18. const handleCopy = (url: string, type: string) => {
  19. navigator.clipboard.writeText(url).then(() => {
  20. setCopiedLink(type);
  21. setTimeout(() => setCopiedLink(null), 2000);
  22. });
  23. };
  24. return (
  25. <div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center backdrop-blur-sm" onClick={onClose}>
  26. <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-3xl p-8 border border-gray-200 dark:border-gray-700" onClick={e => e.stopPropagation()}>
  27. <div className="flex justify-between items-center mb-6">
  28. <h2 className="text-3xl font-bold text-gray-900 dark:text-white">{t('modal.share.title')}</h2>
  29. <button onClick={onClose} className="text-gray-400 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
  30. <Icon className="h-8 w-8"><path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" /></Icon>
  31. </button>
  32. </div>
  33. <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
  34. {/* PC Version */}
  35. <div className="text-center">
  36. <h3 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('modal.share.pc_version')}</h3>
  37. <div className="flex justify-center mb-4">
  38. <QRCode url={pcUrl} />
  39. </div>
  40. <div className="flex items-center bg-gray-100 dark:bg-gray-700 rounded-md">
  41. <input type="text" readOnly value={pcUrl} className="flex-1 bg-transparent p-2 text-sm text-gray-600 dark:text-gray-300 focus:outline-none truncate" />
  42. <button onClick={() => handleCopy(pcUrl, 'pc')} className="bg-brand-primary text-white font-semibold py-2 px-3 rounded-r-md hover:bg-brand-secondary text-sm">
  43. {copiedLink === 'pc' ? t('modal.share.copied') : t('modal.share.copy')}
  44. </button>
  45. </div>
  46. </div>
  47. {/* Mobile Version */}
  48. <div className="text-center">
  49. <h3 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('modal.share.mobile_version')}</h3>
  50. <div className="flex justify-center mb-4">
  51. <QRCode url={mobileUrl} />
  52. </div>
  53. <div className="flex items-center bg-gray-100 dark:bg-gray-700 rounded-md">
  54. <input type="text" readOnly value={mobileUrl} className="flex-1 bg-transparent p-2 text-sm text-gray-600 dark:text-gray-300 focus:outline-none truncate" />
  55. <button onClick={() => handleCopy(mobileUrl, 'mobile')} className="bg-brand-primary text-white font-semibold py-2 px-3 rounded-r-md hover:bg-brand-secondary text-sm">
  56. {copiedLink === 'mobile' ? t('modal.share.copied') : t('modal.share.copy')}
  57. </button>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. );
  64. };
  65. export default ShareModal;