fix(tool-search): remove tabs and show all tools by default

- Remove Tabs component and activeTab state
- Show all tools in a single grid view
- Simplify API calls by removing unnecessary count fetches
- Add missing Script import in layout.tsx
This commit is contained in:
Ajax Davis 2025-12-11 06:25:04 +10:00
parent e6d7fc6209
commit 89c0d552f6
2 changed files with 18 additions and 45 deletions

View file

@ -1,5 +1,6 @@
import type { Metadata } from 'next';
import { Space_Grotesk, Space_Mono } from 'next/font/google';
import Script from 'next/script';
import { AppFooter } from '../components/AppFooter';
import { ThemeProvider } from '../components/providers/ThemeProvider';
import './globals.css';
@ -34,6 +35,20 @@ export default function RootLayout({
suppressHydrationWarning
className={`${spaceGrotesk.variable} ${spaceMono.variable}`}
>
<head>
{process.env.NODE_ENV === 'development' && (
<>
<Script
src="//unpkg.com/react-grab/dist/index.global.js"
strategy="beforeInteractive"
/>
<Script
src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"
strategy="lazyOnload"
/>
</>
)}
</head>
<body className={spaceGrotesk.className}>
<ThemeProvider
attribute="class"

View file

@ -16,7 +16,6 @@ import { Icon } from '@tpmjs/ui/Icon/Icon';
import { Input } from '@tpmjs/ui/Input/Input';
import { ProgressBar } from '@tpmjs/ui/ProgressBar/ProgressBar';
import { Select } from '@tpmjs/ui/Select/Select';
import { Tabs } from '@tpmjs/ui/Tabs/Tabs';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import { AppHeader } from '~/components/AppHeader';
@ -44,7 +43,6 @@ interface Tool {
* Fetches tools from the /api/tools endpoint and displays them in a searchable grid.
*/
export default function ToolSearchPage(): React.ReactElement {
const [activeTab, setActiveTab] = useState('all');
const [searchQuery, setSearchQuery] = useState('');
const [categoryFilter, setCategoryFilter] = useState('all');
const [healthFilter, setHealthFilter] = useState('all');
@ -52,8 +50,6 @@ export default function ToolSearchPage(): React.ReactElement {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [availableCategories, setAvailableCategories] = useState<string[]>([]);
const [totalCount, setTotalCount] = useState(0);
const [officialCount, setOfficialCount] = useState(0);
// Fetch tools from API
useEffect(() => {
@ -66,10 +62,6 @@ export default function ToolSearchPage(): React.ReactElement {
params.set('q', searchQuery);
}
if (activeTab === 'featured') {
params.set('official', 'true');
}
if (categoryFilter !== 'all') {
params.set('category', categoryFilter);
}
@ -81,32 +73,14 @@ export default function ToolSearchPage(): React.ReactElement {
params.set('broken', 'true');
}
// Fetch tools and counts in parallel
const [toolsResponse, allCountResponse, officialCountResponse] = await Promise.all([
fetch(`/api/tools?${params.toString()}`),
fetch('/api/tools'),
fetch('/api/tools?official=true'),
]);
const [toolsData, allCountData, officialCountData] = await Promise.all([
toolsResponse.json(),
allCountResponse.json(),
officialCountResponse.json(),
]);
const toolsResponse = await fetch(`/api/tools?${params.toString()}`);
const toolsData = await toolsResponse.json();
if (toolsData.success) {
const fetchedTools = toolsData.data;
setTools(fetchedTools);
setError(null);
// Update counts
if (allCountData.success) {
setTotalCount(allCountData.data.length);
}
if (officialCountData.success) {
setOfficialCount(officialCountData.data.length);
}
// Extract unique categories from all tools
const categories = new Set<string>();
@ -128,7 +102,7 @@ export default function ToolSearchPage(): React.ReactElement {
};
fetchTools();
}, [searchQuery, activeTab, categoryFilter, healthFilter]);
}, [searchQuery, categoryFilter, healthFilter]);
return (
<div className="min-h-screen bg-background">
@ -203,22 +177,6 @@ export default function ToolSearchPage(): React.ReactElement {
</div>
</div>
{/* Tabs */}
<Tabs
tabs={[
{ id: 'all', label: 'All Tools', count: totalCount },
{
id: 'featured',
label: 'Official',
count: officialCount,
},
]}
activeTab={activeTab}
onTabChange={setActiveTab}
size="md"
className="mb-8"
/>
{/* Loading state */}
{loading && (
<div className="text-center py-12 text-foreground-secondary">Loading tools...</div>