diff --git a/website/src/components/strategy_editor/PreFlopStrategy.tsx b/website/src/components/strategy_editor/PreFlopStrategy.tsx index 3f419f2..29ea88e 100644 --- a/website/src/components/strategy_editor/PreFlopStrategy.tsx +++ b/website/src/components/strategy_editor/PreFlopStrategy.tsx @@ -1,8 +1,21 @@ import axios from "axios"; import React, { useEffect, useState } from "react"; import { API_URL } from "../../views/config"; +import "./PreFlopStrategyEditor.css"; // Make sure the path is correct + +const getBackgroundColor = (value) => { + const hue = ((value / 100) * 120).toString(10); + return `hsl(${hue}, 100%, 50%)`; +}; + +const getDefaultStrategy = () => ({ + call: 0, + raise: 0, + betSizeCall: "Bet Halfpot", + betSizeRaise: "Bet Halfpot", +}); + -// Subcomponent for each hand scenario row const HandScenarioRow = ({ hand, scenario, @@ -13,13 +26,27 @@ const HandScenarioRow = ({ const [call, setCall] = useState(0); const [raise, setRaise] = useState(0); + const [betSizeCall, setBetSizeCall] = useState("Bet Halfpot"); + const [betSizeRaise, setBetSizeRaise] = useState("Bet Halfpot"); + // Update call and raise when strategies or position changes useEffect(() => { const posStrategy = strategies[position]?.[hand]?.[scenario]; setCall(posStrategy?.call || 0); setRaise(posStrategy?.raise || 0); + setBetSizeCall(posStrategy?.betSizeCall || "Bet Halfpot"); + setBetSizeRaise(posStrategy?.betSizeRaise || "Bet Halfpot"); }, [hand, scenario, position, strategies]); + const handleBetSizeChange = (betType, value, hand, scenario) => { + if (betType === "call") { + setBetSizeCall(value); + onStrategyChange(hand, scenario, call, raise, value, betSizeRaise); + } else if (betType === "raise") { + setBetSizeRaise(value); + onStrategyChange(hand, scenario, call, raise, betSizeCall, value); + } + }; const handleCallChange = (e) => { const newCall = Math.max( 0, @@ -48,6 +75,13 @@ const HandScenarioRow = ({ min="0" max="100" /> + % @@ -58,6 +92,13 @@ const HandScenarioRow = ({ min="0" max="100" /> + % {`${fold}%`} @@ -86,14 +127,21 @@ const PreFlopStrategyEditor = () => { fetchPreflopValues(); }, []); - const handleStrategyChange = (hand, scenario, call, raise) => { + const handleStrategyChange = ( + hand, + scenario, + call, + raise, + betSizeCall, + betSizeRaise + ) => { setStrategies((prevStrategies) => ({ ...prevStrategies, [position]: { ...prevStrategies[position], [hand]: { ...prevStrategies[position]?.[hand], - [scenario]: { call, raise }, + [scenario]: { call, raise, betSizeCall, betSizeRaise }, }, }, })); @@ -120,6 +168,79 @@ const PreFlopStrategyEditor = () => { // Optionally, display an error message to the user } }; + // Handle call percentage change + // Handle call percentage change +const handleCallChange = (event, hand, scenario) => { + const newCall = Math.max( + 0, + Math.min(100, parseInt(event.target.value, 10) || 0) + ); + + setStrategies((prev) => ({ + ...prev, + [position]: { + ...prev[position], + [hand]: { + ...(prev[position]?.[hand] || {}), // Initialize hand if not exists + [scenario]: { + ...(prev[position]?.[hand]?.[scenario] || getDefaultStrategy()), // Initialize scenario if not exists + call: newCall, + raise: prev[position]?.[hand]?.[scenario]?.raise || 0, // Use default if not set + betSizeCall: prev[position]?.[hand]?.[scenario]?.betSizeCall || "Bet Halfpot", // Use default if not set + betSizeRaise: prev[position]?.[hand]?.[scenario]?.betSizeRaise || "Bet Halfpot", // Use default if not set + }, + }, + }, + })); +}; + + + // Handle raise percentage change +// Handle raise percentage change +const handleRaiseChange = (event, hand, scenario) => { + const newRaise = Math.max( + 0, + Math.min(100, parseInt(event.target.value, 10) || 0) + ); + + setStrategies((prev) => ({ + ...prev, + [position]: { + ...prev[position], + [hand]: { + ...(prev[position]?.[hand] || {}), // Initialize hand if not exists + [scenario]: { + ...(prev[position]?.[hand]?.[scenario] || getDefaultStrategy()), // Initialize scenario if not exists + call: prev[position]?.[hand]?.[scenario]?.call || 0, // Use default if not set + raise: newRaise, + betSizeCall: prev[position]?.[hand]?.[scenario]?.betSizeCall || "Bet Halfpot", // Use default if not set + betSizeRaise: prev[position]?.[hand]?.[scenario]?.betSizeRaise || "Bet Halfpot", // Use default if not set + }, + }, + }, + })); +}; + +// Handle bet size change +const handleBetSizeChange = (betType, value, hand, scenario) => { + setStrategies((prev) => ({ + ...prev, + [position]: { + ...prev[position], + [hand]: { + ...(prev[position]?.[hand] || {}), // Initialize hand if not exists + [scenario]: { + ...(prev[position]?.[hand]?.[scenario] || getDefaultStrategy()), // Initialize scenario if not exists + call: prev[position]?.[hand]?.[scenario]?.call || 0, // Use default if not set + raise: prev[position]?.[hand]?.[scenario]?.raise || 0, // Use default if not set + [`betSize${betType[0].toUpperCase()}${betType.slice(1)}`]: value, + }, + }, + }, + })); +}; + + const scenarios = ["noCalls", "previousCalls", "previousRaises"]; const hands = [ @@ -191,6 +312,11 @@ const PreFlopStrategyEditor = () => { "KJo", "QJo", ]; + const getBackgroundColor = (value) => { + // Assuming value is between 0 to 100 + const hue = ((value / 100) * 120).toString(10); + return `hsl(${hue}, 100%, 50%)`; // From red (0) to green (120) + }; return (
@@ -209,16 +335,26 @@ const PreFlopStrategyEditor = () => { Hand - No calls or raises {/* Colspan of 3 for the scenario grouping */} - 1 or more calls {/* Colspan of 3 for the scenario grouping */} - 1 or more raises {/* Colspan of 3 for the scenario grouping */} + + No calls or bets + + 1 or more calls + + 1 or more raises + - {scenarios.map((scenario) => ( + {scenarios.map((scenario, index) => ( - Call - Raise - Fold + 0 ? "left-border" : ""}>% Call + Call Bet Size + % Raise + Raise Bet Size + + % Fold + ))} @@ -227,16 +363,83 @@ const PreFlopStrategyEditor = () => { {hands.map((hand) => ( {hand} - {scenarios.map((scenario) => ( - - ))} + + {scenarios.map((scenario) => { + const strategy = + strategies[position]?.[hand]?.[scenario] || getDefaultStrategy(); + + const fold = 100 - strategy.call - strategy.raise; + return ( + + + handleCallChange(e, hand, scenario)} + min="0" + max="100" + /> + + + + + + handleRaiseChange(e, hand, scenario)} + min="0" + max="100" + /> + + + + + + {fold} + + + ); + })} ))} @@ -245,4 +448,6 @@ const PreFlopStrategyEditor = () => { ); }; +// Make sure to define handleCallChange, handleRaiseChange, and handleBetSizeChange functions + export default PreFlopStrategyEditor; diff --git a/website/src/components/strategy_editor/PreFlopStrategyEditor.css b/website/src/components/strategy_editor/PreFlopStrategyEditor.css new file mode 100644 index 0000000..0d6fa1c --- /dev/null +++ b/website/src/components/strategy_editor/PreFlopStrategyEditor.css @@ -0,0 +1,20 @@ +.left-border { + border-left: 2px solid black; + } + + .right-border { + border-right: 2px solid black; + } + + .value-cell { + position: relative; + } + + .value-cell::after { + content: '%'; + position: absolute; + right: 5px; + top: 50%; + transform: translateY(-50%); + } + \ No newline at end of file