106 lines
3.9 KiB
TypeScript
106 lines
3.9 KiB
TypeScript
'use client'
|
||
|
||
import Image from 'next/image'
|
||
|
||
interface DisplayImageUploadProps {
|
||
displayImageUrl: string
|
||
isDisplayImageDragging: boolean
|
||
displayImageDropZoneRef: React.RefObject<HTMLDivElement>
|
||
disabled?: boolean
|
||
onDisplayImageChange: (e: React.ChangeEvent<HTMLInputElement>) => void
|
||
onDisplayImageDragEnter: (e: React.DragEvent) => void
|
||
onDisplayImageDragLeave: (e: React.DragEvent) => void
|
||
onDisplayImageDragOver: (e: React.DragEvent) => void
|
||
onDisplayImageDrop: (e: React.DragEvent) => void
|
||
materialType?: string // 素材类型,用于显示不同的提示文字
|
||
}
|
||
|
||
export default function DisplayImageUpload({
|
||
displayImageUrl,
|
||
isDisplayImageDragging,
|
||
displayImageDropZoneRef,
|
||
disabled = false,
|
||
onDisplayImageChange,
|
||
onDisplayImageDragEnter,
|
||
onDisplayImageDragLeave,
|
||
onDisplayImageDragOver,
|
||
onDisplayImageDrop,
|
||
materialType = '',
|
||
}: DisplayImageUploadProps) {
|
||
// 根据素材类型显示不同的标签和提示
|
||
const isBrandVI = materialType === '品牌VI灵感'
|
||
const labelText = isBrandVI ? '展示图片(可选)' : '详情页展示图片 *'
|
||
const hintText = isBrandVI
|
||
? '上传品牌VI的展示图片,用于详情页预览。如果不上传,将直接显示PDF预览。'
|
||
: '上传详情页/详情模板的展示图片,或拖拽图片到此区域'
|
||
|
||
return (
|
||
<div>
|
||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||
{labelText}
|
||
</label>
|
||
<div
|
||
ref={displayImageDropZoneRef}
|
||
aria-disabled={disabled}
|
||
className={`border-2 border-dashed rounded-apple p-4 transition-colors ${
|
||
disabled ? 'cursor-not-allowed opacity-60' : ''
|
||
} ${
|
||
isDisplayImageDragging
|
||
? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20'
|
||
: 'border-gray-300 dark:border-gray-600'
|
||
}`}
|
||
onDragEnter={onDisplayImageDragEnter}
|
||
onDragLeave={onDisplayImageDragLeave}
|
||
onDragOver={onDisplayImageDragOver}
|
||
onDrop={onDisplayImageDrop}
|
||
>
|
||
<div className="flex items-center space-x-4">
|
||
{displayImageUrl ? (
|
||
<div className="relative w-32 h-32 rounded-apple overflow-hidden border-2 border-gray-200 dark:border-gray-600">
|
||
<Image
|
||
src={displayImageUrl}
|
||
alt="Display"
|
||
fill
|
||
unoptimized
|
||
className="object-cover"
|
||
/>
|
||
</div>
|
||
) : (
|
||
<div className="w-32 h-32 rounded-apple bg-gray-100 dark:bg-gray-700 flex items-center justify-center">
|
||
<svg className="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||
</svg>
|
||
</div>
|
||
)}
|
||
<div className="flex-1">
|
||
<input
|
||
type="file"
|
||
onChange={onDisplayImageChange}
|
||
accept="image/*"
|
||
className="hidden"
|
||
id="displayImageInput"
|
||
disabled={disabled}
|
||
/>
|
||
<button
|
||
type="button"
|
||
onClick={() => document.getElementById('displayImageInput')?.click()}
|
||
className="btn-secondary"
|
||
disabled={disabled}
|
||
>
|
||
选择展示图片
|
||
</button>
|
||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-2">
|
||
{hintText}
|
||
</p>
|
||
{!isBrandVI && (
|
||
<p className="text-xs text-blue-600 dark:text-blue-400 mt-1">
|
||
💡 上传原图即可,系统会自动压缩和切片(高度超过1500px会自动切割)
|
||
</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|