mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
linted all front code, excepted profile-completion/
and prrofile-custom-fields/
This commit is contained in:
parent
37bc2b3d43
commit
2033329342
@ -6,7 +6,7 @@
|
||||
],
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"no-use-before-define": "off",
|
||||
"no-use-before-define": "off"
|
||||
},
|
||||
"globals": {
|
||||
"Application": true,
|
||||
|
@ -13,6 +13,10 @@ interface Oauth2DataMappingFormProps<TFieldValues, TContext extends object> {
|
||||
index: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial form to set the data mapping for an OAuth 2.0 provider.
|
||||
* The data mapping is the way to bind data from the authentication provider API to the Fab-manager's database
|
||||
*/
|
||||
export const Oauth2DataMappingForm = <TFieldValues extends FieldValues, TContext extends object>({ register, control, index }: Oauth2DataMappingFormProps<TFieldValues, TContext>) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
|
@ -16,6 +16,10 @@ interface OpenidConnectDataMappingFormProps<TFieldValues> {
|
||||
index: number,
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial form to set the data mapping for an OpenID Connect provider.
|
||||
* The data mapping is the way to bind data from the OIDC claims to the Fab-manager's database
|
||||
*/
|
||||
export const OpenidConnectDataMappingForm = <TFieldValues extends FieldValues>({ register, setValue, currentFormValues, index }: OpenidConnectDataMappingFormProps<TFieldValues>) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
|
@ -20,6 +20,9 @@ interface OpenidConnectFormProps<TFieldValues, TContext extends object> {
|
||||
setValue: UseFormSetValue<TFieldValues>,
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial form to fill the OpenID Connect (OIDC) settings for a new/existing authentication provider.
|
||||
*/
|
||||
export const OpenidConnectForm = <TFieldValues extends FieldValues, TContext extends object>({ register, control, currentFormValues, formState, setValue }: OpenidConnectFormProps<TFieldValues, TContext>) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
|
@ -168,7 +168,7 @@ export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools, video,
|
||||
>
|
||||
<Quotes size={24} />
|
||||
</button>
|
||||
<span className='divider'></span>
|
||||
<span className='menu-divider'></span>
|
||||
</>)
|
||||
}
|
||||
<button
|
||||
@ -203,7 +203,7 @@ export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools, video,
|
||||
>
|
||||
<LinkSimpleHorizontal size={24} />
|
||||
</button>
|
||||
{ (video || image) && <span className='divider'></span> }
|
||||
{ (video || image) && <span className='menu-divider'></span> }
|
||||
{ video &&
|
||||
(<>
|
||||
<button
|
||||
|
@ -13,6 +13,9 @@ interface EventCardProps {
|
||||
cardType: 'sm' | 'md' | 'lg'
|
||||
}
|
||||
|
||||
/**
|
||||
* This component is a box showing the picture of the given event, and a short description of it.
|
||||
*/
|
||||
export const EventCard: React.FC<EventCardProps> = ({ event, cardType }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
|
@ -30,6 +30,9 @@ interface ChangeGroupProps {
|
||||
*/
|
||||
type selectOption = { value: number, label: string };
|
||||
|
||||
/**
|
||||
* Component to display the group of the provided user, and allow him to change his group.
|
||||
*/
|
||||
export const ChangeGroup: React.FC<ChangeGroupProps> = ({ user, onSuccess, onError, allowChange, className }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
|
@ -40,6 +40,9 @@ const MachineCard: React.FC<MachineCardProps> = ({ user, machine, onShowMachine,
|
||||
onShowMachine(machine);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the machine's picture or a placeholder
|
||||
*/
|
||||
const machinePicture = (): ReactNode => {
|
||||
if (!machine.machine_image) {
|
||||
return <div className="machine-picture no-picture" />;
|
||||
@ -82,10 +85,10 @@ const MachineCard: React.FC<MachineCardProps> = ({ user, machine, onShowMachine,
|
||||
);
|
||||
};
|
||||
|
||||
const MachineCardWrapper: React.FC<MachineCardProps> = ({ user, machine, onShowMachine, onReserveMachine, onError, onSuccess, onLoginRequested, onEnrollRequested, canProposePacks }) => {
|
||||
const MachineCardWrapper: React.FC<MachineCardProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<MachineCard user={user} machine={machine} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} onError={onError} onSuccess={onSuccess} onLoginRequested={onLoginRequested} onEnrollRequested={onEnrollRequested} canProposePacks={canProposePacks} />
|
||||
<MachineCard {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
@ -12,6 +12,9 @@ interface MachinesFiltersProps {
|
||||
*/
|
||||
type selectOption = { value: boolean, label: string };
|
||||
|
||||
/**
|
||||
* Allows filtering on machines list
|
||||
*/
|
||||
export const MachinesFilters: React.FC<MachinesFiltersProps> = ({ onStatusSelected }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
|
@ -31,7 +31,7 @@ interface ReserveButtonProps {
|
||||
/**
|
||||
* Button component that makes the training verification before redirecting the user to the reservation calendar
|
||||
*/
|
||||
const ReserveButtonComponent: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onSuccess, onReserveMachine, onEnrollRequested, className, children, canProposePacks }) => {
|
||||
const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onSuccess, onReserveMachine, onEnrollRequested, className, children, canProposePacks }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const [machine, setMachine] = useState<Machine>(null);
|
||||
@ -183,14 +183,16 @@ const ReserveButtonComponent: React.FC<ReserveButtonProps> = ({ currentUser, mac
|
||||
);
|
||||
};
|
||||
|
||||
export const ReserveButton: React.FC<ReserveButtonProps> = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onSuccess, onReserveMachine, onEnrollRequested, className, children, canProposePacks }) => {
|
||||
const ReserveButtonWrapper: React.FC<ReserveButtonProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<ReserveButtonComponent currentUser={currentUser} machineId={machineId} onError={onError} onSuccess={onSuccess} onLoadingStart={onLoadingStart} onLoadingEnd={onLoadingEnd} onReserveMachine={onReserveMachine} onLoginRequested={onLoginRequested} onEnrollRequested={onEnrollRequested} className={className} canProposePacks={canProposePacks}>
|
||||
{children}
|
||||
</ReserveButtonComponent>
|
||||
<ReserveButton {...props}>
|
||||
{props.children}
|
||||
</ReserveButton>
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('reserveButton', react2angular(ReserveButton, ['currentUser', 'machineId', 'onLoadingStart', 'onLoadingEnd', 'onError', 'onSuccess', 'onReserveMachine', 'onLoginRequested', 'onEnrollRequested', 'className', 'canProposePacks']));
|
||||
export { ReserveButtonWrapper as ReserveButton };
|
||||
|
||||
Application.Components.component('reserveButton', react2angular(ReserveButtonWrapper, ['currentUser', 'machineId', 'onLoadingStart', 'onLoadingEnd', 'onError', 'onSuccess', 'onReserveMachine', 'onLoginRequested', 'onEnrollRequested', 'className', 'canProposePacks']));
|
||||
|
@ -123,6 +123,9 @@ const PaymentSchedulesTable: React.FC<PaymentSchedulesTableProps> = ({ paymentSc
|
||||
refreshList();
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the JSX table element that list all payment schedules and allows to perform actions on them.
|
||||
*/
|
||||
const renderPaymentSchedulesTable = (): ReactElement => {
|
||||
return (
|
||||
<table className="payment-schedules-table">
|
||||
|
@ -19,6 +19,9 @@ interface UpdatePaymentMeanModalProps {
|
||||
*/
|
||||
type selectOption = { value: PaymentMethod, label: string };
|
||||
|
||||
/**
|
||||
* Component to allow the member to change his payment mean for the given payment schedule (e.g. from card to transfer)
|
||||
*/
|
||||
export const UpdatePaymentMeanModal: React.FC<UpdatePaymentMeanModalProps> = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
|
@ -29,7 +29,7 @@ interface CardPaymentModalProps {
|
||||
* This component open a modal dialog for the configured payment gateway, allowing the user to input his card data
|
||||
* to process an online payment.
|
||||
*/
|
||||
const CardPaymentModalComponent: React.FC<CardPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, currentUser, schedule, cart, customer }) => {
|
||||
const CardPaymentModal: React.FC<CardPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, currentUser, schedule, cart, customer }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const [gateway, setGateway] = useState<Setting>(null);
|
||||
@ -89,12 +89,14 @@ const CardPaymentModalComponent: React.FC<CardPaymentModalProps> = ({ isOpen, to
|
||||
}
|
||||
};
|
||||
|
||||
export const CardPaymentModal: React.FC<CardPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, currentUser, schedule, cart, customer }) => {
|
||||
const CardPaymentModalWrapper: React.FC<CardPaymentModalProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<CardPaymentModalComponent isOpen={isOpen} toggleModal={toggleModal} afterSuccess={afterSuccess} onError={onError} currentUser={currentUser} schedule={schedule} cart={cart} customer={customer} />
|
||||
<CardPaymentModal {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('cardPaymentModal', react2angular(CardPaymentModal, ['isOpen', 'toggleModal', 'afterSuccess', 'onError', 'currentUser', 'schedule', 'cart', 'customer']));
|
||||
export { CardPaymentModalWrapper as CardPaymentModal };
|
||||
|
||||
Application.Components.component('cardPaymentModal', react2angular(CardPaymentModalWrapper, ['isOpen', 'toggleModal', 'afterSuccess', 'onError', 'currentUser', 'schedule', 'cart', 'customer']));
|
||||
|
@ -28,7 +28,7 @@ interface LocalPaymentModalProps {
|
||||
/**
|
||||
* This component enables a privileged user to confirm a local payments.
|
||||
*/
|
||||
const LocalPaymentModalComponent: React.FC<LocalPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, cart, updateCart, currentUser, schedule, customer }) => {
|
||||
const LocalPaymentModal: React.FC<LocalPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, cart, updateCart, currentUser, schedule, customer }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
/**
|
||||
@ -93,12 +93,14 @@ const LocalPaymentModalComponent: React.FC<LocalPaymentModalProps> = ({ isOpen,
|
||||
);
|
||||
};
|
||||
|
||||
export const LocalPaymentModal: React.FC<LocalPaymentModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, currentUser, schedule, cart, updateCart, customer }) => {
|
||||
const LocalPaymentModalWrapper: React.FC<LocalPaymentModalProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<LocalPaymentModalComponent isOpen={isOpen} toggleModal={toggleModal} afterSuccess={afterSuccess} onError={onError} currentUser={currentUser} schedule={schedule} cart={cart} updateCart={updateCart} customer={customer} />
|
||||
<LocalPaymentModal {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('localPaymentModal', react2angular(LocalPaymentModal, ['isOpen', 'toggleModal', 'afterSuccess', 'onError', 'currentUser', 'schedule', 'cart', 'updateCart', 'customer']));
|
||||
export { LocalPaymentModalWrapper as LocalPaymentModal };
|
||||
|
||||
Application.Components.component('localPaymentModal', react2angular(LocalPaymentModalWrapper, ['isOpen', 'toggleModal', 'afterSuccess', 'onError', 'currentUser', 'schedule', 'cart', 'updateCart', 'customer']));
|
||||
|
@ -16,6 +16,9 @@ interface PayzenCardUpdateModalProps {
|
||||
operator: User
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal dialog to allow the member to update his payment card for a payment schedule, when the PayZen gateway is used
|
||||
*/
|
||||
export const PayzenCardUpdateModal: React.FC<PayzenCardUpdateModalProps> = ({ isOpen, toggleModal, onSuccess, schedule, operator }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
|
@ -143,6 +143,9 @@ export const PayzenForm: React.FC<PayzenFormProps> = ({ onSubmit, onSuccess, onE
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a loader
|
||||
*/
|
||||
const Loader: FunctionComponent = () => {
|
||||
return (
|
||||
<div className={`fa-3x ${loadingClass}`}>
|
||||
@ -154,7 +157,7 @@ export const PayzenForm: React.FC<PayzenFormProps> = ({ onSubmit, onSuccess, onE
|
||||
return (
|
||||
<form onSubmit={handleSubmit} id={formId} className={`payzen-form ${className || ''}`}>
|
||||
<Loader />
|
||||
<div className="container">
|
||||
<div className="payzen-container">
|
||||
<div id="payzenPaymentForm" />
|
||||
</div>
|
||||
{children}
|
||||
|
@ -28,7 +28,7 @@ let pendingKeysValidation = false;
|
||||
/**
|
||||
* Form to set the PayZen's username, password and public key
|
||||
*/
|
||||
const PayzenKeysFormComponent: React.FC<PayzenKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const PayzenKeysForm: React.FC<PayzenKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
// values of the PayZen settings
|
||||
@ -205,10 +205,12 @@ const PayzenKeysFormComponent: React.FC<PayzenKeysFormProps> = ({ onValidKeys, o
|
||||
);
|
||||
};
|
||||
|
||||
export const PayzenKeysForm: React.FC<PayzenKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const PayzenKeysFormWrapper: React.FC<PayzenKeysFormProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<PayzenKeysFormComponent onValidKeys={onValidKeys} onInvalidKeys={onInvalidKeys} />
|
||||
<PayzenKeysForm {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { PayzenKeysFormWrapper as PayzenKeysForm };
|
||||
|
@ -16,6 +16,9 @@ interface StripeCardUpdateModalProps {
|
||||
operator: User
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal dialog to allow the member to update his payment card for a payment schedule, when the Stripe gateway is used
|
||||
*/
|
||||
export const StripeCardUpdateModal: React.FC<StripeCardUpdateModalProps> = ({ isOpen, toggleModal, onSuccess, schedule, operator }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
@ -30,7 +33,7 @@ export const StripeCardUpdateModal: React.FC<StripeCardUpdateModalProps> = ({ is
|
||||
const logoFooter = (): ReactNode => {
|
||||
return (
|
||||
<div className="stripe-modal-icons">
|
||||
<i className="fa fa-lock fa-2x m-r-sm pos-rlt" />
|
||||
<i className="fa fa-lock fa-2x" />
|
||||
<img src={stripeLogo} alt="powered by stripe" />
|
||||
<img src={mastercardLogo} alt="mastercard" />
|
||||
<img src={visaLogo} alt="visa" />
|
||||
|
@ -15,7 +15,7 @@ interface StripeKeysFormProps {
|
||||
/**
|
||||
* Form to set the stripe's public and private keys
|
||||
*/
|
||||
const StripeKeysFormComponent: React.FC<StripeKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const StripeKeysForm: React.FC<StripeKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
// used to prevent promises from resolving if the component was unmounted
|
||||
@ -153,10 +153,12 @@ const StripeKeysFormComponent: React.FC<StripeKeysFormProps> = ({ onValidKeys, o
|
||||
);
|
||||
};
|
||||
|
||||
export const StripeKeysForm: React.FC<StripeKeysFormProps> = ({ onValidKeys, onInvalidKeys }) => {
|
||||
const StripeKeysFormWrapper: React.FC<StripeKeysFormProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<StripeKeysFormComponent onValidKeys={onValidKeys} onInvalidKeys={onInvalidKeys} />
|
||||
<StripeKeysForm {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { StripeKeysFormWrapper as StripeKeysForm };
|
||||
|
@ -36,7 +36,7 @@ export const StripeModal: React.FC<StripeModalProps> = ({ isOpen, toggleModal, a
|
||||
const logoFooter = (): ReactNode => {
|
||||
return (
|
||||
<div className="stripe-modal-icons">
|
||||
<i className="fa fa-lock fa-2x m-r-sm pos-rlt" />
|
||||
<i className="fa fa-lock fa-2x" />
|
||||
<img src={stripeLogo} alt="powered by stripe" />
|
||||
<img src={mastercardLogo} alt="mastercard" />
|
||||
<img src={visaLogo} alt="visa" />
|
||||
|
@ -19,7 +19,7 @@ interface UpdateCardModalProps {
|
||||
* This component open a modal dialog for the configured payment gateway, allowing the user to input his card data
|
||||
* to process an online payment.
|
||||
*/
|
||||
const UpdateCardModalComponent: React.FC<UpdateCardModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, operator, schedule }) => {
|
||||
const UpdateCardModal: React.FC<UpdateCardModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, operator, schedule }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
const [gateway, setGateway] = useState<string>('');
|
||||
|
||||
@ -68,10 +68,12 @@ const UpdateCardModalComponent: React.FC<UpdateCardModalProps> = ({ isOpen, togg
|
||||
}
|
||||
};
|
||||
|
||||
export const UpdateCardModal: React.FC<UpdateCardModalProps> = ({ isOpen, toggleModal, afterSuccess, onError, operator, schedule }) => {
|
||||
const UpdateCardModalWrapper: React.FC<UpdateCardModalProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<UpdateCardModalComponent isOpen={isOpen} toggleModal={toggleModal} afterSuccess={afterSuccess} onError={onError} operator={operator} schedule={schedule} />
|
||||
<UpdateCardModal {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { UpdateCardModalWrapper as UpdateCardModal };
|
||||
|
@ -16,7 +16,7 @@ interface DeletePlanCategoryProps {
|
||||
* This component shows a button.
|
||||
* When clicked, we show a modal dialog to ask the user for confirmation about the deletion of the provided plan-category.
|
||||
*/
|
||||
const DeletePlanCategoryComponent: React.FC<DeletePlanCategoryProps> = ({ onSuccess, onError, category }) => {
|
||||
const DeletePlanCategory: React.FC<DeletePlanCategoryProps> = ({ onSuccess, onError, category }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [deletionModal, setDeletionModal] = useState<boolean>(false);
|
||||
@ -56,10 +56,12 @@ const DeletePlanCategoryComponent: React.FC<DeletePlanCategoryProps> = ({ onSucc
|
||||
);
|
||||
};
|
||||
|
||||
export const DeletePlanCategory: React.FC<DeletePlanCategoryProps> = ({ onSuccess, onError, category }) => {
|
||||
const DeletePlanCategoryWrapper: React.FC<DeletePlanCategoryProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<DeletePlanCategoryComponent onSuccess={onSuccess} onError={onError} category={category} />
|
||||
<DeletePlanCategory {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { DeletePlanCategoryWrapper as DeletePlanCategory };
|
||||
|
@ -17,7 +17,7 @@ interface ManagePlanCategoryProps {
|
||||
* This component shows a button.
|
||||
* When clicked, we show a modal dialog allowing to fill the parameters of a plan-category (create new or update existing).
|
||||
*/
|
||||
const ManagePlanCategoryComponent: React.FC<ManagePlanCategoryProps> = ({ category, action, onSuccess, onError }) => {
|
||||
const ManagePlanCategory: React.FC<ManagePlanCategoryProps> = ({ category, action, onSuccess, onError }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
// is the creation modal open?
|
||||
@ -61,7 +61,7 @@ const ManagePlanCategoryComponent: React.FC<ManagePlanCategoryProps> = ({ catego
|
||||
return (
|
||||
<FabButton type='button'
|
||||
icon={<i className='fa fa-plus' />}
|
||||
className="btn-warning"
|
||||
className="create-button"
|
||||
onClick={toggleModal}>
|
||||
{t('app.admin.manage_plan_category.create_category.title')}
|
||||
</FabButton>
|
||||
@ -90,10 +90,12 @@ const ManagePlanCategoryComponent: React.FC<ManagePlanCategoryProps> = ({ catego
|
||||
);
|
||||
};
|
||||
|
||||
export const ManagePlanCategory: React.FC<ManagePlanCategoryProps> = ({ category, action, onSuccess, onError }) => {
|
||||
const ManagePlanCategoryWrapper: React.FC<ManagePlanCategoryProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<ManagePlanCategoryComponent category={category} action={action} onSuccess={onSuccess} onError={onError} />
|
||||
<ManagePlanCategory {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { ManagePlanCategoryWrapper as ManagePlanCategory };
|
||||
|
@ -16,7 +16,10 @@ interface PlanCategoryFormProps {
|
||||
onError: (message: string) => void
|
||||
}
|
||||
|
||||
const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, category, onSuccess, onError }) => {
|
||||
/**
|
||||
* Form to create/edit a plan category
|
||||
*/
|
||||
const PlanCategoryForm: React.FC<PlanCategoryFormProps> = ({ action, category, onSuccess, onError }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const { register, control, handleSubmit } = useForm<PlanCategory>({ defaultValues: { ...category } });
|
||||
@ -58,10 +61,12 @@ const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, ca
|
||||
);
|
||||
};
|
||||
|
||||
export const PlanCategoryForm: React.FC<PlanCategoryFormProps> = ({ action, category, onSuccess, onError }) => {
|
||||
const PlanCategoryFormWrapper: React.FC<PlanCategoryFormProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<PlanCategoryFormComponent action={action} category={category} onSuccess={onSuccess} onError={onError} />
|
||||
<PlanCategoryForm {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { PlanCategoryFormWrapper as PlanCategoryForm };
|
||||
|
@ -20,6 +20,9 @@ interface PlansFilterProps {
|
||||
*/
|
||||
type selectOption = { value: number, label: string };
|
||||
|
||||
/**
|
||||
* Allows filtering on plans list
|
||||
*/
|
||||
export const PlansFilter: React.FC<PlansFilterProps> = ({ user, groups, onGroupSelected, onError, onDurationSelected }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
|
@ -14,6 +14,7 @@ import { react2angular } from 'react2angular';
|
||||
import { IApplication } from '../../models/application';
|
||||
import { PrepaidPack } from '../../models/prepaid-pack';
|
||||
import PrepaidPackAPI from '../../api/prepaid-pack';
|
||||
import { FabAlert } from '../base/fab-alert';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -29,7 +30,11 @@ interface PacksSummaryProps {
|
||||
refresh?: Promise<void>
|
||||
}
|
||||
|
||||
const PacksSummaryComponent: React.FC<PacksSummaryProps> = ({ item, itemType, customer, operator, onError, onSuccess, refresh }) => {
|
||||
/**
|
||||
* Display a short summary of the prepaid-packs already bought by the provider customer, for the given item.
|
||||
* May also allows members to buy directly some new prepaid-packs.
|
||||
*/
|
||||
const PacksSummary: React.FC<PacksSummaryProps> = ({ item, itemType, customer, operator, onError, onSuccess, refresh }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
|
||||
const [packs, setPacks] = useState<Array<PrepaidPack>>(null);
|
||||
@ -140,9 +145,9 @@ const PacksSummaryComponent: React.FC<PacksSummaryProps> = ({ item, itemType, cu
|
||||
<span className="remaining-hours">
|
||||
{t('app.logged.packs_summary.remaining_HOURS', { HOURS: totalHours(), ITEM: itemType })}
|
||||
{isPackOnlyForSubscription && !customer.subscribed_plan &&
|
||||
<div className="alert alert-warning m-t m-b">
|
||||
<FabAlert level="warning">
|
||||
{t('app.logged.packs_summary.unable_to_use_pack_for_subsription_is_expired')}
|
||||
</div>
|
||||
</FabAlert>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
@ -178,12 +183,14 @@ const PacksSummaryComponent: React.FC<PacksSummaryProps> = ({ item, itemType, cu
|
||||
);
|
||||
};
|
||||
|
||||
export const PacksSummary: React.FC<PacksSummaryProps> = ({ item, itemType, customer, operator, onError, onSuccess, refresh }) => {
|
||||
const PacksSummaryWrapper: React.FC<PacksSummaryProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<PacksSummaryComponent item={item} itemType={itemType} customer={customer} operator={operator} onError={onError} onSuccess={onSuccess} refresh={refresh} />
|
||||
<PacksSummary {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
Application.Components.component('packsSummary', react2angular(PacksSummary, ['item', 'itemType', 'customer', 'operator', 'onError', 'onSuccess', 'refresh']));
|
||||
export { PacksSummaryWrapper as PacksSummary };
|
||||
|
||||
Application.Components.component('packsSummary', react2angular(PacksSummaryWrapper, ['item', 'itemType', 'customer', 'operator', 'onError', 'onSuccess', 'refresh']));
|
||||
|
@ -16,7 +16,7 @@ interface DeletePackProps {
|
||||
* This component shows a button.
|
||||
* When clicked, we show a modal dialog to ask the user for confirmation about the deletion of the provided pack.
|
||||
*/
|
||||
const DeletePackComponent: React.FC<DeletePackProps> = ({ onSuccess, onError, pack }) => {
|
||||
const DeletePack: React.FC<DeletePackProps> = ({ onSuccess, onError, pack }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [deletionModal, setDeletionModal] = useState<boolean>(false);
|
||||
@ -56,10 +56,12 @@ const DeletePackComponent: React.FC<DeletePackProps> = ({ onSuccess, onError, pa
|
||||
);
|
||||
};
|
||||
|
||||
export const DeletePack: React.FC<DeletePackProps> = ({ onSuccess, onError, pack }) => {
|
||||
const DeletePackWrapper: React.FC<DeletePackProps> = (props) => {
|
||||
return (
|
||||
<Loader>
|
||||
<DeletePackComponent onSuccess={onSuccess} onError={onError} pack={pack} />
|
||||
<DeletePack {...props} />
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
|
||||
export { DeletePackWrapper as DeletePack };
|
||||
|
@ -20,6 +20,13 @@ interface ProfileFormOptionProps {
|
||||
onSuccess: (user: User) => void,
|
||||
}
|
||||
|
||||
/**
|
||||
* After first logged-in from a SSO, the user has two options:
|
||||
* - complete his profile (*) ;
|
||||
* - bind his profile to his existing account ;
|
||||
* (*) This component handle the first case.
|
||||
* It also deals with duplicate email addresses in database
|
||||
*/
|
||||
export const ProfileFormOption: React.FC<ProfileFormOptionProps> = ({ user, activeProvider, onError, onSuccess }) => {
|
||||
const { t } = useTranslation('logged');
|
||||
|
||||
|
@ -97,10 +97,10 @@ export const BooleanSetting: React.FC<BooleanSettingProps> = ({ name, label, cla
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`boolean-setting form-group ${className || ''}`}>
|
||||
<label htmlFor={`setting-${name}`} className="control-label m-r">{label}</label>
|
||||
<Switch checked={value} id={`setting-${name}}`} onChange={handleChanged} className="v-middle"></Switch>
|
||||
{!hideSave && <FabButton className="btn btn-warning m-l" onClick={handleSave}>{t('app.admin.check_list_setting.save')}</FabButton> }
|
||||
<div className={`boolean-setting ${className || ''}`}>
|
||||
<label htmlFor={`setting-${name}`}>{label}</label>
|
||||
<Switch checked={value} id={`setting-${name}}`} onChange={handleChanged} className="switch"></Switch>
|
||||
{!hideSave && <FabButton className="save-btn" onClick={handleSave}>{t('app.admin.check_list_setting.save')}</FabButton> }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ import { Loader } from '../base/loader';
|
||||
import { FabButton } from '../base/fab-button';
|
||||
import { BooleanSetting } from './boolean-setting';
|
||||
import { CheckListSetting } from './check-list-setting';
|
||||
import { FabAlert } from '../base/fab-alert';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -82,9 +83,9 @@ export const UserValidationSetting: React.FC<UserValidationSettingProps> = ({ on
|
||||
<p>
|
||||
{t('app.admin.settings.compte.user_validation_required_list_info')}
|
||||
</p>
|
||||
<p className="alert alert-warning">
|
||||
<FabAlert level="warning">
|
||||
{t('app.admin.settings.compte.user_validation_required_list_other_info')}
|
||||
</p>
|
||||
</FabAlert>
|
||||
<CheckListSetting name={SettingName.UserValidationRequiredList}
|
||||
label=""
|
||||
availableOptions={userValidationRequiredOptions}
|
||||
@ -96,7 +97,7 @@ export const UserValidationSetting: React.FC<UserValidationSettingProps> = ({ on
|
||||
</CheckListSetting>
|
||||
</div>
|
||||
}
|
||||
<FabButton className="btn btn-warning m-t" onClick={handleSave}>{t('app.admin.check_list_setting.save')}</FabButton>
|
||||
<FabButton className="save-btn" onClick={handleSave}>{t('app.admin.check_list_setting.save')}</FabButton>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -16,6 +16,9 @@ interface EditSocialsProps<TFieldValues> {
|
||||
disabled: boolean|((id: string) => boolean),
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow a user to edit its personnal social networks
|
||||
*/
|
||||
export const EditSocials = <TFieldValues extends FieldValues>({ register, setValue, networks, formState, disabled }: EditSocialsProps<TFieldValues>) => {
|
||||
const { t } = useTranslation('shared');
|
||||
// regular expression to validate the the input fields
|
||||
@ -23,10 +26,17 @@ export const EditSocials = <TFieldValues extends FieldValues>({ register, setVal
|
||||
|
||||
const initSelectedNetworks = networks.filter(el => !['', null, undefined].includes(el.url));
|
||||
const [selectedNetworks, setSelectedNetworks] = useState(initSelectedNetworks);
|
||||
|
||||
/**
|
||||
* Callback triggered when the user adds a network, from the list of available networks, to the editable networks.
|
||||
*/
|
||||
const selectNetwork = (network) => {
|
||||
setSelectedNetworks([...selectedNetworks, network]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a derivated state of the selected networks list, depending on the given action.
|
||||
*/
|
||||
const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case 'delete':
|
||||
|
@ -20,6 +20,9 @@ interface FabSocialsProps {
|
||||
onSuccess: (message: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the Fablab to edit its corporate social networks, or to display them read-only to the end users (show=true)
|
||||
*/
|
||||
export const FabSocials: React.FC<FabSocialsProps> = ({ show = false, onError, onSuccess }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
// regular expression to validate the the input fields
|
||||
@ -42,6 +45,9 @@ export const FabSocials: React.FC<FabSocialsProps> = ({ show = false, onError, o
|
||||
setSelectedNetworks(fabNetworks.filter(el => el.url !== ''));
|
||||
}, [fabNetworks]);
|
||||
|
||||
/**
|
||||
* Callback triggered when the social networks are saved
|
||||
*/
|
||||
const onSubmit = (data) => {
|
||||
const updatedNetworks = new Map<SettingName, string>();
|
||||
Object.keys(data).forEach(key => updatedNetworks.set(key as SettingName, data[key]));
|
||||
@ -55,17 +61,24 @@ export const FabSocials: React.FC<FabSocialsProps> = ({ show = false, onError, o
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback triggered when the user adds a network, from the list of available networks, to the editable networks.
|
||||
*/
|
||||
const selectNetwork = (network) => {
|
||||
setSelectedNetworks([...selectedNetworks, network]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback triggered when the user removes a network, from the list of editables networks, add put it back to the
|
||||
* list of avaiable networks.
|
||||
*/
|
||||
const remove = (network) => {
|
||||
setSelectedNetworks(selectedNetworks.filter(el => el !== network));
|
||||
setValue(network.name, '');
|
||||
};
|
||||
|
||||
return (
|
||||
<>{show
|
||||
<div className="fab-socials">{show
|
||||
? (selectedNetworks.length > 0) && <>
|
||||
<h2>{t('app.shared.fab_socials.follow_us')}</h2>
|
||||
<div className='social-icons'>
|
||||
@ -107,11 +120,11 @@ export const FabSocials: React.FC<FabSocialsProps> = ({ show = false, onError, o
|
||||
)}
|
||||
</div>}
|
||||
<FabButton type='submit'
|
||||
className='btn-warning'>
|
||||
className='save-btn'>
|
||||
{t('app.shared.buttons.save')}
|
||||
</FabButton>
|
||||
</form>
|
||||
}</>
|
||||
}</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { User } from '../../models/user';
|
||||
import { IApplication } from '../../models/application';
|
||||
import { react2angular } from 'react2angular';
|
||||
import MemberAPI from '../../api/member';
|
||||
import { TDateISO } from '../../typings/date-iso';
|
||||
|
||||
declare const Application: IApplication;
|
||||
|
||||
@ -34,7 +35,7 @@ export const UserValidation: React.FC<UserValidationProps> = ({ member, onSucces
|
||||
setValue(_value);
|
||||
const _member = _.clone(member);
|
||||
if (_value) {
|
||||
_member.validated_at = new Date();
|
||||
_member.validated_at = new Date().toISOString() as TDateISO;
|
||||
} else {
|
||||
_member.validated_at = null;
|
||||
}
|
||||
@ -49,8 +50,8 @@ export const UserValidation: React.FC<UserValidationProps> = ({ member, onSucces
|
||||
|
||||
return (
|
||||
<div className="user-validation">
|
||||
<label htmlFor="user-validation-switch" className="control-label m-r">{t('app.admin.members_edit.validate_account')}</label>
|
||||
<Switch checked={value} id="user-validation-switch" onChange={handleChanged} className="v-middle"></Switch>
|
||||
<label htmlFor="user-validation-switch">{t('app.admin.members_edit.validate_account')}</label>
|
||||
<Switch checked={value} id="user-validation-switch" onChange={handleChanged} className="switch"></Switch>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,13 +1,5 @@
|
||||
// from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054
|
||||
|
||||
interface Date {
|
||||
/**
|
||||
* Give a more precise return type to the method `toISOString()`:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
*/
|
||||
toISOString(): TDateISO;
|
||||
}
|
||||
|
||||
type TYear = `${number}${number}${number}${number}`;
|
||||
type TMonth = `${number}${number}`;
|
||||
type TDay = `${number}${number}`;
|
||||
|
@ -76,7 +76,10 @@
|
||||
@import "modules/profile-completion/completion-header-info";
|
||||
@import "modules/profile-completion/profile-form-option";
|
||||
@import "modules/select-gateway-modal";
|
||||
@import "modules/settings/boolean-setting";
|
||||
@import "modules/settings/check-list-setting";
|
||||
@import "modules/settings/user-validation-setting";
|
||||
@import "modules/socials/fab-socials";
|
||||
@import "modules/subscriptions/free-extend-modal";
|
||||
@import "modules/subscriptions/renew-modal";
|
||||
@import "modules/user/avatar";
|
||||
|
@ -39,7 +39,7 @@
|
||||
}
|
||||
|
||||
button { @include button(4rem); }
|
||||
.divider {
|
||||
.menu-divider {
|
||||
width: 2px;
|
||||
height: 2.4rem;
|
||||
background-color: var(--gray-soft-dark);
|
||||
|
@ -24,7 +24,7 @@
|
||||
left: 190px;
|
||||
z-index: 1;
|
||||
}
|
||||
.container {
|
||||
.payzen-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: inherit;
|
||||
|
@ -12,7 +12,7 @@
|
||||
left: 190px;
|
||||
z-index: 1;
|
||||
}
|
||||
.container {
|
||||
.payzen-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: inherit;
|
||||
|
@ -47,6 +47,8 @@
|
||||
.fa.fa-lock {
|
||||
top: 7px;
|
||||
color: #9edd78;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img {
|
||||
|
@ -5,6 +5,8 @@
|
||||
.fa.fa-lock {
|
||||
top: 7px;
|
||||
color: #9edd78;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img {
|
||||
|
@ -1,4 +1,10 @@
|
||||
.manage-plan-category {
|
||||
display: inline;
|
||||
margin-right: 5px;
|
||||
|
||||
.create-button {
|
||||
background-color: var(--secondary-dark);
|
||||
border-color: var(--secondary-dark);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,13 @@
|
||||
.content {
|
||||
padding: 15px;
|
||||
|
||||
.remaining-hours {
|
||||
.fab-alert {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-wrapper {
|
||||
text-align: center;
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
.boolean-setting {
|
||||
margin-bottom: 15px;
|
||||
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.switch {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.save-btn {
|
||||
background-color: var(--secondary-dark);
|
||||
border-color: var(--secondary-dark);
|
||||
color: var(--secondary-text-color);
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
.user-validation-setting {
|
||||
.save-btn {
|
||||
background-color: var(--secondary-dark);
|
||||
border-color: var(--secondary-dark);
|
||||
color: var(--secondary-text-color);
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
.fab-socials {
|
||||
.save-btn {
|
||||
background-color: var(--secondary-dark);
|
||||
border-color: var(--secondary-dark);
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
.user-validation {
|
||||
label {
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.switch {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
"@typescript-eslint/parser": "^5.17.0",
|
||||
"eslint": "~8.12.0",
|
||||
"eslint-config-standard": "~17.0.0-1",
|
||||
"eslint-plugin-fabmanager": "^0.4.2",
|
||||
"eslint-plugin-fabmanager": "^0.4.8",
|
||||
"eslint-plugin-html-erb": "^1.0.1",
|
||||
"eslint-plugin-import": "~2.25.4",
|
||||
"eslint-plugin-n": "^15.1.0",
|
||||
|
@ -4082,10 +4082,10 @@ eslint-plugin-es@^4.1.0:
|
||||
eslint-utils "^2.0.0"
|
||||
regexpp "^3.0.0"
|
||||
|
||||
eslint-plugin-fabmanager@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-fabmanager/-/eslint-plugin-fabmanager-0.4.2.tgz#87f18b13a29fe77dcbb9cb8c4a996b0b108f8a07"
|
||||
integrity sha512-3SKm4YXXzrgQYnaCmk0/QLh+2YaCSMAZFazC7fFB57BBo0PR70YMrGNoyiEW4oQ52qYNeIMwlFHHNPEgWfcwsw==
|
||||
eslint-plugin-fabmanager@^0.4.8:
|
||||
version "0.4.8"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-fabmanager/-/eslint-plugin-fabmanager-0.4.8.tgz#2104feddee06fa0245e64a3b8491412b17dcd16e"
|
||||
integrity sha512-Heey9vsr2WmRjY4JOskwWK8H2qgfR9nVX0osQyOb5bc+r6gQPci0Q0eECcN3pT9tXjLl2oL0oxWA5DFhleBi2A==
|
||||
dependencies:
|
||||
requireindex "^1.2.0"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user