-
Notifications
You must be signed in to change notification settings - Fork 77
feat(provider): changed AKT dropdown popup design change #2202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| import React from "react"; | ||
| import { FormattedNumber } from "react-intl"; | ||
| import { Address, Button, Separator } from "@akashnetwork/ui/components"; | ||
| import { LogOut } from "iconoir-react"; | ||
|
|
||
| import { usePricing } from "@src/context/PricingProvider"; | ||
| import { useWallet } from "@src/context/WalletProvider"; | ||
| import { uAktDenom } from "@src/utils/constants"; | ||
| import { udenomToDenom } from "@src/utils/mathHelpers"; | ||
| import { uaktToAKT } from "@src/utils/priceUtils"; | ||
|
|
||
| interface WalletPopupProps extends React.PropsWithChildren { | ||
| walletBalances: { uakt: number; usdc: number } | null; | ||
| } | ||
|
|
||
| export const WalletPopup: React.FC<WalletPopupProps> = ({ walletBalances }) => { | ||
| const { address, logout } = useWallet(); | ||
| const { isLoaded, getPriceForDenom } = usePricing(); | ||
|
|
||
| const aktAmount = walletBalances ? uaktToAKT(walletBalances.uakt, 2) : 0; | ||
| const aktPrice = getPriceForDenom(uAktDenom); | ||
| const aktUsdValue = isLoaded && walletBalances && aktPrice > 0 ? aktAmount * aktPrice : 0; | ||
| const usdcAmount = walletBalances ? udenomToDenom(walletBalances.usdc, 2) : 0; | ||
|
|
||
| return ( | ||
| <div className="w-[300px] p-2"> | ||
| <div className="mb-4"> | ||
| <Address address={address} isCopyable disableTooltip className="text-foreground flex items-center justify-between text-sm font-bold" showIcon /> | ||
| </div> | ||
|
|
||
| <div className="text-muted-foreground mb-1 text-xs">Wallet Balance</div> | ||
| <div className="border-success/10 bg-success/10 text-success dark:border-success/80 dark:bg-success/80 dark:text-foreground mb-4 rounded-md border p-2"> | ||
| {walletBalances ? ( | ||
| <> | ||
| <div className="flex items-center justify-between space-x-2"> | ||
| <span className="text-xs">AKT</span> | ||
| <span className="flex items-center space-x-1"> | ||
| {isLoaded && aktPrice ? <FormattedNumber value={aktUsdValue} style="currency" currency="USD" /> : <span className="text-xs">$0.00</span>} | ||
| <span className="font-light2 space-x-2 text-xs">({aktAmount} AKT)</span> | ||
| </span> | ||
| </div> | ||
|
|
||
| <Separator className="bg-success/10 my-2 dark:bg-white/20" /> | ||
|
|
||
| <div className="flex items-center justify-between space-x-2"> | ||
| <span className="text-xs">USDC</span> | ||
| <span> | ||
| <FormattedNumber value={usdcAmount} style="currency" currency="USD" /> | ||
| </span> | ||
| </div> | ||
| </> | ||
| ) : ( | ||
| <div className="space-x-2 text-xs text-white">Wallet Balance is unknown because the blockchain is unavailable</div> | ||
| )} | ||
| </div> | ||
|
|
||
| <div className="text-muted-foreground text-xs">Wallet Actions</div> | ||
|
|
||
| <div className="flex flex-col items-center justify-end space-y-2 pt-2"> | ||
| <Button onClick={logout} variant="outline" className="w-full space-x-2"> | ||
| <LogOut /> | ||
| <span>Disconnect Wallet</span> | ||
| </Button> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,32 @@ import { useQuery } from "@tanstack/react-query"; | |
| import type { MarketData } from "@src/types"; | ||
| import { QueryKeys } from "./queryKeys"; | ||
|
|
||
| async function getMarketData(): Promise<any> { | ||
| return {}; | ||
| async function getMarketData(): Promise<MarketData> { | ||
| try { | ||
| const response = await fetch("https://api.coingecko.com/api/v3/coins/akash-network/tickers"); | ||
| const data = await response.json(); | ||
| const coinbasePrice = data.tickers.find((ticker: any) => ticker.market.name === "Coinbase Exchange"); | ||
| const price = coinbasePrice ? parseFloat(coinbasePrice.converted_last.usd) : 0; | ||
|
|
||
|
Comment on lines
+11
to
+13
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Replace
import type { QueryKey, UseQueryOptions } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import type { MarketData } from "@src/types";
import { QueryKeys } from "./queryKeys";
+
+type CoinGeckoTicker = {
+ market: { name: string };
+ converted_last: { usd: number | string };
+};
+
+type CoinGeckoResponse = {
+ tickers: CoinGeckoTicker[];
+};
+
+function extractCoinbaseUsd(tickers: CoinGeckoTicker[]): number | null {
+ const usd = tickers.find((ticker) => ticker.market.name === "Coinbase Exchange")?.converted_last.usd;
+ const numericUsd = typeof usd === "string" ? Number.parseFloat(usd) : usd;
+ return typeof numericUsd === "number" && Number.isFinite(numericUsd) ? numericUsd : null;
+}
async function getMarketData(): Promise<MarketData> {
try {
- const response = await fetch("https://api.coingecko.com/api/v3/coins/akash-network/tickers");
- const data = await response.json();
- const coinbasePrice = data.tickers.find((ticker: any) => ticker.market.name === "Coinbase Exchange");
- const price = coinbasePrice ? parseFloat(coinbasePrice.converted_last.usd) : 0;
+ const response = await fetch("https://api.coingecko.com/api/v3/coins/akash-network/tickers");
+ const data: CoinGeckoResponse = await response.json();
+ const price = extractCoinbaseUsd(data.tickers) ?? 0;
return {
price,
@@
async function getAKTPrice(): Promise<{ aktPrice: string }> {
const response = await fetch("https://api.coingecko.com/api/v3/coins/akash-network/tickers");
- const data = await response.json();
- const coinbasePrice = data.tickers.find((ticker: any) => ticker.market.name === "Coinbase Exchange");
+ const data: CoinGeckoResponse = await response.json();
+ const usdPrice = extractCoinbaseUsd(data.tickers);
return {
- aktPrice: coinbasePrice ? coinbasePrice.converted_last.usd.toFixed(2) : "N/A"
+ aktPrice: usdPrice !== null ? usdPrice.toFixed(2) : "N/A"
};
}As per coding guidelines Also applies to: 46-48 🤖 Prompt for AI Agents |
||
| return { | ||
| price, | ||
| volume: 0, | ||
| marketCap: 0, | ||
| marketCapRank: 0, | ||
| priceChange24h: 0, | ||
| priceChangePercentage24: 0 | ||
| }; | ||
| } catch (error) { | ||
| console.error("Failed to fetch market data:", error); | ||
| return { | ||
| price: 0, | ||
| volume: 0, | ||
| marketCap: 0, | ||
| marketCapRank: 0, | ||
| priceChange24h: 0, | ||
| priceChangePercentage24: 0 | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| export function useMarketData(options?: Omit<UseQueryOptions<MarketData, Error, any, QueryKey>, "queryKey" | "queryFn">) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore an accessible trigger for the dropdown.
With the trigger now being a plain
<div>that only setsopenononMouseOver, touch users can’t open the wallet menu at all and keyboard users can’t focus/activate it, so they lose the ability to see balances or disconnect. Please use a focusable button (or let the Radix trigger manage state) and wireonOpenChangeso pointer, keyboard, and touch interactions all work.📝 Committable suggestion
🤖 Prompt for AI Agents