Initial commit with 2026 World Cup Quant Platform core modules and CI/CD
This commit is contained in:
72
platform/web/components/TransparentImage.tsx
Normal file
72
platform/web/components/TransparentImage.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Image, { ImageProps } from 'next/image';
|
||||
|
||||
interface TransparentImageProps extends Omit<ImageProps, 'src'> {
|
||||
src: string;
|
||||
alt: string;
|
||||
teamOrBrandName?: string;
|
||||
theme?: 'light' | 'dark'; // bg-stone-50 vs bg-stone-900
|
||||
}
|
||||
|
||||
/**
|
||||
* 字串過濾器 (String Formatter)
|
||||
* 確保專有名詞的大小寫與字元間距嚴格對齊
|
||||
*/
|
||||
export const formatBrandName = (name: string) => {
|
||||
return name.toUpperCase().replace(/\s+/g, ' ').trim();
|
||||
};
|
||||
|
||||
export default function TransparentImage({
|
||||
src,
|
||||
alt,
|
||||
teamOrBrandName,
|
||||
theme = 'dark',
|
||||
className = '',
|
||||
...props
|
||||
}: TransparentImageProps) {
|
||||
|
||||
const [isValidAlpha, setIsValidAlpha] = useState<boolean | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// 實務上這裡可以加上 Canvas 檢查,掃描圖片角落是否有典型的實體灰白棋盤格特徵
|
||||
// 或者只允許載入已經過後端白名單校驗的 CDN 圖片
|
||||
// 這裡我們假設 src 來自信任的 CDN 或本地 public
|
||||
setIsValidAlpha(true);
|
||||
}, [src]);
|
||||
|
||||
// 防呆機制:若檢測到無效透明度,顯示佔位符
|
||||
if (isValidAlpha === false) {
|
||||
return (
|
||||
<div className={`flex flex-col items-center justify-center border border-quant-red border-dashed rounded ${className} p-2`}>
|
||||
<span className="text-quant-red font-dotmatrix text-[10px] uppercase">Alpha Error</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Anti-aliasing 最佳化樣式
|
||||
const edgeSmoothing = theme === 'dark' ? 'mix-blend-plus-lighter' : 'mix-blend-multiply';
|
||||
|
||||
return (
|
||||
<div className={`flex flex-col items-center ${className}`}>
|
||||
<div className={`relative ${props.width ? `w-[${props.width}px]` : 'w-full'} ${props.height ? `h-[${props.height}px]` : 'h-full'}`}>
|
||||
<Image
|
||||
src={src}
|
||||
alt={alt}
|
||||
className={`object-contain ${edgeSmoothing}`}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
{teamOrBrandName && (
|
||||
<span className="mt-2 text-sm font-dotmatrix tracking-widest uppercase">
|
||||
{theme === 'dark' ? (
|
||||
<span className="text-stone-300">{formatBrandName(teamOrBrandName)}</span>
|
||||
) : (
|
||||
<span className="text-stone-800">{formatBrandName(teamOrBrandName)}</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user