1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-10 00:46:15 +01:00
fab-manager/app/frontend/src/javascript/components/pricing/machines/pack-form.tsx

146 lines
4.5 KiB
TypeScript
Raw Normal View History

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 (
<form id={formId} onSubmit={handleSubmit} className="pack-form">
<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
};