Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add skeleton loading
Browse files Browse the repository at this point in the history
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.