mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-22 11:52:21 +01:00
(feat) admin can refuse child's supporting document file
This commit is contained in:
parent
f1d3fdf2de
commit
42946effe0
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { useForm, useWatch } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import moment from 'moment';
|
||||
@ -9,25 +9,32 @@ import { FormFileUpload } from '../form/form-file-upload';
|
||||
import { FileType } from '../../models/file';
|
||||
import { SupportingDocumentType } from '../../models/supporting-document-type';
|
||||
import { User } from '../../models/user';
|
||||
import { SupportingDocumentsRefusalModal } from '../supporting-documents/supporting-documents-refusal-modal';
|
||||
|
||||
interface ChildFormProps {
|
||||
child: Child;
|
||||
operator: User;
|
||||
onSubmit: (data: Child) => void;
|
||||
supportingDocumentsTypes: Array<SupportingDocumentType>;
|
||||
onSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
}
|
||||
|
||||
/**
|
||||
* A form for creating or editing a child.
|
||||
*/
|
||||
export const ChildForm: React.FC<ChildFormProps> = ({ child, onSubmit, supportingDocumentsTypes, operator }) => {
|
||||
export const ChildForm: React.FC<ChildFormProps> = ({ child, onSubmit, supportingDocumentsTypes, operator, onSuccess, onError }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
const { register, formState, handleSubmit, setValue, control } = useForm<Child>({
|
||||
defaultValues: child
|
||||
});
|
||||
const output = useWatch<Child>({ control }); // eslint-disable-line
|
||||
const [refuseModalIsOpen, setRefuseModalIsOpen] = useState<boolean>(false);
|
||||
|
||||
/**
|
||||
* get the name of the supporting document type by id
|
||||
*/
|
||||
const getSupportingDocumentsTypeName = (id: number): string => {
|
||||
const supportingDocumentType = supportingDocumentsTypes.find((supportingDocumentType) => supportingDocumentType.id === id);
|
||||
return supportingDocumentType ? supportingDocumentType.name : '';
|
||||
@ -40,9 +47,24 @@ export const ChildForm: React.FC<ChildFormProps> = ({ child, onSubmit, supportin
|
||||
return (operator?.role === 'admin' || operator?.role === 'manager');
|
||||
};
|
||||
|
||||
/**
|
||||
* Open/closes the modal dialog to refuse the documents
|
||||
*/
|
||||
const toggleRefuseModal = (): void => {
|
||||
setRefuseModalIsOpen(!refuseModalIsOpen);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback triggered when the refusal was successfully saved
|
||||
*/
|
||||
const onSaveRefusalSuccess = (message: string): void => {
|
||||
setRefuseModalIsOpen(false);
|
||||
onSuccess(message);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="child-form">
|
||||
{isPrivileged() &&
|
||||
{!isPrivileged() &&
|
||||
<div className="info-area">
|
||||
{t('app.public.child_form.child_form_info')}
|
||||
</div>
|
||||
@ -113,6 +135,20 @@ export const ChildForm: React.FC<ChildFormProps> = ({ child, onSubmit, supportin
|
||||
<FabButton type="button" onClick={handleSubmit(onSubmit)}>
|
||||
{t('app.public.child_form.save')}
|
||||
</FabButton>
|
||||
{isPrivileged() &&
|
||||
<div>
|
||||
<FabButton className="refuse-btn" onClick={toggleRefuseModal}>{t('app.public.child_form.refuse_documents')}</FabButton>
|
||||
<SupportingDocumentsRefusalModal
|
||||
isOpen={refuseModalIsOpen}
|
||||
proofOfIdentityTypes={supportingDocumentsTypes}
|
||||
toggleModal={toggleRefuseModal}
|
||||
operator={operator}
|
||||
supportable={child}
|
||||
documentType="Child"
|
||||
onError={onError}
|
||||
onSuccess={onSaveRefusalSuccess} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@ interface ChildModalProps {
|
||||
operator: User;
|
||||
isOpen: boolean;
|
||||
toggleModal: () => void;
|
||||
onSuccess: (child: Child, msg: string) => void;
|
||||
onSuccess: (msg: string) => void;
|
||||
onError: (error: string) => void;
|
||||
supportingDocumentsTypes: Array<SupportingDocumentType>;
|
||||
}
|
||||
@ -35,7 +35,7 @@ export const ChildModal: React.FC<ChildModalProps> = ({ child, isOpen, toggleMod
|
||||
await ChildAPI.create(data);
|
||||
}
|
||||
toggleModal();
|
||||
onSuccess(data, '');
|
||||
onSuccess('');
|
||||
} catch (error) {
|
||||
onError(error);
|
||||
}
|
||||
@ -51,7 +51,14 @@ export const ChildModal: React.FC<ChildModalProps> = ({ child, isOpen, toggleMod
|
||||
{(operator?.role === 'admin' || operator?.role === 'manager') &&
|
||||
<ChildValidation child={child} onSuccess={onSuccess} onError={onError} />
|
||||
}
|
||||
<ChildForm child={child} onSubmit={handleSaveChild} supportingDocumentsTypes={supportingDocumentsTypes} operator={operator}/>
|
||||
<ChildForm
|
||||
child={child}
|
||||
onSubmit={handleSaveChild}
|
||||
supportingDocumentsTypes={supportingDocumentsTypes}
|
||||
operator={operator}
|
||||
onSuccess={onSuccess}
|
||||
onError={onError}
|
||||
/>
|
||||
</FabModal>
|
||||
);
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ import { TDateISO } from '../../typings/date-iso';
|
||||
|
||||
interface ChildValidationProps {
|
||||
child: Child
|
||||
onSuccess: (child: Child, message: string) => void,
|
||||
onSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
}
|
||||
|
||||
@ -37,8 +37,8 @@ export const ChildValidation: React.FC<ChildValidationProps> = ({ child, onSucce
|
||||
_child.validated_at = null;
|
||||
}
|
||||
ChildAPI.validate(_child)
|
||||
.then((child: Child) => {
|
||||
onSuccess(child, t(`app.admin.child_validation.${_value ? 'validate' : 'invalidate'}_child_success`));
|
||||
.then(() => {
|
||||
onSuccess(t(`app.admin.child_validation.${_value ? 'validate' : 'invalidate'}_child_success`));
|
||||
}).catch(err => {
|
||||
setValue(!_value);
|
||||
onError(t(`app.admin.child_validation.${_value ? 'validate' : 'invalidate'}_child_error`) + err);
|
||||
|
@ -78,7 +78,7 @@ export const ChildrenList: React.FC<ChildrenListProps> = ({ user, operator, onEr
|
||||
/**
|
||||
* Handle save child success from the API
|
||||
*/
|
||||
const handleSaveChildSuccess = (_child: Child, msg: string) => {
|
||||
const handleSaveChildSuccess = (msg: string) => {
|
||||
ChildAPI.index({ user_id: user.id }).then(setChildren);
|
||||
if (msg) {
|
||||
onSuccess(msg);
|
||||
|
@ -5,6 +5,7 @@ import { FabModal } from '../base/fab-modal';
|
||||
import { SupportingDocumentType } from '../../models/supporting-document-type';
|
||||
import { SupportingDocumentRefusal } from '../../models/supporting-document-refusal';
|
||||
import { User } from '../../models/user';
|
||||
import { Child } from '../../models/child';
|
||||
import SupportingDocumentRefusalAPI from '../../api/supporting-document-refusal';
|
||||
import { SupportingDocumentsRefusalForm } from './supporting-documents-refusal-form';
|
||||
|
||||
@ -15,20 +16,21 @@ interface SupportingDocumentsRefusalModalProps {
|
||||
onError: (message: string) => void,
|
||||
proofOfIdentityTypes: Array<SupportingDocumentType>,
|
||||
operator: User,
|
||||
member: User
|
||||
supportable: User | Child,
|
||||
documentType: 'User' | 'Child',
|
||||
}
|
||||
|
||||
/**
|
||||
* Modal dialog to notify the member that his documents are refused
|
||||
*/
|
||||
export const SupportingDocumentsRefusalModal: React.FC<SupportingDocumentsRefusalModalProps> = ({ isOpen, toggleModal, onSuccess, proofOfIdentityTypes, operator, member, onError }) => {
|
||||
export const SupportingDocumentsRefusalModal: React.FC<SupportingDocumentsRefusalModalProps> = ({ isOpen, toggleModal, onSuccess, proofOfIdentityTypes, operator, supportable, onError, documentType }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [data, setData] = useState<SupportingDocumentRefusal>({
|
||||
id: null,
|
||||
operator_id: operator.id,
|
||||
supportable_id: member.id,
|
||||
supportable_type: 'User',
|
||||
supportable_id: supportable.id,
|
||||
supportable_type: documentType,
|
||||
supporting_document_type_ids: [],
|
||||
message: ''
|
||||
});
|
||||
|
@ -19,6 +19,7 @@ declare const Application: IApplication;
|
||||
interface SupportingDocumentsValidationProps {
|
||||
operator: User,
|
||||
member: User
|
||||
documentType: 'User' | 'Child',
|
||||
onSuccess: (message: string) => void,
|
||||
onError: (message: string) => void,
|
||||
}
|
||||
@ -26,7 +27,7 @@ interface SupportingDocumentsValidationProps {
|
||||
/**
|
||||
* This component shows a list of supporting documents file of member, admin can download and valid
|
||||
**/
|
||||
const SupportingDocumentsValidation: React.FC<SupportingDocumentsValidationProps> = ({ operator, member, onSuccess, onError }) => {
|
||||
const SupportingDocumentsValidation: React.FC<SupportingDocumentsValidationProps> = ({ operator, member, onSuccess, onError, documentType }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
// list of supporting documents type
|
||||
@ -112,7 +113,8 @@ const SupportingDocumentsValidation: React.FC<SupportingDocumentsValidationProps
|
||||
proofOfIdentityTypes={documentsTypes}
|
||||
toggleModal={toggleModal}
|
||||
operator={operator}
|
||||
member={member}
|
||||
supportable={member}
|
||||
documentType={documentType}
|
||||
onError={onError}
|
||||
onSuccess={onSaveRefusalSuccess}/>
|
||||
</FabPanel>
|
||||
@ -131,4 +133,4 @@ const SupportingDocumentsValidationWrapper: React.FC<SupportingDocumentsValidati
|
||||
|
||||
export { SupportingDocumentsValidationWrapper as SupportingDocumentsValidation };
|
||||
|
||||
Application.Components.component('supportingDocumentsValidation', react2angular(SupportingDocumentsValidationWrapper, ['operator', 'member', 'onSuccess', 'onError']));
|
||||
Application.Components.component('supportingDocumentsValidation', react2angular(SupportingDocumentsValidationWrapper, ['operator', 'member', 'onSuccess', 'onError', 'documentType']));
|
||||
|
@ -70,6 +70,7 @@
|
||||
<supporting-documents-validation
|
||||
operator="currentUser"
|
||||
member="user"
|
||||
document-type="User"
|
||||
on-error="onError"
|
||||
on-success="onSuccess" />
|
||||
</uib-tab>
|
||||
|
@ -17,4 +17,8 @@ class Child < ApplicationRecord
|
||||
def validate_age
|
||||
errors.add(:birthday, I18n.t('.errors.messages.birthday_less_than_18_years_ago')) if birthday.blank? || birthday > 18.years.ago
|
||||
end
|
||||
|
||||
def full_name
|
||||
"#{(first_name || '').humanize.titleize} #{(last_name || '').humanize.titleize}"
|
||||
end
|
||||
end
|
||||
|
@ -14,13 +14,23 @@ class SupportingDocumentRefusalService
|
||||
def self.create(supporting_document_refusal)
|
||||
saved = supporting_document_refusal.save
|
||||
|
||||
if saved && supporting_document_refusal.supportable_type == 'User'
|
||||
if saved
|
||||
case supporting_document_refusal.supportable_type
|
||||
when 'User'
|
||||
NotificationCenter.call type: 'notify_admin_user_supporting_document_refusal',
|
||||
receiver: User.admins_and_managers,
|
||||
attached_object: supporting_document_refusal
|
||||
NotificationCenter.call type: 'notify_user_supporting_document_refusal',
|
||||
receiver: supporting_document_refusal.supportable,
|
||||
attached_object: supporting_document_refusal
|
||||
when 'Child'
|
||||
NotificationCenter.call type: 'notify_admin_user_child_supporting_document_refusal',
|
||||
receiver: User.admins_and_managers,
|
||||
attached_object: SupportingDocumentRefusal.last
|
||||
NotificationCenter.call type: 'notify_user_child_supporting_document_refusal',
|
||||
receiver: SupportingDocumentRefusal.last.supportable.user,
|
||||
attached_object: SupportingDocumentRefusal.last
|
||||
end
|
||||
end
|
||||
saved
|
||||
end
|
||||
|
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
json.description t('.refusal',
|
||||
NAME: notification.attached_object&.supportable&.full_name || t('api.notifications.deleted_user'))
|
@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
json.description t('.refusal')
|
@ -0,0 +1,15 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= t('.body.user_child_supporting_document_files_refusal',
|
||||
NAME: @attached_object&.supportable&.full_name || t('api.notifications.deleted_user'),
|
||||
OPERATOR: @attached_object&.operator&.profile&.full_name || t('api.notifications.deleted_user')) %>
|
||||
</p>
|
||||
<ul>
|
||||
<% @attached_object.supporting_document_types.each do |type| %>
|
||||
<li><%= type.name %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p>
|
||||
<%= @attached_object.message %>
|
||||
</p>
|
@ -0,0 +1,16 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= t('.body.user_child_supporting_document_files_refusal') %>
|
||||
</p>
|
||||
<ul>
|
||||
<% @attached_object.supporting_document_types.each do |type| %>
|
||||
<li><%= type.name %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p>
|
||||
<%= @attached_object.message %>
|
||||
</p>
|
||||
<p>
|
||||
<%= t('.body.action') %>
|
||||
</p>
|
@ -291,6 +291,7 @@ en:
|
||||
notify_admin_import_complete: "An import is done"
|
||||
notify_admin_user_group_changed: "A user has changed his group"
|
||||
notify_admin_user_supporting_document_refusal: "A supporting document has been rejected"
|
||||
notify_admin_user_child_supporting_document_refusal: "A supporting document of child has been rejected"
|
||||
notify_admin_user_supporting_document_files_created: "A user has uploaded a supporting document"
|
||||
notify_admin_user_supporting_document_files_updated: "A user has updated a supporting document"
|
||||
notify_admin_member_create_reservation: "A member books a reservation"
|
||||
|
@ -291,6 +291,7 @@ fr:
|
||||
notify_admin_import_complete: "Un import est terminé"
|
||||
notify_admin_user_group_changed: "Un utilisateur a changé de groupe"
|
||||
notify_admin_user_supporting_document_refusal: "Un justificatif a été refusé"
|
||||
notify_admin_user_child_supporting_document_refusal: "Un justificatif de l'enfant a été refusé"
|
||||
notify_admin_user_supporting_document_files_created: "Un utilisateur a téléversé un justificatif"
|
||||
notify_admin_user_supporting_document_files_updated: "Un utilisateur a mis à jour un justificatif"
|
||||
notify_admin_member_create_reservation: "Un membre fait une réservation"
|
||||
|
@ -492,6 +492,7 @@ en:
|
||||
phone: "Phone"
|
||||
save: "Save"
|
||||
to_complete: "To complete"
|
||||
refuse_documents: "Refusing the documents"
|
||||
child_item:
|
||||
first_name: "First name of the child"
|
||||
last_name: "Last name of the child"
|
||||
|
@ -492,6 +492,7 @@ fr:
|
||||
phone: "Téléphone"
|
||||
save: "Enregistrer"
|
||||
to_complete: "À compléter"
|
||||
refuse_documents: "Refuser les documents"
|
||||
child_item:
|
||||
first_name: "Prénom de l'enfant"
|
||||
last_name: "Nom de l'enfant"
|
||||
|
@ -449,6 +449,10 @@ en:
|
||||
refusal: "Your supporting documents were refused"
|
||||
notify_admin_user_supporting_document_refusal:
|
||||
refusal: "Member's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||
notify_user_child_supporting_document_refusal:
|
||||
refusal: "Your child's supporting documents were refused"
|
||||
notify_admin_user_child_supporting_document_refusal:
|
||||
refusal: "Child's supporting document <strong><em>%{NAME}</strong></em> was refused."
|
||||
notify_user_order_is_ready:
|
||||
order_ready: "Your command %{REFERENCE} is ready"
|
||||
notify_user_order_is_canceled:
|
||||
|
@ -449,6 +449,10 @@ fr:
|
||||
refusal: "Vos pièces justificatives ont été refusées"
|
||||
notify_admin_user_supporting_document_refusal:
|
||||
refusal: "Le justificatif du membre <strong><em>%{NAME}</strong></em> a été refusé."
|
||||
notify_user_child_supporting_document_refusal:
|
||||
refusal: "Vos pièces justificatives de l'enfant ont été refusées"
|
||||
notify_admin_user_child_supporting_document_refusal:
|
||||
refusal: "Le justificatif de l'enfant <strong><em>%{NAME}</strong></em> a été refusé."
|
||||
notify_user_order_is_ready:
|
||||
order_ready: "Votre commande %{REFERENCE} est prête"
|
||||
notify_user_order_is_canceled:
|
||||
|
@ -406,6 +406,15 @@ en:
|
||||
subject: "A member's supporting documents were refused"
|
||||
body:
|
||||
user_supporting_document_files_refusal: "Member %{NAME}'s supporting documents were rejected by %{OPERATOR}:"
|
||||
notify_user_child_supporting_document_refusal:
|
||||
subject: "Your child's supporting documents were refused"
|
||||
body:
|
||||
user_child_supporting_document_files_refusal: "Your supporting documents were refused:"
|
||||
action: "Please re-upload some new supporting documents."
|
||||
notify_admin_user_child_supporting_document_refusal:
|
||||
subject: "A child's supporting documents were refused"
|
||||
body:
|
||||
user_child_supporting_document_files_refusal: "Child %{NAME}'s supporting documents were rejected by %{OPERATOR}:"
|
||||
shared:
|
||||
hello: "Hello %{user_name}"
|
||||
notify_user_order_is_ready:
|
||||
|
@ -406,6 +406,15 @@ fr:
|
||||
subject: "Les justificatifs d'un membre ont été refusés"
|
||||
body:
|
||||
user_supporting_document_files_refusal: "Le justificatif du membre %{NAME} a été refusé par %{OPERATOR} :"
|
||||
notify_user_child_supporting_document_refusal:
|
||||
subject: "Vos pièces justificatives de l'enfant ont été refusées"
|
||||
body:
|
||||
user_child_supporting_document_files_refusal: "Vos pièces justificatives ont été refusées :"
|
||||
action: "Veuillez téléverser de nouvelles pièces justificatives."
|
||||
notify_admin_user_child_supporting_document_refusal:
|
||||
subject: "Les justificatifs d'un enfant ont été refusés"
|
||||
body:
|
||||
user_child_supporting_document_files_refusal: "Le justificatif de l'enfant %{NAME} a été refusé par %{OPERATOR} :"
|
||||
shared:
|
||||
hello: "Bonjour %{user_name}"
|
||||
notify_user_order_is_ready:
|
||||
|
@ -31,3 +31,19 @@ unless NotificationType.find_by(name: 'notify_member_reservation_limit_reached')
|
||||
is_configurable: false
|
||||
)
|
||||
end
|
||||
|
||||
unless NotificationType.find_by(name: 'notify_admin_user_child_supporting_document_refusal')
|
||||
NotificationType.create!(
|
||||
name: 'notify_admin_user_child_supporting_document_refusal',
|
||||
category: 'supporting_documents',
|
||||
is_configurable: true
|
||||
)
|
||||
end
|
||||
|
||||
unless NotificationType.find_by(name: 'notify_user_child_supporting_document_refusal')
|
||||
NotificationType.create!(
|
||||
name: 'notify_user_child_supporting_document_refusal',
|
||||
category: 'supporting_documents',
|
||||
is_configurable: false
|
||||
)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user