diff --git a/src/components/SnippetCard.tsx b/src/components/SnippetCard.tsx index f86268e..fbf810c 100644 --- a/src/components/SnippetCard.tsx +++ b/src/components/SnippetCard.tsx @@ -1,200 +1,184 @@ -import { useState, useMemo } from 'react' -import { Card } from '@/components/ui/card' -import { Card } from '@/components/ui/card' -import { Badge } from '@/components/ui/badge' -import { cn } from '@/lib/utils' -interface SnippetCardProps { - onEdit: (snippet: Snippet) => - -} -export function Sn - const [hasRenderError, setHasRende - const safeSnippet = useMemo(() - const title = snippet?.tit - const code = snippet?.code || - - - description, - fullCode: code, - isTruncated, - - setHasRenderError(true) - t - code: '', - language: 'Other', - hasPreview: false, - } - - - setIsCopie - } - const handleEdit = - onEdit(snippet) - - e.stopPropaga - } - if (hasRenderError) { - < -

- } - return ( - className={cn( - - -
- - - - - - className="rel - - - e.prevent - }} - - - variant="ghost" - - aria-label="Delete snip - -
- - ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +import { useState, useMemo } from 'react' +import { Card } from '@/components/ui/card' +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { cn } from '@/lib/utils' +import { Snippet, LANGUAGE_COLORS } from '@/lib/types' +import { Copy, Pencil, Trash, Eye } from '@phosphor-icons/react' + +interface SnippetCardProps { + snippet: Snippet + onEdit: (snippet: Snippet) => void + onDelete: (id: string) => void + onCopy: (code: string) => void + onView: (snippet: Snippet) => void +} + +export function SnippetCard({ snippet, onEdit, onDelete, onCopy, onView }: SnippetCardProps) { + const [isCopied, setIsCopied] = useState(false) + const [hasRenderError, setHasRenderError] = useState(false) + + const safeSnippet = useMemo(() => { + try { + const title = snippet?.title || 'Untitled Snippet' + const code = snippet?.code || '' + const description = snippet?.description || '' + const maxCodeLength = 100 + const isTruncated = code.length > maxCodeLength + const displayCode = isTruncated ? code.slice(0, maxCodeLength) + '...' : code + + return { + title, + description, + displayCode, + fullCode: code, + isTruncated, + language: snippet?.language || 'Other', + hasPreview: snippet?.hasPreview || false + } + } catch { + setHasRenderError(true) + return { + title: 'Error Loading Snippet', + description: 'This snippet could not be loaded properly', + displayCode: '', + fullCode: '', + isTruncated: false, + language: 'Other', + hasPreview: false + } + } + }, [snippet]) + + const handleCopy = (e: React.MouseEvent) => { + e.stopPropagation() + onCopy(safeSnippet.fullCode) + setIsCopied(true) + setTimeout(() => setIsCopied(false), 2000) + } + + const handleEdit = (e: React.MouseEvent) => { + e.stopPropagation() + onEdit(snippet) + } + + const handleDelete = (e: React.MouseEvent) => { + e.stopPropagation() + onDelete(snippet.id) + } + + if (hasRenderError) { + return ( + +

Error Loading Snippet

+

+ This snippet could not be loaded properly +

+ +
+ ) + } + + return ( + +
+
+

+ {safeSnippet.title} +

+ {safeSnippet.description && ( +

+ {safeSnippet.description} +

+ )} +
+ +
+ + {safeSnippet.language} + + + {safeSnippet.isTruncated ? `${safeSnippet.fullCode.length} chars` : `${safeSnippet.fullCode.length} chars`} + +
+ +
{ + e.preventDefault() + onView(snippet) + }} + > + + {safeSnippet.displayCode} + + {safeSnippet.isTruncated && ( + + )} +
+ +
+ +
+ + +
+
+
+
+ ) +}