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"
>
-
))}
+
+
+