2025-08-15 13:34:23 +02:00

139 lines
4.2 KiB
TypeScript

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import Button from './Button'
import TeamPremierRankBadge from './TeamPremierRankBadge'
import type { Team } from '../types/team'
type Props = {
team: Team
currentUserSteamId: string
invitationId?: string
onUpdateInvitation: (teamId: string, newValue: string | null | 'pending') => void
adminMode?: boolean
}
export default function TeamCard({
team,
currentUserSteamId,
invitationId,
onUpdateInvitation,
adminMode = false,
}: Props) {
const router = useRouter()
const [joining, setJoining] = useState(false)
const isRequested = Boolean(invitationId)
const isDisabled = joining || currentUserSteamId === team.leader?.steamId
const handleClick = async () => {
if (joining) return
setJoining(true)
try {
if (isRequested) {
await fetch('/api/user/invitations/reject', {
method : 'POST',
headers: { 'Content-Type': 'application/json' },
body : JSON.stringify({ invitationId }),
})
onUpdateInvitation(team.id, null)
} else {
await fetch('/api/team/request-join', {
method : 'POST',
headers: { 'Content-Type': 'application/json' },
body : JSON.stringify({ teamId: team.id }),
})
onUpdateInvitation(team.id, 'pending')
}
} catch (err) {
console.error('[TeamCard] Join/Reject-Fehler:', err)
} finally {
setJoining(false)
}
}
const targetHref = adminMode ? `/admin/teams/${team.id}` : `/team/${team.id}`
return (
<div
role="button"
tabIndex={0}
onClick={() => router.push(targetHref)}
onKeyDown={e => (e.key === 'Enter') && router.push(targetHref)}
className="p-4 border rounded-lg bg-white dark:bg-neutral-800
dark:border-neutral-700 shadow-sm hover:shadow-md
transition cursor-pointer focus:outline-none
hover:scale-105 hover:bg-neutral-200 hover:dark:bg-neutral-700"
>
<div className="flex items-center justify-between gap-3 mb-3">
<div className="flex items-center gap-3">
<img
src={team.logo ? `/assets/img/logos/${team.logo}` : `/assets/img/logos/cs2.webp`}
alt={team.name ?? 'Teamlogo'}
className="w-12 h-12 rounded-full object-cover border
border-gray-200 dark:border-neutral-600"
/>
<div className="flex items-center gap-2">
<span className="font-medium truncate text-gray-800 dark:text-neutral-200">
{team.name ?? 'Team'}
</span>
<TeamPremierRankBadge players={team.activePlayers} />
</div>
</div>
{adminMode ? (
<Button
title="Verwalten"
size="md"
color="blue"
variant="solid"
onClick={e => {
e.stopPropagation()
router.push(`/admin/teams/${team.id}`)
}}
>
Verwalten
</Button>
) : (
<Button
title={isRequested ? 'Angefragt (zurückziehen)' : 'Beitritt anfragen'}
size="sm"
color={isRequested ? 'gray' : 'blue'}
disabled={isDisabled}
onClick={e => { e.stopPropagation(); handleClick() }}
>
{joining ? (
<>
<span
className="animate-spin inline-block size-4 border-[3px] border-current border-t-transparent rounded-full mr-1"
role="status"
aria-label="loading"
/>
Lädt
</>
) : isRequested ? (
'Angefragt'
) : (
'Beitritt anfragen'
)}
</Button>
)}
</div>
<div className="flex -space-x-3">
{[...team.activePlayers, ...team.inactivePlayers].map(p => (
<img
key={p.steamId}
src={p.avatar}
alt={p.name}
title={p.name}
className="w-8 h-8 rounded-full border-2 border-white
dark:border-neutral-800 object-cover"
/>
))}
</div>
</div>
)
}