Skip to content

Commit

Permalink
Merge branch 'main' into deploy/production
Browse files Browse the repository at this point in the history
  • Loading branch information
juandavidkincaid committed Nov 28, 2023
2 parents 4e1cb8c + 0dd1baa commit 9571aa6
Show file tree
Hide file tree
Showing 16 changed files with 1,202 additions and 34 deletions.
44 changes: 42 additions & 2 deletions src/api/block-explorer/address.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useContext } from 'react';
import { Balance, Transaction } from '../../types';
import { AddressRewardsResponse, Balance, Transaction } from '../../types';
import { useFetch } from '../../utils/reactQuery';
import { NetworkContext, NetworkContextType } from '../../context/NetworkContext';
import { Network } from '../../constants';
Expand All @@ -20,7 +20,7 @@ const getMetagraphUrl = (metagraphId: string) => {
};

export const useGetAddressTransactions = (address: string, metagraphId?: string, params?: any) => {
const baseUrl = (!metagraphId || metagraphId === 'ALL_METAGRAPHS') ? getUrl() : getMetagraphUrl(metagraphId);
const baseUrl = !metagraphId || metagraphId === 'ALL_METAGRAPHS' ? getUrl() : getMetagraphUrl(metagraphId);
return useFetch<{ data: Transaction[]; meta?: any }>(
baseUrl + '/' + address + '/transactions',
params,
Expand Down Expand Up @@ -48,3 +48,43 @@ export const useGetAddressTotalRewards = (address: string, network: Exclude<Netw
REACT_APP_DAG_EXPLORER_API_URL + '/' + network + '/addresses/' + address + '/rewards'
);
};

export const useGetAddressRewards = (
address: string,
network: Exclude<Network, 'mainnet1'>,
limit?: number,
offset?: number
) => {
const response = useFetch<{ data: AddressRewardsResponse[]; meta: { limit: number; offset: number; total: number } }>(
REACT_APP_DAG_EXPLORER_API_URL + '/' + network + '/addresses/' + address + '/rewardss',
{ limit, offset },
undefined,
false
);

return { ...response, data: response?.data?.data, meta: response?.data?.meta };
};

export const useGetAddressMetagraphRewards = (
address: string,
metagraphId: string,
network: Exclude<Network, 'mainnet1'>,
limit?: number,
offset?: number
) => {
const response = useFetch<{ data: AddressRewardsResponse[]; meta: { limit: number; offset: number; total: number } }>(
REACT_APP_DAG_EXPLORER_API_URL +
'/' +
network +
'/addresses/' +
address +
'/metagraphs/' +
metagraphId +
'/rewards',
{ limit, offset },
undefined,
false
);

return { ...response, data: response?.data?.data, meta: response?.data?.meta };
};
55 changes: 55 additions & 0 deletions src/components/RewardsTable/HeaderRow.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@use '../../styles/colors' as *;
@use '../../styles/breakpoints' as *;
.headerColumn {
background-color: $grayCool-100;
display: flex;
height: 3.5rem;
align-items: center;
justify-content: flex-start;
padding-left: 1.5rem;
min-height: 2.5rem;
border-width: 0px 0px 1px 0px;
border-style: solid;
border-color: $grayCool-200;
}

.topLeftBorder {
border-top-left-radius: 8px 8px;
}

.topRightBorder {
border-top-right-radius: 8px 8px;
}

.headerText {
font-family: 'Lausanne';
font-weight: 700;
color: $grayCool-500;
letter-spacing: 0.1em;
font-size: 12px;
white-space: nowrap;
}

.rightAligned {
justify-content: flex-end;
padding-right: 1.5rem;
}

.stackFromTo {
display: flex;
}

@media screen and (max-width: $lg) {
.stackFromTo {
display: flex;
}
}

@media screen and (max-width: 780px) {
.enoughSpace {
display: none;
}
.direction {
display: none;
}
}
37 changes: 37 additions & 0 deletions src/components/RewardsTable/HeaderRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import styles from './HeaderRow.module.scss';
import clsx from 'clsx';

export const HeaderRow = ({ headerCols }: { headerCols?: string[] }) => {
if (headerCols) {
return (
<>
{headerCols.map((text, index) => (
<div className={styles.headerColumn} key={index}>
<p className={styles.headerText}>{text}</p>
</div>
))}
</>
);
}
const columns = (
<>
<div className={`${styles.headerColumn} ${styles.stackFromTo}`}>
<p className={styles.headerText}>SENT TO</p>
</div>

<div className={`${styles.headerColumn}`}>
<p className={styles.headerText}>ORDINAL</p>
</div>

<div className={clsx(styles.headerColumn, styles.topRightBorder)}>
<p className={styles.headerText}>AMOUNT</p>
</div>

<div className={clsx(styles.headerColumn, styles.timestamp)}>
<p className={styles.headerText}>TIMESTAMP</p>
</div>
</>
);

return columns;
};
121 changes: 121 additions & 0 deletions src/components/RewardsTable/MobileCard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
@use '../../styles/colors' as *;
.cardContainer {
display: flex;
align-items: flex-start;
background: $white;
border: 1px solid $grayCool-200;
gap: 1rem;
padding: 16px;
}

.cardContainer:first-child {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}

.cardContainer:last-child {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}

%container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
padding: 0px;
}

