Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor /devtools and /vectordatabases to support metadata #595

Merged
merged 4 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 (
<SimpleLayout
Expand All @@ -54,7 +60,7 @@ export default function DevToolsIndex() {
/>
</div>
<DevToolSearchFilter
tools={allTools}
tools={initialTools}
onFilter={handleFilter}
onReset={handleReset}
searchTerm={searchTerm}
Expand Down
14 changes: 14 additions & 0 deletions src/app/devtools/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Metadata } from 'next'
import DevToolsPageClient from './DevToolsPageClient'
import { getTools } from '@/lib/getTools'
import { createMetadata } from '@/utils/createMetadata'

export const metadata: Metadata = createMetadata({
title: 'AI-Assisted Developer Tools Compared',
description: 'Compare different AI-assisted developer tools to find the best fit for your needs',
});

export default function DevToolsPage() {
const tools = getTools()
return <DevToolsPageClient initialTools={tools} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)}`);
};
Expand All @@ -44,7 +52,7 @@ export default function GalleryPage() {
intro="Explore and compare vector databases"
>
<SearchFilter
databases={allDatabases}
databases={initialDatabases}
onFilter={handleFilter}
onReset={handleReset}
searchTerm={searchTerm}
Expand All @@ -70,7 +78,7 @@ export default function GalleryPage() {
</CardContent>
<div className="p-4 mt-auto flex justify-between">
<Button
variant="primary"
variant="secondary"
className="bg-blue-500 hover:bg-blue-600 text-white"
onClick={() => handleCompareClick(db.name)}
>
Expand All @@ -92,4 +100,4 @@ export default function GalleryPage() {
</div>
</SimpleLayout>
);
}
}
14 changes: 14 additions & 0 deletions src/app/vectordatabases/page.tsx
Original file line number Diff line number Diff line change
@@ -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 <VectorDatabasesPageClient initialDatabases={databases} />
}
30 changes: 24 additions & 6 deletions src/components/SearchFilter.jsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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) => {
Expand Down Expand Up @@ -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 (
Expand All @@ -68,6 +85,7 @@ export default function SearchFilter({ databases, onFilter }) {
</div>
))}
</div>
<button onClick={handleReset}>Reset</button>
</div>
);
}
Loading