2021-06-16 18:03:06 +02:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import { Machine } from '../../models/machine';
|
|
|
|
import { IApplication } from '../../models/application';
|
|
|
|
import { react2angular } from 'react2angular';
|
|
|
|
import { Loader } from '../base/loader';
|
|
|
|
import MachineAPI from '../../api/machine';
|
|
|
|
import { MachineCard } from './machine-card';
|
2021-06-17 10:25:13 +02:00
|
|
|
import { MachinesFilters } from './machines-filters';
|
2021-06-17 17:08:22 +02:00
|
|
|
import { User } from '../../models/user';
|
2022-08-25 18:46:55 +02:00
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { FabButton } from '../base/fab-button';
|
2021-06-16 18:03:06 +02:00
|
|
|
|
2021-07-01 12:34:10 +02:00
|
|
|
declare const Application: IApplication;
|
2021-06-16 18:03:06 +02:00
|
|
|
|
|
|
|
interface MachinesListProps {
|
2021-06-17 17:08:22 +02:00
|
|
|
user?: User,
|
2021-06-16 18:03:06 +02:00
|
|
|
onError: (message: string) => void,
|
2021-06-28 18:17:11 +02:00
|
|
|
onSuccess: (message: string) => void,
|
2021-06-16 18:03:06 +02:00
|
|
|
onShowMachine: (machine: Machine) => void,
|
|
|
|
onReserveMachine: (machine: Machine) => void,
|
2021-06-17 17:08:22 +02:00
|
|
|
onLoginRequested: () => Promise<User>,
|
2021-06-18 16:05:36 +02:00
|
|
|
onEnrollRequested: (trainingId: number) => void,
|
2022-03-18 19:44:30 +01:00
|
|
|
canProposePacks: boolean,
|
2021-06-16 18:03:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This component shows a list of all machines and allows filtering on that list.
|
|
|
|
*/
|
2022-06-01 15:24:25 +02:00
|
|
|
export const MachinesList: React.FC<MachinesListProps> = ({ onError, onSuccess, onShowMachine, onReserveMachine, onLoginRequested, onEnrollRequested, user, canProposePacks }) => {
|
2022-08-25 18:46:55 +02:00
|
|
|
const { t } = useTranslation('public');
|
2021-06-17 10:25:13 +02:00
|
|
|
// shown machines
|
2021-06-16 18:03:06 +02:00
|
|
|
const [machines, setMachines] = useState<Array<Machine>>(null);
|
2021-06-17 10:25:13 +02:00
|
|
|
// we keep the full list of machines, for filtering
|
|
|
|
const [allMachines, setAllMachines] = useState<Array<Machine>>(null);
|
2021-06-16 18:03:06 +02:00
|
|
|
|
2021-06-17 10:25:13 +02:00
|
|
|
// retrieve the full list of machines on component mount
|
2021-06-16 18:03:06 +02:00
|
|
|
useEffect(() => {
|
|
|
|
MachineAPI.index()
|
2021-06-17 10:25:13 +02:00
|
|
|
.then(data => setAllMachines(data))
|
2021-06-16 18:03:06 +02:00
|
|
|
.catch(e => onError(e));
|
|
|
|
}, []);
|
|
|
|
|
2021-06-17 10:25:13 +02:00
|
|
|
// filter the machines shown when the full list was retrieved
|
|
|
|
useEffect(() => {
|
|
|
|
handleFilterByStatus(true);
|
2021-07-01 12:34:10 +02:00
|
|
|
}, [allMachines]);
|
2021-06-17 10:25:13 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when the user changes the status filter.
|
|
|
|
* Set the 'machines' state to a filtered list, depending on the provided parameter.
|
2021-06-18 11:51:26 +02:00
|
|
|
* @param status, true = enabled machines, false = disabled machines, null = all machines
|
2021-06-17 10:25:13 +02:00
|
|
|
*/
|
|
|
|
const handleFilterByStatus = (status: boolean): void => {
|
|
|
|
if (!allMachines) return;
|
|
|
|
if (status === null) return setMachines(allMachines);
|
|
|
|
|
2021-06-18 11:51:26 +02:00
|
|
|
// enabled machines may have the m.disabled property null (for never disabled machines)
|
|
|
|
// or false (for re-enabled machines)
|
|
|
|
setMachines(allMachines.filter(m => !!m.disabled === !status));
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-17 10:25:13 +02:00
|
|
|
|
2022-08-25 18:46:55 +02:00
|
|
|
/**
|
|
|
|
* Go to store
|
|
|
|
*/
|
|
|
|
const linkToStore = (): void => {
|
|
|
|
window.location.href = '/#!/store';
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO: Conditionally display the store ad
|
2021-06-16 18:03:06 +02:00
|
|
|
return (
|
|
|
|
<div className="machines-list">
|
2021-06-17 10:25:13 +02:00
|
|
|
<MachinesFilters onStatusSelected={handleFilterByStatus} />
|
|
|
|
<div className="all-machines">
|
2022-08-25 18:46:55 +02:00
|
|
|
{false &&
|
|
|
|
<div className='store-ad' onClick={() => linkToStore}>
|
|
|
|
<div className='content'>
|
|
|
|
<h3>{t('app.public.machines_list.store_ad.title')}</h3>
|
|
|
|
<p>{t('app.public.machines_list.store_ad.buy')}</p>
|
|
|
|
<p className='sell'>{t('app.public.machines_list.store_ad.sell')}</p>
|
|
|
|
</div>
|
|
|
|
<FabButton icon={<i className="fa fa-cart-plus fa-lg" />} className="cta" onClick={linkToStore}>
|
|
|
|
{t('app.public.machines_list.store_ad.link')}
|
|
|
|
</FabButton>
|
|
|
|
</div>
|
|
|
|
}
|
2021-06-17 10:25:13 +02:00
|
|
|
{machines && machines.map(machine => {
|
2021-06-17 17:08:22 +02:00
|
|
|
return <MachineCard key={machine.id}
|
2021-07-01 12:34:10 +02:00
|
|
|
user={user}
|
|
|
|
machine={machine}
|
|
|
|
onShowMachine={onShowMachine}
|
|
|
|
onReserveMachine={onReserveMachine}
|
|
|
|
onError={onError}
|
|
|
|
onSuccess={onSuccess}
|
|
|
|
onLoginRequested={onLoginRequested}
|
2022-03-18 19:44:30 +01:00
|
|
|
onEnrollRequested={onEnrollRequested}
|
|
|
|
canProposePacks={canProposePacks}/>;
|
2021-06-17 10:25:13 +02:00
|
|
|
})}
|
|
|
|
</div>
|
2021-06-16 18:03:06 +02:00
|
|
|
</div>
|
|
|
|
);
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-16 18:03:06 +02:00
|
|
|
|
2022-10-28 17:13:41 +02:00
|
|
|
const MachinesListWrapper: React.FC<MachinesListProps> = (props) => {
|
2021-06-16 18:03:06 +02:00
|
|
|
return (
|
|
|
|
<Loader>
|
2022-10-28 17:13:41 +02:00
|
|
|
<MachinesList {...props} />
|
2021-06-16 18:03:06 +02:00
|
|
|
</Loader>
|
|
|
|
);
|
2021-07-01 12:34:10 +02:00
|
|
|
};
|
2021-06-16 18:03:06 +02:00
|
|
|
|
2022-03-18 19:44:30 +01:00
|
|
|
Application.Components.component('machinesList', react2angular(MachinesListWrapper, ['user', 'onError', 'onSuccess', 'onShowMachine', 'onReserveMachine', 'onLoginRequested', 'onEnrollRequested', 'canProposePacks']));
|