From 679f520873ad55df3a83e07130fd4ce2901f0702 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sat, 17 Jan 2026 15:15:54 +0000 Subject: [PATCH] Generated by Spark: A snippet card can render stuff - see if we can make it more robust --- src/components/SnippetCard.tsx | 137 ++++++++++++++++++++++++++++----- 1 file changed, 117 insertions(+), 20 deletions(-) diff --git a/src/components/SnippetCard.tsx b/src/components/SnippetCard.tsx index 1df6439..87ce7f5 100644 --- a/src/components/SnippetCard.tsx +++ b/src/components/SnippetCard.tsx @@ -1,8 +1,8 @@ -import { useState } from 'react' +import { useState, useMemo } from 'react' import { Card } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' -import { Copy, Pencil, Trash, Check, ArrowsOut, SplitVertical } from '@phosphor-icons/react' +import { Copy, Pencil, Trash, Check, ArrowsOut, SplitVertical, WarningCircle } from '@phosphor-icons/react' import { Snippet, LANGUAGE_COLORS } from '@/lib/types' import { cn } from '@/lib/utils' @@ -16,16 +16,101 @@ interface SnippetCardProps { export function SnippetCard({ snippet, onEdit, onDelete, onCopy, onView }: SnippetCardProps) { const [isCopied, setIsCopied] = useState(false) + const [hasRenderError, setHasRenderError] = useState(false) - const handleCopy = () => { + const handleCopy = (e: React.MouseEvent) => { + e.stopPropagation() onCopy(snippet.code) setIsCopied(true) setTimeout(() => setIsCopied(false), 2000) } - const truncatedCode = snippet.code.length > 200 - ? snippet.code.slice(0, 200) + '...' - : snippet.code + const handleEdit = (e: React.MouseEvent) => { + e.stopPropagation() + onEdit(snippet) + } + + const handleDelete = (e: React.MouseEvent) => { + e.stopPropagation() + onDelete(snippet.id) + } + + const safeSnippet = useMemo(() => { + try { + const title = snippet?.title ?? 'Untitled Snippet' + const description = snippet?.description ?? '' + const code = snippet?.code ?? '' + const language = snippet?.language ?? 'Other' + const updatedAt = snippet?.updatedAt ?? Date.now() + + const truncatedCode = code.length > 200 + ? code.slice(0, 200) + '...' + : code + + return { + title, + description, + code, + truncatedCode, + language, + updatedAt, + hasPreview: snippet?.hasPreview ?? false, + isTruncated: code.length > 200 + } + } catch (err) { + setHasRenderError(true) + return { + title: 'Error Loading Snippet', + description: 'This snippet contains invalid data', + code: '', + truncatedCode: '', + language: 'Other', + updatedAt: Date.now(), + hasPreview: false, + isTruncated: false + } + } + }, [snippet]) + + if (hasRenderError) { + return ( + +
+
+ +
+

+ {safeSnippet.title} +

+

+ Unable to render this snippet +

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

- {snippet.title} + {safeSnippet.title}

- {snippet.description && ( + {safeSnippet.description && (

- {snippet.description} + {safeSnippet.description}

)}
- {snippet.hasPreview && ( + {safeSnippet.hasPreview && ( - {snippet.language} + {safeSnippet.language}
@@ -71,18 +156,27 @@ export function SnippetCard({ snippet, onEdit, onDelete, onCopy, onView }: Snipp
onView(snippet)} + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + onView(snippet) + } + }} > -
-            {truncatedCode}
+          
+            {safeSnippet.truncatedCode}
           
- {snippet.code.length > 200 && ( -
+ {safeSnippet.isTruncated && ( +
)}