SupportFab.tsx 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * 站内客服 Widget - 右下角浮动按钮 + 支持面板(纯静态 UI,无后端)
  3. */
  4. 'use client';
  5. import { useState } from 'react';
  6. import { useTranslations } from 'next-intl';
  7. export function SupportFab() {
  8. const t = useTranslations('chat');
  9. const [open, setOpen] = useState(false);
  10. const suggestions = [t('q_balance'), t('q_key'), t('q_model')];
  11. return (
  12. <>
  13. {/* 支持面板 */}
  14. <div
  15. data-open={open}
  16. className="support-panel fixed bottom-[92px] right-[22px] z-[300] w-[330px] max-w-[calc(100vw-44px)] overflow-hidden rounded-[18px] border border-[rgba(124,92,255,.4)] bg-brand-card shadow-[0_18px_60px_rgba(0,0,0,.55)]"
  17. >
  18. <div
  19. className="flex items-center justify-between border-b border-white/[0.08] px-[18px] py-[14px]"
  20. style={{
  21. background: 'linear-gradient(120deg, rgba(124,92,255,.25), rgba(0,229,160,.1))',
  22. }}
  23. >
  24. <b className="text-[14.5px]">{t('title')}</b>
  25. <span className="flex items-center gap-[5px] text-[11.5px] text-brand-green-l">
  26. <span className="h-[7px] w-[7px] rounded-full bg-brand-green shadow-[0_0_8px_#00E5A0]" />
  27. {t('online')}
  28. </span>
  29. </div>
  30. <div className="px-[18px] py-4">
  31. <p className="mb-3 text-[13px] text-brand-muted">{t('hello')}</p>
  32. <div className="mb-3.5 flex flex-col gap-[7px]">
  33. {suggestions.map((s) => (
  34. <button
  35. key={s}
  36. type="button"
  37. className="rounded-[10px] border border-white/[0.08] bg-brand-card2 px-3 py-[9px] text-left text-[12.5px] text-brand-text transition-colors hover:border-brand-purple"
  38. >
  39. {s}
  40. </button>
  41. ))}
  42. </div>
  43. <div className="flex gap-2">
  44. <input
  45. type="text"
  46. placeholder={t('input')}
  47. className="flex-1 rounded-[10px] border border-white/[0.08] bg-brand-card2 px-3 py-2.5 text-[13px] text-brand-text outline-none focus:border-brand-purple"
  48. />
  49. <button
  50. type="button"
  51. aria-label="Send"
  52. className="w-10 rounded-[10px] bg-gradient-to-br from-brand-purple to-brand-purple-d text-[15px] text-white"
  53. >
  54. </button>
  55. </div>
  56. <div className="mt-3.5 flex justify-center gap-[7px]">
  57. <span className="inline-block rounded-full border border-[rgba(124,92,255,.35)] bg-[rgba(124,92,255,.12)] px-2.5 py-0.5 text-[11.5px] text-brand-purple-l">Zalo</span>
  58. <span className="inline-block rounded-full border border-[rgba(0,229,160,.3)] bg-[rgba(0,229,160,.1)] px-2.5 py-0.5 text-[11.5px] text-brand-green-l">Telegram</span>
  59. <span className="inline-block rounded-full border border-[rgba(154,163,192,.3)] bg-[rgba(154,163,192,.1)] px-2.5 py-0.5 text-[11.5px] text-brand-muted">Email</span>
  60. </div>
  61. </div>
  62. </div>
  63. {/* 浮动按钮 */}
  64. <button
  65. type="button"
  66. aria-label="Support"
  67. onClick={() => setOpen((v) => !v)}
  68. className="fixed bottom-[22px] right-[22px] z-[300] flex h-[58px] w-[58px] items-center justify-center rounded-full bg-gradient-to-br from-brand-purple to-brand-purple-d shadow-[0_6px_24px_rgba(124,92,255,.5)] transition-all duration-200 hover:scale-[1.08] hover:shadow-[0_8px_30px_rgba(124,92,255,.65)]"
  69. >
  70. <span className="animate-fab-pulse absolute -inset-1.5 rounded-full border-2 border-[rgba(124,92,255,.4)]" />
  71. <svg viewBox="0 0 24 24" width="26" height="26" fill="#fff">
  72. <path d="M12 3C7 3 3 6.6 3 11c0 2.3 1 4.3 2.7 5.8L5 20l3.4-1.5c1.1.4 2.3.5 3.6.5 5 0 9-3.6 9-8s-4-8-9-8z" />
  73. <circle cx="8.5" cy="11" r="1.2" fill="#0B1020" />
  74. <circle cx="12" cy="11" r="1.2" fill="#0B1020" />
  75. <circle cx="15.5" cy="11" r="1.2" fill="#0B1020" />
  76. </svg>
  77. </button>
  78. </>
  79. );
  80. }