Skip to content

Commit

Permalink
Add skeleton loading
Browse files Browse the repository at this point in the history
  • Loading branch information
rubycop committed Dec 18, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 662cd6c commit d520a92
Showing 4 changed files with 169 additions and 109 deletions.
231 changes: 128 additions & 103 deletions instances/treasury-devdao.near/widget/pages/dashboard/Chart.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
const { nearPrice, ftTokens, accountId, title } = props;

const Loading = () => (
<Widget
src={"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.dashboard.Loading"}
/>
);

const API_HOST = "https://ref-sdk-api.fly.dev/api";
const [height, setHeight] = useState(350);
const [history, setHistory] = useState([]);
@@ -21,9 +27,20 @@ const tokens = Array.isArray(ftTokens)
? [nearTokenInfo, ...ftTokens]
: [nearTokenInfo];

const Loading = () => (
<Widget src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Spinner"} />
);
const Skeleton = styled.div`
background: "#efefef";
animation: pulse 1.5s ease-in-out infinite;
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.4;
}
}
`;

const periodMap = [
{ period: "1H", value: 1 / 6, interval: 6 },
@@ -300,110 +317,118 @@ useEffect(() => {

return (
<div className="card flex-1 w-100 card-body">
<div>
<div className="d-flex justify-content-between flex-row align-items-start">
<div className="d-flex flex-column gap-2">
<h6 className="text-grey mb-0">{title}</h6>
<div className="d-flex align-items-center gap-3">
<h3 className="fw-bold mb-0">
{isLoading ? "-" : formatCurrency(balanceDate.balance)}{" "}
{
[nearTokenInfo, ...(ftTokens ?? [])].find(
(t) => t.contract === selectedToken
)?.ft_meta?.symbol
}
</h3>
{balanceDate.date && (
<div style={{ fontSize: 14 }}>
{new Date(balanceDate.date).toLocaleDateString("en-US", {
dateStyle: "medium",
})}{" "}
{new Date(balanceDate.date).toLocaleTimeString("en-US", {
hour: "numeric",
minute: "numeric",
})}
{isLoading ? (
<Loading />
) : (
<>
<div>
<div className="d-flex justify-content-between flex-row align-items-start">
<div className="d-flex flex-column gap-2">
<h6 className="text-grey mb-0">{title}</h6>
<div className="d-flex align-items-center gap-3">
<h3 className="fw-bold mb-0">
{formatCurrency(balanceDate.balance)}{" "}
{
[nearTokenInfo, ...(ftTokens ?? [])].find(
(t) => t.contract === selectedToken
)?.ft_meta?.symbol
}
</h3>
{balanceDate.date && (
<div style={{ fontSize: 14 }}>
{new Date(balanceDate.date).toLocaleDateString("en-US", {
dateStyle: "medium",
})}{" "}
{new Date(balanceDate.date).toLocaleTimeString("en-US", {
hour: "numeric",
minute: "numeric",
})}
</div>
)}
</div>
)}
</div>

<div className="d-flex gap-1">
{periodMap.map(({ period, value, interval }, idx) => (
<Period
role="button"
key={idx}
onClick={() => setSelectedPeriod({ value, interval })}
className={
selectedPeriod.value === value &&
selectedPeriod.interval === interval
? "selected"
: ""
}
>
{period}
</Period>
))}
</div>
</div>

<div className="d-flex gap-4 mt-2 flex-wrap align-items-center">
{tokens.slice(0, 5).map((item, _index) => {
const { contract, ft_meta } = item;
const { symbol } = ft_meta;

return (
<RadioButton className="d-flex align-items-center" key={idx}>
<input
style={{ visibility: "hidden", width: 0, padding: 0 }}
id={contract}
type="radio"
value={contract}
onClick={() => setSelectedToken(contract)}
selected={contract === selectedToken}
/>
<label
htmlFor={contract}
role="button"
className="d-flex align-items-center gap-1"
>
<div className="radio-btn">
<div
className={contract === selectedToken ? "selected" : ""}
/>
</div>
<span
className={contract === selectedToken ? "fw-bold" : ""}
>
{symbol}
</span>
</label>
</RadioButton>
);
})}
</div>
</div>

<div className="d-flex gap-1">
{periodMap.map(({ period, value, interval }, idx) => (
<Period
role="button"
key={idx}
onClick={() => setSelectedPeriod({ value, interval })}
className={
selectedPeriod.value === value &&
selectedPeriod.interval === interval
? "selected"
: ""
}
>
{period}
</Period>
))}
<div
className="w-100 d-flex justify-content-center align-items-center"
style={{ height: "400px" }}
>
{isLoading ? (
<Loading />
) : (
<iframe
style={{ width: "100%", height: `${height}px` }}
srcDoc={code}
message={{ account_id, history }}
onMessage={(e) => {
switch (e.handler) {
case "chartHeight": {
setHeight(e.chartHeight);
}
case "balance": {
setBalanceDate({ balance: e.balance, date: e.date });
}
}
}}
/>
)}
</div>
</div>

<div className="d-flex gap-4 mt-2 flex-wrap align-items-center">
{tokens.slice(0, 5).map((item, _index) => {
const { contract, ft_meta } = item;
const { symbol } = ft_meta;

return (
<RadioButton className="d-flex align-items-center" key={idx}>
<input
style={{ visibility: "hidden", width: 0, padding: 0 }}
id={contract}
type="radio"
value={contract}
onClick={() => setSelectedToken(contract)}
selected={contract === selectedToken}
/>
<label
htmlFor={contract}
role="button"
className="d-flex align-items-center gap-1"
>
<div className="radio-btn">
<div
className={contract === selectedToken ? "selected" : ""}
/>
</div>
<span className={contract === selectedToken ? "fw-bold" : ""}>
{symbol}
</span>
</label>
</RadioButton>
);
})}
</div>
</div>

<div
className="w-100 d-flex justify-content-center align-items-center"
style={{ height: "400px" }}
>
{isLoading ? (
<Loading />
) : (
<iframe
style={{ width: "100%", height: `${height}px` }}
srcDoc={code}
message={{ account_id, history }}
onMessage={(e) => {
switch (e.handler) {
case "chartHeight": {
setHeight(e.chartHeight);
}
case "balance": {
setBalanceDate({ balance: e.balance, date: e.date });
}
}
}}
/>
)}
</div>
</>
)}
</div>
);
33 changes: 33 additions & 0 deletions instances/treasury-devdao.near/widget/pages/dashboard/Loading.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const Skeleton = styled.div`
background: #efefef;
animation: pulse 1.5s ease-in-out infinite;
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.4;
}
}
`;

return (
<div className="d-flex align-items-center gap-2 w-100">
<Skeleton
style={{ height: "48px", width: "48px" }}
className="rounded-circle"
/>
<div className="d-flex flex-column gap-1 w-75">
<Skeleton
style={{ height: "16px", width: "100%" }}
className="rounded-1"
/>
<Skeleton
style={{ height: "24px", width: "90%" }}
className="rounded-2"
/>
</div>
</div>
);
Original file line number Diff line number Diff line change
@@ -37,8 +37,10 @@ function getPrice(tokensNumber, tokenPrice) {
.toFixed(2);
}

const loading = (
<Widget src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Spinner"} />
const Loading = () => (
<Widget
src={"${REPL_BASE_DEPLOYMENT_ACCOUNT}/widget/pages.dashboard.Loading"}
/>
);

const [isNearPortfolioExpanded, setNearPortfolioExpanded] = useState(false);
@@ -281,13 +283,13 @@ return (
}}
>
{heading}
<div>
<div className="my-2 mx-2">
{isLoading ? (
<div className="d-flex justify-content-center align-items-center w-100 h-100">
{loading}
<Loading />
</div>
) : (
<div className="mt-2">
<div>
{!ftTokens.length && !nearBalances?.total ? (
<div className="fw-bold p-3">Account doesn't own any FTs.</div>
) : (
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@ const nearPrice = useCache(
const userFTTokens = useCache(
() =>
asyncFetch(
`https://api3.nearblocks.io/v1/account/${treasuryDaoID }/inventory`,
`https://api3.nearblocks.io/v1/account/${treasuryDaoID}/inventory`,
{ headers: { Authorization: "Bearer ${REPL_NEARBLOCKS_KEY}" } }
).then((res) => {
let fts = res.body.inventory.fts;

0 comments on commit d520a92

Please sign in to comment.