mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-19 08:52:25 +01:00
(ui) profile data: website, job, cad softwares, interests
This commit is contained in:
parent
dba636b6e6
commit
7a6fe34b90
@ -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);
|
||||
onChangeCb(val);
|
||||
}}
|
||||
checked={value as boolean}
|
||||
checked={value as boolean || false}
|
||||
height={19}
|
||||
width={40}
|
||||
ref={ref}
|
||||
|
@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next';
|
||||
import PlanCategoryAPI from '../../api/plan-category';
|
||||
import { PlanCategory } from '../../models/plan-category';
|
||||
import { Loader } from '../base/loader';
|
||||
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
|
||||
import { FabTextEditor } from '../base/text-editor/fab-text-editor';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import { FormInput } from '../form/form-input';
|
||||
import { FabAlert } from '../base/fab-alert';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import { FormRichText } from '../form/form-rich-text';
|
||||
|
||||
interface PlanCategoryFormProps {
|
||||
action: 'create' | 'update',
|
||||
@ -47,9 +47,7 @@ const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, ca
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<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 } }) =>
|
||||
<FabTextEditor label={t('app.admin.manage_plan_category.description')} onChange={onChange} content={value} limit={100} />
|
||||
} />
|
||||
<FormRichText control={control} id="description" label={t('app.admin.manage_plan_category.description')} limit={100} />
|
||||
|
||||
<FormInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} />
|
||||
<FabAlert level="info" className="significance-info">
|
||||
|
@ -11,6 +11,7 @@ import { GenderInput } from './gender-input';
|
||||
import { ChangePassword } from './change-password';
|
||||
import { PasswordInput } from './password-input';
|
||||
import { FormSwitch } from '../form/form-switch';
|
||||
import { FormRichText } from '../form/form-rich-text';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -25,6 +26,10 @@ interface UserProfileFormProps {
|
||||
export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size, user, className, onError }) => {
|
||||
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 output = useWatch<User>({ control });
|
||||
|
||||
@ -67,7 +72,7 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
register={register}
|
||||
rules={{
|
||||
pattern: {
|
||||
value: /^((00|\+)[0-9]{2,3})?[0-9]{4,14}$/,
|
||||
value: phoneRegex,
|
||||
message: t('app.shared.user_profile_form.phone_number_invalid')
|
||||
}
|
||||
}}
|
||||
@ -133,6 +138,30 @@ export const UserProfileForm: React.FC<UserProfileFormProps> = ({ action, size,
|
||||
</div>
|
||||
<div className="profile-data">
|
||||
<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 className="preferences-data">
|
||||
<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')}
|
||||
tooltip={t('app.shared.user_profile_form.allow_newsletter_help')} />
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit">GO</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
@ -31,6 +31,7 @@
|
||||
@import "modules/calendar/calendar";
|
||||
@import "modules/form/form-input";
|
||||
@import "modules/form/form-item";
|
||||
@import "modules/form/form-rich-text";
|
||||
@import "modules/form/form-switch";
|
||||
@import "modules/machines/machine-card";
|
||||
@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;
|
||||
}
|
||||
|
||||
.names, .birth-phone {
|
||||
.names, .birth-phone, .website-job, .interests-CAD {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.form-input:first-child {
|
||||
.form-item:first-child {
|
||||
margin-right: 32px;
|
||||
}
|
||||
}
|
||||
@ -32,10 +32,10 @@
|
||||
&--small {
|
||||
flex-direction: column;
|
||||
|
||||
.names, .birth-phone {
|
||||
.names, .birth-phone, .website-job, .interests-CAD {
|
||||
flex-direction: column;
|
||||
|
||||
.form-input:first-child {
|
||||
.form-item:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ en:
|
||||
organization_address: "Organization address"
|
||||
date_of_birth: "Date of birth"
|
||||
website: "Website"
|
||||
website_invalid: "The website address is not a valid URL"
|
||||
job: "Job"
|
||||
interests: "Interests"
|
||||
CAD_softwares_mastered: "CAD Softwares mastered"
|
||||
@ -57,7 +58,7 @@ en:
|
||||
birthday_is_required: "Date of birth is required."
|
||||
address: "Address"
|
||||
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_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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user