mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-17 11:54:22 +01:00
show more results for the payment schedules interface
This commit is contained in:
parent
eddf23622d
commit
d22d011a10
38
app/frontend/src/javascript/components/fab-button.tsx
Normal file
38
app/frontend/src/javascript/components/fab-button.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* This component is a template for a clickable button that wraps the application style
|
||||
*/
|
||||
|
||||
import React, { ReactNode, SyntheticEvent } from 'react';
|
||||
|
||||
interface FabButtonProps {
|
||||
onClick?: (event: SyntheticEvent) => void,
|
||||
icon?: ReactNode,
|
||||
className?: string,
|
||||
}
|
||||
|
||||
|
||||
export const FabButton: React.FC<FabButtonProps> = ({ onClick, icon, className, children }) => {
|
||||
/**
|
||||
* Check if the current component was provided an icon to display
|
||||
*/
|
||||
const hasIcon = (): boolean => {
|
||||
return !!icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the action of the button
|
||||
*/
|
||||
const handleClick = (e: SyntheticEvent): void => {
|
||||
if (typeof onClick === 'function') {
|
||||
onClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={handleClick} className={`fab-button ${className}`}>
|
||||
{hasIcon() && <span className="fab-button--icon">{icon}</span>}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -10,23 +10,63 @@ import { react2angular } from 'react2angular';
|
||||
import PaymentScheduleAPI from '../api/payment-schedule';
|
||||
import { DocumentFilters } from './document-filters';
|
||||
import { PaymentSchedulesTable } from './payment-schedules-table';
|
||||
import { FabButton } from './fab-button';
|
||||
|
||||
declare var Application: IApplication;
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
const paymentSchedulesList = PaymentScheduleAPI.list({ query: { page: 1, size: 20 } });
|
||||
|
||||
const PaymentSchedulesList: React.FC = () => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [paymentSchedules, setPaymentSchedules] = useState(paymentSchedulesList.read());
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
const [referenceFilter, setReferenceFilter] = useState(null);
|
||||
const [customerFilter, setCustomerFilter] = useState(null);
|
||||
const [dateFilter, setDateFilter] = useState(null);
|
||||
|
||||
/**
|
||||
* Fetch from the API the payments schedules matching the given filters and reset the results table with the new schedules.
|
||||
*/
|
||||
const handleFiltersChange = ({ reference, customer, date }): void => {
|
||||
setReferenceFilter(reference);
|
||||
setCustomerFilter(customer);
|
||||
setDateFilter(date);
|
||||
|
||||
const api = new PaymentScheduleAPI();
|
||||
api.list({ query: { reference, customer, date, page: 1, size: 20 }}).then((res) => {
|
||||
api.list({ query: { reference, customer, date, page: 1, size: PAGE_SIZE }}).then((res) => {
|
||||
setPaymentSchedules(res);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch from the API the next payment schedules to display, for the current filters, and append them to the current results table.
|
||||
*/
|
||||
const handleLoadMore = (): void => {
|
||||
setPageNumber(pageNumber + 1);
|
||||
|
||||
const api = new PaymentScheduleAPI();
|
||||
api.list({ query: { reference: referenceFilter, customer: customerFilter, date: dateFilter, page: pageNumber + 1, size: PAGE_SIZE }}).then((res) => {
|
||||
const list = paymentSchedules.concat(res);
|
||||
setPaymentSchedules(list);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current collection of payment schedules is empty or not.
|
||||
*/
|
||||
const hasSchedules = (): boolean => {
|
||||
return paymentSchedules.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are some results for the current filters that aren't currently shown.
|
||||
*/
|
||||
const hasMoreSchedules = (): boolean => {
|
||||
return hasSchedules() && paymentSchedules.length < paymentSchedules[0].max_length;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="payment-schedules-list">
|
||||
<h3>
|
||||
@ -36,7 +76,11 @@ const PaymentSchedulesList: React.FC = () => {
|
||||
<div className="schedules-filters">
|
||||
<DocumentFilters onFilterChange={handleFiltersChange} />
|
||||
</div>
|
||||
<PaymentSchedulesTable paymentSchedules={paymentSchedules} showCustomer={true} />
|
||||
{!hasSchedules() && <div>{t('app.admin.invoices.payment_schedules.no_payment_schedules')}</div>}
|
||||
{hasSchedules() && <div className="schedules-list">
|
||||
<PaymentSchedulesTable paymentSchedules={paymentSchedules} showCustomer={true} />
|
||||
{hasMoreSchedules() && <FabButton className="load-more" onClick={handleLoadMore}>{t('app.admin.invoices.payment_schedules.load_more')}</FabButton>}
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import moment from 'moment';
|
||||
import { IFablab } from '../models/fablab';
|
||||
import _ from 'lodash';
|
||||
import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../models/payment-schedule';
|
||||
import { FabButton } from './fab-button';
|
||||
|
||||
declare var Fablab: IFablab;
|
||||
|
||||
@ -119,24 +120,24 @@ const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({
|
||||
return downloadButton(TargetType.Invoice, item.invoice_id);
|
||||
case PaymentScheduleItemState.Pending:
|
||||
return (
|
||||
<button className="action-button" onClick={handleConfirmCheckPayment(item)}>
|
||||
<i className="fas fa-money-check" />
|
||||
<FabButton onClick={handleConfirmCheckPayment(item)}
|
||||
icon={<i className="fas fa-money-check" />}>
|
||||
{t('app.admin.invoices.schedules_table.confirm_payment')}
|
||||
</button>
|
||||
</FabButton>
|
||||
);
|
||||
case PaymentScheduleItemState.RequireAction:
|
||||
return (
|
||||
<button className="action-button" onClick={handleSolveAction(item)}>
|
||||
<i className="fas fa-wrench" />
|
||||
<FabButton onClick={handleSolveAction(item)}
|
||||
icon={<i className="fas fa-wrench" />}>
|
||||
{t('app.admin.invoices.schedules_table.solve')}
|
||||
</button>
|
||||
</FabButton>
|
||||
);
|
||||
case PaymentScheduleItemState.RequirePaymentMethod:
|
||||
return (
|
||||
<button className="action-button" onClick={handleUpdateCard(item)}>
|
||||
<i className="fas fa-credit-card" />
|
||||
<FabButton onClick={handleUpdateCard(item)}
|
||||
icon={<i className="fas fa-credit-card" />}>
|
||||
{t('app.admin.invoices.schedules_table.update_card')}
|
||||
</button>
|
||||
</FabButton>
|
||||
);
|
||||
default:
|
||||
return <span />
|
||||
|
@ -27,6 +27,7 @@ export interface PaymentScheduleItem {
|
||||
}
|
||||
|
||||
export interface PaymentSchedule {
|
||||
max_length: number;
|
||||
id: number,
|
||||
scheduled_type: string,
|
||||
scheduled_id: number,
|
||||
|
@ -22,6 +22,7 @@
|
||||
@import "modules/stripe";
|
||||
@import "modules/tour";
|
||||
@import "modules/fab-modal";
|
||||
@import "modules/fab-button";
|
||||
@import "modules/payment-schedule-summary";
|
||||
@import "modules/wallet-info";
|
||||
@import "modules/stripe-modal";
|
||||
|
39
app/frontend/src/stylesheets/modules/fab-button.scss
Normal file
39
app/frontend/src/stylesheets/modules/fab-button.scss
Normal file
@ -0,0 +1,39 @@
|
||||
.fab-button {
|
||||
color: black;
|
||||
background-color: #fbfbfb;
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid #c9c9c9;
|
||||
padding: 6px 12px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
border-radius: 4px;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f2f2;
|
||||
color: black;
|
||||
border-color: #aaaaaa;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: black;
|
||||
background-color: #f2f2f2;
|
||||
border-color: #aaaaaa;
|
||||
outline: 0;
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
|
||||
&--icon {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
@ -1,3 +1,11 @@
|
||||
.schedules-filters {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.schedules-list {
|
||||
text-align: center;
|
||||
|
||||
.load-more {
|
||||
margin-top: 2em;
|
||||
}
|
||||
}
|
||||
|
@ -99,41 +99,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.download-button,
|
||||
.action-button {
|
||||
color: black;
|
||||
background-color: #fbfbfb;
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid #c9c9c9;
|
||||
padding: 6px 12px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
border-radius: 4px;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f2f2;
|
||||
color: black;
|
||||
border-color: #aaaaaa;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: black;
|
||||
background-color: #f2f2f2;
|
||||
border-color: #aaaaaa;
|
||||
outline: 0;
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.download-button {
|
||||
@extend .fab-button;
|
||||
|
||||
& > i {
|
||||
margin-right: 0.5em;
|
||||
|
@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
max_schedules = @payment_schedules.except(:offset, :limit, :order).count
|
||||
|
||||
json.array! @payment_schedules do |ps|
|
||||
json.max_length max_schedules
|
||||
json.extract! ps, :id, :reference, :created_at, :payment_method
|
||||
json.total ps.total / 100.00
|
||||
json.chained_footprint ps.check_footprint
|
||||
|
@ -642,6 +642,8 @@ en:
|
||||
stripe_currency: "Stripe currency"
|
||||
payment_schedules:
|
||||
filter_schedules: "Filter schedules"
|
||||
no_payment_schedules: "No payment schedules to display"
|
||||
load_more: "Load more"
|
||||
schedules_table:
|
||||
schedule_num: "Schedule #"
|
||||
date: "Date"
|
||||
|
@ -642,6 +642,8 @@ fr:
|
||||
stripe_currency: "Devise Stripe"
|
||||
payment_schedules:
|
||||
filter_schedules: "Filtrer les échéanciers"
|
||||
no_payment_schedules: "Pas d'échéancier à afficher"
|
||||
load_more: "Voir plus"
|
||||
schedules_table:
|
||||
schedule_num: "Échéancier n°"
|
||||
date: "Date"
|
||||
|
Loading…
x
Reference in New Issue
Block a user