From 3ff9df1c668ca0b4fed0f5fb9b913170df2edec6 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sat, 17 Jan 2026 21:19:10 +0000 Subject: [PATCH] Generated by Spark: Remove duplicate components. --- src/components/SnippetManager.tsx | 524 +----------------------------- 1 file changed, 1 insertion(+), 523 deletions(-) diff --git a/src/components/SnippetManager.tsx b/src/components/SnippetManager.tsx index a6c531a..42ae5d6 100644 --- a/src/components/SnippetManager.tsx +++ b/src/components/SnippetManager.tsx @@ -1,523 +1 @@ -import { useState, useMemo, useCallback, useEffect } from 'react' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Plus, MagnifyingGlass, CaretDown, CheckSquare, FolderOpen, X } from '@phosphor-icons/react' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, - DropdownMenuLabel, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, -} from '@/components/ui/dropdown-menu' -import { SnippetCard } from '@/components/SnippetCard' -import { SnippetDialog } from '@/components/SnippetDialog' -import { SnippetViewer } from '@/components/SnippetViewer' -import { EmptyState } from '@/components/EmptyState' -import { NamespaceSelector } from '@/components/NamespaceSelector' -import { Snippet, SnippetTemplate, Namespace } from '@/lib/types' -import { toast } from 'sonner' -import { strings } from '@/lib/config' -import templatesData from '@/data/templates.json' -import { - getAllSnippets, - createSnippet, - updateSnippet, - deleteSnippet as deleteSnippetDB, - seedDatabase, - syncTemplatesFromJSON, - getSnippetsByNamespace, - ensureDefaultNamespace, - getAllNamespaces, - bulkMoveSnippets -} from '@/lib/db' - -const templates = templatesData as SnippetTemplate[] - -export function SnippetManager() { - const [snippets, setSnippets] = useState([]) - const [loading, setLoading] = useState(true) - const [searchQuery, setSearchQuery] = useState('') - const [dialogOpen, setDialogOpen] = useState(false) - const [viewerOpen, setViewerOpen] = useState(false) - const [editingSnippet, setEditingSnippet] = useState(null) - const [viewingSnippet, setViewingSnippet] = useState(null) - const [selectedNamespaceId, setSelectedNamespaceId] = useState(null) - const [selectionMode, setSelectionMode] = useState(false) - const [selectedSnippetIds, setSelectedSnippetIds] = useState>(new Set()) - const [namespaces, setNamespaces] = useState([]) - - useEffect(() => { - const loadData = async () => { - setLoading(true) - try { - await seedDatabase() - await syncTemplatesFromJSON(templates) - - const loadedNamespaces = await getAllNamespaces() - setNamespaces(loadedNamespaces) - - const defaultNamespace = loadedNamespaces.find(n => n.isDefault) - if (defaultNamespace) { - setSelectedNamespaceId(defaultNamespace.id) - const loadedSnippets = await getSnippetsByNamespace(defaultNamespace.id) - setSnippets(loadedSnippets) - } - } catch (error) { - console.error('Failed to load data:', error) - toast.error('Failed to load data') - } finally { - setLoading(false) - } - } - - loadData() - }, []) - - useEffect(() => { - const loadSnippetsForNamespace = async () => { - if (!selectedNamespaceId) return - - try { - const loadedSnippets = await getSnippetsByNamespace(selectedNamespaceId) - setSnippets(loadedSnippets) - } catch (error) { - console.error('Failed to load snippets:', error) - toast.error('Failed to load snippets') - } - } - - loadSnippetsForNamespace() - }, [selectedNamespaceId]) - - const filteredSnippets = useMemo(() => { - const allSnippets = snippets || [] - if (!searchQuery.trim()) return allSnippets - - const query = searchQuery.toLowerCase() - return allSnippets.filter( - (snippet) => - snippet.title.toLowerCase().includes(query) || - snippet.description.toLowerCase().includes(query) || - snippet.language.toLowerCase().includes(query) || - snippet.code.toLowerCase().includes(query) - ) - }, [snippets, searchQuery]) - - const handleSaveSnippet = useCallback(async (snippetData: Omit) => { - try { - if (editingSnippet?.id) { - const updatedSnippet = { - ...editingSnippet, - ...snippetData, - updatedAt: Date.now(), - } - await updateSnippet(updatedSnippet) - setSnippets((current) => - current.map((s) => s.id === editingSnippet.id ? updatedSnippet : s) - ) - toast.success(strings.toast.snippetUpdated) - } else { - const newSnippet: Snippet = { - ...snippetData, - id: Date.now().toString(), - namespaceId: selectedNamespaceId || undefined, - createdAt: Date.now(), - updatedAt: Date.now(), - } - await createSnippet(newSnippet) - setSnippets((current) => [newSnippet, ...current]) - toast.success(strings.toast.snippetCreated) - } - setEditingSnippet(null) - } catch (error) { - console.error('Failed to save snippet:', error) - toast.error('Failed to save snippet') - } - }, [editingSnippet, selectedNamespaceId]) - - const handleEditSnippet = useCallback((snippet: Snippet) => { - setEditingSnippet(snippet) - setDialogOpen(true) - }, []) - - const handleDeleteSnippet = useCallback(async (id: string) => { - try { - await deleteSnippetDB(id) - setSnippets((current) => current.filter((s) => s.id !== id)) - toast.success(strings.toast.snippetDeleted) - } catch (error) { - console.error('Failed to delete snippet:', error) - toast.error('Failed to delete snippet') - } - }, []) - - const handleCopyCode = useCallback((code: string) => { - navigator.clipboard.writeText(code) - toast.success(strings.toast.codeCopied) - }, []) - - const handleViewSnippet = useCallback((snippet: Snippet) => { - setViewingSnippet(snippet) - setViewerOpen(true) - }, []) - - const handleMoveSnippet = useCallback(async () => { - if (!selectedNamespaceId) return - - try { - const loadedSnippets = await getSnippetsByNamespace(selectedNamespaceId) - setSnippets(loadedSnippets) - } catch (error) { - console.error('Failed to reload snippets:', error) - toast.error('Failed to reload snippets') - } - }, [selectedNamespaceId]) - - const handleCreateNew = useCallback(() => { - setEditingSnippet(null) - setDialogOpen(true) - }, []) - - const handleCreateFromTemplate = useCallback((templateId: string) => { - const template = templates.find((t) => t.id === templateId) - if (!template) return - - const templateSnippet = { - title: template.title, - description: template.description, - language: template.language, - code: template.code, - category: template.category, - hasPreview: template.hasPreview, - functionName: template.functionName, - } as Partial - - setEditingSnippet(templateSnippet as Snippet) - setDialogOpen(true) - }, []) - - const handleDialogClose = useCallback((open: boolean) => { - setDialogOpen(open) - if (!open) { - setEditingSnippet(null) - } - }, []) - - const handleToggleSelectionMode = useCallback(() => { - setSelectionMode(!selectionMode) - setSelectedSnippetIds(new Set()) - }, [selectionMode]) - - const handleToggleSnippetSelection = useCallback((snippetId: string) => { - setSelectedSnippetIds((prev) => { - const newSet = new Set(prev) - if (newSet.has(snippetId)) { - newSet.delete(snippetId) - } else { - newSet.add(snippetId) - } - return newSet - }) - }, []) - - const handleSelectAll = useCallback(() => { - if (selectedSnippetIds.size === filteredSnippets.length) { - setSelectedSnippetIds(new Set()) - } else { - setSelectedSnippetIds(new Set(filteredSnippets.map(s => s.id))) - } - }, [filteredSnippets, selectedSnippetIds.size]) - - const handleBulkMove = useCallback(async (targetNamespaceId: string) => { - if (selectedSnippetIds.size === 0) { - toast.error('No snippets selected') - return - } - - try { - await bulkMoveSnippets(Array.from(selectedSnippetIds), targetNamespaceId) - const targetNamespace = namespaces.find(n => n.id === targetNamespaceId) - toast.success(`Moved ${selectedSnippetIds.size} snippet${selectedSnippetIds.size > 1 ? 's' : ''} to ${targetNamespace?.name || 'namespace'}`) - - setSelectedSnippetIds(new Set()) - setSelectionMode(false) - - if (selectedNamespaceId) { - const loadedSnippets = await getSnippetsByNamespace(selectedNamespaceId) - setSnippets(loadedSnippets) - } - } catch (error) { - console.error('Failed to bulk move snippets:', error) - toast.error('Failed to move snippets') - } - }, [selectedSnippetIds, namespaces, selectedNamespaceId]) - - const allSnippets = snippets || [] - - if (loading) { - return ( -
-

Loading snippets...

-
- ) - } - - if (allSnippets.length === 0) { - return ( - <> -
- -
- - - - ) - } - - return ( -
- - -
-
- - setSearchQuery(e.target.value)} - className="pl-10" - /> -
-
- - - - - - - - - Blank Snippet - - - React Components - {templates.filter((t) => t.category === 'react').map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} - - JavaScript / TypeScript - {templates.filter((t) => ['api', 'basics', 'async', 'types'].includes(t.category)).map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} - - CSS Layouts - {templates.filter((t) => t.category === 'layout').map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} - - Python - Project Euler - {templates.filter((t) => t.category === 'euler').map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} - - Python - Algorithms - {templates.filter((t) => t.category === 'algorithms' && t.language === 'Python').map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} - - Python - Interactive Programs - {templates.filter((t) => t.category === 'interactive').map((template) => ( - handleCreateFromTemplate(template.id)} - > -
- {template.title} - - {template.description} - -
-
- ))} -
-
-
-
- - {selectionMode && ( -
-
- - - {selectedSnippetIds.size} of {filteredSnippets.length} selected - -
-
- - - - - - {namespaces - .filter(n => n.id !== selectedNamespaceId) - .map((namespace) => ( - handleBulkMove(namespace.id)} - > - {namespace.name} - {namespace.isDefault && ( - (Default) - )} - - ))} - - -
-
- )} - - {filteredSnippets.length === 0 ? ( -
-

{strings.noResults.title}

-

{strings.noResults.description}

-
- ) : ( -
- {filteredSnippets.map((snippet) => ( - - ))} -
- )} - - - - -
- ) -} +export { SnippetManagerRedux as SnippetManager } from './SnippetManagerRedux'