Add historical transactions to Admin Transactions page

This commit is contained in:
Tanner Collin 2020-02-22 05:22:39 +00:00
parent 65ffdcc00f
commit dac93abd78
4 changed files with 104 additions and 15 deletions

View File

@ -2,6 +2,8 @@ import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
import './light.css';
import { Button, Container, Checkbox, Dimmer, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react';
import * as Datetime from 'react-datetime';
import 'react-datetime/css/react-datetime.css';
import moment from 'moment';
import { statusColor, BasicTable, staticUrl, requester } from './utils.js';
import { TransactionList, TransactionEditor } from './Transactions.js';
@ -25,9 +27,7 @@ export function AdminReportedTransactions(props) {
}, []);
return (
<Container>
<Header size='large'>Reported Transactions</Header>
<div>
{!error ?
transactions ?
<div>
@ -36,14 +36,91 @@ export function AdminReportedTransactions(props) {
:
<p>Loading...</p>
:
<NotFound />
<p>Error loading.</p>
}
</div>
);
};
</Container>
let transactionsCache = false;
export function AdminHistoricalTransactions(props) {
const { token, user } = props;
const [input, setInput] = useState({ month: moment() });
const [transactions, setTransactions] = useState(transactionsCache);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const handleDatetime = (v) => setInput({ ...input, month: v });
const handleSubmit = (e) => {
if (loading) return;
setLoading(true);
const month = input.month.format('YYYY-MM');
requester('/transactions/?month=' + month, 'GET', token)
.then(res => {
setLoading(false);
setError(false);
setTransactions(res.results);
transactionsCache = res.results;
})
.catch(err => {
setLoading(false);
console.log(err);
setError(true);
});
};
return (
<div>
<Form onSubmit={handleSubmit}>
<label>Month</label>
<Form.Group>
<Form.Field>
<Datetime
dateFormat='YYYY-MM'
timeFormat={false}
value={input.month}
onChange={handleDatetime}
/>
</Form.Field>
<Form.Button loading={loading}>
Submit
</Form.Button>
</Form.Group>
</Form>
{!error ?
transactions && <div>
<p>Found {transactions.length} transactions.</p>
{!!transactions.length &&
<Header size='small'>{moment(transactions[0].date, 'YYYY-MM-DD').format('MMMM YYYY')} Transactions</Header>
}
<TransactionList transactions={transactions} />
</div>
:
<p>Error loading transactions.</p>
}
</div>
);
};
export function AdminTransactions(props) {
return (
<Container>
<Header size='large'>Admin Transactions</Header>
<Header size='medium'>Reported</Header>
<AdminReportedTransactions {...props} />
<Header size='medium'>Historical</Header>
<AdminHistoricalTransactions {...props} />
</Container>
);
}
export function AdminMemberTransactions(props) {
const { token, result, refreshResult } = props;
const transactions = result.transactions;
const [open, setOpen] = useState(false);
@ -92,7 +169,7 @@ export function AdminTransactions(props) {
{transactions.length ?
open ?
<TransactionList transactions={transactions} />
<TransactionList noMember transactions={transactions} />
:
<Button onClick={() => setOpen(true)}>
View / Edit Transactions

View File

@ -11,7 +11,7 @@ import { Transactions, TransactionDetail } from './Transactions.js';
import { Paymaster } from './Paymaster.js';
import { Cards } from './Cards.js';
import { Training } from './Training.js';
import { AdminReportedTransactions } from './AdminTransactions.js';
import { AdminTransactions } from './AdminTransactions.js';
import { Admin } from './Admin.js';
import { Paste } from './Paste.js';
import { Courses, CourseDetail } from './Courses.js';
@ -237,7 +237,7 @@ function App() {
{user && isAdmin(user) &&
<Route path='/admintrans'>
<AdminReportedTransactions token={token} user={user} />
<AdminTransactions token={token} user={user} />
</Route>
}

View File

@ -5,7 +5,7 @@ import { Button, Container, Divider, Dropdown, Form, Grid, Header, Icon, Image,
import { statusColor, isAdmin, BasicTable, staticUrl, requester } from './utils.js';
import { NotFound, PleaseLogin } from './Misc.js';
import { AdminMemberInfo, AdminMemberPause, AdminMemberForm, AdminMemberCards } from './AdminMembers.js';
import { AdminTransactions } from './AdminTransactions.js';
import { AdminMemberTransactions } from './AdminTransactions.js';
export function MembersDropdown(props) {
const { token, name, onChange, value, initial } = props;
@ -194,7 +194,7 @@ export function MemberDetail(props) {
</Segment>}
{isAdmin(user) && <Segment padded>
<AdminTransactions result={result} refreshResult={refreshResult} {...props} />
<AdminMemberTransactions result={result} refreshResult={refreshResult} {...props} />
</Segment>}
</div>

View File

@ -49,12 +49,12 @@ export function TransactionEditor(props) {
const categoryOptions = [
{ key: '0', text: 'Membership Dues', value: 'Membership' },
{ key: '1', text: 'Payment On Account or Prepayment', value: 'OnAcct' },
{ key: '1', text: 'Payment On Account (ie. Course Fee)', value: 'OnAcct' },
{ key: '2', text: 'Snack / Pop / Coffee', value: 'Snacks' },
{ key: '3', text: 'Donations', value: 'Donation' },
{ key: '4', text: 'Consumables (Specify which in memo)', value: 'Consumables' },
{ key: '5', text: 'Purchases of Goods or Parts or Stock', value: 'Purchases' },
{ key: '6', text: 'Auction, Garage Sale, Nearly Free Shelf, Etc.', value: 'Garage Sale' },
{ key: '5', text: 'Purchase of Locker / Goods / Merch / Stock', value: 'Purchases' },
{ key: '6', text: 'Auction, Garage Sale, Nearly Free Shelf', value: 'Garage Sale' },
{ key: '7', text: 'Reimbursement (Enter a negative value)', value: 'Reimburse' },
{ key: '8', text: 'Other (Explain in memo)', value: 'Other' },
];
@ -250,15 +250,17 @@ function ReportTransaction(props) {
};
export function TransactionList(props) {
const { transactions } = props;
const { transactions, noMember, noCategory } = props;
return (
<Table basic='very'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Date</Table.HeaderCell>
{!noMember && <Table.HeaderCell>Member</Table.HeaderCell>}
<Table.HeaderCell>Amount</Table.HeaderCell>
<Table.HeaderCell>Account</Table.HeaderCell>
{!noCategory && <Table.HeaderCell>Category</Table.HeaderCell>}
<Table.HeaderCell>Memo</Table.HeaderCell>
</Table.Row>
</Table.Header>
@ -270,8 +272,18 @@ export function TransactionList(props) {
<Table.Cell>
<Link to={'/transactions/'+x.id}>{x.date}</Link>
</Table.Cell>
{!noMember && <Table.Cell>
{x.member_id ?
<Link to={'/members/'+x.member_id}>
{x.member_name}
</Link>
:
x.member_name
}
</Table.Cell>}
<Table.Cell>${x.amount}</Table.Cell>
<Table.Cell>{x.account_type}</Table.Cell>
{!noCategory && <Table.Cell>{x.category}</Table.Cell>}
<Table.Cell>{x.memo || x.report_memo}</Table.Cell>
</Table.Row>
)
@ -290,7 +302,7 @@ export function Transactions(props) {
<Container>
<Header size='large'>Transactions</Header>
<TransactionList transactions={user.transactions} />
<TransactionList noMember noCategory transactions={user.transactions} />
</Container>
);