diff --git a/packages/app/src/common/components/tree/DynamicTree.tsx b/packages/app/src/common/components/tree/DynamicTree.tsx index e7e07d3d..76690c37 100644 --- a/packages/app/src/common/components/tree/DynamicTree.tsx +++ b/packages/app/src/common/components/tree/DynamicTree.tsx @@ -71,12 +71,20 @@ const width = (index: number, total: number): string => { }; export const DynamicTree: FC<{ + className?: string; details: TreeComponent; - style?: CSSProperties; + islandHeight?: number; onClick?: () => void; - className?: string; + style?: CSSProperties; variant?: "sm" | "md"; -}> = ({ details, style = {}, onClick, className = "", variant = "md" }) => { +}> = ({ + className = "", + details, + islandHeight = 300, + onClick, + style = {}, + variant = "md", +}) => { const { level, species } = details.metadata.type; const treeImages = []; @@ -119,8 +127,8 @@ export const DynamicTree: FC<{ {components} diff --git a/packages/app/src/common/container/Card.tsx b/packages/app/src/common/container/Card.tsx index 5c833c5a..dd33665c 100644 --- a/packages/app/src/common/container/Card.tsx +++ b/packages/app/src/common/container/Card.tsx @@ -2,7 +2,8 @@ import { type FC, type PropsWithChildren, type ReactNode } from "react"; import clx from "classnames"; interface CardProps { - title?: string; + className?: string; + title?: string | ReactNode; image?: ReactNode; orientation?: "horizontal" | "vertical"; size?: "small" | "medium" | "large"; @@ -10,6 +11,7 @@ interface CardProps { export const Card: FC = ({ children, + className, image, title, orientation = "vertical", @@ -19,25 +21,26 @@ export const Card: FC = ({ className={clx( orientation === "horizontal" && "card-side", size === "small" - ? "w-32 h-32 p-2" + ? "w-32 sm:h-32 p-2" : size === "medium" - ? "w-48 h-48 p-4" + ? "w-40 sm:w-48 h-40 sm:h-48 p-4" : "w-128 h-128 p-4", - "card glass" + "card glass", + className )} > {image !== undefined &&
{image}
}
{title !== undefined && (

{title} diff --git a/packages/app/src/common/container/TopicContainer.tsx b/packages/app/src/common/container/TopicContainer.tsx deleted file mode 100644 index e25449b6..00000000 --- a/packages/app/src/common/container/TopicContainer.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { - type ForwardRefRenderFunction, - type PropsWithChildren, - type ReactNode, -} from "react"; -import clx from "classnames"; - -interface TitleProps { - children: ReactNode; -} - -const Title: React.FC = ({ children }) => ( -
{children}
-); - -interface MainProps { - children: ReactNode; -} - -const Main: React.FC = ({ children }) => ( -
- {children} -
-); - -const _TopicContainer: ForwardRefRenderFunction< - HTMLDivElement, - { - className?: string; - active?: boolean; - titleContents: ReactNode; - } & React.HTMLAttributes & - PropsWithChildren -> = ({ children, titleContents, className, active = false, ...rest }, ref) => ( -
- {titleContents} -
{children}
-
-); - -export const TopicContainer = React.forwardRef(_TopicContainer); diff --git a/packages/app/src/common/partials/Layout.tsx b/packages/app/src/common/partials/Layout.tsx index 28751d9a..8d193ec9 100644 --- a/packages/app/src/common/partials/Layout.tsx +++ b/packages/app/src/common/partials/Layout.tsx @@ -42,7 +42,7 @@ const Layout: FC<{ children: ReactNode }> = ({ children }) => { (arr: T[], oldItem: T, newItem: T): T[] => { return [...arr.slice(0, index), newItem, ...arr.slice(index + 1)]; }; -const isMobilePortrait = (width: number): boolean => width < 768; - export { addUp, round, @@ -200,5 +198,4 @@ export { memoise, handleError, noop, - isMobilePortrait, }; diff --git a/packages/app/src/forest/ForestApp.tsx b/packages/app/src/forest/ForestApp.tsx index d98edb76..efa033d7 100644 --- a/packages/app/src/forest/ForestApp.tsx +++ b/packages/app/src/forest/ForestApp.tsx @@ -22,7 +22,6 @@ import { ForestLink } from "./ForestLink"; import { useWallet } from "@solana/wallet-adapter-react"; import { type ParentRelationship, type TreeNode } from "../api/types"; import { LinkWithQuery } from "../common/components/LinkWithQuery"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; const ForestTree: FC<{ details: TreeComponent; style?: CSSProperties }> = ({ details, @@ -101,13 +100,12 @@ const _ForestApp: ForwardRefRenderFunction< > = ({ className, active = false, ...rest }, ref) => { const [, updateZenMode] = useZenMode(); const { currentHelpRoute } = useHelp(); - const { screenType } = useScreenOrientation(); useEffect(() => { if (currentHelpRoute !== AppRoute.Forest) return; // we are not on the forest page, so don't update zen mode updateZenMode((prev) => ({ ...prev, showHelpButton: true, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, showWallet: false, })); }, [active, currentHelpRoute]); diff --git a/packages/app/src/grow/GrowApp.tsx b/packages/app/src/grow/GrowApp.tsx index 1703dd72..4a6739ff 100644 --- a/packages/app/src/grow/GrowApp.tsx +++ b/packages/app/src/grow/GrowApp.tsx @@ -25,7 +25,6 @@ import { partners } from "./partners"; import { PartnerButton } from "./components/PartnerButton"; import { OrgButtonContent } from "./OrgButtonContent"; import { LinkWithQuery } from "../common/components/LinkWithQuery"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; const Placeholder: FC = ({ children }) => (
@@ -44,7 +43,6 @@ const _GrowApp: ForwardRefRenderFunction< const navigate = useNavigate(); const wallet = useWallet(); - const { screenType } = useScreenOrientation(); useEffect(() => { if (!wallet.connected && active) navigate("/"); }, [active, wallet.connected]); @@ -55,7 +53,7 @@ const _GrowApp: ForwardRefRenderFunction< ...prev, showBGImage: false, showHelpButton: true, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, showWallet: active, })); }, [active, currentHelpRoute]); @@ -64,7 +62,10 @@ const _GrowApp: ForwardRefRenderFunction< return (
diff --git a/packages/app/src/hub/HubApp.tsx b/packages/app/src/hub/HubApp.tsx index d06bd456..c3c8a7d0 100644 --- a/packages/app/src/hub/HubApp.tsx +++ b/packages/app/src/hub/HubApp.tsx @@ -22,7 +22,6 @@ import { useForest } from "../common/context/forestContext"; import { useHelp } from "../common/context/HelpContext"; import { AppRoute } from "../Routes"; import { LinkWithQuery } from "../common/components/LinkWithQuery"; -import { useScreenOrientation } from "./hooks/useScreenOrientation"; const LINK_CHEVRON_SIZE = 32; @@ -41,7 +40,6 @@ const _HubApp: ForwardRefRenderFunction< const [showHubNav, updateShowHubNav] = useState(false); const wasHubNavShown = useRef(false); - const { screenType } = useScreenOrientation(); const showWalletButton = useMemo(() => { return wallet.connected && showHubNav; }, [wallet.connected, showHubNav]); @@ -95,7 +93,7 @@ const _HubApp: ForwardRefRenderFunction< console.log("showLinks useEffect timeout"); updateZenMode((prev) => ({ ...prev, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, })); }, 6000); @@ -130,154 +128,159 @@ const _HubApp: ForwardRefRenderFunction< return (
- - { - updateIntroLeft(false); - }} - onLeft={() => { - updateIntroLeft(true); - }} - /> -
-
- -
- - Forest -
-
- {myTree && ( - { - updateShowHubNav(!showHubNav); - }} - /> - )} - -
- Grow - -
-
-
-
- {myTree?.metadata?.type?.level !== undefined && - myTree?.metadata?.type?.level > 0 ? ( -
- - +
+
+ + { + updateIntroLeft(false); + }} + onLeft={() => { + updateIntroLeft(true); + }} + /> +
+
+ +
+ + Forest +
-
- ) : ( -
{ + updateShowHubNav(!showHubNav); + }} + /> )} - > - - + +
+ Grow + +
- )} -
- -
- - Forest -
-
- -
- Grow - -
-
-
-
- -
- Lock +
+ {myTree?.metadata?.type?.level !== undefined && + myTree?.metadata?.type?.level > 0 ? ( +
+ + + +
+ ) : ( +
+ + + +
+ )} +
+ +
+ + Forest +
+
+ +
+ Grow + +
+
-
- - - -
- Referral +
+ +
+ Lock +
+
+ +
+ +
+ Referral +
+
+ +
-
- - +
diff --git a/packages/app/src/hub/hooks/useScreenOrientation.ts b/packages/app/src/hub/hooks/useScreenOrientation.ts deleted file mode 100644 index 99699fdb..00000000 --- a/packages/app/src/hub/hooks/useScreenOrientation.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useWindowSize } from "usehooks-ts"; -import { useMemo } from "react"; -import { isMobilePortrait } from "../../common/utils"; - -export const useScreenOrientation = (): { - screenType: "mobilePortrait" | "landscapeOrDesktop"; -} => { - const windowSize = useWindowSize(); - const isPortrait = useMemo( - () => isMobilePortrait(windowSize.width), - [windowSize] - ); - - return { - screenType: isPortrait ? "mobilePortrait" : "landscapeOrDesktop", - }; -}; diff --git a/packages/app/src/locking/LockingApp.tsx b/packages/app/src/locking/LockingApp.tsx index 7ccdf9f3..1702cc61 100644 --- a/packages/app/src/locking/LockingApp.tsx +++ b/packages/app/src/locking/LockingApp.tsx @@ -1,5 +1,6 @@ -import clx from "classnames"; +import { useWallet } from "@solana/wallet-adapter-react"; import { type Details } from "@sunrisestake/client"; +import clx from "classnames"; import React, { forwardRef, type ForwardRefRenderFunction, @@ -23,7 +24,6 @@ import { DynamicTree } from "../common/components/tree/DynamicTree"; import { useForest } from "../common/context/forestContext"; import { AppRoute } from "../Routes"; import { useHelp } from "../common/context/HelpContext"; -import { useWallet } from "@solana/wallet-adapter-react"; import { useNFTs } from "../common/context/NFTsContext"; import { LockDetailsView } from "./LockDetails"; import { detailsIndicateUpgradePossible } from "./utils"; @@ -31,7 +31,6 @@ import { LockForm } from "./LockForm"; import { LockingSuccessModal } from "./LockingSuccessModal"; import { useInfoModal } from "../common/hooks/useInfoModal"; import { LinkWithQuery } from "../common/components/LinkWithQuery"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; // one full epoch has passed since the lock was created const canBeUnlocked = (details: Details | undefined): boolean => { @@ -57,7 +56,6 @@ const _LockingApp: ForwardRefRenderFunction< const { refresh } = useNFTs(); const navigate = useNavigate(); const wallet = useWallet(); - const { screenType } = useScreenOrientation(); useEffect(() => { if (!wallet.connected && active) navigate("/"); }, [active, wallet.connected]); @@ -69,7 +67,7 @@ const _LockingApp: ForwardRefRenderFunction< showBGImage: false, showHelpButton: true, showWallet: active, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, })); }, [active, currentHelpRoute]); @@ -153,7 +151,7 @@ const _LockingApp: ForwardRefRenderFunction< return (
{myTree && details?.impactNFTDetails === undefined && ( - + )} {details?.lockDetails === undefined && (
diff --git a/packages/app/src/referral/CopyButton.tsx b/packages/app/src/referral/CopyButton.tsx deleted file mode 100644 index 103e76de..00000000 --- a/packages/app/src/referral/CopyButton.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { type FC, type PropsWithChildren, useState } from "react"; -import { Transition } from "@headlessui/react"; -import { useCopyToClipboard } from "usehooks-ts"; - -export const CopyButton: FC = ({ - link, - children, -}) => { - const [, copy] = useCopyToClipboard(); - const [copied, setCopied] = useState(false); - - const copyLink = (): void => { - if (link === null) return; - copy(link) - .then(() => { - setCopied(true); - setTimeout(() => { - setCopied(false); - }, 5000); - }) - .catch(console.error); - }; - - return ( - - - - ✓ - - - {children} - - ); -}; diff --git a/packages/app/src/referral/ReferTweetButton.tsx b/packages/app/src/referral/ReferTweetButton.tsx deleted file mode 100644 index 38254a9c..00000000 --- a/packages/app/src/referral/ReferTweetButton.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React, { type PropsWithChildren } from "react"; -import { Tweet } from "../common/components/Tweet"; - -const ReferTweetButton: React.FC<{ link: string } & PropsWithChildren> = ({ - link, - children, -}) => { - return ( -
-
- -
- {children} -
- ); -}; - -export { ReferTweetButton }; diff --git a/packages/app/src/referral/ReferralApp.tsx b/packages/app/src/referral/ReferralApp.tsx index 80822d86..a838dabd 100644 --- a/packages/app/src/referral/ReferralApp.tsx +++ b/packages/app/src/referral/ReferralApp.tsx @@ -1,10 +1,9 @@ -import React, { +import clx from "classnames"; +import { type FC, forwardRef, type ForwardRefRenderFunction, - type PropsWithChildren, useEffect, - useMemo, } from "react"; import { useNavigate } from "react-router-dom"; @@ -14,12 +13,8 @@ import { AppRoute } from "../Routes"; import { useHelp } from "../common/context/HelpContext"; import { useWallet } from "@solana/wallet-adapter-react"; import { LinkWithQuery } from "../common/components/LinkWithQuery"; -import { TopicContainer } from "../common/container/TopicContainer"; import { Card } from "../common/container/Card"; import { ReferralOptions } from "./ReferralOptions"; -import { isMobilePortrait } from "../common/utils"; -import { useWindowSize } from "usehooks-ts"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; const Title: FC = () => (
@@ -31,35 +26,18 @@ const Title: FC = () => (
-

+

Share Your Referral Link

); -const Wrapper: FC = ({ children }) => { - const windowSize = useWindowSize(); - const isPortrait = useMemo( - () => isMobilePortrait(window.innerWidth), - [windowSize] - ); - - return isPortrait ? ( -
{children}
- ) : ( - - {children} - - ); -}; - const _ReferralApp: ForwardRefRenderFunction< HTMLDivElement, { className?: string; active?: boolean } & React.HTMLAttributes > = ({ className, active = false, ...rest }, ref) => { const { currentHelpRoute } = useHelp(); const [, updateZenMode] = useZenMode(); - const { screenType } = useScreenOrientation(); const navigate = useNavigate(); const wallet = useWallet(); @@ -79,17 +57,18 @@ const _ReferralApp: ForwardRefRenderFunction< showBGImage: false, showHelpButton: true, showWallet: active, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, })); }, [active, currentHelpRoute]); return ( - } > + + <div className="relative flex flex-col items-center pt-8"></div> {link === null && ( <div className="flex flex-col items-center m-4"> <h1 className="text-3xl text-center">Loading...</h1> @@ -100,13 +79,17 @@ const _ReferralApp: ForwardRefRenderFunction< </div> )} {link !== null && ( - <div className="mx-4 mb-3 flex flex-col items-center"> - <Wrapper> + <div className="mb-20 flex flex-col items-center"> + <Card + className="bg-green-light" + size="large" + orientation="horizontal" + > <ReferralOptions link={link} /> - </Wrapper> + </Card> </div> )} - </TopicContainer> + </div> ); }; diff --git a/packages/app/src/referral/ReferralOptions.tsx b/packages/app/src/referral/ReferralOptions.tsx index b7f9b49f..bd57b29d 100644 --- a/packages/app/src/referral/ReferralOptions.tsx +++ b/packages/app/src/referral/ReferralOptions.tsx @@ -1,59 +1,64 @@ -import React, { type FC } from "react"; -import { ShareButton } from "./ShareButton"; -import { FaShareSquare } from "react-icons/fa"; -import { Tweet } from "../common/components/Tweet"; -import { CopyButton } from "./CopyButton"; +import { useState, type FC } from "react"; +import { useCopyToClipboard } from "usehooks-ts"; + import { Card } from "../common/container/Card"; -import { ReferTweetButton } from "./ReferTweetButton"; import { QRCodeCard } from "./QRCodeCard"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; +import { FaTwitter } from "react-icons/fa"; export const ReferralOptions: FC<{ link: string }> = ({ link }) => { - const { screenType } = useScreenOrientation(); - const isPortrait = screenType === "mobilePortrait"; - const shareSupported = window.navigator?.canShare?.(); + const [, copy] = useCopyToClipboard(); + const [copied, setCopied] = useState(false); + + const copyLink = (): void => { + if (link === null) return; + copy(link) + .then(() => { + setCopied(true); + setTimeout(() => { + setCopied(false); + }, 5000); + }) + .catch(console.error); + }; return ( - <div className="w-full h-full md:space-x-8 space-y-4 md:space-y-0 justify-around items-center flex flex-col-reverse md:flex-row"> - {isPortrait && ( - <div className="flex flex-row justify-around w-full mt-5 items-center"> - {shareSupported && ( - <ShareButton link={link}> - <FaShareSquare className="text-white w-8 h-8" /> - </ShareButton> - )} - <Tweet - url={link} - tweet="Join my forest on Sunrise Stake! Join me and the Solana community in making a collective positive environmental impact." - /> - </div> - )} - {!isPortrait && ( - <> - <CopyButton link={link}> - <Card - title={"Copy to Clipboard"} - size="medium" - image={ - <img - src="/clip.png" - className="w-full h-full object-contain" - alt="Copy" - /> - } - ></Card> - </CopyButton> - <Card - size="medium" - title={"Share"} - image={ - <ReferTweetButton link={link}> - <img src="/sowing.png" alt="Share link" /> - </ReferTweetButton> - } - ></Card> - </> - )} + <div className="grid grid-cols-2 lg:grid-cols-4 gap-2 sm:gap-4"> + <button onClick={copyLink}> + <Card + title={copied ? "✓ Copied" : "Copy to Clipboard"} + size="medium" + image={ + <img + src="/clip.png" + className="w-full h-full object-contain" + alt="Copy" + /> + } + ></Card> + </button> + <a + href={`https://twitter.com/share?text=Join my forest on @SunriseStake!%0A%0AJoin me and the Solana community in making a collective positive environmental impact:%0A${link}`} + target="_blank" + rel="noreferrer" + referrerPolicy="origin" + > + <Card + size="medium" + title={ + <> + <FaTwitter size={20} title="Twitter" /> + Share + </> + } + image={ + <img + src="/sowing.png" + className="w-full h-full object-contain" + alt="Copy" + /> + } + /> + </a> <QRCodeCard link={link} type="sunrise" /> <QRCodeCard link={link} type="solanapay" /> </div> diff --git a/packages/app/src/staking/StakingApp.tsx b/packages/app/src/staking/StakingApp.tsx index 54e9eaa6..3319afc2 100644 --- a/packages/app/src/staking/StakingApp.tsx +++ b/packages/app/src/staking/StakingApp.tsx @@ -7,7 +7,6 @@ import { AppRoute } from "../Routes"; import { useHelp } from "../common/context/HelpContext"; import { useNavigate } from "react-router-dom"; import { useWallet } from "@solana/wallet-adapter-react"; -import { useScreenOrientation } from "../hub/hooks/useScreenOrientation"; const _StakingApp: ForwardRefRenderFunction< HTMLDivElement, @@ -15,7 +14,6 @@ const _StakingApp: ForwardRefRenderFunction< > = ({ className, active = false, ...rest }, ref) => { const { currentHelpRoute } = useHelp(); const [, updateZenMode] = useZenMode(); - const { screenType } = useScreenOrientation(); const navigate = useNavigate(); const wallet = useWallet(); @@ -29,14 +27,14 @@ const _StakingApp: ForwardRefRenderFunction< ...prev, showBGImage: false, showHelpButton: true, - showExternalLinks: screenType !== "mobilePortrait", + showExternalLinks: true, showWallet: active, })); }, [active, currentHelpRoute]); return ( <div - className={clx("container flex flex-col items-center", className)} + className={clx("flex flex-col items-center pb-14", className)} ref={ref} {...rest} > diff --git a/packages/app/src/staking/pages/StakeDashboard.tsx b/packages/app/src/staking/pages/StakeDashboard.tsx index 6f6f05c3..47de9348 100644 --- a/packages/app/src/staking/pages/StakeDashboard.tsx +++ b/packages/app/src/staking/pages/StakeDashboard.tsx @@ -303,7 +303,7 @@ const StakeDashboard: FC = () => { <div> <LinkWithQuery to="/lock" - className="flex items-center text-green justify-center mb-8" + className="flex items-center text-green justify-center" > <div className="flex flex-col items-center nowrap"> <span className="text-2xl">Lock</span> diff --git a/packages/app/tsconfig.json b/packages/app/tsconfig.json index d7be8ff8..47aad755 100644 --- a/packages/app/tsconfig.json +++ b/packages/app/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "paths": { - "react": ["node_modules/@types/react"] + "react": ["./node_modules/@types/react"] }, "target": "es5", "lib": [ @@ -25,6 +25,6 @@ "jsx": "react-jsx" }, "include": [ - "src" + "./src/**/*" ] }