chore: use monorepo organization

This commit is contained in:
Rafael Taranto 2025-05-12 10:52:54 +01:00
parent deaf7d6ecc
commit a687827f7e
1099 changed files with 8184 additions and 11535 deletions

View file

@ -0,0 +1,303 @@
import { useQuery, gql } from '@apollo/client'
import { formatCryptoAddress } from '@lamassu/coins/lightUtils'
import BigNumber from 'bignumber.js'
import classnames from 'classnames'
import { format } from 'date-fns/fp'
import { QRCodeSVG as QRCode } from 'qrcode.react'
import * as R from 'ramda'
import React, { useState } from 'react'
import TableLabel from 'src/pages/Funding/TableLabel.jsx'
import Title from 'src/components/Title.jsx'
import {
Tr,
Td,
THead,
TBody,
Table
} from 'src/components/fake-table/Table.jsx'
import Sidebar from 'src/components/layout/Sidebar.jsx'
import {
H3,
Info1,
Info2,
Info3,
Label1,
Label3
} from 'src/components/typography/index.jsx'
import CopyToClipboard from 'src/components/CopyToClipboard.jsx'
import { primaryColor } from 'src/styling/variables.js'
import classes from './Funding.module.css'
const NODE_NOT_CONNECTED_ERR =
"Couldn't establish connection with the node. Make sure it is installed and try again"
const sizes = {
big: 165,
time: 140,
date: 130
}
const GET_FUNDING = gql`
{
funding {
cryptoCode
errorMsg
fundingAddress
fundingAddressUrl
confirmedBalance
pending
fiatConfirmedBalance
fiatPending
fiatCode
display
unitScale
}
}
`
const formatAddress = (cryptoCode = '', address = '') =>
formatCryptoAddress(cryptoCode, address).replace(/(.{4})/g, '$1 ')
const sumReducer = (acc, value) => acc.plus(value)
const formatNumber = it => new BigNumber(it).toFormat(2)
const getConfirmedTotal = list => {
return formatNumber(
list
.filter(it => !it.errorMsg)
.map(it => new BigNumber(it.fiatConfirmedBalance))
.reduce(sumReducer, new BigNumber(0))
)
}
const getPendingTotal = list => {
return formatNumber(
list
.filter(it => !it.errorMsg)
.map(it => new BigNumber(it.fiatPending))
.reduce(sumReducer, new BigNumber(0))
)
}
const Funding = () => {
const [selected, setSelected] = useState(null)
const [viewHistory] = useState(false)
const fundingHistory = [
{
cryptoAmount: 2.0,
balance: 10.23,
fiatValue: 1000.0,
date: new Date(),
performedBy: null,
pending: true
},
{
cryptoAmount: 10.0,
balance: 12.23,
fiatValue: 12000.0,
date: new Date(),
performedBy: null
},
{
cryptoAmount: 5.0,
balance: 5.0,
fiatValue: 50000.0,
date: new Date(),
performedBy: null
}
]
const isSelected = it => {
return selected && selected.cryptoCode === it.cryptoCode
}
const { data: fundingResponse, loading } = useQuery(GET_FUNDING)
const funding = R.path(['funding'])(fundingResponse) ?? []
if (funding.length && !selected) {
setSelected(funding[0])
}
const itemRender = (it, active) => {
const itemClass = {
[classes.item]: true,
[classes.inactiveItem]: !active
}
const wrapperClass = {
[classes.itemWrapper]: true,
[classes.error]: it.errorMsg
}
return (
<div className={classnames(wrapperClass)}>
<div className={classes.firstItem}>{it.display}</div>
{!it.errorMsg && (
<>
<div className={classnames(itemClass)}>
{formatNumber(it.fiatConfirmedBalance)} {it.fiatCode}
</div>
<div className={classnames(itemClass)}>
{it.confirmedBalance} {it.cryptoCode}
</div>
</>
)}
</div>
)
}
const pendingTotal = getPendingTotal(funding)
const signIfPositive = num => (num >= 0 ? '+' : '')
return (
<>
<div>
<Title>Funding</Title>
{/* <button onClick={it => setViewHistory(!viewHistory)}>history</button> */}
</div>
<div className={classes.wrapper}>
<Sidebar
data={funding}
isSelected={isSelected}
onClick={setSelected}
displayName={it => it.display}
itemRender={itemRender}
loading={loading}>
{funding.length && (
<div className={classes.total}>
<Label1 className={classes.totalTitle}>
Total crypto balance
</Label1>
<Info1 noMargin>
{getConfirmedTotal(funding)}
{funding[0].fiatCode}
</Info1>
<Label1 className={classes.totalPending}>
({signIfPositive(pendingTotal)} {pendingTotal} pending)
</Label1>
</div>
)}
</Sidebar>
{selected && !viewHistory && selected.errorMsg && (
<div className={classes.main}>
<div className={classes.firstSide}>
<Info3 className={classes.error}>
{R.includes('ECONNREFUSED', selected.errorMsg)
? NODE_NOT_CONNECTED_ERR
: selected.errorMsg}
</Info3>
</div>
</div>
)}
{selected && !viewHistory && !selected.errorMsg && (
<div className={classes.main}>
<div className={classes.firstSide}>
<H3>Balance</H3>
<div className={classes.coinTotal}>
<Info1 inline noMargin>
{`${selected.confirmedBalance} ${selected.cryptoCode}`}
</Info1>
<Info2 inline noMargin className="ml-2">
{`(${signIfPositive(selected.pending)} ${
selected.pending
} pending)`}
</Info2>
</div>
<div className={classes.coinTotal}>
<Info3 inline noMargin>
{`= ${formatNumber(selected.fiatConfirmedBalance)} ${
selected.fiatCode
}`}
</Info3>
<Label3 inline noMargin className="ml-2">
{`(${signIfPositive(selected.fiatPending)} ${formatNumber(
selected.fiatPending
)} pending)`}
</Label3>
</div>
<H3 className={classes.topSpacer}>Address</H3>
<div className={classes.addressWrapper}>
<div className={classes.mono}>
<strong>
<CopyToClipboard
buttonClassname={classes.copyToClipboard}
key={selected.cryptoCode}>
{formatAddress(
selected.cryptoCode,
selected.fundingAddress
)}
</CopyToClipboard>
</strong>
</div>
</div>
</div>
<div className={classes.secondSide}>
<Label1>Scan to send {selected.display}</Label1>
<QRCode
size={240}
fgColor={primaryColor}
value={selected.fundingAddressUrl}
/>
</div>
</div>
)}
{selected && viewHistory && (
<div>
<TableLabel
className={classes.tableLabel}
label="Pending"
color="#cacaca"
/>
<Table className={classes.table}>
<THead>
<Td header width={sizes.big}>
Amount Entered
</Td>
<Td header width={sizes.big}>
Balance After
</Td>
<Td header width={sizes.big}>
Cash Value
</Td>
<Td header width={sizes.date}>
Date
</Td>
<Td header width={sizes.time}>
Time (h:m:s)
</Td>
<Td header width={sizes.big}>
Performed By
</Td>
</THead>
<TBody>
{fundingHistory.map((it, idx) => (
<Tr
key={idx}
className={classnames({ [classes.pending]: it.pending })}>
<Td width={sizes.big}>
{it.cryptoAmount} {selected.cryptoCode}
</Td>
<Td width={sizes.big}>
{it.balance} {selected.cryptoCode}
</Td>
<Td width={sizes.big}>
{it.fiatValue} {selected.fiatCode}
</Td>
<Td width={sizes.date}>{format('yyyy-MM-dd', it.date)}</Td>
<Td width={sizes.time}>{format('hh:mm:ss', it.date)}</Td>
<Td width={sizes.big}>add</Td>
</Tr>
))}
</TBody>
</Table>
</div>
)}
</div>
</>
)
}
export default Funding

