Skip to content

Commit f849e73

Browse files
committed
fix: address AI review - abstract image fallback logic and prevent error loops
1 parent a9b3dfd commit f849e73

5 files changed

Lines changed: 36 additions & 27 deletions

File tree

components/bridge-form/bridge-form.component.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client'
22

33
import React, { useState } from 'react'
4-
import Image from 'next/image'
4+
import { FallbackImage } from '@/components/fallback-image'
55
import { erc20Abi } from 'viem'
66
import { useConnection, useReadContract } from 'wagmi'
77
import { FaArrowRight } from 'react-icons/fa6'
@@ -172,19 +172,15 @@ export const BridgeForm = ({ remainingDailyLimit }: MainComponentProps) => {
172172
<div className="hidden lg:flex flex-col">
173173
<div className="w-fit flex py-1 2xl:py-2 px-3 bg-gray-200 items-center rounded-3xl justify-center self-end">
174174
<div className="w-5 h-5 rounded-full overflow-hidden -ml-1 mr-2 relative">
175-
<Image
175+
<FallbackImage
176176
src={fromNetwork.icon}
177177
fill
178178
sizes="20px"
179179
alt={t('network_icon_alt', {
180180
network: fromNetwork.name,
181181
})}
182182
className="rounded-full object-cover"
183-
onError={(e) => {
184-
;(e.target as HTMLImageElement).srcset = ''
185-
;(e.target as HTMLImageElement).src =
186-
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"%3E%3Ccircle cx="10" cy="10" r="10" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="10" y="14" font-family="Arial" font-size="12" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
187-
}}
183+
fallbackSvg='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"%3E%3Ccircle cx="10" cy="10" r="10" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="10" y="14" font-family="Arial" font-size="12" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
188184
/>
189185
</div>
190186
<div className="font-bold text-[12.85px]">{fromToken}</div>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
3+
import React from 'react';
4+
import Image from 'next/image';
5+
import { ImageProps } from 'next/image';
6+
7+
interface FallbackImageProps extends ImageProps {
8+
fallbackSvg: string;
9+
}
10+
11+
export const FallbackImage: React.FC<FallbackImageProps> = ({ fallbackSvg, onError, ...props }) => {
12+
const handleImageError = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {
13+
e.currentTarget.onerror = null; // Prevent infinite loop
14+
e.currentTarget.srcset = '';
15+
e.currentTarget.src = fallbackSvg;
16+
onError?.(e); // Call original onError if provided
17+
};
18+
19+
return <Image {...props} onError={handleImageError} />;
20+
};
21+

components/fallback-image/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
export * from './fallback-image.component';
4+

components/modals/network-switch-modal/network-switch-modal.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import Image from 'next/image'
3+
import { FallbackImage } from '@/components/fallback-image'
44
import { useSwitchChain } from 'wagmi'
55
import { IoCloseOutline } from 'react-icons/io5'
66
import { NetworkSwitchModalProps } from './network-switch-modal.types'
@@ -42,17 +42,13 @@ export const NetworkSwitchModal = ({ closeModalAction, supportedChains }: Networ
4242
className="hover:bg-gray-200/80 hover:cursor-pointer p-4 font-medium w-full text-left flex items-center gap-3"
4343
>
4444
<div className="w-[36px] h-[36px] rounded-full overflow-hidden relative flex-shrink-0">
45-
<Image
45+
<FallbackImage
4646
src={chain.icon}
4747
fill
4848
sizes="36px"
4949
alt={`${chain.name} icon`}
5050
className="object-cover"
51-
onError={(e) => {
52-
;(e.target as HTMLImageElement).srcset = ''
53-
;(e.target as HTMLImageElement).src =
54-
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36"%3E%3Ccircle cx="18" cy="18" r="18" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="18" y="24" font-family="Arial" font-size="18" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
55-
}}
51+
fallbackSvg='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36"%3E%3Ccircle cx="18" cy="18" r="18" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="18" y="24" font-family="Arial" font-size="18" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
5652
/>
5753
</div>
5854
<div>

components/network-box/network-box.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import Image from 'next/image'
2+
import { FallbackImage } from '@/components/fallback-image'
33
import { IoIosArrowUp, IoIosArrowDown } from 'react-icons/io'
44

55
import { NetworkBoxProps } from './network-box.types'
@@ -25,17 +25,13 @@ export const NetworkBox = ({ type, selected, isOpen, networks, onToggle, onSelec
2525
<div className="relative">
2626
<div className="flex items-center gap-3 p-2 px-4 bg-white rounded-xl border border-gray-200 min-h-[90px] max-h-[90px]">
2727
<div className="w-[38px] h-[38px] relative rounded-full overflow-hidden ml-3">
28-
<Image
28+
<FallbackImage
2929
src={selected.icon}
3030
fill
3131
alt={selected.name}
3232
sizes="38px"
3333
className="object-cover rounded-full"
34-
onError={(e) => {
35-
;(e.target as HTMLImageElement).srcset = ''
36-
;(e.target as HTMLImageElement).src =
37-
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 38 38"%3E%3Ccircle cx="19" cy="19" r="19" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="19" y="25" font-family="Arial" font-size="20" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
38-
}}
34+
fallbackSvg='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 38 38"%3E%3Ccircle cx="19" cy="19" r="19" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="19" y="25" font-family="Arial" font-size="20" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
3935
/>
4036
</div>
4137
<div className="flex flex-col text-xs text-gray-500 font-medium">
@@ -58,17 +54,13 @@ export const NetworkBox = ({ type, selected, isOpen, networks, onToggle, onSelec
5854
onClick={() => onSelect(network)}
5955
>
6056
<div className="w-6 h-6 relative">
61-
<Image
57+
<FallbackImage
6258
src={network.icon}
6359
fill
6460
alt={network.name}
6561
sizes="24px"
6662
className="object-cover rounded-full"
67-
onError={(e) => {
68-
;(e.target as HTMLImageElement).srcset = ''
69-
;(e.target as HTMLImageElement).src =
70-
'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"%3E%3Ccircle cx="12" cy="12" r="12" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="12" y="16" font-family="Arial" font-size="14" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
71-
}}
63+
fallbackSvg='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"%3E%3Ccircle cx="12" cy="12" r="12" fill="%23ccc"%3E%3C/circle%3E%3Ctext x="12" y="16" font-family="Arial" font-size="14" fill="%23fff" text-anchor="middle"%3E%3F%3C/text%3E%3C/svg%3E'
7264
/>
7365
</div>
7466
<span className="text-sm font-medium text-gray-800">{network.name}</span>

0 commit comments

Comments
 (0)