guoj5 commited on
Commit
8a0b26b
Β·
1 Parent(s): c5568e6

decorated the frontend

Browse files
Files changed (2) hide show
  1. frontend/src/App.css +440 -0
  2. frontend/src/App.js +214 -41
frontend/src/App.css CHANGED
@@ -1,3 +1,9 @@
 
 
 
 
 
 
1
  .App {
2
  text-align: center;
3
  }
@@ -22,6 +28,22 @@
22
  justify-content: center;
23
  font-size: calc(10px + 2vmin);
24
  color: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
 
27
  .App-link {
@@ -36,3 +58,421 @@
36
  transform: rotate(360deg);
37
  }
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
  .App {
8
  text-align: center;
9
  }
 
28
  justify-content: center;
29
  font-size: calc(10px + 2vmin);
30
  color: white;
31
+ text-align: center;
32
+ padding: 2rem 1rem;
33
+ color: white;
34
+ background: rgba(0, 0, 0, 0.1);
35
+ backdrop-filter: blur(10px);
36
+ }
37
+
38
+ .App-header h1 {
39
+ font-size: 2.5rem;
40
+ margin-bottom: 0.5rem;
41
+ font-weight: 700;
42
+ }
43
+
44
+ .App-header p {
45
+ font-size: 1.1rem;
46
+ opacity: 0.9;
47
  }
48
 
49
  .App-link {
 
58
  transform: rotate(360deg);
59
  }
60
  }
