import { useRef, useState } from 'react'; import { STORE_PACKAGE_IMAGE_MAX_COUNT, STORE_PACKAGE_MAX_COUNT, } from '@dukang/shared-types'; import { emptyPackage, type PackageFormItem } from '../lib/storePackages'; import { uploadFileToOss } from '../lib/upload'; type Props = { items: PackageFormItem[]; onChange: (items: PackageFormItem[]) => void; disabled?: boolean; }; export default function ShopPackagesForm({ items, onChange, disabled }: Props) { const [collapsed, setCollapsed] = useState>({}); const [uploadingIndex, setUploadingIndex] = useState(null); const fileRefs = useRef>({}); async function pickPackageImages(pkgIndex: number, fileList?: FileList | null) { if (!fileList?.length || disabled) return; const current = items[pkgIndex]; const existing = Array.isArray(current.imageUrls) && current.imageUrls.length > 0 ? current.imageUrls.map((u) => String(u ?? '')).filter((u) => u.trim()) : current.imageUrl ? [String(current.imageUrl)] : []; const room = Math.max(0, STORE_PACKAGE_IMAGE_MAX_COUNT - existing.length); const files = Array.from(fileList).slice(0, room); if (!files.length) return; setUploadingIndex(pkgIndex); try { const appended: string[] = []; for (const file of files) { const result = await uploadFileToOss(file, 'STORE_PACKAGE'); appended.push(result.url); } const next = [...existing, ...appended]; updateAt(pkgIndex, { imageUrls: next, imageUrl: next[0] ?? '' }); } finally { setUploadingIndex(null); const input = fileRefs.current[pkgIndex]; if (input) input.value = ''; } } function updateAt(index: number, patch: Partial) { onChange(items.map((item, i) => (i === index ? { ...item, ...patch } : item))); } function addItem() { if (items.length >= STORE_PACKAGE_MAX_COUNT) return; onChange([...items, emptyPackage(items.length)]); } function removeAt(index: number) { onChange(items.filter((_, i) => i !== index).map((item, i) => ({ ...item, sortOrder: i }))); setCollapsed((prev) => { const next: Record = {}; Object.entries(prev).forEach(([k, v]) => { const i = Number(k); if (i < index) next[i] = v; else if (i > index) next[i - 1] = v; }); return next; }); } function toggleCollapse(index: number) { setCollapsed((prev) => ({ ...prev, [index]: !prev[index] })); } const list = items.length ? items : [emptyPackage(0)]; return (
{list.map((item, index) => { const isCollapsed = !!collapsed[index]; const displayName = item.name.trim() || `套餐 ${index + 1}`; const filled = Array.isArray(item.imageUrls) && item.imageUrls.length > 0 ? item.imageUrls.map((u) => String(u ?? '')).filter((u) => u.trim()) : item.imageUrl ? [String(item.imageUrl)] : []; return (
{!disabled && list.length > 1 ? ( ) : null}
{!isCollapsed ? ( <>