AnayShukla commited on
Commit
1e125cd
·
1 Parent(s): 2f19576
frontend/src/components/Fixtures.jsx CHANGED
@@ -21,11 +21,11 @@ export default function Fixtures() {
21
 
22
  const TEAM_MAP = {
23
  "Arsenal": 1, "Aston Villa": 2, "Burnley": 3, "AFC Bournemouth": 4, "Brentford": 5,
24
- "Brighton": 6, "Chelsea": 7, "Crystal Palace": 8, "Everton": 9, "Fulham": 10,
25
- "Leeds United": 11, "Liverpool": 12, "Man City": 13, "Manchester City": 13,
26
  "Man Utd": 14, "Manchester United": 14, "Newcastle": 15, "Newcastle United": 15,
27
- "Nott'm Forest": 16, "Nottingham Forest": 16, "Sunderland": 17,
28
- "Spurs": 18, "Tottenham": 18, "Tottenham Hotspur": 18,
29
  "West Ham": 19, "West Ham United": 19, "Wolves": 20, "Wolverhampton Wanderers": 20
30
  };
31
 
@@ -60,24 +60,24 @@ export default function Fixtures() {
60
  {Object.entries(groupedFixtures).map(([gw, matches]) => (
61
  <div key={gw} className="bg-slate-900/40 p-6 rounded-xl border border-slate-800 backdrop-blur-sm shadow-xl">
62
  <h3 className="text-xl font-bold text-luigi-400 mb-4 border-b border-slate-800 pb-2">Gameweek {gw}</h3>
63
-
64
  <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
65
  {matches.map((match, idx) => {
66
-
67
  const hw = match.home_win_prob;
68
  const aw = match.away_win_prob;
69
  const isGhost = match.shiftProb < 0.995;
70
 
71
  const homeBox = hw > aw ? 'text-emerald-400 bg-emerald-900/30' : (hw < aw ? 'text-rose-400 bg-rose-900/30' : 'text-slate-300 bg-slate-800/50');
72
  const awayBox = aw > hw ? 'text-emerald-400 bg-emerald-900/30' : (aw < hw ? 'text-rose-400 bg-rose-900/30' : 'text-slate-300 bg-slate-800/50');
73
-
74
- const ghostStyles = isGhost
75
- ? "border-dashed border-indigo-500/50 opacity-80 bg-[repeating-linear-gradient(45deg,transparent,transparent_10px,rgba(99,102,241,0.05)_10px,rgba(99,102,241,0.05)_20px)]"
76
  : "border-slate-800/80 hover:border-slate-600";
77
 
78
  return (
79
- <div
80
- key={`${idx}-${match.shiftProb}`}
81
  title={isGhost ? `${Math.round(match.shiftProb * 100)}% chance of playing in GW${gw}` : `Confirmed Fixture`}
82
  className={`relative bg-slate-950 rounded-lg border overflow-hidden shadow-lg transition-colors ${ghostStyles}`}
83
  >
@@ -86,7 +86,7 @@ export default function Fixtures() {
86
  {Math.round(match.shiftProb * 100)}% Chance
87
  </div>
88
  )}
89
-
90
  {/* Header: Teams & xG */}
91
  <div className="bg-slate-900/80 px-4 py-3 flex justify-between items-center border-b border-slate-800">
92
  <div className="flex flex-col items-center w-1/3">
@@ -96,9 +96,9 @@ export default function Fixtures() {
96
  {match.expected_home_goals.toFixed(2)} xG
97
  </span>
98
  </div>
99
-
100
  <span className="text-slate-600 text-xs font-bold uppercase tracking-widest bg-slate-950 px-2 py-1 rounded-full border border-slate-800">vs</span>
101
-
102
  <div className="flex flex-col items-center w-1/3">
103
  <span className="text-lg font-bold text-slate-100">{getShortName(match.away_team)}</span>
104
  {/* UPDATED: Larger, bolder xG text */}
 
21
 
22
  const TEAM_MAP = {
23
  "Arsenal": 1, "Aston Villa": 2, "Burnley": 3, "AFC Bournemouth": 4, "Brentford": 5,
24
+ "Brighton": 6, "Brighton and Hove Albion": 6, "Chelsea": 7, "Crystal Palace": 8, "Everton": 9, "Fulham": 10,
25
+ "Leeds United": 11, "Liverpool": 12, "Man City": 13, "Manchester City": 13,
26
  "Man Utd": 14, "Manchester United": 14, "Newcastle": 15, "Newcastle United": 15,
27
+ "Nott'm Forest": 16, "Nottingham Forest": 16, "Sunderland": 17,
28
+ "Spurs": 18, "Tottenham": 18, "Tottenham Hotspur": 18,
29
  "West Ham": 19, "West Ham United": 19, "Wolves": 20, "Wolverhampton Wanderers": 20
30
  };
31
 
 
60
  {Object.entries(groupedFixtures).map(([gw, matches]) => (
61
  <div key={gw} className="bg-slate-900/40 p-6 rounded-xl border border-slate-800 backdrop-blur-sm shadow-xl">
62
  <h3 className="text-xl font-bold text-luigi-400 mb-4 border-b border-slate-800 pb-2">Gameweek {gw}</h3>
63
+
64
  <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
65
  {matches.map((match, idx) => {
66
+
67
  const hw = match.home_win_prob;
68
  const aw = match.away_win_prob;
69
  const isGhost = match.shiftProb < 0.995;
70
 
71
  const homeBox = hw > aw ? 'text-emerald-400 bg-emerald-900/30' : (hw < aw ? 'text-rose-400 bg-rose-900/30' : 'text-slate-300 bg-slate-800/50');
72
  const awayBox = aw > hw ? 'text-emerald-400 bg-emerald-900/30' : (aw < hw ? 'text-rose-400 bg-rose-900/30' : 'text-slate-300 bg-slate-800/50');
73
+
74
+ const ghostStyles = isGhost
75
+ ? "border-dashed border-indigo-500/50 opacity-80 bg-[repeating-linear-gradient(45deg,transparent,transparent_10px,rgba(99,102,241,0.05)_10px,rgba(99,102,241,0.05)_20px)]"
76
  : "border-slate-800/80 hover:border-slate-600";
77
 
78
  return (
79
+ <div
80
+ key={`${idx}-${match.shiftProb}`}
81
  title={isGhost ? `${Math.round(match.shiftProb * 100)}% chance of playing in GW${gw}` : `Confirmed Fixture`}
82
  className={`relative bg-slate-950 rounded-lg border overflow-hidden shadow-lg transition-colors ${ghostStyles}`}
83
  >
 
86
  {Math.round(match.shiftProb * 100)}% Chance
87
  </div>
88
  )}
89
+
90
  {/* Header: Teams & xG */}
91
  <div className="bg-slate-900/80 px-4 py-3 flex justify-between items-center border-b border-slate-800">
92
  <div className="flex flex-col items-center w-1/3">
 
96
  {match.expected_home_goals.toFixed(2)} xG
97
  </span>
98
  </div>
99
+
100
  <span className="text-slate-600 text-xs font-bold uppercase tracking-widest bg-slate-950 px-2 py-1 rounded-full border border-slate-800">vs</span>
101
+
102
  <div className="flex flex-col items-center w-1/3">
103
  <span className="text-lg font-bold text-slate-100">{getShortName(match.away_team)}</span>
104
  {/* UPDATED: Larger, bolder xG text */}
frontend/src/components/ProjectionsTable.jsx CHANGED
@@ -278,7 +278,12 @@ export default function ProjectionsTable() {
278
  if (setGlobalPlayers) {
279
  setGlobalPlayers(prev => prev.map(p => {
280
  const newBaseline = type === 'baseline' ? (valueStr === '' ? null : value) : (activeBaseline !== undefined ? activeBaseline : p.baseline_xMins);
281
- if (p.ID === playerId) return { ...p, ...updatedRow, baseline_xMins: newBaseline };
 
 
 
 
 
282
  return p;
283
  }));
284
  }
 
278
  if (setGlobalPlayers) {
279
  setGlobalPlayers(prev => prev.map(p => {
280
  const newBaseline = type === 'baseline' ? (valueStr === '' ? null : value) : (activeBaseline !== undefined ? activeBaseline : p.baseline_xMins);
281
+
282
+ if (p.ID === playerId) {
283
+ // THE FIX: Protect the original match dictionary so Python doesn't wipe out the DGW tags!
284
+ const pristineMatches = p.match_projections;
285
+ return { ...p, ...updatedRow, match_projections: pristineMatches, baseline_xMins: newBaseline };
286
+ }
287
  return p;
288
  }));
289
  }