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/socials/edit-socials.tsx

78 lines
3.1 KiB
TypeScript
Raw Normal View History

2022-04-28 17:31:31 +02:00
import React, { useState, useReducer } from 'react';
2022-05-04 14:57:31 +02:00
import { FormState, UseFormRegister, UseFormSetValue } from 'react-hook-form';
2022-04-28 17:31:31 +02:00
import { FieldValues } from 'react-hook-form/dist/types/fields';
import { User } from '../../models/user';
import { SocialNetwork } from '../../models/social-network';
import Icons from '../../../../images/social-icons.svg';
import { FormInput } from '../form/form-input';
import { Trash } from 'phosphor-react';
import { useTranslation } from 'react-i18next';
interface EditSocialsProps<TFieldValues> {
register: UseFormRegister<TFieldValues>,
2022-05-04 08:55:51 +02:00
setValue: UseFormSetValue<User>,
2022-04-28 17:31:31 +02:00
networks: SocialNetwork[],
2022-05-04 14:57:31 +02:00
formState: FormState<TFieldValues>
2022-04-28 17:31:31 +02:00
}
2022-05-04 14:57:31 +02:00
export const EditSocials = <TFieldValues extends FieldValues>({ register, setValue, networks, formState }: EditSocialsProps<TFieldValues>) => {
2022-04-28 17:31:31 +02:00
const { t } = useTranslation('shared');
2022-05-04 14:57:31 +02:00
// regular expression to validate the the input fields
const urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([-a-z\d.]{2,30})([/\w .-]*)*\/?$/;
2022-04-28 17:31:31 +02:00
const initSelectedNetworks = networks.filter(el => el.url !== '');
const [selectedNetworks, setSelectedNetworks] = useState(initSelectedNetworks);
const selectNetwork = (network) => {
setSelectedNetworks([...selectedNetworks, network]);
};
const reducer = (state, action) => {
switch (action.type) {
case 'delete':
setSelectedNetworks(selectedNetworks.filter(el => el !== action.payload.network));
2022-05-04 08:55:51 +02:00
setValue(action.payload.field, '');
2022-04-28 17:31:31 +02:00
return state.map(el => el === action.payload.network
? { ...el, url: '' }
: el);
case 'update':
return state.map(el => el === action.payload
? { ...el, url: action.payload.url }
: el);
default:
return state;
}
};
const [userNetworks, dispatch] = useReducer(reducer, networks);
return (
<>
<div className='social-icons'>
{userNetworks.map((network, index) =>
!selectedNetworks.includes(network) && <img key={index} src={`${Icons}#${network.name}`} onClick={() => selectNetwork(network)}></img>
)}
</div>
2022-05-04 14:57:31 +02:00
{selectNetwork.length && <div className='social-inputs'>
2022-04-28 17:31:31 +02:00
{userNetworks.map((network, index) =>
selectedNetworks.includes(network) &&
<FormInput key={index}
id={`profile.${network.name}`}
register={register}
2022-05-04 14:57:31 +02:00
rules= {{
pattern: {
value: urlRegex,
message: t('app.shared.user_profile_form.website_invalid')
}
}}
formState={formState}
2022-04-28 17:31:31 +02:00
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={() => dispatch({ type: 'delete', payload: { network, field: `profile.${network.name}` } })} />
)}
2022-05-04 14:57:31 +02:00
</div>}
2022-04-28 17:31:31 +02:00
</>
);
};