import React, { FC, useEffect, useState } from 'react' import { __experimentalHeading as Heading, Button, SelectControl, TextareaControl, } from '@wordpress/components' import { Notice } from '@wordpress/ui' import { useAnnounce } from './useAnnounce' import { useI18n } from '@wordpress/react-i18n' import apiFetch from '@wordpress/api-fetch' type ReturnAction = { action: string label: string } type ReturnBooking = { consignmentNumber: string labelUrl: string trackingUrl: string } type OrderReturn = { id: string state: string statusLabel: string statusHint: string byStore: boolean lines: Array note: string booking: ReturnBooking | null actions: Array } type ReturnableItem = { itemId: number name: string quantity: number } export type OrderReturnsData = { enabled: boolean returns: Array returnable: Array reasons: Record } const errorMessage = (e: unknown, fallback: string) => typeof e === 'string' ? e : fallback const OrderReturns: FC<{ orderId: string }> = ({ orderId }) => { const { __ } = useI18n() const [data, setData] = useState() const [loadFailed, setLoadFailed] = useState(false) const [busy, setBusy] = useState() const [error, setError] = useState() const [booking, setBooking] = useState(false) const [quantities, setQuantities] = useState>({}) const [reasons, setReasons] = useState>({}) const [note, setNote] = useState('') const path = `/posten-bring-checkout/orders/${orderId}/returns` const load = () => { setLoadFailed(false) apiFetch({ path }) .then(setData) .catch(() => setLoadFailed(true)) } useEffect(load, [path]) const run = async (key: string, request: Promise) => { setBusy(key) setError(undefined) try { setData(await request) return true } catch (e) { setError( errorMessage( e, __( 'Something went wrong. Please try again.', 'posten-bring-checkout' ) ) ) return false } finally { setBusy(undefined) } } const handle = (returnId: string, action: string) => { if ( action === 'cancel' && !window.confirm( __( 'Only cancel the return if the customer is not sending the items. They can then return them again.', 'posten-bring-checkout' ) ) ) { return } run( `${returnId}:${action}`, apiFetch({ path: `${path}/${returnId}`, method: 'POST', data: { action }, }) ) } const bookReturn = async () => { const items = Object.fromEntries( Object.entries(quantities).filter(([, quantity]) => quantity > 0) ) const booked = await run( 'book', apiFetch({ path, method: 'POST', data: { items, reasons, note }, }) ) if (booked) { setBooking(false) setQuantities({}) setReasons({}) setNote('') } } const loadError = __( 'Could not load the returns for this order.', 'posten-bring-checkout' ) useAnnounce( (data?.enabled || (data?.returns.length ?? 0) > 0) && error, 'assertive' ) useAnnounce(loadFailed && loadError, 'assertive') if (loadFailed) { return (
{__('Returns', 'posten-bring-checkout')} {loadError}
) } if (!data || (!data.enabled && data.returns.length === 0)) { return null } const selected = Object.values(quantities).some(quantity => quantity > 0) return (
{__('Returns', 'posten-bring-checkout')} {!booking && data.returnable.length > 0 && ( )}
{data.returns.length === 0 && !booking && (

{__('No returns for this order.', 'posten-bring-checkout')}

)} {data.returns.map(orderReturn => (
{orderReturn.statusLabel} {orderReturn.id}
{orderReturn.statusHint && (

{orderReturn.statusHint}

)}
    {orderReturn.lines.map(line => (
  • {line}
  • ))}
{orderReturn.byStore && (

{__('Booked by the store', 'posten-bring-checkout')}

)} {orderReturn.note && (

{orderReturn.note}

)} {orderReturn.booking && (

{orderReturn.booking.consignmentNumber} {' ยท '} {__('Label', 'posten-bring-checkout')}

)} {orderReturn.actions.length > 0 && (
{orderReturn.actions.map((action, index) => ( ))}
)}
))} {booking && (

{__( 'Choose what the customer is sending back. Bring emails them a return code and a QR code for handing it in.', 'posten-bring-checkout' )}

{data.returnable.map(item => (
{item.name} ({ label: String(quantity), value: String(quantity), }) )} onChange={(value: string) => setQuantities({ ...quantities, [item.itemId]: parseInt(value, 10), }) } /> ({ label, value, })), ]} onChange={(value: string) => setReasons({ ...reasons, [item.itemId]: value }) } />
))}
)} {error && ( {error} )}
) } export default OrderReturns