+ {sortedSolves.length === 0 ? (
+
+ No activities recorded yet.
+
+ ) : (
+ sortedSolves.map((solve, idx) => {
+ const team = state.teams.find(t => t.id === solve.teamId);
+ const challenge = state.challenges.find(c => c.id === solve.challengeId);
+
+ if (!team || !challenge) return null;
+
+ const challengeSolves = state.solves
+ .filter(s => s.challengeId === solve.challengeId)
+ .sort((a, b) => a.timestamp - b.timestamp);
+
+ const rank = challengeSolves.findIndex(s => s.teamId === solve.teamId);
+ const bonusFactor = getFirstBloodBonusFactor(rank);
+ const basePoints = calculateChallengeValue(
+ challenge.initialPoints,
+ challenge.minimumPoints || 0,
+ challenge.decaySolves || 1,
+ challengeSolves.length
+ );
+ const bonus = Math.floor(challenge.initialPoints * bonusFactor);
+ const pointsGained = basePoints + bonus;
+
+ const getRankIcon = (rank: number) => {
+ if (rank === 0) return
; // Gold
+ if (rank === 1) return
; // Silver
+ if (rank === 2) return
; // Bronze
+ return
; // Checkmark
+ };
+
+ const difficultyColor =
+ challenge.difficulty === 'Low' ? 'text-[#00ff00]' :
+ challenge.difficulty === 'Medium' ? 'text-[#ffaa00]' :
+ 'text-[#ff0000]';
+
+ const dateStr = new Date(solve.timestamp).toLocaleString();
+
+ return (
+
+
+ {getRankIcon(rank)}
+
+
+ [{dateStr}]
+ {team.name} solved {challenge.category} - {challenge.title} and gained {pointsGained} points.
+
+
+ );
+ })
+ )}
+