AlertPreviewPanel.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use client';
  2. import { useState } from 'react';
  3. import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
  4. import { faPlay } from '@fortawesome/free-solid-svg-icons';
  5. import {
  6. DONATION_AMOUNT_MIN, DONATION_AMOUNT_MAX, DONATION_AMOUNT_STEP, DONATION_AMOUNT_DEFAULT,
  7. ALERT_NAME_MAX_LENGTH, ALERT_MESSAGE_MAX_LENGTH,
  8. PREVIEW_DEFAULT_NAME, PREVIEW_DEFAULT_MESSAGE
  9. } from '@/constants/donation';
  10. type Props = {
  11. widgetToken: string|null;
  12. iframeRef: React.RefObject<HTMLIFrameElement|null>;
  13. };
  14. export default function AlertPreviewPanel({ widgetToken, iframeRef }: Props) {
  15. const [previewName, setPreviewName] = useState(PREVIEW_DEFAULT_NAME);
  16. const [previewAmount, setPreviewAmount] = useState(DONATION_AMOUNT_DEFAULT);
  17. const [previewMessage, setPreviewMessage] = useState(PREVIEW_DEFAULT_MESSAGE);
  18. const handlePreview = () => {
  19. if (!iframeRef.current?.contentWindow) {
  20. return;
  21. }
  22. iframeRef.current.contentWindow.postMessage({
  23. type: 'ALERT_TEST',
  24. sendName: previewName || PREVIEW_DEFAULT_NAME,
  25. amount: previewAmount || DONATION_AMOUNT_DEFAULT,
  26. message: previewMessage || '',
  27. }, window.location.origin);
  28. };
  29. return (
  30. <aside className="alert-config__preview-panel">
  31. {/* 미리보기 iframe */}
  32. <div className="alert-config__widget">
  33. <div className="alert-config__widget-label">미리보기</div>
  34. {widgetToken ? (
  35. <iframe
  36. ref={iframeRef}
  37. src={`/widget/alert/${widgetToken}?preview=1`}
  38. className="alert-config__widget-frame"
  39. title="알림 미리보기"
  40. />
  41. ) : (
  42. <div className="alert-config__widget-empty">채널 정보를 불러오는 중...</div>
  43. )}
  44. </div>
  45. {/* 미리보기 form */}
  46. <fieldset className="alert-config__fieldset">
  47. <legend className="alert-config__legend">미리보기</legend>
  48. <div className="alert-config__preview-form">
  49. <div className="alert-config__field">
  50. <label htmlFor="preview-amount" className="alert-config__field-label">후원 금액 (원)</label>
  51. <input
  52. id="preview-amount"
  53. type="number"
  54. className="alert-config__input"
  55. min={DONATION_AMOUNT_MIN}
  56. max={DONATION_AMOUNT_MAX}
  57. step={DONATION_AMOUNT_STEP}
  58. value={previewAmount}
  59. onChange={e => setPreviewAmount(parseInt(e.target.value) || DONATION_AMOUNT_DEFAULT)}
  60. />
  61. </div>
  62. <div className="alert-config__field">
  63. <label htmlFor="preview-name" className="alert-config__field-label">이름</label>
  64. <input
  65. id="preview-name"
  66. type="text"
  67. className="alert-config__input"
  68. maxLength={ALERT_NAME_MAX_LENGTH}
  69. value={previewName}
  70. onChange={e => setPreviewName(e.target.value)}
  71. placeholder="후원자 이름"
  72. />
  73. </div>
  74. <div className="alert-config__field">
  75. <label htmlFor="preview-message" className="alert-config__field-label">보낼 내용</label>
  76. <input
  77. id="preview-message"
  78. type="text"
  79. className="alert-config__input"
  80. maxLength={ALERT_MESSAGE_MAX_LENGTH}
  81. value={previewMessage}
  82. onChange={e => setPreviewMessage(e.target.value)}
  83. placeholder="후원 메시지"
  84. />
  85. </div>
  86. <button
  87. type="button"
  88. className="alert-config__btn alert-config__btn--primary alert-config__preview-btn"
  89. onClick={handlePreview}
  90. disabled={!widgetToken}
  91. >
  92. <FontAwesomeIcon icon={faPlay} />
  93. 미리보기
  94. </button>
  95. </div>
  96. </fieldset>
  97. </aside>
  98. );
  99. }