Skip to content

Commit 8d51cce

Browse files
authored
Chore/staking app improv (#51)
* feat: added new icons * chore: made NavItem icon non shrinkable * chore: improved stakePoolCard * chore: improved stakeProjectCard * chore: use actions instead of consolelogs in stories * added changeset
1 parent 0fe7bb4 commit 8d51cce

File tree

15 files changed

+193
-100
lines changed

15 files changed

+193
-100
lines changed

.changeset/funny-crews-attend.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@gitcoin/ui": patch
3+
---
4+
5+
Staking app components improvements
Loading

packages/ui/src/assets/icons/heroicons.ts

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
PaperClipIcon,
55
LogoutIcon,
66
LoginIcon,
7+
UserCircleIcon,
8+
ShoppingCartIcon,
79
} from "@heroicons/react/outline";
810
import {
911
BriefcaseIcon,
@@ -74,6 +76,8 @@ enum HeroiconsType {
7476
LOGOUT = "logout",
7577
LOGIN = "login",
7678
BADGE_CHECK = "badge-check",
79+
USER_CIRCLE = "user-circle",
80+
SHOPPING_CART = "shopping-cart",
7781
}
7882

7983
const heroiconsComponents: Record<HeroiconsType, React.FC<React.SVGProps<SVGSVGElement>>> = {
@@ -111,6 +115,8 @@ const heroiconsComponents: Record<HeroiconsType, React.FC<React.SVGProps<SVGSVGE
111115
logout: LoginIcon,
112116
login: LogoutIcon,
113117
"badge-check": BadgeCheckIcon,
118+
"user-circle": UserCircleIcon,
119+
"shopping-cart": ShoppingCartIcon,
114120
};
115121

116122
const heroIcons = Object.keys(heroiconsComponents).sort((a, b) =>
@@ -144,6 +150,8 @@ export {
144150
ExternalLinkIcon,
145151
LogoutIcon,
146152
LoginIcon,
153+
UserCircleIcon,
154+
ShoppingCartIcon,
147155
BadgeCheckIcon,
148156
};
149157

packages/ui/src/components/SideNav/SideNav.stories.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import type { Meta, StoryObj } from "@storybook/react";
55

66
import { SideNav, SideNavProps } from "@/components/SideNav";
77

8-
const handleClick = action("handleClick");
8+
const handleClickAction = action("handleClick");
99

1010
// Wrapper component to handle state
1111
function SideNavWrapper(props: SideNavProps) {
1212
const [activeId, setActiveId] = useState<string | undefined>(props.activeId);
1313
const handleClick = (id: string | undefined) => {
14-
console.log("id", id);
14+
handleClickAction(id);
1515
setActiveId(id);
1616
};
1717

@@ -95,7 +95,7 @@ const sampleItems = [
9595
export const Default: Story = {
9696
args: {
9797
items: sampleItems,
98-
onClick: handleClick,
98+
onClick: handleClickAction,
9999
hoverVariant: "grey",
100100
},
101101
};
@@ -110,6 +110,6 @@ export const WithCustomClass: Story = {
110110
args: {
111111
items: sampleItems,
112112
className: "bg-gray-100 p-4 rounded-lg",
113-
onClick: handleClick,
113+
onClick: handleClickAction,
114114
},
115115
};

packages/ui/src/components/SideNav/components/NavItem.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ export const NavItem = ({
3434
{isRecursive ? (
3535
<div className={cn(baseClasses, "-ml-6")}>
3636
<div className="flex items-center gap-2 pl-6">
37-
{item.iconType ? <Icon type={item.iconType} /> : item.icon}
37+
{item.iconType ? <Icon type={item.iconType} className="shrink-0" /> : item.icon}
3838
{item.content}
3939
</div>
4040
</div>
4141
) : (
4242
<div className={cn(baseClasses, "flex items-center gap-2")}>
43-
{item.iconType ? <Icon type={item.iconType} /> : item.icon}
43+
{item.iconType ? <Icon type={item.iconType} className="shrink-0" /> : item.icon}
4444
{item.content}
4545
</div>
4646
)}

packages/ui/src/features/checker/components/ProjectEvaluationAction/ProjectEvaluationAction.stories.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import type { Meta, StoryObj } from "@storybook/react";
44
import { EvaluationAction } from "../../types";
55
import { ProjectEvaluationAction } from "./ProjectEvaluationAction";
66

7+
const onEvaluateAction = action("onEvaluate");
8+
79
const meta = {
810
title: "Features/Checker/Components/ProjectEvaluationAction",
911
component: ProjectEvaluationAction,
1012
args: {
1113
status: "pending",
1214
onEvaluate: (projectId: string, action: EvaluationAction) => {
13-
console.log(`Evaluating project ${projectId} with action ${action}`);
15+
onEvaluateAction(projectId, action);
1416
},
1517
},
1618
} satisfies Meta;
@@ -19,8 +21,6 @@ export default meta;
1921

2022
type Story = StoryObj<typeof ProjectEvaluationAction>;
2123

22-
const onEvaluateAction = action("onEvaluate");
23-
2424
export const Default: Story = {
2525
args: {
2626
status: "pending",

packages/ui/src/features/pool/components/StakePoolCard/StakePoolCard.stories.tsx

+51-19
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const availableToClaimCardProps = [
1313
id: "1",
1414
chainId: 1,
1515
roundId: "1",
16-
amount: 100,
16+
stakedAmount: 100,
1717
stakedAt: new Date(),
1818
unlockAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 10),
1919
},
@@ -23,7 +23,7 @@ const availableToClaimCardProps = [
2323
id: "2",
2424
chainId: 1,
2525
roundId: "1",
26-
amount: 100,
26+
stakedAmount: 100,
2727
stakedAt: new Date(),
2828
unlockAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 10),
2929
},
@@ -41,6 +41,7 @@ const simpleRound = {
4141
onClick: (pool?: { chainId: number; roundId: string }) => onPoolClick(pool),
4242
createdAtBlock: 123456,
4343
matchingPoolAmount: 100000,
44+
matchingPoolTokenTicker: "GTC",
4445
stakedAmount: 100000,
4546
totalProjects: 100,
4647
totalStaked: 100000,
@@ -73,78 +74,109 @@ type Story = StoryObj<typeof StakePoolCard>;
7374

7475
export const Default: Story = {
7576
args: {
76-
data: simpleRound as StakePoolDataCardProps,
77+
data: {
78+
...simpleRound,
79+
} as StakePoolDataCardProps,
80+
},
81+
parameters: {
82+
date: new Date(2023, 1, 1),
83+
},
84+
};
85+
86+
export const Claimable: Story = {
87+
args: {
88+
data: {
89+
...simpleRound,
90+
isClaimable: true,
91+
stakedProjects: simpleRound.stakedProjects.map((project) => ({
92+
...project,
93+
unlockAt: simpleRound.votingEndDate,
94+
isClaimable: true,
95+
})),
96+
} as StakePoolDataCardProps,
7797
},
7898
parameters: {
7999
date: new Date(2025, 1, 1),
80100
},
81101
};
82102

83-
export const Upcoming: Story = {
103+
export const PendingFinalization: Story = {
84104
args: {
85105
data: {
86106
...simpleRound,
87-
stakedAmount: 0,
107+
stakedProjects: simpleRound.stakedProjects.map((project) => ({
108+
...project,
109+
unlockAt: simpleRound.votingEndDate,
110+
})),
88111
} as StakePoolDataCardProps,
89112
},
90113
parameters: {
91-
date: new Date(2023, 1, 1),
114+
date: new Date(2025, 1, 1),
92115
},
93116
};
94117

95-
export const Active: Story = {
118+
export const Claimed: Story = {
96119
args: {
97120
data: {
98121
...simpleRound,
99-
stakedAmount: 0,
122+
stakedAmount: 100000,
123+
claimed: true,
124+
isClaimable: true,
125+
stakedProjects: simpleRound.stakedProjects.map((project) => ({
126+
...project,
127+
variant: "claimed",
128+
isClaimable: true,
129+
claimedAt: new Date(2025, 29, 12),
130+
txHash: "0x1234567890abcdef",
131+
})),
100132
} as StakePoolDataCardProps,
101133
},
102134
parameters: {
103-
date: new Date("2024-12-10T19:22:30.678Z"),
135+
date: new Date(2026, 1, 1),
104136
},
105137
};
106138

107-
export const Ended: Story = {
139+
export const Upcoming: Story = {
108140
args: {
109141
data: {
110142
...simpleRound,
111143
stakedAmount: 0,
112144
} as StakePoolDataCardProps,
113145
},
114146
parameters: {
115-
date: new Date("2024-12-11T19:22:30.678Z"),
147+
date: new Date(2023, 1, 1),
116148
},
117149
};
118150

119-
export const Claimed: Story = {
151+
export const Active: Story = {
120152
args: {
121153
data: {
122154
...simpleRound,
123-
stakedAmount: 100000,
124-
claimed: true,
155+
stakedAmount: 0,
125156
} as StakePoolDataCardProps,
126157
},
127158
parameters: {
128-
date: new Date(2026, 1, 1),
159+
date: new Date("2024-12-10T19:22:30.678Z"),
129160
},
130161
};
131162

132-
export const Loading: Story = {
163+
export const Ended: Story = {
133164
args: {
134165
data: {
135166
...simpleRound,
136-
isLoading: true,
167+
stakedAmount: 0,
137168
} as StakePoolDataCardProps,
138169
},
139170
parameters: {
140-
date: new Date(2023, 1, 1),
171+
date: new Date("2024-12-11T19:22:30.678Z"),
141172
},
142173
};
143174

144-
export const NoLogo: Story = {
175+
export const Loading: Story = {
145176
args: {
146177
data: {
147178
...simpleRound,
179+
isLoading: true,
148180
} as StakePoolDataCardProps,
149181
},
150182
parameters: {

packages/ui/src/features/pool/components/StakePoolCard/components/PoolMetricsSection.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { IconWithDetails } from "./IconWithDetails";
88
*/
99
export const PoolMetricsSection = ({
1010
matchingPoolAmount,
11+
matchingPoolTokenTicker,
1112
totalProjects,
1213
totalStaked,
1314
chainIcon,
1415
}: {
1516
matchingPoolAmount?: number;
17+
matchingPoolTokenTicker?: string;
1618
totalProjects?: number;
1719
totalStaked?: number;
1820
chainIcon: IconType;
@@ -24,7 +26,7 @@ export const PoolMetricsSection = ({
2426
<div className="flex items-center justify-start gap-8">
2527
<IconWithDetails
2628
icon={IconType.GLOBE}
27-
label={`${matchingPoolAmount} USD`}
29+
label={`${matchingPoolAmount} ${matchingPoolTokenTicker}`}
2830
value="Matching Pool"
2931
/>
3032
<IconWithDetails

packages/ui/src/features/pool/components/StakePoolCard/components/StakePoolDataCard.tsx

+31-14
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ export const StakePoolDataCard = ({
2525
totalProjects,
2626
totalStaked,
2727
matchingPoolAmount,
28+
matchingPoolTokenTicker,
2829
stakedAmount,
2930
lastStakeDate,
3031
claimed,
32+
isClaimable,
3133
onClick,
3234
stakedProjects,
3335
}: StakePoolDataCardProps) => {
@@ -48,7 +50,12 @@ export const StakePoolDataCard = ({
4850
const hasStaked = Boolean(stakedAmount && stakedAmount > 0);
4951

5052
// Format unlock message
51-
const unlockMessage = formatUnlockMessage(isUnlocked, unlocksInMonths, unlocksInDays);
53+
const unlockMessage = formatUnlockMessage(
54+
isUnlocked,
55+
!!isClaimable,
56+
unlocksInMonths,
57+
unlocksInDays,
58+
);
5259

5360
// Handle card click
5461
const handleCardClick = () => {
@@ -82,7 +89,13 @@ export const StakePoolDataCard = ({
8289
<div className="flex flex-col gap-2">
8390
<Button
8491
size="small"
85-
value={!isUnlocked ? "Pending" : claimed ? "Claimed" : "Ready to claim"}
92+
value={
93+
claimed
94+
? "Claimed"
95+
: !isUnlocked || !isClaimable
96+
? "Pending"
97+
: "Ready to claim"
98+
}
8699
icon={
87100
<Icon
88101
type={IconType.CHEVRON_DOWN}
@@ -111,6 +124,7 @@ export const StakePoolDataCard = ({
111124

112125
<PoolMetricsSection
113126
matchingPoolAmount={matchingPoolAmount}
127+
matchingPoolTokenTicker={matchingPoolTokenTicker}
114128
totalProjects={totalProjects}
115129
totalStaked={totalStaked}
116130
chainIcon={icon}
@@ -123,7 +137,7 @@ export const StakePoolDataCard = ({
123137
"h-auto opacity-100": isOpen,
124138
})}
125139
>
126-
<div className="mt-2 flex flex-col gap-2 p-2">
140+
<div className="mt-2 flex max-h-[330px] flex-col gap-2 overflow-y-auto p-2">
127141
{stakedProjects?.map((project) => <StakeProjectCard key={project.id} {...project} />)}
128142
</div>
129143
</div>
@@ -163,21 +177,24 @@ const getRoundStatus = (
163177
*/
164178
const formatUnlockMessage = (
165179
isUnlocked: boolean,
180+
isClaimable: boolean,
166181
unlocksInMonths: number,
167182
unlocksInDays: number,
168183
): string => {
169184
if (isUnlocked) {
170-
return `Unlocked ${
171-
unlocksInMonths === 1
172-
? `${unlocksInMonths} month`
173-
: unlocksInMonths > 1
174-
? `${Math.ceil(unlocksInMonths)} months`
175-
: unlocksInDays === 1
176-
? `${unlocksInDays} day`
177-
: unlocksInDays > 1
178-
? `${Math.ceil(unlocksInDays)} days`
179-
: "< 1 day"
180-
} ago`;
185+
return isClaimable
186+
? `Unlocked ${
187+
unlocksInMonths === 1
188+
? `${unlocksInMonths} month`
189+
: unlocksInMonths > 1
190+
? `${Math.ceil(unlocksInMonths)} months`
191+
: unlocksInDays === 1
192+
? `${unlocksInDays} day`
193+
: unlocksInDays > 1
194+
? `${Math.ceil(unlocksInDays)} days`
195+
: "< 1 day"
196+
} ago`
197+
: "Finalizing the claim process";
181198
}
182199
return `Unlocks in ${
183200
unlocksInMonths === 1

0 commit comments

Comments
 (0)