Skip to content

Commit ff6ae91

Browse files
committed
search box implemented
1 parent 594c544 commit ff6ae91

1 file changed

Lines changed: 100 additions & 34 deletions

File tree

src/app/page.tsx

Lines changed: 100 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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,10 +104,39 @@ 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 Search, Add + and theme toggle */}
108+
<div className="flex items-center justify-between mb-10">
109+
{/* Left side - Search Box */}
110+
<div className="relative w-64 hidden sm:block">
111+
<input
112+
type="text"
113+
placeholder="Search tools..."
114+
value={searchQuery}
115+
onChange={(e) => setSearchQuery(e.target.value)}
116+
className="w-full px-4 py-2 pl-10 bg-[var(--card-bg)] text-[var(--foreground)] border border-gray-600 rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200 text-sm"
117+
/>
118+
<svg
119+
className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400"
120+
fill="none"
121+
stroke="currentColor"
122+
viewBox="0 0 24 24"
123+
>
124+
<path
125+
strokeLinecap="round"
126+
strokeLinejoin="round"
127+
strokeWidth={2}
128+
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
129+
/>
130+
</svg>
131+
</div>
132+
133+
{/* Center - Title */}
134+
<h1 className="text-4xl sm:text-6xl font-extrabold tracking-tight">
135+
DevSetup
136+
</h1>
137+
138+
{/* Right side - Action buttons */}
139+
<div className="flex gap-3">
110140
{/* Add New + button */}
111141
<a
112142
href="https://forms.gle/cWfDnzvYo5dBuy7C7"
@@ -117,15 +147,41 @@ export default function ScriptGenerator() {
117147
Add New +
118148
</a>
119149

120-
{/* Theme Toggle button (exactly same size/style as Add +) */}
150+
{/* Theme Toggle button */}
121151
<button
122152
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
123153
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"
124154
>
125155
{theme === "light" ? "🌞 Light" : "🌙 Dark"}
126156
</button>
127157
</div>
128-
</h1>
158+
</div>
159+
160+
{/* Mobile Search Box */}
161+
<div className="mb-6 sm:hidden">
162+
<div className="relative">
163+
<input
164+
type="text"
165+
placeholder="Search tools..."
166+
value={searchQuery}
167+
onChange={(e) => setSearchQuery(e.target.value)}
168+
className="w-full px-4 py-3 pl-10 bg-[var(--card-bg)] text-[var(--foreground)] border border-gray-600 rounded-full focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition-all duration-200"
169+
/>
170+
<svg
171+
className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400"
172+
fill="none"
173+
stroke="currentColor"
174+
viewBox="0 0 24 24"
175+
>
176+
<path
177+
strokeLinecap="round"
178+
strokeLinejoin="round"
179+
strokeWidth={2}
180+
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
181+
/>
182+
</svg>
183+
</div>
184+
</div>
129185

130186
{/* OS Selector */}
131187
<div className="flex flex-wrap gap-3 justify-center sm:justify-start mb-6">
@@ -169,35 +225,45 @@ export default function ScriptGenerator() {
169225
</div>
170226

171227
{/* 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-
})}
228+
{toolsData.map((group, i) => {
229+
// Filter tools based on search query
230+
const filteredTools = group.tools.filter(tool =>
231+
tool.name.toLowerCase().includes(searchQuery.toLowerCase())
232+
);
233+
234+
// Only render category if it has matching tools
235+
if (filteredTools.length === 0) return null;
236+
237+
return (
238+
<div key={i} className="mb-10">
239+
<h2 className="text-2xl font-semibold mb-4 border-b border-gray-700 pb-1">
240+
{group.category}
241+
</h2>
242+
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-5 gap-6">
243+
{filteredTools.map((tool, index) => {
244+
const isAvailable = !!tool.install[selectedPkg];
245+
return (
246+
<label
247+
key={index}
248+
className={`relative flex flex-col items-center justify-center rounded-2xl p-4 transition cursor-pointer border border-transparent bg-[var(--card-bg)] ${
249+
isAvailable? "hover:shadow-xl hover:border-indigo-500" : "opacity-50 cursor-not-allowed"
250+
}`}
251+
>
252+
<input
253+
type="checkbox"
254+
disabled={!isAvailable}
255+
checked={selectedTools.includes(tool.name)}
256+
onChange={() => handleToolSelect(tool.name)}
257+
className="absolute top-2 right-2 w-5 h-5 accent-indigo-500"
258+
/>
259+
<span className="text-sm text-center">{tool.name}</span>
260+
</label>
261+
);
262+
})}
263+
</div>
198264
</div>
199-
</div>
200-
))}
265+
);
266+
})}
201267

202268
{/* Script Output */}
203269
<div className="mt-12">

0 commit comments

Comments
 (0)