diff --git a/src/components/composite/Hero.tsx b/src/components/composite/Hero.tsx index 17b4b6c1..f72dede4 100644 --- a/src/components/composite/Hero.tsx +++ b/src/components/composite/Hero.tsx @@ -42,7 +42,7 @@ export default function Hero({ navigation, icons, title, description, tags, chil return ( <> @@ -106,15 +106,15 @@ export default function Hero({ navigation, icons, title, description, tags, chil {tags && ( - + {description} )} - + {tags && {tags}} {!tags && ( - + {description} )} diff --git a/src/components/element/SwitchMode.tsx b/src/components/element/SwitchMode.tsx new file mode 100644 index 00000000..1ebe8951 --- /dev/null +++ b/src/components/element/SwitchMode.tsx @@ -0,0 +1,15 @@ +import config from "merkl.config"; +import { Button, Icon, useTheme } from "packages/dappkit/src"; +import { useMemo } from "react"; + +export default function SwitchMode() { + const { mode, toggleMode } = useTheme(); + const canSwitchModes = useMemo(() => !(!config.modes || config.modes?.length === 1), []); + return ( + canSwitchModes && ( + + ) + ); +} diff --git a/src/components/element/Tag.tsx b/src/components/element/Tag.tsx index a76048a3..d940a69e 100644 --- a/src/components/element/Tag.tsx +++ b/src/components/element/Tag.tsx @@ -1,5 +1,5 @@ -import type { Chain, Opportunity, Token } from "@angleprotocol/merkl-api"; -import { Button, Divider, Dropdown, Group, Hash, Icon, PrimitiveTag, Text, Title } from "dappkit"; +import type { Opportunity, Token } from "@angleprotocol/merkl-api"; +import { Button, Divider, Dropdown, Group, Hash, Icon, PrimitiveTag, Text } from "dappkit"; import type { ButtonProps } from "dappkit"; import { type Action, actions } from "src/config/actions"; import type { Protocol } from "src/config/protocols"; @@ -29,23 +29,27 @@ export default function Tag({ type, value, ...props }: const status = statuses[value as TagTypes["status"]] ?? statuses.LIVE; return ( + - - Status - - - {status?.label} + + + {status?.label} + - - {status?.description} - - + + + {status?.description} + + + }> @@ -58,23 +62,27 @@ export default function Tag({ type, value, ...props }: const chain = value as TagTypes["chain"]; return ( - - - Chain - id: {chain?.id} - + + - - {chain?.name} + + + {chain?.name} + + id: {chain?.id} - - - + + + + + + }> @@ -88,23 +96,25 @@ export default function Tag({ type, value, ...props }: if (!action) return ; return ( + - - Action - - - {action?.label} + + + {action?.label} + - + {action?.description} - - + }> @@ -118,31 +128,36 @@ export default function Tag({ type, value, ...props }: if (!token) return ; return ( - - - Token - - {token.address} - - + + - {token?.name} + + {token?.name} + + + + {token.address} + + - - {/* {token?.description} */} - - - - + }> @@ -156,10 +171,12 @@ export default function Tag({ type, value, ...props }: if (!token) return ; return ( + - + Token {token.address} @@ -167,24 +184,28 @@ export default function Tag({ type, value, ...props }: - {token?.name} + + {token?.name} + - - {/* {token?.description} */} - + + + {/* {token?.description} */} - - - + }> @@ -198,28 +219,29 @@ export default function Tag({ type, value, ...props }: if (!protocol) return ; return ( - - - Protocol - - - - {value?.name} - + + + + + {value?.name} + - - {/* {token?.description} */} - - - - + }> diff --git a/src/components/element/functions/SearchBar.tsx b/src/components/element/functions/SearchBar.tsx index 840782c3..687ffad2 100644 --- a/src/components/element/functions/SearchBar.tsx +++ b/src/components/element/functions/SearchBar.tsx @@ -24,7 +24,11 @@ function OpportunityResult({ opportunity }: { opportunity: Opportunity }) { ); } -export default function SearchBar() { +interface SearchBarProps { + icon?: boolean; +} + +export default function SearchBar({ icon = false }: SearchBarProps) { useShortcut("ctrlKey", "k", () => { setOpened(true); }); @@ -98,13 +102,19 @@ export default function SearchBar() { }>
- } - /> + {icon ? ( + + ) : ( + } + /> + )}
); diff --git a/src/components/element/opportunity/OpportunityLibrary.tsx b/src/components/element/opportunity/OpportunityLibrary.tsx index 6e09968f..92977713 100644 --- a/src/components/element/opportunity/OpportunityLibrary.tsx +++ b/src/components/element/opportunity/OpportunityLibrary.tsx @@ -16,7 +16,9 @@ export type OpportunityLibrary = { export default function OpportunityLibrary({ opportunities, count, only, exclude, chains }: OpportunityLibrary) { const rows = useMemo( () => - opportunities?.map(o => ), + opportunities?.map(o => ( + + )), [opportunities], ); diff --git a/src/components/element/opportunity/OpportunityPagination.tsx b/src/components/element/opportunity/OpportunityPagination.tsx index dd8841b0..0addf7de 100644 --- a/src/components/element/opportunity/OpportunityPagination.tsx +++ b/src/components/element/opportunity/OpportunityPagination.tsx @@ -30,18 +30,18 @@ export default function OpportunityPagination({ count }: OpportunityPaginationPr diff --git a/src/components/element/opportunity/OpportunityTable.tsx b/src/components/element/opportunity/OpportunityTable.tsx index 8a2cb631..0ad21996 100644 --- a/src/components/element/opportunity/OpportunityTable.tsx +++ b/src/components/element/opportunity/OpportunityTable.tsx @@ -2,14 +2,20 @@ import { createTable } from "dappkit"; export const [OpportunityTable, OpportunityRow, opportunityColumns] = createTable({ opportunity: { - name: "OPPORTUNITY", + name: "Opportunities", size: "minmax(350px,1fr)", compact: "1fr", className: "justify-start", main: true, }, - apr: { - name: "APR", + actions: { + name: "Actions", + size: "minmax(min-content,150px)", + compactSize: "minmax(min-content,1fr)", + className: "justify-center", + }, + apy: { + name: "APY", size: "minmax(min-content,150px)", compactSize: "minmax(min-content,1fr)", className: "justify-center", @@ -21,7 +27,7 @@ export const [OpportunityTable, OpportunityRow, opportunityColumns] = createTabl className: "justify-center", }, rewards: { - name: "DAILY REWARDS", + name: "Daily rewards", size: "minmax(min-content,150px)", compactSize: "minmax(min-content,1fr)", className: "justify-center", diff --git a/src/components/element/opportunity/OpportunityTableRow.tsx b/src/components/element/opportunity/OpportunityTableRow.tsx index 6e8b52e4..c113262b 100644 --- a/src/components/element/opportunity/OpportunityTableRow.tsx +++ b/src/components/element/opportunity/OpportunityTableRow.tsx @@ -26,7 +26,17 @@ export default function OpportunityTableRow({ hideTags, opportunity, className, content="sm" className={mergeClass("", className)} {...props} - aprColumn={ + actionsColumn={ + + {tags + ?.filter(({ type }) => !hideTags || hideTags.includes(type)) + .map(tag => { + console.table(tag); + return ; + })} + + } + apyColumn={ - ); - })} - {canSwitchModes && ( - + {!mdScreens && ( + <> + {Object.entries(config.routes) + .filter(([key]) => !["homepage", "privacy", "terms"].includes(key)) + .map(([key, { route }]) => { + return ( + + ); + })} + + + + )} - {!mdScreens && } - + {!smScreens && }
diff --git a/src/components/layout/LayerMenu.tsx b/src/components/layout/LayerMenu.tsx index 7edf1efb..4731d06e 100644 --- a/src/components/layout/LayerMenu.tsx +++ b/src/components/layout/LayerMenu.tsx @@ -1,16 +1,20 @@ import { NavLink } from "@remix-run/react"; -import { Text } from "dappkit"; +import { Divider, Group, Text, WalletButton } from "dappkit"; import { Icon } from "packages/dappkit/src"; import type { FC } from "react"; +import { useMediaQuery } from "react-responsive"; import type { routesType } from "src/config/type"; +import SCREENS from "../../../packages/dappkit/src/constants/SCREENS.json"; +import SwitchMode from "../element/SwitchMode"; import SearchBar from "../element/functions/SearchBar"; export const LayerMenu: FC<{ nav: routesType; setOpen: (open: boolean) => void; }> = ({ nav, setOpen }) => { + const smScreens = useMediaQuery({ maxWidth: SCREENS.md }); return ( -
+
    {Object.entries(nav) @@ -20,9 +24,9 @@ export const LayerMenu: FC<{ setOpen(false)} to={value.route} - className="flex items-center gap-md text-main-12 capitalize"> - - + className="flex items-center gap-md capitalize"> + + {key} @@ -31,7 +35,18 @@ export const LayerMenu: FC<{
- + + + + + + {!!smScreens && ( + <> + + + + )} +
); diff --git a/src/routes/_merkl.opportunity.$chain.$type.$id.tsx b/src/routes/_merkl.opportunity.$chain.$type.$id.tsx index b6e179cc..f2f38b23 100644 --- a/src/routes/_merkl.opportunity.$chain.$type.$id.tsx +++ b/src/routes/_merkl.opportunity.$chain.$type.$id.tsx @@ -1,5 +1,9 @@ import type { Opportunity } from "@angleprotocol/merkl-api"; -import { type LoaderFunctionArgs, type MetaFunction, json } from "@remix-run/node"; +import { + type LoaderFunctionArgs, + type MetaFunction, + json, +} from "@remix-run/node"; import { Meta, Outlet, useLoaderData } from "@remix-run/react"; import { useMemo } from "react"; import { ChainService } from "src/api/services/chain.service"; @@ -9,7 +13,9 @@ import Tag from "src/components/element/Tag"; import { ErrorHeading } from "src/components/layout/ErrorHeading"; import useOpportunity from "src/hooks/resources/useOpportunity"; -export async function loader({ params: { id, type, chain: chainId } }: LoaderFunctionArgs) { +export async function loader({ + params: { id, type, chain: chainId }, +}: LoaderFunctionArgs) { if (!chainId || !id || !type) throw ""; const chain = await ChainService.get({ search: chainId }); @@ -43,22 +49,28 @@ export default function Index() { return spaced .map((str, index) => { + const key = str + crypto.randomUUID(); if (!str.match(/[\p{Letter}\p{Mark}]+/gu)) return [ - + {str} , ]; if (str.includes("-")) return str .split("-") - .flatMap((s, i, arr) => [s, i !== arr.length - 1 && -]); + .flatMap((s, i, arr) => [ + s, + i !== arr.length - 1 && -, + ]); if (str.includes("/")) return str .split("/") - .flatMap((s, i, arr) => [s, i !== arr.length - 1 && /]); - // biome-ignore lint/suspicious/noArrayIndexKey: required - return [{str}]; + .flatMap((s, i, arr) => [ + s, + i !== arr.length - 1 && /, + ]); + return [{str}]; }) .flatMap((str, index, arr) => [str, index !== arr.length - 1 && " "]); }, [opportunity]); @@ -67,7 +79,7 @@ export default function Index() { <> ({ src: t.icon }))} + icons={opportunity.tokens.map((t) => ({ src: t.icon }))} navigation={{ label: "Back to opportunities", link: "/" }} title={styleName} description={description} @@ -75,8 +87,15 @@ export default function Index() { { label: "Overview", link }, { label: "Leaderboard", link: `${link}/leaderboard` }, ]} - tags={tags.map(tag => )} - opportunity={opportunity}> + tags={tags.map((tag) => ( + + ))} + opportunity={opportunity} + > diff --git a/src/routes/_merkl.user.$address.tsx b/src/routes/_merkl.user.$address.tsx index 79732364..ebd63f51 100644 --- a/src/routes/_merkl.user.$address.tsx +++ b/src/routes/_merkl.user.$address.tsx @@ -17,7 +17,7 @@ export default function Index() { $6k - + Total earned @@ -25,7 +25,7 @@ export default function Index() { $1.2k - + Earned today @@ -33,7 +33,7 @@ export default function Index() { $3k - + Claimable