* feat: create new buttons * feat: update anchor and button link styles * feat: add icon support * feat: fix full width with icon * feat: convert invalid button props to use new props * feat: tidy up explorer * feat: more tidy up for token and trading * feat: move styles to css file using @apply * chore: remove css with @apply as its not working in apps * fix: deposit form button * feat: use default tailwind config, start on forms * feat: fixup trade grid styles * feat: form styles * feat: styles for order book and tables * feat: make key management use dropdown * feat: update various components * feat: tidy up wallet section * feat: token tidy up * feat: token governance styles * Feat/927: Dialog styling * feat: token styles * feat: add font familys * feat: change token borders to be softer * feat: console-lite changes to support new theme * Feat/927: Centered key-value-table.tsx spacing * Feat/927: Tweak to Explorer site border colours to be inline with trading * Feat/927: Tweak to Explorer header * Feat/927: Theme switcher icon colours * Feat/927: Fix for Explorer block data styling * feat: fix tests, add status footer and change logos * feat: render both theme icons to avoid hydration error * chore: run migrations for project * fix: tailwindconfig build to work with new next version * feat: use document page for next as per documentation * chore: update build targets to use development mode when serving * fix: console-lite default text colors * chore: fix tooltip text break, change submit button * feat: adjust console-lite styles to work with tabs * feat: add bespoke dialog for console-lite market-selector * Feat/927: Theme switcher now has prop for fixed bg colour * Feat/927: Font size and border radius tweak for toggles * Feat/927: Cleaned up trade-grid.tsx spacing * feat: responsive styles for market header and nav * feat: update designs for market popover * fix: nav active state * chore: allow classname to be passed to button * Feat/927: Fix Token width on desktop (was overflowing) * Feat/927: Fix token header h1 from wrapping * Feat/927: Tweak for claim-flow.tsx * fix: connect button test * Feat/927: Proposals list styling polish * Feat/927: key-value-table.tsx spacing tweak * feat: add copy button to kp dropdown * Feat/927: Removing old theme params and uses * Feat/927: Removing old theme params and uses, documenting the now used otb sizes * feat: use key val table in asset dialog * feat: align tooltip styles * fix: orderbook grid alignment * chore: linting * fix: dialog sizing in medium mode, node switcher styles * chore: remove unused color classes * feat: update radio and checkbox designs * feat: updates to storybook * feat: update design system stories * chore: stories update * chore: rename resize panels and tidy * feat: fix checkbox tick * fix: add poyfills for jest in trading test setup * chore: fix checkbox tests * chore: fix tests * chore: fix tests again * chore: revert token wallet name test * fix: tooltip tests on console-lite * fix: wallet dropdown test Co-authored-by: sam-keen <samuel.kleinmann@gmail.com>
This commit is contained in:
parent
688d15ef75
commit
c259622848
3
.gitignore
vendored
3
.gitignore
vendored
@ -43,3 +43,6 @@ Thumbs.db
|
||||
.local.env
|
||||
.env.local
|
||||
cypress.env.json
|
||||
|
||||
# Next.js
|
||||
.next
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/console-lite-e2e",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/console-lite-e2e/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
|
@ -127,7 +127,7 @@ describe('market selector', () => {
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.should('have.length', 3);
|
||||
cy.get('div[role="dialog"]').should('have.class', 'w-full');
|
||||
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
|
@ -255,17 +255,19 @@ describe('Market trade', () => {
|
||||
connectVegaWallet();
|
||||
cy.get('#step-3-control').click();
|
||||
|
||||
// Start from the bottom tooltip to ensure the tooltip above
|
||||
// can be interacted with
|
||||
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The notional size represents the position size'
|
||||
);
|
||||
|
||||
cy.getByTestId('review-trade')
|
||||
.get('#contracts_tooltip_trigger')
|
||||
.realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The number of contracts determines'
|
||||
);
|
||||
|
||||
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
|
||||
cy.get('[data-radix-popper-content-wrapper]').contains(
|
||||
'The notional size represents the position size'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'console-lite',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/console-lite",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/console-lite/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
@ -43,7 +43,7 @@
|
||||
"serve": {
|
||||
"executor": "./tools/executors/webpack:serve",
|
||||
"options": {
|
||||
"buildTarget": "console-lite:build",
|
||||
"buildTarget": "console-lite:build:development",
|
||||
"hmr": true,
|
||||
"port": 4001
|
||||
},
|
||||
@ -65,12 +65,12 @@
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/console-lite"],
|
||||
"options": {
|
||||
"jestConfig": "apps/console-lite/jest.config.js",
|
||||
"jestConfig": "apps/console-lite/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"build-netlify": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"cp apps/console-lite/netlify.toml netlify.toml",
|
||||
|
@ -19,7 +19,7 @@ import useLocalValues from './hooks/use-local-values';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const localValues = useLocalValues(toggleTheme);
|
||||
const localValues = useLocalValues(theme, toggleTheme);
|
||||
const {
|
||||
vegaWalletDialog,
|
||||
menu: { setMenuOpen },
|
||||
@ -37,7 +37,7 @@ function App() {
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog
|
||||
|
@ -54,7 +54,7 @@ export const DealTicketContainer = () => {
|
||||
{(data) => {
|
||||
const balance = (
|
||||
<DealTicketBalance
|
||||
className="mb-16"
|
||||
className="mb-4"
|
||||
settlementAsset={
|
||||
data.market.tradableInstrument.instrument.product?.settlementAsset
|
||||
}
|
||||
@ -76,7 +76,7 @@ export const DealTicketContainer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="flex">
|
||||
<section className="flex p-4 md:p-6">
|
||||
<section className="w-full md:w-1/2 md:min-w-[500px]">
|
||||
{keypair ? container : <ConnectWallet />}
|
||||
</section>
|
||||
|
@ -34,7 +34,7 @@ interface ValueTooltipProps {
|
||||
}
|
||||
|
||||
const ValueTooltipRow = ({ value, description, id }: ValueTooltipProps) => (
|
||||
<dd className="flex gap-x-5 items-center">
|
||||
<dd className="flex gap-x-2 items-center">
|
||||
{value}
|
||||
<Tooltip align="center" description={description}>
|
||||
<div className="cursor-help" id={id || ''} tabIndex={-1}>
|
||||
@ -59,7 +59,7 @@ export const DealTicketEstimates = ({
|
||||
}: DealTicketEstimatesProps) => (
|
||||
<dl className="text-black dark:text-white">
|
||||
{size && (
|
||||
<div className="flex justify-between mb-8">
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle>{t('Contracts')}</DataTitle>
|
||||
<ValueTooltipRow
|
||||
value={size}
|
||||
@ -69,13 +69,13 @@ export const DealTicketEstimates = ({
|
||||
</div>
|
||||
)}
|
||||
{price && (
|
||||
<div className="flex justify-between mb-8">
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle>{t('Est. Price')}</DataTitle>
|
||||
<dd>{price}</dd>
|
||||
</div>
|
||||
)}
|
||||
{notionalSize && (
|
||||
<div className="flex justify-between mb-8">
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle quoteName={quoteName}>{t('Est. Position Size')}</DataTitle>
|
||||
<ValueTooltipRow
|
||||
value={notionalSize}
|
||||
@ -84,7 +84,7 @@ export const DealTicketEstimates = ({
|
||||
</div>
|
||||
)}
|
||||
{fees && (
|
||||
<div className="flex justify-between mb-8">
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle quoteName={quoteName}>{t('Est. Fees')}</DataTitle>
|
||||
<ValueTooltipRow
|
||||
value={fees}
|
||||
|
@ -5,7 +5,6 @@ import {
|
||||
SliderThumb,
|
||||
SliderTrack,
|
||||
SliderRange,
|
||||
Button,
|
||||
Input,
|
||||
FormGroup,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@ -108,12 +107,12 @@ export const DealTicketSize = ({
|
||||
<p>Not enough balance to trade</p>
|
||||
) : (
|
||||
<div>
|
||||
<div className="flex justify-between text-black dark:text-white mb-8">
|
||||
<div className="flex justify-between text-black dark:text-white mb-2">
|
||||
<span data-testid="min-label">{min}</span>
|
||||
<span data-testid="max-label">{max}</span>
|
||||
</div>
|
||||
<SliderRoot
|
||||
className="mb-8"
|
||||
className="mb-2"
|
||||
value={[value]}
|
||||
onValueChange={onValueChange}
|
||||
step={step}
|
||||
@ -128,35 +127,34 @@ export const DealTicketSize = ({
|
||||
|
||||
<div
|
||||
data-testid="percentage-selector"
|
||||
className="flex w-full justify-between text-black dark:text-white mb-32"
|
||||
className="flex w-full justify-between text-black dark:text-white mb-6"
|
||||
>
|
||||
{sizeRatios.map((size, index) => {
|
||||
const proportionalSize = size ? (size / 100) * max : min;
|
||||
return (
|
||||
<Button
|
||||
variant="inline-link"
|
||||
className="no-underline !text-blue"
|
||||
<button
|
||||
className="no-underline hover:underline text-blue"
|
||||
onClick={() => onButtonValueChange(proportionalSize)}
|
||||
type="button"
|
||||
key={index}
|
||||
>
|
||||
{getSizeLabel(size)}
|
||||
</Button>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<dl className="text-black dark:text-white">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<dt>{t('Contracts')}</dt>
|
||||
<dd className="flex justify-end w-full">
|
||||
<FormGroup
|
||||
className="mb-0 flex items-center"
|
||||
labelClassName="mr-8 sr-only"
|
||||
hideLabel={true}
|
||||
label="Enter Size"
|
||||
labelFor="trade-size-input"
|
||||
>
|
||||
{isInputVisible ? (
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
<Input
|
||||
id="input-order-size-market"
|
||||
type="number"
|
||||
@ -168,22 +166,22 @@ export const DealTicketSize = ({
|
||||
onKeyDown={onInputEnter}
|
||||
onChange={onInputValueChange}
|
||||
/>
|
||||
<Button
|
||||
variant="inline-link"
|
||||
className="no-underline !text-blue"
|
||||
<button
|
||||
className="no-underline hover:underline text-blue ml-2"
|
||||
type="button"
|
||||
onClick={toggleInput}
|
||||
>
|
||||
{t('set')}
|
||||
</Button>
|
||||
</>
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
variant="inline-link"
|
||||
className="no-underline !text-blue"
|
||||
<button
|
||||
className="no-underline hover:underline text-blue"
|
||||
onClick={toggleInput}
|
||||
type="button"
|
||||
>
|
||||
{value}
|
||||
</Button>
|
||||
</button>
|
||||
)}
|
||||
</FormGroup>
|
||||
</dd>
|
||||
|
@ -213,9 +213,11 @@ export const DealTicketSteps = ({
|
||||
component: (
|
||||
<div className="mb-8">
|
||||
{invalidText && (
|
||||
<InputError className="mb-8" data-testid="dealticket-error-message">
|
||||
{invalidText}
|
||||
</InputError>
|
||||
<div className="mb-2">
|
||||
<InputError data-testid="dealticket-error-message">
|
||||
{invalidText}
|
||||
</InputError>
|
||||
</div>
|
||||
)}
|
||||
<ReviewTrade
|
||||
market={market}
|
||||
@ -246,7 +248,7 @@ export const DealTicketSteps = ({
|
||||
];
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="px-4 py-8">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="px-2 py-4">
|
||||
<Stepper steps={steps} />
|
||||
</form>
|
||||
);
|
||||
|
@ -67,7 +67,7 @@ export default ({
|
||||
<div className="mb-8 text-black dark:text-white" data-testid="review-trade">
|
||||
<KeyValueTable>
|
||||
<KeyValueTableRow noBorder>
|
||||
<div className="flex flex-none gap-x-5 items-center">
|
||||
<div className="flex flex-none gap-x-2 items-center">
|
||||
<div
|
||||
className={classNames(
|
||||
{
|
||||
@ -75,7 +75,7 @@ export default ({
|
||||
'sellButton dark:sellButtonDark':
|
||||
order.side === Side.SIDE_SELL,
|
||||
},
|
||||
'px-8 py-4 inline text-ui-small'
|
||||
'px-2 py-1 inline text-ui-small'
|
||||
)}
|
||||
>
|
||||
{SIDE_NAMES[order.side]}
|
||||
@ -107,17 +107,17 @@ export default ({
|
||||
notionalSize={notionalSize}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="w-full !py-8 mt-64 max-w-sm"
|
||||
boxShadow={false}
|
||||
variant="secondary"
|
||||
type="submit"
|
||||
disabled={transactionStatus === 'pending' || isDisabled}
|
||||
data-testid="place-order"
|
||||
appendIconName="arrow-top-right"
|
||||
>
|
||||
{transactionStatus === 'pending' ? t('Pending...') : t('Submit')}
|
||||
</Button>
|
||||
<div className="mt-12 max-w-sm">
|
||||
<Button
|
||||
fill={true}
|
||||
type="submit"
|
||||
disabled={transactionStatus === 'pending' || isDisabled}
|
||||
data-testid="place-order"
|
||||
rightIcon="arrow-top-right"
|
||||
>
|
||||
{transactionStatus === 'pending' ? t('Pending...') : t('Submit')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
|
||||
@ -19,36 +19,36 @@ export default ({ value, onSelect }: SideSelectorProps) => {
|
||||
<FormGroup
|
||||
label={t('Direction')}
|
||||
labelFor="order-side-toggle"
|
||||
labelClassName="sr-only"
|
||||
hideLabel={true}
|
||||
>
|
||||
<fieldset
|
||||
className="w-full grid md:grid-cols-2 gap-20"
|
||||
className="w-full grid md:grid-cols-2 gap-4"
|
||||
id="order-side-toggle"
|
||||
>
|
||||
<Button
|
||||
variant="inline-link"
|
||||
<button
|
||||
aria-label={t('Open long position')}
|
||||
type="button"
|
||||
className={classNames(
|
||||
'py-8',
|
||||
'px-8 py-2',
|
||||
'buyButton hover:buyButton dark:buyButtonDark dark:hover:buyButtonDark',
|
||||
{ selected: value === Side.SIDE_BUY }
|
||||
)}
|
||||
onClick={() => onSelect(Side.SIDE_BUY)}
|
||||
>
|
||||
{t('Long')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="inline-link"
|
||||
</button>
|
||||
<button
|
||||
aria-label={t('Open short position')}
|
||||
type="button"
|
||||
className={classNames(
|
||||
'py-8',
|
||||
'px-8 py-2',
|
||||
'sellButton hover:sellButton dark:sellButtonDark dark:hover:sellButtonDark',
|
||||
{ selected: value === Side.SIDE_SELL }
|
||||
)}
|
||||
onClick={() => onSelect(Side.SIDE_SELL)}
|
||||
>
|
||||
{t('Short')}
|
||||
</Button>
|
||||
</button>
|
||||
<div className="md:col-span-2 text-black dark:text-white text-ui-small">
|
||||
{t(
|
||||
'Trading derivatives allows you to make a profit or loss regardless of whether the market you are trading goes up or down. If you open a "long" position, you will make a profit if the price of your chosen market goes up, and you will make a profit for "short" positions when the price goes down.'
|
||||
|
@ -9,7 +9,7 @@ interface Props {
|
||||
|
||||
export const DrawerContent = ({ children, className = '' }: Props) => {
|
||||
const classes = classNames(
|
||||
'w-full sm:w-full grow-1 p-12 md:p-20 overflow-hidden',
|
||||
'w-full sm:w-full grow-1 overflow-hidden',
|
||||
className
|
||||
);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { ButtonLink, Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import type { IconName } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEffect, useState } from 'react';
|
||||
@ -37,13 +37,10 @@ export const DrawerToggle = ({
|
||||
} Sidebar Navigation Menu`;
|
||||
|
||||
return (
|
||||
<Button
|
||||
aria-label={ariaLabel}
|
||||
variant="inline-link"
|
||||
className={classes}
|
||||
onClick={onToggle}
|
||||
>
|
||||
<Icon name={iconName as IconName} />
|
||||
</Button>
|
||||
<span className={classes}>
|
||||
<ButtonLink aria-label={ariaLabel} onClick={onToggle}>
|
||||
<Icon name={iconName as IconName} />
|
||||
</ButtonLink>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
@ -22,8 +22,9 @@ export const NavigationDrawer = ({
|
||||
const width = 'w-full md:w-auto md:min-w-[15%] shrink-0';
|
||||
const position = 'absolute inset-0 h-full z-10 md:static';
|
||||
const background = 'bg-black/50 dark:bg-white/50';
|
||||
const border = 'border-r border-neutral-300 dark:border-neutral-700';
|
||||
const flex = 'flex justify-end overflow-hidden';
|
||||
const joinedClasses = [flex, width, position, background].join(' ');
|
||||
const joinedClasses = [flex, width, position, background, border].join(' ');
|
||||
|
||||
const outerStyles = classNames(joinedClasses, {
|
||||
visible: isMenuOpen,
|
||||
|
@ -7,23 +7,25 @@ import LocalContext from '../../context/local-context';
|
||||
const Header = () => {
|
||||
const {
|
||||
vegaWalletDialog: { setConnect, setManage },
|
||||
theme,
|
||||
toggleTheme,
|
||||
} = useContext(LocalContext);
|
||||
return (
|
||||
<div
|
||||
className="flex items-stretch pr-16 py-16 bg-black text-white-60"
|
||||
className="flex items-stretch pr-6 py-6 bg-black text-neutral-400 border-b border-neutral-300 dark:border-neutral-700"
|
||||
data-testid="header"
|
||||
>
|
||||
<Logo />
|
||||
<div className="flex items-center gap-4 ml-auto mr-8 relative z-10">
|
||||
<div className="flex items-center gap-2 ml-auto relative z-10">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={setConnect}
|
||||
setManageDialog={setManage}
|
||||
/>
|
||||
<ThemeSwitcher
|
||||
theme={theme}
|
||||
onToggle={toggleTheme}
|
||||
className="-my-4"
|
||||
sunClassName="text-white"
|
||||
fixedBg="dark"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,11 +6,11 @@ import { VLogo } from '@vegaprotocol/ui-toolkit';
|
||||
const Logo = () => {
|
||||
return (
|
||||
<NavLink
|
||||
className="mx-20 text-white"
|
||||
className="mx-6 text-white"
|
||||
aria-label={t('Go to home page')}
|
||||
to="/"
|
||||
>
|
||||
<VLogo />
|
||||
<VLogo className="mx-6 my-2" />
|
||||
</NavLink>
|
||||
);
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ export const Main = () => {
|
||||
variant={DRAWER_TOGGLE_VARIANTS.CLOSE}
|
||||
className="p-16"
|
||||
/>
|
||||
<Nav className="hidden md:block my-20 h-full" />
|
||||
<Nav className="hidden md:block my-6 h-full" />
|
||||
</NavigationDrawer>
|
||||
<DrawerContent>
|
||||
<AppRouter />
|
||||
|
@ -9,7 +9,7 @@ interface NavItemProps {
|
||||
export const NavItem = ({ iconName, label }: NavItemProps) => {
|
||||
return (
|
||||
<div className="flex flex-col md:flex-row items-center justify-start cursor-pointer relative">
|
||||
<Icon name={iconName} className="mr-8" />
|
||||
<Icon name={iconName} className="mr-2" />
|
||||
<span className="text-lg">{label}</span>
|
||||
</div>
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ export const Nav = ({ className, tabs = false }: NavProps) => {
|
||||
key={r.name}
|
||||
to={r.path}
|
||||
className={({ isActive }) =>
|
||||
`text-h5 block md:mb-40 px-40 md:text-black md:dark:text-white ${
|
||||
`text-base block md:mb-10 px-12 md:text-black md:dark:text-white ${
|
||||
isActive && 'text-white md:text-blue md:dark:text-blue'
|
||||
}`
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ interface TabBarProps {
|
||||
export const TabBar = ({ className }: TabBarProps) => (
|
||||
<div role="group" aria-label="Tab Bar Navigation Menu" className={className}>
|
||||
<div role="presentation" className="py-[42px]" />
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-16">
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-700">
|
||||
<Nav tabs className="flex justify-evenly items-center" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@ import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { IS_MARKET_TRADABLE } from '../../constants';
|
||||
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
||||
import colors from 'tailwindcss/colors';
|
||||
|
||||
export const STATES_FILTER = [
|
||||
{ value: 'all', text: t('All') },
|
||||
@ -36,7 +37,7 @@ export const agGridLightVariables = `
|
||||
overflow: visible;
|
||||
}
|
||||
.ag-theme-balham .ag-row-hover:not(.mobile) {
|
||||
--ag-row-border-color: ${theme.colors.black[100]};
|
||||
--ag-row-border-color: ${colors.black};
|
||||
}
|
||||
.ag-theme-balham .ag-row-hover .icon-green-hover {
|
||||
fill: ${theme.colors.darkerGreen};
|
||||
@ -123,7 +124,7 @@ export const agGridDarkVariables = `
|
||||
overflow: visible;
|
||||
}
|
||||
.ag-theme-balham-dark .ag-row-hover:not(.mobile){
|
||||
--ag-row-border-color: ${theme.colors.white[100]};
|
||||
--ag-row-border-color: ${colors.white};
|
||||
}
|
||||
.ag-theme-balham-dark .ag-row-hover .icon-green-hover {
|
||||
fill: ${theme.colors.lightGreen};
|
||||
|
@ -22,7 +22,7 @@ const SimpleMarketExpires = ({
|
||||
return agg;
|
||||
}, null);
|
||||
return dateFound ? (
|
||||
<div className="p-2 text-ui-small border-1 border-pink text-pink inline-block">{`${format(
|
||||
<div className="p-2 text-ui-small border border-pink text-pink inline-block">{`${format(
|
||||
dateFound as Date,
|
||||
EXPIRE_DATE_FORMAT
|
||||
)}`}</div>
|
||||
|
@ -130,7 +130,7 @@ const SimpleMarketList = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="h-full grid grid-rows-[min-content,1fr]">
|
||||
<div className="h-full p-4 md:p-6 grid grid-rows-[min-content,1fr]">
|
||||
<SimpleMarketToolbar data={data || []} />
|
||||
<AsyncRenderer loading={loading} error={error} data={localData}>
|
||||
<AgGrid
|
||||
|
@ -10,10 +10,10 @@ interface Props {
|
||||
|
||||
const MarketNameRenderer = ({ market, isMobile }: Props) => {
|
||||
return (
|
||||
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-4 md:gap-x-8 gap-y-0 grid-cols-[min-content,1fr,1fr] md:pl-8">
|
||||
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-2 md:gap-x-4 gap-y-0 grid-cols-[min-content,1fr,1fr] md:pl-4">
|
||||
<div
|
||||
className={classNames(
|
||||
'row-span-2 bg-pink rounded-full bg-gradient-to-br from-white-60 to--white-80 opacity-30 w-20 h-20 md:w-44 md:h-44'
|
||||
'row-span-2 bg-pink rounded-full bg-gradient-to-br from-white/40 to-white/80 opacity-30 w-6 h-6 md:w-10 md:h-10'
|
||||
)}
|
||||
/>
|
||||
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-ui-small md:text-market self-end">
|
||||
|
@ -75,14 +75,14 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-full mb-32 font-alpha">
|
||||
<div className="w-full max-w-full mb-4 font-alpha">
|
||||
<ul
|
||||
ref={slideContRef}
|
||||
className="grid grid-flow-col auto-cols-min gap-8 relative pb-4 mb-16"
|
||||
className="grid grid-flow-col auto-cols-min gap-4 relative pb-2 mb-2"
|
||||
data-testid="market-products-menu"
|
||||
aria-label={t('Product type')}
|
||||
>
|
||||
<li key="all-markets" className="md:mr-16 whitespace-nowrap">
|
||||
<li key="all-markets" className="md:mr-2 whitespace-nowrap">
|
||||
<Link
|
||||
to={`/markets${
|
||||
params.state && params.state !== MarketState.STATE_ACTIVE
|
||||
@ -90,7 +90,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
: ''
|
||||
}`}
|
||||
aria-label={t('All markets')}
|
||||
className={classNames('text-h5 pl-0 text-pink hover:opacity-75', {
|
||||
className={classNames('pl-0 text-pink hover:opacity-75', {
|
||||
active: !activeNumber,
|
||||
})}
|
||||
>
|
||||
@ -98,13 +98,13 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
</Link>
|
||||
</li>
|
||||
{products.map((product, i) => (
|
||||
<li key={product} className="mx-16 whitespace-nowrap">
|
||||
<li key={product} className="mx-2 whitespace-nowrap">
|
||||
<Link
|
||||
to={`/markets/${
|
||||
params.state || MarketState.STATE_ACTIVE
|
||||
}/${product}`}
|
||||
className={classNames(
|
||||
'text-h5 hover:opacity-75 text-black dark:text-white',
|
||||
'hover:opacity-75 text-black dark:text-white',
|
||||
{
|
||||
active: activeNumber - 1 === i,
|
||||
}
|
||||
@ -116,16 +116,16 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
</li>
|
||||
))}
|
||||
<li
|
||||
className="absolute bottom-0 h-2 transition-left duration-300 dark:bg-white bg-black"
|
||||
className="absolute bottom-0 h-[2px] transition-left duration-300 dark:bg-white bg-black"
|
||||
key="slider"
|
||||
style={sliderStyles}
|
||||
/>
|
||||
</ul>
|
||||
<div className="grid gap-8 pb-4 mt-8 md:grid-cols-[min-content,min-content,1fr]">
|
||||
<div className="grid gap-8 pb-4 mt-6 md:grid-cols-[min-content,min-content,1fr]">
|
||||
<div className="pb-8">
|
||||
<DropdownMenu onOpenChange={(open) => setOpen(open)}>
|
||||
<DropdownMenuTrigger
|
||||
className="mr-16 w-auto text-capMenu text-black dark:text-white"
|
||||
className="mr-2 w-auto text-capMenu text-black dark:text-white"
|
||||
data-testid="state-trigger"
|
||||
>
|
||||
<div className="w-full justify-between uppercase inline-flex items-center justify-center box-border">
|
||||
@ -137,12 +137,11 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
<Icon
|
||||
name={IconNames.ARROW_DOWN}
|
||||
className={classNames(
|
||||
'fill-current ml-8 transition-transform',
|
||||
'fill-current ml-2 transition-transform',
|
||||
{
|
||||
'rotate-180': isOpen,
|
||||
}
|
||||
)}
|
||||
size={16}
|
||||
/>
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
@ -151,17 +150,16 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
<DropdownMenuCheckboxItem
|
||||
className="uppercase text-ui dark:text-white"
|
||||
key={value}
|
||||
inset
|
||||
checked={
|
||||
value === params.state ||
|
||||
(!params.state && value === MarketState.STATE_ACTIVE)
|
||||
}
|
||||
onCheckedChange={() => onStateChange(value)}
|
||||
>
|
||||
{text}
|
||||
<DropdownMenuItemIndicator>
|
||||
<Icon name="tick" />
|
||||
</DropdownMenuItemIndicator>
|
||||
{text}
|
||||
</DropdownMenuCheckboxItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
@ -172,14 +170,14 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
</div>
|
||||
{activeNumber > 0 && (
|
||||
<ul
|
||||
className="md:gap-16 gap-12 pb-4 md:ml-16 flex flex-wrap"
|
||||
className="md:gap-6 gap-4 pb-4 md:ml-2 flex flex-wrap"
|
||||
data-testid="market-assets-menu"
|
||||
aria-label={t('Asset on the market')}
|
||||
>
|
||||
<li key="all">
|
||||
<Link
|
||||
to={`/markets/${params.state}/${params.product}`}
|
||||
className={classNames('uppercase pl-0 md:pl-4 text-capMenu', {
|
||||
className={classNames('uppercase pl-0 md:pl-2 text-capMenu', {
|
||||
'text-deemphasise dark:text-midGrey':
|
||||
params.asset && params.asset !== 'all',
|
||||
'active text-black dark:text-white':
|
||||
|
@ -25,13 +25,13 @@ export const Counter = ({ label, isActive, className }: CounterProps) => {
|
||||
|
||||
const unselected: TStyleMap = {
|
||||
border: 'border',
|
||||
size: 'w-[30px] md:w-40',
|
||||
size: 'w-[30px] md:w-10',
|
||||
margin: 'mt-[5px] md:ml-[10px] md:mt-0',
|
||||
};
|
||||
|
||||
const selected: TStyleMap = {
|
||||
colours: 'text-xl text-white',
|
||||
size: 'w-40 md:w-[60px]',
|
||||
size: 'w-10 md:w-[60px]',
|
||||
};
|
||||
|
||||
const classes = classNames(
|
||||
|
@ -58,13 +58,13 @@ export const Stepper = ({ steps }: StepperProps) => {
|
||||
key={`${index}-${step.label}`}
|
||||
aria-label={t(`Step ${index + 1}`)}
|
||||
>
|
||||
<div className="flex relative md:pt-16">
|
||||
<div className="flex relative md:pt-6">
|
||||
{!isFirstStep ? (
|
||||
<div
|
||||
aria-hidden
|
||||
className="flex-auto absolute top-[20px] -left-1/2 right-1/2 md:-top-1/2 md:bottom-1/2 md:left-[29.5px] md:right-auto"
|
||||
>
|
||||
<span className="h-full block border-t-1 border-black dark:border-white w-full md:border-l-1 md:border-t-0" />
|
||||
<span className="h-full block border-t border-black dark:border-white w-full md:border-l md:border-t-0" />
|
||||
</div>
|
||||
) : undefined}
|
||||
<button
|
||||
@ -79,7 +79,7 @@ export const Stepper = ({ steps }: StepperProps) => {
|
||||
>
|
||||
<div className="flex-1 flex flex-col md:flex-row items-center w-full text-center">
|
||||
<Counter
|
||||
className="md:mr-16"
|
||||
className="md:mr-4"
|
||||
isActive={isActive}
|
||||
label={(index + 1).toString()}
|
||||
/>
|
||||
@ -87,8 +87,8 @@ export const Stepper = ({ steps }: StepperProps) => {
|
||||
className={classNames(
|
||||
'md:mt-0 font-alpha uppercase text-black dark:text-white',
|
||||
{
|
||||
'mt-8 text-md md:text-2xl': isActive,
|
||||
'mt-16 text-sm md:text-lg ml-8': !isActive,
|
||||
'mt-2 text-md md:text-2xl': isActive,
|
||||
'mt-4 text-sm md:text-lg md:ml-8': !isActive,
|
||||
}
|
||||
)}
|
||||
>
|
||||
@ -134,22 +134,22 @@ export const Stepper = ({ steps }: StepperProps) => {
|
||||
id={`step-${activeStep}-panel`}
|
||||
aria-labelledby={`step-${activeStep}-control`}
|
||||
role="tabpanel"
|
||||
className="md:hidden mt-32" // md:hidden as fallback
|
||||
className="md:hidden mt-10" // md:hidden as fallback
|
||||
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
||||
tabIndex={0}
|
||||
>
|
||||
{steps[activeStep].component}
|
||||
{!isLastStep && (
|
||||
<Button
|
||||
className="w-full !py-8 mt-64 md:sr-only"
|
||||
boxShadow={false}
|
||||
variant="secondary"
|
||||
onClick={handleNext}
|
||||
disabled={steps[activeStep].disabled}
|
||||
data-testid="next-button"
|
||||
>
|
||||
{t('Next')}
|
||||
</Button>
|
||||
<div className="mt-10 md:sr-only">
|
||||
<Button
|
||||
fill={true}
|
||||
onClick={handleNext}
|
||||
disabled={steps[activeStep].disabled}
|
||||
data-testid="next-button"
|
||||
>
|
||||
{t('Next')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
@ -10,19 +10,17 @@ const ConnectWallet = () => {
|
||||
} = useContext(LocalContext);
|
||||
return (
|
||||
<section
|
||||
className="p-32 bg-white-normal dark:bg-offBlack"
|
||||
className="p-8 bg-white-normal dark:bg-offBlack"
|
||||
data-testid="trading-connect-wallet"
|
||||
>
|
||||
<h3 className="mb-16 text-2xl text-offBlack dark:text-white">
|
||||
<h3 className="mb-4 text-2xl text-offBlack dark:text-white">
|
||||
{t('Please connect your Vega wallet to make a trade')}
|
||||
</h3>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => setConnect(true)}
|
||||
className="h-[50px] mb-16"
|
||||
>
|
||||
{t('Connect Vega wallet')}
|
||||
</Button>
|
||||
<div className="mb-4">
|
||||
<Button variant="primary" onClick={() => setConnect(true)} size="lg">
|
||||
{t('Connect Vega wallet')}
|
||||
</Button>
|
||||
</div>
|
||||
<h4 className="text-lg text-offBlack dark:text-white">
|
||||
{t("Don't have a wallet?")}
|
||||
</h4>
|
||||
|
@ -16,6 +16,7 @@ interface MenuState {
|
||||
export interface LocalValues {
|
||||
vegaWalletDialog: VegaWalletDialogState;
|
||||
menu: MenuState;
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ const useColumnDefinitions = ({ isMobile }: Props) => {
|
||||
width: isMobile ? 35 : 100,
|
||||
cellRenderer: ({ data }: { data: SimpleMarkets_markets }) => (
|
||||
<div className="h-full flex h-full items-center justify-end">
|
||||
<div className="uppercase text-center pr-8">
|
||||
<div className="uppercase text-center pr-2">
|
||||
{!isMobile && t('Trade')}
|
||||
<Icon
|
||||
name={IconNames.ARROW_TOP_RIGHT}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import type { LocalValues } from '../context/local-context';
|
||||
|
||||
const useLocalValues = (toggleTheme: () => void) => {
|
||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
const [connect, setConnect] = useState<boolean>(false);
|
||||
const [manage, setManage] = useState<boolean>(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
@ -9,9 +9,10 @@ const useLocalValues = (toggleTheme: () => void) => {
|
||||
() => ({
|
||||
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||
theme,
|
||||
toggleTheme,
|
||||
}),
|
||||
[connect, manage, toggleTheme, menuOpen]
|
||||
[connect, manage, theme, toggleTheme, menuOpen]
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx"
|
||||
"**/*.test.jsx",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts"
|
||||
]
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/explorer-e2e",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/explorer-e2e/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
|
@ -1,9 +1,9 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://tm.n06.testnet.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
||||
NX_TENDERMINT_URL=https://tm.n06.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n06.testnet.vega.xyz/websocket
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'explorer',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/explorer",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/explorer/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
@ -41,7 +41,7 @@
|
||||
"executor": "./tools/executors/webpack:serve",
|
||||
"options": {
|
||||
"port": 3000,
|
||||
"buildTarget": "explorer:build",
|
||||
"buildTarget": "explorer:build:development",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
@ -62,12 +62,12 @@
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/explorer"],
|
||||
"options": {
|
||||
"jestConfig": "apps/explorer/jest.config.js",
|
||||
"jestConfig": "apps/explorer/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"build-netlify": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"cp apps/explorer/netlify.toml netlify.toml",
|
||||
|
@ -45,15 +45,16 @@ function App() {
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||
>
|
||||
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-black dark:border-white lg:border-l-1 lg:border-r-1 mx-auto">
|
||||
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
|
||||
<Header
|
||||
theme={theme}
|
||||
toggleTheme={toggleTheme}
|
||||
menuOpen={menuOpen}
|
||||
setMenuOpen={setMenuOpen}
|
||||
/>
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
|
@ -22,7 +22,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
|
||||
<TableRow data-testid="block-row" modifier="background">
|
||||
<TableCell
|
||||
data-testid="block-height"
|
||||
className="pl-4 py-2 font-mono"
|
||||
className="p-0.5 font-mono"
|
||||
aria-label={t('Block height')}
|
||||
>
|
||||
<Link
|
||||
@ -34,7 +34,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
|
||||
</TableCell>
|
||||
<TableCell
|
||||
data-testid="num-txs"
|
||||
className="px-8 text-center"
|
||||
className="text-center"
|
||||
aria-label={t('Number of transactions')}
|
||||
>
|
||||
{block.num_txs === '1'
|
||||
@ -43,7 +43,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
|
||||
</TableCell>
|
||||
<TableCell
|
||||
data-testid="validator-link"
|
||||
className="px-8 text-center font-mono"
|
||||
className="text-center font-mono"
|
||||
aria-label={t('Validator')}
|
||||
>
|
||||
<Link to={`/${Routes.VALIDATORS}`}>
|
||||
@ -52,7 +52,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
|
||||
</TableCell>
|
||||
<TableCell
|
||||
data-testid="block-time"
|
||||
className="text-center pr-28 text-neutral-300 w-[170px]"
|
||||
className="text-center pr-6 w-[170px]"
|
||||
aria-label={t('Block genesis')}
|
||||
>
|
||||
<Tooltip
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTendermintWebsocket } from '../../hooks/use-tendermint-websocket';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
interface BlocksRefetchProps {
|
||||
refetch: () => void;
|
||||
@ -26,17 +26,11 @@ export const BlocksRefetch = ({ refetch }: BlocksRefetchProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<span data-testid="new-blocks">{blocksToLoad} new blocks -</span>
|
||||
|
||||
<Button
|
||||
onClick={refresh}
|
||||
variant="inline-link"
|
||||
className="mb-28"
|
||||
data-testid="refresh"
|
||||
>
|
||||
<div className="mb-4">
|
||||
<span data-testid="new-blocks">{blocksToLoad} new blocks - </span>
|
||||
<ButtonLink onClick={refresh} data-testid="refresh">
|
||||
{t('refresh to see latest')}
|
||||
</Button>
|
||||
</>
|
||||
</ButtonLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,26 +1,35 @@
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ThemeSwitcher, Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Search } from '../search';
|
||||
import { Routes } from '../../routes/route-names';
|
||||
import type { Dispatch, SetStateAction } from 'react';
|
||||
|
||||
interface ThemeToggleProps {
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
menuOpen: boolean;
|
||||
setMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const Header = ({
|
||||
theme,
|
||||
toggleTheme,
|
||||
menuOpen,
|
||||
setMenuOpen,
|
||||
}: ThemeToggleProps) => {
|
||||
const headerClasses = classnames(
|
||||
'md:col-span-2',
|
||||
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
||||
'p-4 gap-2 md:gap-4',
|
||||
'border-b border-neutral-700 dark:border-neutral-300'
|
||||
);
|
||||
return (
|
||||
<header className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-b-1">
|
||||
<header className={headerClasses}>
|
||||
<Link to={Routes.HOME}>
|
||||
<h1
|
||||
className="text-h3 font-alpha uppercase calt mb-2"
|
||||
className="text-3xl font-alpha uppercase calt mb-0"
|
||||
data-testid="explorer-header"
|
||||
>
|
||||
{t('Vega Explorer')}
|
||||
@ -31,10 +40,10 @@ export const Header = ({
|
||||
className="md:hidden"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
>
|
||||
<Icon name={menuOpen ? 'cross' : 'menu'} size={20} />
|
||||
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
||||
</button>
|
||||
<Search />
|
||||
<ThemeSwitcher onToggle={toggleTheme} />
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
@ -25,13 +25,10 @@ export const JumpTo = ({
|
||||
}: JumpToProps) => {
|
||||
return (
|
||||
<form onSubmit={submitHandler}>
|
||||
<label
|
||||
htmlFor={inputId}
|
||||
className="block uppercase text-h5 font-bold mb-4"
|
||||
>
|
||||
<label htmlFor={inputId} className="block uppercase font-bold mb-2">
|
||||
{label}
|
||||
</label>
|
||||
<div className="flex">
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
data-testid={inputId}
|
||||
id={inputId}
|
||||
@ -42,12 +39,7 @@ export const JumpTo = ({
|
||||
min={inputMin}
|
||||
max={inputMax}
|
||||
/>
|
||||
<Button
|
||||
data-testid="go-submit"
|
||||
variant="secondary"
|
||||
boxShadow={false}
|
||||
type="submit"
|
||||
>
|
||||
<Button data-testid="go-submit" size="sm" type="submit">
|
||||
{t('Go')}
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@ import { AppRouter } from '../../routes';
|
||||
|
||||
export const Main = () => {
|
||||
return (
|
||||
<main className="p-20 overflow-hidden">
|
||||
<main className="p-4 overflow-hidden">
|
||||
<AppRouter />
|
||||
</main>
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ export const Nav = ({ menuOpen }: NavProps) => {
|
||||
<div
|
||||
className={classnames(
|
||||
'absolute top-0 z-50 md:static',
|
||||
'w-full p-20 md:border-r-1',
|
||||
'w-full p-4 md:border-r border-neutral-700 dark:border-neutral-300',
|
||||
'bg-white dark:bg-black',
|
||||
'transition-[right]',
|
||||
{
|
||||
@ -27,8 +27,8 @@ export const Nav = ({ menuOpen }: NavProps) => {
|
||||
to={r.path}
|
||||
className={({ isActive }) =>
|
||||
classnames(
|
||||
'block mb-8 px-8',
|
||||
'text-h5 hover:bg-vega-pink dark:hover:bg-vega-yellow hover:text-white dark:hover:text-black',
|
||||
'block mb-2 px-2',
|
||||
'text-lg hover:bg-vega-pink dark:hover:bg-vega-yellow hover:text-white dark:hover:text-black',
|
||||
{
|
||||
'bg-vega-pink text-white dark:bg-vega-yellow dark:text-black':
|
||||
isActive,
|
||||
|
@ -14,10 +14,9 @@ export const RouteTitle = ({
|
||||
}: RouteTitleProps) => {
|
||||
const classes = classnames(
|
||||
'font-alpha',
|
||||
'text-h3',
|
||||
'text-2xl',
|
||||
'uppercase',
|
||||
'mt-12',
|
||||
'mb-28',
|
||||
'mb-8',
|
||||
className
|
||||
);
|
||||
return (
|
||||
|
@ -53,14 +53,12 @@ export const Search = () => {
|
||||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
className="flex-1 flex self-center md:ml-16 md:mr-12 md:justify-end"
|
||||
className="w-full md:max-w-[620px] justify-self-end"
|
||||
>
|
||||
<FormGroup
|
||||
label={t('Search by block number or transaction hash')}
|
||||
className="relative w-full md:w-2/3 mb-0"
|
||||
labelClassName="sr-only"
|
||||
labelFor="search"
|
||||
>
|
||||
<label htmlFor="search" className="sr-only">
|
||||
{t('Search by block number or transaction hash')}
|
||||
</label>
|
||||
<div className="flex items-stretch gap-2">
|
||||
<Input
|
||||
{...register('search')}
|
||||
id="search"
|
||||
@ -70,23 +68,16 @@ export const Search = () => {
|
||||
placeholder={t('Enter block number or transaction hash')}
|
||||
/>
|
||||
{error?.message && (
|
||||
<InputError
|
||||
data-testid="search-error"
|
||||
intent="danger"
|
||||
className="absolute top-[100%] flex-1 w-full"
|
||||
>
|
||||
{error.message}
|
||||
</InputError>
|
||||
<div className="absolute top-[100%] flex-1 w-full">
|
||||
<InputError data-testid="search-error" intent="danger">
|
||||
{error.message}
|
||||
</InputError>
|
||||
</div>
|
||||
)}
|
||||
</FormGroup>
|
||||
<Button
|
||||
type="submit"
|
||||
boxShadow={false}
|
||||
variant="secondary"
|
||||
data-testid="search-button"
|
||||
>
|
||||
{t('Search')}
|
||||
</Button>
|
||||
<Button type="submit" size="sm" data-testid="search-button">
|
||||
{t('Search')}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ export const StatusMessage = ({
|
||||
className,
|
||||
...props
|
||||
}: StatusMessageProps) => {
|
||||
const classes = classnames('font-alpha text-h4 mb-28', className);
|
||||
const classes = classnames('font-alpha text-2xl mb-28', className);
|
||||
return (
|
||||
<h3 className={classes} {...props}>
|
||||
{children}
|
||||
|
@ -13,10 +13,9 @@ export const SubHeading = ({
|
||||
}: SubHeadingProps) => {
|
||||
const classes = classnames(
|
||||
'font-alpha',
|
||||
'text-h4',
|
||||
'text-2xl',
|
||||
'uppercase',
|
||||
'mt-12',
|
||||
'mb-12',
|
||||
'mt-8 mb-2',
|
||||
'truncate',
|
||||
className
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ import type { ThHTMLAttributes } from 'react';
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
interface TableProps extends ThHTMLAttributes<HTMLTableElement> {
|
||||
interface TableProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
@ -73,8 +73,9 @@ export const TableRow = ({
|
||||
...props
|
||||
}: TableRowProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'border-b border-black-40 dark:border-white-40': modifier === 'bordered',
|
||||
'border-b-4 bg-black-25 border-b-white dark:bg-white-25 dark:border-b-black':
|
||||
'border-b border-neutral-600 dark:border-neutral-400':
|
||||
modifier === 'bordered',
|
||||
'border-b-2 bg-neutral-300 border-white dark:bg-neutral-700 dark:border-black':
|
||||
modifier === 'background',
|
||||
});
|
||||
return (
|
||||
@ -91,7 +92,7 @@ export const TableCell = ({
|
||||
...props
|
||||
}: TableCellProps) => {
|
||||
const cellClasses = classnames(className, {
|
||||
'py-4': modifier === 'bordered',
|
||||
'py-1': modifier === 'bordered',
|
||||
});
|
||||
return (
|
||||
<td className={cellClasses} {...props}>
|
||||
|
@ -76,6 +76,6 @@ describe('Table cell', () => {
|
||||
</TableWithTbody>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('modifier-class-test')).toHaveClass('py-4');
|
||||
expect(screen.getByTestId('modifier-class-test')).toHaveClass('py-1');
|
||||
});
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ export const TxsInfiniteListItem = ({
|
||||
return (
|
||||
<div
|
||||
data-testid="transaction-row"
|
||||
className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full border-t border-black-60 dark:border-white-25 py-8 txs-infinite-list-item"
|
||||
className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full border-t border-neutral-600 dark:border-neutral-800 py-8 txs-infinite-list-item"
|
||||
>
|
||||
<div className="whitespace-nowrap overflow-scroll" data-testid="tx-hash">
|
||||
<TruncatedLink
|
||||
|
@ -72,9 +72,9 @@ export const TxsInfiniteList = ({
|
||||
return (
|
||||
<div className={className} data-testid="transactions-list">
|
||||
<div className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full mb-8">
|
||||
<div className="text-h5 font-bold">Txn hash</div>
|
||||
<div className="text-h5 font-bold">Party</div>
|
||||
<div className="text-h5 font-bold pl-2">Type</div>
|
||||
<div className="text-lg font-bold">Txn hash</div>
|
||||
<div className="text-lg font-bold">Party</div>
|
||||
<div className="text-lg font-bold pl-2">Type</div>
|
||||
</div>
|
||||
<div data-testid="infinite-scroll-wrapper">
|
||||
<InfiniteLoader
|
||||
|
@ -113,7 +113,7 @@ const Blocks = () => {
|
||||
blocks={blocksData}
|
||||
loadMoreBlocks={loadBlocks}
|
||||
error={blocksError}
|
||||
className="mb-28"
|
||||
className="mb-4"
|
||||
/>
|
||||
<JumpToBlock />
|
||||
</section>
|
||||
|
@ -31,16 +31,16 @@ const Block = () => {
|
||||
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
|
||||
<RenderFetched error={error} loading={loading}>
|
||||
<>
|
||||
<div className="grid grid-cols-2 gap-16 mb-24">
|
||||
<div className="grid grid-cols-2 gap-2 mb-8">
|
||||
<Link
|
||||
data-testid="previous-block"
|
||||
to={`/${Routes.BLOCKS}/${Number(block) - 1}`}
|
||||
>
|
||||
<Button
|
||||
data-testid="previous-block-button"
|
||||
className="w-full"
|
||||
fill={true}
|
||||
size="sm"
|
||||
disabled={Number(block) === 1}
|
||||
variant="secondary"
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
@ -49,14 +49,14 @@ const Block = () => {
|
||||
data-testid="next-block"
|
||||
to={`/${Routes.BLOCKS}/${Number(block) + 1}`}
|
||||
>
|
||||
<Button className="w-full" variant="secondary">
|
||||
<Button size="sm" fill={true}>
|
||||
Next
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
{blockData && (
|
||||
<>
|
||||
<TableWithTbody className="mb-28">
|
||||
<TableWithTbody className="mb-8">
|
||||
<TableRow modifier="bordered">
|
||||
<TableHeader scope="row">Mined by</TableHeader>
|
||||
<TableCell modifier="bordered">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||
|
||||
const Home = () => {
|
||||
const classnames = 'mt-12 grid grid-cols-1 lg:grid-cols-2 lg:gap-16';
|
||||
const classnames = 'mt-4 grid grid-cols-1 lg:grid-cols-2 lg:gap-4';
|
||||
return (
|
||||
<section>
|
||||
<StatsManager className={classnames} />
|
||||
|
@ -41,7 +41,7 @@ const Tx = () => {
|
||||
/>
|
||||
</RenderFetched>
|
||||
|
||||
<h2 className="text-h4 uppercase mb-16">{t('Transaction content')}</h2>
|
||||
<h2 className="text-2xl uppercase mb-4">{t('Transaction content')}</h2>
|
||||
<RenderFetched error={ceTxError} loading={ceTxLoading}>
|
||||
<TxContent data={ceTxData} />
|
||||
</RenderFetched>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Routes } from '../../route-names';
|
||||
import { Button, CopyWithTooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { ButtonLink, CopyWithTooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
TableWithTbody,
|
||||
TableCell,
|
||||
@ -61,12 +61,9 @@ export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
|
||||
startChars={txDetailsTruncateLength}
|
||||
endChars={txDetailsTruncateLength}
|
||||
/>
|
||||
<CopyWithTooltip text="">
|
||||
<Button
|
||||
variant="inline-link"
|
||||
prependIconName="duplicate"
|
||||
<CopyWithTooltip text={txData.tx}>
|
||||
<ButtonLink
|
||||
title={t('Copy tx to clipboard')}
|
||||
onClick={() => navigator.clipboard.writeText(txData.tx)}
|
||||
data-testid="copy-tx-to-clipboard"
|
||||
/>
|
||||
</CopyWithTooltip>
|
||||
|
@ -10,6 +10,8 @@ module.exports = {
|
||||
...createGlobPatternsForDependencies(__dirname),
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme,
|
||||
theme: {
|
||||
extend: theme,
|
||||
},
|
||||
plugins: [vegaCustomClasses],
|
||||
};
|
||||
|
@ -16,7 +16,8 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx"
|
||||
"**/*.test.jsx",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
|
@ -14,7 +14,8 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"files": [
|
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"root": "apps/static",
|
||||
"sourceRoot": "apps/static/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
@ -46,9 +46,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"build-netlify": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"cp apps/static/netlify.toml netlify.toml",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/stats-e2e",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/stats-e2e/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'stats',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/stats",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/stats/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
@ -40,7 +40,7 @@
|
||||
"executor": "./tools/executors/webpack:serve",
|
||||
"options": {
|
||||
"port": 3010,
|
||||
"buildTarget": "stats:build",
|
||||
"buildTarget": "stats:build:development",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
@ -61,7 +61,7 @@
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/stats"],
|
||||
"options": {
|
||||
"jestConfig": "apps/stats/jest.config.js",
|
||||
"jestConfig": "apps/stats/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ function App() {
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-black-95 dark:bg-black dark:text-white-80">
|
||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
||||
<div className="layout-grid w-screen justify-self-center">
|
||||
<Header toggleTheme={toggleTheme} />
|
||||
<Header theme={theme} toggleTheme={toggleTheme} />
|
||||
<StatsManager className="max-w-3xl px-24" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,10 +2,11 @@ import { VegaLogo, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { VegaBackgroundVideo } from '../videos';
|
||||
|
||||
interface ThemeToggleProps {
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
export const Header = ({ toggleTheme }: ThemeToggleProps) => {
|
||||
export const Header = ({ theme, toggleTheme }: ThemeToggleProps) => {
|
||||
return (
|
||||
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
|
||||
<VegaBackgroundVideo />
|
||||
@ -13,7 +14,7 @@ export const Header = ({ toggleTheme }: ThemeToggleProps) => {
|
||||
<div className="relative flex justify-center px-8 dark:bg-black bg-white">
|
||||
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
|
||||
<VegaLogo />
|
||||
<ThemeSwitcher onToggle={toggleTheme} />
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
@ -16,7 +16,8 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx"
|
||||
"**/*.test.jsx",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
|
@ -14,7 +14,8 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"files": [
|
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/token-e2e",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/token-e2e/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { truncateByChars } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const walletContainer = '[data-testid="vega-wallet"]';
|
||||
const walletHeader = '[data-testid="wallet-header"] h1';
|
||||
const connectButton = '[data-testid="connect-vega"]';
|
||||
@ -19,9 +21,6 @@ const vegaUnstaked = '[data-testid="vega-wallet-balance-unstaked"] .text-right';
|
||||
const governanceBtn = '[href="/governance"]';
|
||||
const stakingBtn = '[href="/staking"]';
|
||||
const manageLink = '[data-testid="manage-vega-wallet"]';
|
||||
const dialogWalletName = `[data-testid="key-${Cypress.env(
|
||||
'vegaWalletPublicKey'
|
||||
)}"] h2`;
|
||||
const dialogVegaKey = '[data-testid="vega-public-key-full"]';
|
||||
const dialogDisconnectBtn = '[data-testid="disconnect"]';
|
||||
const copyPublicKeyBtn = '[data-testid="copy-vega-public-key"]';
|
||||
@ -239,19 +238,16 @@ context('Vega Wallet - verify elements on widget', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should have wallet name visible', function () {
|
||||
cy.get(dialog).within(() => {
|
||||
cy.get(dialogWalletName)
|
||||
.should('be.visible')
|
||||
.and('have.text', `${Cypress.env('vegaWalletName')} key 1`);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have vega wallet public key visible', function () {
|
||||
it('should have vega wallet public key and name visible', function () {
|
||||
cy.get(dialog).within(() => {
|
||||
cy.get(dialogVegaKey)
|
||||
.should('be.visible')
|
||||
.and('have.text', `${Cypress.env('vegaWalletPublicKey')}`);
|
||||
.and(
|
||||
'have.text',
|
||||
`${Cypress.env('vegaWalletName')} key 1 ${truncateByChars(
|
||||
Cypress.env('vegaWalletPublicKey')
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'token',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"root": "apps/token",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/token/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
@ -41,7 +41,7 @@
|
||||
"executor": "./tools/executors/webpack:serve",
|
||||
"options": {
|
||||
"port": 4210,
|
||||
"buildTarget": "token:build",
|
||||
"buildTarget": "token:build:development",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
@ -62,12 +62,12 @@
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/token"],
|
||||
"options": {
|
||||
"jestConfig": "apps/token/jest.config.js",
|
||||
"jestConfig": "apps/token/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"build-netlify": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"cp apps/token/netlify.toml netlify.toml",
|
||||
|
@ -3,7 +3,6 @@ import './i18n';
|
||||
import React, { useMemo } from 'react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { AppLoader } from './app-loader';
|
||||
import { AppBanner } from './components/app-banner';
|
||||
import { NetworkInfo } from '@vegaprotocol/network-info';
|
||||
import { BalanceManager } from './components/balance-manager';
|
||||
import { EthWallet } from './components/eth-wallet';
|
||||
@ -40,7 +39,7 @@ const AppContainer = () => {
|
||||
return (
|
||||
<Router>
|
||||
<AppStateProvider>
|
||||
<div className="grid min-h-full text-white-80">
|
||||
<div className="grid min-h-full text-white">
|
||||
<AsyncRenderer loading={loading} data={config} error={error}>
|
||||
{Connectors && (
|
||||
<Web3Provider connectors={Connectors}>
|
||||
@ -50,12 +49,11 @@ const AppContainer = () => {
|
||||
<AppLoader>
|
||||
<BalanceManager>
|
||||
<>
|
||||
<div className="app 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">
|
||||
<AppBanner />
|
||||
<div className="app w-full max-w-[1300px] mx-auto grid grid-rows-[1fr_min-content] min-h-full border-neutral-700 lg:border-l lg:border-r lg:text-body-large">
|
||||
<TemplateSidebar sidebar={sideBar}>
|
||||
<AppRouter />
|
||||
</TemplateSidebar>
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
|
||||
<footer className="p-4 border-t border-neutral-700">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
|
@ -25,9 +25,9 @@ export const AddLockedTokenAddress = () => {
|
||||
image={vegaVesting}
|
||||
/>
|
||||
</p>
|
||||
<div className="flex my-12 gap-12">
|
||||
<hr className="flex-1 mt-8" />
|
||||
{t('Or')} <hr className="flex-1 mt-8" />
|
||||
<div className="flex my-2 gap-4">
|
||||
<hr className="flex-1 mt-4" />
|
||||
{t('Or')} <hr className="flex-1 mt-4" />
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useAddAssetToWallet } from '../../hooks/use-add-asset-to-wallet';
|
||||
@ -24,11 +24,7 @@ export const AddTokenButtonLink = ({
|
||||
if (!addSupported) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Button variant="inline-link" className="add-token-button" onClick={add}>
|
||||
{t('addTokenToWallet')}
|
||||
</Button>
|
||||
);
|
||||
return <ButtonLink onClick={add}>{t('addTokenToWallet')}</ButtonLink>;
|
||||
};
|
||||
|
||||
export const AddTokenButton = ({
|
||||
@ -56,13 +52,13 @@ export const AddTokenButton = ({
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Button variant="inline-link" className="add-token-button" onClick={add}>
|
||||
<ButtonLink onClick={add}>
|
||||
<img
|
||||
className={className}
|
||||
style={{ width: size, height: size }}
|
||||
alt="token-logo"
|
||||
src={image}
|
||||
/>
|
||||
</Button>
|
||||
</ButtonLink>
|
||||
);
|
||||
};
|
||||
|
@ -1,22 +0,0 @@
|
||||
import { useAppState } from '../../contexts/app-state/app-state-context';
|
||||
import { Error } from '../icons';
|
||||
|
||||
export const AppBanner = () => {
|
||||
const {
|
||||
appState: { bannerMessage },
|
||||
} = useAppState();
|
||||
|
||||
// Return empty div so that grid placement remains correct
|
||||
if (!bannerMessage) return <div />;
|
||||
|
||||
return (
|
||||
<div className="row-start-1 bg-white p-8 text-black" role="alert">
|
||||
<p>
|
||||
<span className="inline-block relative top-[1px] text-danger text-ui mr-[5px]">
|
||||
<Error />
|
||||
</span>
|
||||
{bannerMessage}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1 +0,0 @@
|
||||
export * from './app-banner';
|
@ -10,11 +10,11 @@ export const BulletHeader = ({ tag, children, style }: BulletHeaderProps) => {
|
||||
return React.createElement(
|
||||
tag,
|
||||
{
|
||||
className: 'mt-24 py-8 border-t border-white uppercase text-white',
|
||||
className: 'mb-2 uppercase',
|
||||
style,
|
||||
},
|
||||
<>
|
||||
<span className="inline-block w-[12px] h-[12px] mr-12 bg-white" />
|
||||
<span className="inline-block w-4 h-4 mr-4 bg-white" />
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
|
@ -59,17 +59,17 @@ export function EpochCountdown({
|
||||
return (
|
||||
<div data-testid="epoch-countdown" className="epoch-countdown">
|
||||
<div className="flex items-end">
|
||||
<h3 className="flex-1 font-normal mb-4">
|
||||
<h3 className="flex-1">
|
||||
{t('Epoch')} {id}
|
||||
</h3>
|
||||
<p className="text-ui-small mb-4">
|
||||
<p className="text-sm m-0">
|
||||
{endsIn
|
||||
? t('Next epoch in {{endText}}', { endText: endsIn })
|
||||
: t('Awaiting next epoch')}
|
||||
</p>
|
||||
</div>
|
||||
<ProgressBar value={progress} />
|
||||
<div className="flex mt-4 text-ui-small">
|
||||
<div className="flex text-sm">
|
||||
<p>{format(startDate, DATE_FORMAT_DETAILED)}</p>
|
||||
<div className="flex-1 text-center">
|
||||
<img
|
||||
|
@ -2,7 +2,7 @@ import { useWeb3React } from '@web3-react/core';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getButtonClasses, Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import {
|
||||
AppStateActionType,
|
||||
@ -24,9 +24,7 @@ import {
|
||||
WalletCardRow,
|
||||
} from '../wallet-card';
|
||||
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||
import { theme } from '@vegaprotocol/tailwindcss-config';
|
||||
|
||||
const Colors = theme.colors;
|
||||
import colors from 'tailwindcss/colors';
|
||||
|
||||
const removeLeadingAddressSymbol = (key: string) => {
|
||||
if (key && key.length > 2 && key.slice(0, 2) === '0x') {
|
||||
@ -69,18 +67,12 @@ const AssociatedAmounts = ({
|
||||
total={associationAmounts.total}
|
||||
leftLabel={t('associated')}
|
||||
rightLabel={t('notAssociated')}
|
||||
leftColor={Colors.white.DEFAULT}
|
||||
rightColor={Colors.black.DEFAULT}
|
||||
light={false}
|
||||
leftColor={colors.white}
|
||||
rightColor={colors.black}
|
||||
/>
|
||||
{vestingAssociationByVegaKey.length ? (
|
||||
<div>
|
||||
<hr style={{ borderStyle: 'dashed' }} />
|
||||
<WalletCardRow
|
||||
label="Associated with Vega keys"
|
||||
bold={true}
|
||||
dark={true}
|
||||
/>
|
||||
<div className="pt-2 border-t border-dashed">
|
||||
<WalletCardRow label="Associated with Vega keys" />
|
||||
{vestingAssociationByVegaKey.map(([key, amount], i) => {
|
||||
return (
|
||||
<div data-testid="eth-wallet-associated-balances" key={i}>
|
||||
@ -88,7 +80,6 @@ const AssociatedAmounts = ({
|
||||
key={key}
|
||||
label={removeLeadingAddressSymbol(key)}
|
||||
value={amount}
|
||||
dark={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -138,7 +129,6 @@ const ConnectedKey = () => {
|
||||
name="VEGA"
|
||||
symbol="In vesting contract"
|
||||
balance={totalInVestingContract}
|
||||
dark={true}
|
||||
/>
|
||||
<LockedProgress
|
||||
locked={totalLockedBalance}
|
||||
@ -146,7 +136,6 @@ const ConnectedKey = () => {
|
||||
total={totalVestedBalance.plus(totalLockedBalance)}
|
||||
leftLabel={t('Locked')}
|
||||
rightLabel={t('Unlocked')}
|
||||
light={false}
|
||||
/>
|
||||
</section>
|
||||
)}
|
||||
@ -165,7 +154,6 @@ const ConnectedKey = () => {
|
||||
name="VEGA"
|
||||
symbol="In Wallet"
|
||||
balance={walletWithAssociations}
|
||||
dark={true}
|
||||
/>
|
||||
{!Object.keys(
|
||||
appState.associationBreakdown.stakingAssociations
|
||||
@ -177,17 +165,15 @@ const ConnectedKey = () => {
|
||||
)}
|
||||
</section>
|
||||
<WalletCardActions>
|
||||
<Link
|
||||
className={getButtonClasses('flex-1 mr-4', 'secondary')}
|
||||
to={`${Routes.STAKING}/associate`}
|
||||
>
|
||||
{t('associate')}
|
||||
<Link className="flex-1" to={`${Routes.STAKING}/associate`}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('associate')}
|
||||
</Button>
|
||||
</Link>
|
||||
<Link
|
||||
className={getButtonClasses('flex-1 ml-4', 'secondary')}
|
||||
to={`${Routes.STAKING}/disassociate`}
|
||||
>
|
||||
{t('disassociate')}
|
||||
<Link className="flex-1" to={`${Routes.STAKING}/disassociate`}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('disassociate')}
|
||||
</Button>
|
||||
</Link>
|
||||
</WalletCardActions>
|
||||
</>
|
||||
@ -201,12 +187,12 @@ export const EthWallet = () => {
|
||||
const pendingTxs = usePendingTransactions();
|
||||
|
||||
return (
|
||||
<WalletCard dark={true}>
|
||||
<WalletCard>
|
||||
<section data-testid="ethereum-wallet">
|
||||
<WalletCardHeader>
|
||||
<h1 className="m-0 text-h3 uppercase">{t('ethereumKey')}</h1>
|
||||
<h1 className="m-0 uppercase">{t('ethereumKey')}</h1>
|
||||
{account && (
|
||||
<div className="place-self-end font-mono px-4 pb-2">
|
||||
<div className="place-self-end font-mono">
|
||||
<div
|
||||
className="font-mono"
|
||||
data-testid="ethereum-account-truncated"
|
||||
@ -238,8 +224,7 @@ export const EthWallet = () => {
|
||||
<ConnectedKey />
|
||||
) : (
|
||||
<Button
|
||||
variant={'secondary'}
|
||||
className="w-full"
|
||||
fill={true}
|
||||
onClick={() =>
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
|
||||
@ -252,15 +237,15 @@ export const EthWallet = () => {
|
||||
</Button>
|
||||
)}
|
||||
{account && (
|
||||
<WalletCardActions>
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
className="mt-4 underline"
|
||||
className="underline"
|
||||
onClick={() => connector.deactivate()}
|
||||
data-testid="disconnect-from-eth-wallet-button"
|
||||
>
|
||||
{t('disconnect')}
|
||||
</button>
|
||||
</WalletCardActions>
|
||||
</div>
|
||||
)}
|
||||
</WalletCardContent>
|
||||
</section>
|
||||
|
@ -3,9 +3,14 @@ import classNames from 'classnames';
|
||||
interface HeadingProps {
|
||||
title?: string;
|
||||
centerContent?: boolean;
|
||||
marginBottom?: boolean;
|
||||
}
|
||||
|
||||
export const Heading = ({ title, centerContent = true }: HeadingProps) => {
|
||||
export const Heading = ({
|
||||
title,
|
||||
centerContent = true,
|
||||
marginBottom = true,
|
||||
}: HeadingProps) => {
|
||||
if (!title) return null;
|
||||
|
||||
return (
|
||||
@ -14,7 +19,9 @@ export const Heading = ({ title, centerContent = true }: HeadingProps) => {
|
||||
'mx-auto': centerContent,
|
||||
})}
|
||||
>
|
||||
<h1 className="font-alpha calt">{title}</h1>
|
||||
<h1 className={classNames('font-alpha calt', { 'mb-0': !marginBottom })}>
|
||||
{title}
|
||||
</h1>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
@ -6,18 +6,12 @@ import classnames from 'classnames';
|
||||
|
||||
const Colors = theme.colors;
|
||||
|
||||
const ProgressContents = ({
|
||||
light,
|
||||
children,
|
||||
}: {
|
||||
light: boolean;
|
||||
children: React.ReactNode;
|
||||
}) => (
|
||||
const ProgressContents = ({ children }: { children: React.ReactNode }) => (
|
||||
<div
|
||||
className={classnames('flex justify-between py-2 font-mono mb-2', {
|
||||
'gap-0 px-0 text-black': light,
|
||||
'gap-y-0 gap-x-4': !light,
|
||||
})}
|
||||
className={classnames(
|
||||
'flex justify-between font-mono mb-2',
|
||||
'gap-y-0 gap-x-4'
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
@ -36,9 +30,9 @@ const ProgressIndicator = ({
|
||||
style={{
|
||||
backgroundColor: bgColor,
|
||||
}}
|
||||
className={classnames('inline-block w-12 h-12 border', {
|
||||
'mr-8': side === 'left',
|
||||
'ml-8': side === 'right',
|
||||
className={classnames('inline-block w-4 h-4 border', {
|
||||
'mr-2': side === 'left',
|
||||
'ml-2': side === 'right',
|
||||
'border-black': light,
|
||||
'border-white': !light,
|
||||
})}
|
||||
@ -53,7 +47,7 @@ const ProgressBar = ({
|
||||
bgColor: string;
|
||||
}) => (
|
||||
<div
|
||||
className="h-16"
|
||||
className="h-4"
|
||||
style={{
|
||||
flex: isNaN(percentage.toNumber()) ? 0 : percentage.toNumber(),
|
||||
backgroundColor: bgColor,
|
||||
@ -69,7 +63,6 @@ export interface LockedProgressProps {
|
||||
rightLabel: string;
|
||||
leftColor?: string;
|
||||
rightColor?: string;
|
||||
light?: boolean;
|
||||
decimals?: number;
|
||||
}
|
||||
|
||||
@ -81,7 +74,6 @@ export const LockedProgress = ({
|
||||
rightLabel,
|
||||
leftColor = Colors.vega.pink,
|
||||
rightColor = Colors.vega.green,
|
||||
light = false,
|
||||
decimals = 2,
|
||||
}: LockedProgressProps) => {
|
||||
const lockedPercentage = React.useMemo(() => {
|
||||
@ -93,18 +85,12 @@ export const LockedProgress = ({
|
||||
}, [total, unlocked]);
|
||||
|
||||
return (
|
||||
<div className="mb-8">
|
||||
<div
|
||||
className={classnames('flex border', {
|
||||
'border-black': light,
|
||||
'border-white': !light,
|
||||
})}
|
||||
data-testid="progress-bar"
|
||||
>
|
||||
<div className="mb-4">
|
||||
<div className="flex border border-white mb-2" data-testid="progress-bar">
|
||||
<ProgressBar percentage={lockedPercentage} bgColor={leftColor} />
|
||||
<ProgressBar percentage={unlockedPercentage} bgColor={rightColor} />
|
||||
</div>
|
||||
<ProgressContents light={light}>
|
||||
<ProgressContents>
|
||||
<span>
|
||||
<ProgressIndicator bgColor={leftColor} side={'left'} light={false} />
|
||||
{leftLabel}
|
||||
@ -118,8 +104,7 @@ export const LockedProgress = ({
|
||||
/>
|
||||
</span>
|
||||
</ProgressContents>
|
||||
|
||||
<ProgressContents light={light}>
|
||||
<ProgressContents>
|
||||
<span data-testid="currency-locked">
|
||||
{formatNumber(locked, decimals)}
|
||||
</span>
|
||||
|
@ -99,10 +99,10 @@ export const Nav = () => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`px-16 py-8 ${
|
||||
className={`px-4 py-2 ${
|
||||
inverted
|
||||
? 'bg-clouds bg-no-repeat bg-cover bg-vega-yellow'
|
||||
: 'border-b-white border-b-1'
|
||||
: 'border-neutral-700 border-b'
|
||||
}`}
|
||||
>
|
||||
{isDesktop && <NavHeader fairground={inverted} />}
|
||||
@ -124,7 +124,7 @@ const NavHeader = ({ fairground }: { fairground: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link to="/">
|
||||
{fairground ? (
|
||||
<Fish />
|
||||
@ -132,26 +132,24 @@ const NavHeader = ({ fairground }: { fairground: boolean }) => {
|
||||
<img alt="Vega" src={vegaWhite} height={30} width={30} />
|
||||
)}
|
||||
</Link>
|
||||
<div className="h-[30px] inline-flex items-center lg:h-40 uppercase">
|
||||
<h1
|
||||
data-testid="header-title"
|
||||
className={`text-h4 sm:text-h3 font-alpha uppercase calt mb-2 ${
|
||||
fairground ? 'text-black' : 'text-white'
|
||||
}`}
|
||||
>
|
||||
{fairground ? t('fairgroundTitle') : t('title')}
|
||||
</h1>
|
||||
</div>
|
||||
<h1
|
||||
data-testid="header-title"
|
||||
className={`uppercase md:text-2xl sm:text-lg font-alpha uppercase calt my-0 ${
|
||||
fairground ? 'text-black' : 'text-white'
|
||||
}`}
|
||||
>
|
||||
{fairground ? t('fairgroundTitle') : t('title')}
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DrawerSection = ({ children }: { children: React.ReactNode }) => (
|
||||
<div className="p-12">{children}</div>
|
||||
<div className="px-4 my-4">{children}</div>
|
||||
);
|
||||
|
||||
const IconLine = ({ inverted }: { inverted: boolean }) => (
|
||||
<span className={`block w-28 h-4 ${inverted ? 'bg-black' : 'bg-white'}`} />
|
||||
<span className={`block w-6 h-[2px] ${inverted ? 'bg-black' : 'bg-white'}`} />
|
||||
);
|
||||
|
||||
const NavDrawer = ({ inverted }: { inverted: boolean }) => {
|
||||
@ -162,7 +160,7 @@ const NavDrawer = ({ inverted }: { inverted: boolean }) => {
|
||||
// Positions the modal in the center of screen
|
||||
'fixed w-[80vw] max-w-[420px] top-0 right-0',
|
||||
'flex flex-col flex-nowrap justify-between h-full bg-banner overflow-y-scroll border-l border-white',
|
||||
'bg-black text-white-95'
|
||||
'bg-black text-neutral-200'
|
||||
);
|
||||
return (
|
||||
<>
|
||||
@ -173,7 +171,7 @@ const NavDrawer = ({ inverted }: { inverted: boolean }) => {
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
className="flex flex-col flex-nowrap gap-4"
|
||||
className="flex flex-col flex-nowrap gap-1"
|
||||
>
|
||||
<IconLine inverted={inverted} />
|
||||
<IconLine inverted={inverted} />
|
||||
@ -230,7 +228,7 @@ const NavLinks = ({
|
||||
{ route: Routes.GOVERNANCE, text: t('Governance') },
|
||||
];
|
||||
const navClasses = classNames('flex', {
|
||||
'flex-row gap-8 mt-8 uppercase': isDesktop,
|
||||
'flex-row gap-2 mt-4 uppercase': isDesktop,
|
||||
'flex-col': !isDesktop,
|
||||
});
|
||||
|
||||
@ -243,19 +241,16 @@ const NavLinks = ({
|
||||
to={route}
|
||||
key={route}
|
||||
className={({ isActive }) =>
|
||||
classNames(
|
||||
'no-underline hover:no-underline focus-visible:outline-none focus-visible:border-none focus-visible:shadow-inset-white',
|
||||
{
|
||||
'bg-vega-yellow text-black': !isInverted && isActive,
|
||||
'bg-transparent text-white hover:text-vega-yellow':
|
||||
!isInverted && !isActive,
|
||||
'bg-black text-white': isInverted && isActive,
|
||||
'bg-transparent text-black hover:text-white':
|
||||
isInverted && !isActive,
|
||||
'py-2 px-12': isDesktop,
|
||||
'border-t border-white p-20': !isDesktop,
|
||||
}
|
||||
)
|
||||
classNames({
|
||||
'bg-vega-yellow text-black': !isInverted && isActive,
|
||||
'bg-transparent text-white hover:text-vega-yellow':
|
||||
!isInverted && !isActive,
|
||||
'bg-black text-white': isInverted && isActive,
|
||||
'bg-transparent text-black hover:text-white':
|
||||
isInverted && !isActive,
|
||||
'py-1 px-2': isDesktop,
|
||||
'border-t border-white p-4': !isDesktop,
|
||||
})
|
||||
}
|
||||
>
|
||||
{text}
|
||||
|
@ -9,12 +9,12 @@ export interface TemplateSidebarProps {
|
||||
|
||||
export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
|
||||
return (
|
||||
<div className="row-start-2 border-b border-white lg:grid lg:grid-rows-[auto_minmax(600px,_1fr)] lg:grid-cols-[850px_450px]">
|
||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[min-content_1fr] lg:grid-cols-[1fr_450px]">
|
||||
<Nav />
|
||||
<main className="col-start-1 p-20">{children}</main>
|
||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-20 bg-banner bg-contain border-l border-white">
|
||||
<main className="col-start-1 p-4">{children}</main>
|
||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
||||
{sidebar.map((Component, i) => (
|
||||
<section className="mb-20 last:mb-0" key={i}>
|
||||
<section className="mb-4 last:mb-0" key={i}>
|
||||
{Component}
|
||||
</section>
|
||||
))}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
Intent,
|
||||
FormGroup,
|
||||
Lozenge,
|
||||
ButtonLink,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
@ -60,14 +61,14 @@ export const AmountInput = ({
|
||||
/>
|
||||
</div>
|
||||
{maximum && (
|
||||
<Button
|
||||
variant="inline-link"
|
||||
onClick={() => setAmount(maximum.toString())}
|
||||
data-testid="token-amount-use-maximum"
|
||||
className="flex flex-col justify-center p-8 h-28 my-0 mx-8"
|
||||
>
|
||||
{t('Use maximum')}
|
||||
</Button>
|
||||
<div className="flex flex-col justify-center p-8 h-28 my-0 mx-8">
|
||||
<ButtonLink
|
||||
onClick={() => setAmount(maximum.toString())}
|
||||
data-testid="token-amount-use-maximum"
|
||||
>
|
||||
{t('Use maximum')}
|
||||
</ButtonLink>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@ -158,7 +159,7 @@ export const TokenInput = ({
|
||||
approveContent = (
|
||||
<Button
|
||||
data-testid="token-input-approve-button"
|
||||
className="token-input__submit w-full"
|
||||
fill={true}
|
||||
onClick={approve}
|
||||
>
|
||||
{approveText}
|
||||
@ -176,9 +177,9 @@ export const TokenInput = ({
|
||||
return (
|
||||
<>
|
||||
<FormGroup
|
||||
labelClassName="sr-only"
|
||||
label={t('Input Amount')}
|
||||
labelFor={inputName}
|
||||
hideLabel={true}
|
||||
>
|
||||
<AmountInput
|
||||
amount={amount}
|
||||
@ -190,7 +191,7 @@ export const TokenInput = ({
|
||||
{approveContent ? <div className="mb-24">{approveContent}</div> : null}
|
||||
<Button
|
||||
data-testid="token-input-submit-button"
|
||||
className="w-full"
|
||||
fill={true}
|
||||
disabled={isDisabled}
|
||||
onClick={perform}
|
||||
>
|
||||
|
@ -13,7 +13,7 @@ import type { TxData } from '../../stores/transactions';
|
||||
import { useTransactionStore } from '../../stores/transactions';
|
||||
|
||||
const TransactionModalTh = ({ children }: { children: React.ReactNode }) => (
|
||||
<th className="border-b border-black-25 text-black-60 text-left font-normal">
|
||||
<th className="border-b border-neutral-600 text-neutral-600 text-left font-normal">
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
|
@ -6,9 +6,9 @@ export const DownloadWalletPrompt = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<h3 className="mt-12 mb-4">{t('getWallet')}</h3>
|
||||
<p className="mb-4">
|
||||
<Link className="text-deemphasise" href={Links.WALLET_PAGE}>
|
||||
<h3 className="mt-4 mb-2">{t('getWallet')}</h3>
|
||||
<p>
|
||||
<Link className="text-neutral-500" href={Links.WALLET_PAGE}>
|
||||
{t('getWalletLink')}
|
||||
</Link>
|
||||
</p>
|
||||
|
@ -24,7 +24,7 @@ import { DownloadWalletPrompt } from './download-wallet-prompt';
|
||||
import { usePollForDelegations } from './hooks';
|
||||
import type { VegaKeyExtended } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const VegaWallet = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -38,14 +38,14 @@ export const VegaWallet = () => {
|
||||
|
||||
return (
|
||||
<section className="vega-wallet" data-testid="vega-wallet">
|
||||
<WalletCard dark={true}>
|
||||
<WalletCard>
|
||||
<WalletCardHeader dark={true}>
|
||||
<h1 className="col-start-1 m-0">{t('vegaWallet')}</h1>
|
||||
{keypair && (
|
||||
<>
|
||||
<div
|
||||
data-testid="wallet-name"
|
||||
className="sm:row-start-2 sm:col-start-1 sm:col-span-2 text-h6 mb-12"
|
||||
className="sm:row-start-2 sm:col-start-1 sm:col-span-2 text-base mb-4"
|
||||
>
|
||||
{keypair.name}
|
||||
</div>
|
||||
@ -77,8 +77,7 @@ const VegaWalletNotConnected = () => {
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
variant="secondary"
|
||||
className="w-full"
|
||||
fill={true}
|
||||
data-testid="connect-vega"
|
||||
>
|
||||
{t('connectVegaWalletToUseAssociated')}
|
||||
@ -100,12 +99,10 @@ const VegaWalletAssetList = ({ accounts }: VegaWalletAssetsListProps) => {
|
||||
return (
|
||||
<>
|
||||
<WalletCardHeader>
|
||||
<BulletHeader style={{ border: 'none' }} tag="h2">
|
||||
{t('assets')}
|
||||
</BulletHeader>
|
||||
<BulletHeader tag="h2">{t('assets')}</BulletHeader>
|
||||
</WalletCardHeader>
|
||||
{accounts.map((a, i) => (
|
||||
<WalletCardAsset key={i} {...a} dark={true} />
|
||||
<WalletCardAsset key={i} {...a} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
@ -133,11 +130,9 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||
}, [currentStakeAvailable, delegations]);
|
||||
|
||||
const footer = (
|
||||
<WalletCardActions>
|
||||
<Button
|
||||
<div className="flex justify-end">
|
||||
<ButtonLink
|
||||
data-testid="manage-vega-wallet"
|
||||
variant="inline-link"
|
||||
className="mt-4"
|
||||
onClick={() =>
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_MANAGE_OVERLAY,
|
||||
@ -146,8 +141,8 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||
}
|
||||
>
|
||||
Manage
|
||||
</Button>
|
||||
</WalletCardActions>
|
||||
</ButtonLink>
|
||||
</div>
|
||||
);
|
||||
|
||||
return vegaKeys.length ? (
|
||||
@ -159,13 +154,12 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||
subheading={t('Associated')}
|
||||
symbol="VEGA"
|
||||
balance={currentStakeAvailable}
|
||||
dark={true}
|
||||
/>
|
||||
<div data-testid="vega-wallet-balance-unstaked">
|
||||
<WalletCardRow label={t('unstaked')} value={unstaked} dark={true} />
|
||||
<WalletCardRow label={t('unstaked')} value={unstaked} />
|
||||
</div>
|
||||
{delegatedNodes.length ? (
|
||||
<WalletCardRow label={t('stakedValidators')} dark={true} bold={true} />
|
||||
<WalletCardRow label={t('stakedValidators')} />
|
||||
) : null}
|
||||
{delegatedNodes.map((d) => (
|
||||
<div key={d.nodeId} data-testid="vega-wallet-balance-staked-validators">
|
||||
@ -177,7 +171,6 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||
}`}
|
||||
link={`${Routes.STAKING}/${d.nodeId}`}
|
||||
value={d.currentEpochStake}
|
||||
dark={true}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@ -189,20 +182,19 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||
)})`}
|
||||
link={`${Routes.STAKING}/${d.nodeId}`}
|
||||
value={d.nextEpochStake}
|
||||
dark={true}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<WalletCardActions>
|
||||
<Link className="flex-1 pr-8" to={Routes.GOVERNANCE}>
|
||||
<Button variant={'secondary'} className="w-full">
|
||||
<Link className="flex-1" to={Routes.GOVERNANCE}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('governance')}
|
||||
</Button>
|
||||
</Link>
|
||||
<Link className="flex-1 pl-8" to={Routes.STAKING}>
|
||||
<Button variant={'secondary'} className="w-full">
|
||||
<Link className="flex-1" to={Routes.STAKING}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('staking')}
|
||||
</Button>
|
||||
</Link>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
@ -8,19 +7,14 @@ import { useNumberParts } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface WalletCardProps {
|
||||
children: React.ReactNode;
|
||||
dark?: boolean;
|
||||
}
|
||||
|
||||
export const WalletCard = ({ dark, children }: WalletCardProps) => {
|
||||
const className = classNames(
|
||||
'text-ui border border-white',
|
||||
'pt-4 pl-8 pr-12 pb-12',
|
||||
{
|
||||
'bg-black text-white': dark,
|
||||
'bg-white text-black': !dark,
|
||||
}
|
||||
export const WalletCard = ({ children }: WalletCardProps) => {
|
||||
return (
|
||||
<div className="text-sm border border-neutral-700 p-4 bg-black text-white">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
return <div className={className}>{children}</div>;
|
||||
};
|
||||
|
||||
interface WalletCardHeaderProps {
|
||||
@ -31,7 +25,7 @@ interface WalletCardHeaderProps {
|
||||
export const WalletCardHeader = ({ children }: WalletCardHeaderProps) => {
|
||||
return (
|
||||
<div
|
||||
className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-4"
|
||||
className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-2 mb-2"
|
||||
data-testid="wallet-header"
|
||||
>
|
||||
{children}
|
||||
@ -44,23 +38,19 @@ interface WalletCardContentProps {
|
||||
}
|
||||
|
||||
export const WalletCardContent = ({ children }: WalletCardContentProps) => {
|
||||
return <div className="mt-8">{children}</div>;
|
||||
return <div>{children}</div>;
|
||||
};
|
||||
|
||||
export const WalletCardRow = ({
|
||||
label,
|
||||
link,
|
||||
value,
|
||||
dark = false,
|
||||
decimals = 18,
|
||||
bold = false,
|
||||
}: {
|
||||
label: string;
|
||||
link?: string;
|
||||
decimals?: number;
|
||||
value?: BigNumber | null;
|
||||
dark?: boolean;
|
||||
bold?: boolean;
|
||||
}) => {
|
||||
const ref = React.useRef<HTMLDivElement | null>(null);
|
||||
useAnimateValue(ref, value);
|
||||
@ -68,9 +58,7 @@ export const WalletCardRow = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex justify-between gap-y-0 gap-x-4 text-ui my-4 p-2 ${
|
||||
dark ? 'text-white-60' : 'text-black'
|
||||
} ${bold && 'font-bold'}`}
|
||||
className="flex justify-between gap-y-0 gap-x-2 text-sm mb-2"
|
||||
ref={ref}
|
||||
>
|
||||
{link ? (
|
||||
@ -78,10 +66,7 @@ export const WalletCardRow = ({
|
||||
{label}
|
||||
</Link>
|
||||
) : (
|
||||
<span
|
||||
className={`max-w-[200px] ${dark ? 'text-white' : 'text-black'}`}
|
||||
data-test-id="associated-key"
|
||||
>
|
||||
<span className="max-w-[200px]" data-test-id="associated-key">
|
||||
{label}
|
||||
</span>
|
||||
)}
|
||||
@ -90,12 +75,8 @@ export const WalletCardRow = ({
|
||||
className="font-mono flex-1 text-right"
|
||||
data-test-id="associated-amount"
|
||||
>
|
||||
<span className={dark ? 'text-white' : 'text-black'}>
|
||||
{integers}.
|
||||
</span>
|
||||
<span className={dark ? 'text-white-60' : 'text-black-60'}>
|
||||
{decimalsPlaces}
|
||||
</span>
|
||||
<span>{integers}.</span>
|
||||
<span>{decimalsPlaces}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -107,7 +88,7 @@ export const WalletCardActions = ({
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
return <div className="flex justify-end gap-2 py-2">{children}</div>;
|
||||
return <div className="flex justify-end gap-2 mb-4">{children}</div>;
|
||||
};
|
||||
|
||||
export interface WalletCardAssetProps {
|
||||
@ -117,7 +98,6 @@ export interface WalletCardAssetProps {
|
||||
balance: BigNumber;
|
||||
decimals: number;
|
||||
border?: boolean;
|
||||
dark?: boolean;
|
||||
subheading?: string;
|
||||
}
|
||||
|
||||
@ -128,48 +108,32 @@ export const WalletCardAsset = ({
|
||||
balance,
|
||||
decimals,
|
||||
border,
|
||||
dark,
|
||||
subheading,
|
||||
}: WalletCardAssetProps) => {
|
||||
const [integers, decimalsPlaces] = useNumberParts(balance, decimals);
|
||||
|
||||
return (
|
||||
<div className="flex flex-nowrap mt-8 mb-16">
|
||||
<div className="flex flex-nowrap mt-2 mb-4">
|
||||
<img
|
||||
alt="Vega"
|
||||
src={image}
|
||||
className={`inline-block h-[30px] rounded-[50%] border ${
|
||||
className={`inline-block w-6 h-6 mt-2 rounded-full border ${
|
||||
border ? 'border-white' : 'border-black'
|
||||
}`}
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
className="flex font-medium align-center"
|
||||
className="flex align-center text-base"
|
||||
data-testid="currency-title"
|
||||
>
|
||||
<h1
|
||||
className={`text-h5 mb-0 px-8 uppercase leading-none ${
|
||||
dark ? 'text-white' : 'text-black'
|
||||
}`}
|
||||
>
|
||||
{name}
|
||||
</h1>
|
||||
<h2
|
||||
className={`text-h5 mb-0 uppercase leading-none ${
|
||||
dark ? 'text-white-60' : 'text-black-60'
|
||||
}`}
|
||||
>
|
||||
<div className="mb-0 px-2 uppercase">{name}</div>
|
||||
<div className="mb-0 uppercase text-neutral-400">
|
||||
{subheading || symbol}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="px-8 text-h5 basis-full font-mono"
|
||||
data-testid="currency-value"
|
||||
>
|
||||
<div className="px-2 basis-full font-mono" data-testid="currency-value">
|
||||
<span>{integers}.</span>
|
||||
<span className={dark ? 'text-white-60' : 'text-black-60'}>
|
||||
{decimalsPlaces}
|
||||
</span>
|
||||
<span className="text-neutral-400">{decimalsPlaces}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import { usePrevious } from './use-previous';
|
||||
import type { BigNumber } from '../lib/bignumber';
|
||||
import { theme as tailwindcss } from '@vegaprotocol/tailwindcss-config';
|
||||
const Colors = tailwindcss.colors;
|
||||
import { theme } from '@vegaprotocol/tailwindcss-config';
|
||||
import colors from 'tailwindcss/colors';
|
||||
const customColors = theme.colors;
|
||||
|
||||
const FLASH_DURATION = 1200; // Duration of flash animation in milliseconds
|
||||
|
||||
@ -29,15 +30,15 @@ export function useAnimateValue(
|
||||
) {
|
||||
elRef.current?.animate(
|
||||
[
|
||||
{ backgroundColor: Colors.vega.red, color: Colors.white.DEFAULT },
|
||||
{ backgroundColor: customColors.vega.red, color: colors.white },
|
||||
{
|
||||
backgroundColor: Colors.vega.red,
|
||||
color: Colors.white.DEFAULT,
|
||||
backgroundColor: customColors.vega.red,
|
||||
color: colors.white,
|
||||
offset: 0.8,
|
||||
},
|
||||
{
|
||||
backgroundColor: Colors.white[60],
|
||||
color: Colors.white.DEFAULT,
|
||||
backgroundColor: colors.neutral[500],
|
||||
color: colors.white,
|
||||
},
|
||||
],
|
||||
FLASH_DURATION
|
||||
@ -52,17 +53,17 @@ export function useAnimateValue(
|
||||
elRef.current?.animate(
|
||||
[
|
||||
{
|
||||
backgroundColor: Colors.vega.green,
|
||||
color: Colors.white.DEFAULT,
|
||||
backgroundColor: customColors.vega.green,
|
||||
color: colors.white,
|
||||
},
|
||||
{
|
||||
backgroundColor: Colors.vega.green,
|
||||
color: Colors.white.DEFAULT,
|
||||
backgroundColor: customColors.vega.green,
|
||||
color: colors.white,
|
||||
offset: 0.8,
|
||||
},
|
||||
{
|
||||
backgroundColor: Colors.white[60],
|
||||
color: Colors.white.DEFAULT,
|
||||
backgroundColor: colors.neutral[500],
|
||||
color: colors.white,
|
||||
},
|
||||
],
|
||||
FLASH_DURATION
|
||||
|
@ -4,6 +4,6 @@ import { formatNumber as format } from '@vegaprotocol/react-helpers';
|
||||
export const formatNumber = (value: BigNumber, decimals?: number) => {
|
||||
return format(
|
||||
value,
|
||||
typeof decimals === 'undefined' ? Math.max(value.dp(), 2) : decimals
|
||||
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals
|
||||
);
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ export const ClaimFlow = ({
|
||||
return (
|
||||
<>
|
||||
<section>
|
||||
<div className="lg:grid lg:gap-24 lg:grid-cols-[1fr_1fr] lg:grid-rows-[min-content_min-content]">
|
||||
<div className="lg:grid lg:gap-6 lg:grid-cols-[1fr_1fr] lg:grid-rows-[min-content_min-content]">
|
||||
<div>
|
||||
<p>
|
||||
<Trans
|
||||
|
@ -76,7 +76,7 @@ export const ClaimForm = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Button type="submit" onClick={handleOnClick} className="fill">
|
||||
<Button type="submit" onClick={handleOnClick}>
|
||||
{countryCheck === CountryCheck.Pending
|
||||
? t('verifyingCountryPrompt')
|
||||
: t('Continue')}
|
||||
|
@ -40,7 +40,7 @@ export const ClaimStep2 = ({
|
||||
|
||||
return (
|
||||
<div data-testid="claim-step-2">
|
||||
<Button type="submit" onClick={onSubmit} className="fill">
|
||||
<Button type="submit" onClick={onSubmit}>
|
||||
{t('Claim {amount} Vega', { amount: formatNumber(amount) })}
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -57,7 +57,7 @@ export const Complete = ({
|
||||
</p>
|
||||
)}
|
||||
<RouteLink to={Routes.VESTING}>
|
||||
<Button className="fill">{t('Check your vesting VEGA tokens')}</Button>
|
||||
<Button>{t('Check your vesting VEGA tokens')}</Button>
|
||||
</RouteLink>
|
||||
</Callout>
|
||||
);
|
||||
|
@ -77,7 +77,7 @@ export const TargetedClaim = ({
|
||||
onSubmit={claimTargeted}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-white-60">{t('selectCountryPrompt')}</p>
|
||||
<p>{t('selectCountryPrompt')}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -99,7 +99,7 @@ export const UntargetedClaim = ({
|
||||
onSubmit={commitClaim}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-white-60">{t('selectCountryPrompt')}</p>
|
||||
<p>{t('selectCountryPrompt')}</p>
|
||||
)}
|
||||
<BulletHeader tag="h2">
|
||||
{t('Step')} 3. {t('Claim tokens')}
|
||||
@ -112,7 +112,7 @@ export const UntargetedClaim = ({
|
||||
onSubmit={commitReveal}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-white-60">{t('claimNotReady')}</p>
|
||||
<p>{t('claimNotReady')}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -16,7 +16,7 @@ export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
|
||||
const terms = proposal.terms;
|
||||
|
||||
return (
|
||||
<KeyValueTable data-testid="proposal-change-table" muted={true}>
|
||||
<KeyValueTable data-testid="proposal-change-table">
|
||||
<KeyValueTableRow>
|
||||
{t('id')}
|
||||
{proposal.id}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user