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:
parent
e6d7fc6209
commit
89c0d552f6
2 changed files with 18 additions and 45 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue