2021-06-23 17:00:15 +02:00
|
|
|
import React, { BaseSyntheticEvent } from 'react';
|
|
|
|
import Select from 'react-select';
|
2021-06-24 17:59:05 +02:00
|
|
|
import Switch from 'react-switch';
|
2021-12-21 20:13:55 +01:00
|
|
|
import { PrepaidPack } from '../../../models/prepaid-pack';
|
2021-06-23 17:00:15 +02:00
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { useImmer } from 'use-immer';
|
2021-12-21 20:13:55 +01:00
|
|
|
import { FabInput } from '../../base/fab-input';
|
|
|
|
import { IFablab } from '../../../models/fablab';
|
2021-06-23 17:00:15 +02:00
|
|
|
|
2021-07-01 12:34:10 +02:00
|
|
|
declare let Fablab: IFablab;
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
interface PackFormProps {
|
|
|
|
formId: string,
|
|
|
|
onSubmit: (pack: PrepaidPack) => void,
|
2021-06-25 09:56:39 +02:00
|
|
|
pack?: PrepaidPack,
|
2021-06-23 17:00:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const ALL_INTERVALS = ['day', 'week', 'month', 'year'] as const;
|
|
|
|
type interval = typeof ALL_INTERVALS[number];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Option format, expected by react-select
|
|
|
|
* @see https://github.com/JedWatson/react-select
|
|
|
|
*/
|
|
|
|
type selectOption = { value: interval, label: string };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A form component to create/edit a PrepaidPack.
|
|
|
|
* The form validation must be created elsewhere, using the attribute form={formId}.
|
|
|
|
*/
|
2021-06-25 09:56:39 +02:00
|
|
|
export const PackForm: React.FC<PackFormProps> = ({ formId, onSubmit, pack }) => {
|
|
|
|
const [packData, updatePackData] = useImmer<PrepaidPack>(pack || {} as PrepaidPack);
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
const { t } = useTranslation('admin');
|
|
|
|
|
|
|
|
/**
|
2021-06-25 09:56:39 +02:00
|
|
|
* Convert all validity-intervals to the react-select format
|
2021-06-23 17:00:15 +02:00
|
|
|
*/
|
|
|
|
const buildOptions = (): Array<selectOption> => {
|
2021-06-25 09:56:39 +02:00
|
|
|
return ALL_INTERVALS.map(i => intervalToOption(i));
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-25 09:56:39 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert the given validity-interval to the react-select format
|
|
|
|
*/
|
|
|
|
const intervalToOption = (value: interval): selectOption => {
|
|
|
|
if (!value) return { value, label: '' };
|
|
|
|
|
|
|
|
return { value, label: t(`app.admin.pack_form.intervals.${value}`, { COUNT: packData.validity_count || 0 }) };
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user sends the form.
|
|
|
|
*/
|
|
|
|
const handleSubmit = (event: BaseSyntheticEvent): void => {
|
|
|
|
event.preventDefault();
|
2021-06-25 09:56:39 +02:00
|
|
|
onSubmit(packData);
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user inputs an amount for the current pack.
|
|
|
|
*/
|
|
|
|
const handleUpdateAmount = (amount: string) => {
|
2021-06-25 09:56:39 +02:00
|
|
|
updatePackData(draft => {
|
2021-06-23 17:00:15 +02:00
|
|
|
draft.amount = parseFloat(amount);
|
|
|
|
});
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user inputs a number of hours for the current pack.
|
|
|
|
*/
|
|
|
|
const handleUpdateHours = (hours: string) => {
|
2021-06-25 09:56:39 +02:00
|
|
|
updatePackData(draft => {
|
2021-06-23 17:00:15 +02:00
|
|
|
draft.minutes = parseInt(hours, 10) * 60;
|
|
|
|
});
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user inputs a number of periods for the current pack.
|
|
|
|
*/
|
|
|
|
const handleUpdateValidityCount = (count: string) => {
|
2021-06-25 09:56:39 +02:00
|
|
|
updatePackData(draft => {
|
2021-06-23 17:00:15 +02:00
|
|
|
draft.validity_count = parseInt(count, 10);
|
|
|
|
});
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user selects a type of interval for the current pack.
|
|
|
|
*/
|
|
|
|
const handleUpdateValidityInterval = (option: selectOption) => {
|
2021-06-25 09:56:39 +02:00
|
|
|
updatePackData(draft => {
|
2021-06-23 17:00:15 +02:00
|
|
|
draft.validity_interval = option.value as interval;
|
|
|
|
});
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-23 17:00:15 +02:00
|
|
|
|
2021-06-24 17:59:05 +02:00
|
|
|
/**
|
|
|
|
* Callback triggered when the user disables the pack.
|
|
|
|
*/
|
|
|
|
const handleUpdateDisabled = (checked: boolean) => {
|
2021-06-25 09:56:39 +02:00
|
|
|
updatePackData(draft => {
|
2021-06-24 17:59:05 +02:00
|
|
|
draft.disabled = checked;
|
2021-07-01 12:34:10 +02:00
|
|
|
});
|
|
|
|
};
|
2021-06-24 17:59:05 +02:00
|
|
|
|
2021-06-23 17:00:15 +02:00
|
|
|
return (
|
2021-12-22 17:25:02 +01:00
|
|
|
<form id={formId} onSubmit={handleSubmit} className="group-form">
|
2021-06-23 17:00:15 +02:00
|
|
|
<label htmlFor="hours">{t('app.admin.pack_form.hours')} *</label>
|
|
|
|
<FabInput id="hours"
|
2021-07-01 12:34:10 +02:00
|
|
|
type="number"
|
|
|
|
defaultValue={packData?.minutes / 60 || ''}
|
|
|
|
onChange={handleUpdateHours}
|
|
|
|
min={1}
|
|
|
|
icon={<i className="fas fa-clock" />}
|
|
|
|
required />
|
2021-06-23 17:00:15 +02:00
|
|
|
<label htmlFor="amount">{t('app.admin.pack_form.amount')} *</label>
|
|
|
|
<FabInput id="amount"
|
2021-07-01 12:34:10 +02:00
|
|
|
type="number"
|
|
|
|
step={0.01}
|
|
|
|
min={0}
|
|
|
|
defaultValue={packData?.amount || ''}
|
|
|
|
onChange={handleUpdateAmount}
|
|
|
|
icon={<i className="fas fa-money-bill" />}
|
|
|
|
addOn={Fablab.intl_currency}
|
|
|
|
required />
|
2021-06-23 17:00:15 +02:00
|
|
|
<label htmlFor="validity_count">{t('app.admin.pack_form.validity_count')}</label>
|
|
|
|
<div className="interval-inputs">
|
|
|
|
<FabInput id="validity_count"
|
2021-07-01 12:34:10 +02:00
|
|
|
type="number"
|
|
|
|
min={0}
|
|
|
|
defaultValue={packData?.validity_count || ''}
|
|
|
|
onChange={handleUpdateValidityCount}
|
|
|
|
icon={<i className="fas fa-calendar-week" />} />
|
2021-06-23 17:00:15 +02:00
|
|
|
<Select placeholder={t('app.admin.pack_form.select_interval')}
|
2021-07-01 12:34:10 +02:00
|
|
|
className="select-interval"
|
|
|
|
defaultValue={intervalToOption(packData?.validity_interval)}
|
|
|
|
onChange={handleUpdateValidityInterval}
|
|
|
|
options={buildOptions()} />
|
2021-06-23 17:00:15 +02:00
|
|
|
</div>
|
2021-06-24 17:59:05 +02:00
|
|
|
<label htmlFor="disabled">{t('app.admin.pack_form.disabled')}</label>
|
|
|
|
<div>
|
2021-06-25 09:56:39 +02:00
|
|
|
<Switch checked={packData?.disabled || false} onChange={handleUpdateDisabled} id="disabled" />
|
2021-06-24 17:59:05 +02:00
|
|
|
</div>
|
2021-06-23 17:00:15 +02:00
|
|
|
</form>
|
|
|
|
);
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|