'use client' import { useState } from 'react' import { useTranslations, useLocale } from 'next-intl' import type { RecruitRewardView } from '@/lib/recruit-claim' import type { CharOption } from '@/components/CharacterSelect' import { wowheadUrl, wowheadData, wowheadIcon } from '@/lib/wowhead' function claimErrorKey(message?: string): string { switch (message) { case 'requirementsNotMet': return 'recruit.errRequirements' case 'alreadyClaimed': return 'recruit.errAlreadyClaimed' case 'invalidCharacter': return 'recruit.errInvalidCharacter' case 'notFound': return 'recruit.errNotFound' default: return 'recruit.errGeneric' } } /** * Panel de Recluta a un amigo: estadísticas de la cuenta + tabla de recompensas * (objetivo, objeto y estado) con botón para reclamar las disponibles. */ export function RecruitPanel({ rewards, characters, level80Count, isRecruited, recruitedCount, }: { rewards: RecruitRewardView[] characters: CharOption[] level80Count: number isRecruited: boolean recruitedCount: number }) { const t = useTranslations('UI') const locale = useLocale() const [character, setCharacter] = useState(characters[0]?.name ?? '') const selectedCss = characters.find((c) => c.name === character)?.classCss const [busyId, setBusyId] = useState(null) const [msg, setMsg] = useState<{ ok: boolean; text: string } | null>(null) const claimedCount = rewards.filter((r) => r.claimed).length const available = rewards.filter((r) => !r.claimed && level80Count >= r.required_friends) async function claim(reward: RecruitRewardView) { if (busyId !== null || !character) return setBusyId(reward.id) setMsg(null) try { const res = await fetch('/api/recruit/claim', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin', body: JSON.stringify({ rewardId: reward.id, character }), }) const d: { success?: boolean; message?: string } = await res.json() if (d.success) { window.location.reload() return } setMsg({ ok: false, text: t(claimErrorKey(d.message)) }) setBusyId(null) } catch { setMsg({ ok: false, text: t(claimErrorKey()) }) setBusyId(null) } } function rewardCell(r: RecruitRewardView) { const [quality, icon] = (r.icon_class || '').split(' ') return ( <> {r.reward_name} {r.item_quantity > 1 ? ` x${r.item_quantity}` : ''} ) } return ( <>

{t('recruit.accountRecruited')} {isRecruited ? t('recruit.yes') : t('recruit.no')}

{t('recruit.friendsRecruited')} {recruitedCount}

{t('recruit.friendsAtLevel80')} {level80Count}

{t('recruit.rewardsClaimed')} {claimedCount}/{rewards.length}


{characters.length > 0 && (

{t('recruit.receiveRewardsOn')}{' '}

)} {msg &&

{msg.text}

} {rewards.map((r) => { const eligible = level80Count >= r.required_friends return ( ) })}
{t('recruit.thFriends')} {t('recruit.thReward')} {t('recruit.thStatus')}
{t('recruit.friendsAtLevel80Row', { count: r.required_friends })} {rewardCell(r)} {r.claimed ? ( {t('recruit.claimed')} ) : eligible ? ( ) : ( {t('recruit.unclaimed')} )}


{t('recruit.availableRewards')}


{available.length === 0 ? ( {t('recruit.recruitToClaim')} ) : ( {t('recruit.readyToClaim', { count: available.length })} )} ) }