diff --git a/app/components/sections/streaming/streaming.tsx b/app/components/sections/streaming/streaming.tsx index 97a8f91..1e8491f 100644 --- a/app/components/sections/streaming/streaming.tsx +++ b/app/components/sections/streaming/streaming.tsx @@ -1,8 +1,8 @@ import type { Route } from ".react-router/types/app/routes/+types/streaming"; import MuxPlayer from "@mux/mux-player-react"; import { BadgeCheck } from "lucide-react"; -import { useState } from "react"; -import { cn } from "~/lib/utils"; +import { useEffect, useState } from "react"; +import { cn, parseSpeakerImage } from "~/lib/utils"; export const StreamingSection = ({ componentProps, @@ -11,6 +11,9 @@ export const StreamingSection = ({ }) => { const [talkExpansion, setTalkExpansion] = useState(true); const [speakerBioExpansion, setSpeakerBioExpansion] = useState(true); + const [speakerImageSrc, setSpeakerImageSrc] = useState( + "/images/default-avatar.webp", + ); const scheduleDetail = componentProps.loaderData.scheduleDetail; const scheduleStream = componentProps.loaderData.scheduleStream; @@ -25,9 +28,26 @@ export const StreamingSection = ({ scheduleDetail.speaker?.user.facebook_username || scheduleDetail.speaker?.user.email; - console.log("Instagram ", scheduleDetail.speaker?.user.instagram_username); - console.log("Facebook ", scheduleDetail.speaker?.user.facebook_username); - console.log("Email ", scheduleDetail.speaker?.user.email); + const first_name = scheduleDetail.speaker?.user.first_name; + const last_name = scheduleDetail.speaker?.user.last_name; + + useEffect(() => { + if (scheduleDetail.speaker?.id) { + const imageUrl = parseSpeakerImage({ id: scheduleDetail.speaker.id }); + const img = new Image(); + + img.onload = () => { + setSpeakerImageSrc(imageUrl); + }; + + img.onerror = () => { + console.log("Failed to load speaker image, using default avatar"); + setSpeakerImageSrc("/images/default-avatar.webp"); + }; + + img.src = imageUrl; + } + }, [scheduleDetail.speaker?.id]); return (
@@ -46,7 +66,7 @@ export const StreamingSection = ({ />
-

+

{scheduleDetail.title}

@@ -58,16 +78,18 @@ export const StreamingSection = ({ {scheduleDetail.speaker?.user ? (

placeholder + />
-

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

-
- -
+

+ {`${first_name} ${last_name}`}{" "} + + + +

{scheduleDetail.speaker?.user.job_title && (

@@ -86,16 +108,16 @@ export const StreamingSection = ({

-

+

{scheduleDetail.title}

{scheduleDetail.description ? (

100 && talkExpansion - ? "line-clamp-3" + ? "line-clamp-2" : "", )} > @@ -113,13 +135,13 @@ export const StreamingSection = ({ ? "...show more" : "show less..."} -

- {talkExpansion && scheduleDetail.slide_link ? ( +

+ {!talkExpansion && scheduleDetail.slide_link ? ( - Access Presentation File + Access presentation file ) : null}

@@ -130,14 +152,14 @@ export const StreamingSection = ({
{scheduleDetail.speaker?.user ? ( -
+
placeholder + />
-

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

+

{`${scheduleDetail.speaker?.user.first_name} ${scheduleDetail.speaker?.user.last_name}`}

{scheduleDetail.speaker?.user.job_title ? (

{scheduleDetail.speaker?.user.job_title} at{" "} @@ -147,13 +169,15 @@ export const StreamingSection = ({ {speakerBio ? (

-

Bio

+

+ Bio +

100 && speakerBioExpansion - ? "line-clamp-3" + ? "line-clamp-2" : "", )} > diff --git a/app/lib/utils.ts b/app/lib/utils.ts index 1416b71..dfd7162 100644 --- a/app/lib/utils.ts +++ b/app/lib/utils.ts @@ -35,7 +35,12 @@ export const onAvatarError = ( evt: React.SyntheticEvent, ) => { const element = evt.target as HTMLImageElement; - element.onerror = () => null; + console.log("🔴 Image load failed:", element.src); + console.log("🔄 Setting fallback to:", "/images/default-avatar.webp"); + element.onerror = () => { + console.log("❌ Fallback image ALSO failed to load!"); + return null; + }; element.src = "/images/default-avatar.webp"; element.srcset = "/images/default-avatar.webp"; };