| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 'use client';
- // D3 장착 지위 아이템 렌더 — 댓글/게시글 작성자·프로필 옆 배지 + 닉네임 이펙트.
- // EquippedItem[] 을 직접 받는 프레젠테이션 컴포넌트 (배치 조회는 상위에서 useEquippedItems 로).
- import '@/app/styles/reward.scss';
- import { EquipSlot, ItemKind, parseEffectPayload } from '@/types/reward';
- import type { EquippedItem } from '@/types/reward';
- interface BadgeProps {
- items: EquippedItem[]|undefined|null;
- }
- // 배지 슬롯만 렌더 (닉네임 옆 아이콘/라벨). 닉네임 이펙트는 NicknameText 로 분리.
- export function EquippedBadge({ items }: BadgeProps)
- {
- if (!items || items.length === 0) {
- return null;
- }
- const badge = items.find(i => i.slot === EquipSlot.Badge || i.kind === ItemKind.Badge);
- if (!badge) {
- return null;
- }
- const payload = parseEffectPayload(badge.effectPayload);
- const label = payload?.label ?? badge.productName;
- return (
- <span
- className='equipped-badge'
- title={badge.productName}
- style={payload?.background ? { background: payload.background, color: payload.textColor ?? payload.color } : undefined}
- >
- {badge.thumbnail ? (
- // eslint-disable-next-line @next/next/no-img-element
- <img src={badge.thumbnail} alt='' className='equipped-badge__icon' />
- ) : payload?.icon ? (
- <span className='equipped-badge__emoji' aria-hidden='true'>{payload.icon}</span>
- ) : null}
- <span className='equipped-badge__label'>{label}</span>
- </span>
- );
- }
- interface NicknameProps {
- name: string;
- items: EquippedItem[]|undefined|null;
- className?: string;
- }
- // 닉네임 이펙트 슬롯 적용 — 색상/강조. 이펙트 없으면 평범한 텍스트.
- export function NicknameText({ name, items, className }: NicknameProps)
- {
- const effect = items?.find(i => i.slot === EquipSlot.NicknameEffect || i.kind === ItemKind.NicknameEffect);
- const payload = parseEffectPayload(effect?.effectPayload);
- if (!effect || !payload) {
- return <span className={className}>{name}</span>;
- }
- const animCls = payload.animation ? ` nickname-effect--${payload.animation}` : '';
- return (
- <span
- className={`nickname-effect${animCls}${className ? ` ${className}` : ''}`}
- style={{ color: payload.color ?? payload.textColor }}
- >
- {name}
- </span>
- );
- }
- interface RowProps {
- name: string;
- items: EquippedItem[]|undefined|null;
- className?: string;
- }
- // 닉네임 이펙트 + 배지를 한 줄로 (작성자 표시 공용).
- export function EquippedNickname({ name, items, className }: RowProps)
- {
- return (
- <span className={`inline-flex items-center gap-1 align-middle${className ? ` ${className}` : ''}`}>
- <NicknameText name={name} items={items} />
- <EquippedBadge items={items} />
- </span>
- );
- }
|