Compare commits
2 Commits
40fe18d89e
...
46bdab07b3
Author | SHA1 | Date | |
---|---|---|---|
46bdab07b3 | |||
7974eb8687 |
@ -13,6 +13,8 @@ Reference for adding JWT authentication is [here](https://jasonwatmore.com/net-7
|
||||
|
||||
### User Interface
|
||||
|
||||
Use [layoutit.com](https://www.layoutit.com/build).
|
||||
|
||||
* View Income overview
|
||||
* Projected Income - Based on statistical metrics (with controls for fine-tuning sample date range)
|
||||
* Historical Income (with source breakdown)
|
||||
|
@ -3,6 +3,8 @@ import { RouterProvider, useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
import RowButton from "../ui-elements/table/RowButton";
|
||||
import DataFormatter, { RenderType } from "../ui-elements/table/DataFormatter";
|
||||
|
||||
export default function Accounts() {
|
||||
useEffect(() => {
|
||||
@ -46,31 +48,40 @@ export default function Accounts() {
|
||||
|
||||
function renderAllAccountsTable(accounts) {
|
||||
return (
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Balance</th>
|
||||
<th>External Account Number</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
accounts.map(account => (
|
||||
<tr key={account.id}>
|
||||
<td>{account.name}</td>
|
||||
<td>{account.owner}</td>
|
||||
<td>{account.balance}</td>
|
||||
<td>{account.externalAccountNumber}</td>
|
||||
<td><button onClick={() => onAccountEdit(account.id)} className="btn btn-success">Edit</button> ||
|
||||
<button onClick={() => onAccountDelete(account.id)} className="btn btn-danger">Delete</button></td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<table className="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Balance</th>
|
||||
<th>External Account Number</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
accounts.map(account => (
|
||||
<tr key={account.id}>
|
||||
<td><DataFormatter data={account.name} /></td>
|
||||
<td><DataFormatter data={account.owner} /></td>
|
||||
<td><DataFormatter data={account.balance} renderType={RenderType.MoneyUnsigned} /></td>
|
||||
<td><DataFormatter data={account.externalAccountNumber} /></td>
|
||||
<td>
|
||||
<RowButton className="btn btn-sm btn-outline-primary" text="Edit" onClick={() => onAccountEdit(account.id)} />
|
||||
|
||||
<RowButton className="btn btn-sm btn-outline-danger" text="Delete" onClick={() => onAccountDelete(account.id)} />
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import '../main.css';
|
||||
|
||||
export const RenderType = {
|
||||
MoneyUnsigned: "money-unsigned",
|
||||
MoneySigned: "money-signed",
|
||||
MoneyNoColor: "money-nocolor",
|
||||
MoneyNothing: "money-nothing",
|
||||
}
|
||||
|
||||
export default function DataFormatter({
|
||||
data,
|
||||
renderType,
|
||||
currencySymbol = "$"
|
||||
}) {
|
||||
|
||||
const isNotUndefinedOrNull = (object) => {
|
||||
return !(object === undefined || object === null);
|
||||
}
|
||||
|
||||
function filterData(data) {
|
||||
if (renderType != undefined && renderType != null) {
|
||||
let num = Number(data)
|
||||
let moneySign = true;
|
||||
|
||||
switch (renderType)
|
||||
{
|
||||
case RenderType.MoneyUnsigned:
|
||||
moneySign = false;
|
||||
case RenderType.MoneySigned:
|
||||
if (num >= 0) {
|
||||
return <span className='text-success'>{ moneySign && "+"}{currencySymbol + (Math.round(num * 100) / 100).toFixed(2)}</span>
|
||||
} else {
|
||||
return <span className='text-danger'>{ moneySign && "-"}{currencySymbol + (Math.round(num * -100) / 100).toFixed(2)}</span>
|
||||
}
|
||||
break;
|
||||
case RenderType.MoneyNoColor:
|
||||
if (num >= 0) {
|
||||
return moneySign && "+" + currencySymbol + (Math.round(num * 100) / 100).toFixed(2)
|
||||
} else {
|
||||
return moneySign && "-" + currencySymbol + (Math.round(num * -100) / 100).toFixed(2)
|
||||
}
|
||||
case RenderType.MoneyNothing:
|
||||
return currencySymbol + (Math.round(Math.abs(num) * 100) / 100).toFixed(2)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
return (
|
||||
filterData(data)
|
||||
);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import '../main.css';
|
||||
|
||||
export default function RowButton({ text, onClick, hidden, className, disabled }) {
|
||||
return (
|
||||
<button disabled={disabled} className={className} onClick={onClick} hidden={hidden}>
|
||||
{text}
|
||||
</button>
|
||||
);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import '../main.css';
|
||||
//import VintageButton from '../../VintageButton';
|
||||
//import { Badge } from 'reactstrap';
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function Table({
|
||||
headerRender,
|
||||
bodyRender,
|
||||
}) {
|
||||
let navigate = useNavigate();
|
||||
const routeChange = () =>{
|
||||
//let path = `/services/gallery/project?id=` + projectId;
|
||||
//navigate(path);
|
||||
}
|
||||
|
||||
const isNotUndefinedOrNull = (object) => {
|
||||
return !(object === undefined || object === null);
|
||||
}
|
||||
|
||||
return (
|
||||
<table>
|
||||
<thead>
|
||||
{ headerRender() }
|
||||
</thead>
|
||||
<tbody>
|
||||
{ bodyRender() }
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
<div className="outer-border floating-shadow vintage-gallery-card">
|
||||
<div className="mid-border">
|
||||
<div className="inner-border card">
|
||||
<img src={imageUrl} className='card-img-top' style={{borderRadius: 0}} alt={imageCaption}/>
|
||||
{(isNotUndefinedOrNull(title) || isNotUndefinedOrNull(dateText) || isNotUndefinedOrNull(body)
|
||||
|| isNotUndefinedOrNull(priceText) || isNotUndefinedOrNull(buttonText)) &&
|
||||
<div className='card-body'>
|
||||
{isNotUndefinedOrNull(title) && <h5 className='card-title'>{title}</h5>}
|
||||
{isNotUndefinedOrNull(dateText) && <p>{dateText}</p>}
|
||||
{isNotUndefinedOrNull(body) && <p className='card-text'>{body}</p>}
|
||||
{isNotUndefinedOrNull(priceText) && <p style={{fontSize: 20}}><Badge className='vintage-badge' color='dark'>{priceText}</Badge></p>}
|
||||
{isNotUndefinedOrNull(buttonText) && <VintageButton text={buttonText} onClick={routeChange}></VintageButton>}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import '../main.css';
|
||||
|
||||
export default function Tr({
|
||||
keyValue,
|
||||
body
|
||||
}) {
|
||||
|
||||
const isNotUndefinedOrNull = (object) => {
|
||||
return !(object === undefined || object === null);
|
||||
}
|
||||
|
||||
function filterData(data) {
|
||||
return data
|
||||
}
|
||||
|
||||
console.log("Key: " + keyValue);
|
||||
|
||||
return (
|
||||
<tr key={keyValue}>{ body }</tr>
|
||||
);
|
||||
}
|
@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from 'react';
|
||||
import { Routes } from "../services/Routes";
|
||||
import RowButton from "../ui-elements/table/RowButton";
|
||||
|
||||
export default function Users() {
|
||||
useEffect(() => {
|
||||
@ -74,12 +75,52 @@ export default function Users() {
|
||||
);
|
||||
}
|
||||
|
||||
function renderBootstrapTable(users) {
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
<table className="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>User Name</th>
|
||||
<th>Email</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
users.map(user => (
|
||||
<tr key={user.id}>
|
||||
<td>{user.firstName}</td>
|
||||
<td>{user.lastName}</td>
|
||||
<td>{user.username}</td>
|
||||
<td>{user.email}</td>
|
||||
<td>
|
||||
<RowButton className="btn btn-sm btn-outline-primary" text="Edit" onClick={() => onUserEdit(user.id)} />
|
||||
|
||||
<RowButton className="btn btn-sm btn-outline-danger" text="Delete" onClick={() => onUserDelete(user.id)} />
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let content = state.loading ? (
|
||||
<p>
|
||||
<em>Loading...</em>
|
||||
</p>
|
||||
) : (
|
||||
renderAllUsersTable(state.users)
|
||||
//renderAllUsersTable(state.users)
|
||||
renderBootstrapTable(state.users)
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user