Skip to content

Commit 87c690d

Browse files
authored
Merge pull request #47 from SujalTripathi/feat/step-explanation-ui
feat: Add Step Explanation UI to String Visualizer
2 parents fe98bdf + 77f8e84 commit 87c690d

3 files changed

Lines changed: 73 additions & 38 deletions

File tree

frontend/src/App.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,9 @@ const AppContent = () => {
6262
path="*"
6363
element={<NotFoundPage />}
6464
/>
65-
<Route
66-
path="/tutorials"
67-
element={<TutorialsPage darkMode={darkMode} />}
68-
/>
69-
<Route
70-
path="/tutorial/:tutorialId"
71-
element={<TutorialPage darkMode={darkMode} />}
72-
/>
65+
<Route path="/tutorials" element={<TutorialsPage darkMode={isDark} />} />
66+
<Route path="/tutorial/:tutorialId" element={<TutorialPage darkMode={isDark} />} />
67+
7368
</Routes>
7469
</Layout>
7570
</Router>

frontend/src/components/Sorting/ComplexityDisplay.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const ComplexityDisplay = ({ algorithm, currentData, steps }) => {
3333
</div>
3434
<div className="flex justify-between">
3535
<span className="text-gray-600">Steps:</span>
36-
<span className="font-medium">{steps.length}</span>
36+
<span className="font-medium">{steps?.length || 0}</span>
3737
</div>
3838
</div>
3939
</div>

frontend/src/pages/StringVisualizer.jsx

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import React, { useState } from 'react';
2-
import { useTheme } from '../contexts/ThemeContext'; // Use the project's theme system
3-
import { Play, RotateCcw, Text, Hash } from 'lucide-react';
2+
// STEP 1: Add 'BookOpen' to the import list
3+
import { Play, RotateCcw, Text, Hash, BookOpen } from 'lucide-react';
4+
import { useTheme } from '../contexts/ThemeContext';
45

56
const StringVisualizer = () => {
6-
const { classes } = useTheme(); // Get the theme classes
7+
const { isDark } = useTheme();
78
const [text, setText] = useState('ababcabcabababd');
89
const [pattern, setPattern] = useState('abababd');
910

11+
// STEP 2: Add the new state for the explanation text
12+
const [showDetailedLog, setShowDetailedLog] = useState(false);
13+
const [explanation, setExplanation] = useState({
14+
operation: 'Ready to start.',
15+
details: 'Enter text and a pattern, then click Visualize to begin the process.',
16+
algorithmInfo: 'The Naive (or Brute-Force) search algorithm checks for a match at every possible position in the text.'
17+
});
18+
1019
const handleVisualize = () => console.log('Visualize clicked!', { text, pattern });
1120
const handleReset = () => {
1221
setText('');
@@ -15,9 +24,8 @@ const StringVisualizer = () => {
1524
};
1625

1726
return (
18-
// Use the theme's background class
19-
<div className={`w-full min-h-screen ${classes.bgPrimary} p-4 sm:p-8`}>
20-
{/* Spacer div */}
27+
<div className="w-full min-h-screen bg-slate-50 p-4 sm:p-8">
28+
{/* Spacer to push content down from the main site navigation */}
2129
<div className="h-24"></div>
2230

2331
{/* 1. Gradient Header Card */}
@@ -32,42 +40,40 @@ const StringVisualizer = () => {
3240

3341
<div className="max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-3 gap-8">
3442

35-
{/* 2. Left Column: Inputs & Controls Card */}
36-
<div className="lg:col-span-1">
37-
<div className={`${classes.cardBg} p-6 rounded-xl shadow-md border ${classes.border}`}>
38-
<h2 className={`text-xl font-bold ${classes.textPrimary} mb-6 flex items-center gap-2`}>
43+
{/* 2. Left Column: Contains both cards now */}
44+
<div className="lg:col-span-1 space-y-8">
45+
{/* Inputs & Controls Card */}
46+
<div className="bg-white p-6 rounded-xl shadow-md border border-slate-200">
47+
<h2 className="text-xl font-bold text-slate-800 mb-6 flex items-center gap-2">
3948
<Text size={22} className="text-indigo-500" />
4049
Inputs & Controls
4150
</h2>
42-
4351
<div className="mb-4">
44-
<label htmlFor="main-text" className={`block text-sm font-medium ${classes.textSecondary} mb-2`}>
52+
<label htmlFor="main-text" className="block text-sm font-medium text-slate-600 mb-2">
4553
Main Text (Haystack)
4654
</label>
4755
<input
4856
id="main-text"
4957
type="text"
5058
value={text}
5159
onChange={(e) => setText(e.target.value)}
52-
className={`w-full p-3 ${classes.inputBg} ${classes.textPrimary} placeholder-slate-400 rounded-lg border ${classes.border} focus:outline-none focus:ring-2 focus:ring-indigo-500 transition`}
60+
className="w-full p-3 bg-slate-100 text-slate-800 placeholder-slate-400 rounded-lg border border-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition"
5361
placeholder="Enter text..."
5462
/>
5563
</div>
56-
5764
<div className="mb-6">
58-
<label htmlFor="pattern-text" className={`block text-sm font-medium ${classes.textSecondary} mb-2`}>
65+
<label htmlFor="pattern-text" className="block text-sm font-medium text-slate-600 mb-2">
5966
Pattern to Find (Needle)
6067
</label>
6168
<input
6269
id="pattern-text"
6370
type="text"
6471
value={pattern}
6572
onChange={(e) => setPattern(e.target.value)}
66-
className={`w-full p-3 ${classes.inputBg} ${classes.textPrimary} placeholder-slate-400 rounded-lg border ${classes.border} focus:outline-none focus:ring-2 focus:ring-indigo-500 transition`}
73+
className="w-full p-3 bg-slate-100 text-slate-800 placeholder-slate-400 rounded-lg border border-slate-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 transition"
6774
placeholder="Enter pattern..."
6875
/>
6976
</div>
70-
7177
<div className="flex flex-col sm:flex-row gap-4">
7278
<button
7379
onClick={handleVisualize}
@@ -85,39 +91,73 @@ const StringVisualizer = () => {
8591
</button>
8692
</div>
8793
</div>
94+
95+
{/* Step Explanation Card */}
96+
<div className={`backdrop-blur-xl rounded-2xl shadow-2xl border overflow-hidden ${isDark ? 'bg-gray-800/20 border-gray-700/50' : 'bg-white/20 border-white/50'}`}>
97+
<div className={`p-4 border-b ${isDark ? 'border-gray-700/50' : 'border-white/50'}`}>
98+
<div className="flex justify-between items-center">
99+
<h4 className={`text-lg font-bold flex items-center ${isDark ? 'text-white' : 'text-gray-800'}`}>
100+
<BookOpen className="h-5 w-5 mr-2 text-purple-500" />
101+
Step Explanation
102+
</h4>
103+
<button
104+
onClick={() => setShowDetailedLog(!showDetailedLog)}
105+
className={`text-sm px-3 py-1 rounded transition-colors ${isDark ? 'text-gray-300 hover:text-white hover:bg-gray-700' : 'text-gray-600 hover:text-gray-800 hover:bg-gray-100'}`}
106+
>
107+
{showDetailedLog ? 'Hide Log' : 'Show Log'}
108+
</button>
109+
</div>
110+
</div>
111+
<div className="p-4 space-y-4">
112+
<div className={`p-4 rounded-lg border-l-4 border-blue-500 ${isDark ? 'bg-blue-900/20' : 'bg-blue-50'}`}>
113+
<p className={`text-sm font-medium mb-1 ${isDark ? 'text-white' : 'text-gray-800'}`}>Current Operation:</p>
114+
<p className={`text-sm ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>{explanation.operation}</p>
115+
</div>
116+
<div className={`p-4 rounded-lg border-l-4 border-purple-500 ${isDark ? 'bg-purple-900/20' : 'bg-purple-50'}`}>
117+
<p className={`text-sm font-medium mb-1 ${isDark ? 'text-white' : 'text-gray-800'}`}>What's Happening:</p>
118+
<p className={`text-sm leading-relaxed ${isDark ? 'text-gray-300' : 'text-gray-700'}`}>{explanation.details}</p>
119+
</div>
120+
<div className={`p-4 rounded-lg border-l-4 border-green-500 bg-green-50`}>
121+
<p className={`text-sm font-medium mb-1 text-slate-800`}>
122+
Algorithm Info:
123+
</p>
124+
<p className={`text-sm leading-relaxed text-slate-700`}>
125+
{explanation.algorithmInfo}
126+
</p>
127+
</div>
128+
</div>
129+
</div>
88130
</div>
89131

90132
{/* 3. Right Column: Display Area Card */}
91133
<div className="lg:col-span-2">
92-
<div className={`${classes.cardBg} p-6 rounded-xl shadow-md border ${classes.border} min-h-[300px]`}>
93-
<h2 className={`text-xl font-bold ${classes.textPrimary} mb-6 flex items-center gap-2`}>
134+
<div className="bg-white p-6 rounded-xl shadow-md border border-slate-200 min-h-[300px]">
135+
<h2 className="text-xl font-bold text-slate-800 mb-6 flex items-center gap-2">
94136
<Hash size={22} className="text-indigo-500" />
95137
Visualization
96138
</h2>
97-
98139
<div className="mb-6">
99-
<h3 className={`text-md font-semibold mb-3 ${classes.textSecondary}`}>Text</h3>
100-
<div className={`flex flex-wrap gap-1 p-3 ${classes.inputBg} rounded-lg`}>
140+
<h3 className="text-md font-semibold mb-3 text-slate-600">Text</h3>
141+
<div className="flex flex-wrap gap-1 p-3 bg-slate-100 rounded-lg">
101142
{text.split('').map((char, index) => (
102143
<div key={`text-${index}`} className="flex flex-col items-center">
103-
<div className={`flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 ${classes.cardBg} border ${classes.border} rounded-md text-lg font-mono ${classes.textPrimary}`}>
144+
<div className="flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 bg-white border border-slate-300 rounded-md text-lg font-mono text-slate-800">
104145
{char}
105146
</div>
106-
<span className={`text-xs ${classes.textMuted} mt-1`}>{index}</span>
147+
<span className="text-xs text-slate-500 mt-1">{index}</span>
107148
</div>
108149
))}
109150
</div>
110151
</div>
111-
112152
<div>
113-
<h3 className={`text-md font-semibold mb-3 ${classes.textSecondary}`}>Pattern</h3>
114-
<div className={`flex flex-wrap gap-1 p-3 ${classes.inputBg} rounded-lg`}>
153+
<h3 className="text-md font-semibold mb-3 text-slate-600">Pattern</h3>
154+
<div className="flex flex-wrap gap-1 p-3 bg-slate-100 rounded-lg">
115155
{pattern.split('').map((char, index) => (
116156
<div key={`pattern-${index}`} className="flex flex-col items-center">
117-
<div className={`flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 ${classes.cardBg} border ${classes.border} rounded-md text-lg font-mono ${classes.textPrimary}`}>
157+
<div className="flex items-center justify-center w-8 h-8 sm:w-10 sm:h-10 bg-white border border-slate-300 rounded-md text-lg font-mono text-slate-800">
118158
{char}
119159
</div>
120-
<span className={`text-xs ${classes.textMuted} mt-1`}>{index}</span>
160+
<span className="text-xs text-slate-500 mt-1">{index}</span>
121161
</div>
122162
))}
123163
</div>

0 commit comments

Comments
 (0)