diff --git a/app/frontend/src/javascript/components/editorial-block/editorial-block-form.tsx b/app/frontend/src/javascript/components/editorial-block/editorial-block-form.tsx new file mode 100644 index 000000000..933b31b3b --- /dev/null +++ b/app/frontend/src/javascript/components/editorial-block/editorial-block-form.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { FieldValues } from 'react-hook-form/dist/types/fields'; +import { Control, FormState, UseFormRegister } from 'react-hook-form'; +import { FormSwitch } from '../form/form-switch'; +import { FormRichText } from '../form/form-rich-text'; +import { FormInput } from '../form/form-input'; + +interface EditorialBlockFormProps { + register: UseFormRegister, + control: Control, + formState: FormState, + info?: string +} + +// regular expression to validate the input fields +const urlRegex = /^(https?:\/\/)([^.]+)\.(.{2,30})(\/.*)*\/?$/; + +/** + * Allows to create a formatted text and optional cta button in a form block, to be included in a resource form managed by react-hook-form. + */ +export const EditorialBlockForm = ({ register, control, formState, info }: EditorialBlockFormProps) => { + const { t } = useTranslation('admin'); + + const [isActiveTextBlock, setIsActiveTextBlock] = useState(false); + const [isActiveCta, setIsActiveCta] = useState(false); + + /** 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); + }; + + return ( + <> +
+

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

