diff --git a/frontend/src/components/BinaryConverter.tsx b/frontend/src/components/BinaryConverter.tsx index b0fd16ba..1b2f6d16 100644 --- a/frontend/src/components/BinaryConverter.tsx +++ b/frontend/src/components/BinaryConverter.tsx @@ -47,7 +47,7 @@ export default function BinaryConverter({ dec = parseInt(binary, 2); } return ( -
+
- {dec === undefined || isNaN(dec) ? "Invalid" : dec} + {binary === "" ? "" : (dec === undefined || isNaN(dec) ? "Invalid" : dec)}
{dec !== undefined && !isNaN(dec) && conversionSteps diff --git a/frontend/src/components/CostarColoring.tsx b/frontend/src/components/CostarColoring.tsx index efe9ee51..d41141be 100644 --- a/frontend/src/components/CostarColoring.tsx +++ b/frontend/src/components/CostarColoring.tsx @@ -32,6 +32,14 @@ const availableParts = [ "letter_r", ]; +// Helper function to format display names (e.g., "letter_c" -> "Letter C") +const formatDisplayName = (name: string): string => { + return name + .split("_") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); +}; + enum AlertType { NONE, SUCCESS, @@ -54,6 +62,7 @@ export function CostarColoring({ letter_a: "", letter_r: "", }); + const [rowColors, setRowColors] = useState(["", "", "", "", "", ""]); const [currentColorIndex, setCurrentColorIndex] = useState(0); const colorNextPart = (color: string) => { @@ -91,36 +100,74 @@ export function CostarColoring({ }); } }; + const handleValueOnBlur = (value: string, isColorInput: boolean = false) => { + const val = value.toLowerCase().trim(); - const handleValueOnBlur = (value: string) => { - if ( - !availableColors.includes(value) && - !availableParts.includes(value) && - value !== "" - ) { - setCurrentAlert({ - type: AlertType.FAILURE, - message: "That isn't quite one of the options. Try again.", - }); + + if (isColorInput) { + const strippedValue = val.startsWith('"') && val.endsWith('"') + ? val.substring(1, val.length - 1) + : val; + + if ( + !availableColors.includes(strippedValue) && + value !== "" + ) { + setCurrentAlert({ + type: AlertType.FAILURE, + message: "That isn't quite one of the options. Try again.", + }); + } + } else { + // For letter input + if ( + !availableParts.includes(val) && + value !== "" + ) { + setCurrentAlert({ + type: AlertType.FAILURE, + message: "That isn't quite one of the options. Try again.", + }); + } } }; - const handleColorChange = (part: string, value: string) => { + + + const handleColorChange = (part: string, value: string, rowIndex?: number) => { const val = value.toLowerCase(); if (availableParts.includes(val)) { setCurrentAlert({ type: AlertType.FAILURE, message: "This value is a color, not a body part!", }); + return; } if (value.startsWith('"') && value.endsWith('"')) { const strippedValue = val.substring(1, val.length - 1); - if (availableColors.includes(strippedValue) && part !== "") { + if (availableColors.includes(strippedValue)) { setCurrentAlert({ type: AlertType.SUCCESS, message: "Correct!" }); - setColors((prevColors) => ({ - ...prevColors, - [part]: strippedValue, - })); + + // If typeVariable mode, store by row index + if (props?.typeVariable && rowIndex !== undefined) { + const updatedRowColors = [...rowColors]; + updatedRowColors[rowIndex] = strippedValue; + setRowColors(updatedRowColors); + + // Also update the actual variable if it's been typed + if (part && part !== "") { + setColors((prevColors) => ({ + ...prevColors, + [part]: strippedValue, + })); + } + } else { + // Normal mode - store by variable name + setColors((prevColors) => ({ + ...prevColors, + [part]: strippedValue, + })); + } } else if (availableParts.includes(strippedValue)) { setCurrentAlert({ type: AlertType.FAILURE, @@ -130,6 +177,8 @@ export function CostarColoring({ } }; + + function handleOnDrop(e: React.DragEvent, part: string) { const color = e.dataTransfer.getData("Color") as string; const temp = (colors[part as keyof CostarColorState] = color); @@ -188,40 +237,41 @@ export function CostarColoring({ onDragOver={(e) => handleDragOver(e)} className="border-2 flex flex-row rounded-sm outline-dotted text-center" > -
))} + + +

Options:

@@ -263,7 +317,9 @@ export function CostarColoring({ if (!props?.type) colorNextPart(color); }} > - {color} + + {props?.type ? `"${color}"` : formatDisplayName(color)} +
))} @@ -275,6 +331,18 @@ export function CostarColoring({ } function CostarColor() { + // Determine which colors to display based on mode + const displayColors = props?.typeVariable + ? { + letter_c: rowColors[0] || "", + letter_o: rowColors[1] || "", + letter_s: rowColors[2] || "", + letter_t: rowColors[3] || "", + letter_a: rowColors[4] || "", + letter_r: rowColors[5] || "", + } + : colors; + return (
book book book book book book diff --git a/frontend/src/pages/BookPage.tsx b/frontend/src/pages/BookPage.tsx index df364ea4..953d6314 100644 --- a/frontend/src/pages/BookPage.tsx +++ b/frontend/src/pages/BookPage.tsx @@ -19,7 +19,7 @@ import { useTheme } from "../context/ThemeContext"; function BookContent({ content }: { content: string[] }) { return (
-