From 4ecdf431d525739bddab3582398b26fe19d15834 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Fri, 18 Jun 2021 12:47:04 +0200 Subject: [PATCH] fix pending traning modal --- .../components/machines/machine-card.tsx | 10 ++-- .../machines/pending-training-modal.tsx | 12 +++- .../components/machines/reserve-button.tsx | 44 ++++++++++---- .../modules/machines/machine-card.scss | 57 +++++++++++-------- config/locales/app.logged.en.yml | 1 + 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/app/frontend/src/javascript/components/machines/machine-card.tsx b/app/frontend/src/javascript/components/machines/machine-card.tsx index bbbc68bb9..eb4320cd6 100644 --- a/app/frontend/src/javascript/components/machines/machine-card.tsx +++ b/app/frontend/src/javascript/components/machines/machine-card.tsx @@ -65,10 +65,12 @@ const MachineCardComponent: React.FC = ({ user, machine, onSho {t('app.public.machine_card.book')} } - + + + ); diff --git a/app/frontend/src/javascript/components/machines/pending-training-modal.tsx b/app/frontend/src/javascript/components/machines/pending-training-modal.tsx index 742e3b76a..6f4758998 100644 --- a/app/frontend/src/javascript/components/machines/pending-training-modal.tsx +++ b/app/frontend/src/javascript/components/machines/pending-training-modal.tsx @@ -1,7 +1,11 @@ import React from 'react'; +import moment from 'moment'; import { FabModal } from '../base/fab-modal'; import { useTranslation } from 'react-i18next'; import { HtmlTranslate } from '../base/html-translate'; +import { IFablab } from '../../models/fablab'; + +declare var Fablab: IFablab; interface PendingTrainingModalProps { isOpen: boolean, @@ -15,8 +19,10 @@ export const PendingTrainingModal: React.FC = ({ isOp /** * Return the formatted localized date for the given date */ - const formatDate = (date: Date): string => { - return Intl.DateTimeFormat().format(date); + const formatDateTime = (date: Date): string => { + const day = Intl.DateTimeFormat().format(moment(date).toDate()); + const time = Intl.DateTimeFormat(Fablab.intl_locale, { hour: 'numeric', minute: 'numeric' }).format(moment(date).toDate()); + return t('app.logged.pending_training_modal.DATE_TIME', { DATE: day, TIME:time }); } return ( @@ -25,7 +31,7 @@ export const PendingTrainingModal: React.FC = ({ isOp toggleModal={toggleModal} closeButton={true}>

{t('app.logged.pending_training_modal.wait_for_validated')}

-

+

) } diff --git a/app/frontend/src/javascript/components/machines/reserve-button.tsx b/app/frontend/src/javascript/components/machines/reserve-button.tsx index f39b46376..e4a85ad8d 100644 --- a/app/frontend/src/javascript/components/machines/reserve-button.tsx +++ b/app/frontend/src/javascript/components/machines/reserve-button.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { BaseSyntheticEvent, useState } from 'react'; import { PendingTrainingModal } from './pending-training-modal'; import MachineAPI from '../../api/machine'; import { Machine } from '../../models/machine'; @@ -20,17 +20,27 @@ interface ReserveButtonProps { */ export const ReserveButton: React.FC = ({ currentUser, machineId, onLoginRequested, onLoadingStart, onLoadingEnd, onError, onReserveMachine, className, children }) => { + const [machine, setMachine] = useState(null); const [pendingTraining, setPendingTraining] = useState(false); /** * Callback triggered when the user clicks on the 'reserve' button. - * We load the full machine data, then we check if the user has passed the training for it (if it's needed) */ - const handleClick = (user?: User): void => { + const handleClick = (event: BaseSyntheticEvent): void => { + event.preventDefault(); + getMachine(currentUser); + }; + + /** + * We load the full machine data, including data on the current user status for this machine. + * Then we check if the user has passed the training for it (if it's needed) + */ + const getMachine = (user: User): void => { if (onLoadingStart) onLoadingStart(); MachineAPI.get(machineId) .then(data => { + setMachine(data); checkTraining(data, user); if (onLoadingEnd) onLoadingEnd(); }) @@ -38,7 +48,14 @@ export const ReserveButton: React.FC = ({ currentUser, machi onError(error); if (onLoadingEnd) onLoadingEnd(); }); - } + }; + + /** + * Open/closes the alert modal informing the user about his pending training + */ + const togglePendingTrainingModal = (): void => { + setPendingTraining(!pendingTraining); + }; /** * Check that the current user has passed the required training before allowing him to book @@ -47,7 +64,7 @@ export const ReserveButton: React.FC = ({ currentUser, machi // if there's no user currently logged, trigger the logging process if (!user) { onLoginRequested() - .then(user => handleClick(user)) + .then(user => getMachine(user)) .catch(error => onError(error)); return; } @@ -58,17 +75,22 @@ export const ReserveButton: React.FC = ({ currentUser, machi return onReserveMachine(machineId); } - // if a user is authenticated and have booked a training for this machine, tell him that he must wait + // if there's an authenticated user, and he booked a training for this machine, tell him that he must wait // for an admin to validate the training before he can book the reservation if (machine.current_user_next_training_reservation) { return setPendingTraining(true); } - } + }; return ( - + + + + + ); } diff --git a/app/frontend/src/stylesheets/modules/machines/machine-card.scss b/app/frontend/src/stylesheets/modules/machines/machine-card.scss index 1a1c22e24..5b7dcdd7e 100644 --- a/app/frontend/src/stylesheets/modules/machines/machine-card.scss +++ b/app/frontend/src/stylesheets/modules/machines/machine-card.scss @@ -17,6 +17,7 @@ background: rgba(29, 29, 29, 0.5); border-radius: 6px; margin: -1px; + z-index: 1; } &.loading::after { @@ -25,9 +26,9 @@ text-align: center; font-weight: 900; position: absolute; - left: 41%; + width: 100%; font-size: 4em; - top: 35%; + top: 110px; color: white; animation: spin 2s linear infinite; } @@ -83,7 +84,10 @@ font-weight: 600; color: #000; margin: 0; - line-height: 1.8rem; + height: 4em; + display: flex; + justify-content: center; + align-items: center; } .machine-actions { @@ -95,31 +99,36 @@ text-align: center; display: flex; - & > button { - border: none !important; - padding: 15px 12px; - display: block; + & > span { width: 50%; - background-color: #fbfbfb; - margin-bottom: 0; - font-weight: normal; - text-align: center; - white-space: nowrap; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; - font-size: 16px; - line-height: 1.5; - border-radius: 4px; - & > i { - margin-right: 5px; + & > button { + border: none !important; + padding: 15px 12px; + display: block; + width: 100%; + background-color: #fbfbfb; + margin-bottom: 0; + font-weight: normal; + text-align: center; + white-space: nowrap; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + background-image: none; + font-size: 16px; + line-height: 1.5; + border-radius: 4px; + + & > i { + margin-right: 5px; + } + + &.reserve-button { + border-right: 1px solid #dddddd !important; + } } - &.reserve-button { - border-right: 1px solid #dddddd !important; - } } } diff --git a/config/locales/app.logged.en.yml b/config/locales/app.logged.en.yml index 920ba7bd2..1da8edfe1 100644 --- a/config/locales/app.logged.en.yml +++ b/config/locales/app.logged.en.yml @@ -170,6 +170,7 @@ en: machine_reservation: "Machine reservation" wait_for_validated: "You must wait for your training is being validated by the FabLab team to book this machine." training_will_occur_DATE_html: "Your training will occur at {DATE}" + DATE_TIME: "{DATE} {TIME}" #book a training trainings_reserve: trainings_planning: "Trainings planning"