From 470621733221226e76494f748e72a666e389ef4f Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Mon, 2 Aug 2021 19:42:31 +0800 Subject: [PATCH] cleanup and landing page w background img --- frontend/next.config.js | 6 +- frontend/package.json | 5 +- frontend/pages/403.js | 3 +- frontend/pages/404.js | 3 +- frontend/pages/_document.js | 4 +- frontend/pages/api/hello.ts | 13 - frontend/pages/index.js | 482 ++++++++------- frontend/pages/pricing.js | 249 -------- frontend/pages/tos/index.js | 574 ++++++++++++++++++ frontend/src/components/AccountIconButton.js | 6 +- frontend/src/components/AccountNavbar.js | 3 +- frontend/src/components/AppNavbar.js | 2 - frontend/src/components/ChangePassword.js | 3 +- frontend/src/components/ConnectedButtons.js | 19 +- frontend/src/components/ContentBlock.js | 67 -- frontend/src/components/CopyButton.js | 4 +- frontend/src/components/CopyEntryButton.js | 95 --- frontend/src/components/EntriesNavigation.js | 10 +- frontend/src/components/Footer.js | 2 +- frontend/src/components/ForgotPassword.js | 4 +- frontend/src/components/FourOFour.js | 3 +- frontend/src/components/FourOThree.js | 3 +- frontend/src/components/HeadLinks.js | 3 +- frontend/src/components/HeadSEO.js | 3 +- frontend/src/components/HubspotForm.js | 45 ++ frontend/src/components/IconButton.js | 20 - frontend/src/components/LandingNavbar.js | 24 +- frontend/src/components/Modal/index.js | 2 +- frontend/src/components/Navbar.js | 28 +- frontend/src/components/NewSubscription.js | 2 +- frontend/src/components/PasswordInput.js | 2 +- frontend/src/components/RadioCard.js | 2 +- frontend/src/components/Scrollable.js | 38 +- frontend/src/components/SearchBar.js | 288 --------- frontend/src/components/SignIn.js | 4 +- frontend/src/components/SignUp.js | 2 +- frontend/src/components/SplitWithImage.js | 36 +- frontend/src/components/TagsList.js | 46 -- frontend/src/components/TokenList.js | 103 ---- frontend/src/components/TokenRequest.js | 109 ---- frontend/src/components/TrustedBadge.js | 36 -- frontend/src/core/hooks/useAnalytics.js | 5 +- frontend/src/core/hooks/useGroup.js | 6 +- frontend/src/core/hooks/useGroups.js | 10 +- .../src/core/hooks/useJournalPermissions.js | 4 - frontend/src/core/hooks/useLogin.js | 6 +- frontend/src/core/hooks/useLogout.js | 2 +- frontend/src/core/hooks/useSignUp.js | 2 +- frontend/src/core/hooks/useStream.js | 10 +- frontend/src/core/hooks/useSubscriptions.js | 41 +- frontend/src/core/hooks/useToast.js | 4 +- .../providers/AnalyticsProvider/constants.js | 3 +- .../core/providers/AnalyticsProvider/index.js | 31 + frontend/src/core/services/auth.service.js | 33 +- frontend/src/core/services/humbug.service.js | 25 +- frontend/src/core/services/journal.service.js | 112 ++-- frontend/src/core/utils/mockupRequests.js | 4 +- frontend/src/layouts/AccountLayout.js | 2 +- frontend/src/layouts/AppLayout.js | 1 - frontend/src/layouts/LandingLayout.js | 4 +- frontend/src/layouts/RootLayout.js | 1 - 61 files changed, 1148 insertions(+), 1511 deletions(-) delete mode 100644 frontend/pages/api/hello.ts delete mode 100644 frontend/pages/pricing.js create mode 100644 frontend/pages/tos/index.js delete mode 100644 frontend/src/components/ContentBlock.js delete mode 100644 frontend/src/components/CopyEntryButton.js create mode 100644 frontend/src/components/HubspotForm.js delete mode 100644 frontend/src/components/IconButton.js delete mode 100644 frontend/src/components/SearchBar.js delete mode 100644 frontend/src/components/TagsList.js delete mode 100644 frontend/src/components/TokenList.js delete mode 100644 frontend/src/components/TokenRequest.js delete mode 100644 frontend/src/components/TrustedBadge.js diff --git a/frontend/next.config.js b/frontend/next.config.js index dd157ad0..a3c32211 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -2,7 +2,5 @@ module.exports = { reactStrictMode: true, target: "serverless", trailingSlash: true, - presets: [ - require.resolve('next/babel') - ] -}; \ No newline at end of file + presets: [require.resolve("next/babel")], +}; diff --git a/frontend/package.json b/frontend/package.json index db9ed226..30cbfa29 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,9 +4,10 @@ "private": true, "scripts": { "dev": "next dev", - "build": "next build", + "build": "next build && next export -o build", "start": "next start", - "lint": "next lint" + "lint": "eslint ./ --ext js,jsx,ts,tsx --fix", + "pretty": "prettier --write \"./**/*.{js,jsx,json}\"" }, "dependencies": { "@chakra-ui/icons": "^1.0.14", diff --git a/frontend/pages/403.js b/frontend/pages/403.js index f5263be5..735ea290 100644 --- a/frontend/pages/403.js +++ b/frontend/pages/403.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import FourOThree from "../src/components/FourOThree"; const Page403 = () => { diff --git a/frontend/pages/404.js b/frontend/pages/404.js index bd902deb..6fc4a0ae 100644 --- a/frontend/pages/404.js +++ b/frontend/pages/404.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import FourOFour from "../src/components/FourOFour"; const Page404 = () => { diff --git a/frontend/pages/_document.js b/frontend/pages/_document.js index 004ffbef..2eeaf257 100644 --- a/frontend/pages/_document.js +++ b/frontend/pages/_document.js @@ -1,6 +1,4 @@ - -import { jsx } from "@emotion/react"; - +import React from "react"; import Document, { Html, Head, Main, NextScript } from "next/document"; export default class MyDocument extends Document { diff --git a/frontend/pages/api/hello.ts b/frontend/pages/api/hello.ts deleted file mode 100644 index f8bcc7e5..00000000 --- a/frontend/pages/api/hello.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next' - -type Data = { - name: string -} - -export default function handler( - req: NextApiRequest, - res: NextApiResponse -) { - res.status(200).json({ name: 'John Doe' }) -} diff --git a/frontend/pages/index.js b/frontend/pages/index.js index b50ac6e7..2bf4b23a 100644 --- a/frontend/pages/index.js +++ b/frontend/pages/index.js @@ -1,116 +1,118 @@ -import React, { useState, useEffect, Suspense, useContext } from "react"; +import React, { useEffect, Suspense, useContext, useState } from "react"; import { Flex, Heading, - Text, Box, - Image, + Image as ChakraImage, Button, - useBreakpointValue, Center, Fade, chakra, Stack, + Link, + SimpleGrid, + useMediaQuery, } from "@chakra-ui/react"; import { Grid, GridItem } from "@chakra-ui/react"; import { useUser, useAnalytics, useModals, useRouter } from "../src/core/hooks"; import { getLayout } from "../src/layouts"; import SplitWithImage from "../src/components/SplitWithImage"; -import { - IoAnalyticsSharp, - IoLogoBitcoin, - IoSearchSharp, -} from "react-icons/io5"; import ConnectedButtons from "../src/components/ConnectedButtons"; import UIContext from "../src/core/providers/UIProvider/context"; +import { MIXPANEL_PROPS } from "../src/core/providers/AnalyticsProvider/constants"; +import { FaFileContract } from "react-icons/fa"; +import { RiDashboardFill } from "react-icons/ri"; +import { + GiMeshBall, + GiLogicGateXor, + GiSuspicious, + GiHook, +} from "react-icons/gi"; +import { AiFillApi } from "react-icons/ai"; +import { BiTransfer } from "react-icons/bi"; +import { IoTelescopeSharp } from "react-icons/io5"; const HEADING_PROPS = { fontWeight: "700", fontSize: ["4xl", "5xl", "4xl", "5xl", "6xl", "7xl"], }; - -const TRIPLE_PICS_PROPS = { - fontSize: ["1xl", "2xl", "2xl", "2xl", "3xl", "3xl"], - textAlign: "center", - fontWeight: "600", - py: 4, -}; - -const TRIPLE_PICS_TEXT = { - fontSize: ["lg", "xl", "xl", "xl", "2xl", "3xl"], - textAlign: "center", - fontWeight: "400", - mb: ["2rem", "2rem", "0", null, "0"], -}; - -const CARD_CONTAINER = { - className: "CardContainer", - w: "100%", - mx: [0, 0, "2rem", null, "4rem"], - - alignSelf: ["center", null, "flex-start"], -}; - -const IMAGE_CONTAINER = { - className: "ImageContainer", - // objectFit: "contain", - h: ["10rem", null], - // h: ["10rem", "14rem", "14rem", "15rem", "18rem", "20rem"], - justifyContent: "center", -}; - const AWS_PATH = "https://s3.amazonaws.com/static.simiotics.com/moonstream/assets"; const assets = { - background: `https://s3.amazonaws.com/static.simiotics.com/landing/landing-background-2.png`, - aviator: `https://s3.amazonaws.com/static.simiotics.com/landing/aviator-2.svg`, - icon1: `${AWS_PATH}/Image+1.png`, - icon2: `${AWS_PATH}/Image+2.png`, - icon3: `${AWS_PATH}/Image+3.png`, - icon4: `${AWS_PATH}/Image+4.png`, - icon5: `${AWS_PATH}/Image+5.png`, - icon6: `${AWS_PATH}/Image+6.png`, + background720: `${AWS_PATH}/background720.png`, + background1920: `${AWS_PATH}/background720.png`, + background2880: `${AWS_PATH}/background720.png`, + background3840: `${AWS_PATH}/background720.png`, + minedTransactions: `${AWS_PATH}/Ethereum+mined+transactions.png`, + pendingTransactions: `${AWS_PATH}/Ethereum+pending+transactions.png`, + priceInformation: `${AWS_PATH}/Price+information.png`, + socialMediaPosts: `${AWS_PATH}/Social+media+posts.png`, + algorithmicFunds: `${AWS_PATH}/algorithmic+funds.png`, + cryptoTraders: `${AWS_PATH}/crypto+traders.png`, + smartDevelopers: `${AWS_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); + const [backgroundLoaded2880, setBackgroundLoaded2880] = useState(false); + const [backgroundLoaded3840, setBackgroundLoaded3840] = useState(false); + const router = useRouter(); - const buttonSize = useBreakpointValue({ - base: "md", - sm: "md", - md: "md", - lg: "lg", - xl: "xl", - "2xl": "xl", - }); - - const ButtonRadius = "2xl"; - const buttonWidth = ["100%", "100%", "40%", "45%", "45%", "45%"]; - const buttonMinWidth = "10rem"; const { isInit } = useUser(); - const { withTracking, MIXPANEL_EVENTS } = useAnalytics(); - + const { MIXPANEL_EVENTS, track } = useAnalytics(); const { toggleModal } = useModals(); - const [scrollDepth, setScrollDepth] = useState(0); + const [ + isLargerThan720px, + isLargerThan1920px, + isLargerThan2880px, + isLargerThan3840px, + ] = useMediaQuery([ + "(min-width: 720px)", + "(min-width: 1920px)", + "(min-width: 2880px)", + "(min-width: 3840px)", + ]); - const getScrollPrecent = ({ currentTarget }) => { - const scroll_level = - (100 * (currentTarget.scrollTop + currentTarget.clientHeight)) / - currentTarget.scrollHeight; - return scroll_level; - }; + useEffect(() => { + assets["background720"] = `${AWS_PATH}/background720.png`; + assets["background2880"] = `${AWS_PATH}/background2880.png`; + assets["background3840"] = `${AWS_PATH}/background3840.png`; + }, []); - const handleScroll = (e) => { - const currentScroll = Math.ceil(getScrollPrecent(e) / 10); - - if (currentScroll > scrollDepth) { - withTracking( - setScrollDepth(currentScroll), - MIXPANEL_EVENTS.HOMEPAGE_SCROLL_DEPTH, - scrollDepth - ); + useEffect(() => { + console.log( + "isLargerChanged, ", + isLargerThan720px, + isLargerThan1920px, + isLargerThan2880px, + isLargerThan3840px, + backgroundLoaded720, + backgroundLoaded1920, + backgroundLoaded2880, + backgroundLoaded3840 + ); + if (isLargerThan3840px && backgroundLoaded3840) { + setBackground("background3840"); + } else if (isLargerThan2880px && backgroundLoaded2880) { + setBackground("background2880"); + } else if (isLargerThan1920px && backgroundLoaded1920) { + setBackground("background1920"); + } else { + setBackground("background720"); } - }; + }, [ + isLargerThan720px, + isLargerThan1920px, + isLargerThan2880px, + isLargerThan3840px, + backgroundLoaded720, + backgroundLoaded1920, + backgroundLoaded2880, + backgroundLoaded3840, + ]); useEffect(() => { if ( @@ -118,19 +120,53 @@ const Homepage = () => { router.nextRouter.asPath.slice(0, 2) !== "/?" && router.nextRouter.asPath.slice(0, 2) !== "/#" ) { + console.log("replacing!"); router.replace(router.nextRouter.asPath, undefined, { shallow: true, }); } }, [isInit, router]); + useEffect(() => { + console.log("rerender check"); + const imageLoader720 = new Image(); + imageLoader720.src = `${AWS_PATH}/background720.png`; + imageLoader720.onload = () => { + setBackgroundLoaded720(true); + }; + + const imageLoader1920 = new Image(); + imageLoader1920.src = `${AWS_PATH}/background1920.png`; + imageLoader1920.onload = () => { + setBackgroundLoaded1920(true); + }; + + const imageLoader2880 = new Image(); + imageLoader2880.src = `${AWS_PATH}/background2880.png`; + imageLoader2880.onload = () => { + setBackgroundLoaded2880(true); + }; + + const imageLoader3840 = new Image(); + imageLoader3840.src = `${AWS_PATH}/background3840.png`; + imageLoader3840.onload = () => { + setBackgroundLoaded3840(true); + }; + }, []); + + console.log("backgroundLoaded", background); + return ( handleScroll(e)} sx={{ scrollBehavior: "smooth" }} + // bgColor="primary.1900" + // backgroundImage={`url(${assets["background"]})`} + // backgroundImage={`url(https://cdn3.vectorstock.com/i/1000x1000/75/62/moon-landscape-game-background-vector-24977562.jpg)`} + bgSize="cover" > { position="relative" w="100%" overflow="initial" + pt={0} > - - - + + + { textAlign="center" alignItems="center" spacing={6} - maxW="1220px" + maxW="1620px" px="7%" + h="100%" + pt={["10vh", null, "30vh"]} > {/* */} All the crypto data you care about in a single stream @@ -177,6 +236,7 @@ const Homepage = () => { { pool to Elon Musk’s latest tweets. { colSpan="12" pt={["20px", "20px", "100px", null, "120px"]} pb={["20px", "56px", null, "184px"]} - bgSize="cover" - bgImage={`url(${assets["background"]})`} + minH="100vh" + // bgSize="cover" + // bgImage={`url(${assets["background"]})`} > { Data you can add to your stream: - - - - privacy is our prioriy - - + + + Ethereum mined transactions - - - - - live metrics - - + + + + Ethereum pending transactions - - - - - live metrics - - - Centralized exchanges - - - - - - - we make it simple for user - - Social media posts - - - - {/* - We currently support Python, Javascript and Go! -
- Want us to support other programming languages?{" "} - -
*/} -
- + + + + Centralized exchanges + + + + Social media posts + + +
+ + Moonstream is ment for you if + +
{ button1={{ label: "Crypto trader", link: "/#cryptoTrader", - onClick: null, + onClick: () => { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to CryptoTrader`, + }); + }, }} button2={{ label: "Algorithmic Fund", link: "/#algoFund", - onClick: null, + onClick: () => { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to AlgoFund`, + }); + }, }} button3={{ label: "Developer", link: "/#smartDeveloper", - onClick: null, + onClick: () => { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to Developer`, + }); + }, }} /> @@ -336,8 +378,15 @@ const Homepage = () => { minH={ui.isMobileView ? "100vh" : null} > { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Early access CTA: Crypto trader`, + }); + toggleModal("hubspot-trader"); + }, + }} elementName={"element1"} colorScheme="suggested" badge={`For crypto traders`} @@ -346,25 +395,25 @@ const Homepage = () => { bullets={[ { text: `Subscribe to the defi contracts you care about`, - icon: IoLogoBitcoin, + icon: FaFileContract, color: "suggested.50", bgColor: "suggested.900", }, { text: `Make sense of how others are calling these contracts using Moonstream dashboards. `, - icon: IoAnalyticsSharp, + icon: RiDashboardFill, color: "suggested.50", bgColor: "suggested.900", }, { text: `Get data directly from the transaction pool through our global network of Ethereum nodes`, - icon: IoSearchSharp, + icon: GiMeshBall, color: "suggested.50", bgColor: "suggested.900", }, ]} - imgURL={assets["icon2"]} + imgURL={assets["cryptoTraders"]} />
{ minH={ui.isMobileView ? "100vh" : null} > { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Early access CTA: Algo fund`, + }); + toggleModal("hubspot-fund"); + }, + }} elementName={"element2"} mirror={true} colorScheme="secondary" badge={`For algorithmic funds`} - // title={`Get API access to your stream`} - // body={`Specify actions. - // Something happens on blockchain and we automatically execute for them. - // Algorithmic trading on the blockchain`} bullets={[ { text: `Get API access to your stream`, - icon: IoLogoBitcoin, + icon: AiFillApi, color: "secondary.50", bgColor: "secondary.900", }, { text: `Set conditions that trigger predefined actions`, - icon: IoAnalyticsSharp, + icon: GiLogicGateXor, color: "secondary.50", bgColor: "secondary.900", }, { text: `Execute transactions directly on Moonstream nodes`, - icon: IoSearchSharp, + icon: BiTransfer, color: "secondary.50", bgColor: "secondary.900", }, ]} - imgURL={assets["icon3"]} + imgURL={assets["algorithmicFunds"]} /> { minH={ui.isMobileView ? "100vh" : null} > { + track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, { + [`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Early access CTA: developer`, + }); + toggleModal("hubspot-developer"); + }, + }} elementName={"element3"} colorScheme="primary" badge={`For smart contract developers`} - // title={`Learn how people use your smart contracts`} - // body={` - // Connect decentralized application with centralized application - // Creat Blockchain based web hooks and get full visibility of your smart contracts`} bullets={[ { text: `See how people use your smart contracts`, - icon: IoLogoBitcoin, + icon: IoTelescopeSharp, color: "primary.50", bgColor: "primary.900", }, { text: `Set up alerts on suspicious activity`, - icon: IoAnalyticsSharp, + icon: GiSuspicious, color: "primary.50", bgColor: "primary.900", }, { text: `Register webhooks to connect your off-chain infrastructure`, - icon: IoSearchSharp, + icon: GiHook, color: "primary.50", bgColor: "primary.900", }, ]} - imgURL={assets["icon6"]} + imgURL={assets["smartDevelopers"]} /> { >
- {/* */}
); diff --git a/frontend/pages/pricing.js b/frontend/pages/pricing.js deleted file mode 100644 index 0c87c052..00000000 --- a/frontend/pages/pricing.js +++ /dev/null @@ -1,249 +0,0 @@ -import React from "react"; -import { - Box, - Stack, - HStack, - Heading, - Text, - VStack, - useColorModeValue, - List, - ListItem, - ListIcon, - Button, -} from "@chakra-ui/react"; -import { FaCheckCircle } from "react-icons/fa"; -import { getLayout } from "../src/layouts"; - -function PriceWrapper({ children }) { - return ( - - {children} - - ); -} - -const Pricing = (props) => { - return ( - - - - Plans that fit your need - - - Start with 14-day free trial. No credit card needed. Cancel at - anytime. - - - - - - - Hobby - - - - $ - - - 79 - - - /month - - - - - - - - unlimited build minutes - - - - Lorem, ipsum dolor. - - - - 5TB Lorem, ipsum dolor. - - - - - - - - - - - - - Most Popular - - - - - Growth - - - - $ - - - 149 - - - /month - - - - - - - - unlimited build minutes - - - - Lorem, ipsum dolor. - - - - 5TB Lorem, ipsum dolor. - - - - 5TB Lorem, ipsum dolor. - - - - 5TB Lorem, ipsum dolor. - - - - - - - - - - - - Scale - - - - $ - - - 349 - - - /month - - - - - - - - unlimited build minutes - - - - Lorem, ipsum dolor. - - - - 5TB Lorem, ipsum dolor. - - - - - - - - - - ); -}; - -export async function getStaticProps() { - const metaTags = { - title: "Bugout: Measure the success of your dev tool", - description: - "Get usage metrics and crash reports. Improve your users' experience", - keywords: - "bugout, bugout-dev, bugout.dev, usage-metrics, analytics, dev-tool ,knowledge, docs, journal, entry, find-anything", - url: "https://bugout.dev", - image: - "https://s3.amazonaws.com/static.simiotics.com/landing/aviator-2.svg", - }; - -// const assetPreload = Object.keys(assets).map((key) => { -// return { -// rel: "preload", -// href: assets[key], -// as: "image", -// }; -// }); -// const preconnects = [ -// { rel: "preconnect", href: "https://s3.amazonaws.com" }, -// { rel: "preconnect", href: "https://assets.calendly.com/" }, -// ]; - -// const preloads = assetPreload.concat(preconnects); - - return { - props: { metaTags }, - }; -} - -Pricing.getLayout = getLayout; - -export default Pricing; diff --git a/frontend/pages/tos/index.js b/frontend/pages/tos/index.js new file mode 100644 index 00000000..ca04a67e --- /dev/null +++ b/frontend/pages/tos/index.js @@ -0,0 +1,574 @@ +import React from "react"; +import { Box, Heading, ListItem, Text, Link } from "@chakra-ui/react"; +import { UnorderedList, OrderedList } from "@chakra-ui/react"; +import { DEFAULT_METATAGS } from "../../src/components/constants"; + +export async function getStaticProps() { + return { + props: { metaTags: { ...DEFAULT_METATAGS } }, + }; +} + +const TermsOfService = () => ( + + + + Moonstream.to Terms of Service + + + Welcome to Bugout! Please read these Terms of Service before accessing + or using Bugout. + + Definitions + + + + {`An "Account" represents your legal relationship with Simiotics, Inc. + A “User Account” represents an individual User’s authorization to + log in to and use the Service and serves as a User’s identity on + Bugout. “Groups” represent teams of users. A User Account can be a + member of any number of Groups.`} + + + {` The “Agreement” refers, collectively, to all the terms, conditions, + notices contained or referenced in this document (the “Terms of + Service” or the "Terms") and all other operating rules, policies + (including the Bugout.dev Privacy Statement) and procedures that we + may publish from time to time on the Website.`} + + + {` “Content” refers to content featured or displayed through the + Website, including without limitation code, text, data, articles, + images, photographs, graphics, software, applications, packages, + designs, features, and other materials that are available on the + Website or otherwise available through the Service. "Content" also + includes Services. “User-Generated Content” is Content, written or + otherwise, created or uploaded by our Users. "Your Content" is + Content that you create or own.`} + + + “Bugout,” “Bugout.dev”, “Simiotics”, “We,” and “Us” refer to + Simiotics, Inc., as well as our affiliates, directors, subsidiaries, + contractors, licensors, officers, agents, and employees. + + + The “Service” refers to the applications, software, products, and + services provided by Simiotics. + + + “The User,” “You,” and “Your” refer to the individual person, + company, or organization that has visited or is using the Website or + Service; that accesses or uses any part of the Account; or that + directs the use of the Account in the performance of its functions. + A User must be at least 13 years of age. + + + The “Website” refers to Bugout’s website located at bugout.dev, and + all content, services, and products provided by Bugout at or through + the Website. It also refers to subdomains of bugout.dev, such as + blog.bugout.dev. Occasionally, websites owned by Bugout may provide + different or additional terms of service. If those additional terms + conflict with this Agreement, the more specific terms apply to the + relevant page or service. + + + + Account Terms + + Account Controls + + + Subject to these Terms, you retain ultimate administrative control over + your User Account and the Content within it. + + + {` The "owner" of a Group that was created under these Terms has ultimate + administrative control over that Group and the Content within it. Within + the Service, an owner can manage User access to the Group’s data and + projects. A Group may have multiple owners, but there must be at least + one User Account designated as an owner of a Group. If you are the owner + of an Group under these Terms, we consider you responsible for the + actions that are performed on or through that Group.`} + + + Required Information + + + You must provide a valid email address in order to complete the signup + process. Any other information requested, such as your real name, is + optional, unless you are accepting these terms on behalf of a legal + entity (in which case we need more information about the legal entity) + or if you opt for a paid Account, in which case additional information + will be necessary for billing purposes. + + + Account Requirements + + + {`We have a few simple rules for User Accounts on Bugout's Service. You + must be a human to create an Account. Accounts registered by "bots" or + other automated methods are not permitted.`} + + + {`We do permit machine accounts. A machine account is an Account set up by + an individual human who accepts the Terms on behalf of the Account, + provides a valid email address, and is responsible for its actions. A + machine account is used exclusively for performing automated tasks. + Multiple users may direct the actions of a machine account, but the + owner of the Account is ultimately responsible for the machine's + actions. You may maintain no more than one free machine account in + addition to your free User Account.`} + + + {`One person or legal entity may maintain no more than one free Account + (if you choose to control a machine account as well, that's fine, but it + can only be used for running a machine).`} + + + You must be age 13 or older. If we learn of any User under the age of + 13, we will terminate that User’s Account immediately. If you are a + resident of a country outside the United States, your country’s minimum + age may be older; in such a case, you are responsible for complying with + your country’s laws. + + + Your login may only be used by one person — i.e., a single login may not + be shared by multiple people. + + + A paid Group may only provide access to as many User Accounts as your + subscription allows. + + + User Account Security + + + You are responsible for keeping your Account secure while you use our + Service. The content of your Account and its security are up to you. You + are responsible for all content posted and activity that occurs under + your Account. You are responsible for maintaining the security of your + Account and password. Bugout cannot and will not be liable for any loss + or damage from your failure to comply with this security obligation. + + + You will promptly notify Bugout if you become aware of any unauthorized + use of, or access to, our Service through your Account, including any + unauthorized use of your password or Account. + + Acceptable Use + + Your use of the Website and Service must not violate any applicable + laws, including copyright or trademark laws, export control or sanctions + laws, or other laws in your jurisdiction. You are responsible for making + sure that your use of the Service is in compliance with laws and any + applicable regulations. + + User-Generated Content + + Responsibility for User-Generated Content + + + You may create or upload User-Generated Content while using the Service. + You are solely responsible for the content of, and for any harm + resulting from, any User-Generated Content that you post, upload, link + to or otherwise make available via the Service, regardless of the form + of that Content. We are not responsible for any public display or misuse + of your User-Generated Content. + + + Bugout May Remove Content + + + We have the right to refuse or remove any User-Generated Content that, + in our sole discretion, violates any laws or Bugout terms or policies. + + + Ownership of Content, Right to Post, and License Grants + + + {`You retain ownership of and responsibility for Your Content. If you're + posting anything you did not create yourself or do not own the rights + to, you agree that you are responsible for any Content you post; that + you will only submit Content that you have the right to post; and that + you will fully comply with any third party licenses relating to Content + you post.`} + + + Because you retain ownership of and responsibility for Your Content, we + need you to grant us — and other Bugout Users — certain legal + permissions. These license grants apply to Your Content. If you upload + Content that already comes with a license granting Bugout the + permissions we need to run our Service, no additional license is + required. You understand that you will not receive any payment for any + of these granted rights. The licenses you grant to us will end when you + remove Your Content from our servers, unless other Users have cloned it. + + + + License Grant to Us + + + + We need the legal right to do things like host Your Content, publish it, + and share it. You grant us and our legal successors the right to store, + archive, parse, and display Your Content, and make incidental copies, as + necessary to provide the Service, including improving the Service over + time. This license includes the right to do things like copy it to our + database and make backups; show it to you and other users; parse it into + a search index or otherwise analyze it on our servers; share it with + other users; and perform it, in case Your Content is something like + music or video. This license does not grant Bugout the right to sell + Your Content. It also does not grant Bugout the right to otherwise + distribute or use Your Content outside of our provision of the Service. + + + License Grant to Other Users + + + + {`Any User-Generated Content you post publicly may be viewed by others. By + setting your content to be viewed publicly, you agree to allow others to + view and "clone" your content (this means that others may make their own + copies of Your Content). If you set your Content to be viewed publicly, + you grant each User of Bugout a nonexclusive, worldwide license to use, + display, and perform Your Content through the Bugout Service and to + reproduce Your Content solely on Bugout as permitted through Bugout's + functionality (for example, through cloning). If you are uploading + Content you did not create or own, you are responsible for ensuring that + the Content you upload is licensed under terms that grant these + permissions to other Bugout Users.`} + + + Moral Rights + + + + You retain all moral rights to Your Content that you upload, publish, or + submit to any part of the Service, including the rights of integrity and + attribution. However, you waive these rights and agree not to assert + them against us, to enable us to reasonably exercise the rights granted + above, but not otherwise. + + + To the extent this agreement is not enforceable by applicable law, you + grant Bugout the rights we need to use Your Content without attribution + and to make reasonable adaptations of Your Content as necessary to + render the Website and provide the Service. + + Private Content + + Control of Private Content + + + Some Accounts may have private content -- for example, groups or + journals -- which allow the User to control access to Content. + + + Confidentiality of Private Content + + + Bugout considers private content to be confidential to you. Bugout will + protect the contents of private repositories from unauthorized use, + access, or disclosure in the same manner that we would use to protect + our own confidential information of a similar nature and in no event + with less than a reasonable degree of care. + + + Access + + + Bugout personnel may only access the content of your private content in + the situations described in our{" "} + + Privacy Policy + + . + + + Additionally, we may be compelled by law to disclose your private + content. + + Intellectual Property Notice + + {`Bugout's Rights to Content`} + + + Bugout and our licensors, vendors, agents, and/or our content providers + retain ownership of all intellectual property rights of any kind related + to the Website and Service. We reserve all rights that are not expressly + granted to you under this Agreement or by law. + + API Terms + + {`Abuse or excessively frequent requests to Bugout via the API may result + in the temporary or permanent suspension of your Account's access to the + API. Bugout, in our sole discretion, will determine abuse or excessive + usage of the API. We will make a reasonable attempt to warn you via + email prior to suspension.`} + + + {`You may not share API tokens to exceed Bugout's rate limitations.`} + + + {`You may not use the API to download data or Content from Bugout for + spamming purposes, including for the purposes of selling Bugout users' + personal information, such as to recruiters, headhunters, and job + boards.`} + + + All use of the Bugout API is subject to these Terms of Service and the + Bugout{" "} + + Privacy Policy + + . + + + {`Bugout may offer subscription-based access to our API for those Users + who require high- throughput access or access that would result in + resale of Bugout's Service.`} + + Payment + + Pricing + + + If you agree to a subscription price, that will remain your price for + the duration of the payment term; however, prices are subject to change + at the end of a payment term. + + + Authorization + + + By agreeing to these Terms, you are giving us permission to charge your + on-file credit card, PayPal account, or other approved methods of + payment for fees that you authorize for Bugout. + + + Responsibility for Payment + + + You are responsible for all fees, including taxes, associated with your + use of the Service. By using the Service, you agree to pay Bugout any + charge incurred in connection with your use of the Service. If you + dispute the matter, contact us. You are responsible for providing us + with a valid means of payment for paid Accounts. Free Accounts are not + required to provide payment information. + + Cancellation and Termination + + Account Cancellation + + + It is your responsibility to properly cancel your Account with Bugout. + You can cancel your Account at any time by contacting us by email + (neeraj@simiotics.com). + + + Upon Cancellation + + + We will retain and use your information as necessary to comply with our + legal obligations, resolve disputes, and enforce our agreements, but + barring legal requirements, we will delete your full profile and the + Content of your repositories within 90 days of cancellation or + termination (though some information may remain in encrypted backups). + This information can not be recovered once your Account is cancelled. + + + We will not delete Content that you have contributed to Groups or that + other Users have cloned. + + + Upon request, we will make a reasonable effort to provide an Account + owner with a copy of your lawful, non-infringing Account contents after + Account cancellation, termination, or downgrade. + + + You must make this request within 90 days of cancellation, termination, + or downgrade. + + + Bugout May Terminate + + + Bugout has the right to suspend or terminate your access to all or any + part of the Website at any time, with or without cause, with or without + notice, effective immediately. + + + Bugout reserves the right to refuse service to anyone for any reason at + any time. + + + Survival + + + All provisions of this Agreement which, by their nature, should survive + termination will survive termination — including, without limitation: + ownership provisions, warranty disclaimers, indemnity, and limitations + of liability. + + Communications with Bugout + + For contractual purposes, you (1) consent to receive communications from + us in an electronic form via the email address you have submitted or via + the Service; and (2) agree that all Terms of Service, agreements, + notices, disclosures, and other communications that we provide to you + electronically satisfy any legal requirement that those communications + would satisfy if they were on paper. This section does not affect your + non-waivable rights. + + Disclaimer of Warranties + + Bugout provides the Website and the Service “as is” and “as available,” + without warranty of any kind. Without limiting this, we expressly + disclaim all warranties, whether express, implied or statutory, + regarding the Website and the Service including without limitation any + warranty of merchantability, fitness for a particular purpose, title, + security, accuracy and non-infringement. + + + Bugout does not warrant that the Service will meet your requirements; + that the Service will be uninterrupted, timely, secure, or error-free; + that the information provided through the Service is accurate, reliable + or correct; that any defects or errors will be corrected; that the + Service will be available at any particular time or location; or that + the Service is free of viruses or other harmful components. You assume + full responsibility and risk of loss resulting from your downloading + and/or use of files, information, content or other material obtained + from the Service. + + Limitation of Liability + + You understand and agree that we will not be liable to you or any third + party for any loss of profits, use, goodwill, or data, or for any + incidental, indirect, special, consequential or exemplary damages, + however arising, that result from the use, disclosure, or display of + your: + + User-Generated Content; + your use or inability to use the Service; + + any modification, price change, suspension or discontinuance of the + Service; + + + the Service generally or the software or systems that make the + Service available; + + + unauthorized access to or alterations of your transmissions or data; + + + statements or conduct of any third party on the Service; + + + any other user interactions that you input or receive through your + use of the Service; + + or any other matter relating to the Service. + + + + Our liability is limited whether or not we have been informed of the + possibility of such damages, and even if a remedy set forth in this + Agreement is found to have failed of its essential purpose. We will have + no liability for any failure or delay due to matters beyond our + reasonable control. + + Release and Indemnification + + If you have a dispute with one or more Users, you agree to release + Bugout from any and all claims, demands and damages (actual and + consequential) of every kind and nature, known and unknown, arising out + of or in any way connected with such disputes. + + + You agree to indemnify us, defend us, and hold us harmless from and + against any and all claims, liabilities, and expenses, including + attorneys’ fees, arising out of your use of the Website and the Service, + including but not limited to your violation of this Agreement, provided + that Bugout (1) promptly gives you written notice of the claim, demand, + suit or proceeding; (2) gives you sole control of the defense and + settlement of the claim, demand, suit or proceeding (provided that you + may not settle any claim, demand, suit or proceeding unless the + settlement unconditionally releases Bugout of all liability); and (3) + provides to you all reasonable assistance, at your expense. + + Changes to These Terms + + {`We reserve the right, at our sole discretion, to amend these Terms of + Service at any time and will update these Terms of Service in the event + of any such amendments. We will notify our Users of material changes to + this Agreement, such as price increases, at least 30 days prior to the + change taking effect by posting a notice on our Website or sending email + to the primary email address specified in your Bugout account. + Customer's continued use of the Service after those 30 days constitutes + agreement to those revisions of this Agreement. For any other + modifications, your continued use of the Website constitutes agreement + to our revisions of these Terms of Service.`} + + Miscellaneous + + Governing Law + + + Except to the extent applicable law provides otherwise, this Agreement + between you and Bugout and any access to or use of the Website or the + Service are governed by the federal laws of the United States of America + and the laws of the State of California, without regard to conflict of + law provisions. You and Bugout agree to submit to the exclusive + jurisdiction and venue of the courts located in the City and County of + San Francisco, California. + + + Non-Assignability + + + Bugout may assign or delegate these Terms of Service and/or the Bugout + + {" "} + Privacy Policy + + , in whole or in part, to any person or entity at any time with or + without your consent. You may not assign or delegate any rights or + obligations under the Terms of Service or Privacy Statement without our + prior written consent, and any unauthorized assignment and delegation by + you is void. + + + Severability, No Waiver, and Survival + + + If any part of this Agreement is held invalid or unenforceable, that + portion of the Agreement will be construed to reflect the parties’ + original intent. The remaining portions will remain in full force and + effect. Any failure on the part of Bugout to enforce any provision of + this Agreement will not be considered a waiver of our right to enforce + such provision. Our rights under this Agreement will survive any + termination of this Agreement. + + + Amendments; Complete Agreement + + + This Agreement may only be modified by a written amendment signed by an + authorized representative of Bugout, or by the posting by Bugout of a + revised version in accordance with Section Q. Changes to These Terms. + These Terms of Service, together with the Bugout{" "} + + Privacy Policy + + , represent the complete and exclusive statement of the agreement + between you and us. This Agreement supersedes any proposal or prior + agreement oral or written, and any other communications between you and + Bugout relating to the subject matter of these terms including any + confidentiality or nondisclosure agreements. + + + +); + +export default TermsOfService; diff --git a/frontend/src/components/AccountIconButton.js b/frontend/src/components/AccountIconButton.js index 4daf4b6f..d89a3694 100644 --- a/frontend/src/components/AccountIconButton.js +++ b/frontend/src/components/AccountIconButton.js @@ -1,6 +1,4 @@ -/** @jsxRuntime classic */ -/** @jsx jsx */ -import { jsx } from "@emotion/react"; +import React from "react"; import RouterLink from "next/link"; import { Menu, @@ -24,7 +22,7 @@ const AccountIconButton = (props) => { {...props} as={IconButton} aria-label="Account menu" - icon={} + icon={} // variant="outline" color="gray.100" /> diff --git a/frontend/src/components/AccountNavbar.js b/frontend/src/components/AccountNavbar.js index 534cd901..4a3fbba0 100644 --- a/frontend/src/components/AccountNavbar.js +++ b/frontend/src/components/AccountNavbar.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import { useUser, useRouter } from "../core/hooks"; import { useEffect, Fragment, useState } from "react"; import { Heading, Center, Spinner, Link, Button } from "@chakra-ui/react"; diff --git a/frontend/src/components/AppNavbar.js b/frontend/src/components/AppNavbar.js index 19346734..e85796f8 100644 --- a/frontend/src/components/AppNavbar.js +++ b/frontend/src/components/AppNavbar.js @@ -21,9 +21,7 @@ import { } from "@chakra-ui/react"; import { HamburgerIcon, - PlusSquareIcon, QuestionOutlineIcon, - BellIcon, ArrowLeftIcon, ArrowRightIcon, } from "@chakra-ui/icons"; diff --git a/frontend/src/components/ChangePassword.js b/frontend/src/components/ChangePassword.js index c90e31a6..0fd3555f 100644 --- a/frontend/src/components/ChangePassword.js +++ b/frontend/src/components/ChangePassword.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import { useChangePassword, useRouter } from "../core/hooks"; diff --git a/frontend/src/components/ConnectedButtons.js b/frontend/src/components/ConnectedButtons.js index 960b59f8..97f7420e 100644 --- a/frontend/src/components/ConnectedButtons.js +++ b/frontend/src/components/ConnectedButtons.js @@ -1,12 +1,5 @@ import React, { useEffect, useRef, useContext } from "react"; -import { - Flex, - Heading, - Button, - Link, - SimpleGrid, - useBreakpointValue, -} from "@chakra-ui/react"; +import { Flex, Heading, Button, Link, SimpleGrid } from "@chakra-ui/react"; import Xarrow, { useXarrow } from "react-xarrows"; import UIContext from "../core/providers/UIProvider/context"; @@ -17,19 +10,11 @@ const ArrowCTA = (props) => { const box2Ref = useRef(null); const box3Ref = useRef(null); - const gridSetup = useBreakpointValue({ - base: "column", - sm: "horizontal", - md: "grid", - lg: "grid", - xl: "grid", - "2xl": "grid", - }); - const updateXarrow = useXarrow(); useEffect(() => { updateXarrow(); + // eslint-disable-next-line }, [ui.isMobileView]); return ( diff --git a/frontend/src/components/ContentBlock.js b/frontend/src/components/ContentBlock.js deleted file mode 100644 index 3fd0f38e..00000000 --- a/frontend/src/components/ContentBlock.js +++ /dev/null @@ -1,67 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { GridItem } from "@chakra-ui/react"; -import { Heading, Text, Image } from "@chakra-ui/react"; -import { Fragment } from "react"; - -const Block = (content) => { - const TitleRef = content.PrevTitle - ? `#${content.PrevTitle}-${content.title}` - : `#${content.title}`; - - var HeaderStyle = content.PrevTitle - ? { as: "h2", fontSize: "3xl" } - : { as: "h1", fontSize: "4xl" }; - - return ( - - {content.title && ( - - - {content.title} - - - )} - {content.body.map((element, idx) => { - if ("text" in element) { - return ( - - {element.text.map((paragraph, idx) => { - return ( - - {paragraph} - - ); - })} - - ); - } - if ("image" in element) { - return ( - - {element.image.annotation} - - ); - } - if ("title" in element) { - element.PrevTitle = content.title; - return ; - } - return ""; - })} - - ); -}; -export default Block; diff --git a/frontend/src/components/CopyButton.js b/frontend/src/components/CopyButton.js index bf18d57c..ea248ba2 100644 --- a/frontend/src/components/CopyButton.js +++ b/frontend/src/components/CopyButton.js @@ -1,6 +1,4 @@ - -import { Fragment } from "react"; -import { jsx } from "@emotion/react"; +import React, { Fragment } from "react"; import { useClipboard, IconButton, diff --git a/frontend/src/components/CopyEntryButton.js b/frontend/src/components/CopyEntryButton.js deleted file mode 100644 index 275db74f..00000000 --- a/frontend/src/components/CopyEntryButton.js +++ /dev/null @@ -1,95 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { - Button, - Menu, - MenuButton, - MenuList, - MenuItem, - MenuGroup, - MenuDivider, -} from "@chakra-ui/react"; -import { - useJournalEntry, - useJournals, - useRouter, - useToast, -} from "../core/hooks"; -import { EntryService } from "../core/services"; -import { useQueryCache } from "react-query"; - -const CopyEntryButton = ({ id, journalId }) => { - const router = useRouter(); - const cache = useQueryCache(); - const { appScope } = router.params; - const { data: entryToCopy, isLoading: sourceIsLoading } = useJournalEntry( - journalId, - id, - appScope - ); - const toast = useToast(); - const { journalsCache } = useJournals(); - const copyEntry = async (targetJournalId) => { - try { - const newEntry = { ...entryToCopy }; - newEntry.title = "Copy of " + newEntry.title; - await EntryService.create(targetJournalId)(newEntry).then((response) => { - journalsCache.refetch(); - setTimeout( - () => cache.refetchQueries(["journal-entries", { journalId }]), - 500 - ); - if (response.status === 200) { - toast("Copied!", "success"); - } - }); - } catch (e) { - console.error( - "Error copying entry. Please email engineering@bugout.dev if you encounter this issue.", - e - ); - } - }; - - if (journalsCache.isLoading || sourceIsLoading) return ""; - - return ( - - - Copy - - - - copyEntry(journalId)}> - { - journalsCache?.data?.data?.journals?.filter( - (journal) => journal.id === journalId - )[0]?.name - } - - - {journalsCache?.data?.data?.journals?.map((journal) => { - if (journal.id === journalId) return ""; - return ( - copyEntry(journal.id)} - > - {journal.name} - - ); - })} - - - - ); -}; - -export default CopyEntryButton; diff --git a/frontend/src/components/EntriesNavigation.js b/frontend/src/components/EntriesNavigation.js index c3f627e9..3800cb57 100644 --- a/frontend/src/components/EntriesNavigation.js +++ b/frontend/src/components/EntriesNavigation.js @@ -68,11 +68,6 @@ const EntriesNavigation = () => { const [filterState, setFilterState] = useState([]); const setNewFilterState = (props) => { - console.log( - "setNewFilterState", - props, - subscriptionsCache.data.subscriptions[0].id - ); _setNewFilterState(props); }; const loadMoreButtonRef = useRef(null); @@ -112,6 +107,7 @@ const EntriesNavigation = () => { value: subscriptionsCache.data.subscriptions[0].address, }); } + // eslint-disable-next-line }, [subscriptionsCache.isLoading]); const entriesPagesData = EntriesPages @@ -132,7 +128,6 @@ const EntriesNavigation = () => { }; const dropFilterArrayItem = (idx) => { - console.log("dropFilterArrayItem", idx, filterState); const newArray = [...filterState]; newArray[idx].type = FILTER_TYPES.DISABLED; setFilterState(newArray); @@ -148,18 +143,15 @@ const EntriesNavigation = () => { }; const handleConditionChange = (idx) => (e) => { - console.log("handleConditionChange", idx, e.target.value); setFilterProps(idx, { condition: parseInt(e.target.value) }); }; const handleFilterStateCallback = (props) => { - console.log("handleFilterStateCallback", props); const newFilterState = [...filterState]; newFilterState.push({ ...props }); setFilterState(newFilterState); }; if (subscriptionsCache.isLoading) return ""; - console.log("filterstate test", filterState); return ( ( flexGrow="1" w="100%" maxW="40rem" - alignItems={["center", "center", null, "flex-end"]} + alignItems={["flex-end", "flex-end", null, "flex-end"]} pr={[0, null, 8]} > { const toast = useToast(); diff --git a/frontend/src/components/FourOFour.js b/frontend/src/components/FourOFour.js index e2716fc1..0fe51891 100644 --- a/frontend/src/components/FourOFour.js +++ b/frontend/src/components/FourOFour.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import { Heading, Box, Text, Center, VStack } from "@chakra-ui/react"; const Page404 = () => ( diff --git a/frontend/src/components/FourOThree.js b/frontend/src/components/FourOThree.js index 541ac5d2..ab61257d 100644 --- a/frontend/src/components/FourOThree.js +++ b/frontend/src/components/FourOThree.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import { Heading, Box, Text, VStack, Center } from "@chakra-ui/react"; const Page403 = ({ location }) => ( diff --git a/frontend/src/components/HeadLinks.js b/frontend/src/components/HeadLinks.js index bf28c4c1..1145bb0b 100644 --- a/frontend/src/components/HeadLinks.js +++ b/frontend/src/components/HeadLinks.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import Head from "next/head"; import propTypes from "prop-types"; diff --git a/frontend/src/components/HeadSEO.js b/frontend/src/components/HeadSEO.js index c068b472..9cf0942b 100644 --- a/frontend/src/components/HeadSEO.js +++ b/frontend/src/components/HeadSEO.js @@ -1,5 +1,4 @@ - -import { jsx } from "@emotion/react"; +import React from "react"; import Head from "next/head"; import propTypes from "prop-types"; diff --git a/frontend/src/components/HubspotForm.js b/frontend/src/components/HubspotForm.js new file mode 100644 index 00000000..af343a9d --- /dev/null +++ b/frontend/src/components/HubspotForm.js @@ -0,0 +1,45 @@ +import React, { useEffect } from "react"; +import { Heading, Spinner } from "@chakra-ui/react"; +import Modal from "./Modal"; +import { useToast } from "../core/hooks"; +import HubspotForm from "react-hubspot-form"; + +const RequestIntegration = ({ toggleModal, title, formId }) => { + const toast = useToast(); + + useEffect(() => { + function handler(event) { + if ( + event.data.type === "hsFormCallback" && + event.data.eventName === "onFormSubmitted" + ) { + if (event.data.id === formId) { + toggleModal(null); + toast("Request sent", "success"); + } + } + } + + window.addEventListener("message", handler); + return () => { + window.removeEventListener("message", handler); + }; + // eslint-disable-next-line + }, [toast, toggleModal]); + + return ( + toggleModal(null)}> + + {title} + + } + /> + + ); +}; + +export default RequestIntegration; diff --git a/frontend/src/components/IconButton.js b/frontend/src/components/IconButton.js deleted file mode 100644 index 3e45e2a0..00000000 --- a/frontend/src/components/IconButton.js +++ /dev/null @@ -1,20 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { IconButton as IconButtonChakra } from "@chakra-ui/react"; -import { CheckIcon } from "@chakra-ui/icons"; - -const IconButton = (props) => { - return ( - } - bg="none" - _hover={{ transform: "scale(1.2)" }} - _focus={{ outline: "none" }} - _active={{ bg: "none" }} - {...props} - /> - ); -}; -export default IconButton; diff --git a/frontend/src/components/LandingNavbar.js b/frontend/src/components/LandingNavbar.js index c1afb174..c789a9ab 100644 --- a/frontend/src/components/LandingNavbar.js +++ b/frontend/src/components/LandingNavbar.js @@ -20,7 +20,18 @@ const LandingNavbar = () => { return ( <> <> - + {ui.isMobileView && ( + <> + ui.setSidebarToggled(!ui.sidebarToggled)} + icon={} + /> + + )} + { )} - - {ui.isMobileView && ( - <> - ui.setSidebarToggled(!ui.sidebarToggled)} - icon={} - /> - - )} ); }; diff --git a/frontend/src/components/Modal/index.js b/frontend/src/components/Modal/index.js index feb8a155..22969e3e 100644 --- a/frontend/src/components/Modal/index.js +++ b/frontend/src/components/Modal/index.js @@ -2,7 +2,7 @@ /** @jsx jsx */ import { jsx } from "@emotion/react"; import { Flex } from "@chakra-ui/react"; -import CustomIcon from "../CustomIcon" +import CustomIcon from "../CustomIcon"; import styles from "./styles"; const Modal = ({ children, onClose }) => ( diff --git a/frontend/src/components/Navbar.js b/frontend/src/components/Navbar.js index a1350120..20d9bedc 100644 --- a/frontend/src/components/Navbar.js +++ b/frontend/src/components/Navbar.js @@ -9,11 +9,11 @@ const SignIn = React.lazy(() => import("./SignIn")); const SignUp = React.lazy(() => import("./SignUp")); const LandingNavbar = React.lazy(() => import("./LandingNavbar")); const AppNavbar = React.lazy(() => import("./AppNavbar")); +const HubspotForm = React.lazy(() => import("./HubspotForm")); const Navbar = () => { const { modal, toggleModal, isAppView, isLoggedIn } = useContext(UIContext); - return ( { // overflow="initial" bgColor="primary.1200" // flexWrap="wrap" - direction={["column", "row", "row", null, "row"]} + direction={["row", "row", "row", null, "row"]} // zIndex={100} w="100%" minW="100%" @@ -33,11 +33,29 @@ const Navbar = () => { > {modal === "register" && } - {modal === "login" && } - {modal === "forgot" && } - + {modal === "hubspot-trader" && ( + + )} + {modal === "hubspot-fund" && ( + + )} + {modal === "hubspot-developer" && ( + + )} {(!isAppView || !isLoggedIn) && } {isAppView && isLoggedIn && } diff --git a/frontend/src/components/NewSubscription.js b/frontend/src/components/NewSubscription.js index c1add3d9..33f4a707 100644 --- a/frontend/src/components/NewSubscription.js +++ b/frontend/src/components/NewSubscription.js @@ -22,7 +22,7 @@ const NewSubscription = ({ isFreeOption, onClose }) => { const { typesCache, createSubscription } = useSubscriptions(); const { handleSubmit, errors, register } = useForm(); const [radioState, setRadioState] = useState("ethereum_blockchain"); - let { getRootProps, getRadioProps, ref } = useRadioGroup({ + let { getRootProps, getRadioProps } = useRadioGroup({ name: "type", defaultValue: radioState, onChange: setRadioState, diff --git a/frontend/src/components/PasswordInput.js b/frontend/src/components/PasswordInput.js index 163efd98..89aa7f8f 100644 --- a/frontend/src/components/PasswordInput.js +++ b/frontend/src/components/PasswordInput.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { InputGroup, InputRightElement, Input } from "@chakra-ui/react"; -import CustomIcon from "./CustomIcon" +import CustomIcon from "./CustomIcon"; const PasswordInput = ({ placeholder, name }, ref) => { const [showPassword, togglePassword] = useState(false); diff --git a/frontend/src/components/RadioCard.js b/frontend/src/components/RadioCard.js index 669779f6..c6cc46cb 100644 --- a/frontend/src/components/RadioCard.js +++ b/frontend/src/components/RadioCard.js @@ -8,7 +8,7 @@ const RadioCard = (props) => { const checkbox = getCheckboxProps(); return ( - console.log('hello2')}> + { const scrollerRef = useRef(); const router = useRouter(); const [path, setPath] = useState(); + + const [scrollDepth, setScrollDepth] = useState(0); + const { mixpanel } = useAnalytics(); + + const getScrollPrecent = ({ currentTarget }) => { + const scroll_level = + (100 * (currentTarget.scrollTop + currentTarget.clientHeight)) / + currentTarget.scrollHeight; + return scroll_level; + }; + + const handleScroll = (e) => { + const currentScroll = Math.ceil(getScrollPrecent(e) / 10); + if (currentScroll > scrollDepth) { + // withTracking( + setScrollDepth(currentScroll); + mixpanel.people.increment({ + [`Scroll depth at: ${router.nextRouter.pathname}`]: currentScroll, + }); + } + }; + useEffect(() => { setPath(router.nextRouter.pathname); }, [router.nextRouter.pathname]); - scrollerRef?.current?.scrollTo({ - top: 0, - left: 0, - behavior: path === router.nextRouter.pathname ? "smooth" : "auto", - }); + useEffect(() => { + scrollerRef?.current?.scrollTo({ + top: 0, + left: 0, + behavior: path === router.nextRouter.pathname ? "smooth" : "auto", + }); + // eslint-disable-next-line + }, [path]); return ( { direction="column" ref={scrollerRef} overflowY="scroll" + onScroll={(e) => handleScroll(e)} > {props.children} diff --git a/frontend/src/components/SearchBar.js b/frontend/src/components/SearchBar.js deleted file mode 100644 index 6549d563..00000000 --- a/frontend/src/components/SearchBar.js +++ /dev/null @@ -1,288 +0,0 @@ -import { jsx } from "@emotion/react"; -import { - useState, - useContext, - useRef, - useLayoutEffect, - useEffect, -} from "react"; -import { - Input, - InputLeftElement, - InputGroup, - Box, - Flex, - chakra, - InputRightElement, - Menu, - MenuItem, - MenuList, - MenuButton, - Button, - Portal, - MenuGroup, - Spinner, -} from "@chakra-ui/react"; -import { Search2Icon, CloseIcon } from "@chakra-ui/icons"; -import UIContext from "../core/providers/UIProvider/context"; -import { useJournalEntries, useJournals, useRouter } from "../core/hooks"; - -const SearchBar = (props) => { - const ui = useContext(UIContext); - const router = useRouter(); - const { refetch } = useJournalEntries({ - journalId: router.params.id, - journalType: router.params.appScope, - pageSize: 25, - isContent: false, - searchQuery: ui.searchTerm, - }); - - const [selectedJournal, setSelectedJournal] = useState(); - const [showError, setShowError] = useState(false); - const [InputFieldValue, setInputFieldValue] = useState(ui.serachTerm ?? ""); - const { journalsCache, publicJournalsCache } = useJournals(); - - const inputRef = useRef(null); - const showSearchBar = !ui.isMobileView || ui.searchBarActive; - - const handleSearch = (e) => { - e.preventDefault(); - - const journalIdToSearchIn = - selectedJournal?.id ?? router.params.id ?? false; - const searchAtSameRoute = - router.params.id && - journalIdToSearchIn && - router.params.id === journalIdToSearchIn; - - if (journalIdToSearchIn) { - if (searchAtSameRoute) { - ui.searchTerm === InputFieldValue - ? refetch() - : ui.setSearchTerm(InputFieldValue); - } else { - const newQuery = { ...router.nextRouter.query }; - newQuery.id = selectedJournal.id; - newQuery.appScope = selectedJournal.isPublic ? "public" : "personal"; - - delete newQuery.entryId; - ui.setSearchTerm(InputFieldValue); - router.push({ pathname: "/stream/", query: newQuery }, undefined, { - shallow: false, - }); - } - } else { - setShowError(true); - } - }; - - useLayoutEffect(() => { - showError && setTimeout(() => setShowError(false), 200); - }, [showError]); - - useEffect(() => { - const cache = - router.params.appScope === "personal" - ? publicJournalsCache - : journalsCache; - if (router.params.id && !cache.isLoading) { - const newJournal = cache.data.find( - (journal) => journal.id === router.params.id - ); - newJournal && setSelectedJournal(newJournal); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [router.params.id, journalsCache, publicJournalsCache]); - - useLayoutEffect(() => { - if (ui.searchTerm !== InputFieldValue) { - setInputFieldValue(ui.searchTerm); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ui.searchTerm]); - - const handleBlur = (e) => { - const currentTarget = e.currentTarget; - - // Check the newly focused element in the next tick of the event loop - setTimeout(() => { - // Check if the new activeElement is a child of the original container - if ( - !currentTarget.contains(document.activeElement) && - !document.activeElement.className.includes("bugout-search-bar") - ) { - // You can invoke a callback or add custom logic here - ui.setSearchBarActive(false); - } - }, 100); - }; - - const handleLeftElementClick = () => { - if (!showSearchBar) { - ui.setSearchBarActive(true); - } - inputRef.current.focus(); - }; - - const handleCloseSearchBar = () => { - ui.setSearchBarActive(false); - ui.setSearchTerm(""); - }; - - return ( - -
handleSearch(e)} - style={{ width: "100%", height: "100%" }} - > - { - ui.setSearchBarActive(true); - }} - onBlur={handleBlur} - > - handleLeftElementClick()} - minW="48px" - w="fit-content" - position="static" - justifySelf="flex-start" - h="100%" - overflowY="visible" - transform="1s" - > - {!ui.searchBarActive && ( - - )} - {ui.searchBarActive && ( - - - {`Search in: ${ - router.params.id && !selectedJournal?.name - ? "current" - : selectedJournal?.name ?? "Select one" - }`} - - - - {router.params.id && ( - - setSelectedJournal( - journalsCache.data.filter( - (journal) => journal.id === router.params.id - )[0] - ) - } - > - Current - - )} - - {journalsCache.isLoading && } - {!journalsCache.isLoading && - journalsCache.data.map((journal, idx) => ( - - setSelectedJournal({ - ...journal, - isPublic: false, - }) - } - > - {journal.name} - - ))} - - - {publicJournalsCache.isLoading && } - {!publicJournalsCache.isLoading && - publicJournalsCache.data.map((journal, idx) => ( - - setSelectedJournal({ - ...journal, - isPublic: true, - }) - } - > - {journal.name} - - ))} - - - - - )} - - setInputFieldValue(e.target.value)} - /> - - -
-
- ); -}; - -const ChakraSearchBar = chakra(SearchBar); - -export default ChakraSearchBar; diff --git a/frontend/src/components/SignIn.js b/frontend/src/components/SignIn.js index d87c65e4..80b9a5ad 100644 --- a/frontend/src/components/SignIn.js +++ b/frontend/src/components/SignIn.js @@ -15,7 +15,7 @@ import { Input, InputRightElement, } from "@chakra-ui/react"; -import CustomIcon from "./CustomIcon" +import CustomIcon from "./CustomIcon"; import { useLogin } from "../core/hooks"; import PasswordInput from "./PasswordInput"; import Modal from "./Modal"; @@ -51,7 +51,7 @@ const SignIn = ({ toggleModal }) => { colorScheme="primary" placeholder="Your Bugout username" name="username" - {...register('username', { required: true })} + {...register("username", { required: true })} ref={register({ required: "Username is required!" })} /> diff --git a/frontend/src/components/SignUp.js b/frontend/src/components/SignUp.js index 23364f9e..9edeb8cf 100644 --- a/frontend/src/components/SignUp.js +++ b/frontend/src/components/SignUp.js @@ -26,11 +26,11 @@ const SignUp = ({ toggleModal }) => { const { signUp, isLoading, isSuccess } = useSignUp(); const ui = useContext(UIContext); - useEffect(() => { if (isSuccess) { ui.toggleModal(null); } + // eslint-disable-next-line }, [isSuccess, toggleModal]); return ( diff --git a/frontend/src/components/SplitWithImage.js b/frontend/src/components/SplitWithImage.js index 227b9c68..c1e8dbdd 100644 --- a/frontend/src/components/SplitWithImage.js +++ b/frontend/src/components/SplitWithImage.js @@ -14,15 +14,10 @@ import { useBreakpointValue, } from "@chakra-ui/react"; // import Xarrow, { useXarrow } from "react-xarrows"; -import React, { useContext, useEffect } from "react"; +import React, { useContext } from "react"; import UIContext from "../core/providers/UIProvider/context"; const Feature = ({ text, icon, iconBg, bullets }) => { - // const updateXarrow = useXarrow(); - useEffect(() => { - // updateXarrow(); - }, []); - console.log("bullets;", bullets); return ( @@ -83,11 +78,6 @@ const SplitWithImage = ({ }); const ui = useContext(UIContext); - // const updateXarrow = useXarrow(); - const iconBgColor = useColorModeValue( - `${colorScheme}.100`, - `${colorScheme}.900` - ); const [isVisible, setVisible] = React.useState(true); const domRef = React.useRef(); @@ -106,7 +96,6 @@ const SplitWithImage = ({ py={0} className={`fade-in-section ${isVisible ? "is-visible" : ""}`} ref={domRef} - // onAnimationIteration={() => updateXarrow()} > {mirror && !ui.isMobileView && ( @@ -119,7 +108,7 @@ const SplitWithImage = ({ /> )} - + {badge} - {/* */} {title} {body} @@ -158,7 +136,6 @@ const SplitWithImage = ({ } > {bullets?.map((bullet, idx) => { - console.log("bullet1", bullet?.bullets); return ( - {cta} + {cta.label} {(!mirror || ui.isMobileView) && ( - + {"feature )} diff --git a/frontend/src/components/TagsList.js b/frontend/src/components/TagsList.js deleted file mode 100644 index 26a717f2..00000000 --- a/frontend/src/components/TagsList.js +++ /dev/null @@ -1,46 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { Tag, TagLabel, Flex, Button } from "@chakra-ui/react"; -import { useState } from "react"; - -const TAGS_DISPLAY_NUM_DEF = 5; -const TagsList = ({ tags }) => { - const [showAllTags, toggleAllTags] = useState(false); - const tagButtonText = showAllTags ? "Show less" : "Show all"; - - const TagsToShow = () => - tags - .filter((tag, i) => (showAllTags ? true : i < TAGS_DISPLAY_NUM_DEF)) - .map((tag, index) => { - return ( - - {tag} - - ); - }); - - return ( - - - {tags.length > TAGS_DISPLAY_NUM_DEF && ( - - )} - - ); -}; -export default TagsList; diff --git a/frontend/src/components/TokenList.js b/frontend/src/components/TokenList.js deleted file mode 100644 index 936d4f64..00000000 --- a/frontend/src/components/TokenList.js +++ /dev/null @@ -1,103 +0,0 @@ -import React from "react"; -import { IconButton } from "@chakra-ui/react"; -import { - Table, - Th, - Td, - Tr, - Thead, - Tbody, - Text, - Center, - Spinner, -} from "@chakra-ui/react"; -import { DeleteIcon } from "@chakra-ui/icons"; -import CopyButton from "./CopyEntryButton"; -import ConfirmationRequest from "./ConfirmationRequest"; -import NewTokenTr from "./NewTokenTr"; -import { useForm } from "react-hook-form"; - -const TokenList = ({ - tokens, - revoke, - isLoading, - isNewTokenOpen, - toggleNewToken, - createToken, - journalName, -}) => { - const { register, handleSubmit, errors } = useForm(); - if (isLoading) - return ( -
- -
- ); - - const handleTokenSubmit = ({ appName, appVersion }) => { - createToken({ appName, appVersion }).then(() => toggleNewToken(false)); - }; - - return ( -
- - - - - - - - - - - {tokens.map((token, idx) => { - return ( - - - - - - - ); - })} - - - -
TokenApp NameApp versionAction
- {token.restricted_token_id} - {token.app_name}{token.app_version} - revoke(token.restricted_token_id)} - > - } - /> - -
- {tokens.length < 1 && ( -
- Create Usage report tokens here -
- )} -
- ); -}; -export default TokenList; diff --git a/frontend/src/components/TokenRequest.js b/frontend/src/components/TokenRequest.js deleted file mode 100644 index b6dd42ee..00000000 --- a/frontend/src/components/TokenRequest.js +++ /dev/null @@ -1,109 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { - Box, - InputGroup, - InputLeftElement, - FormControl, - FormErrorMessage, - HStack, - Button, - InputRightElement, - Input, -} from "@chakra-ui/react"; -import { CloseIcon } from "@chakra-ui/icons"; -import { useEffect, useState, useRef } from "react"; -import CustomIcon from "./CustomIcon" -import { useForm } from "react-hook-form"; -import { useUser, useLogin } from "../core/hooks"; - -const TokenRequest = ({ newToken, toggle }) => { - const { user } = useUser(); - const { login, isLoading, data } = useLogin("SendLoginProp"); - const { handleSubmit, errors, register } = useForm(); - const [showPassword, setShowPassword] = useState("password"); - - const togglePassword = () => { - if (showPassword === "password") { - setShowPassword("text"); - } else { - setShowPassword("password"); - } - }; - - const PasswordRef = useRef(); - - useEffect(() => { - if (PasswordRef.current) { - PasswordRef.current.focus(); - } - }, [PasswordRef]); - - useEffect(() => { - if (data) { - newToken(data.data.access_token); - toggle(null); - } - }, [data, newToken, toggle]); - - const formStyle = { - display: "flex", - flexWrap: "wrap", - minWidth: "100px", - flexFlow: "row wrap-reverse", - aligntContent: "flex-end", - }; - - if (!user) return ""; //loading... - - return ( - -
- - - - - - - - - { - register(e, { required: "Password is required!" }); - PasswordRef.current = e; - }} - /> - toggle(null)}> - - - - - {errors.password && errors.password.message} - - - - -
-
- ); -}; -export default TokenRequest; diff --git a/frontend/src/components/TrustedBadge.js b/frontend/src/components/TrustedBadge.js deleted file mode 100644 index 12fbf675..00000000 --- a/frontend/src/components/TrustedBadge.js +++ /dev/null @@ -1,36 +0,0 @@ - -import { jsx } from "@emotion/react"; -import { Flex, Image, Link } from "@chakra-ui/react"; - -const TrustedBadge = ({ name, caseURL, ImgURL }) => { - return ( - - {name} - {caseURL && ( - // - - {`Read case study >`} - - // - )} - - ); -}; -export default TrustedBadge; diff --git a/frontend/src/core/hooks/useAnalytics.js b/frontend/src/core/hooks/useAnalytics.js index ce7fd37e..fee7e9eb 100644 --- a/frontend/src/core/hooks/useAnalytics.js +++ b/frontend/src/core/hooks/useAnalytics.js @@ -2,9 +2,8 @@ import AnalyticsContext from "../providers/AnalyticsProvider/context"; import { useContext } from "react"; import { useState, useEffect, useCallback } from "react"; const useAnalytics = () => { - const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } = useContext( - AnalyticsContext - ); + const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } = + useContext(AnalyticsContext); const [trackProps, setTrackProps] = useState({ event: null, props: null, diff --git a/frontend/src/core/hooks/useGroup.js b/frontend/src/core/hooks/useGroup.js index 0b22fb07..619c0262 100644 --- a/frontend/src/core/hooks/useGroup.js +++ b/frontend/src/core/hooks/useGroup.js @@ -8,7 +8,11 @@ const useGroup = (groupId) => { const cache = useQueryCache(); const toast = useToast(); - const { data: GroupUsersResponse, isLoading, refetch: getUsers } = useQuery( + const { + data: GroupUsersResponse, + isLoading, + refetch: getUsers, + } = useQuery( ["group-users", groupId], GroupService.getGroupUsers, queryCacheProps diff --git a/frontend/src/core/hooks/useGroups.js b/frontend/src/core/hooks/useGroups.js index 9147a8f7..6cdb3276 100644 --- a/frontend/src/core/hooks/useGroups.js +++ b/frontend/src/core/hooks/useGroups.js @@ -15,11 +15,11 @@ const useGroups = () => { return response?.data?.groups; }; - const { data, isLoading, refetch: getGroups } = useQuery( - "groups", - fetchGroups, - queryCacheProps - ); + const { + data, + isLoading, + refetch: getGroups, + } = useQuery("groups", fetchGroups, queryCacheProps); const [createGroup, createStatus] = useMutation( (groupName) => GroupService.createGroup(groupName), diff --git a/frontend/src/core/hooks/useJournalPermissions.js b/frontend/src/core/hooks/useJournalPermissions.js index 441df7ff..cf20af98 100644 --- a/frontend/src/core/hooks/useJournalPermissions.js +++ b/frontend/src/core/hooks/useJournalPermissions.js @@ -158,10 +158,6 @@ const useJournalPermissions = (journalId, journalScope) => { } ); - - - - const holders = data; return { holders, diff --git a/frontend/src/core/hooks/useLogin.js b/frontend/src/core/hooks/useLogin.js index cbb6a8ca..5bfcdc36 100644 --- a/frontend/src/core/hooks/useLogin.js +++ b/frontend/src/core/hooks/useLogin.js @@ -36,10 +36,12 @@ const useLogin = (loginType) => { getUser(); if (analytics.isLoaded) { analytics.mixpanel.people.set_once({ - [`${analytics.MIXPANEL_EVENTS.FIRST_LOGIN_DATE}`]: new Date().toISOString(), + [`${analytics.MIXPANEL_EVENTS.FIRST_LOGIN_DATE}`]: + new Date().toISOString(), }); analytics.mixpanel.people.set({ - [`${analytics.MIXPANEL_EVENTS.LAST_LOGIN_DATE}`]: new Date().toISOString(), + [`${analytics.MIXPANEL_EVENTS.LAST_LOGIN_DATE}`]: + new Date().toISOString(), }); analytics.mixpanel.track( `${analytics.MIXPANEL_EVENTS.USER_LOGS_IN}`, diff --git a/frontend/src/core/hooks/useLogout.js b/frontend/src/core/hooks/useLogout.js index a8c7cec9..1dc5d62a 100644 --- a/frontend/src/core/hooks/useLogout.js +++ b/frontend/src/core/hooks/useLogout.js @@ -8,7 +8,7 @@ const useLogout = () => { const { setLoggingOut } = useContext(UIContext); const router = useRouter(); const analytics = useAnalytics(); - const {mutate: revoke, data } = useMutation(AuthService.revoke, { + const { mutate: revoke, data } = useMutation(AuthService.revoke, { onSuccess: () => { if (analytics.isLoaded) { analytics.mixpanel.track( diff --git a/frontend/src/core/hooks/useSignUp.js b/frontend/src/core/hooks/useSignUp.js index f1212268..0d442083 100644 --- a/frontend/src/core/hooks/useSignUp.js +++ b/frontend/src/core/hooks/useSignUp.js @@ -15,7 +15,7 @@ const useSignUp = (source) => { isLoading, error, data, - isSuccess + isSuccess, } = useMutation(AuthService.register(), { onSuccess: (response) => { localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token); diff --git a/frontend/src/core/hooks/useStream.js b/frontend/src/core/hooks/useStream.js index 6920f9b5..285a6690 100644 --- a/frontend/src/core/hooks/useStream.js +++ b/frontend/src/core/hooks/useStream.js @@ -18,13 +18,6 @@ const useJournalEntries = ({ pageParam = 0; } - const searchTags = searchTerm.split(" ").filter(function (n) { - if (n.startsWith("#")) return n; - else { - return null; - } - }); - const response = await SubscriptionsService.getStream({ searchTerm, isContent, @@ -58,8 +51,7 @@ const useJournalEntries = ({ getNextPageParam: (lastGroup) => { return lastGroup.next_offset === null ? false : lastGroup.next_offset; }, - onSuccess: (data) => { - }, + onSuccess: () => {}, enabled: !!enabled, }); diff --git a/frontend/src/core/hooks/useSubscriptions.js b/frontend/src/core/hooks/useSubscriptions.js index 422ca0ec..16043f80 100644 --- a/frontend/src/core/hooks/useSubscriptions.js +++ b/frontend/src/core/hooks/useSubscriptions.js @@ -9,22 +9,6 @@ const useSubscriptions = () => { const toast = useToast(); const stripe = useStripe(); - // const manageSubscription = useMutation( - // SubscriptionsService.manageSubscription(), - // { - // onError: (error) => toast(error, "error"), - // onSuccess: (response) => { - // const { session_id: sessionId, session_url: sessionUrl } = - // response.data; - // if (sessionId) { - // stripe.redirectToCheckout({ sessionId }); - // } else if (sessionUrl) { - // window.location = sessionUrl; - // } - // }, - // } - // ); - const getSubscriptions = async () => { const response = await SubscriptionsService.getSubscriptions(); return response.data.data; @@ -68,19 +52,28 @@ const useSubscriptions = () => { const changeNote = useMutation(SubscriptionsService.modifySubscription(), { onError: (error) => toast(error, "error"), - onSuccess: (response) => { + onSuccess: () => { subscriptionsCache.refetch(); }, }); - const deleteSubscription = useMutation(SubscriptionsService.deleteSubscription(), { - onError: (error) => toast(error, "error"), - onSuccess: (response) => { - subscriptionsCache.refetch(); - }, - }); + const deleteSubscription = useMutation( + SubscriptionsService.deleteSubscription(), + { + onError: (error) => toast(error, "error"), + onSuccess: () => { + subscriptionsCache.refetch(); + }, + } + ); - return { createSubscription, subscriptionsCache, typesCache, changeNote, deleteSubscription }; + return { + createSubscription, + subscriptionsCache, + typesCache, + changeNote, + deleteSubscription, + }; }; export default useSubscriptions; diff --git a/frontend/src/core/hooks/useToast.js b/frontend/src/core/hooks/useToast.js index 7d30315e..eeae3e7e 100644 --- a/frontend/src/core/hooks/useToast.js +++ b/frontend/src/core/hooks/useToast.js @@ -1,7 +1,5 @@ - -import { jsx } from "@emotion/react"; import { useToast as useChakraToast, Box } from "@chakra-ui/react"; -import { useCallback } from "react"; +import React, { useCallback } from "react"; import { useAnalytics } from "."; const useToast = () => { diff --git a/frontend/src/core/providers/AnalyticsProvider/constants.js b/frontend/src/core/providers/AnalyticsProvider/constants.js index 7b40d468..bf48ddbe 100644 --- a/frontend/src/core/providers/AnalyticsProvider/constants.js +++ b/frontend/src/core/providers/AnalyticsProvider/constants.js @@ -12,13 +12,14 @@ export const MIXPANEL_EVENTS = { LAST_LOGIN_DATE: "Last login date", LAST_VISITED: "Last visited", TOAST_ERROR_DISPLAYED: "Error Toast", - HOMEPAGE_SCROLL_DEPTH: "Homepage scroll depth", + SCROLL_DEPTH: "Homepage scroll depth", CONVERT_TO_USER: "User Signs up", USER_LOGS_IN: "User Logs in", USER_LOGS_OUT: "User Logs out", PAGEVIEW: "Page view", PRICING_PLAN_CLICKED: "Pricing Plan clicked", BUTTON_CLICKED: "Button clicked", + LEFT_PAGE: "Left page", }; export default MIXPANEL_EVENTS; diff --git a/frontend/src/core/providers/AnalyticsProvider/index.js b/frontend/src/core/providers/AnalyticsProvider/index.js index 87e99758..51a5b6c4 100644 --- a/frontend/src/core/providers/AnalyticsProvider/index.js +++ b/frontend/src/core/providers/AnalyticsProvider/index.js @@ -12,6 +12,37 @@ const AnalyticsProvider = ({ children }) => { const router = useRouter(); useEffect(() => { + let durationSeconds = 0; + + const intervalId = + isLoaded && + setInterval(() => { + durationSeconds = durationSeconds + 1; + mixpanel.track( + MIXPANEL_EVENTS.LEFT_PAGE, + { + duration_seconds: durationSeconds, + url: router.nextRouter.pathname, + query: router.query, + pathParams: router.params, + }, + { transport: "sendBeacon" } + ); + }, 1000); + + return () => clearInterval(intervalId); + // eslint-disable-next-line + }, [isLoaded]); + + useEffect(() => { + if (isLoaded) { + console.log( + "track:", + router.nextRouter.pathname, + router.query, + router.params + ); + } isLoaded && mixpanel.track(MIXPANEL_EVENTS.PAGEVIEW, { url: router.nextRouter.pathname, diff --git a/frontend/src/core/services/auth.service.js b/frontend/src/core/services/auth.service.js index a29778fc..097aab73 100644 --- a/frontend/src/core/services/auth.service.js +++ b/frontend/src/core/services/auth.service.js @@ -3,7 +3,6 @@ import { http } from "../utils"; const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL; export const login = ({ username, password }) => { - console.log('login',username, password) const data = new FormData(); data.append("username", username); data.append("password", password); @@ -22,24 +21,26 @@ export const revoke = () => { }); }; -export const register = () => ({ username, email, password }) => { - const data = new FormData(); - data.append("username", username); - data.append("email", email); - data.append("password", password); +export const register = + () => + ({ username, email, password }) => { + const data = new FormData(); + data.append("username", username); + data.append("email", email); + data.append("password", password); - return http({ - method: "POST", - url: `${AUTH_URL}/user`, - data, - }).then(() => - http({ + return http({ method: "POST", - url: `${AUTH_URL}/token`, + url: `${AUTH_URL}/user`, data, - }) - ); -}; + }).then(() => + http({ + method: "POST", + url: `${AUTH_URL}/token`, + data, + }) + ); + }; export const verify = ({ code }) => { const data = new FormData(); diff --git a/frontend/src/core/services/humbug.service.js b/frontend/src/core/services/humbug.service.js index 77dc7b5c..766ca34d 100644 --- a/frontend/src/core/services/humbug.service.js +++ b/frontend/src/core/services/humbug.service.js @@ -50,20 +50,19 @@ export const getTokens = (humbugId) => { }); }; -export const createRestrictedToken = (humbugId) => ({ - appName, - appVersion, -}) => { - const data = new FormData(); - data.append("app_name", appName); - data.append("app_version", appVersion); +export const createRestrictedToken = + (humbugId) => + ({ appName, appVersion }) => { + const data = new FormData(); + data.append("app_name", appName); + data.append("app_version", appVersion); - return http({ - method: "POST", - url: `${API}/humbug/${humbugId}/tokens`, - data, - }); -}; + return http({ + method: "POST", + url: `${API}/humbug/${humbugId}/tokens`, + data, + }); + }; export const deleteRestrictedToken = (humbugId) => (tokenId) => { const data = new FormData(); diff --git a/frontend/src/core/services/journal.service.js b/frontend/src/core/services/journal.service.js index 9115d5eb..eefcc074 100644 --- a/frontend/src/core/services/journal.service.js +++ b/frontend/src/core/services/journal.service.js @@ -62,35 +62,31 @@ export const getJournalsScopes = () => { }); }; -export const setJournalPermission = (journalId) => ({ - holder_type, - holder_id, - permission_list, -}) => { - const data = new FormData(); - data.append("holder_type", holder_type); - data.append("holder_id", holder_id); - data.append("permission_list", permission_list); +export const setJournalPermission = + (journalId) => + ({ holder_type, holder_id, permission_list }) => { + const data = new FormData(); + data.append("holder_type", holder_type); + data.append("holder_id", holder_id); + data.append("permission_list", permission_list); - return http({ - method: "POST", - url: `${API}/journals/${journalId}/scopes`, - data: { holder_type, holder_id, permission_list }, - }); -}; + return http({ + method: "POST", + url: `${API}/journals/${journalId}/scopes`, + data: { holder_type, holder_id, permission_list }, + }); + }; -export const deleteJournalPermission = (journalId) => ({ - holder_type, - holder_id, - permission_list, -}) => { - return http({ - method: "DELETE", - url: `${API}/journals/${journalId}/scopes`, - data: { holder_type, holder_id, permission_list }, - // permission_list: ["read"] - }); -}; +export const deleteJournalPermission = + (journalId) => + ({ holder_type, holder_id, permission_list }) => { + return http({ + method: "DELETE", + url: `${API}/journals/${journalId}/scopes`, + data: { holder_type, holder_id, permission_list }, + // permission_list: ["read"] + }); + }; export const getPublicJournals = () => http({ @@ -98,32 +94,30 @@ export const getPublicJournals = () => url: `${API}/public/`, }); -export const searchEntries = ({ journalId }) => ({ - searchTerm, - limit, - offset, - isContent, - journalType, -}) => { - const journalScope = journalType === "personal" ? "journals" : "public"; - return http({ - method: "GET", - url: `${API}/${journalScope}/${journalId}/search`, - params: { - // filters: searchTags, - q: searchTerm, - limit: encodeURIComponent(limit), - offset: encodeURIComponent(offset), - content: encodeURIComponent(isContent), - }, - }); -}; +export const searchEntries = + ({ journalId }) => + ({ searchTerm, limit, offset, isContent, journalType }) => { + const journalScope = journalType === "personal" ? "journals" : "public"; + return http({ + method: "GET", + url: `${API}/${journalScope}/${journalId}/search`, + params: { + // filters: searchTags, + q: searchTerm, + limit: encodeURIComponent(limit), + offset: encodeURIComponent(offset), + content: encodeURIComponent(isContent), + }, + }); + }; -export const publicSearchEntries = ({ journalId }) => (query) => - http({ - method: "GET", - url: `${API}/public/${journalId}/search?q=${query}`, - }); +export const publicSearchEntries = + ({ journalId }) => + (query) => + http({ + method: "GET", + url: `${API}/public/${journalId}/search?q=${query}`, + }); export const getPublicJournal = (key, { journalId }) => http({ @@ -131,9 +125,11 @@ export const getPublicJournal = (key, { journalId }) => url: `${API}/public/${journalId}`, }); -export const getJournalStats = (key, { journalId }) => () => - http({ - method: "GET", - url: `${API}/journals/${journalId}/stats`, - params: { stats_version: 5 }, - }); +export const getJournalStats = + (key, { journalId }) => + () => + http({ + method: "GET", + url: `${API}/journals/${journalId}/stats`, + params: { stats_version: 5 }, + }); diff --git a/frontend/src/core/utils/mockupRequests.js b/frontend/src/core/utils/mockupRequests.js index 58db4296..3ae20be3 100644 --- a/frontend/src/core/utils/mockupRequests.js +++ b/frontend/src/core/utils/mockupRequests.js @@ -1,7 +1,7 @@ import moment from "moment"; const MOCK_API = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL; var MockAdapter = require("axios-mock-adapter"); -const makeid = (length) => { +export const makeid = (length) => { var result = ""; var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -12,7 +12,7 @@ const makeid = (length) => { return result; }; -const makenum = (length) => { +export const makenum = (length) => { var result = ""; var characters = "0123456789"; var charactersLength = characters.length; diff --git a/frontend/src/layouts/AccountLayout.js b/frontend/src/layouts/AccountLayout.js index 3875414e..68d8ce2b 100644 --- a/frontend/src/layouts/AccountLayout.js +++ b/frontend/src/layouts/AccountLayout.js @@ -1,4 +1,4 @@ -import React from "@emotion/react"; +import React from "react"; import { Box } from "@chakra-ui/react"; import { getLayout as getSiteLayout } from "./AppLayout"; diff --git a/frontend/src/layouts/AppLayout.js b/frontend/src/layouts/AppLayout.js index fdfbe133..c4bf88ba 100644 --- a/frontend/src/layouts/AppLayout.js +++ b/frontend/src/layouts/AppLayout.js @@ -1,4 +1,3 @@ - import { Flex } from "@chakra-ui/react"; import { getLayout as getSiteLayout } from "./RootLayout"; import React, { useContext } from "react"; diff --git a/frontend/src/layouts/LandingLayout.js b/frontend/src/layouts/LandingLayout.js index f3b2b592..01615026 100644 --- a/frontend/src/layouts/LandingLayout.js +++ b/frontend/src/layouts/LandingLayout.js @@ -1,10 +1,10 @@ -import React from "@emotion/react"; +import React from "react"; import { Scrollable, Footer } from "../components"; import { getLayout as getSiteLayout } from "./index"; const DefaultLayout = (props) => { return ( - + {props.children}