kopia lustrzana https://github.com/bugout-dev/moonstream
cleanup and landing page w background img
rodzic
a82267abd6
commit
4706217332
|
@ -2,7 +2,5 @@ module.exports = {
|
|||
reactStrictMode: true,
|
||||
target: "serverless",
|
||||
trailingSlash: true,
|
||||
presets: [
|
||||
require.resolve('next/babel')
|
||||
]
|
||||
};
|
||||
presets: [require.resolve("next/babel")],
|
||||
};
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import React from "react";
|
||||
import FourOThree from "../src/components/FourOThree";
|
||||
|
||||
const Page403 = () => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import React from "react";
|
||||
import FourOFour from "../src/components/FourOFour";
|
||||
|
||||
const Page404 = () => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<Data>
|
||||
) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
|
@ -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 (
|
||||
<Fade in>
|
||||
<Box
|
||||
onLo
|
||||
width="100%"
|
||||
flexDirection="column"
|
||||
onScroll={(e) => 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"
|
||||
>
|
||||
<Flex
|
||||
direction="column"
|
||||
|
@ -138,22 +174,43 @@ const Homepage = () => {
|
|||
position="relative"
|
||||
w="100%"
|
||||
overflow="initial"
|
||||
pt={0}
|
||||
>
|
||||
<Suspense fallback={""}></Suspense>
|
||||
|
||||
<Grid templateColumns="repeat(12,1fr)">
|
||||
<GridItem px="0" colSpan="12" pb={[1, 2, null, 8]}>
|
||||
<chakra.header>
|
||||
<Grid
|
||||
templateColumns="repeat(12,1fr)"
|
||||
mt={0}
|
||||
border="none"
|
||||
boxSizing="content-box"
|
||||
>
|
||||
<GridItem
|
||||
mt={0}
|
||||
px="0"
|
||||
colSpan="12"
|
||||
pb={[1, 2, null, 8]}
|
||||
minH="100vh"
|
||||
// bgColor="primary.1200"
|
||||
>
|
||||
<chakra.header boxSize="full">
|
||||
<Box
|
||||
w="full"
|
||||
h="container.sm"
|
||||
backgroundImage={`url(${assets["background"]})`}
|
||||
bgPos="center"
|
||||
// h="100%"
|
||||
// w="full"
|
||||
// transition=""
|
||||
// bgPos={["initial", "initial", "center", null, "center"]}
|
||||
bgPos="bottom"
|
||||
backgroundImage={`url(${assets[`${background}`]})`}
|
||||
bgSize="cover"
|
||||
boxSize="full"
|
||||
// bgP
|
||||
// h="container.sm"
|
||||
// h={backgroundH}
|
||||
// minH="100vh"
|
||||
// minH="auto"
|
||||
>
|
||||
<Flex
|
||||
align="center"
|
||||
pos="relative"
|
||||
// pos="relative"
|
||||
justify="center"
|
||||
boxSize="full"
|
||||
// bg="blackAlpha.700"
|
||||
|
@ -162,14 +219,16 @@ const Homepage = () => {
|
|||
textAlign="center"
|
||||
alignItems="center"
|
||||
spacing={6}
|
||||
maxW="1220px"
|
||||
maxW="1620px"
|
||||
px="7%"
|
||||
h="100%"
|
||||
pt={["10vh", null, "30vh"]}
|
||||
>
|
||||
<Heading
|
||||
size="xl"
|
||||
size="2xl"
|
||||
fontWeight="semibold"
|
||||
color="white"
|
||||
textTransform="uppercase"
|
||||
// textTransform="uppercase"
|
||||
>
|
||||
{/* <LoadingDots isActive> */}
|
||||
All the crypto data you care about in a single stream
|
||||
|
@ -177,6 +236,7 @@ const Homepage = () => {
|
|||
</Heading>
|
||||
<chakra.span
|
||||
my={12}
|
||||
fontSize={["lg", null, "xl"]}
|
||||
display="inline-block"
|
||||
color="primary.200"
|
||||
textDecor="underline"
|
||||
|
@ -186,6 +246,7 @@ const Homepage = () => {
|
|||
pool to Elon Musk’s latest tweets.
|
||||
</chakra.span>
|
||||
<chakra.span
|
||||
fontSize={["lg", null, "xl"]}
|
||||
display="inline-block"
|
||||
color="primary.300"
|
||||
textDecor="underline"
|
||||
|
@ -203,8 +264,9 @@ const Homepage = () => {
|
|||
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"]})`}
|
||||
>
|
||||
<Heading
|
||||
{...HEADING_PROPS}
|
||||
|
@ -214,91 +276,59 @@ const Homepage = () => {
|
|||
Data you can add to your stream:
|
||||
</Heading>
|
||||
|
||||
<Flex
|
||||
direction={["column", null, "row"]}
|
||||
flexWrap="nowrap"
|
||||
justifyContent={["center", null, "space-evenly"]}
|
||||
<SimpleGrid
|
||||
columns={[1, 2, 2, 4, null, 4]}
|
||||
// overflowY="clip"
|
||||
// direction={["column", null, "row"]}
|
||||
// flexWrap="nowrap"
|
||||
// justifyContent={["center", null, "space-evenly"]}
|
||||
>
|
||||
<Box {...CARD_CONTAINER}>
|
||||
<Flex {...IMAGE_CONTAINER}>
|
||||
<Image
|
||||
objectFit="contain"
|
||||
src={assets["icon2"]}
|
||||
alt="privacy is our prioriy"
|
||||
/>
|
||||
</Flex>
|
||||
<Heading {...TRIPLE_PICS_PROPS}>
|
||||
<Stack spacing={1} px={1} alignItems="center">
|
||||
<ChakraImage
|
||||
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||
objectFit="contain"
|
||||
src={assets["minedTransactions"]}
|
||||
alt="mined transactions"
|
||||
/>
|
||||
<Heading textAlign="center ">
|
||||
Ethereum mined transactions
|
||||
</Heading>
|
||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
||||
</Box>
|
||||
<Box {...CARD_CONTAINER}>
|
||||
<Flex {...IMAGE_CONTAINER}>
|
||||
<Image
|
||||
objectFit="contain"
|
||||
src={assets["icon1"]}
|
||||
alt="live metrics"
|
||||
/>
|
||||
</Flex>
|
||||
<Heading {...TRIPLE_PICS_PROPS}>
|
||||
</Stack>
|
||||
<Stack spacing={1} px={1} alignItems="center">
|
||||
<ChakraImage
|
||||
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||
objectFit="contain"
|
||||
src={assets["pendingTransactions"]}
|
||||
alt="mined transactions"
|
||||
/>
|
||||
<Heading textAlign="center ">
|
||||
Ethereum pending transactions
|
||||
</Heading>
|
||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
||||
</Box>
|
||||
<Box {...CARD_CONTAINER}>
|
||||
<Flex {...IMAGE_CONTAINER}>
|
||||
<Image
|
||||
objectFit="contain"
|
||||
src={assets["icon1"]}
|
||||
alt="live metrics"
|
||||
/>
|
||||
</Flex>
|
||||
<Heading {...TRIPLE_PICS_PROPS}>
|
||||
Centralized exchanges
|
||||
</Heading>
|
||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
||||
</Box>
|
||||
|
||||
<Box {...CARD_CONTAINER}>
|
||||
<Flex {...IMAGE_CONTAINER}>
|
||||
<Image
|
||||
objectFit="contain"
|
||||
src={assets["icon3"]}
|
||||
alt="we make it simple for user"
|
||||
/>
|
||||
</Flex>
|
||||
<Heading {...TRIPLE_PICS_PROPS}>Social media posts</Heading>
|
||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
{/* <Text
|
||||
textAlign="center"
|
||||
fontSize={["xl", "2xl", "2xl", "3xl", "4xl", "5xl"]}
|
||||
fontWeight="600"
|
||||
pt={[4, null, 12]}
|
||||
>
|
||||
We currently support Python, Javascript and Go!
|
||||
<br />
|
||||
Want us to support other programming languages?{" "}
|
||||
<Button
|
||||
size="2xl"
|
||||
colorScheme="primary"
|
||||
variant="link"
|
||||
onClick={() => toggleModal("Integration")}
|
||||
>
|
||||
Let us know
|
||||
</Button>
|
||||
</Text> */}
|
||||
</GridItem>
|
||||
<GridItem
|
||||
px={["7%", "12px", "7%", null, "7%"]}
|
||||
colSpan="12"
|
||||
pb={[1, 2, null, 8]}
|
||||
pt="5.125rem"
|
||||
mb="66px"
|
||||
bgGradient="linear-gradient(to bottom, #e9eaf4, #efeff7, #f4f4f9, #fafafc, #ffffff)"
|
||||
borderRadius="md"
|
||||
>
|
||||
</Stack>
|
||||
<Stack spacing={1} px={1} alignItems="center">
|
||||
<ChakraImage
|
||||
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||
objectFit="contain"
|
||||
src={assets["priceInformation"]}
|
||||
alt="mined transactions"
|
||||
/>
|
||||
<Heading textAlign="center ">Centralized exchanges</Heading>
|
||||
</Stack>
|
||||
<Stack spacing={1} px={1} alignItems="center">
|
||||
<ChakraImage
|
||||
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||
objectFit="contain"
|
||||
src={assets["socialMediaPosts"]}
|
||||
alt="mined transactions"
|
||||
/>
|
||||
<Heading textAlign="center ">Social media posts</Heading>
|
||||
</Stack>
|
||||
</SimpleGrid>
|
||||
<Center>
|
||||
<Heading pt="160px" pb="60px">
|
||||
Moonstream is ment for you if
|
||||
</Heading>
|
||||
</Center>
|
||||
<Flex
|
||||
w="100%"
|
||||
direction={["column", "row", "column", null, "column"]}
|
||||
|
@ -312,17 +342,29 @@ const Homepage = () => {
|
|||
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`,
|
||||
});
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
|
@ -336,8 +378,15 @@ const Homepage = () => {
|
|||
minH={ui.isMobileView ? "100vh" : null}
|
||||
>
|
||||
<SplitWithImage
|
||||
// cta={"Trader early access"}
|
||||
cta={"I want early access!"}
|
||||
cta={{
|
||||
label: "I want early access!",
|
||||
onClick: () => {
|
||||
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"]}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem
|
||||
|
@ -376,37 +425,40 @@ const Homepage = () => {
|
|||
minH={ui.isMobileView ? "100vh" : null}
|
||||
>
|
||||
<SplitWithImage
|
||||
// cta={"Algoritmic fund early access"}
|
||||
cta={"I want early access!"}
|
||||
cta={{
|
||||
label: "I want early access!",
|
||||
onClick: () => {
|
||||
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"]}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem
|
||||
|
@ -418,36 +470,39 @@ const Homepage = () => {
|
|||
minH={ui.isMobileView ? "100vh" : null}
|
||||
>
|
||||
<SplitWithImage
|
||||
// cta={"Developer early access"}
|
||||
cta={"I want early access!"}
|
||||
cta={{
|
||||
label: "I want early access!",
|
||||
onClick: () => {
|
||||
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"]}
|
||||
/>
|
||||
</GridItem>
|
||||
<GridItem
|
||||
|
@ -459,29 +514,26 @@ const Homepage = () => {
|
|||
>
|
||||
<Center>
|
||||
<Button
|
||||
as={Link}
|
||||
isExternal
|
||||
href={"https://discord.gg/FetK5BxD"}
|
||||
size="lg"
|
||||
variant="solid"
|
||||
colorScheme="suggested"
|
||||
id="test"
|
||||
onClick={() => {
|
||||
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Join our discord`,
|
||||
});
|
||||
toggleModal("hubspot");
|
||||
}}
|
||||
>
|
||||
Join our waitlist
|
||||
Join our discord
|
||||
</Button>
|
||||
</Center>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</Flex>
|
||||
{/* <ConnectElements
|
||||
selector=".MoonBadge"
|
||||
overlay={100}
|
||||
elements={[
|
||||
{ from: ".element1", to: ".element2" },
|
||||
{ from: ".element2", to: ".element3" },
|
||||
// { from: ".element3", to: ".element4" },
|
||||
// { from: ".element5", to: ".element4" },
|
||||
// { from: ".element6", to: ".element4" },
|
||||
// { from: ".element7", to: ".element4" },
|
||||
]}
|
||||
/> */}
|
||||
</Box>
|
||||
</Fade>
|
||||
);
|
||||
|
|
|
@ -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 (
|
||||
<Box
|
||||
mb={4}
|
||||
shadow="base"
|
||||
borderWidth="1px"
|
||||
alignSelf={{ base: "center", lg: "flex-start" }}
|
||||
borderColor={useColorModeValue("gray.200", "gray.500")}
|
||||
borderRadius={"xl"}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
const Pricing = (props) => {
|
||||
return (
|
||||
<Box py={12} minH="100vh">
|
||||
<VStack spacing={2} textAlign="center">
|
||||
<Heading as="h1" fontSize="4xl">
|
||||
Plans that fit your need
|
||||
</Heading>
|
||||
<Text fontSize="lg" color={"gray.500"}>
|
||||
Start with 14-day free trial. No credit card needed. Cancel at
|
||||
anytime.
|
||||
</Text>
|
||||
</VStack>
|
||||
<Stack
|
||||
direction={{ base: "column", md: "row" }}
|
||||
textAlign="center"
|
||||
justify="center"
|
||||
spacing={{ base: 4, lg: 10 }}
|
||||
py={10}
|
||||
>
|
||||
<PriceWrapper>
|
||||
<Box py={4} px={12}>
|
||||
<Text fontWeight="500" fontSize="2xl">
|
||||
Hobby
|
||||
</Text>
|
||||
<HStack justifyContent="center">
|
||||
<Text fontSize="3xl" fontWeight="600">
|
||||
$
|
||||
</Text>
|
||||
<Text fontSize="5xl" fontWeight="900">
|
||||
79
|
||||
</Text>
|
||||
<Text fontSize="3xl" color="gray.500">
|
||||
/month
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<VStack
|
||||
bg={useColorModeValue("gray.50", "gray.700")}
|
||||
py={4}
|
||||
borderBottomRadius={"xl"}
|
||||
>
|
||||
<List spacing={3} textAlign="start" px={12}>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
unlimited build minutes
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
5TB Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
</List>
|
||||
<Box w="80%" pt={7}>
|
||||
<Button w="full" colorScheme="primary" variant="outline">
|
||||
Start trial
|
||||
</Button>
|
||||
</Box>
|
||||
</VStack>
|
||||
</PriceWrapper>
|
||||
|
||||
<PriceWrapper>
|
||||
<Box position="relative">
|
||||
<Box
|
||||
position="absolute"
|
||||
top="-16px"
|
||||
left="50%"
|
||||
style={{ transform: "translate(-50%)" }}
|
||||
>
|
||||
<Text
|
||||
textTransform="uppercase"
|
||||
bg={useColorModeValue("secondary.300", "secondary.700")}
|
||||
px={3}
|
||||
py={1}
|
||||
color={useColorModeValue("white.900", "white.300")}
|
||||
fontSize="sm"
|
||||
fontWeight="600"
|
||||
rounded="xl"
|
||||
>
|
||||
Most Popular
|
||||
</Text>
|
||||
</Box>
|
||||
<Box py={4} px={12}>
|
||||
<Text fontWeight="500" fontSize="2xl">
|
||||
Growth
|
||||
</Text>
|
||||
<HStack justifyContent="center">
|
||||
<Text fontSize="3xl" fontWeight="600">
|
||||
$
|
||||
</Text>
|
||||
<Text fontSize="5xl" fontWeight="900">
|
||||
149
|
||||
</Text>
|
||||
<Text fontSize="3xl" color="gray.500">
|
||||
/month
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<VStack
|
||||
bg={useColorModeValue("gray.50", "gray.700")}
|
||||
py={4}
|
||||
borderBottomRadius={"xl"}
|
||||
>
|
||||
<List spacing={3} textAlign="start" px={12}>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
unlimited build minutes
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
5TB Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
5TB Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
5TB Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
</List>
|
||||
<Box w="80%" pt={7}>
|
||||
<Button w="full" colorScheme="suggested">
|
||||
Start trial
|
||||
</Button>
|
||||
</Box>
|
||||
</VStack>
|
||||
</Box>
|
||||
</PriceWrapper>
|
||||
<PriceWrapper>
|
||||
<Box py={4} px={12}>
|
||||
<Text fontWeight="500" fontSize="2xl">
|
||||
Scale
|
||||
</Text>
|
||||
<HStack justifyContent="center">
|
||||
<Text fontSize="3xl" fontWeight="600">
|
||||
$
|
||||
</Text>
|
||||
<Text fontSize="5xl" fontWeight="900">
|
||||
349
|
||||
</Text>
|
||||
<Text fontSize="3xl" color="gray.500">
|
||||
/month
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
<VStack
|
||||
bg={useColorModeValue("gray.50", "gray.700")}
|
||||
py={4}
|
||||
borderBottomRadius={"xl"}
|
||||
>
|
||||
<List spacing={3} textAlign="start" px={12}>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
unlimited build minutes
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListIcon as={FaCheckCircle} color="suggested.900" />
|
||||
5TB Lorem, ipsum dolor.
|
||||
</ListItem>
|
||||
</List>
|
||||
<Box w="80%" pt={7}>
|
||||
<Button w="full" colorScheme="primary" variant="outline">
|
||||
Start trial
|
||||
</Button>
|
||||
</Box>
|
||||
</VStack>
|
||||
</PriceWrapper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
|
@ -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 = () => (
|
||||
<Box>
|
||||
<Box px="1.5rem" m="auto" mb={8} maxWidth="1199.98px" minHeight="60vh">
|
||||
<Heading my={8} as="h1">
|
||||
Moonstream.to Terms of Service
|
||||
</Heading>
|
||||
<Text fontSize="md">
|
||||
Welcome to Bugout! Please read these Terms of Service before accessing
|
||||
or using Bugout.
|
||||
</Text>
|
||||
<Heading mt={4}>Definitions</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
<OrderedList>
|
||||
<ListItem>
|
||||
{`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.`}
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
{` 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.`}
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
{` “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.`}
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
“Bugout,” “Bugout.dev”, “Simiotics”, “We,” and “Us” refer to
|
||||
Simiotics, Inc., as well as our affiliates, directors, subsidiaries,
|
||||
contractors, licensors, officers, agents, and employees.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
The “Service” refers to the applications, software, products, and
|
||||
services provided by Simiotics.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
“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.
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
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.
|
||||
</ListItem>
|
||||
</OrderedList>
|
||||
</Text>
|
||||
<Heading mt={4}>Account Terms</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Account Controls
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
Subject to these Terms, you retain ultimate administrative control over
|
||||
your User Account and the Content within it.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{` 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.`}
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Required Information
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Account Requirements
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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).`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
Your login may only be used by one person — i.e., a single login may not
|
||||
be shared by multiple people.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
A paid Group may only provide access to as many User Accounts as your
|
||||
subscription allows.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
User Account Security
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Acceptable Use</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>User-Generated Content</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Responsibility for User-Generated Content
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Bugout May Remove Content
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Ownership of Content, Right to Post, and License Grants
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
|
||||
<Text as="h3" mt={4} size="md">
|
||||
License Grant to Us
|
||||
</Text>
|
||||
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
License Grant to Other Users
|
||||
</Heading>
|
||||
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Moral Rights
|
||||
</Heading>
|
||||
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Private Content</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Control of Private Content
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
Some Accounts may have private content -- for example, groups or
|
||||
journals -- which allow the User to control access to Content.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Confidentiality of Private Content
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Access
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
Bugout personnel may only access the content of your private content in
|
||||
the situations described in our{" "}
|
||||
<Link color="primary.600" href="/privacy-policy">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
Additionally, we may be compelled by law to disclose your private
|
||||
content.
|
||||
</Text>
|
||||
<Heading mt={4}>Intellectual Property Notice</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
{`Bugout's Rights to Content`}
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>API Terms</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`You may not share API tokens to exceed Bugout's rate limitations.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
All use of the Bugout API is subject to these Terms of Service and the
|
||||
Bugout{" "}
|
||||
<Link color="primary.600" href="/privacy-policy">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Heading mt={4}>Payment</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Pricing
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Authorization
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Responsibility for Payment
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Cancellation and Termination</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Account Cancellation
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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).
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Upon Cancellation
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
We will not delete Content that you have contributed to Groups or that
|
||||
other Users have cloned.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
You must make this request within 90 days of cancellation, termination,
|
||||
or downgrade.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Bugout May Terminate
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
Bugout reserves the right to refuse service to anyone for any reason at
|
||||
any time.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Survival
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Communications with Bugout</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Disclaimer of Warranties</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Limitation of Liability</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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:
|
||||
<UnorderedList pl={3}>
|
||||
<ListItem>User-Generated Content;</ListItem>
|
||||
<ListItem>your use or inability to use the Service;</ListItem>
|
||||
<ListItem>
|
||||
any modification, price change, suspension or discontinuance of the
|
||||
Service;
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
the Service generally or the software or systems that make the
|
||||
Service available;
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
unauthorized access to or alterations of your transmissions or data;
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
statements or conduct of any third party on the Service;
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
any other user interactions that you input or receive through your
|
||||
use of the Service;
|
||||
</ListItem>
|
||||
<ListItem>or any other matter relating to the Service.</ListItem>
|
||||
</UnorderedList>
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Release and Indemnification</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading mt={4}>Changes to These Terms</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
{`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.`}
|
||||
</Text>
|
||||
<Heading mt={4}>Miscellaneous</Heading>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Governing Law
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Heading as="h3" mt={4} size="md">
|
||||
Non-Assignability
|
||||
</Heading>
|
||||
<Text mt={4} fontSize="md">
|
||||
Bugout may assign or delegate these Terms of Service and/or the Bugout
|
||||
<Link color="primary.600" href="/privacy-policy">
|
||||
{" "}
|
||||
Privacy Policy
|
||||
</Link>
|
||||
, 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.
|
||||
</Text>
|
||||
<Text mt={4} size="md">
|
||||
Severability, No Waiver, and Survival
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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.
|
||||
</Text>
|
||||
<Text mt={4} size="md">
|
||||
Amendments; Complete Agreement
|
||||
</Text>
|
||||
<Text mt={4} fontSize="md">
|
||||
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{" "}
|
||||
<Link color="primary.600" href="/privacy-policy">
|
||||
Privacy Policy
|
||||
</Link>
|
||||
, 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.
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export default TermsOfService;
|
|
@ -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={<RiAccountCircleLine size="26px"/>}
|
||||
icon={<RiAccountCircleLine size="26px" />}
|
||||
// variant="outline"
|
||||
color="gray.100"
|
||||
/>
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -21,9 +21,7 @@ import {
|
|||
} from "@chakra-ui/react";
|
||||
import {
|
||||
HamburgerIcon,
|
||||
PlusSquareIcon,
|
||||
QuestionOutlineIcon,
|
||||
BellIcon,
|
||||
ArrowLeftIcon,
|
||||
ArrowRightIcon,
|
||||
} from "@chakra-ui/icons";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 (
|
||||
<Fragment>
|
||||
{content.title && (
|
||||
<GridItem colSpan="12" px="8.3%" py={1} textAlign="center">
|
||||
<Heading
|
||||
id={TitleRef}
|
||||
pt={16}
|
||||
pb={4}
|
||||
fontWeight="200"
|
||||
{...HeaderStyle}
|
||||
>
|
||||
{content.title}
|
||||
</Heading>
|
||||
</GridItem>
|
||||
)}
|
||||
{content.body.map((element, idx) => {
|
||||
if ("text" in element) {
|
||||
return (
|
||||
<GridItem key={idx} colSpan="10" px="8.3%" py={1}>
|
||||
{element.text.map((paragraph, idx) => {
|
||||
return (
|
||||
<Text key={idx} py={2} fontSize="xl">
|
||||
{paragraph}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
</GridItem>
|
||||
);
|
||||
}
|
||||
if ("image" in element) {
|
||||
return (
|
||||
<GridItem key={idx} colSpan="10" py={1} justifySelf="center">
|
||||
<Image
|
||||
justifySelf="center"
|
||||
key={idx}
|
||||
maxHeight="48rem"
|
||||
src={element.image.path}
|
||||
alt={element.image.annotation}
|
||||
/>
|
||||
</GridItem>
|
||||
);
|
||||
}
|
||||
if ("title" in element) {
|
||||
element.PrevTitle = content.title;
|
||||
return <Block key={idx} {...element} />;
|
||||
}
|
||||
return "";
|
||||
})}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
export default Block;
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { Fragment } from "react";
|
||||
import { jsx } from "@emotion/react";
|
||||
import React, { Fragment } from "react";
|
||||
import {
|
||||
useClipboard,
|
||||
IconButton,
|
||||
|
|
|
@ -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 (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
size="xs"
|
||||
variant="link"
|
||||
colorScheme="primary"
|
||||
ml={1}
|
||||
>
|
||||
Copy
|
||||
</MenuButton>
|
||||
<MenuList maxH="sm" overflow="scroll">
|
||||
<MenuGroup title="Destination:">
|
||||
<MenuItem value={journalId} onClick={() => copyEntry(journalId)}>
|
||||
{
|
||||
journalsCache?.data?.data?.journals?.filter(
|
||||
(journal) => journal.id === journalId
|
||||
)[0]?.name
|
||||
}
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
{journalsCache?.data?.data?.journals?.map((journal) => {
|
||||
if (journal.id === journalId) return "";
|
||||
return (
|
||||
<MenuItem
|
||||
key={`option-${journal.id}`}
|
||||
value={journal.id}
|
||||
onClick={() => copyEntry(journal.id)}
|
||||
>
|
||||
{journal.name}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyEntryButton;
|
|
@ -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 (
|
||||
<Flex
|
||||
id="JournalNavigation"
|
||||
|
|
|
@ -92,7 +92,7 @@ const Footer = () => (
|
|||
flexGrow="1"
|
||||
w="100%"
|
||||
maxW="40rem"
|
||||
alignItems={["center", "center", null, "flex-end"]}
|
||||
alignItems={["flex-end", "flex-end", null, "flex-end"]}
|
||||
pr={[0, null, 8]}
|
||||
>
|
||||
<Text
|
||||
|
|
|
@ -13,8 +13,8 @@ import {
|
|||
Input,
|
||||
InputRightElement,
|
||||
} from "@chakra-ui/react";
|
||||
import CustomIcon from "./CustomIcon"
|
||||
import Modal from "./Modal"
|
||||
import CustomIcon from "./CustomIcon";
|
||||
import Modal from "./Modal";
|
||||
|
||||
const ForgotPassword = ({ toggleModal }) => {
|
||||
const toast = useToast();
|
||||
|
|
|
@ -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 = () => (
|
||||
<Box pt={8} w="100%" h="100%">
|
||||
|
|
|
@ -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 }) => (
|
||||
<Box pt={8} w="100%" h="100%">
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import propTypes from "prop-types";
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import propTypes from "prop-types";
|
||||
|
||||
|
|
|
@ -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 (
|
||||
<Modal onClose={() => toggleModal(null)}>
|
||||
<Heading my={2} as="h2" fontSize={["xl", "3xl"]}>
|
||||
{title}
|
||||
</Heading>
|
||||
<HubspotForm
|
||||
region="na1"
|
||||
portalId="8018701"
|
||||
formId={formId}
|
||||
loading={<Spinner colorScheme="primary" speed="1s" />}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default RequestIntegration;
|
|
@ -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 (
|
||||
<IconButtonChakra
|
||||
p={0}
|
||||
boxSize="24px"
|
||||
icon={<CheckIcon boxSize="18px" />}
|
||||
bg="none"
|
||||
_hover={{ transform: "scale(1.2)" }}
|
||||
_focus={{ outline: "none" }}
|
||||
_active={{ bg: "none" }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export default IconButton;
|
|
@ -20,7 +20,18 @@ const LandingNavbar = () => {
|
|||
return (
|
||||
<>
|
||||
<>
|
||||
<Flex position="absolute" left="calc(50% - 100px)">
|
||||
{ui.isMobileView && (
|
||||
<>
|
||||
<IconButton
|
||||
alignSelf="flex-start"
|
||||
colorScheme="primary"
|
||||
variant="solid"
|
||||
onClick={() => ui.setSidebarToggled(!ui.sidebarToggled)}
|
||||
icon={<HamburgerIcon />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Flex ml={ui.isMobileView ? 2 : 8} justifySelf="flex-start">
|
||||
<RouterLink href="/" passHref>
|
||||
<Link>
|
||||
<Image
|
||||
|
@ -81,17 +92,6 @@ const LandingNavbar = () => {
|
|||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
{ui.isMobileView && (
|
||||
<>
|
||||
<IconButton
|
||||
colorScheme="secondary"
|
||||
variant="solid"
|
||||
onClick={() => ui.setSidebarToggled(!ui.sidebarToggled)}
|
||||
icon={<HamburgerIcon />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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 }) => (
|
||||
|
|
|
@ -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 (
|
||||
<Flex
|
||||
boxShadow={["sm", "md"]}
|
||||
|
@ -23,7 +23,7 @@ const Navbar = () => {
|
|||
// 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 = () => {
|
|||
>
|
||||
<Suspense fallback={""}>
|
||||
{modal === "register" && <SignUp toggleModal={toggleModal} />}
|
||||
|
||||
{modal === "login" && <SignIn toggleModal={toggleModal} />}
|
||||
|
||||
{modal === "forgot" && <ForgotPassword toggleModal={toggleModal} />}
|
||||
|
||||
{modal === "hubspot-trader" && (
|
||||
<HubspotForm
|
||||
toggleModal={toggleModal}
|
||||
title={"Join the waitlist"}
|
||||
formId={"29a17405-819b-405d-9563-f75bfb3774e0"}
|
||||
/>
|
||||
)}
|
||||
{modal === "hubspot-fund" && (
|
||||
<HubspotForm
|
||||
toggleModal={toggleModal}
|
||||
title={"Join the waitlist"}
|
||||
formId={"04f0b8df-6b8f-4cd0-871f-4e872523b6f5"}
|
||||
/>
|
||||
)}
|
||||
{modal === "hubspot-developer" && (
|
||||
<HubspotForm
|
||||
toggleModal={toggleModal}
|
||||
title={"Join the waitlist"}
|
||||
formId={"1897f4a1-3a00-475b-9bd5-5ca2725bd720"}
|
||||
/>
|
||||
)}
|
||||
{(!isAppView || !isLoggedIn) && <LandingNavbar />}
|
||||
{isAppView && isLoggedIn && <AppNavbar />}
|
||||
</Suspense>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -8,7 +8,7 @@ const RadioCard = (props) => {
|
|||
const checkbox = getCheckboxProps();
|
||||
|
||||
return (
|
||||
<Flex as="label" h="fill-availible" onClick={() => console.log('hello2')}>
|
||||
<Flex as="label" h="fill-availible">
|
||||
<input {...input} />
|
||||
<Box
|
||||
justifyContent="left"
|
||||
|
|
|
@ -1,19 +1,44 @@
|
|||
import { Flex, Box } from "@chakra-ui/react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useRouter } from "../core/hooks";
|
||||
import { useRouter, useAnalytics } from "../core/hooks";
|
||||
const Scrollable = (props) => {
|
||||
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 (
|
||||
<Flex
|
||||
|
@ -28,6 +53,7 @@ const Scrollable = (props) => {
|
|||
direction="column"
|
||||
ref={scrollerRef}
|
||||
overflowY="scroll"
|
||||
onScroll={(e) => handleScroll(e)}
|
||||
>
|
||||
{props.children}
|
||||
</Box>
|
||||
|
|
|
@ -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 (
|
||||
<Flex {...props} transition="1s">
|
||||
<form
|
||||
onSubmit={(e) => handleSearch(e)}
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
>
|
||||
<InputGroup
|
||||
bgColor={showSearchBar ? "white" : "transparent"}
|
||||
borderRadius="lg"
|
||||
overflow="hidden"
|
||||
h="100%"
|
||||
w="100%"
|
||||
onFocus={() => {
|
||||
ui.setSearchBarActive(true);
|
||||
}}
|
||||
onBlur={handleBlur}
|
||||
>
|
||||
<InputLeftElement
|
||||
onClick={() => handleLeftElementClick()}
|
||||
minW="48px"
|
||||
w="fit-content"
|
||||
position="static"
|
||||
justifySelf="flex-start"
|
||||
h="100%"
|
||||
overflowY="visible"
|
||||
transform="1s"
|
||||
>
|
||||
{!ui.searchBarActive && (
|
||||
<Search2Icon
|
||||
color={showSearchBar ? "primary.1200" : "white.100"}
|
||||
/>
|
||||
)}
|
||||
{ui.searchBarActive && (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
variant="ghost"
|
||||
colorScheme="primary"
|
||||
h="100%"
|
||||
m={0}
|
||||
borderRightRadius={0}
|
||||
transition="0.05s"
|
||||
className="bugout-search-bar"
|
||||
bgColor={showError ? "unsafe.900" : "primary.100"}
|
||||
textColor={showError ? "white.100" : "primary.900"}
|
||||
>
|
||||
{`Search in: ${
|
||||
router.params.id && !selectedJournal?.name
|
||||
? "current"
|
||||
: selectedJournal?.name ?? "Select one"
|
||||
}`}
|
||||
</MenuButton>
|
||||
<Portal>
|
||||
<MenuList
|
||||
overflowY="scroll"
|
||||
maxH="300px"
|
||||
className="bugout-search-bar"
|
||||
>
|
||||
{router.params.id && (
|
||||
<MenuItem
|
||||
className="bugout-search-bar"
|
||||
onClick={() =>
|
||||
setSelectedJournal(
|
||||
journalsCache.data.filter(
|
||||
(journal) => journal.id === router.params.id
|
||||
)[0]
|
||||
)
|
||||
}
|
||||
>
|
||||
Current
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuGroup textColor="gray" title="personal journals">
|
||||
{journalsCache.isLoading && <Spinner />}
|
||||
{!journalsCache.isLoading &&
|
||||
journalsCache.data.map((journal, idx) => (
|
||||
<MenuItem
|
||||
className="bugout-search-bar"
|
||||
key={`journal-search-list-${idx}`}
|
||||
onClick={() =>
|
||||
setSelectedJournal({
|
||||
...journal,
|
||||
isPublic: false,
|
||||
})
|
||||
}
|
||||
>
|
||||
{journal.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</MenuGroup>
|
||||
<MenuGroup textColor="gray" title="public journals">
|
||||
{publicJournalsCache.isLoading && <Spinner />}
|
||||
{!publicJournalsCache.isLoading &&
|
||||
publicJournalsCache.data.map((journal, idx) => (
|
||||
<MenuItem
|
||||
className="bugout-search-bar"
|
||||
key={`public-journal-search-list-${idx}`}
|
||||
onClick={() =>
|
||||
setSelectedJournal({
|
||||
...journal,
|
||||
isPublic: true,
|
||||
})
|
||||
}
|
||||
>
|
||||
{journal.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
</Portal>
|
||||
</Menu>
|
||||
)}
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
hidden={!showSearchBar}
|
||||
h="100%"
|
||||
px="8px"
|
||||
display="flex"
|
||||
paddingInlineStart="8px !important"
|
||||
sx={{
|
||||
WebkitPaddingStart: "8px !important",
|
||||
WebkitPaddingEnd: "8px !important",
|
||||
}}
|
||||
flexBasis="50px"
|
||||
flexGrow={1}
|
||||
textColor="black"
|
||||
ref={inputRef}
|
||||
_hover={{ bgColor: "white" }}
|
||||
_active={{ bgColor: "white" }}
|
||||
_focus={{ bgColor: "white", textColor: "black" }}
|
||||
value={InputFieldValue}
|
||||
onChange={(e) => setInputFieldValue(e.target.value)}
|
||||
/>
|
||||
<InputRightElement
|
||||
h="100%"
|
||||
position="static"
|
||||
justifySelf="flex-end"
|
||||
hidden={!ui.searchBarActive}
|
||||
>
|
||||
<Box
|
||||
onClick={() => handleCloseSearchBar()}
|
||||
transition="1s"
|
||||
_hover={{ transform: "scale(1.2)" }}
|
||||
>
|
||||
<CloseIcon color="primary.1200" />
|
||||
</Box>
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
</form>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const ChakraSearchBar = chakra(SearchBar);
|
||||
|
||||
export default ChakraSearchBar;
|
|
@ -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!" })}
|
||||
/>
|
||||
<InputRightElement>
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 (
|
||||
<Flex direction="column">
|
||||
<Stack direction={"row"} align={"center"}>
|
||||
|
@ -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()}
|
||||
>
|
||||
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={[0, 0, 10, null, 10]}>
|
||||
{mirror && !ui.isMobileView && (
|
||||
|
@ -119,7 +108,7 @@ const SplitWithImage = ({
|
|||
/>
|
||||
</Flex>
|
||||
)}
|
||||
<Stack spacing={4}>
|
||||
<Stack spacing={4} justifyContent="center">
|
||||
<Text
|
||||
id={`MoonBadge ${elementName}`}
|
||||
// id={`MoonBadge${elementName}`}
|
||||
|
@ -134,17 +123,6 @@ const SplitWithImage = ({
|
|||
>
|
||||
{badge}
|
||||
</Text>
|
||||
{/* <Xarrow
|
||||
dashness={{
|
||||
strokeLen: 10,
|
||||
nonStrokeLen: 15,
|
||||
animation: -2,
|
||||
}}
|
||||
color="#212990"
|
||||
showHead={false}
|
||||
start={"CryptoTraderButton"} //can be react ref
|
||||
end={`MoonBadge ${elementName}`} //or an id
|
||||
/> */}
|
||||
<Heading>{title}</Heading>
|
||||
<Text color={`primary.500`} fontSize={"lg"}>
|
||||
{body}
|
||||
|
@ -158,7 +136,6 @@ const SplitWithImage = ({
|
|||
}
|
||||
>
|
||||
{bullets?.map((bullet, idx) => {
|
||||
console.log("bullet1", bullet?.bullets);
|
||||
return (
|
||||
<Feature
|
||||
key={`splitWImageBullet-${idx}-${title}`}
|
||||
|
@ -177,23 +154,24 @@ const SplitWithImage = ({
|
|||
colorScheme={colorScheme}
|
||||
variant="outline"
|
||||
mt={[0, 0, null, 16]}
|
||||
textTransform={"uppercase"}
|
||||
fontSize={["xs", "sm", "lg", null, "lg"]}
|
||||
size={buttonSize}
|
||||
onClick={cta.onClick}
|
||||
>
|
||||
{cta}
|
||||
{cta.label}
|
||||
</Button>
|
||||
</Center>
|
||||
</Container>
|
||||
</Stack>
|
||||
</Stack>
|
||||
{(!mirror || ui.isMobileView) && (
|
||||
<Flex>
|
||||
<Flex justifyContent="center">
|
||||
<Image
|
||||
rounded={"md"}
|
||||
alt={"feature image"}
|
||||
src={imgURL}
|
||||
objectFit={"cover"}
|
||||
objectFit={"contain"}
|
||||
// boxSize={ui.isMobileView ? "lg" : null}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
|
|
|
@ -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
|
||||
variant="subtle"
|
||||
colorScheme="primary"
|
||||
size="sm"
|
||||
key={`${tag}-${index}`}
|
||||
>
|
||||
<TagLabel>{tag}</TagLabel>
|
||||
</Tag>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex display="flex" flexWrap="wrap" align="center" spacing={1}>
|
||||
<TagsToShow />
|
||||
{tags.length > TAGS_DISPLAY_NUM_DEF && (
|
||||
<Button
|
||||
m={1}
|
||||
onClick={() => toggleAllTags(!showAllTags)}
|
||||
size="xs"
|
||||
variant="link"
|
||||
color="primary.600"
|
||||
ml={1}
|
||||
style={{ transform: "translateY(-1px)" }}
|
||||
>
|
||||
{tagButtonText}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
export default TagsList;
|
|
@ -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 (
|
||||
<Center>
|
||||
<Spinner />
|
||||
</Center>
|
||||
);
|
||||
|
||||
const handleTokenSubmit = ({ appName, appVersion }) => {
|
||||
createToken({ appName, appVersion }).then(() => toggleNewToken(false));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(handleTokenSubmit)}>
|
||||
<Table
|
||||
variant="simple"
|
||||
colorScheme="primary"
|
||||
justifyContent="center"
|
||||
alignItems="baseline"
|
||||
h="auto"
|
||||
size="sm"
|
||||
>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Token</Th>
|
||||
<Th>App Name</Th>
|
||||
<Th>App version</Th>
|
||||
<Th>Action</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{tokens.map((token, idx) => {
|
||||
return (
|
||||
<Tr key={`RestrictedToken-row-${idx}`}>
|
||||
<Td mr={4} p={0}>
|
||||
<CopyButton>{token.restricted_token_id}</CopyButton>
|
||||
</Td>
|
||||
<Td py={0}>{token.app_name}</Td>
|
||||
<Td py={0}>{token.app_version}</Td>
|
||||
<Td py={0}>
|
||||
<ConfirmationRequest
|
||||
bodyMessage={"please confirm"}
|
||||
header={"Delete token"}
|
||||
onConfirm={() => revoke(token.restricted_token_id)}
|
||||
>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
colorScheme="primary"
|
||||
icon={<DeleteIcon />}
|
||||
/>
|
||||
</ConfirmationRequest>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
|
||||
<NewTokenTr
|
||||
isOpen={isNewTokenOpen}
|
||||
toggleSelf={toggleNewToken}
|
||||
errors={errors}
|
||||
register={register}
|
||||
journalName={journalName}
|
||||
/>
|
||||
</Tbody>
|
||||
</Table>
|
||||
{tokens.length < 1 && (
|
||||
<Center>
|
||||
<Text my={4}>Create Usage report tokens here</Text>
|
||||
</Center>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
export default TokenList;
|
|
@ -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 (
|
||||
<Box>
|
||||
<form onSubmit={handleSubmit(login)} style={formStyle}>
|
||||
<HStack>
|
||||
<Button
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
<FormControl isInvalid={errors.password}>
|
||||
<InputGroup minWidth="300px">
|
||||
<InputLeftElement onClick={togglePassword}>
|
||||
<CustomIcon icon="password" />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
colorScheme="primary"
|
||||
variant="filled"
|
||||
isDisabled={isLoading}
|
||||
autoComplete="on"
|
||||
placeholder="Your Bugout password"
|
||||
name="password"
|
||||
type={showPassword}
|
||||
ref={(e) => {
|
||||
register(e, { required: "Password is required!" });
|
||||
PasswordRef.current = e;
|
||||
}}
|
||||
/>
|
||||
<InputRightElement onClick={() => toggle(null)}>
|
||||
<CloseIcon />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1" justifyContent="Center">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<Input
|
||||
type="hidden"
|
||||
ref={register}
|
||||
name="username"
|
||||
defaultValue={user?.username}
|
||||
/>
|
||||
</HStack>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default TokenRequest;
|
|
@ -1,36 +0,0 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Flex, Image, Link } from "@chakra-ui/react";
|
||||
|
||||
const TrustedBadge = ({ name, caseURL, ImgURL }) => {
|
||||
return (
|
||||
<Flex
|
||||
m={1}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
alignSelf="center"
|
||||
wrap="nowrap"
|
||||
p={8}
|
||||
direction="column"
|
||||
>
|
||||
<Image
|
||||
sx={{ filter: "grayscale(100%)" }}
|
||||
h={["2.25rem", null, "3rem", "3rem", "4rem", "6rem"]}
|
||||
src={ImgURL}
|
||||
alt={name}
|
||||
></Image>
|
||||
{caseURL && (
|
||||
// <RouterLink href={caseURL} passHref scroll={true}>
|
||||
<Link
|
||||
fontSize={["sm", null, "md", "lg"]}
|
||||
textColor="secondary.900"
|
||||
href="/case-studies/activeloop"
|
||||
>
|
||||
{`Read case study >`}
|
||||
</Link>
|
||||
// </RouterLink>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
export default TrustedBadge;
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -158,10 +158,6 @@ const useJournalPermissions = (journalId, journalScope) => {
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const holders = data;
|
||||
return {
|
||||
holders,
|
||||
|
|
|
@ -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}`,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = () => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 },
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { getLayout as getSiteLayout } from "./RootLayout";
|
||||
import React, { useContext } from "react";
|
||||
|
|
|
@ -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 (
|
||||
<Scrollable>
|
||||
<Scrollable bgImg={""}>
|
||||
{props.children}
|
||||
<Footer />
|
||||
</Scrollable>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { jsx } from "@emotion/react";
|
||||
import { Flex, Spinner } from "@chakra-ui/react";
|
||||
import React, { Suspense, useContext, useState, useEffect } from "react";
|
||||
const Sidebar = React.lazy(() => import("../components/Sidebar"));
|
||||
|
|
Ładowanie…
Reference in New Issue