@chakra-ui/react#Th TypeScript Examples
The following examples show how to use
@chakra-ui/react#Th.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DevicesTable.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
DevicesTable = ({ devices }: { devices: Array<DeviceItem> }): JSX.Element => {
return (
<Table variant="striped" colorScheme="blue" size='sm'>
<TableCaption>Devices registered for notifications over Google Play Services</TableCaption>
<Thead>
<Tr>
<Th>Name</Th>
<Th>ID</Th>
<Th isNumeric>Last Active</Th>
</Tr>
</Thead>
<Tbody>
{devices.map(item => (
<Tr key={item.name}>
<Td wordBreak='break-all'>{item.name}</Td>
<Td wordBreak='break-all'>{`${item.id.substring(0, 100)}...`}</Td>
<Td isNumeric>{new Date(item.lastActive).toLocaleString()}</Td>
</Tr>
))}
</Tbody>
</Table>
);
}
Example #2
Source File: LogsTable.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
LogsTable = ({ logs }: { logs: Array<LogItem> }): JSX.Element => {
return (
<Table variant="striped" colorScheme="blue" size='sm'>
<TableCaption>Logs will stream in as they come in</TableCaption>
<Thead>
<Tr>
<Th>Log</Th>
<Th isNumeric>Timestamp</Th>
</Tr>
</Thead>
<Tbody>
{logs.map(item => (
<Tr key={item.id}>
<Td wordBreak="break-word">{item.message}</Td>
<Td isNumeric>{item.timestamp.toLocaleString()}</Td>
</Tr>
))}
</Tbody>
</Table>
);
}
Example #3
Source File: NotificationsTable.tsx From bluebubbles-server with Apache License 2.0 | 6 votes |
NotificationsTable = ({ notifications }: { notifications: Array<NotificationItem> }): JSX.Element => {
return (
<Table variant="striped" colorScheme="blue">
<TableCaption>
Alerts are normal to have. As long as the server recovers,
you have nothing to worry about. Alerts are mostly helpful when you
are experiencing an issue and want to see if any errors have occured.
</TableCaption>
<Thead>
<Tr>
<Th>Type</Th>
<Th>Notification</Th>
<Th isNumeric>Time / Read</Th>
</Tr>
</Thead>
<Tbody>
{notifications.map(item => (
<Tr key={item.id} color={(item?.read ?? false) ? 'gray.400' : 'current'}>
<Td>
<Icon
ml={2}
fontSize="24"
as={AlertTypeIcon[item.type] ?? AiOutlineWarning}
/>
</Td>
<Td>{item.message}</Td>
<Td isNumeric>
<Flex flexDirection="row" justifyContent='flex-end' alignItems='center'>
<Text mr={1}>{item.timestamp.toLocaleString()}</Text>
{(item?.read ?? false) ? <BsCheckAll fontSize={24} /> : null}
</Flex>
</Td>
</Tr>
))}
</Tbody>
</Table>
);
}
Example #4
Source File: Lobby.tsx From dope-monorepo with GNU General Public License v3.0 | 6 votes |
Lobby = () => {
return (
<Layout>
<Stack>
<Flex
align="center"
border="2px"
borderRadius="md"
height={160}
justify="center"
>
RYO
</Flex>
<Container>
<ContainerHeader>
Lobby
</ContainerHeader>
<Table size="sm" color="white">
<Thead>
<Tr>
<Th>Starts</Th>
<Th isNumeric>Players</Th>
</Tr>
</Thead>
<Tbody>
{[0, 1, 2].map((match) => (
<MatchRow key={match} />
))}
</Tbody>
</Table>
</Container>
</Stack>
</Layout>
)
}
Example #5
Source File: OraclesTable.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
OraclesTable = ({
data,
oraclesMap,
}: {
data: any;
oraclesMap: {
[oracleAddr: string]: string[];
};
}) => {
return (
<Table variant="unstyled">
<Thead>
<Tr>
<Th color="white">Oracle:</Th>
<Th color="white">Assets</Th>
</Tr>
</Thead>
<Tbody>
{!!data.defaultOracle && (
<OracleRow
oracle={data.defaultOracle}
underlyings={[]}
isDefault={true}
/>
)}
{Object.keys(oraclesMap).map((oracle) => {
const underlyings = oraclesMap[oracle];
return <OracleRow oracle={oracle} underlyings={underlyings} />;
})}
</Tbody>
</Table>
);
}
Example #6
Source File: ControlAttendeesPage.tsx From takeout-app with MIT License | 5 votes |
ControlTrackCardsPage: React.FC = () => {
const [query, setQuery] = React.useState<string | null>(null);
const [errorAlert, setErrorAlert] = React.useState<JSX.Element | null>(null);
const { register, handleSubmit } = useForm<{
query: string;
}>({ defaultValues: { query: "" } });
const { data: list, isValidating } = ControlApi.useAttendeeList(query);
const onSubmit = handleSubmit(async (data) => {
setQuery(data.query);
});
// TODO: link to registration page and support email
return (
<>
{errorAlert}
<Container mt="20px" maxW={["auto", "auto", "auto", "1400px"]}>
<Box>
<form onSubmit={onSubmit}>
<Input {...register("query")} placeholder="Name, reference code (or submit empty to list all attendees)" />
<Button mt={4} size="lg" type="submit" isLoading={isValidating}>
Search
</Button>
</form>
</Box>
{list ? (
<Box>
<Table>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Reference</Th>
<Th>Flag</Th>
</Tr>
</Thead>
<Tbody>
{list.items.map((item) => (
<Tr key={item.ticket.id}>
<Td>
<Link as={RouterLink} to={`/control/attendees/${item.ticket.id}`}>
{item.attendee.is_ready ? (
<span>{item.attendee.name}</span>
) : (
<i>
{item.ticket.first_name} {item.ticket.last_name}
</i>
)}
</Link>
</Td>
<Td>
<Link href={item.ticket.admin_url} isExternal>
{item.ticket.reference}
</Link>
</Td>
<Td>
{[
item.attendee.is_speaker ? "Speaker" : null,
item.attendee.is_committer ? "Committer" : null,
item.attendee.is_staff ? "Staff" : null,
]
.filter((v): v is string => !!v)
.join(", ")}
</Td>
</Tr>
))}
</Tbody>
</Table>
</Box>
) : null}
</Container>
</>
);
}
Example #7
Source File: mdxComponents.tsx From lucide with ISC License | 5 votes |
components = {
h1: (props) => (
<HeadingAnchored as="h1" size="xl" mb={4} {...props}/>
),
h2: ({children, ...rest}) => (
<HeadingAnchored as="h2" size="lg" py={4} { ...rest}>
{children}
<Divider mt={4}/>
</HeadingAnchored>
),
h3: (props) => (
<HeadingAnchored as="h3" size="md" pt={4} mb={4} {...props}/>
),
h4: (props) => (
<HeadingAnchored as="h4" size="sm" pt={4} mb={4} {...props}/>
),
h5: (props) => (
<HeadingAnchored as="h5" size="xs" pt={2} mb={1} {...props}/>
),
h6: (props) => (
<HeadingAnchored as="h6" size="xs" pt={2} mb={1} opacity={.75} {...props}/>
),
ul: (props) => <UnorderedList my={2}>{props.children}</UnorderedList>,
ol: (props) => <OrderedList my={2}>{props.children}</OrderedList>,
li: (props) => <ListItem my={1}>{props.children}</ListItem>,
p: (props) => <Text my={4}>{props.children}</Text>,
img: ({ children, ...rest }) => <Image {...rest} borderRadius={4} my={2}>{children}</Image>,
code: ({ className, children: code }) => {
const language = className.replace('language-', '');
return (
<CodeBlock
//@ts-ignore
my={6}
code={code}
language={language}
/>
)
},
table: (props) => <Table {...props} rounded={4} mb={4}/>,
thead: Thead,
tbody: Tbody,
tr: Tr,
th: Th,
td: Td,
blockquote: (props) => (
<Alert
mt="4"
role="none"
status="warning"
variant="left-accent"
as="blockquote"
rounded={4}
my="1.5rem"
{...props}
/>
),
inlineCode: InlineCode,
hr: (props) => <Divider my={4}/>,
a: ({children, href, ...rest}) => {
let link = href
const isExternal = link.startsWith('http')
if(link.startsWith('packages/')) {
link = href.replace('packages/', '')
}
link = link.replace('.md', '')
return (
<NextLink
href={isExternal ? href : `/docs/${link}`}
{...rest}
passHref
>
<Link isExternal={isExternal} color='#F56565'>{children}</Link>
</NextLink>
)
}
}
Example #8
Source File: Drugs.tsx From dope-monorepo with GNU General Public License v3.0 | 5 votes |
Drugs = () => {
const { data } = useDrugsQuery();
const drugs = useMemo(() => {
if (!data?.items.edges) return [];
return data.items.edges.reduce((result, edge) => {
if (!edge || !edge.node) return result;
const { node } = edge;
return [
...result,
{
id: node.id,
name: node?.name,
cost: 10,
quantity: 1,
rle: node?.rles ? node?.rles?.male : node?.base?.rles?.male,
},
];
}, [] as Drug[]);
}, [data]);
return (
<Box px={3}>
<Table size="sm" color="white">
<Thead>
<Tr>
<Th></Th>
<Th>Product</Th>
<Th isNumeric>Cost</Th>
<Th isNumeric>Quantity</Th>
</Tr>
</Thead>
<Tbody>
{drugs.map(drug => (
<DrugRow key={drug.name} drug={drug} />
))}
</Tbody>
</Table>
</Box>
);
}
Example #9
Source File: StatsEarnSection.tsx From rari-dApp with GNU Affero General Public License v3.0 | 5 votes |
Earn = () => {
const { totals, aggregatePoolsInfo } = useAggregatePoolInfos();
const { t } = useTranslation();
const hasDeposits = useMemo(() => totals.balance > 0, [totals.balance]);
return (
<motion.div
key="earn"
style={{ width: "100%" }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Table variant="simple">
<Thead color="white">
<Tr>
<Th color="white">{t("Pool")}</Th>
<Th color="white" textAlign="right">
{t("APY")}
</Th>
<Th color="white" textAlign="right">
{t("Deposits")}
</Th>
<Th color="white" textAlign="right">
{t("Interest")}
</Th>
<Th color="white" textAlign="right">
{t("Growth")}
</Th>
</Tr>
</Thead>
<Tbody>
{aggregatePoolsInfo?.map((aggPoolInfo) => {
if (aggPoolInfo?.poolBalance && !aggPoolInfo.poolBalance.isZero()) {
return (
<Tr key={aggPoolInfo.poolInfo.title}>
<Td>{aggPoolInfo.poolInfo.title}</Td>
<Td textAlign="right">
{aggPoolInfo.poolAPY ?? <Spinner />}%
</Td>
<Td textAlign="right">
{aggPoolInfo.formattedPoolBalance ?? <Spinner />}
</Td>
<Td textAlign="right">
{aggPoolInfo.formattedPoolInterestEarned ?? <Spinner />}
</Td>
<Td textAlign="right">
{aggPoolInfo.formattedPoolGrowth ?? <Spinner />}%
</Td>
</Tr>
);
} else return null;
})}
{/* Todo (sharad) - implement totals for apy and growth */}
<Tr fontWeight={hasDeposits ? "bold" : "normal"}>
<Td>
<Text>{t("Total")}</Text>
</Td>
<Td textAlign="right"></Td>
<Td textAlign="right">
<Text>{smallUsdFormatter(totals?.balance)}</Text>
</Td>
<Td textAlign="right">
<Text>{totals?.interestEarned}</Text>
</Td>
<Td textAlign="right"></Td>
</Tr>
</Tbody>
</Table>
</motion.div>
);
}
Example #10
Source File: WebhooksTable.tsx From bluebubbles-server with Apache License 2.0 | 5 votes |
WebhooksTable = ({ webhooks }: { webhooks: Array<WebhookItem> }): JSX.Element => {
const dispatch = useAppDispatch();
const dialogRef = useRef(null);
const [selectedId, setSelectedId] = useState(undefined as number | undefined);
return (
<Box>
<Table variant="striped" colorScheme="blue">
<TableCaption>These are callbacks to receive events from the BlueBubbles Server</TableCaption>
<Thead>
<Tr>
<Th>URL</Th>
<Th>Event Subscriptions</Th>
<Th isNumeric>Actions</Th>
</Tr>
</Thead>
<Tbody>
{webhooks.map(item => (
<Tr key={item.id}>
<Td>{item.url}</Td>
<Td>{JSON.parse(item.events).map((e: string) => webhookEventValueToLabel(e)).join(', ')}</Td>
<Td isNumeric>
<Grid templateColumns="repeat(2, 1fr)">
<Tooltip label='Edit' placement='bottom'>
<GridItem _hover={{ cursor: 'pointer' }} onClick={() => setSelectedId(item.id)}>
<Icon as={AiOutlineEdit} />
</GridItem>
</Tooltip>
<Tooltip label='Delete' placement='bottom'>
<GridItem _hover={{ cursor: 'pointer' }} onClick={() => dispatch(remove(item.id))}>
<Icon as={FiTrash} />
</GridItem>
</Tooltip>
</Grid>
</Td>
</Tr>
))}
</Tbody>
</Table>
<AddWebhookDialog
existingId={selectedId}
modalRef={dialogRef}
isOpen={!!selectedId}
onClose={() => {
setSelectedId(undefined);
}}
/>
</Box>
);
}
Example #11
Source File: StatsFuseSection.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
Fuse = () => {
// Todo - write useFusePoolsData
const { filteredPools } = useFusePools("my-pools");
const { t } = useTranslation();
const poolIds: number[] = filteredPools?.map(({ id }) => id) ?? [];
const fusePoolsData: FusePoolData[] | null = useFusePoolsData(poolIds);
const assetsArray: USDPricedFuseAsset[][] | null =
fusePoolsData?.map((pool) => pool?.assets) ?? null;
const maxBorrows = useBorrowLimits(assetsArray);
const { tokensDataMap }: { tokensDataMap: TokensDataHash } =
useAssetsMapWithTokenData(assetsArray);
const totalBorrowBalanceUSD =
fusePoolsData?.reduce((a, b) => {
return a + b.totalBorrowBalanceUSD;
}, 0) ?? 0;
const totalSupplyBalanceUSD =
fusePoolsData?.reduce((a, b) => {
return a + b.totalSupplyBalanceUSD;
}, 0) ?? 0;
const hasDeposits = useMemo(
() => totalSupplyBalanceUSD > 0,
[totalSupplyBalanceUSD]
);
return (
<motion.div
key="fuse"
style={{ width: "100%" }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Table variant="simple">
<Thead color="white">
<Tr>
<Th textAlign="center" color="white">
{t("Pool")}
</Th>
<Th textAlign="right" color="white">
{t("Borrow Limit")}
</Th>
<Th textAlign="right" color="white">
{t("Deposits")}
</Th>
<Th textAlign="right" color="white">
{t("Borrows")}
</Th>
<Th textAlign="right" color="white">
{`${t("Lend APY")} / ${t("Borrow APY")}`}
</Th>
</Tr>
</Thead>
<Tbody>
{filteredPools?.map((filteredPool, index) => {
const fusePoolData = fusePoolsData?.[index];
const maxBorrow = maxBorrows?.[index];
const ratio =
fusePoolData?.totalBorrowBalanceUSD && maxBorrow
? (fusePoolData.totalBorrowBalanceUSD / maxBorrow) * 100
: 0;
const isAtRiskOfLiquidation = ratio && ratio > 95;
return (
<Tr key={filteredPool.id}>
<Td textAlign="center" fontSize="large">
{filteredPool.id}
</Td>
{/* Borrow limit */}
<Td
textAlign="right"
textStyle="bold"
color={isAtRiskOfLiquidation ? "red" : "#FFF"}
fontSize="large"
fontWeight="bold"
>
{!!ratio ? `${ratio.toFixed(1)}%` : "0%"}
</Td>
{/* Deposits By Asset */}
{/* Lend Balance */}
<Td textAlign="right">
{fusePoolData?.assets.map(
(asset: USDPricedFuseAsset) =>
asset.supplyBalanceUSD > 0 && (
<Box mt={2}>
<AssetContainer
asset={asset}
tokenData={tokensDataMap[asset.underlyingToken]}
/>
</Box>
)
)}
</Td>
{/* Borrow Balance */}
<Td textAlign="right">
{fusePoolData?.assets.map(
(asset: USDPricedFuseAsset) =>
asset.borrowBalanceUSD > 0 && (
<Box mt={2}>
<AssetContainer
asset={asset}
type={AssetContainerType.BORROW}
tokenData={tokensDataMap[asset.underlyingToken]}
/>
</Box>
)
)}
</Td>
{/* Lend Borrow rates */}
<Td textAlign="right">
{fusePoolData?.assets.map(
(asset: USDPricedFuseAsset) =>
(asset.supplyBalanceUSD > 0 ||
asset.borrowBalanceUSD > 0) && (
<Box mt={4}>
<AssetContainer
asset={asset}
type={AssetContainerType.RATES}
tokenData={tokensDataMap[asset.underlyingToken]}
/>
</Box>
)
)}
</Td>
</Tr>
);
})}
{/* Totals */}
<Tr fontWeight={hasDeposits ? "bold" : "normal"}>
<Td>
<Text>Total</Text>
</Td>
<Td textAlign="right"></Td>
<Td textAlign="right">
<Text>{smallUsdFormatter(totalSupplyBalanceUSD)}</Text>
</Td>
<Td textAlign="right">
<Text>-{smallUsdFormatter(totalBorrowBalanceUSD)}</Text>
</Td>
<Td textAlign="right"></Td>
</Tr>
</Tbody>
</Table>
</motion.div>
);
}
Example #12
Source File: StatsPool2Section.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
Earn = () => {
const { t } = useTranslation();
const apr = usePool2APR();
const earned = usePool2UnclaimedRGT();
const balance = usePool2Balance();
const balanceSLP = balance?.hasDeposited ? balance.SLP!.toFixed(4) : "0.0000";
const balanceETH = balance?.hasDeposited ? balance.eth!.toFixed(2) : "0.0000";
const balanceRGT = balance?.hasDeposited ? balance.rgt!.toFixed(2) : "0.0000";
const balanceUSD = balance?.hasDeposited
? smallUsdFormatter(balance.balanceUSD)
: "$0";
const hasDeposits = useMemo(() => earned! > 0, [earned]);
return (
<motion.div
key="pool2"
style={{ width: "100%" }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Table variant="simple">
<Thead color="white">
<Tr>
<Th color="white">{t("Pool")}</Th>
<Th color="white" textAlign="right">
{t("APY")}
</Th>
<Th color="white" textAlign="right">
{t("Deposits")}
</Th>
<Th color="white" textAlign="right">
{t("RGT Earned")}
</Th>
<Th color="white" textAlign="right">
{t("Growth")}
</Th>
</Tr>
</Thead>
<Tbody>
<>
{hasDeposits && (
<Tr>
<Td>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
>
<Box>
<Avatar
bg="#FFF"
boxSize="30px"
name={"RGT"}
src="https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xD291E7a03283640FDc51b121aC401383A46cC623/logo.png"
/>
<Avatar
bg="#FFF"
boxSize="30px"
name={"ETH"}
src="https://icons.iconarchive.com/icons/cjdowner/cryptocurrency-flat/64/Ethereum-ETH-icon.png"
/>
</Box>
<Box ml={3}>RGT-ETH</Box>
</Row>
</Td>
<Td textAlign="right">{apr}%</Td>
<Td textAlign="right">
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
>
<Box>{balanceSLP} RGT-ETH</Box>
<SimpleTooltip
label={`${balanceRGT} RGT - ${balanceETH} ETH `}
placement="top-start"
>
<Box
ml={4}
my="auto"
_hover={{ color: "gray", cursor: "auto" }}
>
<QuestionOutlineIcon color="currentColor" />
</Box>
</SimpleTooltip>
</Row>
</Td>
<Td textAlign="right">{earned?.toFixed(2)} RGT</Td>
<Td textAlign="right">0%</Td>
</Tr>
)}
{/* Todo (sharad) - implement totals for apy and growth */}
<Tr>
<Td>
<Text fontWeight={hasDeposits ? "bold" : "normal"}>Total</Text>
</Td>
<Td textAlign="right">
<Text fontWeight={hasDeposits ? "bold" : "normal"}>
{parseFloat(balanceSLP) > 0 ? `${apr}%` : null}
</Text>
</Td>
<Td textAlign="right">
<Text fontWeight={hasDeposits ? "bold" : "normal"}>
{balanceUSD}
</Text>
</Td>
<Td textAlign="right">
<Text fontWeight={hasDeposits ? "bold" : "normal"}>
{earned?.toFixed(2)} RGT
</Text>
</Td>
<Td textAlign="right"> </Td>
</Tr>
</>
</Tbody>
</Table>
</motion.div>
);
}
Example #13
Source File: StatsTranchesSection.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
Earn = () => {
const { t } = useTranslation();
const mySaffronData: SaffronTranchePool[] = useMySaffronData();
const daiSPrincipal = usePrincipal(TranchePool.DAI, TrancheRating.S);
const daiAPrincipal = usePrincipal(TranchePool.DAI, TrancheRating.A);
const estimatedSFI = useEstimatedSFI();
const totalPrincipalFormatted = usePrincipalBalance();
const totalPrincipal: number = totalPrincipalFormatted
? parseFloat(totalPrincipalFormatted?.replace(",", "").replace("$", ""))
: 0;
const hasDeposits = useMemo(() => totalPrincipal > 0, [totalPrincipal]);
return (
<motion.div
key="pool2"
style={{ width: "100%" }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Table variant="simple">
<Thead color="white">
<Tr>
<Th color="white">{t("Pool")}</Th>
<Th color="white" textAlign="right">
{t("APY")}
</Th>
<Th color="white" textAlign="right">
{t("Deposits")}
</Th>
<Th color="white" textAlign="right">
{t("Est. SFI Earnings")}
</Th>
<Th color="white" textAlign="right">
{t("Growth")}
</Th>
</Tr>
</Thead>
<Tbody>
<>
{/* DAI S Pool */}
{hasDeposits && (
<>
<Tr>
<Td textAlign="right">
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
>
<Box>
<Text textAlign="right"> {t("DAI-S")} </Text>
</Box>
</Row>
</Td>
<Td textAlign="right">
<Text>
{
mySaffronData?.[0]?.tranches?.[TrancheRating.S]?.[
"total-apy"
]
}
%
</Text>
</Td>
<Td textAlign="right">
<Text>
{daiSPrincipal} {t("DAI")}
</Text>
</Td>
<Td textAlign="right">
<Text>{estimatedSFI?.formattedSPoolSFIEarned}</Text>
</Td>
<Td textAlign="right">
<Text textAlign="right">{t("N/A")}</Text>
</Td>
</Tr>
<Tr>
<Td>
<Row
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
>
<Box>
<Text textAlign="right"> {t("DAI-A")} </Text>
</Box>
</Row>
</Td>
<Td>
<Text textAlign="right">
{
mySaffronData?.[0]?.tranches?.[TrancheRating.A]?.[
"total-apy"
]
}
%
</Text>
</Td>
<Td>
<Text textAlign="right">
{daiAPrincipal} {t("DAI")}
</Text>
</Td>
<Td>
{" "}
<Text textAlign="right">
{estimatedSFI?.formattedAPoolSFIEarned}
</Text>{" "}
</Td>
<Td>
<Text textAlign="right">{t("N/A")}</Text>
</Td>
</Tr>
</>
)}
{/* Totals */}
<Tr fontWeight={hasDeposits ? "bold" : "normal"}>
<Td>
<Text>{t("Total")}</Text>
</Td>
<Td>
<Text textAlign="right"></Text>
</Td>
<Td>
<Text textAlign="right">
{smallUsdFormatter(totalPrincipal) ?? 0}
</Text>
</Td>
<Td>
<Text textAlign="right">
{estimatedSFI?.formattedTotalSFIEarned ?? "0 SFI"}
</Text>
</Td>
<Td>
<Text textAlign="right" />
</Td>
</Tr>
</>
</Tbody>
</Table>
</motion.div>
);
}
Example #14
Source File: StatsTotalSection.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
StatsTotalSection = ({
setNetDeposits,
setNetDebt,
}: {
setNetDeposits: (input: number) => void;
setNetDebt: (input: number) => void;
}) => {
const { t } = useTranslation();
// Earn
const { totals, aggregatePoolsInfo }: AggregatePoolsInfoReturn =
useAggregatePoolInfos();
const hasDepositsInEarn = aggregatePoolsInfo?.some(
(p) => !p?.poolBalance?.isZero()
);
// Fuse
const { filteredPools: filteredFusePools } = useFusePools("my-pools");
const poolIds: number[] = filteredFusePools?.map(({ id }) => id) ?? [];
const fusePoolsData: FusePoolData[] | null = useFusePoolsData(poolIds);
// Pool2
const apr = usePool2APR();
const earned = usePool2UnclaimedRGT();
const balance = usePool2Balance();
const hasDepositsInPool2 = !!balance?.SLP;
// Tranches
const daiSPrincipal: string | undefined = usePrincipal(
TranchePool.DAI,
TrancheRating.S
);
const daiAPrincipal: string | undefined = usePrincipal(
TranchePool.DAI,
TrancheRating.A
);
const totalPrincipal: string | undefined = usePrincipalBalance();
const parsedTotalPrincipal: number = totalPrincipal
? parseFloat(totalPrincipal?.replace(",", "").replace("$", ""))
: 0;
const estimatedSFI: UseEstimatedSFIReturn | undefined = useEstimatedSFI();
const hasDepositsInTranches = useMemo(
() => parsedTotalPrincipal > 0 ?? false,
[parsedTotalPrincipal]
);
// Total Deposits
const totalDepositsUSD = useMemo(() => {
const { totalSupplyBalanceUSD: fuseTotal }: FusePoolData =
fusePoolsData?.reduce((a, b) => {
return {
totalSupplyBalanceUSD:
a.totalSupplyBalanceUSD + b.totalSupplyBalanceUSD,
} as FusePoolData;
}) ?? ({ totalSupplyBalanceUSD: 0 } as FusePoolData);
const vaultTotal = totals?.balance ?? 0;
const pool2Total = balance?.balanceUSD ?? 0;
const tranchesTotal = parsedTotalPrincipal ?? 0;
const total = fuseTotal + vaultTotal + pool2Total + tranchesTotal;
return total;
}, [totals, fusePoolsData, balance, parsedTotalPrincipal]);
// Total debt - todo: refactor into the `useFusePoolsData` hook
const totalDebtUSD = useMemo(() => {
const { totalBorrowBalanceUSD }: FusePoolData =
fusePoolsData?.reduce((a, b) => {
return {
totalBorrowBalanceUSD:
a.totalBorrowBalanceUSD + b.totalBorrowBalanceUSD,
} as FusePoolData;
}) ?? ({ totalBorrowBalanceUSD: 0 } as FusePoolData);
return totalBorrowBalanceUSD;
}, [fusePoolsData]);
useEffect(() => {
if (totalDepositsUSD && !Number.isNaN(totalDepositsUSD))
setNetDeposits(totalDepositsUSD);
if (totalDebtUSD && !Number.isNaN(totalDebtUSD)) setNetDebt(totalDebtUSD);
}, [totalDepositsUSD, totalDebtUSD, setNetDeposits, setNetDebt]);
const earnedHeaderText = hasDepositsInTranches
? "RGT + SFI Earned"
: "RGT Earned";
return (
<motion.div
key="totals"
style={{ width: "100%" }}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<Table variant="simple">
<Thead color="white">
<Tr>
<Th color="white">{t("Product")}</Th>
<Th color="white" textAlign="right">
{t("Pool")}
</Th>
<Th color="white" textAlign="right">
{t("Deposits")}
</Th>
<Th color="white" textAlign="right">
{t(earnedHeaderText)}
</Th>
<Th color="white" textAlign="right">
Interest Earned
</Th>
</Tr>
</Thead>
<Tbody>
{/* Fuse section */}
{fusePoolsData && (
<FuseRow
fusePoolsData={fusePoolsData}
filteredPoolsData={filteredFusePools}
/>
)}
{/* earn section */}
{hasDepositsInEarn && <EarnRow poolsInfo={aggregatePoolsInfo} />}
{/* Pool2 Section */}
{hasDepositsInPool2 && (
<Pool2Row apr={apr} earned={earned} balance={balance} />
)}
{/* Tranches */}
{hasDepositsInTranches && (
<TranchesRow
daiSPrincipal={daiSPrincipal}
daiAPrincipal={daiAPrincipal}
estimatedSFI={estimatedSFI}
/>
)}
{/* Todo (sharad) - implement totals for apy and growth */}
<motion.tr
initial={{ opacity: 0, y: -40 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 40 }}
>
<Td fontWeight="bold">{t("Total")}</Td>
<Td textAlign="right"></Td>
<Td textAlign="right">
<Text fontWeight="bold">
{smallUsdFormatter(totalDepositsUSD)}
</Text>
</Td>
<Td textAlign="right">
<Text fontWeight="bold">
{earned?.toFixed(2)} RGT
{hasDepositsInTranches &&
` + ${estimatedSFI?.formattedTotalSFIEarned}`}
</Text>
</Td>
<Td textAlign="right">
<Text fontWeight="bold">{totals?.interestEarned}</Text>
</Td>
</motion.tr>
</Tbody>
</Table>
</motion.div>
);
}
Example #15
Source File: DopeTable.tsx From dope-monorepo with GNU General Public License v3.0 | 4 votes |
DopeTable = ({ className = '', data, selected, onSelect }: DopeTableProps) => {
const [sort, setSort] = useState('id');
const amountOfUnclaimedPaper = (): number => {
const paperPerToken = 125000;
let numberUnclaimed = 0;
for (const item of data) {
numberUnclaimed = item.claimed ? numberUnclaimed : numberUnclaimed + 1;
}
return numberUnclaimed * paperPerToken;
};
const formattedUnclaimedPaper = (): string => {
const formatter = Intl.NumberFormat('en', { notation: 'compact' });
return formatter.format(amountOfUnclaimedPaper());
};
const items = useMemo(
() =>
data
.map(({ id, opened, claimed, rank }, idx) => ({
id,
rank,
opened: opened ? (
''
) : (
<Check
css={css`
display: inline;
`}
/>
),
claimed: claimed ? (
''
) : (
<Check
css={css`
display: inline;
`}
/>
),
idx,
}))
.sort((a, b) => {
switch (sort) {
case 'id':
return a.id < b.id ? -1 : 1;
case 'rank':
return a.rank < b.rank ? -1 : 1;
default:
return a.id > b.id ? -1 : 1;
}
}),
[data, sort],
);
return (
<PanelContainer
className={className}
css={css`
tfoot th {
// Screen > Tablet display items side by side
span.separator {
display: block;
height: 0;
margin: 0;
padding: 0;
overflow: hidden;
${media.tablet`
display: inline;
font-size: var(--text-00);
height: auto;
padding: 8px;
color: #a8a9ae;
`}
}
}
`}
>
<div
css={css`
display: flex;
min-height: 100%;
flex-direction: column;
// justify-content: space-around;
// align-items: stretch;
`}
>
<Table variant="dope">
<colgroup>
<col width="25%" />
<col width="25%" />
<col width="25%" />
<col width="25%" />
</colgroup>
<Thead>
<Tr>
<Th onClick={() => setSort('id')}>Dope ID</Th>
<Th onClick={() => setSort('rank')}>Rank</Th>
<Th>Has Paper</Th>
<Th>Has Gear</Th>
</Tr>
</Thead>
<Tbody>
{items.map(({ id, rank, opened, claimed, idx }) => (
<Tr
className={selected === idx ? 'selected' : ''}
key={id}
onClick={() => onSelect(idx)}
>
<Td>{id}</Td>
<Td>{rank}</Td>
<Td>{claimed}</Td>
<Td>{opened}</Td>
</Tr>
))}
</Tbody>
<Tfoot>
<Th colSpan={4}>
{items.length} DOPE {items.length > 1 ? 'Tokens' : 'Token'}
<span
className="separator"
css={css`
padding: 8px;
color: rgb(168, 169, 174);
`}
>
/
</span>
{formattedUnclaimedPaper()} Unclaimed $PAPER
</Th>
</Tfoot>
</Table>
</div>
</PanelContainer>
);
}
Example #16
Source File: FusePoolEditPage.tsx From rari-dApp with GNU Affero General Public License v3.0 | 4 votes |
FusePoolEditPage = memo(() => {
const { isAuthed } = useRari();
const isMobile = useIsSemiSmallScreen();
const {
isOpen: isAddAssetModalOpen,
onOpen: openAddAssetModal,
onClose: closeAddAssetModal,
} = useDisclosure();
const {
isOpen: isAddRewardsDistributorModalOpen,
onOpen: openAddRewardsDistributorModal,
onClose: closeAddRewardsDistributorModal,
} = useDisclosure();
const {
isOpen: isEditRewardsDistributorModalOpen,
onOpen: openEditRewardsDistributorModal,
onClose: closeEditRewardsDistributorModal,
} = useDisclosure();
const authedOpenModal = useAuthedCallback(openAddAssetModal);
const { t } = useTranslation();
const { poolId } = useParams();
const data = useFusePoolData(poolId);
const isAdmin = useIsComptrollerAdmin(data?.comptroller);
// RewardsDistributor stuff
const poolIncentives = usePoolIncentives(data?.comptroller);
const rewardsDistributors = useRewardsDistributorsForPool(data?.comptroller);
const [rewardsDistributor, setRewardsDistributor] = useState<
RewardsDistributor | undefined
>();
console.log({ rewardsDistributors, poolIncentives });
const handleRewardsRowClick = useCallback(
(rD: RewardsDistributor) => {
setRewardsDistributor(rD);
openEditRewardsDistributorModal();
},
[setRewardsDistributor, openEditRewardsDistributorModal]
);
return (
<>
{data ? (
<AddAssetModal
comptrollerAddress={data.comptroller}
poolOracleAddress={data.oracle}
oracleModel={data.oracleModel}
existingAssets={data.assets}
poolName={data.name}
poolID={poolId!}
isOpen={isAddAssetModalOpen}
onClose={closeAddAssetModal}
/>
) : null}
{data ? (
<AddRewardsDistributorModal
comptrollerAddress={data.comptroller}
poolName={data.name}
poolID={poolId!}
isOpen={isAddRewardsDistributorModalOpen}
onClose={closeAddRewardsDistributorModal}
/>
) : null}
{data && !!rewardsDistributor ? (
<EditRewardsDistributorModal
rewardsDistributor={rewardsDistributor}
pool={data}
isOpen={isEditRewardsDistributorModalOpen}
onClose={closeEditRewardsDistributorModal}
/>
) : null}
<Column
mainAxisAlignment="flex-start"
crossAxisAlignment="center"
color="#FFFFFF"
mx="auto"
width={isMobile ? "100%" : "1150px"}
px={isMobile ? 4 : 0}
>
<Header isAuthed={isAuthed} isFuse />
<FuseStatsBar data={data} />
<FuseTabBar />
{!!data && (
<AdminAlert
isAdmin={isAdmin}
isAdminText="You are the admin of this Fuse Pool!"
isNotAdminText="You are not the admin of this Fuse Pool!"
/>
)}
<RowOrColumn
width="100%"
mainAxisAlignment="flex-start"
crossAxisAlignment="flex-start"
isRow={!isMobile}
>
<DashboardBox
width={isMobile ? "100%" : "50%"}
height={isMobile ? "auto" : "560px"}
mt={4}
>
{data ? (
<PoolConfiguration
assets={data.assets}
comptrollerAddress={data.comptroller}
oracleAddress={data.oracle}
/>
) : (
<Center expand>
<Spinner my={8} />
</Center>
)}
</DashboardBox>
<Box pl={isMobile ? 0 : 4} width={isMobile ? "100%" : "50%"}>
<DashboardBox
width="100%"
mt={4}
height={isMobile ? "auto" : "560px"}
>
{data ? (
data.assets.length > 0 ? (
<AssetConfiguration
openAddAssetModal={authedOpenModal}
assets={data.assets}
poolOracleAddress={data.oracle}
oracleModel={data.oracleModel}
comptrollerAddress={data.comptroller}
poolID={poolId!}
poolName={data.name}
/>
) : (
<Column
expand
mainAxisAlignment="center"
crossAxisAlignment="center"
py={4}
>
<Text mb={4}>{t("There are no assets in this pool.")}</Text>
<AddAssetButton
comptrollerAddress={data.comptroller}
openAddAssetModal={authedOpenModal}
/>
</Column>
)
) : (
<Center expand>
<Spinner my={8} />
</Center>
)}
</DashboardBox>
</Box>
</RowOrColumn>
{/* Rewards Distributors */}
<DashboardBox w="100%" h="100%" my={4}>
<Row
mainAxisAlignment="space-between"
crossAxisAlignment="center"
p={3}
>
<Heading size="md">Rewards Distributors </Heading>
<AddRewardsDistributorButton
openAddRewardsDistributorModal={openAddRewardsDistributorModal}
comptrollerAddress={data?.comptroller}
/>
</Row>
{!!data && !rewardsDistributors.length && (
<Column
w="100%"
h="100%"
mainAxisAlignment="center"
crossAxisAlignment="center"
p={4}
>
<Text mb={4}>
{t("There are no RewardsDistributors for this pool.")}
</Text>
<AddRewardsDistributorButton
openAddRewardsDistributorModal={openAddRewardsDistributorModal}
comptrollerAddress={data?.comptroller}
/>
</Column>
)}
{!data && (
<Column
w="100%"
h="100%"
mainAxisAlignment="center"
crossAxisAlignment="center"
p={4}
>
<Spinner />
</Column>
)}
{!!data && !!rewardsDistributors.length && (
<Table>
<Thead>
<Tr>
<Th color="white" size="sm">
{t("Reward Token:")}
</Th>
<Th color="white">{t("Active CTokens:")}</Th>
<Th color="white">{t("Balance:")}</Th>
<Th color="white">{t("Admin?")}</Th>
</Tr>
</Thead>
<Tbody minHeight="50px">
{!data && !rewardsDistributors.length ? (
<Spinner />
) : (
rewardsDistributors.map((rD, i) => {
return (
<RewardsDistributorRow
key={rD.address}
rewardsDistributor={rD}
handleRowClick={handleRewardsRowClick}
hideModalDivider={i === rewardsDistributors.length - 1}
activeCTokens={
poolIncentives.rewardsDistributorCtokens[rD.address]
}
/>
);
})
)}
</Tbody>
</Table>
)}
<ModalDivider />
</DashboardBox>
</Column>
</>
);
})
Example #17
Source File: AppProxyPorts.tsx From ledokku with MIT License | 4 votes |
AppProxyPorts = ({ appId }: AppProxyPortsProps) => {
const toast = useToast();
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<
false | AppProxyPort
>(false);
const {
data: appProxyPortsData,
loading: appProxyPortsLoading,
// TODO display error
// error: appProxyPortsError,
refetch: appProxyPortsRefetch,
} = useAppProxyPortsQuery({
variables: { appId },
notifyOnNetworkStatusChange: true,
});
const [
removeAppProxyPortMutation,
{ loading: removeAppPortLoading },
] = useRemoveAppProxyPortMutation();
const handleCloseModal = () => {
setIsDeleteModalOpen(false);
};
const handleRemovePort = async () => {
const proxyPort = isDeleteModalOpen;
if (!proxyPort) return;
try {
await removeAppProxyPortMutation({
variables: {
input: {
appId,
scheme: proxyPort.scheme,
host: proxyPort.host,
container: proxyPort.container,
},
},
});
await appProxyPortsRefetch();
setIsDeleteModalOpen(false);
toast.success('Port mapping deleted successfully');
} catch (error) {
toast.error(error.message);
}
};
return (
<>
<Box py="5">
<Heading as="h2" size="md">
Port Management
</Heading>
<Text fontSize="sm" color="gray.400">
The following ports are assigned to your app.
</Text>
</Box>
{appProxyPortsLoading ? (
<Text fontSize="sm" color="gray.400">
Loading...
</Text>
) : null}
{appProxyPortsData && appProxyPortsData.appProxyPorts.length > 0 ? (
<Table>
<Thead>
<Tr>
<Th>Scheme</Th>
<Th isNumeric>Host port</Th>
<Th isNumeric>Container port</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{appProxyPortsData.appProxyPorts.map((proxyPort, index) => (
<Tr key={index}>
<Td>{proxyPort.scheme}</Td>
<Td isNumeric>{proxyPort.host}</Td>
<Td isNumeric>{proxyPort.container}</Td>
<Td>
<Button
colorScheme="red"
variant="link"
size="sm"
onClick={() => setIsDeleteModalOpen(proxyPort)}
>
Delete
</Button>
</Td>
</Tr>
))}
</Tbody>
</Table>
) : null}
<Modal isOpen={!!isDeleteModalOpen} onClose={handleCloseModal} isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>Delete port</ModalHeader>
<ModalCloseButton />
<ModalBody>
Are you sure, you want to delete this port mapping?
</ModalBody>
<ModalFooter>
<Button mr={3} onClick={handleCloseModal}>
Cancel
</Button>
<Button
colorScheme="red"
isLoading={appProxyPortsLoading || removeAppPortLoading}
onClick={handleRemovePort}
>
Delete
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<Button
mt="3"
variant="outline"
size="sm"
onClick={() => setIsAddModalOpen(true)}
>
Add port mapping
</Button>
<AddAppProxyPorts
appId={appId}
appProxyPortsRefetch={appProxyPortsRefetch}
open={isAddModalOpen}
onClose={() => setIsAddModalOpen(false)}
/>
</>
);
}
Example #18
Source File: ContactsTable.tsx From bluebubbles-server with Apache License 2.0 | 4 votes |
ContactsTable = ({
contacts,
onCreate,
onDelete,
onUpdate,
onAddressAdd,
onAddressDelete
}: {
contacts: Array<ContactItem>,
onCreate?: (contact: ContactItem) => void,
onDelete?: (contactId: number | string) => void,
onUpdate?: (contact: Partial<ContactItem>) => void,
onAddressAdd?: (contactId: number | string, address: string) => void;
onAddressDelete?: (contactAddressId: number) => void;
}): JSX.Element => {
const dialogRef = useRef(null);
const [dialogOpen, setDialogOpen] = useBoolean();
const [selectedContact, setSelectedContact] = useState(null as any | null);
return (
<Box>
<Table variant="striped" colorScheme="blue" size='sm'>
<Thead>
<Tr>
<Th>Edit</Th>
<Th>Display Name</Th>
<Th isNumeric>Addresses</Th>
</Tr>
</Thead>
<Tbody>
{contacts.map(item => {
const name = (item.displayName && item.displayName.length > 0)
? item.displayName
: [item?.firstName, item?.lastName].filter((e) => e && e.length > 0).join(' ');
const addresses = [
...(item.phoneNumbers ?? []).map(e => e.address),
...(item.emails ?? []).map(e => e.address)
];
return (
<Tr key={`${item.sourceType}-${item.id}-${name}-${addresses.join('_')}`}>
<Td _hover={{ cursor: (item?.sourceType === 'api') ? 'auto' : 'pointer' }} onClick={() => {
if (item?.sourceType === 'api') return;
setSelectedContact(item);
setDialogOpen.on();
}}>
{(item?.sourceType === 'api') ? (
<Tooltip label="Not Editable" hasArrow aria-label='not editable tooltip'>
<span>
<Icon as={MdOutlineEditOff} />
</span>
</Tooltip>
): (
<Tooltip label="Click to Edit" hasArrow aria-label='editable tooltip'>
<span>
<Icon as={AiOutlineEdit} />
</span>
</Tooltip>
)}
</Td>
<Td>{name}</Td>
<Td isNumeric>{addresses.map((addr) => (
<Badge ml={2} key={`${name}-${addr}-${addresses.length}`}>{addr}</Badge>
))}</Td>
</Tr>
);
})}
</Tbody>
</Table>
<ContactDialog
modalRef={dialogRef}
isOpen={dialogOpen}
existingContact={selectedContact}
onDelete={onDelete}
onCreate={onCreate}
onUpdate={onUpdate}
onAddressAdd={onAddressAdd}
onAddressDelete={onAddressDelete}
onClose={() => {
setSelectedContact(null);
setDialogOpen.off();
}}
/>
</Box>
);
}