gongxiangp2/components/upload/ModelImagesUpload.tsx

60 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useRef } from 'react'
import Image from 'next/image'
import { Plus } from 'lucide-react'
import { dropZoneIdleClass, fieldHintClass, fieldLabelClass, uploadAreaAddTileClass, uploadAreaEmptyButtonClass, uploadAreaTileClass } from './upload-field-styles'
interface ModelImagesUploadProps {
modelImageUrls: string[]
onModelImagesChange: (e: React.ChangeEvent<HTMLInputElement>) => void
onRemoveModelImage: (index: number) => void
disabled?: boolean
}
export default function ModelImagesUpload({
modelImageUrls,
onModelImagesChange,
onRemoveModelImage,
disabled = false,
}: ModelImagesUploadProps) {
const inputRef = useRef<HTMLInputElement>(null)
return (
<div>
<label className={fieldLabelClass}>模特展示图片 *(可上传多张)</label>
<div className={`p-3 ${dropZoneIdleClass} ${disabled ? 'cursor-not-allowed opacity-60' : ''}`}>
<input ref={inputRef} type="file" accept="image/*" multiple onChange={onModelImagesChange} className="hidden" disabled={disabled} />
<div className={modelImageUrls.length > 0 ? 'flex flex-wrap gap-2' : ''}>
{modelImageUrls.map((url, index) => (
<div key={index} className="group relative">
<div className={uploadAreaTileClass}>
<Image src={url} alt={`模特图 ${index + 1}`} fill unoptimized className="object-cover" />
{index === 0 && <span className="absolute inset-x-0 bottom-0 bg-[#1a1c1d]/80 py-0.5 text-center text-xs text-white">主图</span>}
</div>
<button
type="button"
onClick={() => onRemoveModelImage(index)}
disabled={disabled}
aria-label={`移除模特图 ${index + 1}`}
className="absolute right-1 top-1 flex h-7 w-7 items-center justify-center rounded-[6px] bg-[#1a1c1d]/80 text-white opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1677ff]"
>×</button>
</div>
))}
<button
type="button"
onClick={() => inputRef.current?.click()}
disabled={disabled}
aria-label="添加模特图片"
className={modelImageUrls.length > 0 ? uploadAreaAddTileClass : uploadAreaEmptyButtonClass}
>
<Plus className="h-5 w-5" aria-hidden="true" />
{modelImageUrls.length === 0 && '添加模特图片'}
</button>
</div>
</div>
<p className={`mt-1.5 ${fieldHintClass}`}>可一次选择多张 · 首张为预览图,高图会自动切片</p>
</div>
)
}