Skip to content

Commit 84753b3

Browse files
committed
Added stats about opponents played against
1 parent 701fbcd commit 84753b3

File tree

3 files changed

+501
-59
lines changed

3 files changed

+501
-59
lines changed

app/routes/compare-players.$player1Id.$player2Id.tsx

Lines changed: 154 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { PlayerWithStats, getPlayers } from '../services/player-service';
44
import { typedjson, useTypedLoaderData } from 'remix-typedjson';
55
import Select, { createFilter } from 'react-select';
66
import { PageContainerStyling } from './team-duel';
7+
import { BASE_ELO } from '../utils/constants';
78

89
export const meta: MetaFunction = () => {
910
return [
@@ -76,12 +77,80 @@ const findPlayerWinStats = (
7677
};
7778
};
7879

80+
const findMatchesBetweenPlayers = (
81+
player1: PlayerWithStats,
82+
player2: PlayerWithStats
83+
) => {
84+
const sortedLogs1 = [...player1.eloLogs].sort(
85+
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
86+
);
87+
const sortedLogs2 = [...player2.eloLogs].sort(
88+
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
89+
);
90+
91+
const allMatches = [...player1.matchesAsWinner, ...player1.matchesAsLoser]
92+
.filter(
93+
(match) =>
94+
(match.winnerId === player1.id && match.loserId === player2.id) ||
95+
(match.winnerId === player2.id && match.loserId === player1.id)
96+
)
97+
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
98+
.map((match) => {
99+
const matchLog1 = sortedLogs1.find((log) => log.matchId === match.id);
100+
const matchLog2 = sortedLogs2.find((log) => log.matchId === match.id);
101+
102+
let eloDiff1 = 0;
103+
let eloDiff2 = 0;
104+
let player1Elo = BASE_ELO;
105+
let player2Elo = BASE_ELO;
106+
107+
if (matchLog1) {
108+
const matchIndex = sortedLogs1.indexOf(matchLog1);
109+
const previousElo =
110+
matchIndex === 0 ? BASE_ELO : sortedLogs1[matchIndex - 1].elo;
111+
eloDiff1 = matchLog1.elo - previousElo;
112+
player1Elo = matchLog1.elo;
113+
}
114+
115+
if (matchLog2) {
116+
const matchIndex = sortedLogs2.indexOf(matchLog2);
117+
const previousElo =
118+
matchIndex === 0 ? BASE_ELO : sortedLogs2[matchIndex - 1].elo;
119+
eloDiff2 = matchLog2.elo - previousElo;
120+
player2Elo = matchLog2.elo;
121+
}
122+
123+
return {
124+
...match,
125+
eloDiff: match.winnerId === player1.id ? eloDiff1 : -eloDiff1,
126+
player1Elo,
127+
player2Elo,
128+
winner: match.winnerId === player1.id ? player1 : player2,
129+
loser: match.loserId === player1.id ? player1 : player2,
130+
accumulatedEloDiff: 0,
131+
};
132+
});
133+
134+
let runningTotal = 0;
135+
allMatches.reverse().forEach((match) => {
136+
const matchEloDiff = Math.abs(match.eloDiff);
137+
runningTotal +=
138+
match.winner.id === player1.id ? matchEloDiff : -matchEloDiff;
139+
match.accumulatedEloDiff = runningTotal;
140+
});
141+
allMatches.reverse();
142+
143+
return allMatches;
144+
};
145+
79146
export default function Index() {
80147
const navigate = useNavigate();
81148
const { playerOptions, player1, player2, player1WinStats } =
82149
useTypedLoaderData<typeof loader>();
83150

84-
// TODO: migrate datamodel to include elo gains/loses (recalculate elo values?)
151+
const matchHistory =
152+
player1 && player2 ? findMatchesBetweenPlayers(player1, player2) : [];
153+
85154
return (
86155
<div className={PageContainerStyling}>
87156
<div className="flex justify-center py-4">
@@ -154,15 +223,97 @@ export default function Index() {
154223
<div className="text-center">
155224
<div className="text-3xl font-bold text-blue-600 dark:text-blue-400">
156225
{player1WinStats?.winPercentage
157-
? player1WinStats.winPercentage.toFixed(2)
226+
? player1WinStats.winPercentage.toFixed(1)
158227
: 0}
159228
%
160229
</div>
161230
<div className="mt-1 text-sm text-gray-600 dark:text-gray-400">
162-
Overlegenhet
231+
Win rate
163232
</div>
164233
</div>
165234
</div>
235+
236+
<h2 className="mb-4 mt-8 text-2xl font-bold text-gray-900 dark:text-white">
237+
Kamphistorikk 📋
238+
</h2>
239+
<div className="overflow-x-auto rounded-lg bg-white p-6 shadow-lg dark:bg-gray-800">
240+
<table className="min-w-full">
241+
<thead>
242+
<tr className="border-b dark:border-gray-700">
243+
<th className="py-2 text-left text-gray-900 dark:text-white">
244+
Dato
245+
</th>
246+
<th className="py-2 text-left text-gray-900 dark:text-white">
247+
Vinner
248+
</th>
249+
<th className="py-2 text-left text-gray-900 dark:text-white">
250+
Taper
251+
</th>
252+
<th className="py-2 text-right text-gray-900 dark:text-white">
253+
ELO
254+
</th>
255+
<th className="py-2 text-right text-gray-900 dark:text-white">
256+
Total ELO
257+
</th>
258+
</tr>
259+
</thead>
260+
<tbody>
261+
{matchHistory.map((match) => (
262+
<tr key={match.id} className="border-b dark:border-gray-700">
263+
<td className="py-2 text-gray-900 dark:text-white">
264+
{new Date(match.date).toLocaleString('no-NO', {
265+
year: 'numeric',
266+
month: 'short',
267+
day: '2-digit',
268+
})}
269+
</td>
270+
<td className="py-2 font-semibold text-gray-900 dark:text-white">
271+
{match.winner.name}{' '}
272+
<span className="font-normal text-gray-600 dark:text-gray-400">
273+
(
274+
{match.winner.id === player1.id
275+
? match.player1Elo
276+
: match.player2Elo}
277+
)
278+
</span>
279+
</td>
280+
<td className="py-2 font-semibold text-gray-900 dark:text-white">
281+
{match.loser.name}{' '}
282+
<span className="font-normal text-gray-600 dark:text-gray-400">
283+
(
284+
{match.loser.id === player1.id
285+
? match.player1Elo
286+
: match.player2Elo}
287+
)
288+
</span>
289+
</td>
290+
<td
291+
className={`py-2 text-right font-semibold ${
292+
match.winner.id === player1.id
293+
? 'text-green-600 dark:text-green-400'
294+
: 'text-red-600 dark:text-red-400'
295+
}`}
296+
>
297+
{match.winner.id === player1.id ? '+' : '-'}
298+
{Math.abs(match.eloDiff)}
299+
</td>
300+
<td
301+
className={`py-2 text-right font-semibold ${
302+
match.accumulatedEloDiff > 0
303+
? 'text-green-600 dark:text-green-400'
304+
: match.accumulatedEloDiff < 0
305+
? 'text-red-600 dark:text-red-400'
306+
: 'text-gray-900 dark:text-white'
307+
}`}
308+
>
309+
{match.accumulatedEloDiff > 0 ? '+' : ''}
310+
{match.accumulatedEloDiff}
311+
</td>
312+
</tr>
313+
))}
314+
</tbody>
315+
</table>
316+
</div>
166317
</div>
167318
)}
168319
</div>

0 commit comments

Comments
 (0)