mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
Add form validation
This commit is contained in:
parent
d2ed4d4bd8
commit
521229b87b
@ -1,5 +1,5 @@
|
||||
import React, { useState, useReducer } from 'react';
|
||||
import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
|
||||
import { FormState, UseFormRegister, UseFormSetValue } from 'react-hook-form';
|
||||
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||
import { User } from '../../models/user';
|
||||
import { SocialNetwork } from '../../models/social-network';
|
||||
@ -12,10 +12,13 @@ interface EditSocialsProps<TFieldValues> {
|
||||
register: UseFormRegister<TFieldValues>,
|
||||
setValue: UseFormSetValue<User>,
|
||||
networks: SocialNetwork[],
|
||||
formState: FormState<TFieldValues>
|
||||
}
|
||||
|
||||
export const EditSocials = <TFieldValues extends FieldValues>({ register, setValue, networks }: EditSocialsProps<TFieldValues>) => {
|
||||
export const EditSocials = <TFieldValues extends FieldValues>({ register, setValue, networks, formState }: EditSocialsProps<TFieldValues>) => {
|
||||
const { t } = useTranslation('shared');
|
||||
// regular expression to validate the the input fields
|
||||
const urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([-a-z\d.]{2,30})([/\w .-]*)*\/?$/;
|
||||
|
||||
const initSelectedNetworks = networks.filter(el => el.url !== '');
|
||||
const [selectedNetworks, setSelectedNetworks] = useState(initSelectedNetworks);
|
||||
@ -48,12 +51,19 @@ export const EditSocials = <TFieldValues extends FieldValues>({ register, setVal
|
||||
!selectedNetworks.includes(network) && <img key={index} src={`${Icons}#${network.name}`} onClick={() => selectNetwork(network)}></img>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{selectNetwork.length && <div className='social-inputs'>
|
||||
{userNetworks.map((network, index) =>
|
||||
selectedNetworks.includes(network) &&
|
||||
<FormInput key={index}
|
||||
id={`profile.${network.name}`}
|
||||
register={register}
|
||||
rules= {{
|
||||
pattern: {
|
||||
value: urlRegex,
|
||||
message: t('app.shared.user_profile_form.website_invalid')
|
||||
}
|
||||
}}
|
||||
formState={formState}
|
||||
defaultValue={network.url}
|
||||
label={network.name}
|
||||
placeholder={t('app.shared.text_editor.url_placeholder')}
|
||||
@ -61,7 +71,7 @@ export const EditSocials = <TFieldValues extends FieldValues>({ register, setVal
|
||||
addOn={<Trash size={16} />}
|
||||
addOnAction={() => dispatch({ type: 'delete', payload: { network, field: `profile.${network.name}` } })} />
|
||||
)}
|
||||
</div>
|
||||
</div>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -15,13 +15,17 @@ import { FabButton } from '../base/fab-button';
|
||||
declare const Application: IApplication;
|
||||
|
||||
interface FabSocialsProps {
|
||||
show: boolean
|
||||
show: boolean,
|
||||
onError: (message: string) => void,
|
||||
onSuccess: (message: string) => void
|
||||
}
|
||||
|
||||
export const FabSocials: React.FC<FabSocialsProps> = ({ show = false }) => {
|
||||
export const FabSocials: React.FC<FabSocialsProps> = ({ show = false, onError, onSuccess }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
// regular expression to validate the the input fields
|
||||
const urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([-a-z\d.]{2,30})([/\w .-]*)*\/?$/;
|
||||
|
||||
const { handleSubmit, register, setValue } = useForm();
|
||||
const { handleSubmit, register, setValue, formState } = useForm();
|
||||
|
||||
const settingsList = supportedNetworks.map(el => el as SettingName);
|
||||
|
||||
@ -44,7 +48,9 @@ export const FabSocials: React.FC<FabSocialsProps> = ({ show = false }) => {
|
||||
SettingAPI.bulkUpdate(updatedNetworks).then(res => {
|
||||
const errorResults = Array.from(res.values()).filter(item => !item.status);
|
||||
if (errorResults.length > 0) {
|
||||
console.error(errorResults.map(item => item.error[0]).join(' '));
|
||||
onError(t('app.shared.fab_socials.networks_update_error'));
|
||||
} else {
|
||||
onSuccess(t('app.shared.fab_socials.networks_update_success'));
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -70,24 +76,33 @@ export const FabSocials: React.FC<FabSocialsProps> = ({ show = false }) => {
|
||||
</div>
|
||||
|
||||
: <form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="social-icons">
|
||||
<div className='social-icons'>
|
||||
{fabNetworks.map((network, index) =>
|
||||
!selectedNetworks.includes(network) &&
|
||||
<img key={index} src={`${Icons}#${network.name}`} onClick={() => selectNetwork(network)}></img>
|
||||
)}
|
||||
</div>
|
||||
{fabNetworks.map((network, index) =>
|
||||
selectedNetworks.includes(network) &&
|
||||
<FormInput id={network.name}
|
||||
key={index}
|
||||
register={register}
|
||||
defaultValue={network.url}
|
||||
label={network.name}
|
||||
placeholder={t('app.shared.text_editor.url_placeholder')}
|
||||
icon={<img src={`${Icons}#${network.name}`}></img>}
|
||||
addOn={<Trash size={16} />}
|
||||
addOnAction={() => remove(network)} />
|
||||
)}
|
||||
{selectNetwork.length && <div className='social-inputs'>
|
||||
{fabNetworks.map((network, index) =>
|
||||
selectedNetworks.includes(network) &&
|
||||
<FormInput id={network.name}
|
||||
key={index}
|
||||
register={register}
|
||||
rules={{
|
||||
pattern: {
|
||||
value: urlRegex,
|
||||
message: t('app.shared.user_profile_form.website_invalid')
|
||||
}
|
||||
}}
|
||||
formState={formState}
|
||||
defaultValue={network.url}
|
||||
label={network.name}
|
||||
placeholder={t('app.shared.fab_socials.url_placeholder')}
|
||||
icon={<img src={`${Icons}#${network.name}`}></img>}
|
||||
addOn={<Trash size={16} />}
|
||||
addOnAction={() => remove(network)} />
|
||||
)}
|
||||
</div>}
|
||||
<FabButton type='submit'
|
||||
className='btn-warning'>
|
||||
{t('app.shared.buttons.save')}
|
||||
@ -104,4 +119,4 @@ const FabSocialsWrapper: React.FC<FabSocialsProps> = (props) => {
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
Application.Components.component('fabSocials', react2angular(FabSocialsWrapper, ['show']));
|
||||
Application.Components.component('fabSocials', react2angular(FabSocialsWrapper, ['show', 'onError', 'onSuccess']));
|
||||
|
@ -137,7 +137,8 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
<h4>{t('app.shared.user_profile_form.account_networks')}</h4>
|
||||
<EditSocials register={register}
|
||||
networks={userNetworks}
|
||||
setValue={setValue} />
|
||||
setValue={setValue}
|
||||
formState={formState} />
|
||||
</div>
|
||||
<div className="organization-data">
|
||||
<h4>{t('app.shared.user_profile_form.organization_data')}</h4>
|
||||
|
@ -466,6 +466,14 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope'
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onSuccess = function (message) {
|
||||
growl.success(message);
|
||||
};
|
||||
|
||||
$scope.onError = function (message) {
|
||||
growl.error(message);
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ export default class UserLib {
|
||||
getUserSocialNetworks = (customer: User): {name: string, url: string}[] => {
|
||||
const userNetworks = [];
|
||||
|
||||
for (const [name, url] of Object.entries(customer.profile)) {
|
||||
for (const [name, url] of Object.entries(customer.profile_attributes)) {
|
||||
supportedNetworks.includes(name) && userNetworks.push({ name, url });
|
||||
}
|
||||
return userNetworks;
|
||||
|
@ -595,6 +595,11 @@ body.container {
|
||||
}
|
||||
}
|
||||
}
|
||||
.social-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
column-gap: 3rem;
|
||||
}
|
||||
|
||||
// public profile view
|
||||
.profile-top {
|
||||
|
@ -57,10 +57,9 @@
|
||||
<button name="button" class="btn btn-warning" ng-click="save(aboutContactsSetting)" translate>{{ 'app.shared.buttons.save' }}</button>
|
||||
</div>
|
||||
<div class="col-md-4 col-md-offset-2 m-t-xl">
|
||||
<h2 translate>{{ 'app.public.home.follow_us' }}</h2>
|
||||
<fab-socials></fab-socials>
|
||||
<h2 translate>{{ 'app.admin.settings.about_follow_us' }}</h2>
|
||||
<fab-socials on-success="onSuccess" on-error="onError"></fab-socials>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1310,6 +1310,7 @@ en:
|
||||
about_body: "\"About\" page content"
|
||||
about_contacts: "\"About\" page contacts"
|
||||
about_follow_us: "Follow us"
|
||||
about_networks: "Social networks"
|
||||
privacy_draft: "privacy policy draft"
|
||||
privacy_body: "privacy policy"
|
||||
privacy_dpo: "data protection officer address"
|
||||
|
@ -23,7 +23,6 @@ en:
|
||||
you_will_lose_any_unsaved_modification_if_you_reload_this_page: "You will lose any unsaved modification if you reload this page"
|
||||
payment_card_error: "A problem has occurred with your credit card:"
|
||||
payment_card_declined: "Your card was declined."
|
||||
#text editor
|
||||
text_editor:
|
||||
text_placeholder: "Type something…"
|
||||
link_placeholder: "Paste link…"
|
||||
@ -32,6 +31,10 @@ en:
|
||||
add_link: "Insert a link"
|
||||
add_video: "Embed a video"
|
||||
add_image: "Insert an image"
|
||||
fab_socials:
|
||||
networks_update_success: "Social networks update successful"
|
||||
networks_update_error: "Problem trying to update social networks"
|
||||
url_placeholder: "Paste url…"
|
||||
#user edition form
|
||||
user_profile_form:
|
||||
add_an_avatar: "Add an avatar"
|
||||
|
Loading…
x
Reference in New Issue
Block a user