@themesberg/volt-react-dashboard
Version:
Volt React Dashboard is a free and open source admin dashboard template powered by React.js and Bootstrap 5
346 lines (326 loc) • 11.7 kB
JavaScript
import React from "react";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faAngleDown, faAngleUp, faArrowDown, faArrowUp, faEdit, faEllipsisH, faExternalLinkAlt, faEye, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
import { Col, Row, Nav, Card, Image, Button, Table, Dropdown, ProgressBar, Pagination, ButtonGroup } from '@themesberg/react-bootstrap';
import { Link } from 'react-router-dom';
import { Routes } from "../routes";
import { pageVisits, pageTraffic, pageRanking } from "../data/tables";
import transactions from "../data/transactions";
import commands from "../data/commands";
const ValueChange = ({ value, suffix }) => {
const valueIcon = value < 0 ? faAngleDown : faAngleUp;
const valueTxtColor = value < 0 ? "text-danger" : "text-success";
return (
value ? <span className={valueTxtColor}>
<FontAwesomeIcon icon={valueIcon} />
<span className="fw-bold ms-1">
{Math.abs(value)}{suffix}
</span>
</span> : "--"
);
};
export const PageVisitsTable = () => {
const TableRow = (props) => {
const { pageName, views, returnValue, bounceRate } = props;
const bounceIcon = bounceRate < 0 ? faArrowDown : faArrowUp;
const bounceTxtColor = bounceRate < 0 ? "text-danger" : "text-success";
return (
<tr>
<th scope="row">{pageName}</th>
<td>{views}</td>
<td>${returnValue}</td>
<td>
<FontAwesomeIcon icon={bounceIcon} className={`${bounceTxtColor} me-3`} />
{Math.abs(bounceRate)}%
</td>
</tr>
);
};
return (
<Card border="light" className="shadow-sm">
<Card.Header>
<Row className="align-items-center">
<Col>
<h5>Page visits</h5>
</Col>
<Col className="text-end">
<Button variant="secondary" size="sm">See all</Button>
</Col>
</Row>
</Card.Header>
<Table responsive className="align-items-center table-flush">
<thead className="thead-light">
<tr>
<th scope="col">Page name</th>
<th scope="col">Page Views</th>
<th scope="col">Page Value</th>
<th scope="col">Bounce rate</th>
</tr>
</thead>
<tbody>
{pageVisits.map(pv => <TableRow key={`page-visit-${pv.id}`} {...pv} />)}
</tbody>
</Table>
</Card>
);
};
export const PageTrafficTable = () => {
const TableRow = (props) => {
const { id, source, sourceIcon, sourceIconColor, sourceType, category, rank, trafficShare, change } = props;
return (
<tr>
<td>
<Card.Link href="#" className="text-primary fw-bold">{id}</Card.Link>
</td>
<td className="fw-bold">
<FontAwesomeIcon icon={sourceIcon} className={`icon icon-xs text-${sourceIconColor} w-30`} />
{source}
</td>
<td>{sourceType}</td>
<td>{category ? category : "--"}</td>
<td>{rank ? rank : "--"}</td>
<td>
<Row className="d-flex align-items-center">
<Col xs={12} xl={2} className="px-0">
<small className="fw-bold">{trafficShare}%</small>
</Col>
<Col xs={12} xl={10} className="px-0 px-xl-1">
<ProgressBar variant="primary" className="progress-lg mb-0" now={trafficShare} min={0} max={100} />
</Col>
</Row>
</td>
<td>
<ValueChange value={change} suffix="%" />
</td>
</tr>
);
};
return (
<Card border="light" className="shadow-sm mb-4">
<Card.Body className="pb-0">
<Table responsive className="table-centered table-nowrap rounded mb-0">
<thead className="thead-light">
<tr>
<th className="border-0">#</th>
<th className="border-0">Traffic Source</th>
<th className="border-0">Source Type</th>
<th className="border-0">Category</th>
<th className="border-0">Global Rank</th>
<th className="border-0">Traffic Share</th>
<th className="border-0">Change</th>
</tr>
</thead>
<tbody>
{pageTraffic.map(pt => <TableRow key={`page-traffic-${pt.id}`} {...pt} />)}
</tbody>
</Table>
</Card.Body>
</Card>
);
};
export const RankingTable = () => {
const TableRow = (props) => {
const { country, countryImage, overallRank, overallRankChange, travelRank, travelRankChange, widgetsRank, widgetsRankChange } = props;
return (
<tr>
<td className="border-0">
<Card.Link href="#" className="d-flex align-items-center">
<Image src={countryImage} className="image-small rounded-circle me-2" />
<div><span className="h6">{country}</span></div>
</Card.Link>
</td>
<td className="fw-bold border-0">
{overallRank ? overallRank : "-"}
</td>
<td className="border-0">
<ValueChange value={overallRankChange} />
</td>
<td className="fw-bold border-0">
{travelRank ? travelRank : "-"}
</td>
<td className="border-0">
<ValueChange value={travelRankChange} />
</td>
<td className="fw-bold border-0">
{widgetsRank ? widgetsRank : "-"}
</td>
<td className="border-0">
<ValueChange value={widgetsRankChange} />
</td>
</tr>
);
};
return (
<Card border="light" className="shadow-sm">
<Card.Body className="pb-0">
<Table responsive className="table-centered table-nowrap rounded mb-0">
<thead className="thead-light">
<tr>
<th className="border-0">Country</th>
<th className="border-0">All</th>
<th className="border-0">All Change</th>
<th className="border-0">Travel & Local</th>
<th className="border-0">Travel & Local Change</th>
<th className="border-0">Widgets</th>
<th className="border-0">Widgets Change</th>
</tr>
</thead>
<tbody>
{pageRanking.map(r => <TableRow key={`ranking-${r.id}`} {...r} />)}
</tbody>
</Table>
</Card.Body>
</Card>
);
};
export const TransactionsTable = () => {
const totalTransactions = transactions.length;
const TableRow = (props) => {
const { invoiceNumber, subscription, price, issueDate, dueDate, status } = props;
const statusVariant = status === "Paid" ? "success"
: status === "Due" ? "warning"
: status === "Canceled" ? "danger" : "primary";
return (
<tr>
<td>
<Card.Link as={Link} to={Routes.Invoice.path} className="fw-normal">
{invoiceNumber}
</Card.Link>
</td>
<td>
<span className="fw-normal">
{subscription}
</span>
</td>
<td>
<span className="fw-normal">
{issueDate}
</span>
</td>
<td>
<span className="fw-normal">
{dueDate}
</span>
</td>
<td>
<span className="fw-normal">
${parseFloat(price).toFixed(2)}
</span>
</td>
<td>
<span className={`fw-normal text-${statusVariant}`}>
{status}
</span>
</td>
<td>
<Dropdown as={ButtonGroup}>
<Dropdown.Toggle as={Button} split variant="link" className="text-dark m-0 p-0">
<span className="icon icon-sm">
<FontAwesomeIcon icon={faEllipsisH} className="icon-dark" />
</span>
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item>
<FontAwesomeIcon icon={faEye} className="me-2" /> View Details
</Dropdown.Item>
<Dropdown.Item>
<FontAwesomeIcon icon={faEdit} className="me-2" /> Edit
</Dropdown.Item>
<Dropdown.Item className="text-danger">
<FontAwesomeIcon icon={faTrashAlt} className="me-2" /> Remove
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</td>
</tr>
);
};
return (
<Card border="light" className="table-wrapper table-responsive shadow-sm">
<Card.Body className="pt-0">
<Table hover className="user-table align-items-center">
<thead>
<tr>
<th className="border-bottom">#</th>
<th className="border-bottom">Bill For</th>
<th className="border-bottom">Issue Date</th>
<th className="border-bottom">Due Date</th>
<th className="border-bottom">Total</th>
<th className="border-bottom">Status</th>
<th className="border-bottom">Action</th>
</tr>
</thead>
<tbody>
{transactions.map(t => <TableRow key={`transaction-${t.invoiceNumber}`} {...t} />)}
</tbody>
</Table>
<Card.Footer className="px-3 border-0 d-lg-flex align-items-center justify-content-between">
<Nav>
<Pagination className="mb-2 mb-lg-0">
<Pagination.Prev>
Previous
</Pagination.Prev>
<Pagination.Item active>1</Pagination.Item>
<Pagination.Item>2</Pagination.Item>
<Pagination.Item>3</Pagination.Item>
<Pagination.Item>4</Pagination.Item>
<Pagination.Item>5</Pagination.Item>
<Pagination.Next>
Next
</Pagination.Next>
</Pagination>
</Nav>
<small className="fw-bold">
Showing <b>{totalTransactions}</b> out of <b>25</b> entries
</small>
</Card.Footer>
</Card.Body>
</Card>
);
};
export const CommandsTable = () => {
const TableRow = (props) => {
const { name, usage = [], description, link } = props;
return (
<tr>
<td className="border-0" style={{ width: '5%' }}>
<code>{name}</code>
</td>
<td className="fw-bold border-0" style={{ width: '5%' }}>
<ul className="ps-0">
{usage.map(u => (
<ol key={u} className="ps-0">
<code>{u}</code>
</ol>
))}
</ul>
</td>
<td className="border-0" style={{ width: '50%' }}>
<pre className="m-0 p-0">{description}</pre>
</td>
<td className="border-0" style={{ width: '40%' }}>
<pre><Card.Link href={link} target="_blank">Read More <FontAwesomeIcon icon={faExternalLinkAlt} className="ms-1" /></Card.Link></pre>
</td>
</tr>
);
};
return (
<Card border="light" className="shadow-sm">
<Card.Body className="p-0">
<Table responsive className="table-centered rounded" style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>
<thead className="thead-light">
<tr>
<th className="border-0" style={{ width: '5%' }}>Name</th>
<th className="border-0" style={{ width: '5%' }}>Usage</th>
<th className="border-0" style={{ width: '50%' }}>Description</th>
<th className="border-0" style={{ width: '40%' }}>Extra</th>
</tr>
</thead>
<tbody>
{commands.map(c => <TableRow key={`command-${c.id}`} {...c} />)}
</tbody>
</Table>
</Card.Body>
</Card>
);
};