Compare commits

..

3 Commits

Author SHA1 Message Date
bcdb2d41d7 Merge branch 'main' of https://git.rother-woelki.de/chris/ironie-nextjs
# Conflicts:
#	src/app/[locale]/components/CommunityMatchList.tsx
2025-09-26 14:50:17 +02:00
960871f95a timezone via cookie 2025-09-25 21:15:27 +02:00
c03811e860 timezone via cookies 2025-09-25 20:39:06 +02:00
21 changed files with 94 additions and 78 deletions

View File

@ -170,7 +170,7 @@ export default function GameBanner(props: Props) {
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="text-sm flex items-center gap-2"> <div className="text-sm flex items-center gap-2">
<span className="inline-flex items-center gap-1 font-semibold px-2 py-0.5 rounded-md bg-white/10 ring-1 ring-white/15"> <span className="inline-flex items-center gap-1 font-semibold px-2 py-0.5 rounded-md bg-white/10 ring-1 ring-white/15">
{isConnected ? (serverLabel ?? 'CS2 Server') : t('disconnected')} {isConnected ? (serverLabel ?? 'CS2 Server') : t('not-connected')}
</span> </span>
</div> </div>
<InfoRow /> <InfoRow />

View File

@ -401,11 +401,11 @@ export default function MapVotePanel({ match }: Props) {
}, [match, state?.teams?.teamB?.players]) }, [match, state?.teams?.teamB?.players])
const teamAPlayersForRank = useMemo( const teamAPlayersForRank = useMemo(
() => playersA.map(p => ({ premierRank: p.stats?.rankNew ?? 0 })) as any, () => playersA.map(p => ({ premierRank: p.user.premierRank ?? 0 })) as any,
[playersA] [playersA]
) )
const teamBPlayersForRank = useMemo( const teamBPlayersForRank = useMemo(
() => playersB.map(p => ({ premierRank: p.stats?.rankNew ?? 0 })) as any, () => playersB.map(p => ({ premierRank: p.user.premierRank ?? 0 })) as any,
[playersB] [playersB]
) )
@ -647,7 +647,7 @@ export default function MapVotePanel({ match }: Props) {
side={teamLeftKey === 'teamA' ? 'A' : 'B'} side={teamLeftKey === 'teamA' ? 'A' : 'B'}
name={p.user.name ?? 'Unbekannt'} name={p.user.name ?? 'Unbekannt'}
avatar={p.user.avatar} avatar={p.user.avatar}
rank={p.stats?.rankNew ?? 0} rank={p.user.premierRank ?? 0}
matchType={match.matchType} matchType={match.matchType}
onClick={() => router.push(`/profile/${p.user.steamId}`)} onClick={() => router.push(`/profile/${p.user.steamId}`)}
isLeader={(state?.teams?.[teamLeftKey]?.leader?.steamId ?? teamLeft?.leader?.steamId) === p.user.steamId} isLeader={(state?.teams?.[teamLeftKey]?.leader?.steamId ?? teamLeft?.leader?.steamId) === p.user.steamId}
@ -818,7 +818,7 @@ export default function MapVotePanel({ match }: Props) {
side={teamRightKey === 'teamA' ? 'A' : 'B'} side={teamRightKey === 'teamA' ? 'A' : 'B'}
name={p.user.name ?? 'Unbekannt'} name={p.user.name ?? 'Unbekannt'}
avatar={p.user.avatar} avatar={p.user.avatar}
rank={p.stats?.rankNew ?? 0} rank={p.user.premierRank ?? 0}
matchType={match.matchType} matchType={match.matchType}
onClick={() => router.push(`/profile/${p.user.steamId}`)} onClick={() => router.push(`/profile/${p.user.steamId}`)}
isLeader={(state?.teams?.[teamRightKey]?.leader?.steamId ?? teamRight?.leader?.steamId) === p.user.steamId} isLeader={(state?.teams?.[teamRightKey]?.leader?.steamId ?? teamRight?.leader?.steamId) === p.user.steamId}

View File

@ -472,9 +472,18 @@ export function MatchDetails({match, initialNow}: { match: Match; initialNow: nu
<Table.Cell> <Table.Cell>
<div className="flex items-center gap-[6px]"> <div className="flex items-center gap-[6px]">
{match.matchType === 'premier' {match.matchType === 'premier' ? (
? <PremierRankBadge rank={p.stats?.rankNew ?? 0} /> // Premier-Match: Premier-Badge aus Stats (Fallback auf User)
: <CompRankBadge rank={p.stats?.rankNew ?? 0} />} <PremierRankBadge rank={p.stats?.rankNew ?? p.user?.premierRank ?? 0} />
) : match.matchType === 'community' ? (
// Community-Match: IMMER Premier-Badge Quelle primär User.premierRank
<PremierRankBadge rank={p.user?.premierRank ?? p.stats?.rankNew ?? 0} />
) : (
// Alle anderen (z. B. competitive): Comp-Badge
<CompRankBadge rank={p.stats?.rankNew ?? 0} />
)}
{/* Rangänderung nur für echte Premier-Matches anzeigen */}
{match.matchType === 'premier' && typeof p.stats?.rankChange === 'number' && ( {match.matchType === 'premier' && typeof p.stats?.rankChange === 'number' && (
<span <span
className={`text-sm ${ className={`text-sm ${

View File

@ -1,20 +1,27 @@
'use client' 'use client'
import { useMemo } from 'react'
import PremierRankBadge from './PremierRankBadge' import PremierRankBadge from './PremierRankBadge'
import { Player } from '../../../types/team'
type Props = { type PlayerLike = { premierRank?: number | null }
players: Player[] type Props = { players: PlayerLike[] }
}
export default function TeamPremierRankBadge({ players }: Props) { export default function TeamPremierRankBadge({ players }: Props) {
const totalRank = players.reduce((sum, p) => { const avgRank = useMemo(() => {
return typeof p.premierRank === 'number' ? sum + p.premierRank : sum const ranks = players
}, 0) .map(p => p.premierRank ?? 0)
.filter(r => Number.isFinite(r) && r > 0) // 0/undef als "unbekannt" ignorieren
if (ranks.length === 0) return 0
const sum = ranks.reduce((a, b) => a + b, 0)
return Math.round(sum / ranks.length) // oder Math.floor / Math.ceil
}, [players])
// Optional: gar nichts anzeigen, wenn kein valider Rank vorhanden
// if (avgRank === 0) return null
return ( return (
<div className="mt-1"> <div className="mt-1">
<PremierRankBadge rank={totalRank} /> <PremierRankBadge rank={avgRank} />
</div> </div>
) )
} }

View File

@ -74,7 +74,7 @@ export async function POST(req: NextRequest) {
data: { data: {
user : { connect: { steamId } }, user : { connect: { steamId } },
title : 'Team verlassen', title : 'Team verlassen',
message : `Du wurdest aus dem Team „${teamName}entfernt.`, message : `Du wurdest aus dem Team „${teamName}geworfen.`,
actionType : 'team-kick-self', actionType : 'team-kick-self',
}, },
}) })

View File

@ -35,11 +35,11 @@ exports.Prisma = Prisma
exports.$Enums = {} exports.$Enums = {}
/** /**
* Prisma Client JS version: 6.16.2 * Prisma Client JS version: 6.16.1
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43 * Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/ */
Prisma.prismaVersion = { Prisma.prismaVersion = {
client: "6.16.2", client: "6.16.1",
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43" engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
} }
@ -369,7 +369,7 @@ const config = {
"value": "prisma-client-js" "value": "prisma-client-js"
}, },
"output": { "output": {
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma", "value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
"fromEnvVar": null "fromEnvVar": null
}, },
"config": { "config": {
@ -383,7 +383,7 @@ const config = {
} }
], ],
"previewFeatures": [], "previewFeatures": [],
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma", "sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
"isCustomOutput": true "isCustomOutput": true
}, },
"relativeEnvPaths": { "relativeEnvPaths": {
@ -391,7 +391,7 @@ const config = {
"schemaEnvPath": "../../../.env" "schemaEnvPath": "../../../.env"
}, },
"relativePath": "../../../prisma", "relativePath": "../../../prisma",
"clientVersion": "6.16.2", "clientVersion": "6.16.1",
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43", "engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"datasourceNames": [ "datasourceNames": [
"db" "db"

View File

@ -20,11 +20,11 @@ exports.Prisma = Prisma
exports.$Enums = {} exports.$Enums = {}
/** /**
* Prisma Client JS version: 6.16.2 * Prisma Client JS version: 6.16.1
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43 * Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/ */
Prisma.prismaVersion = { Prisma.prismaVersion = {
client: "6.16.2", client: "6.16.1",
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43" engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
} }

View File

@ -460,7 +460,7 @@ export namespace Prisma {
export import Exact = $Public.Exact export import Exact = $Public.Exact
/** /**
* Prisma Client JS version: 6.16.2 * Prisma Client JS version: 6.16.1
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43 * Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/ */
export type PrismaVersion = { export type PrismaVersion = {

View File

@ -35,11 +35,11 @@ exports.Prisma = Prisma
exports.$Enums = {} exports.$Enums = {}
/** /**
* Prisma Client JS version: 6.16.2 * Prisma Client JS version: 6.16.1
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43 * Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/ */
Prisma.prismaVersion = { Prisma.prismaVersion = {
client: "6.16.2", client: "6.16.1",
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43" engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
} }
@ -370,7 +370,7 @@ const config = {
"value": "prisma-client-js" "value": "prisma-client-js"
}, },
"output": { "output": {
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma", "value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
"fromEnvVar": null "fromEnvVar": null
}, },
"config": { "config": {
@ -384,7 +384,7 @@ const config = {
} }
], ],
"previewFeatures": [], "previewFeatures": [],
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma", "sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
"isCustomOutput": true "isCustomOutput": true
}, },
"relativeEnvPaths": { "relativeEnvPaths": {
@ -392,7 +392,7 @@ const config = {
"schemaEnvPath": "../../../.env" "schemaEnvPath": "../../../.env"
}, },
"relativePath": "../../../prisma", "relativePath": "../../../prisma",
"clientVersion": "6.16.2", "clientVersion": "6.16.1",
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43", "engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"datasourceNames": [ "datasourceNames": [
"db" "db"

View File

@ -151,7 +151,7 @@
}, },
"./*": "./*" "./*": "./*"
}, },
"version": "6.16.2", "version": "6.16.1",
"sideEffects": false, "sideEffects": false,
"imports": { "imports": {
"#wasm-engine-loader": { "#wasm-engine-loader": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -35,11 +35,11 @@ exports.Prisma = Prisma
exports.$Enums = {} exports.$Enums = {}
/** /**
* Prisma Client JS version: 6.16.2 * Prisma Client JS version: 6.16.1
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43 * Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/ */
Prisma.prismaVersion = { Prisma.prismaVersion = {
client: "6.16.2", client: "6.16.1",
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43" engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
} }
@ -369,7 +369,7 @@ const config = {
"value": "prisma-client-js" "value": "prisma-client-js"
}, },
"output": { "output": {
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma", "value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
"fromEnvVar": null "fromEnvVar": null
}, },
"config": { "config": {
@ -383,7 +383,7 @@ const config = {
} }
], ],
"previewFeatures": [], "previewFeatures": [],
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma", "sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
"isCustomOutput": true "isCustomOutput": true
}, },
"relativeEnvPaths": { "relativeEnvPaths": {
@ -391,7 +391,7 @@ const config = {
"schemaEnvPath": "../../../.env" "schemaEnvPath": "../../../.env"
}, },
"relativePath": "../../../prisma", "relativePath": "../../../prisma",
"clientVersion": "6.16.2", "clientVersion": "6.16.1",
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43", "engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"datasourceNames": [ "datasourceNames": [
"db" "db"

View File

@ -111,7 +111,7 @@
} }
}, },
"game-banner": { "game-banner": {
"disconnected": "Nicht verbunden", "not-connected": "Nicht verbunden",
"player-connected": "Spieler verbunden", "player-connected": "Spieler verbunden",
"open-game": "Spiel starten", "open-game": "Spiel starten",
"quit": "Beenden", "quit": "Beenden",

View File

@ -111,7 +111,7 @@
} }
}, },
"game-banner": { "game-banner": {
"disconnected": "Disconnected", "not-connected": "Not connected",
"player-connected": "Players connected", "player-connected": "Players connected",
"open-game": "Open Game", "open-game": "Open Game",
"quit": "Quit", "quit": "Quit",