mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
@@ -0,0 +1,3 @@
|
||||
export default function delay(time: number) {
|
||||
return new Promise((resolve) => window.setTimeout(resolve, time));
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Skeleton as SkeletonComponent } from '@chakra-ui/react';
|
||||
import { keyframes } from '@chakra-ui/system';
|
||||
import type { SystemStyleFunction } from '@chakra-ui/theme-tools';
|
||||
import { getColor, mode } from '@chakra-ui/theme-tools';
|
||||
|
||||
const shine = () =>
|
||||
keyframes({
|
||||
to: { backgroundPositionX: '-200%' },
|
||||
});
|
||||
|
||||
const baseStyle: SystemStyleFunction = (props) => {
|
||||
const defaultStartColor = mode('blackAlpha.50', 'whiteAlpha.50')(props);
|
||||
const defaultEndColor = mode('blackAlpha.100', 'whiteAlpha.100')(props);
|
||||
|
||||
const {
|
||||
startColor = defaultStartColor,
|
||||
endColor = defaultEndColor,
|
||||
speed,
|
||||
theme,
|
||||
} = props;
|
||||
|
||||
const start = getColor(theme, startColor);
|
||||
const end = getColor(theme, endColor);
|
||||
|
||||
return {
|
||||
opacity: 1,
|
||||
borderRadius: 'base',
|
||||
borderColor: start,
|
||||
background: `linear-gradient(90deg, ${ start } 8%, ${ end } 18%, ${ start } 33%)`,
|
||||
backgroundSize: '200% 100%',
|
||||
animation: `${ speed }s linear infinite ${ shine() }`,
|
||||
};
|
||||
};
|
||||
|
||||
const Skeleton = {
|
||||
baseStyle,
|
||||
};
|
||||
|
||||
export default Skeleton;
|
||||
|
||||
SkeletonComponent.defaultProps = {
|
||||
...SkeletonComponent.defaultProps,
|
||||
speed: 1,
|
||||
};
|
||||
@@ -7,6 +7,7 @@ import Link from './Link';
|
||||
import Modal from './Modal';
|
||||
import Popover from './Popover';
|
||||
import Radio from './Radio';
|
||||
import Skeleton from './Skeleton';
|
||||
import Table from './Table';
|
||||
import Tabs from './Tabs';
|
||||
import Tag from './Tag';
|
||||
@@ -24,6 +25,7 @@ const components = {
|
||||
Modal,
|
||||
Popover,
|
||||
Radio,
|
||||
Skeleton,
|
||||
Tabs,
|
||||
Table,
|
||||
Tag,
|
||||
|
||||
@@ -18,7 +18,7 @@ interface Props {
|
||||
onDeleteClick: (item: ApiKey) => void;
|
||||
}
|
||||
|
||||
const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
|
||||
const ApiKeyTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
|
||||
|
||||
const onItemEditClick = useCallback(() => {
|
||||
return onEditClick(item);
|
||||
@@ -47,4 +47,4 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default WatchlistTableItem;
|
||||
export default ApiKeyTableItem;
|
||||
|
||||
@@ -22,8 +22,7 @@ import styles from './ColorModeToggler.module.css';
|
||||
export interface ColorModeTogglerProps
|
||||
extends Omit<UseCheckboxProps, 'isIndeterminate'>,
|
||||
Omit<HTMLChakraProps<'label'>, keyof UseCheckboxProps>,
|
||||
ThemingProps<'Switch'> {
|
||||
}
|
||||
ThemingProps<'Switch'> {}
|
||||
|
||||
const ColorModeToggler = forwardRef<ColorModeTogglerProps, 'input'>((props, ref) => {
|
||||
const ownProps = omitThemingProps(props);
|
||||
|
||||
+14
-10
@@ -1,4 +1,4 @@
|
||||
import { Box, Button, HStack, Link, Text, Spinner, useDisclosure } from '@chakra-ui/react';
|
||||
import { Box, Button, HStack, Link, Text, Skeleton, useDisclosure } from '@chakra-ui/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
@@ -10,6 +10,7 @@ import ApiKeyTable from 'ui/apiKey/ApiKeyTable/ApiKeyTable';
|
||||
import DeleteApiKeyModal from 'ui/apiKey/DeleteApiKeyModal';
|
||||
import AccountPageHeader from 'ui/shared/AccountPageHeader';
|
||||
import Page from 'ui/shared/Page/Page';
|
||||
import SkeletonTable from 'ui/shared/SkeletonTable';
|
||||
|
||||
const DATA_LIMIT = 3;
|
||||
|
||||
@@ -50,20 +51,23 @@ const ApiKeysPage: React.FC = () => {
|
||||
|
||||
const content = (() => {
|
||||
if (isLoading || isError) {
|
||||
return <Spinner/>;
|
||||
return (
|
||||
<>
|
||||
<SkeletonTable columns={ [ '100%', '108px' ] }/>
|
||||
<Skeleton height="44px" width="156px" marginTop={ 8 }/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const canAdd = data.length < DATA_LIMIT;
|
||||
return (
|
||||
<>
|
||||
{ data.length > 0 && (
|
||||
<ApiKeyTable
|
||||
data={ data }
|
||||
onDeleteClick={ onDeleteClick }
|
||||
onEditClick={ onEditClick }
|
||||
limit={ DATA_LIMIT }
|
||||
/>
|
||||
) }
|
||||
<ApiKeyTable
|
||||
data={ data }
|
||||
onDeleteClick={ onDeleteClick }
|
||||
onEditClick={ onEditClick }
|
||||
limit={ DATA_LIMIT }
|
||||
/>
|
||||
<HStack marginTop={ 8 } spacing={ 5 }>
|
||||
<Button
|
||||
variant="primary"
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Box, Button, Spinner, Text, useDisclosure } from '@chakra-ui/react';
|
||||
import { Box, Button, Text, Skeleton, useDisclosure } from '@chakra-ui/react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { AddressTags, AddressTag } from 'types/api/account';
|
||||
|
||||
import SkeletonTable from 'ui/shared/SkeletonTable';
|
||||
|
||||
import AddressModal from './AddressModal/AddressModal';
|
||||
import AddressTagTable from './AddressTagTable/AddressTagTable';
|
||||
import DeletePrivateTagModal from './DeletePrivateTagModal';
|
||||
|
||||
type Props = {
|
||||
addressTags: AddressTags;
|
||||
addressTags?: AddressTags;
|
||||
}
|
||||
|
||||
const PrivateAddressTags = ({ addressTags }: Props) => {
|
||||
@@ -38,13 +40,26 @@ const PrivateAddressTags = ({ addressTags }: Props) => {
|
||||
deleteModalProps.onClose();
|
||||
}, [ deleteModalProps ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text marginBottom={ 12 }>
|
||||
const description = (
|
||||
<Text marginBottom={ 12 }>
|
||||
Use private transaction tags to label any transactions of interest.
|
||||
Private tags are saved in your account and are only visible when you are logged in.
|
||||
</Text>
|
||||
{ !addressTags && <Spinner/> }
|
||||
</Text>
|
||||
);
|
||||
|
||||
if (!addressTags) {
|
||||
return (
|
||||
<>
|
||||
{ description }
|
||||
<SkeletonTable columns={ [ '60%', '40%', '108px' ] }/>
|
||||
<Skeleton height="44px" width="156px" marginTop={ 8 }/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ description }
|
||||
{ Boolean(addressTags?.length) && (
|
||||
<AddressTagTable
|
||||
data={ addressTags }
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Box, Button, Text, useDisclosure } from '@chakra-ui/react';
|
||||
import { Box, Button, Skeleton, Text, useDisclosure } from '@chakra-ui/react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { TransactionTags, TransactionTag } from 'types/api/account';
|
||||
|
||||
import SkeletonTable from 'ui/shared/SkeletonTable';
|
||||
|
||||
import DeletePrivateTagModal from './DeletePrivateTagModal';
|
||||
import TransactionModal from './TransactionModal/TransactionModal';
|
||||
import TransactionTagTable from './TransactionTagTable/TransactionTagTable';
|
||||
|
||||
type Props = {
|
||||
transactionTags: TransactionTags;
|
||||
transactionTags?: TransactionTags;
|
||||
}
|
||||
|
||||
const PrivateTransactionTags = ({ transactionTags }: Props) => {
|
||||
@@ -38,12 +40,26 @@ const PrivateTransactionTags = ({ transactionTags }: Props) => {
|
||||
deleteModalProps.onClose();
|
||||
}, [ deleteModalProps ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text marginBottom={ 12 }>
|
||||
const description = (
|
||||
<Text marginBottom={ 12 }>
|
||||
Use private transaction tags to label any transactions of interest.
|
||||
Private tags are saved in your account and are only visible when you are logged in.
|
||||
</Text>
|
||||
</Text>
|
||||
);
|
||||
|
||||
if (!transactionTags) {
|
||||
return (
|
||||
<>
|
||||
{ description }
|
||||
<SkeletonTable columns={ [ '75%', '25%', '108px' ] }/>
|
||||
<Skeleton height="44px" width="156px" marginTop={ 8 }/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ description }
|
||||
{ Boolean(transactionTags.length) && (
|
||||
<TransactionTagTable
|
||||
data={ transactionTags }
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Box, Text } from '@chakra-ui/react';
|
||||
import { keyframes } from '@chakra-ui/system';
|
||||
import React from 'react';
|
||||
|
||||
const runnerAnimation = keyframes`
|
||||
0% { left: 0%; transform: translateX(-1%); }
|
||||
100% { left: '100%'; transform: translateX(-99%); }
|
||||
`;
|
||||
|
||||
const ContentLoader = () => {
|
||||
return (
|
||||
<Box display="inline-block">
|
||||
<Box
|
||||
width="100%"
|
||||
height="6px"
|
||||
position="relative"
|
||||
_after={{
|
||||
content: `" "`,
|
||||
position: 'absolute',
|
||||
width: '60px',
|
||||
height: '6px',
|
||||
animation: `${ runnerAnimation } 700ms ease-in-out infinite alternate`,
|
||||
left: '100%',
|
||||
top: 0,
|
||||
backgroundColor: 'blue.300',
|
||||
borderRadius: 'full',
|
||||
}}
|
||||
/>
|
||||
<Text mt={ 6 } variant="secondary">Loading data, please wait... </Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContentLoader;
|
||||
@@ -0,0 +1,29 @@
|
||||
import { HStack, Skeleton } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
columns: Array<string>;
|
||||
}
|
||||
|
||||
const SkeletonTable = ({ columns }: Props) => {
|
||||
return (
|
||||
<div>
|
||||
<Skeleton height={ 10 } width="100%" borderBottomLeftRadius="none" borderBottomRightRadius="none"/>
|
||||
{ Array.from(Array(3)).map((item, index) => (
|
||||
<HStack key={ index } spacing={ 6 } marginTop={ 8 }>
|
||||
{ columns.map((width, index) => (
|
||||
<Skeleton
|
||||
key={ index }
|
||||
height={ 5 }
|
||||
width={ width }
|
||||
flexShrink={ width.includes('%') ? 'initial' : 0 }
|
||||
borderRadius="full"
|
||||
/>
|
||||
)) }
|
||||
</HStack>
|
||||
)) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SkeletonTable);
|
||||
Reference in New Issue
Block a user