.titleContainer {
@extend %container;
width: 30%;
}

.infoContainer {
@extend %container;
width: 70%;
}

.cardTitle {
font-family: 'Lausanne';
font-style: normal;
font-weight: 600;
font-size: 12px;
line-height: 18px;
display: flex;
align-items: center;
letter-spacing: 0.005em;
color: $grayCool-500;
}

.hash {
display: flex;
align-items: center;
padding: 0px;
gap: 12px;
line-height: 18px;
font-size: 12px;
}

.subValue {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 16px;
color: $gray-500;
margin-left: 1rem;
}

.copy {
margin-left: 0.7rem;
margin-right: 0.5rem;
cursor: pointer;
}

.copied {
position: fixed;
bottom: 0;
background-color: red;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 18px 0px black;
border-radius: 8px;
padding: 1rem;
}

.fade {
animation: fadeIn 0.5s linear;
}

@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

.skeleton {
animation: skeleton-loading 1s linear infinite alternate;
}

@keyframes skeleton-loading {
0% {
background-color: $grayCool-100;
}

100% {
background-color: $grayCool-200;
}
}

.skeleton.content {
width: 100%;
height: 1.5rem;
margin-bottom: 0.5rem;
margin-top: 0.6rem;
border-radius: 0.2rem;
}
71 changes: 71 additions & 0 deletions src/components/RewardsTable/MobileCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Link } from 'react-router-dom';
import styles from './MobileCard.module.scss';
import CopyIcon from '../../assets/icons/Copy.svg';
import ReactTooltip from 'react-tooltip';
import { SkeletonMobileCard } from './SkeletonMobileCard';
import { useState } from 'react';
import { CardDataRow } from './TableCards';

const getElementContent = (dataRows: CardDataRow[], handleCopyToClipboard: (value: string) => void) => {
const card: JSX.Element[] = [];

dataRows.forEach((rowData, idx) => {
card.push(
<div key={idx}>
<p className={styles.hash} data-tip={rowData.dataTip ? rowData.dataTip : null}>
{rowData.element && rowData.element}
{rowData.value && !rowData.linkTo && rowData.value}
{rowData.linkTo && <Link to={rowData.linkTo}>{rowData.value}</Link>}
{rowData.toCopy && (
<img className={`${styles.copy}`} src={CopyIcon} onClick={() => handleCopyToClipboard(rowData.toCopy)} />
)}
</p>
{rowData.dataTip && <ReactTooltip />}
</div>
);
});

return card;
};

export const MobileCard = ({
titles,
cardData,
isSkeleton,
}: {
titles: string[];
cardData: CardDataRow[];
isSkeleton?: boolean;
}) => {
const [copied, setCopied] = useState<boolean>(false);
const titleElements: JSX.Element[] = titles.map((t, index) => (
<p className={styles.cardTitle} key={index}>
{t}
</p>
));

if (isSkeleton) {
return <SkeletonMobileCard titleElements={titleElements} />;
}
if (cardData.length === 0) {
return;
}

const handleCopyToClipboard = (value: string) => {
navigator.clipboard.writeText(value);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 2000);
};

const infoElement = getElementContent(cardData, handleCopyToClipboard);

return (
<div className={styles.cardContainer}>
<div className={styles.titleContainer}>{titleElements}</div>
<div className={styles.infoContainer}>{infoElement}</div>
{copied && <div className={`${styles.copied} ${styles.fade}`}>Value copied to clipboard!</div>}
</div>
);
};
Loading

0 comments on commit 9571aa6

Please sign in to comment.