Zebra / frontend /src /App.js
guoj5's picture
Change a little
d1f88fb
// frontend/src/App.js
import React, { useState, useEffect } from 'react';
function App() {
// For puzzle index and puzzle data
const [puzzleIndex, setPuzzleIndex] = useState(0);
const [puzzleText, setPuzzleText] = useState("");
const [expectedSolution, setExpectedSolution] = useState(null);
// sysContent can be editted, default using Example.txt
const [sysContent, setSysContent] = useState("");
// Interaction results
const [generatedCode, setGeneratedCode] = useState("");
const [executionSuccess, setExecutionSuccess] = useState(null);
const [attempts, setAttempts] = useState(0);
const [isSolving, setIsSolving] = useState(false);
const [problematicConstraints, setProblematicConstraints] = useState("");
// Frontend fetch sysContent in default
useEffect(() => {
fetch(`/default_sys_content`)
.then(res => res.json())
.then(data => {
if(data.success) {
setSysContent(data.sysContent);
}
})
.catch(e => console.error(e));
}, []);
// When puzzleIndex changing,auto get puzzle
useEffect(() => {
fetch(`/get_puzzle?index=${puzzleIndex}`)
.then(res => res.json())
.then(data => {
if(data.success) {
setPuzzleText(data.puzzle);
setExpectedSolution(data.expected_solution);
} else {
console.error("Failed to fetch puzzle", data.error);
setPuzzleText("");
setExpectedSolution(null);
}
})
.catch(e => console.error(e));
}, [puzzleIndex]);
const handleSolve = () => {
if(!puzzleText || !expectedSolution) {
alert("puzzle or expectedSolution incomplete");
return;
}
const payload = {
index: puzzleIndex,
puzzle: puzzleText,
expected_solution: expectedSolution,
sys_content: sysContent,
problematic_constraints: problematicConstraints
};
setIsSolving(true);
fetch(`/solve`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => {
if(!data.success) {
alert("Backend error: " + data.error);
return;
}
const result = data.result;
setGeneratedCode(result.generatedCode || "");
setExecutionSuccess(result.success);
setAttempts(result.attempts || 0);
setProblematicConstraints(result.problematicConstraints || "");
})
.catch(e => console.error(e))
.finally(() => {
setIsSolving(false);
});
};
return (
<div style={{ margin: 20 }}>
<h1>Zebra Puzzle Demo</h1>
<div style={{ marginBottom: 20 }}>
<label>Choose puzzle index (0 - 999): </label>
<input
type="number"
value={puzzleIndex}
onChange={(e) => setPuzzleIndex(Number(e.target.value))}
min={0}
max={999}
/>
<button onClick={() => setPuzzleIndex(puzzleIndex)}>Load Puzzle</button>
</div>
<div style={{ marginBottom: 20 }}>
<h3>Puzzle Text</h3>
<pre>{puzzleText}</pre>
<h3>Expected Solution</h3>
<pre>{JSON.stringify(expectedSolution, null, 2)}</pre>
</div>
<div style={{ marginBottom: 20 }}>
<h3>sys_content</h3>
<textarea
rows={10}
cols={80}
value={sysContent}
onChange={(e) => setSysContent(e.target.value)}
/>
</div>
<div style={{ marginBottom: 20 }}>
<button onClick={handleSolve} disabled={isSolving}>Solve Puzzle with LLM</button>
</div>
<div>
<h2>Result</h2>
<p>Success: {executionSuccess === null ? "N/A" : executionSuccess ? "✅" : "❌"}</p>
<p>Attempts: {attempts}</p>
<h3>Issues</h3>
<pre>{problematicConstraints}</pre>
<h3>Generated Code</h3>
<pre>{generatedCode}</pre>
</div>
</div>
);
}
export default App;