61
+
62
+ /* Progress Steps */
63
+ .progress-container {
64
+ padding: 2rem 1rem;
65
+ display: flex;
66
+ justify-content: center;
67
+ }
68
+
69
+ .progress-steps {
70
+ display: flex;
71
+ align-items: center;
72
+ gap: 2rem;
73
+ background: white;
74
+ padding: 1rem 2rem;
75
+ border-radius: 50px;
76
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
77
+ }
78
+
79
+ .step {
80
+ display: flex;
81
+ flex-direction: column;
82
+ align-items: center;
83
+ gap: 0.5rem;
84
+ opacity: 0.5;
85
+ transition: all 0.3s ease;
86
+ }
87
+
88
+ .step.active {
89
+ opacity: 1;
90
+ }
91
+
92
+ .step-number {
93
+ width: 40px;
94
+ height: 40px;
95
+ border-radius: 50%;
96
+ background: #e0e0e0;
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ font-weight: 600;
101
+ transition: all 0.3s ease;
102
+ }
103
+
104
+ .step.active .step-number {
105
+ background: linear-gradient(135deg, #667eea, #764ba2);
106
+ color: white;
107
+ }
108
+
109
+ .step-label {
110
+ font-size: 0.9rem;
111
+ font-weight: 500;
112
+ white-space: nowrap;
113
+ }
114
+
115
+ /* Main Content */
116
+ .main-content {
117
+ max-width: 1200px;
118
+ margin: 0 auto;
119
+ padding: 0 1rem 2rem;
120
+ }
121
+
122
+ .content-section {
123
+ background: white;
124
+ border-radius: 15px;
125
+ box-shadow: 0 4px 25px rgba(0, 0, 0, 0.1);
126
+ margin-bottom: 1.5rem;
127
+ overflow: hidden;
128
+ transition: all 0.3s ease;
129
+ }
130
+
131
+ .content-section.collapsed {
132
+ background: rgba(255, 255, 255, 0.7);
133
+ }
134
+
135
+ .section-header {
136
+ padding: 1.5rem 2rem;
137
+ background: linear-gradient(135deg, #f8f9ff, #e8ecff);
138
+ border-bottom: 1px solid #e0e0e0;
139
+ cursor: pointer;
140
+ display: flex;
141
+ justify-content: space-between;
142
+ align-items: center;
143
+ transition: all 0.3s ease;
144
+ }
145
+
146
+ .section-header:hover {
147
+ background: linear-gradient(135deg, #f0f4ff, #dde4ff);
148
+ }
149
+
150
+ .section-header h2 {
151
+ font-size: 1.3rem;
152
+ color: #333;
153
+ font-weight: 600;
154
+ }
155
+
156
+ .toggle-icon {
157
+ font-size: 1.2rem;
158
+ color: #666;
159
+ transition: transform 0.3s ease;
160
+ }
161
+
162
+ .section-content {
163
+ padding: 2rem;
164
+ }
165
+
166
+ .content-section.collapsed .section-content {
167
+ display: none;
168
+ }
169
+
170
+ /* Puzzle Selection */
171
+ .puzzle-selector {
172
+ margin-bottom: 2rem;
173
+ }
174
+
175
+ .puzzle-selector label {
176
+ display: block;
177
+ margin-bottom: 0.5rem;
178
+ font-weight: 500;
179
+ color: #555;
180
+ }
181
+
182
+ .input-group {
183
+ display: flex;
184
+ gap: 1rem;
185
+ align-items: center;
186
+ }
187
+
188
+ .number-input {
189
+ padding: 0.75rem 1rem;
190
+ border: 2px solid #e0e0e0;
191
+ border-radius: 8px;
192
+ font-size: 1rem;
193
+ width: 150px;
194
+ transition: border-color 0.3s ease;
195
+ }
196
+
197
+ .number-input:focus {
198
+ outline: none;
199
+ border-color: #667eea;
200
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
201
+ }
202
+
203
+ .puzzle-display {
204
+ display: grid;
205
+ grid-template-columns: 1fr 1fr;
206
+ gap: 2rem;
207
+ }
208
+
209
+ @media (max-width: 768px) {
210
+ .puzzle-display {
211
+ grid-template-columns: 1fr;
212
+ }
213
+ }
214
+
215
+ .puzzle-text, .expected-solution {
216
+ background: #f8f9fa;
217
+ border-radius: 10px;
218
+ padding: 1.5rem;
219
+ }
220
+
221
+ .puzzle-text h3, .expected-solution h3 {
222
+ margin-bottom: 1rem;
223
+ color: #333;
224
+ font-size: 1.1rem;
225
+ }
226
+
227
+ .text-display, .json-display {
228
+ background: white;
229
+ border-radius: 8px;
230
+ padding: 1rem;
231
+ border: 1px solid #e0e0e0;
232
+ white-space: pre-wrap;
233
+ max-height: 300px;
234
+ overflow-y: auto;
235
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
236
+ font-size: 0.9rem;
237
+ line-height: 1.5;
238
+ }
239
+
240
+ /* System Configuration */
241
+ .sys-content-editor h3 {
242
+ margin-bottom: 0.5rem;
243
+ color: #333;
244
+ }
245
+
246
+ .description {
247
+ margin-bottom: 1rem;
248
+ color: #666;
249
+ line-height: 1.6;
250
+ }
251
+
252
+ .sys-content-textarea {
253
+ width: 100%;
254
+ min-height: 300px;
255
+ padding: 1rem;
256
+ border: 2px solid #e0e0e0;
257
+ border-radius: 8px;
258
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
259
+ font-size: 0.9rem;
260
+ line-height: 1.5;
261
+ resize: vertical;
262
+ transition: border-color 0.3s ease;
263
+ }
264
+
265
+ .sys-content-textarea:focus {
266
+ outline: none;
267
+ border-color: #667eea;
268
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
269
+ }
270
+
271
+ /* Buttons */
272
+ .btn {
273
+ padding: 0.75rem 1.5rem;
274
+ border: none;
275
+ border-radius: 8px;
276
+ font-size: 1rem;
277
+ font-weight: 500;
278
+ cursor: pointer;
279
+ transition: all 0.3s ease;
280
+ text-decoration: none;
281
+ display: inline-flex;
282
+ align-items: center;
283
+ justify-content: center;
284
+ gap: 0.5rem;
285
+ }
286
+
287
+ .btn:disabled {
288
+ opacity: 0.6;
289
+ cursor: not-allowed;
290
+ }
291
+
292
+ .btn-primary {
293
+ background: linear-gradient(135deg, #667eea, #764ba2);
294
+ color: white;
295
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
296
+ }
297
+
298
+ .btn-primary:hover:not(:disabled) {
299
+ transform: translateY(-2px);
300
+ box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
301
+ }
302
+
303
+ .btn-secondary {
304
+ background: #6c757d;
305
+ color: white;
306
+ }
307
+
308
+ .btn-secondary:hover:not(:disabled) {
309
+ background: #5a6268;
310
+ transform: translateY(-1px);
311
+ }
312
+
313
+ .btn-outline {
314
+ background: transparent;
315
+ color: #667eea;
316
+ border: 2px solid #667eea;
317
+ }
318
+
319
+ .btn-outline:hover:not(:disabled) {
320
+ background: #667eea;
321
+ color: white;
322
+ }
323
+
324
+ .solve-btn {
325
+ font-size: 1.1rem;
326
+ padding: 1rem 2rem;
327
+ width: 100%;
328
+ max-width: 300px;
329
+ margin: 0 auto;
330
+ display: flex;
331
+ }
332
+
333
+ .solve-btn.loading {
334
+ animation: pulse 2s infinite;
335
+ }
336
+
337
+ @keyframes pulse {
338
+ 0%, 100% { opacity: 1; }
339
+ 50% { opacity: 0.7; }
340
+ }
341
+
342
+ /* Results */
343
+ .solve-section {
344
+ text-align: center;
345
+ margin-bottom: 2rem;
346
+ }
347
+
348
+ .result-summary {
349
+ display: grid;
350
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
351
+ gap: 1rem;
352
+ margin-bottom: 2rem;
353
+ }
354
+
355
+ .result-item {
356
+ background: #f8f9fa;
357
+ padding: 1rem;
358
+ border-radius: 8px;
359
+ display: flex;
360
+ justify-content: space-between;
361
+ align-items: center;
362
+ }
363
+
364
+ .result-label {
365
+ font-weight: 500;
366
+ color: #555;
367
+ }
368
+
369
+ .result-value {
370
+ font-weight: 600;
371
+ }
372
+
373
+ .result-value.success {
374
+ color: #28a745;
375
+ }
376
+
377
+ .result-value.error {
378
+ color: #dc3545;
379
+ }
380
+
381
+ .result-value.pending {
382
+ color: #ffc107;
383
+ }
384
+
385
+ .issues-section, .code-section {
386
+ margin-top: 2rem;
387
+ }
388
+
389
+ .issues-section h3, .code-section h3 {
390
+ margin-bottom: 1rem;
391
+ color: #333;
392
+ }
393
+
394
+ .issues-display, .code-display {
395
+ background: #f8f9fa;
396
+ border: 1px solid #e0e0e0;
397
+ border-radius: 8px;
398
+ padding: 1rem;
399
+ max-height: 400px;
400
+ overflow-y: auto;
401
+ }
402
+
403
+ .code-display {
404
+ background: #282c34;
405
+ color: #abb2bf;
406
+ }
407
+
408
+ .code-display pre {
409
+ margin: 0;
410
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
411
+ font-size: 0.9rem;
412
+ line-height: 1.5;
413
+ }
414
+
415
+ /* Navigation */
416
+ .navigation {
417
+ display: flex;
418
+ justify-content: space-between;
419
+ align-items: center;
420
+ max-width: 1200px;
421
+ margin: 0 auto;
422
+ padding: 2rem 1rem;
423
+ }
424
+
425
+ .step-indicator {
426
+ color: white;
427
+ font-weight: 500;
428
+ background: rgba(255, 255, 255, 0.2);
429
+ padding: 0.5rem 1rem;
430
+ border-radius: 20px;
431
+ backdrop-filter: blur(10px);
432
+ }
433
+
434
+ /* Responsive Design */
435
+ @media (max-width: 768px) {
436
+ .app-header h1 {
437
+ font-size: 2rem;
438
+ }
439
+
440
+ .progress-steps {
441
+ flex-direction: column;
442
+ gap: 1rem;
443
+ }
444
+
445
+ .step {
446
+ flex-direction: row;
447
+ gap: 1rem;
448
+ }
449
+
450
+ .section-content {
451
+ padding: 1rem;
452
+ }
453
+
454
+ .input-group {
455
+ flex-direction: column;
456
+ align-items: stretch;
457
+ }
458
+
459
+ .navigation {
460
+ flex-direction: column;
461
+ gap: 1rem;
462
+ }
463
+ }
464
+
465
+ @media (max-width: 480px) {
466
+ .main-content {
467
+ padding: 0 0.5rem 1rem;
468
+ }
469
+
470
+ .section-header {
471
+ padding: 1rem;
472
+ }
473
+
474
+ .btn {
475
+ padding: 0.5rem 1rem;
476
+ font-size: 0.9rem;
477
+ }
478
+ }
frontend/src/App.js CHANGED
@@ -1,5 +1,5 @@
1
- // frontend/src/App.js
2
  import React, { useState, useEffect } from 'react';
 
3
 
4
  function App() {
5
  // For puzzle index and puzzle data
@@ -17,6 +17,14 @@ function App() {
17
  const [isSolving, setIsSolving] = useState(false);
18
  const [problematicConstraints, setProblematicConstraints] = useState("");
19
 
 
 
 
 
 
 
 
 
20
  // Frontend fetch sysContent in default
21
  useEffect(() => {
22
  fetch(`/default_sys_content`)
@@ -60,6 +68,8 @@ function App() {
60
  };
61
 
62
  setIsSolving(true);
 
 
63
 
64
  fetch(`/solve`, {
65
  method: "POST",
@@ -84,52 +94,215 @@ function App() {
84
  });
85
  };
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  return (
88
- <div style={{ margin: 20 }}>
89
- <h1>Zebra Puzzle Demo</h1>
90
-
91
- <div style={{ marginBottom: 20 }}>
92
- <label>Choose puzzle index (0 - 999): </label>
93
- <input
94
- type="number"
95
- value={puzzleIndex}
96
- onChange={(e) => setPuzzleIndex(Number(e.target.value))}
97
- min={0}
98
- max={999}
99
- />
100
- <button onClick={() => setPuzzleIndex(puzzleIndex)}>Load Puzzle</button>
101
- </div>
102
 
103
- <div style={{ marginBottom: 20 }}>
104
- <h3>Puzzle Text</h3>
105
- <pre>{puzzleText}</pre>
106
- <h3>Expected Solution</h3>
107
- <pre>{JSON.stringify(expectedSolution, null, 2)}</pre>
 
 
 
 
 
 
 
 
 
 
 
108
  </div>
109
 
110
- <div style={{ marginBottom: 20 }}>
111
- <h3>sys_content</h3>
112
- <textarea
113
- rows={10}
114
- cols={80}
115
- value={sysContent}
116
- onChange={(e) => setSysContent(e.target.value)}
117
- />
118
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- <div style={{ marginBottom: 20 }}>
121
- <button onClick={handleSolve} disabled={isSolving}>Solve Puzzle with LLM</button>
122
- </div>
 
 
 
 
123
 
124
- <div>
125
- <h2>Result</h2>
126
- <p>Success: {executionSuccess === null ? "N/A" : executionSuccess ? "βœ…" : "❌"}</p>
127
- <p>Attempts: {attempts}</p>
128
- <h3>Issues</h3>
129
- <pre>{problematicConstraints}</pre>
130
- <h3>Generated Code</h3>
131
- <pre>{generatedCode}</pre>
132
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  </div>
134
  );
135
  }
 
 
1
  import React, { useState, useEffect } from 'react';
2
+ import './App.css';
3
 
4
  function App() {
5
  // For puzzle index and puzzle data
 
17
  const [isSolving, setIsSolving] = useState(false);
18
  const [problematicConstraints, setProblematicConstraints] = useState("");
19
 
20
+ // UI state
21
+ const [currentStep, setCurrentStep] = useState(1);
22
+ const [expandedSections, setExpandedSections] = useState({
23
+ puzzle: true,
24
+ sysContent: false,
25
+ result: false
26
+ });
27
+
28
  // Frontend fetch sysContent in default
29
  useEffect(() => {
30
  fetch(`/default_sys_content`)
 
68
  };
69
 
70
  setIsSolving(true);
71
+ setCurrentStep(3);
72
+ setExpandedSections({...expandedSections, result: true});
73
 
74
  fetch(`/solve`, {
75
  method: "POST",
 
94
  });
95
  };
96
 
97
+ const toggleSection = (section) => {
98
+ setExpandedSections({
99
+ ...expandedSections,
100
+ [section]: !expandedSections[section]
101
+ });
102
+ };
103
+
104
+ const nextStep = () => {
105
+ if (currentStep < 3) {
106
+ setCurrentStep(currentStep + 1);
107
+ if (currentStep === 1) {
108
+ setExpandedSections({puzzle: false, sysContent: true, result: false});
109
+ } else if (currentStep === 2) {
110
+ setExpandedSections({puzzle: false, sysContent: false, result: true});
111
+ }
112
+ }
113
+ };
114
+
115
+ const prevStep = () => {
116
+ if (currentStep > 1) {
117
+ setCurrentStep(currentStep - 1);
118
+ if (currentStep === 2) {
119
+ setExpandedSections({puzzle: true, sysContent: false, result: false});
120
+ } else if (currentStep === 3) {
121
+ setExpandedSections({puzzle: false, sysContent: true, result: false});
122
+ }
123
+ }
124
+ };
125
+
126
  return (
127
+ <div className="app-container">
128
+ <header className="app-header">
129
+ <h1>πŸ¦“ Zebra Puzzle Solver</h1>
130
+ <p>Solve complex logic puzzles using AI-powered constraint satisfaction</p>
131
+ </header>
 
 
 
 
 
 
 
 
 
132
 
133
+ {/* Progress Steps */}
134
+ <div className="progress-container">
135
+ <div className="progress-steps">
136
+ <div className={`step ${currentStep >= 1 ? 'active' : ''}`}>
137
+ <div className="step-number">1</div>
138
+ <div className="step-label">Select Puzzle</div>
139
+ </div>
140
+ <div className={`step ${currentStep >= 2 ? 'active' : ''}`}>
141
+ <div className="step-number">2</div>
142
+ <div className="step-label">Configure System</div>
143
+ </div>
144
+ <div className={`step ${currentStep >= 3 ? 'active' : ''}`}>
145
+ <div className="step-number">3</div>
146
+ <div className="step-label">Solve & Results</div>
147
+ </div>
148
+ </div>
149
  </div>
150
 
151
+ <main className="main-content">
152
+ {/* Step 1: Puzzle Selection */}
153
+ <section className={`content-section ${expandedSections.puzzle ? 'expanded' : 'collapsed'}`}>
154
+ <div className="section-header" onClick={() => toggleSection('puzzle')}>
155
+ <h2>πŸ“‹ Puzzle Selection</h2>
156
+ <span className="toggle-icon">{expandedSections.puzzle ? 'β–Ό' : 'β–Ά'}</span>
157
+ </div>
158
+
159
+ {expandedSections.puzzle && (
160
+ <div className="section-content">
161
+ <div className="puzzle-selector">
162
+ <label htmlFor="puzzle-index">Choose puzzle index (0 - 999):</label>
163
+ <div className="input-group">
164
+ <input
165
+ id="puzzle-index"
166
+ type="number"
167
+ value={puzzleIndex}
168
+ onChange={(e) => setPuzzleIndex(Number(e.target.value))}
169
+ min={0}
170
+ max={999}
171
+ className="number-input"
172
+ />
173
+ <button
174
+ onClick={() => setPuzzleIndex(puzzleIndex)}
175
+ className="btn btn-secondary"
176
+ >
177
+ Load Puzzle
178
+ </button>
179
+ </div>
180
+ </div>
181
 
182
+ <div className="puzzle-display">
183
+ <div className="puzzle-text">
184
+ <h3>πŸ“„ Puzzle Text</h3>
185
+ <div className="text-display">
186
+ {puzzleText || "Loading puzzle..."}
187
+ </div>
188
+ </div>
189
 
190
+ <div className="expected-solution">
191
+ <h3>🎯 Expected Solution</h3>
192
+ <div className="json-display">
193
+ {expectedSolution ? (
194
+ <pre>{JSON.stringify(expectedSolution, null, 2)}</pre>
195
+ ) : (
196
+ "Loading solution..."
197
+ )}
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ )}
203
+ </section>
204
+
205
+ {/* Step 2: System Configuration */}
206
+ <section className={`content-section ${expandedSections.sysContent ? 'expanded' : 'collapsed'}`}>
207
+ <div className="section-header" onClick={() => toggleSection('sysContent')}>
208
+ <h2>βš™οΈ System Configuration</h2>
209
+ <span className="toggle-icon">{expandedSections.sysContent ? 'β–Ό' : 'β–Ά'}</span>
210
+ </div>
211
+
212
+ {expandedSections.sysContent && (
213
+ <div className="section-content">
214
+ <div className="sys-content-editor">
215
+ <h3>πŸ“ System Content</h3>
216
+ <p className="description">
217
+ Edit the system prompt that will guide the AI in solving the puzzle:
218
+ </p>
219
+ <textarea
220
+ value={sysContent}
221
+ onChange={(e) => setSysContent(e.target.value)}
222
+ className="sys-content-textarea"
223
+ placeholder="Enter system content..."
224
+ />
225
+ </div>
226
+ </div>
227
+ )}
228
+ </section>
229
+
230
+ {/* Step 3: Solve & Results */}
231
+ <section className={`content-section ${expandedSections.result ? 'expanded' : 'collapsed'}`}>
232
+ <div className="section-header" onClick={() => toggleSection('result')}>
233
+ <h2>πŸš€ Solve & Results</h2>
234
+ <span className="toggle-icon">{expandedSections.result ? 'β–Ό' : 'β–Ά'}</span>
235
+ </div>
236
+
237
+ {expandedSections.result && (
238
+ <div className="section-content">
239
+ <div className="solve-section">
240
+ <button
241
+ onClick={handleSolve}
242
+ disabled={isSolving || !puzzleText || !expectedSolution}
243
+ className={`btn btn-primary solve-btn ${isSolving ? 'loading' : ''}`}
244
+ >
245
+ {isSolving ? 'πŸ”„ Solving...' : '🧠 Solve Puzzle with AI'}
246
+ </button>
247
+ </div>
248
+
249
+ <div className="results-section">
250
+ <div className="result-summary">
251
+ <div className="result-item">
252
+ <span className="result-label">Status:</span>
253
+ <span className={`result-value ${executionSuccess === true ? 'success' : executionSuccess === false ? 'error' : 'pending'}`}>
254
+ {executionSuccess === null ? "⏳ Pending" : executionSuccess ? "βœ… Success" : "❌ Failed"}
255
+ </span>
256
+ </div>
257
+ <div className="result-item">
258
+ <span className="result-label">Attempts:</span>
259
+ <span className="result-value">{attempts}</span>
260
+ </div>
261
+ </div>
262
+
263
+ {problematicConstraints && (
264
+ <div className="issues-section">
265
+ <h3>⚠️ Issues & Analysis</h3>
266
+ <div className="issues-display">
267
+ <pre>{problematicConstraints}</pre>
268
+ </div>
269
+ </div>
270
+ )}
271
+
272
+ {generatedCode && (
273
+ <div className="code-section">
274
+ <h3>πŸ’» Generated Code</h3>
275
+ <div className="code-display">
276
+ <pre><code>{generatedCode}</code></pre>
277
+ </div>
278
+ </div>
279
+ )}
280
+ </div>
281
+ </div>
282
+ )}
283
+ </section>
284
+ </main>
285
+
286
+ {/* Navigation */}
287
+ <nav className="navigation">
288
+ <button
289
+ onClick={prevStep}
290
+ disabled={currentStep <= 1}
291
+ className="btn btn-outline"
292
+ >
293
+ ← Previous
294
+ </button>
295
+ <span className="step-indicator">
296
+ Step {currentStep} of 3
297
+ </span>
298
+ <button
299
+ onClick={nextStep}
300
+ disabled={currentStep >= 3}
301
+ className="btn btn-outline"
302
+ >
303
+ Next β†’
304
+ </button>
305
+ </nav>
306
  </div>
307
  );
308
  }