@@ -33,6 +33,7 @@ export default function ScriptGenerator() {
3333 const [ selectedPkg , setSelectedPkg ] = useState < PkgManager > ( "choco" ) ;
3434 const [ selectedTools , setSelectedTools ] = useState < string [ ] > ( [ ] ) ;
3535 const [ loading , setLoading ] = useState ( true ) ;
36+ const [ searchQuery , setSearchQuery ] = useState < string > ( "" ) ;
3637
3738 // Theme
3839 const [ theme , setTheme ] = useState < "light" | "dark" > ( "dark" ) ;
@@ -103,29 +104,92 @@ export default function ScriptGenerator() {
103104 data-theme = { theme }
104105 >
105106 < div className = "max-w-screen mx-auto px-4 py-10" >
106- { /* Header with Add + and theme toggle */ }
107- < h1 className = "flex items-center justify-center text-4xl sm:text-6xl font-extrabold mb-10 relative tracking-tight" >
108- DevSetup
109- < div className = "absolute right-0 top-1/2 -translate-y-1/2 flex gap-3" >
107+ { /* Header with Title, Search, and Action buttons */ }
108+ < div className = "flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6 mb-12" >
109+ { /* Left side - Title */ }
110+ < h1 className = "text-4xl sm:text-6xl font-extrabold tracking-tight text-left" >
111+ < span className = "text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 via-purple-600 to-pink-500" >
112+ DevSetup
113+ </ span >
114+ </ h1 >
115+
116+ { /* Center/Bottom - Search Box */ }
117+ < div className = "relative w-full max-w-2xl lg:max-w-3xl hidden sm:block" >
118+ < input
119+ type = "text"
120+ placeholder = "Search for development tools..."
121+ value = { searchQuery }
122+ onChange = { ( e ) => setSearchQuery ( e . target . value ) }
123+ className = "w-full px-8 py-4 pl-16 bg-gradient-to-r from-[var(--card-bg)] to-gray-800/50 text-[var(--foreground)] border-2 border-gray-600/50 rounded-2xl focus:outline-none focus:ring-4 focus:ring-indigo-500/30 focus:border-indigo-400 transition-all duration-500 text-lg placeholder-gray-400 shadow-2xl hover:shadow-indigo-500/20 backdrop-blur-sm"
124+ />
125+ < div className = "absolute left-5 top-1/2 transform -translate-y-1/2" >
126+ < svg
127+ className = "w-6 h-6 text-indigo-400"
128+ fill = "none"
129+ stroke = "currentColor"
130+ viewBox = "0 0 24 24"
131+ >
132+ < path
133+ strokeLinecap = "round"
134+ strokeLinejoin = "round"
135+ strokeWidth = { 2.5 }
136+ d = "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
137+ />
138+ </ svg >
139+ </ div >
140+ < div className = "absolute inset-0 rounded-2xl bg-gradient-to-r from-indigo-500/10 to-purple-500/10 pointer-events-none" > </ div >
141+ </ div >
142+
143+ { /* Right side - Action buttons */ }
144+ < div className = "flex gap-4 lg:flex-shrink-0" >
110145 { /* Add New + button */ }
111146 < a
112147 href = "https://forms.gle/cWfDnzvYo5dBuy7C7"
113148 target = "_blank"
114149 rel = "noopener noreferrer"
115- className = "px-6 py-3 text-lg bg-gradient-to-r from-indigo-500 to -purple-600 hover:from-indigo-600 hover:to -purple-700 text-white font-semibold rounded-full shadow-lg transition duration-300"
150+ className = "px-8 py-4 text-lg bg-gradient-to-r from-indigo-500 via -purple-600 to-pink-500 hover:from-indigo-600 hover:via -purple-700 hover:to-pink-600 text-white font-bold rounded-2xl shadow-2xl hover:shadow-indigo-500/30 transition-all duration-300 transform hover:scale-105 hover:-translate-y-1 "
116151 >
117- Add New +
152+ Add New +
118153 </ a >
119154
120- { /* Theme Toggle button (exactly same size/style as Add +) */ }
155+ { /* Theme Toggle button */ }
121156 < button
122157 onClick = { ( ) => setTheme ( theme === "light" ? "dark" : "light" ) }
123- className = "px-6 py-3 text-lg bg-gradient-to-r from-gray-500 to-gray-700 hover:from-gray-600 hover:to-gray-800 text-white font-semibold rounded-full shadow-lg transition duration-300"
158+ className = "px-8 py-4 text-lg bg-gradient-to-r from-gray-600 to-gray-800 hover:from-gray-700 hover:to-gray-900 text-white font-bold rounded-2xl shadow-2xl hover:shadow-gray-500/30 transition-all duration-300 transform hover:scale-105 hover:-translate-y-1 "
124159 >
125160 { theme === "light" ? "🌞 Light" : "🌙 Dark" }
126161 </ button >
127162 </ div >
128- </ h1 >
163+ </ div >
164+
165+ { /* Mobile Search Box */ }
166+ < div className = "mb-10 sm:hidden" >
167+ < div className = "relative" >
168+ < input
169+ type = "text"
170+ placeholder = "🔍 Search for development tools..."
171+ value = { searchQuery }
172+ onChange = { ( e ) => setSearchQuery ( e . target . value ) }
173+ className = "w-full px-8 py-5 pl-16 bg-gradient-to-r from-[var(--card-bg)] to-gray-800/50 text-[var(--foreground)] border-2 border-gray-600/50 rounded-2xl focus:outline-none focus:ring-4 focus:ring-indigo-500/30 focus:border-indigo-400 transition-all duration-500 text-lg placeholder-gray-400 shadow-2xl hover:shadow-indigo-500/20 backdrop-blur-sm"
174+ />
175+ < div className = "absolute left-5 top-1/2 transform -translate-y-1/2" >
176+ < svg
177+ className = "w-6 h-6 text-indigo-400"
178+ fill = "none"
179+ stroke = "currentColor"
180+ viewBox = "0 0 24 24"
181+ >
182+ < path
183+ strokeLinecap = "round"
184+ strokeLinejoin = "round"
185+ strokeWidth = { 2.5 }
186+ d = "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
187+ />
188+ </ svg >
189+ </ div >
190+ < div className = "absolute inset-0 rounded-2xl bg-gradient-to-r from-indigo-500/10 to-purple-500/10 pointer-events-none" > </ div >
191+ </ div >
192+ </ div >
129193
130194 { /* OS Selector */ }
131195 < div className = "flex flex-wrap gap-3 justify-center sm:justify-start mb-6" >
@@ -169,35 +233,45 @@ export default function ScriptGenerator() {
169233 </ div >
170234
171235 { /* Tool Categories */ }
172- { toolsData . map ( ( group , i ) => (
173- < div key = { i } className = "mb-10" >
174- < h2 className = "text-2xl font-semibold mb-4 border-b border-gray-700 pb-1" >
175- { group . category }
176- </ h2 >
177- < div className = "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-5 gap-6" >
178- { group . tools . map ( ( tool , index ) => {
179- const isAvailable = ! ! tool . install [ selectedPkg ] ;
180- return (
181- < label
182- key = { index }
183- className = { `relative flex flex-col items-center justify-center rounded-2xl p-4 transition cursor-pointer border border-transparent bg-[var(--card-bg)] ${
184- isAvailable ? "hover:shadow-xl hover:border-indigo-500" : "opacity-50 cursor-not-allowed"
185- } `}
186- >
187- < input
188- type = "checkbox"
189- disabled = { ! isAvailable }
190- checked = { selectedTools . includes ( tool . name ) }
191- onChange = { ( ) => handleToolSelect ( tool . name ) }
192- className = "absolute top-2 right-2 w-5 h-5 accent-indigo-500"
193- />
194- < span className = "text-sm text-center" > { tool . name } </ span >
195- </ label >
196- ) ;
197- } ) }
236+ { toolsData . map ( ( group , i ) => {
237+ // Filter tools based on search query
238+ const filteredTools = group . tools . filter ( tool =>
239+ tool . name . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
240+ ) ;
241+
242+ // Only render category if it has matching tools
243+ if ( filteredTools . length === 0 ) return null ;
244+
245+ return (
246+ < div key = { i } className = "mb-10" >
247+ < h2 className = "text-2xl font-semibold mb-4 border-b border-gray-700 pb-1" >
248+ { group . category }
249+ </ h2 >
250+ < div className = "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-5 gap-6" >
251+ { filteredTools . map ( ( tool , index ) => {
252+ const isAvailable = ! ! tool . install [ selectedPkg ] ;
253+ return (
254+ < label
255+ key = { index }
256+ className = { `relative flex flex-col items-center justify-center rounded-2xl p-4 transition cursor-pointer border border-transparent bg-[var(--card-bg)] ${
257+ isAvailable ? "hover:shadow-xl hover:border-indigo-500" : "opacity-50 cursor-not-allowed"
258+ } `}
259+ >
260+ < input
261+ type = "checkbox"
262+ disabled = { ! isAvailable }
263+ checked = { selectedTools . includes ( tool . name ) }
264+ onChange = { ( ) => handleToolSelect ( tool . name ) }
265+ className = "absolute top-2 right-2 w-5 h-5 accent-indigo-500"
266+ />
267+ < span className = "text-sm text-center" > { tool . name } </ span >
268+ </ label >
269+ ) ;
270+ } ) }
271+ </ div >
198272 </ div >
199- </ div >
200- ) ) }
273+ ) ;
274+ } ) }
201275
202276 { /* Script Output */ }
203277 < div className = "mt-12" >
0 commit comments