mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-02 22:52:21 +01:00
130 lines
3.7 KiB
TypeScript
130 lines
3.7 KiB
TypeScript
|
import React, { useState, BaseSyntheticEvent } from 'react';
|
||
|
import { useTranslation } from 'react-i18next';
|
||
|
import Select from 'react-select';
|
||
|
import { FabModal } from '../base/fab-modal';
|
||
|
import OrderAPI from '../../api/order';
|
||
|
import { Order } from '../../models/order';
|
||
|
|
||
|
interface OrderActionsProps {
|
||
|
order: Order,
|
||
|
onSuccess: (order: Order, message: string) => void,
|
||
|
onError: (message: string) => void,
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Option format, expected by react-select
|
||
|
* @see https://github.com/JedWatson/react-select
|
||
|
*/
|
||
|
type selectOption = { value: string, label: string };
|
||
|
|
||
|
/**
|
||
|
* Actions for an order
|
||
|
*/
|
||
|
export const OrderActions: React.FC<OrderActionsProps> = ({ order, onSuccess, onError }) => {
|
||
|
const { t } = useTranslation('shared');
|
||
|
const [currentAction, setCurrentAction] = useState<selectOption>();
|
||
|
const [modalIsOpen, setModalIsOpen] = useState<boolean>(false);
|
||
|
const [readyNote, setReadyNote] = useState<string>('');
|
||
|
|
||
|
// Styles the React-select component
|
||
|
const customStyles = {
|
||
|
control: base => ({
|
||
|
...base,
|
||
|
width: '20ch',
|
||
|
backgroundColor: 'transparent'
|
||
|
}),
|
||
|
indicatorSeparator: () => ({
|
||
|
display: 'none'
|
||
|
})
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Close the action confirmation modal
|
||
|
*/
|
||
|
const closeModal = (): void => {
|
||
|
setModalIsOpen(false);
|
||
|
setCurrentAction(null);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Creates sorting options to the react-select format
|
||
|
*/
|
||
|
const buildOptions = (): Array<selectOption> => {
|
||
|
let actions = [];
|
||
|
switch (order.state) {
|
||
|
case 'paid':
|
||
|
actions = actions.concat(['in_progress', 'ready', 'canceled', 'refunded']);
|
||
|
break;
|
||
|
case 'payment_failed':
|
||
|
actions = actions.concat(['canceled']);
|
||
|
break;
|
||
|
case 'in_progress':
|
||
|
actions = actions.concat(['ready', 'canceled', 'refunded']);
|
||
|
break;
|
||
|
case 'ready':
|
||
|
actions = actions.concat(['canceled', 'refunded']);
|
||
|
break;
|
||
|
case 'canceled':
|
||
|
actions = actions.concat(['refunded']);
|
||
|
break;
|
||
|
default:
|
||
|
actions = [];
|
||
|
}
|
||
|
return actions.map(action => {
|
||
|
return { value: action, label: t(`app.shared.store.order_actions.state.${action}`) };
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Callback after selecting an action
|
||
|
*/
|
||
|
const handleAction = (action: selectOption) => {
|
||
|
setCurrentAction(action);
|
||
|
setModalIsOpen(true);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Callback after confirm an action
|
||
|
*/
|
||
|
const handleActionConfirmation = () => {
|
||
|
OrderAPI.updateState(order, currentAction.value, readyNote).then(data => {
|
||
|
onSuccess(data, t(`app.shared.store.order_actions.order_${currentAction.value}_success`));
|
||
|
setCurrentAction(null);
|
||
|
setModalIsOpen(false);
|
||
|
}).catch((e) => {
|
||
|
onError(e);
|
||
|
setCurrentAction(null);
|
||
|
setModalIsOpen(false);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<Select
|
||
|
options={buildOptions()}
|
||
|
onChange={option => handleAction(option)}
|
||
|
value={currentAction}
|
||
|
styles={customStyles}
|
||
|
/>
|
||
|
<FabModal title={t('app.shared.store.order_actions.confirmation_required')}
|
||
|
isOpen={modalIsOpen}
|
||
|
toggleModal={closeModal}
|
||
|
closeButton={true}
|
||
|
confirmButton={t('app.shared.store.order_actions.confirm')}
|
||
|
onConfirm={handleActionConfirmation}
|
||
|
className="order-actions-confirmation-modal">
|
||
|
<p>{t(`app.shared.store.order_actions.confirm_order_${currentAction?.value}`)}</p>
|
||
|
{currentAction?.value === 'ready' &&
|
||
|
<textarea
|
||
|
id="order-ready-note"
|
||
|
value={readyNote}
|
||
|
placeholder={t('app.shared.store.order_actions.order_ready_note')}
|
||
|
onChange={(e: BaseSyntheticEvent) => setReadyNote(e.target.value)}
|
||
|
style={{ width: '100%' }}
|
||
|
rows={5} />
|
||
|
}
|
||
|
</FabModal>
|
||
|
</>
|
||
|
);
|
||
|
};
|