diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js index ac373fe..8341a6e 100644 --- a/app/components/QuoteBlock.js +++ b/app/components/QuoteBlock.js @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useState } from "react"; import Image from "next/image"; import QuoteDecor from "./QuoteDecor"; @@ -11,7 +11,13 @@ const QuoteBlock = ({ author = "Jo Freeman", source = "The Tyranny of Structurelessness", avatarSrc = "assets/Quote_Avatar.svg", + id, + fallbackAvatarSrc = "assets/Quote_Avatar.svg", // Fallback avatar + onError, // Error callback }) => { + const [imageError, setImageError] = useState(false); + const [imageLoading, setImageLoading] = useState(true); + // Variant configurations const variants = { compact: { @@ -63,8 +69,60 @@ const QuoteBlock = ({ const config = variants[variant] || variants.standard; + // Use provided ID or generate a stable one based on content + const baseId = id || `quote-${author.toLowerCase().replace(/\s+/g, "-")}`; + const quoteId = `${baseId}-content`; + const authorId = `${baseId}-author`; + + // Error handling functions + const handleImageError = (error) => { + console.warn( + `QuoteBlock: Failed to load avatar image for ${author}:`, + error + ); + setImageError(true); + setImageLoading(false); + + // Call error callback if provided + if (onError) { + onError({ + type: "image_load_error", + message: `Failed to load avatar for ${author}`, + author, + avatarSrc, + error, + }); + } + }; + + const handleImageLoad = () => { + setImageLoading(false); + setImageError(false); + }; + + // Validate required props + if (!quote || !author) { + console.error("QuoteBlock: Missing required props (quote or author)"); + if (onError) { + onError({ + type: "missing_props", + message: "QuoteBlock requires quote and author props", + quote: !!quote, + author: !!author, + }); + } + return null; // Don't render if missing required props + } + + // Determine which avatar to use + const currentAvatarSrc = imageError ? fallbackAvatarSrc : avatarSrc; + return ( -
+ {/* Avatar with error handling */} +++ ++ + {/* Loading state */} + {imageLoading && ( + + )} + + {/* Error state - show initials */} + {imageError && !imageLoading && ( + + + {author + .split(" ") + .map((n) => n[0]) + .join("") + .toUpperCase()} + ++ )} +@@ -94,21 +190,24 @@ const QuoteBlock = ({
+ {author} -
-- {source} -
-+ {source} +
+ )} +