import { __ } from '@wordpress/i18n'; import { useMemo, useState, useEffect } from 'react'; import { Card, CardHeader, CardBody, Flex, FlexItem, TextControl, } from '@wordpress/components'; import type { OrderItem, OrderUnits } from '../../types'; import { formatDisplayNumber, getDimensionBounds, getWeightBounds } from '../../shared/utils'; export interface PackagingValues { length?: string; width?: string; height?: string; weight?: string; } interface Props { items?: OrderItem[]; units?: OrderUnits; editableWeight?: boolean; value?: Partial; onChange?: (v: PackagingValues) => void; } const parseNum = (v: unknown): number => { if (typeof v === 'number') return v; if (typeof v === 'string' && v.trim() !== '') { const parsed = Number(v); return Number.isFinite(parsed) ? parsed : 0; } return 0; }; const Packaging = ({ items, units, editableWeight, value, onChange, }: Props) => { const dUnit = units?.dimension || ''; const wUnit = units?.weight || ''; const dimensionBounds = useMemo(() => getDimensionBounds(dUnit || 'cm'), [dUnit]); const weightBounds = useMemo(() => getWeightBounds(wUnit || 'kg'), [wUnit]); // Prefill: find first available L/W/H across items const defaults = useMemo(() => { let defaultLength: string = ''; let defaultWidth: string = ''; let defaultHeight: string = ''; if (Array.isArray(items)) { for (const item of items) { if (!defaultLength && item?.dimensions?.length != null) { defaultLength = formatDisplayNumber(parseNum(item.dimensions.length)); } if (!defaultWidth && item?.dimensions?.width != null) { defaultWidth = formatDisplayNumber(parseNum(item.dimensions.width)); } if (!defaultHeight && item?.dimensions?.height != null) { defaultHeight = formatDisplayNumber(parseNum(item.dimensions.height)); } if (defaultLength && defaultWidth && defaultHeight) break; } } return { defaultLength, defaultWidth, defaultHeight }; }, [items]); const autoWeight = useMemo(() => { if (!Array.isArray(items) || items.length === 0) return ''; let total = 0; for (const item of items) { const qty = typeof item?.quantity === 'number' ? item.quantity! : parseNum(item?.quantity); const itemWeight = parseNum(item?.dimensions?.weight); if (qty && itemWeight) total += qty * itemWeight; } return total > 0 ? formatDisplayNumber(total) : ''; }, [items]); const [length, setLength] = useState(value?.length ?? defaults.defaultLength); const [width, setWidth] = useState(value?.width ?? defaults.defaultWidth); const [height, setHeight] = useState(value?.height ?? defaults.defaultHeight); const [weight, setWeight] = useState( value?.weight ?? (autoWeight || '') ); useEffect(() => { setLength(defaults.defaultLength); setWidth(defaults.defaultWidth); setHeight(defaults.defaultHeight); }, [defaults.defaultLength, defaults.defaultWidth, defaults.defaultHeight]); useEffect(() => { if (!editableWeight) { setWeight(autoWeight || ''); } }, [autoWeight, editableWeight]); useEffect(() => { onChange?.({ length, width, height, weight: editableWeight ? weight : autoWeight || '', }); }, [length, width, height, weight, autoWeight, editableWeight, onChange]); return ( {__('Packaging', 'parcel2go-shipping')} setLength(v)} placeholder="" type="number" min={dimensionBounds.min} max={dimensionBounds.max} step={dimensionBounds.step} /> setWidth(v)} placeholder="" type="number" min={dimensionBounds.min} max={dimensionBounds.max} step={dimensionBounds.step} /> setHeight(v)} placeholder="" type="number" min={dimensionBounds.min} max={dimensionBounds.max} step={dimensionBounds.step} /> editableWeight ? setWeight(v) : undefined } disabled={!editableWeight} />
{editableWeight ? __('Editable', 'parcel2go-shipping') : __('Auto-calculated', 'parcel2go-shipping')}
); }; export default Packaging;