From a27113c9e3ec23b062c506e364f100f13bfeb107 Mon Sep 17 00:00:00 2001 From: kastale Date: Fri, 6 Mar 2026 16:17:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(chart):=20=F0=9F=90=9B=20handle=20missing?= =?UTF-8?q?=20multi-chain=20chart=20preview=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_api/fetchCMS.ts | 24 +++++++++++++++++-- src/app/[chain]/chart/page.tsx | 23 ++++++++++++++++--- src/app/pageProvider.tsx | 42 +++++++++++++++++++++++++--------- 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/_api/fetchCMS.ts b/src/_api/fetchCMS.ts index 98ca239d..9ba262bf 100644 --- a/src/_api/fetchCMS.ts +++ b/src/_api/fetchCMS.ts @@ -1,7 +1,27 @@ import request from '@_api'; -export async function fetchCMS() { + +export interface ICMSChartImageGroup { + [chartKey: string]: string | undefined; +} + +export interface ICMSChartImageConfig { + [chainKey: string]: ICMSChartImageGroup | undefined; + multi?: ICMSChartImageGroup; + multiChain?: ICMSChartImageGroup; +} + +export interface IFetchCMSResult { + headerMenuList: any[]; + footerMenuList: any[]; + chainList: any[]; + networkList: any[]; + config: Record; + chartImg?: ICMSChartImageConfig; +} + +export async function fetchCMS(): Promise { const result = await request.cms.getGlobalConfig({ params: { cache: 'no-store' } }); - const { data } = result; + const { data } = result as { data: IFetchCMSResult }; return data; } diff --git a/src/app/[chain]/chart/page.tsx b/src/app/[chain]/chart/page.tsx index e79a8ca8..319abe0a 100644 --- a/src/app/[chain]/chart/page.tsx +++ b/src/app/[chain]/chart/page.tsx @@ -3,14 +3,30 @@ import { Anchor, Card } from 'antd'; import './index.css'; import Link from 'next/link'; +import { useEffect, useRef } from 'react'; import { useMobileContext } from '@app/pageProvider'; import PageAd from '@_components/PageAd'; import { ChartData, chartItems } from './type'; import { MULTI_CHAIN } from '@_utils/contant'; +const DEFAULT_CHART_IMAGE = '/image/chart.svg'; + export default function Page() { const { chartImg } = useMobileContext(); - const chainType = 'multi'; + const chainType = MULTI_CHAIN; + const chartImgGroup = chartImg?.[chainType] ?? chartImg?.multi; + const loggedMissingChartImgRef = useRef(false); + + useEffect(() => { + if (process.env.NODE_ENV === 'production') { + return; + } + + if (!chartImgGroup && !loggedMissingChartImgRef.current) { + console.warn('[chart] chartImg config is missing, using fallback chart preview image.'); + loggedMissingChartImgRef.current = true; + } + }, [chartImgGroup]); return (
@@ -30,6 +46,7 @@ export default function Page() {
{chartItem.title}
    {chartItem.charts.map((chart) => { + const chartPreviewSrc = chartImgGroup?.[chart.key] || DEFAULT_CHART_IMAGE; return (
  • @@ -39,8 +56,8 @@ export default function Page() { width={316} height={106} className="mx-auto block h-auto max-w-full" - src={chartImg[chainType][chart.key]} - alt="charts"> + src={chartPreviewSrc} + alt={chart.title}>
  • diff --git a/src/app/pageProvider.tsx b/src/app/pageProvider.tsx index 60c7a5c5..201c292c 100644 --- a/src/app/pageProvider.tsx +++ b/src/app/pageProvider.tsx @@ -10,21 +10,39 @@ import { PREFIXCLS, THEME_CONFIG } from '@_lib/AntdThemeConfig'; import { makeStore, AppStore } from '@_store'; +import type { ICMSChartImageConfig } from '@_api/fetchCMS'; // import { wrapper } from '@_store'; -import { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import { createContext, useContext, useRef } from 'react'; import { AELFDProvider } from 'aelf-design'; import 'aelf-design/css'; import { ConfigProvider } from 'antd'; import { Provider as ReduxProvider } from 'react-redux'; -import useResponsive from '@_hooks/useResponsive'; -import dynamic from 'next/dynamic'; import WebLoginProvider from './webLoginProvider'; // const OpentelemetryProvider = dynamic( // () => import('./opentelemetryProvider').then((mod) => mod.OpentelemetryProvider), // { ssr: false }, // ); -const MobileContext = createContext({}); +interface IMobileContextValue { + isMobileSSR: boolean; + config: Record; + chartImg?: ICMSChartImageConfig; +} + +interface IRootProviderProps { + children: React.ReactNode; + isMobileSSR: boolean; + config: Record; + chartImg?: ICMSChartImageConfig; + networkList: any[]; + headerMenuList: any[]; + chainList: any[]; +} + +const MobileContext = createContext({ + isMobileSSR: false, + config: {}, +}); const HeaderContext = createContext({}); const useMobileContext = () => { @@ -35,18 +53,20 @@ const useHeaderContext = () => { }; export { useMobileContext, useHeaderContext }; -function RootProvider({ children, isMobileSSR, config, chartImg, networkList, headerMenuList, chainList }) { +function RootProvider({ + children, + isMobileSSR, + config, + chartImg, + networkList, + headerMenuList, + chainList, +}: IRootProviderProps) { const storeRef = useRef(); if (!storeRef.current) { storeRef.current = makeStore(); } - const [isMobile, setIsMobile] = useState(isMobileSSR); - const { isMobile: isMobileClient } = useResponsive(); - useEffect(() => { - setIsMobile(isMobileClient); - }, [isMobileClient]); - return (