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/user/user-profile-form.tsx

152 lines
6.7 KiB
TypeScript
Raw Normal View History

2022-04-25 17:23:50 +02:00
import React from 'react';
import { react2angular } from 'react2angular';
2022-04-26 18:05:18 +02:00
import { SubmitHandler, useForm, useWatch } from 'react-hook-form';
2022-04-25 17:23:50 +02:00
import { User } from '../../models/user';
import { IApplication } from '../../models/application';
import { Loader } from '../base/loader';
import { FormInput } from '../form/form-input';
2022-04-26 18:05:18 +02:00
import { useTranslation } from 'react-i18next';
import { Avatar } from './avatar';
import { GenderInput } from './gender-input';
import { ChangePassword } from './change-password';
import { PasswordInput } from './password-input';
2022-04-27 15:36:36 +02:00
import { FormSwitch } from '../form/form-switch';
2022-04-25 17:23:50 +02:00
declare const Application: IApplication;
interface UserProfileFormProps {
action: 'create' | 'update',
2022-04-26 18:05:18 +02:00
size?: 'small' | 'large',
user: User,
className?: string,
onError: (message: string) => void,
2022-04-25 17:23:50 +02:00
}
2022-04-26 18:05:18 +02:00
export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size, user, className, onError }) => {
const { t } = useTranslation('shared');
const { handleSubmit, register, control, formState } = useForm<User>({ defaultValues: { ...user } });
const output = useWatch<User>({ control });
const [isOrganization, setIsOrganization] = React.useState<boolean>(user.invoicing_profile.organization !== null);
2022-04-25 17:23:50 +02:00
/**
* Callback triggered when the form is submitted: process with the user creation or update.
*/
const onSubmit: SubmitHandler<User> = (data: User) => {
console.log(action, data);
};
return (
2022-04-26 18:05:18 +02:00
<form className={`user-profile-form user-profile-form--${size} ${className}`} onSubmit={handleSubmit(onSubmit)}>
<div className="avatar-group">
<Avatar user={user}/>
</div>
<div className="fields-group">
<div className="personnal-data">
<h4>{t('app.shared.user_profile_form.personal_data')}</h4>
<GenderInput register={register} />
<div className="names">
<FormInput id="profile_attributes.last_name"
register={register}
rules={{ required: true }}
formState={formState}
label={t('app.shared.user_profile_form.surname')} />
<FormInput id="profile_attributes.first_name"
register={register}
rules={{ required: true }}
formState={formState}
label={t('app.shared.user_profile_form.first_name')} />
</div>
<div className="birth-phone">
<FormInput id="statistic_profile_attributes.birthday"
register={register}
label={t('app.shared.user_profile_form.date_of_birth')}
type="date" />
<FormInput id="profile_attributes.phone"
register={register}
rules={{
pattern: {
value: /^((00|\+)[0-9]{2,3})?[0-9]{4,14}$/,
message: t('app.shared.user_profile_form.phone_number_invalid')
}
}}
formState={formState}
label={t('app.shared.user_profile_form.phone_number')} />
</div>
<div className="address">
<FormInput id="invoicing_profile_attributes.address_attributes.id"
register={register}
type="hidden" />
<FormInput id="invoicing_profile_attributes.address_attributes.address"
register={register}
label={t('app.shared.user_profile_form.address')} />
</div>
</div>
<div className="account-data">
<h4>{t('app.shared.user_profile_form.account_data')}</h4>
<FormInput id="username"
register={register}
rules={{ required: true }}
formState={formState}
label={t('app.shared.user_profile_form.pseudonym')} />
<FormInput id="email"
register={register}
rules={{ required: true }}
formState={formState}
label={t('app.shared.user_profile_form.email_address')} />
{/* TODO: no password change if sso */}
{action === 'update' && <ChangePassword register={register}
onError={onError}
currentFormPassword={output.password}
formState={formState} />}
{action === 'create' && <PasswordInput register={register}
currentFormPassword={output.password}
formState={formState} />}
</div>
<div className="organization-data">
<h4>{t('app.shared.user_profile_form.organization_data')}</h4>
2022-04-27 15:36:36 +02:00
<FormSwitch control={control}
id="invoicing_profile_attributes.organization"
label={t('app.shared.user_profile_form.declare_organization')}
tooltip={t('app.shared.user_profile_form.declare_organization_help')}
defaultValue={user.invoicing_profile.organization !== null}
onChange={setIsOrganization} />
2022-04-26 18:05:18 +02:00
{isOrganization && <div className="organization-fields">
<FormInput id="invoicing_profile_attributes.organization_attributes.id"
register={register}
type="hidden" />
<FormInput id="invoicing_profile_attributes.organization_attributes.name"
register={register}
rules={{ required: isOrganization }}
formState={formState}
label={t('app.shared.user_profile_form.organization_name')} />
<FormInput id="invoicing_profile_attributes.organization_attributes.address_attributes.id"
register={register}
type="hidden" />
<FormInput id="invoicing_profile_attributes.organization_attributes.address_attributes.address"
register={register}
rules={{ required: isOrganization }}
formState={formState}
label={t('app.shared.user_profile_form.organization_address')} />
</div>}
</div>
</div>
2022-04-25 17:23:50 +02:00
</form>
);
};
2022-04-26 18:05:18 +02:00
UserProfileForm.defaultProps = {
size: 'large'
};
2022-04-25 17:23:50 +02:00
const UserProfileFormWrapper: React.FC<UserProfileFormProps> = (props) => {
return (
<Loader>
<UserProfileForm {...props} />
</Loader>
);
};
2022-04-26 18:05:18 +02:00
Application.Components.component('userProfileForm', react2angular(UserProfileFormWrapper, ['action', 'size', 'user', 'className', 'onError']));