CrewWidgetPreviewPanel.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. 'use client';
  2. import { MOCK_CREW_RANKING } from '../constants';
  3. import type { FormState } from '../types';
  4. type Props = {
  5. form: FormState;
  6. };
  7. const THEME_NAMES = ['basic', 'dark', 'minimal'];
  8. export default function CrewWidgetPreviewPanel({ form }: Props)
  9. {
  10. const visibleItems = MOCK_CREW_RANKING.slice(0, form.maxDisplayCount);
  11. const themeName = THEME_NAMES[form.theme] ?? 'basic';
  12. const getFontStyle = (rank: number) => {
  13. if (rank === 1) {
  14. return {
  15. fontFamily: form.rank1FontFamily || undefined,
  16. fontSize: `${form.rank1FontSizePx}px`,
  17. color: form.rank1FontColor
  18. };
  19. }
  20. if (rank === 2) {
  21. return {
  22. fontFamily: form.rank2FontFamily || undefined,
  23. fontSize: `${form.rank2FontSizePx}px`,
  24. color: form.rank2FontColor
  25. };
  26. }
  27. if (rank === 3) {
  28. return {
  29. fontFamily: form.rank3FontFamily || undefined,
  30. fontSize: `${form.rank3FontSizePx}px`,
  31. color: form.rank3FontColor
  32. };
  33. }
  34. return {
  35. fontFamily: form.rowFontFamily || undefined,
  36. fontSize: `${form.rowFontSizePx}px`,
  37. color: form.rowFontColor
  38. };
  39. };
  40. const getBadgeClass = (rank: number) => {
  41. if (rank <= 3) {
  42. return `crew-widget-preview__badge--${rank}`;
  43. }
  44. return 'crew-widget-preview__badge--default';
  45. };
  46. return (
  47. <aside className="crew-widget-preview">
  48. <div className="crew-widget-preview__widget">
  49. <div className="crew-widget-preview__widget-label">미리보기</div>
  50. <div
  51. className={`crew-widget-preview__widget-body crew-widget-preview__widget-body--${themeName}`}
  52. style={{ backgroundColor: form.bgColor }}
  53. >
  54. {/* 위젯 제목 */}
  55. <div className="crew-widget-preview__title" style={{
  56. fontFamily: form.titleFontFamily || undefined,
  57. fontSize: `${form.titleFontSizePx}px`,
  58. color: form.titleFontColor
  59. }}>
  60. {form.title || '크루 순위'}
  61. </div>
  62. {/* 컬럼 헤더 */}
  63. <div className="crew-widget-preview__columns">
  64. <span className="crew-widget-preview__col-rank">순위</span>
  65. {form.isShowMemberIcon && <span className="crew-widget-preview__col-icon" />}
  66. <span className="crew-widget-preview__col-name">이름</span>
  67. {form.isShowContributionRate && <span className="crew-widget-preview__col-rate">기여도</span>}
  68. {form.isShowAmount && <span className="crew-widget-preview__col-amount">후원 점수</span>}
  69. {form.isShowDonationCount && <span className="crew-widget-preview__col-count">건수</span>}
  70. </div>
  71. {/* 순위 리스트 */}
  72. <div className="crew-widget-preview__list">
  73. {visibleItems.map(item => {
  74. const style = getFontStyle(item.rank);
  75. return (
  76. <div
  77. key={item.rank}
  78. className={`crew-widget-preview__item${item.rank <= 3 ? ` crew-widget-preview__item--${item.rank}` : ''}`}
  79. style={style}
  80. >
  81. <span className={`crew-widget-preview__badge ${getBadgeClass(item.rank)}`}>
  82. {item.rank}
  83. </span>
  84. {form.isShowMemberIcon && <span className="crew-widget-preview__member-icon" />}
  85. <span className="crew-widget-preview__name">{item.nickname}</span>
  86. {form.isShowContributionRate && (
  87. <span className="crew-widget-preview__rate">{item.contributionRate.toFixed(1)}%</span>
  88. )}
  89. {form.isShowAmount && (
  90. <span className="crew-widget-preview__amount">{item.totalAmount.toLocaleString()}원</span>
  91. )}
  92. {form.isShowDonationCount && (
  93. <span className="crew-widget-preview__count">{item.donationCount}건</span>
  94. )}
  95. </div>
  96. );
  97. })}
  98. </div>
  99. </div>
  100. </div>
  101. </aside>
  102. );
  103. }