From 7edec2bd696d70bcdf2530d89c414e528fbe8a82 Mon Sep 17 00:00:00 2001 From: vincent Date: Thu, 12 Jan 2023 16:02:27 +0100 Subject: [PATCH] (ui) Training form --- .../accounting/advanced-accounting-form.tsx | 2 +- .../components/trainings/training-form.tsx | 208 ++++++++++++++---- .../trainings/trainings-settings.tsx | 5 +- .../components/trainings/trainings.tsx | 129 +++++++++++ app/frontend/src/stylesheets/application.scss | 1 + .../accounting/accounting-codes-settings.scss | 4 + .../stylesheets/modules/base/fab-panel.scss | 7 +- .../stylesheets/modules/base/fab-tooltip.scss | 5 +- .../modules/form/abstract-form-item.scss | 7 +- .../stylesheets/modules/form/form-switch.scss | 4 - .../stylesheets/modules/store/_utilities.scss | 15 -- .../modules/trainings/training-form.scss | 23 +- .../modules/trainings/trainings-settings.scss | 4 +- .../modules/trainings/trainings.scss | 127 +++++++++++ .../src/stylesheets/variables/decoration.scss | 16 ++ .../templates/admin/trainings/edit.html | 17 +- .../templates/admin/trainings/index.html | 4 +- .../templates/admin/trainings/new.html | 29 +-- config/locales/app.admin.en.yml | 26 ++- 19 files changed, 519 insertions(+), 114 deletions(-) create mode 100644 app/frontend/src/javascript/components/trainings/trainings.tsx create mode 100644 app/frontend/src/stylesheets/modules/trainings/trainings.scss diff --git a/app/frontend/src/javascript/components/accounting/advanced-accounting-form.tsx b/app/frontend/src/javascript/components/accounting/advanced-accounting-form.tsx index a1202b6d3..0d5e9a993 100644 --- a/app/frontend/src/javascript/components/accounting/advanced-accounting-form.tsx +++ b/app/frontend/src/javascript/components/accounting/advanced-accounting-form.tsx @@ -26,7 +26,7 @@ export const AdvancedAccountingForm = ({ regis return (
{isEnabled &&
-

{t('app.admin.advanced_accounting_form.title')}

+

{t('app.admin.advanced_accounting_form.title')}

diff --git a/app/frontend/src/javascript/components/trainings/training-form.tsx b/app/frontend/src/javascript/components/trainings/training-form.tsx index 94eb68b8a..546ad3535 100644 --- a/app/frontend/src/javascript/components/trainings/training-form.tsx +++ b/app/frontend/src/javascript/components/trainings/training-form.tsx @@ -20,6 +20,7 @@ import { SelectOption } from '../../models/select'; import SettingAPI from '../../api/setting'; import { Setting } from '../../models/setting'; import { AdvancedAccountingForm } from '../accounting/advanced-accounting-form'; +import { FabPanel } from '../base/fab-panel'; declare const Application: IApplication; @@ -34,13 +35,19 @@ interface TrainingFormProps { * Form to edit or create trainings */ export const TrainingForm: React.FC = ({ action, training, onError, onSuccess }) => { + const { t } = useTranslation('admin'); + const [machineModule, setMachineModule] = useState(null); + const [isActiveCancellation, setIsActiveCancellation] = useState(false); + const [isActiveTextBlock, setIsActiveTextBlock] = useState(false); + const [isActiveCta, setIsActiveCta] = useState(false); + const [isActiveAccounting, setIsActiveAccounting] = useState(false); const { handleSubmit, register, control, setValue, formState } = useForm({ defaultValues: { ...training } }); const output = useWatch({ control }); - const { t } = useTranslation('admin'); useEffect(() => { SettingAPI.get('machines_module').then(setMachineModule).catch(onError); + SettingAPI.get('advanced_accounting').then(res => setIsActiveAccounting(res.value === 'true')).catch(onError); }, []); /** @@ -71,50 +78,175 @@ export const TrainingForm: React.FC = ({ action, training, on }).catch(error => onError(error)); }; + /** + * Callback triggered when the auto cancellation switch has changed. + */ + const toggleCancellationSwitch = (value: boolean) => { + setIsActiveCancellation(value); + }; + + /** + * Callback triggered when the text block switch has changed. + */ + const toggleTextBlockSwitch = (value: boolean) => { + setIsActiveTextBlock(value); + }; + + /** + * Callback triggered when the CTA switch has changed. + */ + const toggleTextBlockCta = (value: boolean) => { + setIsActiveCta(value); + }; + + /** + * Callback triggered when the CTA label has changed. + */ + const handleCtaLabelChange = (event: React.ChangeEvent): void => { + console.log('cta label:', event.target.value); + }; + /** + * Callback triggered when the cta url has changed. + */ + const handleCtaUrlChange = (event: React.ChangeEvent): void => { + console.log('cta url:', event.target.value); + }; + + // regular expression to validate the input fields + const urlRegex = /^(https?:\/\/)([^.]+)\.(.{2,30})(\/.*)*\/?$/; + return (
- - - - {machineModule?.value === 'true' && } - +

{t('app.admin.training_form.description')}

+ + + + + + +

{t('app.admin.training_form.settings')}

+ {machineModule?.value === 'true' && + } + - - - - + + +
+ + +

+ {t('app.admin.training_form.automatic_cancellation')} +

+ +
{t('app.admin.training_form.automatic_cancellation_info')}
+
+

+ + + {isActiveCancellation && <> + + + } +
+ + +

+ {t('app.admin.training_form.generic_text_block')} +

+ +
{t('app.admin.training_form.generic_text_block_info')}
+
+

+ + + + + + {isActiveTextBlock && <> + + + {isActiveCta && <> + + + } + } +
+ + {isActiveAccounting && + + + + } + + {t('app.admin.training_form.ACTION_training', { ACTION: action })} diff --git a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx index cdc0f7e18..6d3aef275 100644 --- a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx +++ b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx @@ -79,7 +79,7 @@ export const TrainingsSettings: React.FC = () => {

{t('app.admin.trainings_settings.title')}

-
+

{t('app.admin.trainings_settings.automatic_cancellation')}

{t('app.admin.trainings_settings.automatic_cancellation_info')} @@ -108,7 +108,7 @@ export const TrainingsSettings: React.FC = () => { }
-
+

{t('app.admin.trainings_settings.automatic_cancellation')}

{t('app.admin.trainings_settings.generic_text_block_info')} @@ -121,6 +121,7 @@ export const TrainingsSettings: React.FC = () => { diff --git a/app/frontend/src/javascript/components/trainings/trainings.tsx b/app/frontend/src/javascript/components/trainings/trainings.tsx new file mode 100644 index 000000000..8f0f18cf2 --- /dev/null +++ b/app/frontend/src/javascript/components/trainings/trainings.tsx @@ -0,0 +1,129 @@ +import * as React from 'react'; +import { IApplication } from '../../models/application'; +import { Loader } from '../base/loader'; +import { react2angular } from 'react2angular'; +import { ErrorBoundary } from '../base/error-boundary'; +import { useTranslation } from 'react-i18next'; +import { FabButton } from '../base/fab-button'; +import Select from 'react-select'; +import { SelectOption } from '../../models/select'; +import { PencilSimple, Trash } from 'phosphor-react'; + +declare const Application: IApplication; + +interface TrainingsProps { + onError: (message: string) => void, + onSuccess: (message: string) => void, +} + +/** + * Admin list of trainings + */ +export const Trainings: React.FC = () => { + const { t } = useTranslation('admin'); + + /** Goto new training page */ + const newTraining = (): void => { + window.location.href = '/#!/admin/trainings/new'; + }; + + // Styles the React-select component + const customStyles = { + control: base => ({ + ...base, + width: '20ch', + border: 'none', + backgroundColor: 'transparent' + }), + indicatorSeparator: () => ({ + display: 'none' + }) + }; + + /** Creates filtering options to the react-select format */ + const buildFilterOptions = (): Array> => { + return [ + { value: 'all', label: t('app.admin.trainings.status_all') }, + { value: 'enabled', label: t('app.admin.trainings.status_enabled') }, + { value: 'disabled', label: t('app.admin.trainings.status_disabled') } + ]; + }; + + /** Handel filter change */ + const onFilterChange = (option: SelectOption) => { + console.log(option); + }; + + return ( +
+
+

{t('app.admin.trainings.trainings')}

+
+ {t('app.admin.trainings.add_a_new_training')} +
+
+ +
+
+
+

{t('app.admin.trainings.filter_status')}

+