diff --git a/apps/info-dashboard/messages/en.json b/apps/info-dashboard/messages/en.json index 3afc876..2d94934 100644 --- a/apps/info-dashboard/messages/en.json +++ b/apps/info-dashboard/messages/en.json @@ -12,6 +12,13 @@ "leaderboard_node_provider_table_errorState_errorHint": "Something went wrong - try reloading the page!", "leaderboard_node_provider_table_emptyState_emptyHint": "You can either come back later, reload the page or clear your searchbar.", "leaderboard_node_provider_table_emptyState_emptyText": "No entries found", + "leaderboard_node_provider_table_first_status": "Lily Titan", + "leaderboard_node_provider_table_second_status": "Lily Legend", + "leaderboard_node_provider_table_third_status": "Lily Wizard", + "leaderboard_node_provider_table_last_status": "Lily Machine", + + + "not_found_message": "Oops, something went wrong! return", "not_found_home": "home" } \ No newline at end of file diff --git a/apps/info-dashboard/src/app/page.tsx b/apps/info-dashboard/src/app/page.tsx index 32f974d..6ad3a58 100644 --- a/apps/info-dashboard/src/app/page.tsx +++ b/apps/info-dashboard/src/app/page.tsx @@ -8,6 +8,10 @@ import { alertAndFeedbackAlertCircle, generalSearchLg, generalSearchMd, + weatherLightning02, + financeAndEcommerceDiamond01, + editorMagicWand02, + developmentCpuChip02, } from "@frontline-hq/untitledui-icons"; import CardHeader from "@/components/CardHeader"; import InputField from "@/components/InputField/Inputfield"; @@ -19,10 +23,12 @@ import SocialIcon from "@/components/SocialIcon"; import * as m from "@/paraglide/messages.js"; import Head from "next/head"; import { fetchLeaderboard } from "@/lib/fetchers/leaderboard"; +import Badge from "@/components/Badge/Badge"; // TODO add inlang to the values returned from the API after we receive the API const TABLE_HEADERS = [ "Rank", + "Status", "Wallet ID", "Energy Provided (TFLOPS*s)", "Reward Points", @@ -37,9 +43,7 @@ export default function Home() { queryKey: ["leaderboard"], //Array according to Documentation }); - // If a wallet address is found within the search params, filter the table values - - const normaleShareText = encodeURIComponent( + const normalShareText = encodeURIComponent( m.leaderboard_node_provider_table_share_x_tweet_shareText() ); @@ -54,10 +58,10 @@ export default function Home() { const walletId = searchParams.get("wallet_id"); if (walletId) setWalletAddress(walletId); setTwitterUrl( - `https://twitter.com/intent/tweet?text=${normaleShareText}&url=${currentUrl}` + `https://twitter.com/intent/tweet?text=${normalShareText}&url=${currentUrl}` ); } - }, [normaleShareText]); + }, [normalShareText]); return ( <> @@ -178,6 +182,46 @@ export default function Home() { }} + + + {{ + title: ( + + {rowIndex < 5 + ? m.leaderboard_node_provider_table_first_status() + : rowIndex < 15 + ? m.leaderboard_node_provider_table_second_status() + : rowIndex < 35 + ? m.leaderboard_node_provider_table_third_status() + : m.leaderboard_node_provider_table_last_status()} + + ), + }} + + {Object.entries(row) .slice(1) .map(([key, value], i) => ( @@ -195,7 +239,6 @@ export default function Home() { target="_blank" rel="noopener noreferrer" > - {/* TODO replace with button/social icon component */} { + color: BadgeColor; + badgeType: BadgeType; + icon?: BadgeIcon; + size: BadgeSize; + children?: React.ReactNode; +} + +const Badge = ({ + color, + badgeType, + icon, + size, + children, + ...props +}: BadgeProps) => { + return ( + + {icon && icon.type === "icon" && icon.leading && ( + + )} + {children} + + ); +}; + +export default Badge; diff --git a/apps/info-dashboard/src/components/Badge/BadgeIconAtom.tsx b/apps/info-dashboard/src/components/Badge/BadgeIconAtom.tsx new file mode 100644 index 0000000..04c8835 --- /dev/null +++ b/apps/info-dashboard/src/components/Badge/BadgeIconAtom.tsx @@ -0,0 +1,55 @@ +import { CustomCSSProperties } from "@/types"; +import { + BadgeColor, + BadgeSize, + BadgeStyleLayers, + BadgeType, +} from "./BadgeTypes"; + +interface BadgeIconProps extends React.HTMLAttributes { + iconUrl: string; + color: BadgeColor; + badgeType: BadgeType; + size: BadgeSize; +} + +export let src: string; + +const BadgeIconAtom = ({ + iconUrl, + color, + badgeType, + size, + ...props +}: BadgeIconProps) => { + const spanStyle: CustomCSSProperties = { + "--icon-url": `url(${iconUrl})`, + }; + + const layer1 = + "[mask-position:center] [mask-size:contain] [mask-repeat:no-repeat] [mask-image:var(--icon-url)] h-uui-lg w-uui-lg"; + + const iconStyle: BadgeStyleLayers = { + "Pill outline": { + gray: "bg-uui-utility-gray-600", + brand: "bg-uui-utility-brand-600", + warning: "bg-uui-utility-warning-600", + pink: "bg-uui-utility-pink-600", + }, + }; + + const sizes = { + sm: "-mx-uui-xxs only:-mx-uui-xs only:py-uui-md", + }; + + const classes = `${layer1} ${sizes[size]} ${iconStyle[badgeType][color]}`; + + return ( + + ); +}; +export default BadgeIconAtom; diff --git a/apps/info-dashboard/src/components/Badge/BadgeTextAtom.tsx b/apps/info-dashboard/src/components/Badge/BadgeTextAtom.tsx new file mode 100644 index 0000000..3c7cb18 --- /dev/null +++ b/apps/info-dashboard/src/components/Badge/BadgeTextAtom.tsx @@ -0,0 +1,17 @@ +import { BadgeSize } from "./BadgeTypes"; + +type BadgeTextAtomProps = { + children: React.ReactNode; + size: BadgeSize; +}; + +const BadgeTextAtom = ({ children, size }: BadgeTextAtomProps) => { + const layer1 = "antialiased font-medium"; + const sizes = { sm: "uui-text-xs" }; + + const classes = `${layer1} ${sizes[size]}`; + + return {children}; +}; + +export default BadgeTextAtom; diff --git a/apps/info-dashboard/src/components/Badge/BadgeTypes.d.ts b/apps/info-dashboard/src/components/Badge/BadgeTypes.d.ts new file mode 100644 index 0000000..f9cecef --- /dev/null +++ b/apps/info-dashboard/src/components/Badge/BadgeTypes.d.ts @@ -0,0 +1,19 @@ +export type BadgeStyleLayers = { + "Pill outline": { + gray: string; + brand: string; + warning: string; + pink: string; + }; +}; + +export type BadgeColor = "gray" | "brand" | "warning" | "pink"; + +export type BadgeType = "Pill outline"; + +export type BadgeSize = "sm"; + +export type BadgeIcon = { + type: "icon"; + leading?: string; +} & React.HTMLAttributes; diff --git a/apps/info-dashboard/src/components/Badge/BadgeWrapper.tsx b/apps/info-dashboard/src/components/Badge/BadgeWrapper.tsx new file mode 100644 index 0000000..ff6c1e2 --- /dev/null +++ b/apps/info-dashboard/src/components/Badge/BadgeWrapper.tsx @@ -0,0 +1,51 @@ +import { BadgeStyleLayers } from "./BadgeTypes"; +import type { BadgeColor, BadgeSize, BadgeType } from "./BadgeTypes"; + +interface BadgeWrapperProps + extends React.ButtonHTMLAttributes { + color: BadgeColor; + badgeType: BadgeType; + children: React.ReactNode; + size: BadgeSize; +} + +const BadgeWrapper = ({ + color, + badgeType, + size, + children, + ...props +}: BadgeWrapperProps) => { + const layer1 = + "group flex justify-center items-center focus-visible:outline-none focus:outline-none"; + + const backgroundLayer: BadgeStyleLayers = { + "Pill outline": { + gray: "text-uui-utility-gray-600 ring-uui-utility-gray-700 ring-[0.09375rem] rounded-full", + brand: + "text-uui-utility-brand-600 ring-uui-utility-brand-700 ring-[0.09375rem] rounded-full", + warning: + "text-uui-utility-warning-600 ring-uui-utility-warning-700 ring-[0.09375rem] rounded-full", + pink: "text-uui-utility-pink-600 ring-uui-utility-pink-700 ring-[0.09375rem] rounded-full", + }, + }; + + const sizes = { + sm: "px-uui-md py-uui-xxs gap-uui-sm ", + }; + + const onClickClasses = "pointer-events-auto"; + const noOnClickClasses = "pointer-events-auto cursor-default"; + + const classes = `${layer1} ${sizes[size]} ${ + backgroundLayer[badgeType][color] + } ${props.onClick ? onClickClasses : noOnClickClasses}`; + + return ( + + ); +}; + +export default BadgeWrapper;