mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-21 15:54:22 +01:00
(ui) profile data: website, job, cad softwares, interests
This commit is contained in:
parent
c541e02fe2
commit
cad8484231
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FormControlledComponent } from '../../models/form-component';
|
||||||
|
import { AbstractFormItem, AbstractFormItemProps } from './abstract-form-item';
|
||||||
|
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||||
|
import { FabTextEditor } from '../base/text-editor/fab-text-editor';
|
||||||
|
import { Controller, Path } from 'react-hook-form';
|
||||||
|
import { FieldPath } from 'react-hook-form/dist/types/path';
|
||||||
|
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
|
||||||
|
|
||||||
|
interface FormRichTextProps<TFieldValues, TContext extends object> extends FormControlledComponent<TFieldValues, TContext>, AbstractFormItemProps<TFieldValues> {
|
||||||
|
valueDefault?: string,
|
||||||
|
limit?: number,
|
||||||
|
paragraphTools?: boolean,
|
||||||
|
video?: boolean,
|
||||||
|
image?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THis component is a rich-text editor to use with react-hook-form.
|
||||||
|
*/
|
||||||
|
export const FormRichText = <TFieldValues extends FieldValues, TContext extends object>({ id, label, tooltip, className, control, valueDefault, error, warning, rules, disabled, formState, limit, paragraphTools, video, image }: FormRichTextProps<TFieldValues, TContext>) => {
|
||||||
|
return (
|
||||||
|
<AbstractFormItem id={id} label={label} tooltip={tooltip}
|
||||||
|
className={`form-rich-text ${className || ''}`}
|
||||||
|
error={error} warning={warning} rules={rules}
|
||||||
|
disabled={disabled} formState={formState}>
|
||||||
|
<Controller name={id as FieldPath<TFieldValues>}
|
||||||
|
control={control}
|
||||||
|
defaultValue={valueDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
|
||||||
|
render={({ field: { onChange, value } }) =>
|
||||||
|
<FabTextEditor onChange={onChange} content={value} limit={limit} paragraphTools={paragraphTools} video={video} image={image} />
|
||||||
|
} />
|
||||||
|
</AbstractFormItem>
|
||||||
|
);
|
||||||
|
};
|
@ -38,7 +38,7 @@ export const FormSwitch = <TFieldValues, TContext extends object>({ id, label, t
|
|||||||
onChange(val);
|
onChange(val);
|
||||||
onChangeCb(val);
|
onChangeCb(val);
|
||||||
}}
|
}}
|
||||||
checked={value as boolean}
|
checked={value as boolean || false}
|
||||||
height={19}
|
height={19}
|
||||||
width={40}
|
width={40}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import PlanCategoryAPI from '../../api/plan-category';
|
import PlanCategoryAPI from '../../api/plan-category';
|
||||||
import { PlanCategory } from '../../models/plan-category';
|
import { PlanCategory } from '../../models/plan-category';
|
||||||
import { Loader } from '../base/loader';
|
import { Loader } from '../base/loader';
|
||||||
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import { FabTextEditor } from '../base/text-editor/fab-text-editor';
|
|
||||||
import { FormInput } from '../form/form-input';
|
import { FormInput } from '../form/form-input';
|
||||||
import { FabAlert } from '../base/fab-alert';
|
import { FabAlert } from '../base/fab-alert';
|
||||||
import { FabButton } from '../base/fab-button';
|
import { FabButton } from '../base/fab-button';
|
||||||
|
import { FormRichText } from '../form/form-rich-text';
|
||||||
|
|
||||||
interface PlanCategoryFormProps {
|
interface PlanCategoryFormProps {
|
||||||
action: 'create' | 'update',
|
action: 'create' | 'update',
|
||||||
@ -47,9 +47,7 @@ const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, ca
|
|||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<FormInput id='name' register={register} rules={{ required: 'true' }} label={t('app.admin.manage_plan_category.name')} />
|
<FormInput id='name' register={register} rules={{ required: 'true' }} label={t('app.admin.manage_plan_category.name')} />
|
||||||
|
|
||||||
<Controller name="description" control={control} render={({ field: { onChange, value } }) =>
|
<FormRichText control={control} id="description" label={t('app.admin.manage_plan_category.description')} limit={100} />
|
||||||
<FabTextEditor label={t('app.admin.manage_plan_category.description')} onChange={onChange} content={value} limit={100} />
|
|
||||||
} />
|
|
||||||
|
|
||||||
<FormInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} />
|
<FormInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} />
|
||||||
<FabAlert level="info" className="significance-info">
|
<FabAlert level="info" className="significance-info">
|
||||||
|
@ -11,6 +11,7 @@ import { GenderInput } from './gender-input';
|
|||||||
import { ChangePassword } from './change-password';
|
import { ChangePassword } from './change-password';
|
||||||
import { PasswordInput } from './password-input';
|
import { PasswordInput } from './password-input';
|
||||||
import { FormSwitch } from '../form/form-switch';
|
import { FormSwitch } from '../form/form-switch';
|
||||||
|
import { FormRichText } from '../form/form-rich-text';
|
||||||
|
|
||||||
declare const Application: IApplication;
|
declare const Application: IApplication;
|
||||||
|
|
||||||
@ -25,6 +26,10 @@ interface UserProfileFormProps {
|
|||||||
export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size, user, className, onError }) => {
|
export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size, user, className, onError }) => {
|
||||||
const { t } = useTranslation('shared');
|
const { t } = useTranslation('shared');
|
||||||
|
|
||||||
|
// regular expression to validate the the input fields
|
||||||
|
const phoneRegex = /^((00|\+)[0-9]{2,3})?[0-9]{4,14}$/;
|
||||||
|
const urlRegex = /^(https?:\/\/)([\da-z.-]+)\.([-a-z0-9.]{2,30})([/\w .-]*)*\/?$/;
|
||||||
|
|
||||||
const { handleSubmit, register, control, formState } = useForm<User>({ defaultValues: { ...user } });
|
const { handleSubmit, register, control, formState } = useForm<User>({ defaultValues: { ...user } });
|
||||||
const output = useWatch<User>({ control });
|
const output = useWatch<User>({ control });
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
|||||||
register={register}
|
register={register}
|
||||||
rules={{
|
rules={{
|
||||||
pattern: {
|
pattern: {
|
||||||
value: /^((00|\+)[0-9]{2,3})?[0-9]{4,14}$/,
|
value: phoneRegex,
|
||||||
message: t('app.shared.user_profile_form.phone_number_invalid')
|
message: t('app.shared.user_profile_form.phone_number_invalid')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@ -133,6 +138,30 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
|||||||
</div>
|
</div>
|
||||||
<div className="profile-data">
|
<div className="profile-data">
|
||||||
<h4>{t('app.shared.user_profile_form.profile_data')}</h4>
|
<h4>{t('app.shared.user_profile_form.profile_data')}</h4>
|
||||||
|
<div className="website-job">
|
||||||
|
<FormInput id="profile_attributes.website"
|
||||||
|
register={register}
|
||||||
|
rules={{
|
||||||
|
pattern: {
|
||||||
|
value: urlRegex,
|
||||||
|
message: t('app.shared.user_profile_form.website_invalid')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
placeholder="https://www.example.com"
|
||||||
|
formState={formState}
|
||||||
|
label={t('app.shared.user_profile_form.website')} />
|
||||||
|
<FormInput id="profile_attributes.job"
|
||||||
|
register={register}
|
||||||
|
label={t('app.shared.user_profile_form.job')} />
|
||||||
|
</div>
|
||||||
|
<div className="interests-CAD">
|
||||||
|
<FormRichText control={control}
|
||||||
|
id="profile_attributes.interest"
|
||||||
|
label={t('app.shared.user_profile_form.interests')} />
|
||||||
|
<FormRichText control={control}
|
||||||
|
id="profile_attributes.software_mastered"
|
||||||
|
label={t('app.shared.user_profile_form.CAD_softwares_mastered')} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="preferences-data">
|
<div className="preferences-data">
|
||||||
<h4>{t('app.shared.user_profile_form.preferences_data')}</h4>
|
<h4>{t('app.shared.user_profile_form.preferences_data')}</h4>
|
||||||
@ -145,6 +174,9 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
|||||||
label={t('app.shared.user_profile_form.allow_newsletter')}
|
label={t('app.shared.user_profile_form.allow_newsletter')}
|
||||||
tooltip={t('app.shared.user_profile_form.allow_newsletter_help')} />
|
tooltip={t('app.shared.user_profile_form.allow_newsletter_help')} />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit">GO</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
@import "modules/calendar/calendar";
|
@import "modules/calendar/calendar";
|
||||||
@import "modules/form/form-input";
|
@import "modules/form/form-input";
|
||||||
@import "modules/form/form-item";
|
@import "modules/form/form-item";
|
||||||
|
@import "modules/form/form-rich-text";
|
||||||
@import "modules/form/form-switch";
|
@import "modules/form/form-switch";
|
||||||
@import "modules/machines/machine-card";
|
@import "modules/machines/machine-card";
|
||||||
@import "modules/machines/machines-filters";
|
@import "modules/machines/machines-filters";
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
.form-rich-text {
|
||||||
|
.form-item-field {
|
||||||
|
border: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,11 @@
|
|||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.names, .birth-phone {
|
.names, .birth-phone, .website-job, .interests-CAD {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
.form-input:first-child {
|
.form-item:first-child {
|
||||||
margin-right: 32px;
|
margin-right: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,10 +32,10 @@
|
|||||||
&--small {
|
&--small {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.names, .birth-phone {
|
.names, .birth-phone, .website-job, .interests-CAD {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.form-input:first-child {
|
.form-item:first-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ en:
|
|||||||
organization_address: "Organization address"
|
organization_address: "Organization address"
|
||||||
date_of_birth: "Date of birth"
|
date_of_birth: "Date of birth"
|
||||||
website: "Website"
|
website: "Website"
|
||||||
|
website_invalid: "The website address is not a valid URL"
|
||||||
job: "Job"
|
job: "Job"
|
||||||
interests: "Interests"
|
interests: "Interests"
|
||||||
CAD_softwares_mastered: "CAD Softwares mastered"
|
CAD_softwares_mastered: "CAD Softwares mastered"
|
||||||
@ -57,7 +58,7 @@ en:
|
|||||||
birthday_is_required: "Date of birth is required."
|
birthday_is_required: "Date of birth is required."
|
||||||
address: "Address"
|
address: "Address"
|
||||||
phone_number: "Phone number"
|
phone_number: "Phone number"
|
||||||
phone_number_is_required: "Phone number is required."
|
phone_number_invalid: "Phone number is invalid."
|
||||||
allow_public_profile: "I authorize users, registered on the site, to contact me"
|
allow_public_profile: "I authorize users, registered on the site, to contact me"
|
||||||
allow_public_profile_help: "Your profile will be visible to other users and you'll be able to collaborate on projects."
|
allow_public_profile_help: "Your profile will be visible to other users and you'll be able to collaborate on projects."
|
||||||
allow_newsletter: "I accept to receive information from the FabLab"
|
allow_newsletter: "I accept to receive information from the FabLab"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user