View file

@ -0,0 +1,107 @@
.wrapper {
display: flex;
flex: 1;
flex-direction: row;
height: 100%;
}
.main {
display: flex;
flex: 1;
}
.firstSide {
margin: 0 64px 0 48px;
}
.secondSide {
margin-top: -29px;
}
.error {
color: var(--tomato);
}
.coinTotal {
margin: 12px 0;
}
.topSpacer {
margin-top: 40px;
}
.addressWrapper {
display: flex;
flex-direction: column;
flex: 1;
background-color: var(--zircon);
}
.address {
width: 375px;
margin: 12px 24px;
}
.itemWrapper {
text-align: end;
}
.item {
font-family: var(--museo);
font-size: 14px;
font-weight: 500;
margin: 2px;
}
.inactiveItem {
color: var(--comet);
}
.firstItem {
font-weight: 700;
margin: 2px;
}
.total {
margin-top: auto;
text-align: right;
margin-right: 24px;
}
.totalPending {
margin-top: 2px;
}
.totalTitle {
color: var(--comet);
margin-bottom: 2px;
}
.table {
margin-top: 8px;
margin-left: 48px;
}
.tableLabel {
justify-content: end;
margin-top: -38px;
}
.pending {
background-color: var(--zircon);
}
.copyToClipboard {
margin-left: auto;
padding-top: 6px;
padding-left: 15px;
margin-right: -11px;
}
.mono {
font-family: var(--bpmono);
font-size: 14px;
font-weight: 400;
width: 375px;
margin: 12px 24px;
}

View file

@ -0,0 +1,20 @@
import classnames from 'classnames'
import React from 'react'
import { Label1 } from '../../components/typography/index.jsx'
const TableLabel = ({ className, label, color, ...props }) => {
return (
<div className={classnames('flex items-center', className)} {...props}>
{color && (
<div
className="rounded-sm h-3 w-3 mr-2"
style={{ backgroundColor: color }}
/>
)}
<Label1 {...props}>{label}</Label1>
</div>
)
}
export default TableLabel