mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
WIP: migrate machines list to react
This commit is contained in:
parent
7fa89c826a
commit
565002a124
11
app/frontend/src/javascript/api/machine.ts
Normal file
11
app/frontend/src/javascript/api/machine.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import apiClient from './clients/api-client';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { Machine } from '../models/machine';
|
||||
|
||||
export default class MachineAPI {
|
||||
static async index (): Promise<Array<Machine>> {
|
||||
const res: AxiosResponse<Array<Machine>> = await apiClient.get(`/api/machines`);
|
||||
return res?.data;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,70 @@
|
||||
import React from 'react';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Machine } from '../../models/machine';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Loader } from '../base/loader';
|
||||
|
||||
interface MachineCardProps {
|
||||
machine: Machine
|
||||
machine: Machine,
|
||||
onShowMachine: (machine: Machine) => void,
|
||||
onReserveMachine: (machine: Machine) => void,
|
||||
}
|
||||
|
||||
/**
|
||||
* This component is a box showing the picture of the given machine and two buttons: one to start the reservation process
|
||||
* and another to redirect the user to the machine description page.
|
||||
*/
|
||||
const MachineCard: React.FC<MachineCardProps> = ({ machine }) => {
|
||||
const MachineCardComponent: React.FC<MachineCardProps> = ({ machine, onShowMachine, onReserveMachine }) => {
|
||||
const { t } = useTranslation('public');
|
||||
|
||||
const machinePicture = (): ReactNode => {
|
||||
if (!machine.machine_image) {
|
||||
return (
|
||||
<div className="machine-picture">
|
||||
<img src="data:image/png;base64,"
|
||||
data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon"
|
||||
className="img-responsive"
|
||||
alt={machine.name} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="machine-picture" style={{ backgroundImage: `url(${machine.machine_image})` }} onClick={handleShowMachine} />
|
||||
)
|
||||
}
|
||||
|
||||
const handleReserveMachine = (): void => {
|
||||
onReserveMachine(machine);
|
||||
}
|
||||
|
||||
const handleShowMachine = (): void => {
|
||||
onShowMachine(machine);
|
||||
}
|
||||
return (
|
||||
<div/>
|
||||
)
|
||||
<div className="machine-card">
|
||||
{machinePicture()}
|
||||
<div className="machine-name">
|
||||
{machine.name}
|
||||
</div>
|
||||
<div className="machine-actions">
|
||||
{!machine.disabled && <button onClick={handleReserveMachine} className="reserve-button">
|
||||
<i className="fas fa-bookmark" />
|
||||
{t('app.public.machine_card.book')}
|
||||
</button>}
|
||||
<button onClick={handleShowMachine} className={`show-button ${machine.disabled ? 'single-button': ''}`}>
|
||||
<i className="fas fa-eye" />
|
||||
{t('app.public.machine_card.consult')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export const MachineCard: React.FC<MachineCardProps> = ({ machine, onShowMachine, onReserveMachine }) => {
|
||||
return (
|
||||
<Loader>
|
||||
<MachineCardComponent machine={machine} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} />
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
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';
|
||||
|
||||
declare var Application: IApplication;
|
||||
|
||||
interface MachinesListProps {
|
||||
onError: (message: string) => void,
|
||||
onShowMachine: (machine: Machine) => void,
|
||||
onReserveMachine: (machine: Machine) => void,
|
||||
}
|
||||
|
||||
/**
|
||||
* This component shows a list of all machines and allows filtering on that list.
|
||||
*/
|
||||
const MachinesList: React.FC<MachinesListProps> = ({ onError, onShowMachine, onReserveMachine }) => {
|
||||
const [machines, setMachines] = useState<Array<Machine>>(null);
|
||||
|
||||
useEffect(() => {
|
||||
MachineAPI.index()
|
||||
.then(data => setMachines(data))
|
||||
.catch(e => onError(e));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="machines-list">
|
||||
{machines && machines.map(machine => {
|
||||
return <MachineCard machine={machine} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} />
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const MachinesListWrapper: React.FC<MachinesListProps> = ({ onError, onShowMachine, onReserveMachine }) => {
|
||||
return (
|
||||
<Loader>
|
||||
<MachinesList onError={onError} onShowMachine={onShowMachine} onReserveMachine={onReserveMachine} />
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('machinesList', react2angular(MachinesListWrapper, ['onError', 'onShowMachine', 'onReserveMachine']));
|
@ -50,5 +50,7 @@
|
||||
@import "modules/edit-plan-category";
|
||||
@import "modules/delete-plan-category";
|
||||
@import "modules/plans-filter";
|
||||
@import "modules/machines/machine-card";
|
||||
@import "modules/machines/machines-list";
|
||||
|
||||
@import "app.responsive";
|
||||
|
@ -0,0 +1,75 @@
|
||||
.machine-card {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
margin: 0 15px 30px;
|
||||
width: 30%;
|
||||
min-width: 300px;
|
||||
|
||||
.machine-picture {
|
||||
height: 250px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
transition: opacity 0.5s ease;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
color: #333333;
|
||||
background-color: #f5f5f5;
|
||||
border-color: #ddd;
|
||||
border-bottom: 1px solid transparent;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
.machine-name {
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
font-size: 1.6rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
line-height: 1.8rem;
|
||||
}
|
||||
|
||||
.machine-actions {
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
|
||||
& > button {
|
||||
border: none !important;
|
||||
padding: 15px 12px;
|
||||
display: block;
|
||||
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;
|
||||
}
|
||||
|
||||
&.reserve-button {
|
||||
border-right: 1px solid #dddddd !important;
|
||||
}
|
||||
|
||||
&.single-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
.machines-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
</section>
|
||||
|
||||
|
||||
<section class="m-lg machines-list"
|
||||
<section class="m-lg"
|
||||
ui-tour="machines"
|
||||
ui-tour-backdrop="true"
|
||||
ui-tour-template-url="'/shared/tour-step-template.html'"
|
||||
@ -28,53 +28,8 @@
|
||||
ui-tour-scroll-parent-id="content-main"
|
||||
post-render="setupMachinesTour">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 form-group">
|
||||
<div class="input-group m-l-lg m-b">
|
||||
<span class="input-group-addon"><i class="fa fa-filter"></i></span>
|
||||
<select ng-model="machineFiltering" class="form-control">
|
||||
<option ng-repeat="status in filterDisabled" value="{{status}}" translate>{{ 'app.public.machines_list.status_'+status }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-md-offset-6 m-t-n row-centered" ng-if="isAuthorized(['admin', 'manager'])">
|
||||
<a role="button" ui-sref="app.admin.calendar" class="btn btn-lg btn-default rounded m-t-sm text-sm">
|
||||
<i class="fa fa-calendar-check-o m-r" aria-hidden="true"></i><span translate>{{ 'app.public.machines_list.new_availability' }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-xs-12 col-sm-6 col-lg-4 reservable-card" ng-class="{'disabled-reservable' : machine.disabled && machineFiltering === 'all'}" ng-repeat="machine in machines | filterDisabled:machineFiltering">
|
||||
<div class="widget panel panel-default">
|
||||
<div class="panel-heading picture" ng-if="!machine.machine_image" ng-click="showMachine(machine)">
|
||||
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon" bs-holder class="img-responsive">
|
||||
</div>
|
||||
<div class="panel-heading picture" style="background-image:url({{machine.machine_image}})" ng-if="machine.machine_image" ng-click="showMachine(machine)">
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h1 class="text-center m-b">{{machine.name}}</h1>
|
||||
</div>
|
||||
<div class="panel-footer no-padder">
|
||||
|
||||
<div class="text-center clearfix">
|
||||
<div class="col-sm-6 b-r no-padder">
|
||||
<div class="btn btn-default btn-block no-b padder-v red reserve-button" ng-click="reserveMachine(machine, $event)" ng-hide="machine.disabled">
|
||||
<i class="fa fa-bookmark m-r-xs"></i>
|
||||
<span class="hidden-sm" translate>{{ 'app.public.machines_list.book' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-padder" ng-class="{'col-sm-6': !machine.disabled}">
|
||||
<div class="btn btn-default btn-block padder-v no-b red show-button" ng-click="showMachine(machine)">
|
||||
<i class="fa fa-eye m-r-xs"></i>
|
||||
<span class="hidden-sm" translate>{{ 'app.shared.buttons.consult' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<machines-list on-show-machine="showMachine"
|
||||
on-reserve-machine="reserveMachine">
|
||||
</machines-list>
|
||||
|
||||
</section>
|
||||
|
@ -213,6 +213,9 @@ en:
|
||||
status_enabled: "Enabled"
|
||||
status_disabled: "Disabled"
|
||||
status_all: "All"
|
||||
machine_card:
|
||||
book: "Book"
|
||||
consult: "Consult"
|
||||
#details of a machine
|
||||
machines_show:
|
||||
book_this_machine: "Book this machine"
|
||||
|
Loading…
x
Reference in New Issue
Block a user