diff --git a/packages/extension/src/declarations.d.ts b/packages/extension/src/declarations.d.ts index 968a17a95..079760e22 100644 --- a/packages/extension/src/declarations.d.ts +++ b/packages/extension/src/declarations.d.ts @@ -1,5 +1,9 @@ declare module "*.svg" declare module "*.gif" +declare module "*.png" { + const url: string + export default url +} declare module "*.txt" { const url: string export default url diff --git a/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx b/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx index 0a14f54b8..3cad7e28b 100644 --- a/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx +++ b/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx @@ -1,5 +1,7 @@ -import { CellStack } from "@argent/ui" +import { CellStack, DapplandBanner } from "@argent/ui" +import dapplandBanner from "@argent/ui/assets/dapplandBannerBackground.png" import { Flex, VStack } from "@chakra-ui/react" +import { AnimatePresence, motion } from "framer-motion" import { FC, useCallback, useEffect, useRef } from "react" import { useLocation, useNavigate } from "react-router-dom" import useSWR from "swr" @@ -27,6 +29,7 @@ import { useAccountGuardianIsSelf } from "../shield/useAccountGuardian" import { StatusMessageBannerContainer } from "../statusMessage/StatusMessageBanner" import { AccountTokensButtons } from "./AccountTokensButtons" import { AccountTokensHeader } from "./AccountTokensHeader" +import { useDapplandBanner } from "./dappland/banner.state" import { TokenList } from "./TokenList" import { useCurrencyDisplayEnabled } from "./tokenPriceHooks" import { useFeeTokenBalance } from "./tokens.service" @@ -44,6 +47,7 @@ export const AccountTokens: FC = ({ account }) => { const { pendingTransactions } = useAccountTransactions(account) const { accountNames } = useAccountMetadata() const { isBackupRequired } = useBackupRequired() + const { hasSeenBanner } = useDapplandBanner() const currencyDisplayEnabled = useCurrencyDisplayEnabled() const transactionsBeforeReview = useKeyValueStorage( userReviewStore, @@ -102,6 +106,13 @@ export const AccountTokens: FC = ({ account }) => { const hasEscape = accountHasEscape(account) const accountGuardianIsSelf = useAccountGuardianIsSelf(account) + const showDapplandBanner = + !hasSeenBanner && + !showBackupBanner && + !needsUpgrade && + !hasPendingTransactions && + !hasEscape + const hadPendingTransactions = useRef(false) useEffect(() => { if (hasPendingTransactions) { @@ -149,6 +160,23 @@ export const AccountTokens: FC = ({ account }) => { {showNoBalanceForUpgrade && ( )} + + {showDapplandBanner && ( + + { + useDapplandBanner.setState({ hasSeenBanner: true }) + }} + /> + + )} + diff --git a/packages/extension/src/ui/features/accountTokens/dappland/banner.state.ts b/packages/extension/src/ui/features/accountTokens/dappland/banner.state.ts new file mode 100644 index 000000000..d55083073 --- /dev/null +++ b/packages/extension/src/ui/features/accountTokens/dappland/banner.state.ts @@ -0,0 +1,15 @@ +import create from "zustand" +import { persist } from "zustand/middleware" + +export interface DapplandBannerState { + hasSeenBanner: boolean +} + +export const useDapplandBanner = create( + persist( + (_set, _get) => ({ + hasSeenBanner: false, + }), + { name: "hasSeenDapplandBanner" }, + ), +) diff --git a/packages/extension/src/ui/features/settings/DapplandFooter.tsx b/packages/extension/src/ui/features/settings/DapplandFooter.tsx new file mode 100644 index 000000000..f05ab6686 --- /dev/null +++ b/packages/extension/src/ui/features/settings/DapplandFooter.tsx @@ -0,0 +1,28 @@ +import { Button, P3 } from "@argent/ui" +import { SimpleGrid, VStack } from "@chakra-ui/react" +import { FC } from "react" + +import { DapplandIcon } from "./assets/DapplandIcon" + +const DapplandFooter: FC = () => ( + + + Discover Starknet dapps: + + + + + +) + +export { DapplandFooter } diff --git a/packages/extension/src/ui/features/settings/SettingsScreen.tsx b/packages/extension/src/ui/features/settings/SettingsScreen.tsx index 98ff4e4f0..98f947bb6 100644 --- a/packages/extension/src/ui/features/settings/SettingsScreen.tsx +++ b/packages/extension/src/ui/features/settings/SettingsScreen.tsx @@ -18,6 +18,7 @@ import { H2 } from "../../theme/Typography" import { AccountListScreenItem } from "../accounts/AccountListScreenItem" import { useAccount, useSelectedAccount } from "../accounts/accounts.state" import { useExtensionIsInTab, useOpenExtensionInTab } from "../browser/tabs" +import { DapplandFooter } from "./DapplandFooter" import { SettingsMenuItem } from "./SettingsMenuItem" import { SupportFooter } from "./SupportFooter" @@ -145,6 +146,7 @@ export const SettingsScreen: FC = () => { title="Privacy" /> )} + diff --git a/packages/extension/src/ui/features/settings/assets/DapplandIcon.tsx b/packages/extension/src/ui/features/settings/assets/DapplandIcon.tsx new file mode 100644 index 000000000..5370fe0e6 --- /dev/null +++ b/packages/extension/src/ui/features/settings/assets/DapplandIcon.tsx @@ -0,0 +1,31 @@ +import { FC, SVGProps } from "react" + +export const DapplandIcon: FC> = (props) => ( + + + + + + + + + +) diff --git a/packages/storybook/.storybook/main.ts b/packages/storybook/.storybook/main.ts index d8891e51e..3972846b7 100644 --- a/packages/storybook/.storybook/main.ts +++ b/packages/storybook/.storybook/main.ts @@ -4,6 +4,7 @@ export default { stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], addons: [ "@storybook/addon-links", + "@storybook/addon-actions", { name: "@storybook/addon-essentials", options: { @@ -60,5 +61,5 @@ export default { } return config }, - staticDirs: ["../../extension/src"], + staticDirs: ["../../extension/src", "../../ui/assets"], } diff --git a/packages/storybook/src/declarations.d.ts b/packages/storybook/src/declarations.d.ts index 968a17a95..079760e22 100644 --- a/packages/storybook/src/declarations.d.ts +++ b/packages/storybook/src/declarations.d.ts @@ -1,5 +1,9 @@ declare module "*.svg" declare module "*.gif" +declare module "*.png" { + const url: string + export default url +} declare module "*.txt" { const url: string export default url diff --git a/packages/storybook/src/ui/components/DapplandBanner.stories.tsx b/packages/storybook/src/ui/components/DapplandBanner.stories.tsx new file mode 100644 index 000000000..918d038a3 --- /dev/null +++ b/packages/storybook/src/ui/components/DapplandBanner.stories.tsx @@ -0,0 +1,22 @@ +import { DapplandBanner } from "@argent/ui" +import dapplandBanner from "@argent/ui/assets/dapplandBannerBackground.png" +import { action } from "@storybook/addon-actions" +import { ComponentMeta, ComponentStory } from "@storybook/react" + +export default { + title: "components/DapplandBanner", + component: DapplandBanner, +} as ComponentMeta + +const Template: ComponentStory = (props) => ( + +) + +export const Default = Template.bind({}) +Default.args = { + title: "Discover", + subTitle: "Starknet dapps", + backgroundImageUrl: dapplandBanner, + href: "https://www.dappland.com?utm_source=argent&utm_medium=extension&utm_content=banner", + onClose: action("onClose"), +} diff --git a/packages/ui/assets/dapplandBannerBackground.png b/packages/ui/assets/dapplandBannerBackground.png new file mode 100644 index 000000000..fa9f3cb9e Binary files /dev/null and b/packages/ui/assets/dapplandBannerBackground.png differ diff --git a/packages/ui/package.json b/packages/ui/package.json index b11844d8c..544270f99 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -4,7 +4,8 @@ "license": "MIT", "private": true, "files": [ - "dist" + "dist", + "assets" ], "main": "./dist/ui.umd.js", "module": "./dist/ui.es.js", @@ -13,7 +14,8 @@ ".": { "import": "./dist/ui.es.js", "require": "./dist/ui.umd.js" - } + }, + "./assets/dapplandBannerBackground.png": "./assets/dapplandBannerBackground.png" }, "devDependencies": { "@chakra-ui/cli": "^2.1.8", diff --git a/packages/ui/src/components/DapplandBanner.tsx b/packages/ui/src/components/DapplandBanner.tsx new file mode 100644 index 000000000..a85a7849d --- /dev/null +++ b/packages/ui/src/components/DapplandBanner.tsx @@ -0,0 +1,99 @@ +import { Box } from "@chakra-ui/react" +import { FC, MouseEventHandler } from "react" + +import { ButtonCell } from "./CellStack" +import { CloseIcon } from "./icons" +import { P3, P4 } from "./Typography" + +interface CloseButtonProps { + onClick?: MouseEventHandler +} + +interface DapplandBannerProps { + href: string + backgroundImageUrl: string + title?: string + subTitle?: string + onClose?: () => void +} + +const Scrim: FC = () => ( + +) +const CloseButton: FC = ({ ...props }) => ( + + + +) + +export const DapplandBanner: FC = ({ + href, + backgroundImageUrl, + title = "Discover", + subTitle = "Starknet dapps", + onClose, +}) => { + return ( + + + + {title} + + + {subTitle} + + { + e.preventDefault() + e.stopPropagation() + onClose?.() + }} + /> + + ) +} diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 905bcc2d6..4ffccddb5 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -8,6 +8,7 @@ export * from "./AlertDialog" export * from "./Button" export * from "./CellStack" export * from "./CopyTooltip" +export * from "./DapplandBanner" export * from "./Empty" export * from "./Error" export * from "./Input"