Skip to content
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

Campaign manager tweaks #31

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@
},
"workspaces": ["packages/*"],
"dependencies": {
"@merkl/api": "0.10.396",
"viem": "2.21.54",
"wagmi": "^2.14.6",
"tailwindcss": "^3.4.12",
"@ariakit/react": "^0.4.12",
"@elysiajs/eden": "^1.1.3",
"@lifi/widget": "^3.13.1",
"@merkl/api": "0.10.351",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-scroll-area": "^1.2.0",
"@remix-run/dev": "^2.15.2",
"@remix-run/node": "^2.15.2",
"@remix-run/react": "^2.15.2",
"@remix-run/serve": "^2.15.2",
"@remixicon/react": "^4.6.0",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-scroll-area": "^1.2.0",
"@svgr/rollup": "^8.1.0",
"@tanstack/react-query": "^5.55.4",
"@vitejs/plugin-react": "^4.3.1",
Expand All @@ -46,13 +49,10 @@
"react-toastify": "^11.0.2",
"remix-utils": "^7.7.0",
"save": "^2.9.0",
"tailwindcss": "^3.4.12",
"tailwindcss-animate": "^1.0.7",
"typedoc": "^0.26.7",
"uuid": "^11.0.3",
"viem": "2.21.54",
"vite-plugin-dts": "^4.2.1",
"wagmi": "^2.14.6",
"zustand": "^5.0.0-rc.2"
},
"devDependencies": {
Expand Down
13 changes: 7 additions & 6 deletions src/components/element/Tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type TagType<T extends keyof TagTypes = keyof TagTypes> = {
type: T;
value: TagTypes[T];
};
export type TagProps<T extends keyof TagTypes> = {
export type TagProps<T extends keyof TagTypes = keyof TagTypes> = {
type: T;
look?: PrimitiveTagProps["look"];
value: TagTypes[T];
Expand All @@ -34,6 +34,7 @@ export default function Tag<T extends keyof TagTypes>({
type,
filter,
value,
look,
...props
}: Component<TagProps<T>, HTMLButtonElement>) {
const [_searchParams, setSearchParams] = useSearchParams();
Expand All @@ -51,7 +52,7 @@ export default function Tag<T extends keyof TagTypes>({
return s;
});
}}
look="soft"
look={look ?? "soft"}
{...props}>
<Icon size={props?.size} {...status.icon} />
{status?.label}
Expand All @@ -75,7 +76,7 @@ export default function Tag<T extends keyof TagTypes>({
return s;
})
}
look="tint"
look={look ?? "tint"}
key={action.label}
{...props}>
<Icon size={props?.size} {...action.icon} />
Expand All @@ -85,16 +86,16 @@ export default function Tag<T extends keyof TagTypes>({
);
}
case "token": {
return <TokenTag token={value as TagTypes["token"]} {...props} />;
return <TokenTag look={look} token={value as TagTypes["token"]} {...props} />;
}
case "tokenChain": {
return <TokenChainTag token={value as TagTypes["tokenChain"]} />;
return <TokenChainTag look={look} token={value as TagTypes["tokenChain"]} />;
}
case "protocol": {
const protocol = value as TagTypes["protocol"];

if (!protocol) return;
return <ProtocolTag protocol={protocol} {...props} />;
return <ProtocolTag look={look} protocol={protocol} {...props} />;
}
default:
return <PrimitiveTag {...props}>{value as string}</PrimitiveTag>;
Expand Down
3 changes: 1 addition & 2 deletions src/components/element/leaderboard/LeaderboardLibrary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { Chain, Token } from "@merkl/api";
import { useSearchParams } from "@remix-run/react";
import { Group, Text, Title } from "dappkit";
import { useMemo } from "react";
import { v4 as uuidv4 } from "uuid";
import Pagination from "../Pagination";
import { LeaderboardTable, LeaderboardTableWithoutReason } from "./LeaderboardTable";
import LeaderboardTableRow from "./LeaderboardTableRow";
Expand All @@ -30,7 +29,7 @@ export default function LeaderboardLibrary(props: LeaderboardLibraryProps) {
const rows = useMemo(() => {
return leaderboard?.map((row, index) => (
<LeaderboardTableRow
key={uuidv4()}
key={`${row.recipient}_${row.reason}_${row.amount}`}
total={BigInt(total ?? 0n)}
row={row}
showreason={reason}
Expand Down
19 changes: 11 additions & 8 deletions src/components/element/user/User.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import merklConfig from "@core/config";
import type { Chain } from "@merkl/api";
import { Button, Divider, Dropdown, Group, Hash, Icon, PrimitiveTag } from "dappkit";
import { Button, Divider, Dropdown, Group, Hash, Icon, PrimitiveTag, type PrimitiveTagProps } from "dappkit";

export type UserProps = { address: string; chain: Chain };
export type UserProps = { address: string; chain: Chain } & PrimitiveTagProps;

export default function User({ address, chain }: UserProps) {
export default function User({ address, chain, ...props }: UserProps) {
return (
<Dropdown
size="lg"
Expand All @@ -19,10 +20,12 @@ export default function User({ address, chain }: UserProps) {
<Divider className="border-main-6" horizontal />
{/* <Text size="xs">{token?.description}</Text> */}
<Group className="flex-col" size="md">
<Button to={`/users/${address}`} size="xs" look="soft">
<Icon remix="RiArrowRightLine" />
Check user claims
</Button>
{merklConfig.disableNavigation || (
<Button to={`/users/${address}`} size="xs" look="soft">
<Icon remix="RiArrowRightLine" />
Check user claims
</Button>
)}
{chain?.explorers?.map(explorer => {
return (
<Button
Expand All @@ -39,7 +42,7 @@ export default function User({ address, chain }: UserProps) {
</Group>
</Group>
}>
<PrimitiveTag look="soft">
<PrimitiveTag look="soft" {...props}>
<Hash format="short">{address}</Hash>
</PrimitiveTag>
</Dropdown>
Expand Down
25 changes: 23 additions & 2 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { routesType } from "@core/config/type";
import useUserCreator from "@core/modules/user/hooks/useUserCreator";
import { useNavigate } from "@remix-run/react";
import {
Button,
Container,
Dropdown,
Fmt,
Group,
Icon,
Image,
List,
SCREEN_BREAKDOWNS,
Select,
WalletButton,
Expand Down Expand Up @@ -42,7 +45,7 @@ const item = {

export default function Header() {
const { mode } = useTheme();
const { chainId, address: user, chains, switchChain } = useWalletContext();
const { chainId, address: user, chains, switchChain, address } = useWalletContext();
const [open, setOpen] = useState<boolean>(false);
const headerRef = useRef<HTMLElement>(null);

Expand Down Expand Up @@ -115,6 +118,21 @@ export default function Header() {
};
}, [isClient]);

const { creator } = useUserCreator();
const creatorButton = useMemo(
() =>
creator && (
<List flex="row" look="hype">
<Button to={`/${creator.id}`}>
<Icon rounded src={creator.icon} />
{creator.name}
</Button>
<Button>{Fmt.address(address, "short")}</Button>
</List>
),
[creator, address],
);

return (
<motion.header
ref={headerRef}
Expand Down Expand Up @@ -174,7 +192,10 @@ export default function Header() {
</Group>

<Group className="flex">
<WalletButton select={chainSwitcher} hideSpyMode={merklConfig.hideSpyMode}>
<WalletButton
status={creatorButton || undefined}
select={chainSwitcher}
hideSpyMode={merklConfig.hideSpyMode}>
<Button to={`/users/${user}`} size="sm" look="soft">
<Icon remix="RiArrowRightLine" /> Check claims
</Button>
Expand Down
10 changes: 10 additions & 0 deletions src/config/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ export const actions = {
description: "Earn rewards by depositiong liquidity in this pool.",
icon: { remix: "RiCoinFill" },
},
LONG: {
label: "Long",
description: "Earn rewards by depositiong liquidity in this pool.",
icon: { remix: "RiCoinFill" },
},
SHORT: {
label: "Short",
description: "Earn rewards by depositiong liquidity in this pool.",
icon: { remix: "RiCoinFill" },
},
} satisfies { [S in Opportunity["action"]]: { label: string; icon: IconProps; description: string } };

export type Action = keyof typeof actions;
Expand Down
34 changes: 16 additions & 18 deletions src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { OpportunityService } from "@core/modules/opportunity/opportunity.service";
import { type Themes, createColoring } from "dappkit";
import { v4 as uuidv4 } from "uuid";
import { http, createClient, custom } from "viem";
import {
arbitrum,
Expand Down Expand Up @@ -38,7 +37,6 @@ import {
xLayer,
} from "viem/chains";
import { eip712WalletActions, zksync } from "viem/zksync";
import { walletConnect } from "wagmi/connectors";
//TODO: find a better way to handle importing the client config, this works
//@ts-ignore
import merklClientConfig from "../../../../../merkl.config";
Expand Down Expand Up @@ -305,43 +303,43 @@ const defaultMerklConfig: MerklConfig<Themes> = {
route: "/",
enabled: true,
inHeader: false,
key: uuidv4(),
key: "home-link",
},
opportunities: {
icon: "RiPlanetFill",
route: "/opportunities",
enabled: true,
inHeader: true,
key: uuidv4(),
key: "opportunities-link",
},
protocols: {
icon: "RiVipCrown2Fill",
route: "/protocols",
enabled: true,
inHeader: true,
key: uuidv4(),
key: "protocols-link",
},
bridge: {
icon: "RiCompassesLine",
route: "/bridge",
enabled: true,
inHeader: true,
key: uuidv4(),
key: "bridge-link",
},
docs: {
icon: "RiFile4Fill",
route: "https://docs.merkl.xyz/",
external: true,
enabled: true,
inHeader: true,
key: uuidv4(),
key: "docs-link",
},
faq: {
icon: "RiQuestionFill",
route: "/faq",
enabled: true,
inHeader: true,
key: uuidv4(),
key: "faq-link",
},
},
header: {
Expand Down Expand Up @@ -409,16 +407,16 @@ const defaultMerklConfig: MerklConfig<Themes> = {
},
ssr: true,
connectors: [
walletConnect({
customStoragePrefix: "wagmi",
projectId: "26c912aadd2132cd869a5edc00aeea0f",
metadata: {
name: "Merkl Lite",
description: "Merkl Lite",
url: "https://app.merkl.xyz",
icons: [],
},
}),
// walletConnect({
// customStoragePrefix: "wagmi",
// projectId: "26c912aadd2132cd869a5edc00aeea0f",
// metadata: {
// name: "Merkl Lite",
// description: "Merkl Lite",
// url: "https://app.merkl.xyz",
// icons: [],
// },
// }),
],
},
};
Expand Down
4 changes: 4 additions & 0 deletions src/config/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ export type MerklConfig<T extends Themes> = {
};
footerLinks: { image: string; link: string; key: string }[];
footerNavLinks?: routesType;
/**
* Removes links to other pages of the app
*/
disableNavigation?: boolean;
};

export function createConfig<T extends Themes>({ wagmi, ...config }: MerklConfig<T>) {
Expand Down
27 changes: 27 additions & 0 deletions src/hooks/useTagIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { TagProps, TagTypes } from "@core/components/element/Tag";
import { actions } from "@core/config/actions";
import { statuses } from "@core/config/status";
import type { IconProps } from "dappkit";
import { useMemo } from "react";

export default function useTagIcons(tags: TagProps[]) {
return {
icons: useMemo(
() =>
tags?.map(function defineTagIcon<T extends keyof TagTypes>({ type, value }: { type: T; value: TagTypes[T] }) {
//TODO: use this everywhere
const iconDefinitions = {
action: action => actions[action]?.icon,
chain: chain => ({ src: chain.icon }),
protocol: protocol => ({ src: protocol?.icon }),
status: status => (statuses[status] ?? statuses.LIVE).icon,
token: token => ({ src: token.icon }),
tokenChain: token => ({ src: token.icon }),
} as const satisfies { [K in keyof TagTypes]: (value: TagTypes[K]) => IconProps };

return (iconDefinitions[type] as (v: typeof value) => IconProps)(value);
}),
[tags],
),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import { Time } from "dappkit";
import { Tooltip } from "dappkit";
import moment from "moment";
import { type ReactNode, useCallback, useMemo, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import useChain from "../../../chain/hooks/useChain";
import Token from "../../../token/components/element/Token";
import CampaignTooltipDates from "../CampaignTooltipDates";
Expand Down Expand Up @@ -179,7 +178,7 @@ export default function CampaignTableRow({
</Group>
<Group>
{rules?.map(rule => (
<Rule size="md" key={uuidv4()} type={rule.type} value={rule.value} />
<Rule size="md" key={`${rule.type}_${rule.value.label}`} type={rule.type} value={rule.value} />
))}
</Group>
</Group>
Expand Down
5 changes: 4 additions & 1 deletion src/modules/campaigns/components/rules/LiquidityRule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ export default function LiquidityRule({ value, ...props }: LiquidityRuleProps) {
content={<Group className="flex-col text-wrap max-w-[42ch]">{value.description}</Group>}>
<PrimitiveTag look="soft" {...props}>
{value.label}
<Value format="0.#%">{value.percentage / 10000}</Value>
{/* biome-ignore lint/suspicious/noExplicitAny: TODO: type this*/}
<Value size={(props as any).size} format="0.#%">
{value.percentage / 10000}
</Value>
</PrimitiveTag>
</Dropdown>
);
Expand Down
Loading
Loading