1+ import React , { useState } from "react" ;
2+ import { Toaster , toast } from "react-hot-toast" ;
3+ import LinearSearchVisualizer from "../../components/searching/LinearSearchVisualizer" ;
4+ import { linearSearch } from "../../algorithms/searching/linearSearch" ;
5+
6+
7+ export default function LinearSearch ( ) {
8+ const [ array , setArray ] = useState ( [ ] ) ;
9+ const [ input , setInput ] = useState ( "" ) ;
10+
11+ // --- SEARCH STATES ---
12+ const [ target , setTarget ] = useState ( null ) ;
13+ const [ highlightIndex , setHighlightIndex ] = useState ( null ) ;
14+ const [ foundIndex , setFoundIndex ] = useState ( null ) ;
15+ // ---------------------
16+
17+ const [ isRunning , setIsRunning ] = useState ( false ) ;
18+
19+ const handleStart = async ( ) => {
20+ if ( isRunning || array . length === 0 || isNaN ( parseInt ( target ) ) ) {
21+ toast . error ( "Please ensure the array and target are valid." ) ;
22+ return ;
23+ }
24+
25+ setIsRunning ( true ) ;
26+ setHighlightIndex ( null ) ;
27+ setFoundIndex ( null ) ;
28+
29+ const targetNumber = parseInt ( target ) ;
30+
31+ // Pass the array AND the target to the generator
32+ const gen = linearSearch ( array , targetNumber ) ;
33+
34+ for ( let step of gen ) {
35+ // Update search-specific states
36+ setHighlightIndex ( step . highlightIndex ) ;
37+ setFoundIndex ( step . foundIndex ) ;
38+
39+ if ( step . message ) {
40+ if ( step . foundIndex !== null ) {
41+ toast . success ( step . message ) ;
42+ } else {
43+ toast . error ( step . message ) ;
44+ }
45+ }
46+
47+ // Wait for 500ms for visualization (adjust this speed later)
48+ await new Promise ( ( r ) => setTimeout ( r , 500 ) ) ;
49+ }
50+
51+ setIsRunning ( false ) ;
52+ } ;
53+
54+ const handleReset = ( ) => {
55+ setArray ( [ ] ) ;
56+ setInput ( "" ) ;
57+ setTarget ( 50 ) ; // Reset target input
58+ setHighlightIndex ( null ) ;
59+ setFoundIndex ( null ) ;
60+ setIsRunning ( false ) ;
61+ } ;
62+
63+ const handleInput = ( e ) => {
64+ setInput ( e . target . value ) ;
65+ const numbers = e . target . value
66+ . split ( "," )
67+ . map ( ( n ) => parseInt ( n . trim ( ) ) )
68+ . filter ( ( n ) => ! isNaN ( n ) ) ;
69+ setArray ( numbers ) ;
70+ } ;
71+
72+ const handleTargetChange = ( e ) => {
73+ setTarget ( e . target . value ) ;
74+ } ;
75+
76+ return (
77+ < div className = "min-h-screen bg-black text-gray-200 flex flex-col items-center p-6" >
78+ < Toaster position = "top-center" />
79+ < h1 className = "text-4xl font-extrabold mb-8 text-indigo-400 drop-shadow-lg" >
80+ Linear Search Visualizer
81+ </ h1 >
82+
83+ { /* INPUTS: ARRAY AND TARGET */ }
84+ < div className = "flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 mb-6" >
85+ < input
86+ type = "text"
87+ value = { input }
88+ onChange = { handleInput }
89+ placeholder = "Enter array (e.g., 10,20,50,40)"
90+ className = "border-2 border-gray-400 bg-gray-900 text-green-200 rounded-lg p-3 w-80 text-center shadow-lg focus:ring-2 focus:ring-blue-500 outline-none"
91+ />
92+ < input
93+ type = "number"
94+ value = { target }
95+ onChange = { handleTargetChange }
96+ placeholder = "Target Value"
97+ className = "border-2 border-gray-300 bg-gray-900 text-yellow-200 rounded-lg p-3 w-40 text-center shadow-lg focus:ring-2 focus:ring-blue-500 outline-none"
98+ />
99+ </ div >
100+
101+ < div className = "space-x-4 mt-6" >
102+ < button
103+ onClick = { handleStart }
104+ disabled = { isRunning || array . length === 0 }
105+ className = { `${
106+ isRunning || array . length === 0
107+ ? "bg-indigo-500 text-white cursor-not-allowed"
108+ : "bg-indigo-500 hover:bg-indigo-900"
109+ } px-6 py-2 rounded-lg text-white font-semibold shadow-md transition-all duration-300`}
110+ >
111+ { isRunning ? "Searching..." : "Start Linear Search" }
112+ </ button >
113+ < button
114+ onClick = { handleReset }
115+ className = "bg-gray-700 hover:bg-gray-600 px-6 py-2 rounded-lg text-white font-semibold shadow-md transition-all duration-300"
116+ >
117+ Reset
118+ </ button >
119+ </ div >
120+
121+ < div className = "mt-15" >
122+ { /* USE THE NEW VISUALIZER AND PASS SEARCH STATES */ }
123+ < LinearSearchVisualizer
124+ array = { array }
125+ highlightIndex = { highlightIndex }
126+ foundIndex = { foundIndex }
127+ />
128+ </ div >
129+
130+ </ div >
131+ ) ;
132+ }
0 commit comments