diff --git a/src/app/devtools/page.jsx b/src/app/devtools/DevToolsPageClient.tsx similarity index 75% rename from src/app/devtools/page.jsx rename to src/app/devtools/DevToolsPageClient.tsx index f5b93b51..2e6a1899 100644 --- a/src/app/devtools/page.jsx +++ b/src/app/devtools/DevToolsPageClient.tsx @@ -1,43 +1,49 @@ 'use client' -import { SimpleLayout } from '@/components/SimpleLayout' -import { getTools } from '@/lib/getTools' -import DevToolSearchFilter from '@/components/DevToolSearchFilter' import { useState } from 'react' import { useRouter } from 'next/navigation' -import { track } from '@vercel/analytics' -import { Button } from "@/components/ui/button"; -import { DiffIcon, SearchIcon } from "lucide-react"; import Image from 'next/image' -import { CodeIcon } from 'lucide-react' +import { track } from '@vercel/analytics' +import { SimpleLayout } from '@/components/SimpleLayout' +import DevToolSearchFilter from '@/components/DevToolSearchFilter' +import { Button } from "@/components/ui/button" +import { DiffIcon, SearchIcon, CodeIcon } from "lucide-react" import { getLogoById } from '@/lib/logoImports' -import heroImage from '@/images/ai-hacking.webp' +import heroImage from '@/images/ai-hacking.webp' + +interface Tool { + name: string + description: string +} + +interface DevToolsPageClientProps { + initialTools: Tool[] +} -export default function DevToolsIndex() { - const router = useRouter(); - const allTools = getTools(); - const [filteredTools, setFilteredTools] = useState(allTools); - const [searchTerm, setSearchTerm] = useState(''); +export default function DevToolsPageClient({ initialTools }: DevToolsPageClientProps) { + const router = useRouter() + const [filteredTools, setFilteredTools] = useState(initialTools) + const [searchTerm, setSearchTerm] = useState('') - const handleFilter = (filtered, term) => { - setFilteredTools(filtered); - setSearchTerm(term); - }; + const handleFilter = (filtered: Tool[], term: string) => { + setFilteredTools(filtered) + setSearchTerm(term) + } const handleReset = () => { - setFilteredTools(allTools); - setSearchTerm(''); - }; + setFilteredTools(initialTools) + setSearchTerm('') + } - const handleCompareClick = (toolName) => { - track('compare_click', { tool: toolName }); - router.push(`/devtools/compare?tools=${encodeURIComponent(toolName)}`); - }; + const handleCompareClick = (toolName: string) => { + track('compare_click', { tool: toolName }) + router.push(`/devtools/compare?tools=${encodeURIComponent(toolName)}`) + } - const handleDetailsClick = (toolName) => { - track('details_click', { tool: toolName }); - router.push(`/devtools/detail/${encodeURIComponent(toolName)}`); - }; + const handleDetailsClick = (toolName: string) => { + track('details_click', { tool: toolName }) + router.push(`/devtools/detail/${encodeURIComponent(toolName)}`) + } return ( +} \ No newline at end of file diff --git a/src/app/vectordatabases/page.jsx b/src/app/vectordatabases/VectorDatabasesPageClient.tsx similarity index 81% rename from src/app/vectordatabases/page.jsx rename to src/app/vectordatabases/VectorDatabasesPageClient.tsx index ee2fc5bd..06406442 100644 --- a/src/app/vectordatabases/page.jsx +++ b/src/app/vectordatabases/VectorDatabasesPageClient.tsx @@ -6,34 +6,42 @@ import Image from 'next/image'; import { track } from '@vercel/analytics'; import { SimpleLayout } from '@/components/SimpleLayout' import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; -import { getDatabases } from '@/lib/getDatabases'; import { getLogoById } from '@/lib/logoImports'; import SearchFilter from '@/components/SearchFilter'; import { Button } from "@/components/ui/button"; import { DiffIcon, SearchIcon } from "lucide-react"; -export default function GalleryPage() { +interface Database { + name: string; + description: string; + logoId: string; +} + +interface VectorDatabasesPageClientProps { + initialDatabases: Database[]; +} + +export default function VectorDatabasesPageClient({ initialDatabases }: VectorDatabasesPageClientProps) { const router = useRouter(); - const allDatabases = getDatabases(); - const [filteredDatabases, setFilteredDatabases] = useState(allDatabases); + const [filteredDatabases, setFilteredDatabases] = useState(initialDatabases); const [searchTerm, setSearchTerm] = useState(''); - const handleFilter = (filtered, term) => { + const handleFilter = (filtered: Database[], term: string) => { setFilteredDatabases(filtered); setSearchTerm(term); }; const handleReset = () => { - setFilteredDatabases(allDatabases); + setFilteredDatabases(initialDatabases); setSearchTerm(''); }; - const handleCompareClick = (dbName) => { + const handleCompareClick = (dbName: string) => { track('compare_click', { database: dbName }); router.push(`/vectordatabases/compare?dbs=${encodeURIComponent(dbName)}`); }; - const handleDetailsClick = (dbName) => { + const handleDetailsClick = (dbName: string) => { track('details_click', { database: dbName }); router.push(`/vectordatabases/detail/${encodeURIComponent(dbName)}`); }; @@ -44,7 +52,7 @@ export default function GalleryPage() { intro="Explore and compare vector databases" >
); -} +} \ No newline at end of file diff --git a/src/app/vectordatabases/page.tsx b/src/app/vectordatabases/page.tsx new file mode 100644 index 00000000..e391610f --- /dev/null +++ b/src/app/vectordatabases/page.tsx @@ -0,0 +1,14 @@ +import { Metadata } from 'next' +import VectorDatabasesPageClient from './VectorDatabasesPageClient' +import { getDatabases } from '@/lib/getDatabases' +import { createMetadata } from '@/utils/createMetadata' + +export const metadata: Metadata = createMetadata({ + title: 'Vector Databases Compared', + description: 'Explore and compare vector databases', +}) + +export default function VectorDatabasesPage() { + const databases = getDatabases() + return +} diff --git a/src/components/SearchFilter.jsx b/src/components/SearchFilter.jsx index 1e901e62..2319a325 100644 --- a/src/components/SearchFilter.jsx +++ b/src/components/SearchFilter.jsx @@ -1,10 +1,10 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Input } from "@/components/ui/input"; import { Checkbox } from "@/components/ui/checkbox"; import { Label } from "@/components/ui/label"; -export default function SearchFilter({ databases, onFilter }) { - const [search, setSearch] = useState(''); +export default function SearchFilter({ databases, onFilter, onReset, searchTerm: externalSearchTerm }) { + const [search, setSearch] = useState(externalSearchTerm || ''); const [filters, setFilters] = useState({ cloud: false, local: false, @@ -13,9 +13,14 @@ export default function SearchFilter({ databases, onFilter }) { open_source: false, }); + useEffect(() => { + setSearch(externalSearchTerm || ''); + }, [externalSearchTerm]); + const handleSearchChange = (e) => { - setSearch(e.target.value); - applyFilters(e.target.value, filters); + const newSearchTerm = e.target.value; + setSearch(newSearchTerm); + applyFilters(newSearchTerm, filters); }; const handleFilterChange = (key) => { @@ -45,7 +50,19 @@ export default function SearchFilter({ databases, onFilter }) { }); return matchesSearch && matchesFilters; }); - onFilter(filtered); + onFilter(filtered, searchTerm); + }; + + const handleReset = () => { + setSearch(''); + setFilters({ + cloud: false, + local: false, + on_premises: false, + free_tier: false, + open_source: false, + }); + onReset(); }; return ( @@ -68,6 +85,7 @@ export default function SearchFilter({ databases, onFilter }) { ))} + ); }