diff --git a/src/components/TipsList.tsx b/src/components/TipsList.tsx index 1a404d34..2eb09379 100644 --- a/src/components/TipsList.tsx +++ b/src/components/TipsList.tsx @@ -1,11 +1,23 @@ +'use client' + +import { useState } from 'react' import { Link } from 'vocs' import FileText from '~icons/lucide/file-text' +import Search from '~icons/lucide/search' const modules = import.meta.glob('../pages/protocol/tips/tip-*.mdx', { eager: true, }) as Record< string, - { frontmatter?: { id?: string; title?: string; description?: string; status?: string } } + { + frontmatter?: { + id?: string + title?: string + description?: string + status?: string + searchable?: boolean + } + } > const tips = Object.entries(modules) @@ -13,31 +25,58 @@ const tips = Object.entries(modules) path: path.replace('../pages', '').replace(/\.mdx?$/, ''), ...mod.frontmatter, })) - .filter((t) => t.id && t.title) + .filter((t) => t.searchable !== false && t.id && t.title) .sort((a, b) => a.path.localeCompare(b.path, undefined, { numeric: true })) export function TipsList() { + const [query, setQuery] = useState('') + const q = query.trim().toLowerCase() + const filtered = q + ? tips.filter( + (tip) => + tip.id?.toLowerCase().includes(q) || + tip.title?.toLowerCase().includes(q) || + tip.description?.toLowerCase().includes(q) || + tip.status?.toLowerCase().includes(q), + ) + : tips + return ( -
- {tips.map((tip) => ( - - -
- - {tip.id}: {tip.title} - - {tip.description && ( - - {tip.description} +
+
+ + setQuery(e.target.value)} + placeholder="Search by number, name, or status…" + className="vocs:w-full vocs:rounded-md vocs:border vocs:border-primary vocs:bg-surfaceTint/70 vocs:py-2 vocs:pl-9 vocs:pr-3 vocs:text-sm vocs:text-heading vocs:placeholder-secondary vocs:outline-none vocs:focus:border-link" + /> +
+ {filtered.length === 0 ? ( +

No TIPs found.

+ ) : ( + filtered.map((tip) => ( + + +
+ + {tip.id}: {tip.title} - )} -
- - ))} + {tip.description && ( + + {tip.description} + + )} +
+ + )) + )}
) }