diff --git a/frontend/pages/index.js b/frontend/pages/index.js index 91c5be10..4851a0b6 100644 --- a/frontend/pages/index.js +++ b/frontend/pages/index.js @@ -1,26 +1,19 @@ -import React, { - useState, - useContext, - Suspense, - useEffect, - useLayoutEffect, -} from "react"; +import React, { useState, Suspense, useEffect, useLayoutEffect } from "react"; import { Fade, Flex, Heading, Box, - Image as ChakraImage, - Button, Center, chakra, Stack, Link, - SimpleGrid, useMediaQuery, Grid, Text, GridItem, + SimpleGrid, + Image as ChakraImage, } from "@chakra-ui/react"; import dynamic from "next/dynamic"; import useUser from "../src/core/hooks/useUser"; @@ -30,56 +23,15 @@ import { MIXPANEL_PROPS, MIXPANEL_EVENTS, } from "../src/core/providers/AnalyticsProvider/constants"; -import UIContext from "../src/core/providers/UIProvider/context"; import { AWS_ASSETS_PATH } from "../src/core/constants"; import mixpanel from "mixpanel-browser"; -const SplitWithImage = dynamic( - () => import("../src/components/SplitWithImage"), - { - ssr: false, - } -); + const ConnectedButtons = dynamic( () => import("../src/components/ConnectedButtons"), { ssr: false, } ); - -const RiDashboardFill = dynamic(() => - import("react-icons/ri").then((mod) => mod.RiDashboardFill) -); -const FaFileContract = dynamic(() => - import("react-icons/fa").then((mod) => mod.FaFileContract) -); -const GiMeshBall = dynamic(() => - import("react-icons/gi").then((mod) => mod.GiMeshBall) -); - -const GiLogicGateXor = dynamic(() => - import("react-icons/gi").then((mod) => mod.GiLogicGateXor) -); - -const GiSuspicious = dynamic(() => - import("react-icons/gi").then((mod) => mod.GiSuspicious) -); - -const GiHook = dynamic(() => - import("react-icons/gi").then((mod) => mod.GiHook) -); - -const AiFillApi = dynamic(() => - import("react-icons/ai").then((mod) => mod.AiFillApi) -); - -const BiTransfer = dynamic(() => - import("react-icons/bi").then((mod) => mod.BiTransfer) -); - -const IoTelescopeSharp = dynamic(() => - import("react-icons/io5").then((mod) => mod.IoTelescopeSharp) -); - const HEADING_PROPS = { fontWeight: "700", fontSize: ["4xl", "5xl", "4xl", "5xl", "6xl", "7xl"], @@ -94,12 +46,11 @@ const assets = { pendingTransactions: `${AWS_ASSETS_PATH}/Ethereum+pending+transactions.png`, priceInformation: `${AWS_ASSETS_PATH}/Price+information.png`, socialMediaPosts: `${AWS_ASSETS_PATH}/Social+media+posts.png`, - algorithmicFunds: `${AWS_ASSETS_PATH}/algorithmic+funds.png`, cryptoTraders: `${AWS_ASSETS_PATH}/crypto+traders.png`, + comicWhite: `${AWS_ASSETS_PATH}/moonstream-comic-white.png`, smartDevelopers: `${AWS_ASSETS_PATH}/smart+contract+developers.png`, }; const Homepage = () => { - const ui = useContext(UIContext); const [background, setBackground] = useState("background720"); const [backgroundLoaded720, setBackgroundLoaded720] = useState(false); const [backgroundLoaded1920, setBackgroundLoaded1920] = useState(false); @@ -254,7 +205,7 @@ const Homepage = () => { fontWeight="semibold" color="white" > - All the crypto data you care about in a single stream + Open source blockchain analytics { display="inline-block" color="blue.200" > - Get all the crypto data you need in a single stream. - From pending transactions in the Ethereum transaction - pool to Elon Musk’s latest tweets. - - - Access this data through the Moonstream dashboard or - API + Product analytics for Web3. Moonstream helps you + understand exactly how people are using your smart + contracts. @@ -280,16 +223,8 @@ const Homepage = () => { - + { > - {` We believe in financial inclusion. Proprietary technologies - are not financially inclusive. That's why all our software - is `} - + We believe that the blockchain is for everyone. This + requires complete transparency. That’s why all our + software is{" "} + open source @@ -313,10 +252,10 @@ const Homepage = () => { - Data you can add to your stream: + See how your smart contracts are being used from: @@ -369,193 +308,53 @@ const Homepage = () => { w="100%" direction={["column", "row", "column", null, "column"]} flexWrap={["nowrap", "nowrap", "nowrap", null, "nowrap"]} - pb="66px" + pb="32px" > { mixpanel.get_distinct_id() && mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `scroll to CryptoTrader`, + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Connected buttons: scroll to analytics`, + }); + }, + }} + button1={{ + label: "TX pool real time data", + link: "/#txpool", + onClick: () => { + mixpanel.get_distinct_id() && + mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Connected buttons: scroll to txpool`, }); }, }} button2={{ - label: "Algorithmic Fund", - link: "/#algoFund", + label: "Exchange price stream", + link: "/#exchanges", onClick: () => { mixpanel.get_distinct_id() && mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `scroll to AlgoFund`, + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Connected buttons: scroll to exchanges`, }); }, }} button3={{ - label: "Developer", + label: "Social media posts", link: "/#smartDeveloper", onClick: () => { mixpanel.get_distinct_id() && mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `scroll to Developer`, + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Connected buttons: scroll to developer`, }); }, }} /> - - { - mixpanel.get_distinct_id() && - mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Early access CTA: Crypto trader`, - }); - toggleModal("hubspot-trader"); - }, - }} - elementName={"element1"} - colorScheme="green" - badge={`For crypto traders`} - title={``} - body={``} - bullets={[ - { - text: `Subscribe to the defi contracts you care about`, - icon: FaFileContract, - color: "green.50", - bgColor: "green.900", - }, - { - text: `Make sense of how others are calling these contracts using Moonstream dashboards. - `, - icon: RiDashboardFill, - color: "green.50", - bgColor: "green.900", - }, - { - text: `Get data directly from the transaction pool through our global network of Ethereum nodes`, - icon: GiMeshBall, - color: "green.50", - bgColor: "green.900", - }, - ]} - imgURL={assets["cryptoTraders"]} - /> - - - { - mixpanel.get_distinct_id() && - mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Early access CTA: Algo fund`, - }); - toggleModal("hubspot-fund"); - }, - }} - elementName={"element2"} - mirror={true} - colorScheme="orange" - badge={`For algorithmic funds`} - bullets={[ - { - text: `Get API access to your stream`, - icon: AiFillApi, - color: "orange.50", - bgColor: "orange.900", - }, - { - text: `Set conditions that trigger predefined actions`, - icon: GiLogicGateXor, - color: "orange.50", - bgColor: "orange.900", - }, - { - text: `Execute transactions directly on Moonstream nodes`, - icon: BiTransfer, - color: "orange.50", - bgColor: "orange.900", - }, - ]} - imgURL={assets["algorithmicFunds"]} - /> - - - { - mixpanel.get_distinct_id() && - mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Early access CTA: developer`, - }); - toggleModal("hubspot-developer"); - }, - }} - socialButton={{ - url: "https://github.com/bugout-dev/moonstream/", - network: "github", - label: "See our github", - onClick: () => { - mixpanel.get_distinct_id() && - mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { - [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Github link in landing page`, - }); - }, - }} - elementName={"element3"} - colorScheme="blue" - badge={`For smart contract developers`} - bullets={[ - { - text: `See how people use your smart contracts`, - icon: IoTelescopeSharp, - color: "blue.50", - bgColor: "blue.900", - }, - { - text: `Set up alerts on suspicious activity`, - icon: GiSuspicious, - color: "blue.50", - bgColor: "blue.900", - }, - { - text: `Register webhooks to connect your off-chain infrastructure`, - icon: GiHook, - color: "blue.50", - bgColor: "blue.900", - }, - ]} - imgURL={assets["smartDevelopers"]} - /> - { pb="120px" >
- + + + Want to find out more? Reach out to us on{" "} + { + mixpanel.get_distinct_id() && + mixpanel.track( + `${MIXPANEL_EVENTS.BUTTON_CLICKED}`, + { + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Join our discord`, + } + ); + }} + isExternal + href={"https://discord.gg/K56VNUQGvA"} + > + Discord + {" "} + or{" "} + { + mixpanel.get_distinct_id() && + mixpanel.track( + `${MIXPANEL_EVENTS.BUTTON_CLICKED}`, + { + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Early access CTA: developer want to find more button`, + } + ); + toggleModal("hubspot-developer"); + }} + > + request early access + + +
diff --git a/frontend/pages/product/index.js b/frontend/pages/product/index.js index fa03ba4a..ad154392 100644 --- a/frontend/pages/product/index.js +++ b/frontend/pages/product/index.js @@ -1,26 +1,30 @@ import React, { useEffect, useState, useLayoutEffect } from "react"; import { - Heading, Text, Flex, Link, Stack, - chakra, useMediaQuery, useBreakpointValue, + Center, } from "@chakra-ui/react"; -import { DEFAULT_METATAGS, AWS_ASSETS_PATH } from "../../src/core/constants"; -export async function getStaticProps() { - return { - props: { metaTags: { ...DEFAULT_METATAGS } }, - }; -} - +import { AWS_ASSETS_PATH } from "../../src/core/constants"; +import SplitWithImage from "../../src/components/SplitWithImage"; +import mixpanel from "mixpanel-browser"; +import { + MIXPANEL_PROPS, + MIXPANEL_EVENTS, +} from "../../src/core/providers/AnalyticsProvider/constants"; const assets = { background720: `${AWS_ASSETS_PATH}/product-background-720x405.png`, background1920: `${AWS_ASSETS_PATH}/product-background-720x405.png`, background2880: `${AWS_ASSETS_PATH}/product-background-720x405.png`, background3840: `${AWS_ASSETS_PATH}/product-background-720x405.png`, + environment: `${AWS_ASSETS_PATH}/product_comic/environment.png`, + developers: `${AWS_ASSETS_PATH}/product_comic/developers.png`, + meanwhile: `${AWS_ASSETS_PATH}/product_comic/meanwhile.png`, + struggle: `${AWS_ASSETS_PATH}/product_comic/struggle.png`, + solution: `${AWS_ASSETS_PATH}/product_comic/solution.png`, }; const Product = () => { @@ -131,72 +135,115 @@ const Product = () => { alignItems="center" pb={24} > - - - {`Why you'll love Moonstream`} - - - - We strive for financial inclusion. With cryptocurrencies becoming - mainstream, now is the time for anyone with a computer and access to - the Internet to utilize this opportunity to make passive income. - We’re here to make it easier. - - - Right now our source of data is Ethereum blockchain. Our goal is to - provide a live view of the transactions taking place on every public - blockchain - from the activity of specific accounts or smart - contracts to updates about general market movements. - - - This information comes from the blockchains themselves, from their - mempools/transaction pools, and from centralized exchanges, social - media, and the news. This forms a stream of information tailored to - your specific needs. - - - We’re giving you a macro view of the crypto market with direct - access from Moonstream dashboards to execute transactions. You can - also set up programs which execute (on- or off-chain) when your - stream meets certain conditions. - - - Moonstream is accessible through dashboard, API and webhooks. - - - Moonstream’s financial inclusion goes beyond providing access to - data. All of our work is open source as we do not believe that - proprietary technologies are financially inclusive. - - - You can read{" "} - - our code on GitHub. - {" "} - and keep track of our progress using{" "} - - the Moonstream milestones - - . - - + + + + + + +
+ + + To find out more, join us on{" "} + { + mixpanel.get_distinct_id() && + mixpanel.track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_NAME}`]: `Join our discord`, + }); + }} + isExternal + href={"https://discord.gg/K56VNUQGvA"} + > + Discord + {" "} + + +
); }; + +export async function getStaticProps() { + const metaTags = { + title: "Moonstream.to: web3 analytics", + description: + "Moonstream brings product analytics to web3. Instantly get analytics for any smart contract you write.", + keywords: + "blockchain, crypto, data, trading, smart contracts, ethereum, solana, transactions, defi, finance, decentralized, analytics, product", + url: "https://www.moonstream.to/product", + image: `${AWS_ASSETS_PATH}/product_comic/solution.png`, + }; + + const assetPreload = Object.keys(assets).map((key) => { + return { + rel: "preload", + href: assets[key], + as: "image", + }; + }); + const preconnects = [{ rel: "preconnect", href: "https://s3.amazonaws.com" }]; + + const preloads = assetPreload.concat(preconnects); + + return { + props: { metaTags, preloads }, + }; +} + export default Product; diff --git a/frontend/pages/welcome.js b/frontend/pages/welcome.js index 9bb4f2b8..7caeb345 100644 --- a/frontend/pages/welcome.js +++ b/frontend/pages/welcome.js @@ -8,8 +8,6 @@ import { Stack, ButtonGroup, Spacer, - Radio, - RadioGroup, UnorderedList, ListItem, Fade, @@ -28,7 +26,6 @@ import { import StepProgress from "../src/components/StepProgress"; import { ArrowLeftIcon, ArrowRightIcon } from "@chakra-ui/icons"; import Scrollable from "../src/components/Scrollable"; -import AnalyticsContext from "../src/core/providers/AnalyticsProvider/context"; import NewSubscription from "../src/components/NewSubscription"; import StreamEntry from "../src/components/StreamEntry"; import SubscriptionsList from "../src/components/SubscriptionsList"; @@ -39,8 +36,6 @@ import { FaFilter } from "react-icons/fa"; const Welcome = () => { const { subscriptionsCache } = useSubscriptions(); const ui = useContext(UIContext); - const { mixpanel, isLoaded, MIXPANEL_PROPS } = useContext(AnalyticsContext); - const [profile, setProfile] = React.useState(); const [showSubscriptionForm, setShowSubscriptionForm] = useBoolean(true); useEffect(() => { @@ -53,14 +48,6 @@ const Welcome = () => { ui.setOnboardingStep(index); }; - useEffect(() => { - if (profile && isLoaded) { - mixpanel.people.set({ - [`${MIXPANEL_PROPS.USER_SPECIALITY}`]: profile, - }); - } - }, [profile, MIXPANEL_PROPS, isLoaded, mixpanel]); - const SubscriptonCreatedCallback = () => { setShowSubscriptionForm.off(); }; @@ -250,48 +237,6 @@ const Welcome = () => {
- - - - Tell us more about your needs - - - In order to create the best possible experience, we would love - to find out some more about you. - - - Please tell us what profile describes you best.{" "} - - This is purely analytical data, you can change it anytime - later. - - - - - I am trading crypto currency - I represent investment fund - I am developer - - - )} diff --git a/frontend/src/components/ConnectedButtons.js b/frontend/src/components/ConnectedButtons.js index 990f1cc1..f04897d5 100644 --- a/frontend/src/components/ConnectedButtons.js +++ b/frontend/src/components/ConnectedButtons.js @@ -1,5 +1,13 @@ import React, { useEffect, useRef, useContext } from "react"; -import { Flex, Heading, Button, Link, SimpleGrid } from "@chakra-ui/react"; +import { + Flex, + Heading, + Button, + Link, + SimpleGrid, + useBreakpointValue, + useMediaQuery, +} from "@chakra-ui/react"; import Xarrow, { useXarrow } from "react-xarrows"; import UIContext from "../core/providers/UIProvider/context"; @@ -9,6 +17,9 @@ const ArrowCTA = (props) => { const box1Ref = useRef(null); const box2Ref = useRef(null); const box3Ref = useRef(null); + const box4Ref = useRef(null); + + // const gridRow = props.button4 ? [5, 4, 2, null, 2] : [4, 3, 2, null, 2]; const updateXarrow = useXarrow(); @@ -17,24 +28,65 @@ const ArrowCTA = (props) => { // eslint-disable-next-line }, [ui.isMobileView]); + const xarrowEntrySide = useBreakpointValue({ + base: "top", + sm: "left", + md: "top", + lg: "top", + xl: "top", + "2xl": "top", + }); + + const [isLargerThan580px] = useMediaQuery(["(min-width: 580px)"]); + + const buttonWidth = [ + "190px", + isLargerThan580px ? "200px" : "140px", + "230px", + null, + "280px", + ]; + + const fontSize = [ + undefined, + isLargerThan580px ? undefined : "12px", + undefined, + null, + ]; + + const speedConst = -0.05; + return ( - + {props.title} @@ -50,8 +102,9 @@ const ArrowCTA = (props) => { variant="solid" colorScheme="green" className="MoonStockSpeciality element1" - w={["180px", "180px", "250px", null, "250px"]} + w={buttonWidth} onClick={props.button1.onClick} + fontSize={fontSize} > {props.button1.label} @@ -67,7 +120,8 @@ const ArrowCTA = (props) => { variant="solid" colorScheme="orange" className="MoonStockSpeciality element2" - w={["180px", "180px", "250px", null, "250px"]} + w={buttonWidth} + fontSize={fontSize} onClick={props.button2.onClick} > {props.button2.label} @@ -83,46 +137,82 @@ const ArrowCTA = (props) => { boxShadow="md" variant="solid" colorScheme="blue" - w={["180px", "180px", "250px", null, "250px"]} + w={buttonWidth} + fontSize={fontSize} onClick={props.button3.onClick} > {props.button3.label} + {props.button4 && ( + + )} + {props.button4 && ( + + )} ); }; diff --git a/frontend/src/components/Sidebar.js b/frontend/src/components/Sidebar.js index 5cc6f818..fc63394e 100644 --- a/frontend/src/components/Sidebar.js +++ b/frontend/src/components/Sidebar.js @@ -118,6 +118,14 @@ const Sidebar = () => { > Login + + {" "} + Product + + + {" "} + Team + )} diff --git a/frontend/src/components/SplitWithImage.js b/frontend/src/components/SplitWithImage.js index 5220d052..203d9dbf 100644 --- a/frontend/src/components/SplitWithImage.js +++ b/frontend/src/components/SplitWithImage.js @@ -68,6 +68,8 @@ const SplitWithImage = ({ elementName, cta, socialButton, + imgBoxShadow, + py, }) => { var buttonSize = useBreakpointValue({ base: { single: "sm", double: "xs" }, @@ -94,10 +96,20 @@ const SplitWithImage = ({ return () => observer.unobserve(current); }, []); + const themeColor = useColorModeValue( + `${colorScheme}.50`, + `${colorScheme}.900` + ); + + const bgThemeColor = useColorModeValue( + `${colorScheme}.900`, + `${colorScheme}.50` + ); + return ( @@ -109,31 +121,34 @@ const SplitWithImage = ({ alt={"feature image"} src={imgURL} objectFit={"contain"} + boxShadow={imgBoxShadow ?? "inherit"} /> )} - - - + {badge && ( + - {badge} - - - {title} - + + {badge} + + + )} + {title} + {body} - + {cta && ( + + )} {socialButton && ( } > git clone moonstream @@ -194,12 +211,14 @@ const SplitWithImage = ({ {(!mirror || ui.isMobileView) && ( - + {"feature )} diff --git a/frontend/src/core/hooks/hookCommon.js b/frontend/src/core/hooks/hookCommon.js index a3aeef16..72f85a30 100644 --- a/frontend/src/core/hooks/hookCommon.js +++ b/frontend/src/core/hooks/hookCommon.js @@ -11,3 +11,4 @@ export const queryCacheProps = { return status === 404 || status === 403 ? false : true; }, }; +export default queryCacheProps; diff --git a/frontend/src/layouts/RootLayout.js b/frontend/src/layouts/RootLayout.js index cd66abe9..d7afd5c9 100644 --- a/frontend/src/layouts/RootLayout.js +++ b/frontend/src/layouts/RootLayout.js @@ -7,7 +7,7 @@ const Navbar = React.lazy(() => import("../components/Navbar")); const RootLayout = (props) => { const ui = useContext(UIContext); - const [showBanner, setShowBanner] = useState(true); + const [showBanner, setShowBanner] = useState(false); return (