"use client"; import { useState, useEffect } from "react"; import { Button } from "./ui/Button"; import { Input } from "./ui/Input"; import { Search, FileText, FolderOpen, Code, Settings, Database, Copy, Check, } from "lucide-react"; import { fetchSnippets, fetchSnippetCategories, searchSnippets, type BashSnippet, } from "../_server/actions/snippets"; interface BashSnippetHelperProps { onInsertSnippet: (snippet: string) => void; } const categoryIcons = { "File Operations": FileText, Loops: Code, Conditionals: Code, "System Operations": Settings, "Database Operations": Database, "User Examples": FolderOpen, "Custom Scripts": Code, }; export function BashSnippetHelper({ onInsertSnippet }: BashSnippetHelperProps) { const [searchQuery, setSearchQuery] = useState(""); const [selectedCategory, setSelectedCategory] = useState(null); const [copiedId, setCopiedId] = useState(null); const [snippets, setSnippets] = useState([]); const [categories, setCategories] = useState([]); const [filteredSnippets, setFilteredSnippets] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const loadData = async () => { try { const [snippetsData, categoriesData] = await Promise.all([ fetchSnippets(), fetchSnippetCategories(), ]); setSnippets(snippetsData); setCategories(categoriesData); } catch (error) { console.error("Error loading snippets:", error); } finally { setLoading(false); } }; loadData(); }, []); useEffect(() => { const filterSnippets = async () => { if (searchQuery) { const searchResults = await searchSnippets(searchQuery); setFilteredSnippets(searchResults); } else if (selectedCategory) { const categoryResults = snippets.filter( (s) => s.category === selectedCategory ); setFilteredSnippets(categoryResults); } else { setFilteredSnippets(snippets); } }; filterSnippets(); }, [searchQuery, selectedCategory, snippets]); const handleCopy = async (snippet: BashSnippet) => { try { if (navigator.clipboard) { await navigator.clipboard.writeText(snippet.template); } else { const textArea = document.createElement("textarea"); textArea.value = snippet.template; document.body.appendChild(textArea); textArea.select(); document.execCommand("copy"); document.body.removeChild(textArea); } setCopiedId(snippet.id); setTimeout(() => setCopiedId(null), 2000); } catch (error) { console.error("Failed to copy to clipboard:", error); } }; const handleInsert = (snippet: BashSnippet) => { onInsertSnippet(snippet.template); }; if (loading) { return (

Loading snippets...

); } return (
setSearchQuery(e.target.value)} placeholder="Search bash snippets..." className="pl-9" />
{!searchQuery && (
{categories.map((category) => { const Icon = categoryIcons[category as keyof typeof categoryIcons] || Code; return ( ); })}
)}
{filteredSnippets.map((snippet) => { const Icon = categoryIcons[snippet.category as keyof typeof categoryIcons] || Code; return (

{snippet.title}

{snippet.source === "user" && ( User )}

{snippet.description}

{snippet.tags.slice(0, 3).map((tag) => ( {tag} ))} {snippet.tags.length > 3 && ( +{snippet.tags.length - 3} more )}
); })} {filteredSnippets.length === 0 && (

{searchQuery ? `No snippets found for "${searchQuery}"` : "No snippets available"}

)}
); }