mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
feat: display liquidity tiles on the Loop page
This commit is contained in:
parent
725609fbc2
commit
21ecbb75af
8 changed files with 135 additions and 8 deletions
|
|
@ -11,6 +11,7 @@
|
|||
@import '../node_modules/bootstrap/scss/buttons';
|
||||
@import '../node_modules/bootstrap/scss/tables';
|
||||
@import '../node_modules/bootstrap/scss/nav';
|
||||
@import '../node_modules/bootstrap/scss/grid';
|
||||
|
||||
@font-face {
|
||||
font-family: 'OpenSans Light';
|
||||
|
|
|
|||
43
app/src/components/common/Tile.tsx
Normal file
43
app/src/components/common/Tile.tsx
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react';
|
||||
import { styled } from 'components/theme';
|
||||
import { Title } from './text';
|
||||
|
||||
const Styled = {
|
||||
TileWrap: styled.div`
|
||||
min-height: 100px;
|
||||
padding: 15px;
|
||||
background-color: ${props => props.theme.colors.tileBack};
|
||||
border-radius: 4px;
|
||||
`,
|
||||
Text: styled.div`
|
||||
font-size: ${props => props.theme.sizes.xl};
|
||||
line-height: 37px;
|
||||
letter-spacing: 0.43px;
|
||||
margin-top: 10px;
|
||||
`,
|
||||
};
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* the title to display in the tile
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* optional text to display in the tile. if this is not
|
||||
* provided, then the `children` will be displayed instead
|
||||
*/
|
||||
text?: string;
|
||||
}
|
||||
|
||||
const Tile: React.FC<Props> = ({ title, text, children }) => {
|
||||
const { TileWrap, Text } = Styled;
|
||||
|
||||
return (
|
||||
<TileWrap>
|
||||
<Title>{title}</Title>
|
||||
{text ? <Text>{text}</Text> : children}
|
||||
</TileWrap>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tile;
|
||||
14
app/src/components/common/grid.tsx
Normal file
14
app/src/components/common/grid.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
|
||||
/**
|
||||
* This component represents a Row in the bootstrap Grid layout
|
||||
*/
|
||||
export const Row: React.FC = ({ children }) => <div className="row">{children}</div>;
|
||||
|
||||
/**
|
||||
* A column in the bootstrap Grid layout
|
||||
* @param cols the number of columns wide (optional)
|
||||
*/
|
||||
export const Column: React.FC<{ cols?: number }> = ({ cols, children }) => (
|
||||
<div className={cols ? `col-${cols}` : 'col'}>{children}</div>
|
||||
);
|
||||
|
|
@ -31,11 +31,11 @@ export const XLargeText = styled.span<BlockProps>`
|
|||
letter-spacing: 0.43px;
|
||||
`;
|
||||
|
||||
export const PageTitle = styled.h1`
|
||||
export const PageTitle = styled.h2`
|
||||
font-family: ${props => props.theme.fonts.light};
|
||||
font-size: ${props => props.theme.sizes.l};
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2.7px;
|
||||
line-height: 30px;
|
||||
margin-top: 40px;
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,57 @@
|
|||
import React from 'react';
|
||||
import usePrefixedTranslation from 'hooks/usePrefixedTranslation';
|
||||
import React, { useEffect } from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { usePrefixedTranslation } from 'hooks';
|
||||
import { useActions, useStore } from 'store';
|
||||
import { Column, Row } from 'components/common/grid';
|
||||
import { PageTitle } from 'components/common/text';
|
||||
import Tile from 'components/common/Tile';
|
||||
import { styled } from 'components/theme';
|
||||
|
||||
const Styled = {
|
||||
PageWrap: styled.div`
|
||||
padding: 40px 50px;
|
||||
`,
|
||||
TileSection: styled.section`
|
||||
margin-top: 90px;
|
||||
`,
|
||||
};
|
||||
|
||||
const LoopPage: React.FC = () => {
|
||||
const store = useStore();
|
||||
const { node, channel, swap } = useActions();
|
||||
const { l } = usePrefixedTranslation('cmps.loop.LoopPage');
|
||||
|
||||
useEffect(() => {
|
||||
// fetch RPC data when the component mounts if there is no
|
||||
if (store.channels.length === 0) {
|
||||
channel.getChannels();
|
||||
node.getBalances();
|
||||
swap.listSwaps();
|
||||
}
|
||||
}, [store, node, channel, swap]);
|
||||
|
||||
const { PageWrap, TileSection } = Styled;
|
||||
return (
|
||||
<>
|
||||
<PageWrap>
|
||||
<PageTitle>{l('pageTitle')}</PageTitle>
|
||||
</>
|
||||
<TileSection>
|
||||
<Row>
|
||||
<Column cols={4}>
|
||||
<Tile
|
||||
title={l('inbound')}
|
||||
text={`${store.totalInbound.toLocaleString()} SAT`}
|
||||
/>
|
||||
</Column>
|
||||
<Column cols={4}>
|
||||
<Tile
|
||||
title={l('outbound')}
|
||||
text={`${store.totalOutbound.toLocaleString()} SAT`}
|
||||
/>
|
||||
</Column>
|
||||
</Row>
|
||||
</TileSection>
|
||||
</PageWrap>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoopPage;
|
||||
export default observer(LoopPage);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ const theme = {
|
|||
white: '#ffffff',
|
||||
whitish: '#f5f5f5',
|
||||
pink: '#f5406e',
|
||||
tileBack: 'rgba(245,245,245,0.04)',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"cmps.loop.LoopPage.pageTitle": "Lightning Loop",
|
||||
"cmps.loop.LoopPage.history": "Loop history",
|
||||
"cmps.loop.LoopPage.inbound": "Total inbound Liquidity",
|
||||
"cmps.loop.LoopPage.outbound": "Total outbound Liquidity",
|
||||
"App.nodeInfo": "Node Info",
|
||||
"App.pubkey": "Pubkey",
|
||||
"App.alias": "Alias",
|
||||
|
|
|
|||
|
|
@ -1,17 +1,40 @@
|
|||
import { observable } from 'mobx';
|
||||
import { computed, observable } from 'mobx';
|
||||
import { Channel, NodeBalances, NodeInfo, Swap } from 'types/state';
|
||||
|
||||
/**
|
||||
* The store used to manage global app state
|
||||
*/
|
||||
export class Store {
|
||||
//
|
||||
// App state
|
||||
//
|
||||
@observable sidebarCollapsed = false;
|
||||
|
||||
//
|
||||
// API data
|
||||
//
|
||||
@observable info?: NodeInfo = undefined;
|
||||
@observable balances?: NodeBalances = undefined;
|
||||
@observable channels: Channel[] = [];
|
||||
@observable swaps: Swap[] = [];
|
||||
|
||||
//
|
||||
// computed data
|
||||
//
|
||||
|
||||
/**
|
||||
* the sum of remote balance of all channels
|
||||
*/
|
||||
@computed get totalInbound() {
|
||||
return this.channels.reduce((sum, chan) => sum + chan.remoteBalance, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* the sum of local balance of all channels
|
||||
*/
|
||||
@computed get totalOutbound() {
|
||||
return this.channels.reduce((sum, chan) => sum + chan.localBalance, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// re-export from provider
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue