Feat/304 token scss to tailwind - part 1 (#327)

* Converted app.scss

* Made a start converting styles.scss

* commenting out unused colours - test for now

* restoring font-family

* Added correct text colour and height to top level elements

* Eth connect button styling

* Truncated wallet key on staking screen (had been causing overflow)

* Tranches Scss to tailwind

* Withdraw form Scss to tailwind

* Part way done with staking Scss to tailwind

* Removed redundant containerClass prop from epoch-countdown

* Cleanup of colors part 1

* Ran prettier

* Changes from the MR - removed epoch-countdown styles (apart from blueprint, which has moved to styles.scss)

* Changes from mr - removed extra button size classes (to be replaced with a prop later)

* Changes from mr - allow Tailwind's default list styles. Added role="list" for accessibility

* Border-box applied via wildcard again

* MR tweaks

* Removing the eslint warning for using role="list" on unstyled lists

* Correctly naming the jsx-ally plugin in the eslintrc file so that rules were correctly applied

* Removed redundant 'list-none' classes as Tailwind applies this by default for lists
This commit is contained in:
Sam Keen 2022-05-09 00:53:02 +01:00 committed by GitHub
parent 1bb7c23c6e
commit 6eb52c9a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 128 additions and 479 deletions

View File

@ -1,7 +1,7 @@
{ {
"root": true, "root": true,
"ignorePatterns": ["**/*"], "ignorePatterns": ["**/*"],
"plugins": ["@nrwl/nx", "eslint-plugin-unicorn"], "plugins": ["@nrwl/nx", "eslint-plugin-unicorn", "jsx-a11y"],
"overrides": [ "overrides": [
{ {
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
@ -33,6 +33,13 @@
"message": "Import the specific methods you need from lodash e.g. `import get from 'lodash/get'`. This helps with bundle sizing." "message": "Import the specific methods you need from lodash e.g. `import get from 'lodash/get'`. This helps with bundle sizing."
} }
], ],
"jsx-a11y/no-redundant-roles": [
"error",
{
"ul": ["list"],
"ol": ["list"]
}
],
"curly": "warn" "curly": "warn"
} }
}, },

View File

@ -1,14 +0,0 @@
@import './styles/colors';
.app {
max-width: 1300px;
margin: 0 auto;
display: grid;
grid-template-rows: min-content 1fr min-content;
min-height: 100%;
@media (min-width: 960px) {
border-left: 1px solid $white;
border-right: 1px solid $white;
}
}

View File

@ -1,5 +1,4 @@
import './i18n'; import './i18n';
import './app.scss';
import React from 'react'; import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter as Router } from 'react-router-dom';
@ -35,7 +34,7 @@ function App() {
<AppLoader> <AppLoader>
<BalanceManager> <BalanceManager>
<> <>
<div className="app dark"> <div className="app dark max-w-[1300px] mx-auto my-0 grid grid-rows-[min-content_1fr_min-content] min-h-full lg:border-l-1 lg:border-r-1 lg:border-white font-sans text-body lg:text-body-large text-white-80">
<AppBanner /> <AppBanner />
<TemplateSidebar sidebar={sideBar}> <TemplateSidebar sidebar={sideBar}>
<AppRouter /> <AppRouter />

View File

@ -1,50 +0,0 @@
@import '../../styles/colors';
.epoch-countdown {
h3 {
font-size: 16px;
font-weight: normal;
margin: 0 0 5px;
}
p {
font-size: 12px;
margin: 5px 0 0;
}
.bp3-progress-bar {
border: 1px solid $white;
border-radius: 0;
height: 21px;
.bp3-progress-meter {
border-radius: 0;
.bp3-dark & {
background-color: $white;
}
}
}
&__title {
display: flex;
h3:first-child {
flex: 1;
}
}
&__arrow {
flex: 1;
text-align: center;
img {
display: inline-block;
width: 5px;
transform: rotate(180deg);
}
}
&__time-range {
display: flex;
}
}

View File

@ -1,5 +1,3 @@
import './epoch-countdown.scss';
import { Intent, ProgressBar } from '@blueprintjs/core'; import { Intent, ProgressBar } from '@blueprintjs/core';
import { format, formatDistanceStrict } from 'date-fns'; import { format, formatDistanceStrict } from 'date-fns';
import * as React from 'react'; import * as React from 'react';
@ -12,14 +10,12 @@ export interface EpochCountdownProps {
id: string; id: string;
startDate: Date; startDate: Date;
endDate: Date; endDate: Date;
containerClass?: string;
} }
export function EpochCountdown({ export function EpochCountdown({
id, id,
startDate, startDate,
endDate, endDate,
containerClass,
}: EpochCountdownProps) { }: EpochCountdownProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const [now, setNow] = React.useState(Date.now()); const [now, setNow] = React.useState(Date.now());
@ -61,15 +57,12 @@ export function EpochCountdown({
}, [endDate]); }, [endDate]);
return ( return (
<div <div data-testid="epoch-countdown" className="epoch-countdown pt-20">
data-testid="epoch-countdown" <div className="flex items-end">
className={`${containerClass} epoch-countdown`} <h3 className="flex-1 font-normal mb-4">
>
<div className="epoch-countdown__title">
<h3>
{t('Epoch')} {id} {t('Epoch')} {id}
</h3> </h3>
<p> <p className="text-ui-small mb-4">
{endsIn {endsIn
? t('Next epoch in {{endText}}', { endText: endsIn }) ? t('Next epoch in {{endText}}', { endText: endsIn })
: t('Awaiting next epoch')} : t('Awaiting next epoch')}
@ -81,10 +74,14 @@ export function EpochCountdown({
stripes={false} stripes={false}
intent={Intent.NONE} intent={Intent.NONE}
/> />
<div className="epoch-countdown__time-range"> <div className="flex mt-4 text-ui-small">
<p>{format(startDate, DATE_FORMAT_DETAILED)}</p> <p>{format(startDate, DATE_FORMAT_DETAILED)}</p>
<div className="epoch-countdown__arrow"> <div className="flex-1 text-center">
<img alt="arrow" src={arrow} /> <img
className="inline-block w-[5px] rotate-180"
alt="arrow"
src={arrow}
/>
</div> </div>
<p>{format(endDate, DATE_FORMAT_DETAILED)}</p> <p>{format(endDate, DATE_FORMAT_DETAILED)}</p>
</div> </div>

View File

@ -23,7 +23,6 @@ export const EthConnectPrompt = ({ children }: EthConnectPrompProps) => {
isOpen: true, isOpen: true,
}) })
} }
className="fill"
data-testid="connect-to-eth-btn" data-testid="connect-to-eth-btn"
> >
{t('connectEthWallet')} {t('connectEthWallet')}

View File

@ -23,7 +23,7 @@ export const EthWalletContainer = ({ children }: EthWalletContainerProps) => {
if (!account) { if (!account) {
return ( return (
<Button <Button
className="eth-wallet-container fill" className="eth-wallet-container"
data-testid="connect-to-eth-btn" data-testid="connect-to-eth-btn"
onClick={() => onClick={() =>
appDispatch({ appDispatch({

View File

@ -164,14 +164,10 @@ const ConnectedKey = () => {
)} )}
<WalletCardActions> <WalletCardActions>
<Link style={{ flex: 1 }} to={`${Routes.STAKING}/associate`}> <Link style={{ flex: 1 }} to={`${Routes.STAKING}/associate`}>
<Button variant="primary" className="h-auto py-12 w-full"> <Button variant="primary">{t('associate')}</Button>
{t('associate')}
</Button>
</Link> </Link>
<Link style={{ flex: 1 }} to={`${Routes.STAKING}/disassociate`}> <Link style={{ flex: 1 }} to={`${Routes.STAKING}/disassociate`}>
<Button variant="primary" className="h-auto py-12 w-full"> <Button variant="primary">{t('disassociate')}</Button>
{t('disassociate')}
</Button>
</Link> </Link>
</WalletCardActions> </WalletCardActions>
</> </>

View File

@ -22,7 +22,6 @@ export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
return ( return (
<p> <p>
<Button <Button
className="w-full py-12 h-auto text-h5"
onClick={() => onClick={() =>
appDispatch({ appDispatch({
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY, type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,

View File

@ -73,7 +73,6 @@ const VegaWalletNotConnected = () => {
isOpen: true, isOpen: true,
}) })
} }
className="fill w-full py-12 h-auto"
variant="secondary" variant="secondary"
data-testid="connect-vega" data-testid="connect-vega"
> >

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en" class="bg-black w-full h-full">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="stylesheet" href="//static.vega.xyz/fonts.css" /> <link rel="stylesheet" href="//static.vega.xyz/fonts.css" />
@ -20,9 +20,9 @@
<title>Vega Token dApp</title> <title>Vega Token dApp</title>
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" /> <link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
</head> </head>
<body> <body class="h-full">
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" className="bp3-dark"></div> <div id="root" class="bp3-dark h-full"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.

View File

@ -62,11 +62,7 @@ const Home = ({ name }: RouteChildProps) => {
)} )}
</p> </p>
<Link to={Routes.VESTING}> <Link to={Routes.VESTING}>
<Button <Button variant="secondary" data-test-id="check-vesting-page-btn">
variant="secondary"
data-test-id="check-vesting-page-btn"
className="fill py-12 h-auto w-full"
>
{t('Check to see if you can redeem unlocked VEGA tokens')} {t('Check to see if you can redeem unlocked VEGA tokens')}
</Button> </Button>
</Link> </Link>
@ -106,9 +102,7 @@ const Home = ({ name }: RouteChildProps) => {
)} )}
</p> </p>
<Link to={Routes.STAKING}> <Link to={Routes.STAKING}>
<Button variant="secondary" className="py-12 h-auto w-full"> <Button variant="secondary">{t('Nominate a validator')}</Button>
{t('Nominate a validator')}
</Button>
</Link> </Link>
</div> </div>
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
@ -120,7 +114,7 @@ const Home = ({ name }: RouteChildProps) => {
</p> </p>
<p> <p>
<Link to={Routes.GOVERNANCE}> <Link to={Routes.GOVERNANCE}>
<Button variant="secondary" className="py-12 h-auto w-full"> <Button variant="secondary">
{t('View Governance proposals')} {t('View Governance proposals')}
</Button> </Button>
</Link> </Link>

View File

@ -130,7 +130,6 @@ export const RewardsIndex = () => {
data.epoch.timestamps.start && data.epoch.timestamps.start &&
data.epoch.timestamps.expiry && ( data.epoch.timestamps.expiry && (
<EpochCountdown <EpochCountdown
containerClass="staking-node__epoch"
// eslint-disable-next-line // eslint-disable-next-line
id={data!.epoch.id} id={data!.epoch.id}
startDate={new Date(data.epoch.timestamps.start)} startDate={new Date(data.epoch.timestamps.start)}
@ -147,7 +146,7 @@ export const RewardsIndex = () => {
/> />
) : ( ) : (
<Button <Button
className="mt-12 w-full py-12 h-auto text-h5" className="mt-12"
onClick={() => onClick={() =>
appDispatch({ appDispatch({
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY, type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,

View File

@ -18,7 +18,6 @@ export const ConnectToVega = () => {
isOpen: true, isOpen: true,
}) })
} }
className="w-full py-12 h-auto text-h5"
data-test-id="connect-to-vega-wallet-btn" data-test-id="connect-to-vega-wallet-btn"
> >
{t('connectVegaWallet')} {t('connectVegaWallet')}

View File

@ -1,66 +0,0 @@
@import '../../styles/colors';
@import '../../styles/fonts';
.node-list {
list-style: none;
margin: 0;
margin-top: 24px;
padding: 0;
> li {
word-break: break-all;
display: flex;
justify-content: space-between;
flex-direction: column;
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
a {
text-decoration: none;
display: flex;
}
table {
flex: 1;
font-size: 14px;
border-collapse: collapse;
margin-top: 3px;
}
tr {
display: flex;
}
th,
td {
flex: 1;
word-break: break-word;
padding: 1px 5px;
}
th {
color: $text-color-deemphasise;
font-weight: normal;
padding-left: 0;
}
td {
font-family: $font-mono;
text-align: right;
}
&__item-name {
margin-right: 3px;
text-decoration: underline;
}
&__item-id {
text-transform: uppercase;
font-size: 0.8em;
align-self: flex-end;
}
}

View File

@ -1,5 +1,3 @@
import './node-list.scss';
import { gql, useQuery } from '@apollo/client'; import { gql, useQuery } from '@apollo/client';
import { Callout, Intent } from '@vegaprotocol/ui-toolkit'; import { Callout, Intent } from '@vegaprotocol/ui-toolkit';
import React from 'react'; import React from 'react';
@ -47,6 +45,26 @@ export const NODES_QUERY = gql`
} }
`; `;
const NodeListItemName = ({ children }: { children: React.ReactNode }) => (
<span className="mr-4 underline">{children}</span>
);
const NodeListTr = ({ children }: { children: React.ReactNode }) => (
<tr className="flex">{children}</tr>
);
const NodeListTh = ({ children }: { children: React.ReactNode }) => (
<th className="flex-1 break-words py-1 pr-4 pl-0 text-white-60 font-normal">
{children}
</th>
);
const NodeListTd = ({ children }: { children: React.ReactNode }) => (
<td className="flex-1 break-words py-1 px-4 font-mono text-right">
{children}
</td>
);
interface NodeListProps { interface NodeListProps {
epoch: Staking_epoch | undefined; epoch: Staking_epoch | undefined;
party: Staking_party | null | undefined; party: Staking_party | null | undefined;
@ -121,13 +139,12 @@ export const NodeList = ({ epoch, party }: NodeListProps) => {
<> <>
{epoch && epoch.timestamps.start && epoch.timestamps.expiry && ( {epoch && epoch.timestamps.start && epoch.timestamps.expiry && (
<EpochCountdown <EpochCountdown
containerClass="staking-node__epoch"
id={epoch.id} id={epoch.id}
startDate={new Date(epoch.timestamps.start)} startDate={new Date(epoch.timestamps.start)}
endDate={new Date(epoch.timestamps.expiry)} endDate={new Date(epoch.timestamps.expiry)}
/> />
)} )}
<ul className="node-list"> <ul role="list" className="mt-24">
{nodes.map((n, i) => { {nodes.map((n, i) => {
return <NodeListItem key={i} {...n} />; return <NodeListItem key={i} {...n} />;
})} })}
@ -156,36 +173,34 @@ export const NodeListItem = ({
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<li data-testid="node-list-item"> <li
className="break-words flex flex-col justify-between mb-16 last:mb-0"
data-testid="node-list-item"
>
<Link to={id}> <Link to={id}>
{name ? ( {name ? (
<span className="node-list__item-name">{name}</span> <NodeListItemName>{name}</NodeListItemName>
) : ( ) : (
<> <>
<span className="node-list__item-name"> <NodeListItemName>{t('validatorTitleFallback')}</NodeListItemName>
{t('validatorTitleFallback')} <span className="uppercase text-muted" title={`${t('id')}: ${id}`}>
</span>
<span
className="node-list__item-id text-muted"
title={`${t('id')}: ${id}`}
>
{truncateMiddle(id)} {truncateMiddle(id)}
</span> </span>
</> </>
)} )}
</Link> </Link>
<table> <table className="flex-1 text-body border-collapse mt-4">
<tbody> <tbody>
<tr> <NodeListTr>
<th>{t('Total stake')}</th> <NodeListTh>{t('Total stake')}</NodeListTh>
<td>{formatNumber(stakedOnNode, 2)}</td> <NodeListTd>{formatNumber(stakedOnNode, 2)}</NodeListTd>
<td>{stakedTotalPercentage}</td> <NodeListTd>{stakedTotalPercentage}</NodeListTd>
</tr> </NodeListTr>
<tr> <NodeListTr>
<th>{t('Your stake')}</th> <NodeListTh>{t('Your stake')}</NodeListTh>
<td>{formatNumber(userStake, 2)}</td> <NodeListTd>{formatNumber(userStake, 2)}</NodeListTd>
<td>{userStakePercentage}</td> <NodeListTd>{userStakePercentage}</NodeListTd>
</tr> </NodeListTr>
</tbody> </tbody>
</table> </table>
</li> </li>

View File

@ -1,9 +0,0 @@
.staking-node {
&__epoch {
padding-top: 20px;
}
&__callout-container {
margin-top: 20px;
}
}

View File

@ -1,5 +1,3 @@
import './staking-node.scss';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
@ -113,7 +111,6 @@ export const StakingNode = ({ vegaKey, data }: StakingNodeProps) => {
/> />
{data?.epoch.timestamps.start && data?.epoch.timestamps.expiry && ( {data?.epoch.timestamps.start && data?.epoch.timestamps.expiry && (
<EpochCountdown <EpochCountdown
containerClass="staking-node__epoch"
id={data.epoch.id} id={data.epoch.id}
startDate={new Date(data?.epoch.timestamps.start)} startDate={new Date(data?.epoch.timestamps.start)}
endDate={new Date(data?.epoch.timestamps.expiry)} endDate={new Date(data?.epoch.timestamps.expiry)}

View File

@ -18,6 +18,7 @@ import type { Staking as StakingQueryResult } from './__generated__/Staking';
import { ConnectToVega } from './connect-to-vega'; import { ConnectToVega } from './connect-to-vega';
import { NodeList } from './node-list'; import { NodeList } from './node-list';
import { useVegaWallet } from '@vegaprotocol/wallet'; import { useVegaWallet } from '@vegaprotocol/wallet';
import { truncateMiddle } from '../../lib/truncate-middle';
export const Staking = ({ data }: { data?: StakingQueryResult }) => { export const Staking = ({ data }: { data?: StakingQueryResult }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -73,7 +74,11 @@ export const StakingStepConnectWallets = () => {
{t('Connected Ethereum address')}&nbsp; {t('Connected Ethereum address')}&nbsp;
<EtherscanLink address={account} text={account} /> <EtherscanLink address={account} text={account} />
</p> </p>
<p>{t('stakingVegaWalletConnected', { key: keypair.pub })}</p> <p>
{t('stakingVegaWalletConnected', {
key: truncateMiddle(keypair.pub),
})}
</p>
</Callout> </Callout>
); );
} }
@ -108,7 +113,6 @@ export const StakingStepConnectWallets = () => {
isOpen: true, isOpen: true,
}) })
} }
className="fill"
data-testid="connect-to-eth-btn" data-testid="connect-to-eth-btn"
> >
{t('connectEthWallet')} {t('connectEthWallet')}
@ -120,7 +124,7 @@ export const StakingStepConnectWallets = () => {
<Callout <Callout
iconName="tick" iconName="tick"
intent={Intent.Success} intent={Intent.Success}
title={`Vega wallet connected: ${keypair.pub}`} title={`Vega wallet connected: ${truncateMiddle(keypair.pub)}`}
/> />
</div> </div>
) : ( ) : (

View File

@ -1,3 +0,0 @@
.validator-table__cell {
word-break: break-all;
}

View File

@ -1,5 +1,3 @@
import './validator-table.scss';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -9,6 +7,10 @@ import { BigNumber } from '../../lib/bignumber';
import { formatNumber } from '../../lib/format-number'; import { formatNumber } from '../../lib/format-number';
import type { Staking_nodes } from './__generated__/Staking'; import type { Staking_nodes } from './__generated__/Staking';
const ValidatorTableCell = ({ children }: { children: React.ReactNode }) => (
<span className="break-words">{children}</span>
);
export interface ValidatorTableProps { export interface ValidatorTableProps {
node: Staking_nodes; node: Staking_nodes;
stakedTotal: string; stakedTotal: string;
@ -35,11 +37,11 @@ export const ValidatorTable = ({
<KeyValueTable data-testid="validator-table"> <KeyValueTable data-testid="validator-table">
<KeyValueTableRow> <KeyValueTableRow>
<span>{t('id')}:</span> <span>{t('id')}:</span>
<span className="validator-table__cell">{node.id}</span> <ValidatorTableCell>{node.id}</ValidatorTableCell>
</KeyValueTableRow> </KeyValueTableRow>
<KeyValueTableRow> <KeyValueTableRow>
<span>{t('VEGA ADDRESS / PUBLIC KEY')}</span> <span>{t('VEGA ADDRESS / PUBLIC KEY')}</span>
<span className="validator-table__cell">{node.pubkey}</span> <ValidatorTableCell>{node.pubkey}</ValidatorTableCell>
</KeyValueTableRow> </KeyValueTableRow>
<KeyValueTableRow> <KeyValueTableRow>
<span>{t('ABOUT THIS VALIDATOR')}</span> <span>{t('ABOUT THIS VALIDATOR')}</span>

View File

@ -1,13 +0,0 @@
@import '../../styles/colors';
.tranche-label {
margin-right: 5px;
color: $white;
display: inline-block;
text-transform: uppercase;
background-color: $black;
border-style: solid;
margin-left: 5px;
padding: 3px;
border-width: 2px;
}

View File

@ -1,5 +1,3 @@
import './tranche-label.scss';
import { ADDRESSES, EthereumChainIds } from '../../config'; import { ADDRESSES, EthereumChainIds } from '../../config';
import type { EthereumChainId } from '../../config'; import type { EthereumChainId } from '../../config';
@ -39,7 +37,10 @@ export const TrancheLabel = ({ contract, chainId, id }: TrancheLabelProps) => {
return ( return (
<> <>
{TRANCHE_LABELS[id].map((t, i) => ( {TRANCHE_LABELS[id].map((t, i) => (
<strong className="tranche-label" key={`tranche-${id}-${i}`}> <strong
className="inline-block mx-4 p-4 border-2 border-solid bg-black text-white uppercase"
key={`tranche-${id}-${i}`}
>
{t} {t}
</strong> </strong>
))} ))}

View File

@ -1,37 +0,0 @@
@import '../../styles/colors';
@import '../../styles/fonts';
.tranche {
&__user-list {
list-style: none;
padding: 0;
&--item {
padding-bottom: 5px;
}
}
&__progress {
border-left: 1px solid $white;
border-right: 1px solid $white;
&-contents {
display: flex;
justify-content: space-between;
gap: 0 5px;
font-family: $font-mono;
padding: 2px 5px 2px 5px;
color: $text-color-deemphasise;
}
}
&__redeemed {
display: flex;
justify-content: space-between;
gap: 0 5px;
padding: 2px 5px 2px 5px;
:last-child {
font-family: $font-mono;
color: $text-color-deemphasise;
}
}
}

View File

@ -1,5 +1,3 @@
import './tranche.scss';
import type { Tranche as ITranche } from '@vegaprotocol/smart-contracts-sdk'; import type { Tranche as ITranche } from '@vegaprotocol/smart-contracts-sdk';
import { useWeb3React } from '@web3-react/core'; import { useWeb3React } from '@web3-react/core';
import React from 'react'; import React from 'react';
@ -17,6 +15,16 @@ import { TrancheItem } from '../redemption/tranche-item';
import { Routes } from '../router-config'; import { Routes } from '../router-config';
import { TrancheLabel } from './tranche-label'; import { TrancheLabel } from './tranche-label';
const TrancheProgressContents = ({
children,
}: {
children: React.ReactNode;
}) => (
<div className="flex justify-between gap-4 font-mono py-2 px-4 text-white-60">
{children}
</div>
);
export const Tranche = () => { export const Tranche = () => {
const tranches = useOutletContext<ITranche[]>(); const tranches = useOutletContext<ITranche[]>();
const { t } = useTranslation(); const { t } = useTranslation();
@ -54,27 +62,32 @@ export const Tranche = () => {
/> />
} }
/> />
<div className="tranche__redeemed" data-test-id="redeemed-tranche-tokens"> <div
className="flex justify-between gap-x-4 py-2 px-4"
data-test-id="redeemed-tranche-tokens"
>
<span>{t('alreadyRedeemed')}</span> <span>{t('alreadyRedeemed')}</span>
<span>{formatNumber(tranche.total_removed)}</span> <span className="font-mono text-white-60">
{formatNumber(tranche.total_removed)}
</span>
</div> </div>
<h2>{t('Holders')}</h2> <h2>{t('Holders')}</h2>
{tranche.users.length ? ( {tranche.users.length ? (
<ul className="tranche__user-list"> <ul role="list">
{tranche.users.map((user, i) => { {tranche.users.map((user, i) => {
const unlocked = user.remaining_tokens.times(lockedData?.unlocked); const unlocked = user.remaining_tokens.times(lockedData?.unlocked);
const locked = user.remaining_tokens.times(lockedData?.locked); const locked = user.remaining_tokens.times(lockedData?.locked);
return ( return (
<li className="tranche__user-list--item" key={i}> <li className="pb-4" key={i}>
<EtherscanLink address={user.address} text={user.address} /> <EtherscanLink address={user.address} text={user.address} />
<div className="tranche__progress-contents"> <TrancheProgressContents>
<span>{t('Locked')}</span> <span>{t('Locked')}</span>
<span>{t('Unlocked')}</span> <span>{t('Unlocked')}</span>
</div> </TrancheProgressContents>
<div className="tranche__progress-contents"> <TrancheProgressContents>
<span>{formatNumber(locked)}</span> <span>{formatNumber(locked)}</span>
<span>{formatNumber(unlocked)}</span> <span>{formatNumber(unlocked)}</span>
</div> </TrancheProgressContents>
</li> </li>
); );
})} })}

View File

@ -1,101 +0,0 @@
@import '../../styles/colors';
.tranches {
&__list {
list-style: none;
margin: 0;
padding: 0;
}
&__list-item {
border-bottom: 1px solid $white;
padding: 20px 0;
}
&__list-item-container {
color: $gray3;
@media (min-width: 960px) {
display: flex;
justify-content: space-between;
gap: 15px;
}
}
&__button-link {
color: $vega-yellow3;
background-color: transparent !important;
}
&__item-title {
margin-bottom: 10px;
display: flex;
@media (min-width: 960px) {
margin-bottom: 0;
}
}
&__link {
display: inline-block;
color: $white;
text-decoration: none;
margin-right: 15px;
> span {
background-color: $white;
color: $black;
padding: 2px 4px;
margin-right: 10px;
}
> strong {
margin-left: 8px;
}
&:hover {
color: $vega-yellow3;
> span {
background-color: $vega-yellow3;
}
}
}
&__progress {
display: flex;
gap: 5px;
flex-flow: column nowrap;
@media (min-width: 960px) {
align-items: flex-end;
}
}
&__progress-item {
display: flex;
gap: 20px;
align-items: center;
font-size: 12px;
font-weight: 700;
}
&__progress-numbers {
min-width: 85px;
text-align: right;
}
&__progress-title {
min-width: 70px;
text-transform: uppercase;
}
&__message {
text-align: center;
margin-top: 30px;
}
&__secondary-header {
margin: 0;
}
}

View File

@ -1,5 +1,3 @@
import './tranches.scss';
import { useOutletContext } from 'react-router-dom'; import { useOutletContext } from 'react-router-dom';
import type { Tranche } from '@vegaprotocol/smart-contracts-sdk'; import type { Tranche } from '@vegaprotocol/smart-contracts-sdk';
import { useWeb3React } from '@web3-react/core'; import { useWeb3React } from '@web3-react/core';
@ -32,7 +30,7 @@ export const Tranches = () => {
<VestingChart /> <VestingChart />
<p>{t('chartBelow')}</p> <p>{t('chartBelow')}</p>
{tranches?.length ? ( {tranches?.length ? (
<ul className="tranches__list"> <ul role="list">
{(showAll ? tranches : filteredTranches).map((tranche) => { {(showAll ? tranches : filteredTranches).map((tranche) => {
return ( return (
<React.Fragment key={tranche.tranche_id}> <React.Fragment key={tranche.tranche_id}>
@ -57,7 +55,7 @@ export const Tranches = () => {
) : ( ) : (
<p>{t('No tranches')}</p> <p>{t('No tranches')}</p>
)} )}
<section className="tranches__message"> <section className="text-center mt-32">
<Button variant="inline-link" onClick={() => setShowAll(!showAll)}> <Button variant="inline-link" onClick={() => setShowAll(!showAll)}>
{showAll {showAll
? t( ? t(

View File

@ -1,7 +0,0 @@
.withdraw-form {
margin: 40px 0;
svg.icon {
margin-top: 2px;
width: 1.5rem;
}
}

View File

@ -1,5 +1,3 @@
import './withdraw-form.scss';
import { Callout, FormGroup, Intent, Select } from '@vegaprotocol/ui-toolkit'; import { Callout, FormGroup, Intent, Select } from '@vegaprotocol/ui-toolkit';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import React from 'react'; import React from 'react';
@ -76,7 +74,7 @@ export const WithdrawForm = ({
return ( return (
<form <form
className="withdraw-form" className="my-40"
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
if (!valid || !addressValid) return; if (!valid || !addressValid) return;

View File

@ -8,46 +8,14 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
$bg-color-default: rgba(133, 152, 166, 0.25);
$color-default: #bfccd6;
*, *,
*::before, *::before,
*::after { *::after {
box-sizing: border-box; box-sizing: border-box;
} }
html,
body,
#root {
background-color: $black;
color: $text-color;
font-family: $font-main;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-size: 14px;
@media (min-width: 960px) {
font-size: 16px;
}
}
// TODO replace with blueprint themeing // TODO replace with blueprint themeing
// TYPOGRAPHY // TYPOGRAPHY
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
margin-top: 1em;
margin-bottom: 15px;
color: $white;
}
p { p {
word-break: break-word; word-break: break-word;
line-height: 1.4; line-height: 1.4;
@ -84,3 +52,19 @@ a,
.bp3-dark .bp3-input { .bp3-dark .bp3-input {
background-color: $dark-gray4; background-color: $dark-gray4;
} }
.epoch-countdown {
.bp3-progress-bar {
border: 1px solid $white;
border-radius: 0;
height: 21px;
.bp3-progress-meter {
border-radius: 0;
.bp3-dark & {
background-color: $white;
}
}
}
}

View File

@ -35,65 +35,14 @@ $vega-green: #00f780;
$vega-green3: #26ff8a; $vega-green3: #26ff8a;
$vega-red3: #ff261a; $vega-red3: #ff261a;
$vega-blue3: #48aff0;
$vega-yellow3: #daff0d; $vega-yellow3: #daff0d;
$vega-orange3: #ff7a1a; $vega-orange3: #ff7a1a;
$vega-yellow4: #edff22; $vega-yellow4: #edff22;
$vega-red1: darken($vega-red3, 38%);
$vega-green1: darken($vega-green3, 38%);
$vega-yellow1: darken($vega-yellow3, 38%); $vega-yellow1: darken($vega-yellow3, 38%);
$vega-orange1: darken($vega-orange3, 38%);
/* === TEXT COLORS === */ /* === TEXT COLORS === */
$text-color: #c7c7c7; $text-color: #c7c7c7;
$text-color-inverse: #1a1821; $text-color-inverse: #1a1821;
$text-color-deemphasise: #8a9ba8; $text-color-deemphasise: #8a9ba8;
$text-color-emphasise: #f5f8fa; $text-color-emphasise: #f5f8fa;
$text-color-error: $vega-red3;
/* === BUY/SELL BUTTONS === */
$button-sell-hover: #893939;
$button-sell-active: #ff5e5e;
$button-buy-hover: #0a4023;
$button-buy-active: #00ffb2;
/* === MISC BLUEPRINT COLOR OVERRIDES === */
$pt-intent-danger: $vega-red3;
$input-background: #3f3f3f;
// App background
$pt-dark-app-background-color: $dark-gray2;
// Card
$dark-card-background-color: $dark-gray2;
// Menu
$dark-menu-background-color: $dark-gray2;
// Navbar
$dark-navbar-background-color: $black;
// Popover
$dark-popover-background-color: $dark-gray2;
//overlay-backdrop
.bp3-overlay-backdrop {
background-color: rgba(73, 73, 73, 0.7);
}
// Text helpers
.text-deemphasise {
color: $text-color-deemphasise;
}
.text-error {
color: $text-color-error;
}
// hover row
$row-hover-background-color: $dark-gray5;
// backdrop
$backdrop-black: rgba(0, 0, 0, 0.6);