+ {info &&

{info}

} +
+ +
+ + + {/* TODO: error message if empty */} + + + {isActiveTextBlock && <> + + + {isActiveCta && <> + + + } + } +
+ + ); +}; diff --git a/app/frontend/src/javascript/components/base/editorial-block.tsx b/app/frontend/src/javascript/components/editorial-block/editorial-block.tsx similarity index 94% rename from app/frontend/src/javascript/components/base/editorial-block.tsx rename to app/frontend/src/javascript/components/editorial-block/editorial-block.tsx index 39afc2232..69259a910 100644 --- a/app/frontend/src/javascript/components/base/editorial-block.tsx +++ b/app/frontend/src/javascript/components/editorial-block/editorial-block.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { IApplication } from '../../models/application'; import { Loader } from '../base/loader'; import { react2angular } from 'react2angular'; -import { FabButton } from './fab-button'; +import { FabButton } from '../base/fab-button'; declare const Application: IApplication; diff --git a/app/frontend/src/javascript/components/machines/machines-list.tsx b/app/frontend/src/javascript/components/machines/machines-list.tsx index 5f324b99e..31a246249 100644 --- a/app/frontend/src/javascript/components/machines/machines-list.tsx +++ b/app/frontend/src/javascript/components/machines/machines-list.tsx @@ -10,10 +10,7 @@ import { MachineCategory } from '../../models/machine-category'; import { MachineCard } from './machine-card'; import { MachinesFilters } from './machines-filters'; import { User } from '../../models/user'; -import { useTranslation } from 'react-i18next'; -import { FabButton } from '../base/fab-button'; -import { EditorialBlock } from '../base/editorial-block'; -import { CalendarBlank } from 'phosphor-react'; +import { EditorialBlock } from '../editorial-block/editorial-block'; declare const Application: IApplication; @@ -32,7 +29,6 @@ interface MachinesListProps { * This component shows a list of all machines and allows filtering on that list. */ export const MachinesList: React.FC = ({ onError, onSuccess, onShowMachine, onReserveMachine, onLoginRequested, onEnrollRequested, user, canProposePacks }) => { - const { t } = useTranslation('public'); // shown machines const [machines, setMachines] = useState>(null); // we keep the full list of machines, for filtering diff --git a/app/frontend/src/javascript/components/machines/machines-settings.tsx b/app/frontend/src/javascript/components/machines/machines-settings.tsx index b3905c158..ce7ba6cc0 100644 --- a/app/frontend/src/javascript/components/machines/machines-settings.tsx +++ b/app/frontend/src/javascript/components/machines/machines-settings.tsx @@ -1,15 +1,12 @@ import * as React from 'react'; -import { useState } 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 { useForm, SubmitHandler } from 'react-hook-form'; -import { FormRichText } from '../form/form-rich-text'; -import { FormSwitch } from '../form/form-switch'; -import { FormInput } from '../form/form-input'; import { FabButton } from '../base/fab-button'; +import { EditorialBlockForm } from '../editorial-block/editorial-block-form'; declare const Application: IApplication; @@ -25,63 +22,6 @@ export const MachinesSettings: React.FC = () => { const { t } = useTranslation('admin'); const { register, control, formState, handleSubmit } = useForm(); - // regular expression to validate the input fields - const urlRegex = /^(https?:\/\/)([^.]+)\.(.{2,30})(\/.*)*\/?$/; - - const [isActiveAutoCancellation, setIsActiveAutoCancellation] = useState(false); - const [isActiveAuthorizationValidity, setIsActiveAuthorizationValidity] = useState(false); - const [isActiveTextBlock, setIsActiveTextBlock] = useState(false); - const [isActiveValidationRule, setIsActiveValidationRule] = useState(false); - const [isActiveCta, setIsActiveCta] = useState(false); - - /** - * Callback triggered when the auto cancellation switch has changed. - */ - const toggleAutoCancellation = (value: boolean) => { - setIsActiveAutoCancellation(value); - }; - - /** - * Callback triggered when the authorisation validity switch has changed. - */ - const toggleAuthorizationValidity = (value: boolean) => { - setIsActiveAuthorizationValidity(value); - }; - - /** - * Callback triggered when the authorisation validity switch has changed. - */ - const toggleValidationRule = (value: boolean) => { - setIsActiveValidationRule(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); - }; - /** * Callback triggered when the form is submitted: save the settings */ @@ -97,43 +37,10 @@ export const MachinesSettings: React.FC = () => {
-
-

{t('app.admin.machines_settings.generic_text_block')}

-

{t('app.admin.machines_settings.generic_text_block_info')}

-
- -
- - - - - {isActiveTextBlock && <> - - - {isActiveCta && <> - - - } - } -
+
diff --git a/app/frontend/src/javascript/components/store/categories/product-categories.tsx b/app/frontend/src/javascript/components/store/categories/product-categories.tsx index b9da7430f..bcc00ceec 100644 --- a/app/frontend/src/javascript/components/store/categories/product-categories.tsx +++ b/app/frontend/src/javascript/components/store/categories/product-categories.tsx @@ -6,7 +6,6 @@ import ProductCategoryAPI from '../../../api/product-category'; import { ManageProductCategory } from './manage-product-category'; import { ProductCategoriesTree } from './product-categories-tree'; import { FabAlert } from '../../base/fab-alert'; -import { HtmlTranslate } from '../../base/html-translate'; import { IApplication } from '../../../models/application'; import { Loader } from '../../base/loader'; import { react2angular } from 'react2angular'; diff --git a/app/frontend/src/javascript/components/store/product-form.tsx b/app/frontend/src/javascript/components/store/product-form.tsx index af63e3560..1c27246d5 100644 --- a/app/frontend/src/javascript/components/store/product-form.tsx +++ b/app/frontend/src/javascript/components/store/product-form.tsx @@ -4,7 +4,6 @@ import { SubmitHandler, useForm, useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import slugify from 'slugify'; import _ from 'lodash'; -import { HtmlTranslate } from '../base/html-translate'; import { Product } from '../../models/product'; import { FormInput } from '../form/form-input'; import { FormSwitch } from '../form/form-switch'; @@ -12,7 +11,6 @@ import { FormSelect } from '../form/form-select'; import { FormChecklist } from '../form/form-checklist'; import { FormRichText } from '../form/form-rich-text'; import { FabButton } from '../base/fab-button'; -import { FabAlert } from '../base/fab-alert'; import ProductCategoryAPI from '../../api/product-category'; import MachineAPI from '../../api/machine'; import ProductAPI from '../../api/product'; diff --git a/app/frontend/src/javascript/components/store/product-stock-form.tsx b/app/frontend/src/javascript/components/store/product-stock-form.tsx index 94c555689..bf12a121f 100644 --- a/app/frontend/src/javascript/components/store/product-stock-form.tsx +++ b/app/frontend/src/javascript/components/store/product-stock-form.tsx @@ -10,10 +10,8 @@ import { StockMovementReason, StockType } from '../../models/product'; -import { HtmlTranslate } from '../base/html-translate'; import { FormSwitch } from '../form/form-switch'; import { FormInput } from '../form/form-input'; -import { FabAlert } from '../base/fab-alert'; import { FabButton } from '../base/fab-button'; import { ProductStockModal } from './product-stock-modal'; import { FabStateLabel } from '../base/fab-state-label'; diff --git a/app/frontend/src/javascript/components/store/store-settings.tsx b/app/frontend/src/javascript/components/store/store-settings.tsx index 22fa41d65..d313afa65 100644 --- a/app/frontend/src/javascript/components/store/store-settings.tsx +++ b/app/frontend/src/javascript/components/store/store-settings.tsx @@ -4,9 +4,7 @@ import { react2angular } from 'react2angular'; import { Loader } from '../base/loader'; import { IApplication } from '../../models/application'; import { useTranslation } from 'react-i18next'; -import { HtmlTranslate } from '../base/html-translate'; import { useForm, SubmitHandler } from 'react-hook-form'; -import { FabAlert } from '../base/fab-alert'; import { FormRichText } from '../form/form-rich-text'; import { FabButton } from '../base/fab-button'; import SettingAPI from '../../api/setting'; diff --git a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx index 645d75a93..5021192f8 100644 --- a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx +++ b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx @@ -6,10 +6,10 @@ import { react2angular } from 'react2angular'; import { ErrorBoundary } from '../base/error-boundary'; import { useTranslation } from 'react-i18next'; import { useForm, SubmitHandler } from 'react-hook-form'; -import { FormRichText } from '../form/form-rich-text'; import { FormSwitch } from '../form/form-switch'; import { FormInput } from '../form/form-input'; import { FabButton } from '../base/fab-button'; +import { EditorialBlockForm } from '../editorial-block/editorial-block-form'; declare const Application: IApplication; @@ -25,14 +25,9 @@ export const TrainingsSettings: React.FC = () => { const { t } = useTranslation('admin'); const { register, control, formState, handleSubmit } = useForm(); - // regular expression to validate the input fields - const urlRegex = /^(https?:\/\/)([^.]+)\.(.{2,30})(\/.*)*\/?$/; - const [isActiveAutoCancellation, setIsActiveAutoCancellation] = useState(false); const [isActiveAuthorizationValidity, setIsActiveAuthorizationValidity] = useState(false); - const [isActiveTextBlock, setIsActiveTextBlock] = useState(false); const [isActiveValidationRule, setIsActiveValidationRule] = useState(false); - const [isActiveCta, setIsActiveCta] = useState(false); /** * Callback triggered when the auto cancellation switch has changed. @@ -55,33 +50,6 @@ export const TrainingsSettings: React.FC = () => { setIsActiveValidationRule(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); - }; - /** * Callback triggered when the form is submitted: save the settings */ @@ -97,43 +65,10 @@ export const TrainingsSettings: React.FC = () => {
-
-

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

-

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

-
- -
- - - - - {isActiveTextBlock && <> - - - {isActiveCta && <> - - - } - } -
+
diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index f7a92d9c3..6ea515d03 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -2388,3 +2388,9 @@ en: value: "Value" date: "Changed at" operator: "By" + editorial_block_form: + title: "Editorial text block" + switch: "Display editorial block" + cta_switch: "Display a button" + cta_label: "Button label" + cta_url: "url"