Skip to content

Commit d592787

Browse files
authored
feat: add whitelist implementation with yaml and metrics (#209)
1 parent ae2364a commit d592787

2,589 files changed

Lines changed: 386957 additions & 188 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/components/LeftSidebar/index.tsx

Lines changed: 152 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ReferralsButton } from '@/components/Referrals/Button';
88
import { SettingsButton } from '@/components/Settings';
99
import { TeamsButton } from '@/components/Teams/Button';
1010
import { usePrivyAuth } from '@/contexts/auth/PrivyAuthProvider';
11+
import { useMetricsWhitelist } from '@/hooks/useMetricsWhitelist';
1112
import { Box, Divider, Flex, Text, Tooltip } from '@chakra-ui/react';
1213
import { ConnectButton } from '@rainbow-me/rainbowkit';
1314
import {
@@ -17,6 +18,7 @@ import {
1718
IconQuestionMark,
1819
IconWorld,
1920
} from '@tabler/icons-react';
21+
import { useRouter } from 'next/router';
2022
import React, { FC } from 'react';
2123
import styles from './index.module.css';
2224

@@ -29,20 +31,35 @@ export type LeftSidebarProps = {
2931
const MenuSection = ({
3032
title,
3133
children,
34+
onClick,
35+
isClickable,
3236
}: {
3337
title: string;
3438
children: React.ReactNode;
39+
onClick?: () => void;
40+
isClickable?: boolean;
3541
}) => (
3642
<Box mb={1}>
37-
<Text
38-
color="gray.400"
39-
fontSize="xs"
40-
px={3}
41-
py={1}
42-
textTransform="uppercase"
43+
<Tooltip
44+
label={isClickable ? 'Click to view metrics dashboard' : undefined}
45+
placement="right"
46+
isDisabled={!isClickable}
4347
>
44-
{title}
45-
</Text>
48+
<Text
49+
color={isClickable ? 'green.400' : 'gray.400'}
50+
fontSize="xs"
51+
px={3}
52+
py={1}
53+
textTransform="uppercase"
54+
cursor={isClickable ? 'pointer' : 'default'}
55+
onClick={isClickable ? onClick : undefined}
56+
_hover={isClickable ? { color: 'green.300', opacity: 0.9 } : {}}
57+
transition="all 0.2s"
58+
fontWeight={isClickable ? 'semibold' : 'normal'}
59+
>
60+
{title}
61+
</Text>
62+
</Tooltip>
4663
{children}
4764
</Box>
4865
);
@@ -80,11 +97,7 @@ const ExternalLinkMenuItem = ({
8097
onClick={() => window.open(href, '_blank', 'noopener,noreferrer')}
8198
>
8299
<Flex align="center" gap={3}>
83-
{letter ? (
84-
<LetterIcon letter={letter} />
85-
) : (
86-
Icon && <Icon size={20} />
87-
)}
100+
{letter ? <LetterIcon letter={letter} /> : Icon && <Icon size={20} />}
88101
<Text>{title}</Text>
89102
</Flex>
90103
</div>
@@ -97,9 +110,15 @@ export const LeftSidebar: FC<LeftSidebarProps> = ({
97110
}) => {
98111
const ToggleIcon = isSidebarOpen ? IconChevronLeft : IconChevronRight;
99112
const { isAuthenticated } = usePrivyAuth();
113+
const { isWhitelisted } = useMetricsWhitelist();
114+
const router = useRouter();
100115

101116
// For wallet connection support alongside Privy, we can still check account but don't require it
102-
const WalletConnectWrapper = ({ children }: { children: (account: any) => React.ReactNode }) => {
117+
const WalletConnectWrapper = ({
118+
children,
119+
}: {
120+
children: (account: any) => React.ReactNode;
121+
}) => {
103122
return (
104123
<ConnectButton.Custom>
105124
{({ account }) => children(account)}
@@ -125,134 +144,142 @@ export const LeftSidebar: FC<LeftSidebarProps> = ({
125144
{(account) => {
126145
// Use Privy authentication OR wallet connection for access
127146
const hasAccess = isAuthenticated || !!account;
128-
147+
129148
return (
130-
<div className={styles.mainContent}>
131-
<MenuSection title="General">
132-
<Tooltip
133-
isDisabled={hasAccess}
134-
label="Sign in to access dashboard features."
135-
placement="right"
136-
>
137-
<div className={styles.menuItem}>
138-
<Box
139-
pointerEvents={hasAccess ? 'auto' : 'none'}
140-
opacity={hasAccess ? 1 : 0.5}
141-
>
142-
<DashboardButton />
143-
</Box>
144-
</div>
145-
</Tooltip>
146-
<Tooltip
147-
isDisabled={hasAccess}
148-
label="Sign in to access referral system and earn bonus jobs."
149-
placement="right"
150-
>
151-
<div className={styles.menuItem}>
152-
<Box
153-
pointerEvents={hasAccess ? 'auto' : 'none'}
154-
opacity={hasAccess ? 1 : 0.5}
155-
>
156-
<ReferralsButton />
157-
</Box>
158-
</div>
159-
</Tooltip>
160-
</MenuSection>
149+
<div className={styles.mainContent}>
150+
<MenuSection title="General">
151+
<Tooltip
152+
isDisabled={hasAccess}
153+
label="Sign in to access dashboard features."
154+
placement="right"
155+
>
156+
<div className={styles.menuItem}>
157+
<Box
158+
pointerEvents={hasAccess ? 'auto' : 'none'}
159+
opacity={hasAccess ? 1 : 0.5}
160+
>
161+
<DashboardButton />
162+
</Box>
163+
</div>
164+
</Tooltip>
165+
<Tooltip
166+
isDisabled={hasAccess}
167+
label="Sign in to access referral system and earn bonus jobs."
168+
placement="right"
169+
>
170+
<div className={styles.menuItem}>
171+
<Box
172+
pointerEvents={hasAccess ? 'auto' : 'none'}
173+
opacity={hasAccess ? 1 : 0.5}
174+
>
175+
<ReferralsButton />
176+
</Box>
177+
</div>
178+
</Tooltip>
179+
</MenuSection>
161180

162-
<Divider my={0.5} borderColor="whiteAlpha.200" />
181+
<Divider my={0.5} borderColor="whiteAlpha.200" />
163182

164-
<MenuSection title="Preferences">
165-
<Tooltip
166-
isDisabled={hasAccess}
167-
label="Sign in to access personalized settings, scheduling preferences, and configurations."
168-
placement="right"
183+
<MenuSection
184+
title="Preferences"
185+
isClickable={hasAccess && isWhitelisted === true}
186+
onClick={() => {
187+
if (hasAccess && isWhitelisted === true) {
188+
router.push('/metrics');
189+
}
190+
}}
169191
>
170-
<div className={styles.menuItem}>
171-
<Box
172-
pointerEvents={hasAccess ? 'auto' : 'none'}
173-
opacity={hasAccess ? 1 : 0.5}
174-
>
175-
<SettingsButton />
176-
</Box>
177-
</div>
178-
</Tooltip>
179-
<Box className={styles.modelSelection}>
180-
<ModelSelectionButton />
181-
</Box>
182-
</MenuSection>
192+
<Tooltip
193+
isDisabled={hasAccess}
194+
label="Sign in to access personalized settings, scheduling preferences, and configurations."
195+
placement="right"
196+
>
197+
<div className={styles.menuItem}>
198+
<Box
199+
pointerEvents={hasAccess ? 'auto' : 'none'}
200+
opacity={hasAccess ? 1 : 0.5}
201+
>
202+
<SettingsButton />
203+
</Box>
204+
</div>
205+
</Tooltip>
206+
<Box className={styles.modelSelection}>
207+
<ModelSelectionButton />
208+
</Box>
209+
</MenuSection>
183210

184-
<Divider my={0.5} borderColor="whiteAlpha.200" />
211+
<Divider my={0.5} borderColor="whiteAlpha.200" />
185212

186-
<MenuSection title="Advanced">
187-
<Tooltip
188-
isDisabled={hasAccess}
189-
label="Sign in to access advanced features like workflows, API integrations, device sync, and CDP wallets."
190-
placement="right"
191-
>
192-
<div>
193-
<Box
194-
pointerEvents={hasAccess ? 'auto' : 'none'}
195-
opacity={hasAccess ? 1 : 0.5}
196-
pl={1}
197-
>
198-
<div className={styles.menuItem}>
199-
<AgentsButton />
200-
</div>
201-
<div className={styles.menuItem}>
202-
<TeamsButton />
203-
</div>
204-
<StyledTooltip
205-
label="Coinbase Developer Platform's managed wallets integration coming soon. This will enable secure key management and automated CDP interactions such as trading, borrowing, and more."
206-
placement="right"
213+
<MenuSection title="Advanced">
214+
<Tooltip
215+
isDisabled={hasAccess}
216+
label="Sign in to access advanced features like workflows, API integrations, device sync, and CDP wallets."
217+
placement="right"
218+
>
219+
<div>
220+
<Box
221+
pointerEvents={hasAccess ? 'auto' : 'none'}
222+
opacity={hasAccess ? 1 : 0.5}
223+
pl={1}
207224
>
208225
<div className={styles.menuItem}>
209-
<CdpWalletsButton />
226+
<AgentsButton />
227+
</div>
228+
<div className={styles.menuItem}>
229+
<TeamsButton />
210230
</div>
211-
</StyledTooltip>
212-
</Box>
213-
</div>
214-
</Tooltip>
215-
</MenuSection>
231+
<StyledTooltip
232+
label="Coinbase Developer Platform's managed wallets integration coming soon. This will enable secure key management and automated CDP interactions such as trading, borrowing, and more."
233+
placement="right"
234+
>
235+
<div className={styles.menuItem}>
236+
<CdpWalletsButton />
237+
</div>
238+
</StyledTooltip>
239+
</Box>
240+
</div>
241+
</Tooltip>
242+
</MenuSection>
216243

217-
<Divider my={0.5} borderColor="whiteAlpha.200" />
244+
<Divider my={0.5} borderColor="whiteAlpha.200" />
218245

219-
<MenuSection title="About">
220-
<ExternalLinkMenuItem
221-
icon={IconBrandDiscord}
222-
title="Join our Discord community!"
223-
href="https://discord.gg/Dc26EFb6JK"
224-
/>
225-
<ExternalLinkMenuItem
226-
letter="T"
227-
title="Follow us on Twitter"
228-
href="https://twitter.com/MorpheusAIs"
229-
/>
230-
<ExternalLinkMenuItem
231-
letter="G"
232-
title="Become a contributor"
233-
href="https://github.com/MorpheusAIs/Docs"
234-
/>
235-
<ExternalLinkMenuItem
236-
icon={IconWorld}
237-
title="Learn about Morpheus"
238-
href="https://mor.org/"
239-
/>
240-
<ExternalLinkMenuItem
241-
icon={IconQuestionMark}
242-
title="Help Center & FAQs"
243-
href="https://morpheusai.gitbook.io/morpheus/faqs"
244-
/>
245-
</MenuSection>
246-
</div>
246+
<MenuSection title="About">
247+
<ExternalLinkMenuItem
248+
icon={IconBrandDiscord}
249+
title="Join our Discord community!"
250+
href="https://discord.gg/Dc26EFb6JK"
251+
/>
252+
<ExternalLinkMenuItem
253+
letter="T"
254+
title="Follow us on Twitter"
255+
href="https://twitter.com/MorpheusAIs"
256+
/>
257+
<ExternalLinkMenuItem
258+
letter="G"
259+
title="Become a contributor"
260+
href="https://github.com/MorpheusAIs/Docs"
261+
/>
262+
<ExternalLinkMenuItem
263+
icon={IconWorld}
264+
title="Learn about Morpheus"
265+
href="https://mor.org/"
266+
/>
267+
<ExternalLinkMenuItem
268+
icon={IconQuestionMark}
269+
title="Help Center & FAQs"
270+
href="https://morpheusai.gitbook.io/morpheus/faqs"
271+
/>
272+
</MenuSection>
273+
</div>
247274
);
248275
}}
249276
</WalletConnectWrapper>
250277

251278
<div className={styles.footer}>
252279
<Box p={4}>
253-
<Box
254-
bg="rgba(255, 255, 255, 0.02)"
255-
borderRadius="12px"
280+
<Box
281+
bg="rgba(255, 255, 255, 0.02)"
282+
borderRadius="12px"
256283
border="1px solid rgba(255, 255, 255, 0.08)"
257284
p={3}
258285
>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.metricsButton {
2+
transition: opacity 0.2s ease;
3+
}
4+
5+
.icon {
6+
color: #59F886;
7+
}
8+

app/components/Metrics/Button.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { useMetricsWhitelist } from '@/hooks/useMetricsWhitelist';
2+
import { Flex, Text } from '@chakra-ui/react';
3+
import { BarChart3 } from 'lucide-react';
4+
import { useRouter } from 'next/router';
5+
import React from 'react';
6+
import styles from './Button.module.css';
7+
8+
export const MetricsButton: React.FC = () => {
9+
const router = useRouter();
10+
const { isWhitelisted, isLoading } = useMetricsWhitelist();
11+
12+
const handleClick = () => {
13+
if (isWhitelisted) {
14+
router.push('/metrics');
15+
}
16+
};
17+
18+
if (isLoading || !isWhitelisted) {
19+
return null;
20+
}
21+
22+
return (
23+
<Flex
24+
as="button"
25+
align="center"
26+
gap={3}
27+
width="100%"
28+
onClick={handleClick}
29+
pl={1}
30+
className={styles.metricsButton}
31+
_hover={{ opacity: 0.8 }}
32+
cursor="pointer"
33+
>
34+
<BarChart3 className={styles.icon} size={20} />
35+
<Text fontSize="14px" color="white">
36+
Metrics
37+
</Text>
38+
</Flex>
39+
);
40+
};

0 commit comments

Comments
 (0)