Skip to content

Commit

Permalink
Merge pull request #33 from Lilypad-Tech/nadiem/feat-badge-component
Browse files Browse the repository at this point in the history
feat: add badge component to leaderboard page
  • Loading branch information
benjaminpreiss authored Jun 14, 2024
2 parents 8684a6a + 5969247 commit 13e3e9d
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 6 deletions.
7 changes: 7 additions & 0 deletions apps/info-dashboard/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
55 changes: 49 additions & 6 deletions apps/info-dashboard/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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",
Expand All @@ -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()
);

Expand All @@ -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 (
<>
Expand Down Expand Up @@ -178,6 +182,46 @@ export default function Home() {
}}
</TableLeadText>
</td>
<td>
<TableLeadText>
{{
title: (
<Badge
badgeType="Pill outline"
color={
rowIndex < 5
? "warning"
: rowIndex < 15
? "pink"
: rowIndex < 35
? "brand"
: "gray"
}
size="sm"
icon={{
type: "icon",
leading:
rowIndex < 5
? weatherLightning02
: rowIndex < 15
? financeAndEcommerceDiamond01
: rowIndex < 35
? editorMagicWand02
: developmentCpuChip02,
}}
>
{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()}
</Badge>
),
}}
</TableLeadText>
</td>
{Object.entries(row)
.slice(1)
.map(([key, value], i) => (
Expand All @@ -195,7 +239,6 @@ export default function Home() {
target="_blank"
rel="noopener noreferrer"
>
{/* TODO replace with button/social icon component */}
<SocialIcon
className="[&&]:h-uui-xl [&&]:w-uui-xl"
iconUrl="/x.svg"
Expand Down
39 changes: 39 additions & 0 deletions apps/info-dashboard/src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import BadgeWrapper from "./BadgeWrapper";
import BadgeIconAtom from "./BadgeIconAtom";
import { BadgeColor, BadgeIcon, BadgeSize, BadgeType } from "./BadgeTypes";
import BadgeTextAtom from "./BadgeTextAtom";

export interface BadgeProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
color: BadgeColor;
badgeType: BadgeType;
icon?: BadgeIcon;
size: BadgeSize;
children?: React.ReactNode;
}

const Badge = ({
color,
badgeType,
icon,
size,
children,
...props
}: BadgeProps) => {
return (
<BadgeWrapper {...props} color={color} badgeType={badgeType} size={size}>
{icon && icon.type === "icon" && icon.leading && (
<BadgeIconAtom
className={icon.className}
iconUrl={icon.leading}
badgeType={badgeType}
color={color}
size={size}
/>
)}
<BadgeTextAtom size={size}>{children}</BadgeTextAtom>
</BadgeWrapper>
);
};

export default Badge;
55 changes: 55 additions & 0 deletions apps/info-dashboard/src/components/Badge/BadgeIconAtom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { CustomCSSProperties } from "@/types";
import {
BadgeColor,
BadgeSize,
BadgeStyleLayers,
BadgeType,
} from "./BadgeTypes";

interface BadgeIconProps extends React.HTMLAttributes<HTMLSpanElement> {
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 (
<span
{...props}
style={spanStyle}
className={`${classes + " " + props.className} `}
/>
);
};
export default BadgeIconAtom;
17 changes: 17 additions & 0 deletions apps/info-dashboard/src/components/Badge/BadgeTextAtom.tsx
Original file line number Diff line number Diff line change
@@ -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 <span className={`${classes}`}>{children}</span>;
};

export default BadgeTextAtom;
19 changes: 19 additions & 0 deletions apps/info-dashboard/src/components/Badge/BadgeTypes.d.ts
Original file line number Diff line number Diff line change
@@ -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<HTMLSpanElement>;
51 changes: 51 additions & 0 deletions apps/info-dashboard/src/components/Badge/BadgeWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { BadgeStyleLayers } from "./BadgeTypes";
import type { BadgeColor, BadgeSize, BadgeType } from "./BadgeTypes";

interface BadgeWrapperProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
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 (
<button {...props} className={classes + " " + props.className}>
{children}
</button>
);
};

export default BadgeWrapper;

0 comments on commit 13e3e9d

Please sign in to comment.