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,
|
reactStrictMode: true,
|
||||||
target: "serverless",
|
target: "serverless",
|
||||||
trailingSlash: true,
|
trailingSlash: true,
|
||||||
presets: [
|
presets: [require.resolve("next/babel")],
|
||||||
require.resolve('next/babel')
|
|
||||||
]
|
|
||||||
};
|
};
|
|
@ -4,9 +4,10 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build && next export -o build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "eslint ./ --ext js,jsx,ts,tsx --fix",
|
||||||
|
"pretty": "prettier --write \"./**/*.{js,jsx,json}\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^1.0.14",
|
"@chakra-ui/icons": "^1.0.14",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import FourOThree from "../src/components/FourOThree";
|
import FourOThree from "../src/components/FourOThree";
|
||||||
|
|
||||||
const Page403 = () => {
|
const Page403 = () => {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import FourOFour from "../src/components/FourOFour";
|
import FourOFour from "../src/components/FourOFour";
|
||||||
|
|
||||||
const Page404 = () => {
|
const Page404 = () => {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
|
|
||||||
import Document, { Html, Head, Main, NextScript } from "next/document";
|
import Document, { Html, Head, Main, NextScript } from "next/document";
|
||||||
|
|
||||||
export default class MyDocument extends 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 {
|
import {
|
||||||
Flex,
|
Flex,
|
||||||
Heading,
|
Heading,
|
||||||
Text,
|
|
||||||
Box,
|
Box,
|
||||||
Image,
|
Image as ChakraImage,
|
||||||
Button,
|
Button,
|
||||||
useBreakpointValue,
|
|
||||||
Center,
|
Center,
|
||||||
Fade,
|
Fade,
|
||||||
chakra,
|
chakra,
|
||||||
Stack,
|
Stack,
|
||||||
|
Link,
|
||||||
|
SimpleGrid,
|
||||||
|
useMediaQuery,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Grid, GridItem } from "@chakra-ui/react";
|
import { Grid, GridItem } from "@chakra-ui/react";
|
||||||
import { useUser, useAnalytics, useModals, useRouter } from "../src/core/hooks";
|
import { useUser, useAnalytics, useModals, useRouter } from "../src/core/hooks";
|
||||||
import { getLayout } from "../src/layouts";
|
import { getLayout } from "../src/layouts";
|
||||||
import SplitWithImage from "../src/components/SplitWithImage";
|
import SplitWithImage from "../src/components/SplitWithImage";
|
||||||
import {
|
|
||||||
IoAnalyticsSharp,
|
|
||||||
IoLogoBitcoin,
|
|
||||||
IoSearchSharp,
|
|
||||||
} from "react-icons/io5";
|
|
||||||
import ConnectedButtons from "../src/components/ConnectedButtons";
|
import ConnectedButtons from "../src/components/ConnectedButtons";
|
||||||
import UIContext from "../src/core/providers/UIProvider/context";
|
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 = {
|
const HEADING_PROPS = {
|
||||||
fontWeight: "700",
|
fontWeight: "700",
|
||||||
fontSize: ["4xl", "5xl", "4xl", "5xl", "6xl", "7xl"],
|
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 =
|
const AWS_PATH =
|
||||||
"https://s3.amazonaws.com/static.simiotics.com/moonstream/assets";
|
"https://s3.amazonaws.com/static.simiotics.com/moonstream/assets";
|
||||||
|
|
||||||
const assets = {
|
const assets = {
|
||||||
background: `https://s3.amazonaws.com/static.simiotics.com/landing/landing-background-2.png`,
|
background720: `${AWS_PATH}/background720.png`,
|
||||||
aviator: `https://s3.amazonaws.com/static.simiotics.com/landing/aviator-2.svg`,
|
background1920: `${AWS_PATH}/background720.png`,
|
||||||
icon1: `${AWS_PATH}/Image+1.png`,
|
background2880: `${AWS_PATH}/background720.png`,
|
||||||
icon2: `${AWS_PATH}/Image+2.png`,
|
background3840: `${AWS_PATH}/background720.png`,
|
||||||
icon3: `${AWS_PATH}/Image+3.png`,
|
minedTransactions: `${AWS_PATH}/Ethereum+mined+transactions.png`,
|
||||||
icon4: `${AWS_PATH}/Image+4.png`,
|
pendingTransactions: `${AWS_PATH}/Ethereum+pending+transactions.png`,
|
||||||
icon5: `${AWS_PATH}/Image+5.png`,
|
priceInformation: `${AWS_PATH}/Price+information.png`,
|
||||||
icon6: `${AWS_PATH}/Image+6.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 Homepage = () => {
|
||||||
const ui = useContext(UIContext);
|
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 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 { isInit } = useUser();
|
||||||
const { withTracking, MIXPANEL_EVENTS } = useAnalytics();
|
const { MIXPANEL_EVENTS, track } = useAnalytics();
|
||||||
|
|
||||||
const { toggleModal } = useModals();
|
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 }) => {
|
useEffect(() => {
|
||||||
const scroll_level =
|
assets["background720"] = `${AWS_PATH}/background720.png`;
|
||||||
(100 * (currentTarget.scrollTop + currentTarget.clientHeight)) /
|
assets["background2880"] = `${AWS_PATH}/background2880.png`;
|
||||||
currentTarget.scrollHeight;
|
assets["background3840"] = `${AWS_PATH}/background3840.png`;
|
||||||
return scroll_level;
|
}, []);
|
||||||
};
|
|
||||||
|
|
||||||
const handleScroll = (e) => {
|
useEffect(() => {
|
||||||
const currentScroll = Math.ceil(getScrollPrecent(e) / 10);
|
console.log(
|
||||||
|
"isLargerChanged, ",
|
||||||
if (currentScroll > scrollDepth) {
|
isLargerThan720px,
|
||||||
withTracking(
|
isLargerThan1920px,
|
||||||
setScrollDepth(currentScroll),
|
isLargerThan2880px,
|
||||||
MIXPANEL_EVENTS.HOMEPAGE_SCROLL_DEPTH,
|
isLargerThan3840px,
|
||||||
scrollDepth
|
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(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
|
@ -118,19 +120,53 @@ const Homepage = () => {
|
||||||
router.nextRouter.asPath.slice(0, 2) !== "/?" &&
|
router.nextRouter.asPath.slice(0, 2) !== "/?" &&
|
||||||
router.nextRouter.asPath.slice(0, 2) !== "/#"
|
router.nextRouter.asPath.slice(0, 2) !== "/#"
|
||||||
) {
|
) {
|
||||||
|
console.log("replacing!");
|
||||||
router.replace(router.nextRouter.asPath, undefined, {
|
router.replace(router.nextRouter.asPath, undefined, {
|
||||||
shallow: true,
|
shallow: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [isInit, router]);
|
}, [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 (
|
return (
|
||||||
<Fade in>
|
<Fade in>
|
||||||
<Box
|
<Box
|
||||||
|
onLo
|
||||||
width="100%"
|
width="100%"
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
onScroll={(e) => handleScroll(e)}
|
|
||||||
sx={{ scrollBehavior: "smooth" }}
|
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
|
<Flex
|
||||||
direction="column"
|
direction="column"
|
||||||
|
@ -138,22 +174,43 @@ const Homepage = () => {
|
||||||
position="relative"
|
position="relative"
|
||||||
w="100%"
|
w="100%"
|
||||||
overflow="initial"
|
overflow="initial"
|
||||||
|
pt={0}
|
||||||
>
|
>
|
||||||
<Suspense fallback={""}></Suspense>
|
<Suspense fallback={""}></Suspense>
|
||||||
|
|
||||||
<Grid templateColumns="repeat(12,1fr)">
|
<Grid
|
||||||
<GridItem px="0" colSpan="12" pb={[1, 2, null, 8]}>
|
templateColumns="repeat(12,1fr)"
|
||||||
<chakra.header>
|
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
|
<Box
|
||||||
w="full"
|
// h="100%"
|
||||||
h="container.sm"
|
// w="full"
|
||||||
backgroundImage={`url(${assets["background"]})`}
|
// transition=""
|
||||||
bgPos="center"
|
// bgPos={["initial", "initial", "center", null, "center"]}
|
||||||
|
bgPos="bottom"
|
||||||
|
backgroundImage={`url(${assets[`${background}`]})`}
|
||||||
bgSize="cover"
|
bgSize="cover"
|
||||||
|
boxSize="full"
|
||||||
|
// bgP
|
||||||
|
// h="container.sm"
|
||||||
|
// h={backgroundH}
|
||||||
|
// minH="100vh"
|
||||||
|
// minH="auto"
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
align="center"
|
align="center"
|
||||||
pos="relative"
|
// pos="relative"
|
||||||
justify="center"
|
justify="center"
|
||||||
boxSize="full"
|
boxSize="full"
|
||||||
// bg="blackAlpha.700"
|
// bg="blackAlpha.700"
|
||||||
|
@ -162,14 +219,16 @@ const Homepage = () => {
|
||||||
textAlign="center"
|
textAlign="center"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
spacing={6}
|
spacing={6}
|
||||||
maxW="1220px"
|
maxW="1620px"
|
||||||
px="7%"
|
px="7%"
|
||||||
|
h="100%"
|
||||||
|
pt={["10vh", null, "30vh"]}
|
||||||
>
|
>
|
||||||
<Heading
|
<Heading
|
||||||
size="xl"
|
size="2xl"
|
||||||
fontWeight="semibold"
|
fontWeight="semibold"
|
||||||
color="white"
|
color="white"
|
||||||
textTransform="uppercase"
|
// textTransform="uppercase"
|
||||||
>
|
>
|
||||||
{/* <LoadingDots isActive> */}
|
{/* <LoadingDots isActive> */}
|
||||||
All the crypto data you care about in a single stream
|
All the crypto data you care about in a single stream
|
||||||
|
@ -177,6 +236,7 @@ const Homepage = () => {
|
||||||
</Heading>
|
</Heading>
|
||||||
<chakra.span
|
<chakra.span
|
||||||
my={12}
|
my={12}
|
||||||
|
fontSize={["lg", null, "xl"]}
|
||||||
display="inline-block"
|
display="inline-block"
|
||||||
color="primary.200"
|
color="primary.200"
|
||||||
textDecor="underline"
|
textDecor="underline"
|
||||||
|
@ -186,6 +246,7 @@ const Homepage = () => {
|
||||||
pool to Elon Musk’s latest tweets.
|
pool to Elon Musk’s latest tweets.
|
||||||
</chakra.span>
|
</chakra.span>
|
||||||
<chakra.span
|
<chakra.span
|
||||||
|
fontSize={["lg", null, "xl"]}
|
||||||
display="inline-block"
|
display="inline-block"
|
||||||
color="primary.300"
|
color="primary.300"
|
||||||
textDecor="underline"
|
textDecor="underline"
|
||||||
|
@ -203,8 +264,9 @@ const Homepage = () => {
|
||||||
colSpan="12"
|
colSpan="12"
|
||||||
pt={["20px", "20px", "100px", null, "120px"]}
|
pt={["20px", "20px", "100px", null, "120px"]}
|
||||||
pb={["20px", "56px", null, "184px"]}
|
pb={["20px", "56px", null, "184px"]}
|
||||||
bgSize="cover"
|
minH="100vh"
|
||||||
bgImage={`url(${assets["background"]})`}
|
// bgSize="cover"
|
||||||
|
// bgImage={`url(${assets["background"]})`}
|
||||||
>
|
>
|
||||||
<Heading
|
<Heading
|
||||||
{...HEADING_PROPS}
|
{...HEADING_PROPS}
|
||||||
|
@ -214,91 +276,59 @@ const Homepage = () => {
|
||||||
Data you can add to your stream:
|
Data you can add to your stream:
|
||||||
</Heading>
|
</Heading>
|
||||||
|
|
||||||
<Flex
|
<SimpleGrid
|
||||||
direction={["column", null, "row"]}
|
columns={[1, 2, 2, 4, null, 4]}
|
||||||
flexWrap="nowrap"
|
// overflowY="clip"
|
||||||
justifyContent={["center", null, "space-evenly"]}
|
// direction={["column", null, "row"]}
|
||||||
|
// flexWrap="nowrap"
|
||||||
|
// justifyContent={["center", null, "space-evenly"]}
|
||||||
>
|
>
|
||||||
<Box {...CARD_CONTAINER}>
|
<Stack spacing={1} px={1} alignItems="center">
|
||||||
<Flex {...IMAGE_CONTAINER}>
|
<ChakraImage
|
||||||
<Image
|
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||||
objectFit="contain"
|
objectFit="contain"
|
||||||
src={assets["icon2"]}
|
src={assets["minedTransactions"]}
|
||||||
alt="privacy is our prioriy"
|
alt="mined transactions"
|
||||||
/>
|
/>
|
||||||
</Flex>
|
<Heading textAlign="center ">
|
||||||
<Heading {...TRIPLE_PICS_PROPS}>
|
|
||||||
Ethereum mined transactions
|
Ethereum mined transactions
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
</Stack>
|
||||||
</Box>
|
<Stack spacing={1} px={1} alignItems="center">
|
||||||
<Box {...CARD_CONTAINER}>
|
<ChakraImage
|
||||||
<Flex {...IMAGE_CONTAINER}>
|
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||||
<Image
|
objectFit="contain"
|
||||||
objectFit="contain"
|
src={assets["pendingTransactions"]}
|
||||||
src={assets["icon1"]}
|
alt="mined transactions"
|
||||||
alt="live metrics"
|
/>
|
||||||
/>
|
<Heading textAlign="center ">
|
||||||
</Flex>
|
|
||||||
<Heading {...TRIPLE_PICS_PROPS}>
|
|
||||||
Ethereum pending transactions
|
Ethereum pending transactions
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
</Stack>
|
||||||
</Box>
|
<Stack spacing={1} px={1} alignItems="center">
|
||||||
<Box {...CARD_CONTAINER}>
|
<ChakraImage
|
||||||
<Flex {...IMAGE_CONTAINER}>
|
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||||
<Image
|
objectFit="contain"
|
||||||
objectFit="contain"
|
src={assets["priceInformation"]}
|
||||||
src={assets["icon1"]}
|
alt="mined transactions"
|
||||||
alt="live metrics"
|
/>
|
||||||
/>
|
<Heading textAlign="center ">Centralized exchanges</Heading>
|
||||||
</Flex>
|
</Stack>
|
||||||
<Heading {...TRIPLE_PICS_PROPS}>
|
<Stack spacing={1} px={1} alignItems="center">
|
||||||
Centralized exchanges
|
<ChakraImage
|
||||||
</Heading>
|
boxSize={["220px", "220px", "xs", null, "xs"]}
|
||||||
<Text {...TRIPLE_PICS_TEXT}></Text>
|
objectFit="contain"
|
||||||
</Box>
|
src={assets["socialMediaPosts"]}
|
||||||
|
alt="mined transactions"
|
||||||
<Box {...CARD_CONTAINER}>
|
/>
|
||||||
<Flex {...IMAGE_CONTAINER}>
|
<Heading textAlign="center ">Social media posts</Heading>
|
||||||
<Image
|
</Stack>
|
||||||
objectFit="contain"
|
</SimpleGrid>
|
||||||
src={assets["icon3"]}
|
<Center>
|
||||||
alt="we make it simple for user"
|
<Heading pt="160px" pb="60px">
|
||||||
/>
|
Moonstream is ment for you if
|
||||||
</Flex>
|
</Heading>
|
||||||
<Heading {...TRIPLE_PICS_PROPS}>Social media posts</Heading>
|
</Center>
|
||||||
<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"
|
|
||||||
>
|
|
||||||
<Flex
|
<Flex
|
||||||
w="100%"
|
w="100%"
|
||||||
direction={["column", "row", "column", null, "column"]}
|
direction={["column", "row", "column", null, "column"]}
|
||||||
|
@ -312,17 +342,29 @@ const Homepage = () => {
|
||||||
button1={{
|
button1={{
|
||||||
label: "Crypto trader",
|
label: "Crypto trader",
|
||||||
link: "/#cryptoTrader",
|
link: "/#cryptoTrader",
|
||||||
onClick: null,
|
onClick: () => {
|
||||||
|
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to CryptoTrader`,
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
button2={{
|
button2={{
|
||||||
label: "Algorithmic Fund",
|
label: "Algorithmic Fund",
|
||||||
link: "/#algoFund",
|
link: "/#algoFund",
|
||||||
onClick: null,
|
onClick: () => {
|
||||||
|
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to AlgoFund`,
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
button3={{
|
button3={{
|
||||||
label: "Developer",
|
label: "Developer",
|
||||||
link: "/#smartDeveloper",
|
link: "/#smartDeveloper",
|
||||||
onClick: null,
|
onClick: () => {
|
||||||
|
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `scroll to Developer`,
|
||||||
|
});
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -336,8 +378,15 @@ const Homepage = () => {
|
||||||
minH={ui.isMobileView ? "100vh" : null}
|
minH={ui.isMobileView ? "100vh" : null}
|
||||||
>
|
>
|
||||||
<SplitWithImage
|
<SplitWithImage
|
||||||
// cta={"Trader early access"}
|
cta={{
|
||||||
cta={"I want early access!"}
|
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"}
|
elementName={"element1"}
|
||||||
colorScheme="suggested"
|
colorScheme="suggested"
|
||||||
badge={`For crypto traders`}
|
badge={`For crypto traders`}
|
||||||
|
@ -346,25 +395,25 @@ const Homepage = () => {
|
||||||
bullets={[
|
bullets={[
|
||||||
{
|
{
|
||||||
text: `Subscribe to the defi contracts you care about`,
|
text: `Subscribe to the defi contracts you care about`,
|
||||||
icon: IoLogoBitcoin,
|
icon: FaFileContract,
|
||||||
color: "suggested.50",
|
color: "suggested.50",
|
||||||
bgColor: "suggested.900",
|
bgColor: "suggested.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Make sense of how others are calling these contracts using Moonstream dashboards.
|
text: `Make sense of how others are calling these contracts using Moonstream dashboards.
|
||||||
`,
|
`,
|
||||||
icon: IoAnalyticsSharp,
|
icon: RiDashboardFill,
|
||||||
color: "suggested.50",
|
color: "suggested.50",
|
||||||
bgColor: "suggested.900",
|
bgColor: "suggested.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Get data directly from the transaction pool through our global network of Ethereum nodes`,
|
text: `Get data directly from the transaction pool through our global network of Ethereum nodes`,
|
||||||
icon: IoSearchSharp,
|
icon: GiMeshBall,
|
||||||
color: "suggested.50",
|
color: "suggested.50",
|
||||||
bgColor: "suggested.900",
|
bgColor: "suggested.900",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
imgURL={assets["icon2"]}
|
imgURL={assets["cryptoTraders"]}
|
||||||
/>
|
/>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem
|
<GridItem
|
||||||
|
@ -376,37 +425,40 @@ const Homepage = () => {
|
||||||
minH={ui.isMobileView ? "100vh" : null}
|
minH={ui.isMobileView ? "100vh" : null}
|
||||||
>
|
>
|
||||||
<SplitWithImage
|
<SplitWithImage
|
||||||
// cta={"Algoritmic fund early access"}
|
cta={{
|
||||||
cta={"I want early access!"}
|
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"}
|
elementName={"element2"}
|
||||||
mirror={true}
|
mirror={true}
|
||||||
colorScheme="secondary"
|
colorScheme="secondary"
|
||||||
badge={`For algorithmic funds`}
|
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={[
|
bullets={[
|
||||||
{
|
{
|
||||||
text: `Get API access to your stream`,
|
text: `Get API access to your stream`,
|
||||||
icon: IoLogoBitcoin,
|
icon: AiFillApi,
|
||||||
color: "secondary.50",
|
color: "secondary.50",
|
||||||
bgColor: "secondary.900",
|
bgColor: "secondary.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Set conditions that trigger predefined actions`,
|
text: `Set conditions that trigger predefined actions`,
|
||||||
icon: IoAnalyticsSharp,
|
icon: GiLogicGateXor,
|
||||||
color: "secondary.50",
|
color: "secondary.50",
|
||||||
bgColor: "secondary.900",
|
bgColor: "secondary.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Execute transactions directly on Moonstream nodes`,
|
text: `Execute transactions directly on Moonstream nodes`,
|
||||||
icon: IoSearchSharp,
|
icon: BiTransfer,
|
||||||
color: "secondary.50",
|
color: "secondary.50",
|
||||||
bgColor: "secondary.900",
|
bgColor: "secondary.900",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
imgURL={assets["icon3"]}
|
imgURL={assets["algorithmicFunds"]}
|
||||||
/>
|
/>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem
|
<GridItem
|
||||||
|
@ -418,36 +470,39 @@ const Homepage = () => {
|
||||||
minH={ui.isMobileView ? "100vh" : null}
|
minH={ui.isMobileView ? "100vh" : null}
|
||||||
>
|
>
|
||||||
<SplitWithImage
|
<SplitWithImage
|
||||||
// cta={"Developer early access"}
|
cta={{
|
||||||
cta={"I want early access!"}
|
label: "I want early access!",
|
||||||
|
onClick: () => {
|
||||||
|
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Early access CTA: developer`,
|
||||||
|
});
|
||||||
|
toggleModal("hubspot-developer");
|
||||||
|
},
|
||||||
|
}}
|
||||||
elementName={"element3"}
|
elementName={"element3"}
|
||||||
colorScheme="primary"
|
colorScheme="primary"
|
||||||
badge={`For smart contract developers`}
|
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={[
|
bullets={[
|
||||||
{
|
{
|
||||||
text: `See how people use your smart contracts`,
|
text: `See how people use your smart contracts`,
|
||||||
icon: IoLogoBitcoin,
|
icon: IoTelescopeSharp,
|
||||||
color: "primary.50",
|
color: "primary.50",
|
||||||
bgColor: "primary.900",
|
bgColor: "primary.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Set up alerts on suspicious activity`,
|
text: `Set up alerts on suspicious activity`,
|
||||||
icon: IoAnalyticsSharp,
|
icon: GiSuspicious,
|
||||||
color: "primary.50",
|
color: "primary.50",
|
||||||
bgColor: "primary.900",
|
bgColor: "primary.900",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `Register webhooks to connect your off-chain infrastructure`,
|
text: `Register webhooks to connect your off-chain infrastructure`,
|
||||||
icon: IoSearchSharp,
|
icon: GiHook,
|
||||||
color: "primary.50",
|
color: "primary.50",
|
||||||
bgColor: "primary.900",
|
bgColor: "primary.900",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
imgURL={assets["icon6"]}
|
imgURL={assets["smartDevelopers"]}
|
||||||
/>
|
/>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem
|
<GridItem
|
||||||
|
@ -459,29 +514,26 @@ const Homepage = () => {
|
||||||
>
|
>
|
||||||
<Center>
|
<Center>
|
||||||
<Button
|
<Button
|
||||||
|
as={Link}
|
||||||
|
isExternal
|
||||||
|
href={"https://discord.gg/FetK5BxD"}
|
||||||
size="lg"
|
size="lg"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorScheme="suggested"
|
colorScheme="suggested"
|
||||||
id="test"
|
id="test"
|
||||||
|
onClick={() => {
|
||||||
|
track(`${MIXPANEL_EVENTS.BUTTON_CLICKED}`, {
|
||||||
|
[`${MIXPANEL_PROPS.BUTTON_CLICKED}`]: `Join our discord`,
|
||||||
|
});
|
||||||
|
toggleModal("hubspot");
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Join our waitlist
|
Join our discord
|
||||||
</Button>
|
</Button>
|
||||||
</Center>
|
</Center>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Flex>
|
</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>
|
</Box>
|
||||||
</Fade>
|
</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 */
|
import React from "react";
|
||||||
/** @jsx jsx */
|
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import RouterLink from "next/link";
|
import RouterLink from "next/link";
|
||||||
import {
|
import {
|
||||||
Menu,
|
Menu,
|
||||||
|
@ -24,7 +22,7 @@ const AccountIconButton = (props) => {
|
||||||
{...props}
|
{...props}
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
aria-label="Account menu"
|
aria-label="Account menu"
|
||||||
icon={<RiAccountCircleLine size="26px"/>}
|
icon={<RiAccountCircleLine size="26px" />}
|
||||||
// variant="outline"
|
// variant="outline"
|
||||||
color="gray.100"
|
color="gray.100"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { useUser, useRouter } from "../core/hooks";
|
import { useUser, useRouter } from "../core/hooks";
|
||||||
import { useEffect, Fragment, useState } from "react";
|
import { useEffect, Fragment, useState } from "react";
|
||||||
import { Heading, Center, Spinner, Link, Button } from "@chakra-ui/react";
|
import { Heading, Center, Spinner, Link, Button } from "@chakra-ui/react";
|
||||||
|
|
|
@ -21,9 +21,7 @@ import {
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
HamburgerIcon,
|
HamburgerIcon,
|
||||||
PlusSquareIcon,
|
|
||||||
QuestionOutlineIcon,
|
QuestionOutlineIcon,
|
||||||
BellIcon,
|
|
||||||
ArrowLeftIcon,
|
ArrowLeftIcon,
|
||||||
ArrowRightIcon,
|
ArrowRightIcon,
|
||||||
} from "@chakra-ui/icons";
|
} from "@chakra-ui/icons";
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useChangePassword, useRouter } from "../core/hooks";
|
import { useChangePassword, useRouter } from "../core/hooks";
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
import React, { useEffect, useRef, useContext } from "react";
|
import React, { useEffect, useRef, useContext } from "react";
|
||||||
import {
|
import { Flex, Heading, Button, Link, SimpleGrid } from "@chakra-ui/react";
|
||||||
Flex,
|
|
||||||
Heading,
|
|
||||||
Button,
|
|
||||||
Link,
|
|
||||||
SimpleGrid,
|
|
||||||
useBreakpointValue,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
import Xarrow, { useXarrow } from "react-xarrows";
|
import Xarrow, { useXarrow } from "react-xarrows";
|
||||||
import UIContext from "../core/providers/UIProvider/context";
|
import UIContext from "../core/providers/UIProvider/context";
|
||||||
|
|
||||||
|
@ -17,19 +10,11 @@ const ArrowCTA = (props) => {
|
||||||
const box2Ref = useRef(null);
|
const box2Ref = useRef(null);
|
||||||
const box3Ref = useRef(null);
|
const box3Ref = useRef(null);
|
||||||
|
|
||||||
const gridSetup = useBreakpointValue({
|
|
||||||
base: "column",
|
|
||||||
sm: "horizontal",
|
|
||||||
md: "grid",
|
|
||||||
lg: "grid",
|
|
||||||
xl: "grid",
|
|
||||||
"2xl": "grid",
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateXarrow = useXarrow();
|
const updateXarrow = useXarrow();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateXarrow();
|
updateXarrow();
|
||||||
|
// eslint-disable-next-line
|
||||||
}, [ui.isMobileView]);
|
}, [ui.isMobileView]);
|
||||||
|
|
||||||
return (
|
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 React, { Fragment } from "react";
|
||||||
import { Fragment } from "react";
|
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import {
|
import {
|
||||||
useClipboard,
|
useClipboard,
|
||||||
IconButton,
|
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 [filterState, setFilterState] = useState([]);
|
||||||
|
|
||||||
const setNewFilterState = (props) => {
|
const setNewFilterState = (props) => {
|
||||||
console.log(
|
|
||||||
"setNewFilterState",
|
|
||||||
props,
|
|
||||||
subscriptionsCache.data.subscriptions[0].id
|
|
||||||
);
|
|
||||||
_setNewFilterState(props);
|
_setNewFilterState(props);
|
||||||
};
|
};
|
||||||
const loadMoreButtonRef = useRef(null);
|
const loadMoreButtonRef = useRef(null);
|
||||||
|
@ -112,6 +107,7 @@ const EntriesNavigation = () => {
|
||||||
value: subscriptionsCache.data.subscriptions[0].address,
|
value: subscriptionsCache.data.subscriptions[0].address,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
}, [subscriptionsCache.isLoading]);
|
}, [subscriptionsCache.isLoading]);
|
||||||
|
|
||||||
const entriesPagesData = EntriesPages
|
const entriesPagesData = EntriesPages
|
||||||
|
@ -132,7 +128,6 @@ const EntriesNavigation = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const dropFilterArrayItem = (idx) => {
|
const dropFilterArrayItem = (idx) => {
|
||||||
console.log("dropFilterArrayItem", idx, filterState);
|
|
||||||
const newArray = [...filterState];
|
const newArray = [...filterState];
|
||||||
newArray[idx].type = FILTER_TYPES.DISABLED;
|
newArray[idx].type = FILTER_TYPES.DISABLED;
|
||||||
setFilterState(newArray);
|
setFilterState(newArray);
|
||||||
|
@ -148,18 +143,15 @@ const EntriesNavigation = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConditionChange = (idx) => (e) => {
|
const handleConditionChange = (idx) => (e) => {
|
||||||
console.log("handleConditionChange", idx, e.target.value);
|
|
||||||
setFilterProps(idx, { condition: parseInt(e.target.value) });
|
setFilterProps(idx, { condition: parseInt(e.target.value) });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilterStateCallback = (props) => {
|
const handleFilterStateCallback = (props) => {
|
||||||
console.log("handleFilterStateCallback", props);
|
|
||||||
const newFilterState = [...filterState];
|
const newFilterState = [...filterState];
|
||||||
newFilterState.push({ ...props });
|
newFilterState.push({ ...props });
|
||||||
setFilterState(newFilterState);
|
setFilterState(newFilterState);
|
||||||
};
|
};
|
||||||
if (subscriptionsCache.isLoading) return "";
|
if (subscriptionsCache.isLoading) return "";
|
||||||
console.log("filterstate test", filterState);
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
id="JournalNavigation"
|
id="JournalNavigation"
|
||||||
|
|
|
@ -92,7 +92,7 @@ const Footer = () => (
|
||||||
flexGrow="1"
|
flexGrow="1"
|
||||||
w="100%"
|
w="100%"
|
||||||
maxW="40rem"
|
maxW="40rem"
|
||||||
alignItems={["center", "center", null, "flex-end"]}
|
alignItems={["flex-end", "flex-end", null, "flex-end"]}
|
||||||
pr={[0, null, 8]}
|
pr={[0, null, 8]}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
|
|
|
@ -13,8 +13,8 @@ import {
|
||||||
Input,
|
Input,
|
||||||
InputRightElement,
|
InputRightElement,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import CustomIcon from "./CustomIcon"
|
import CustomIcon from "./CustomIcon";
|
||||||
import Modal from "./Modal"
|
import Modal from "./Modal";
|
||||||
|
|
||||||
const ForgotPassword = ({ toggleModal }) => {
|
const ForgotPassword = ({ toggleModal }) => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { Heading, Box, Text, Center, VStack } from "@chakra-ui/react";
|
import { Heading, Box, Text, Center, VStack } from "@chakra-ui/react";
|
||||||
const Page404 = () => (
|
const Page404 = () => (
|
||||||
<Box pt={8} w="100%" h="100%">
|
<Box pt={8} w="100%" h="100%">
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { Heading, Box, Text, VStack, Center } from "@chakra-ui/react";
|
import { Heading, Box, Text, VStack, Center } from "@chakra-ui/react";
|
||||||
const Page403 = ({ location }) => (
|
const Page403 = ({ location }) => (
|
||||||
<Box pt={8} w="100%" h="100%">
|
<Box pt={8} w="100%" h="100%">
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import propTypes from "prop-types";
|
import propTypes from "prop-types";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
|
import React from "react";
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import propTypes from "prop-types";
|
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 (
|
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>
|
<RouterLink href="/" passHref>
|
||||||
<Link>
|
<Link>
|
||||||
<Image
|
<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 */
|
/** @jsx jsx */
|
||||||
import { jsx } from "@emotion/react";
|
import { jsx } from "@emotion/react";
|
||||||
import { Flex } from "@chakra-ui/react";
|
import { Flex } from "@chakra-ui/react";
|
||||||
import CustomIcon from "../CustomIcon"
|
import CustomIcon from "../CustomIcon";
|
||||||
import styles from "./styles";
|
import styles from "./styles";
|
||||||
|
|
||||||
const Modal = ({ children, onClose }) => (
|
const Modal = ({ children, onClose }) => (
|
||||||
|
|
|
@ -9,11 +9,11 @@ const SignIn = React.lazy(() => import("./SignIn"));
|
||||||
const SignUp = React.lazy(() => import("./SignUp"));
|
const SignUp = React.lazy(() => import("./SignUp"));
|
||||||
const LandingNavbar = React.lazy(() => import("./LandingNavbar"));
|
const LandingNavbar = React.lazy(() => import("./LandingNavbar"));
|
||||||
const AppNavbar = React.lazy(() => import("./AppNavbar"));
|
const AppNavbar = React.lazy(() => import("./AppNavbar"));
|
||||||
|
const HubspotForm = React.lazy(() => import("./HubspotForm"));
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const { modal, toggleModal, isAppView, isLoggedIn } = useContext(UIContext);
|
const { modal, toggleModal, isAppView, isLoggedIn } = useContext(UIContext);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
boxShadow={["sm", "md"]}
|
boxShadow={["sm", "md"]}
|
||||||
|
@ -23,7 +23,7 @@ const Navbar = () => {
|
||||||
// overflow="initial"
|
// overflow="initial"
|
||||||
bgColor="primary.1200"
|
bgColor="primary.1200"
|
||||||
// flexWrap="wrap"
|
// flexWrap="wrap"
|
||||||
direction={["column", "row", "row", null, "row"]}
|
direction={["row", "row", "row", null, "row"]}
|
||||||
// zIndex={100}
|
// zIndex={100}
|
||||||
w="100%"
|
w="100%"
|
||||||
minW="100%"
|
minW="100%"
|
||||||
|
@ -33,11 +33,29 @@ const Navbar = () => {
|
||||||
>
|
>
|
||||||
<Suspense fallback={""}>
|
<Suspense fallback={""}>
|
||||||
{modal === "register" && <SignUp toggleModal={toggleModal} />}
|
{modal === "register" && <SignUp toggleModal={toggleModal} />}
|
||||||
|
|
||||||
{modal === "login" && <SignIn toggleModal={toggleModal} />}
|
{modal === "login" && <SignIn toggleModal={toggleModal} />}
|
||||||
|
|
||||||
{modal === "forgot" && <ForgotPassword 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) && <LandingNavbar />}
|
||||||
{isAppView && isLoggedIn && <AppNavbar />}
|
{isAppView && isLoggedIn && <AppNavbar />}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
@ -22,7 +22,7 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
|
||||||
const { typesCache, createSubscription } = useSubscriptions();
|
const { typesCache, createSubscription } = useSubscriptions();
|
||||||
const { handleSubmit, errors, register } = useForm();
|
const { handleSubmit, errors, register } = useForm();
|
||||||
const [radioState, setRadioState] = useState("ethereum_blockchain");
|
const [radioState, setRadioState] = useState("ethereum_blockchain");
|
||||||
let { getRootProps, getRadioProps, ref } = useRadioGroup({
|
let { getRootProps, getRadioProps } = useRadioGroup({
|
||||||
name: "type",
|
name: "type",
|
||||||
defaultValue: radioState,
|
defaultValue: radioState,
|
||||||
onChange: setRadioState,
|
onChange: setRadioState,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { InputGroup, InputRightElement, Input } from "@chakra-ui/react";
|
import { InputGroup, InputRightElement, Input } from "@chakra-ui/react";
|
||||||
import CustomIcon from "./CustomIcon"
|
import CustomIcon from "./CustomIcon";
|
||||||
|
|
||||||
const PasswordInput = ({ placeholder, name }, ref) => {
|
const PasswordInput = ({ placeholder, name }, ref) => {
|
||||||
const [showPassword, togglePassword] = useState(false);
|
const [showPassword, togglePassword] = useState(false);
|
||||||
|
|
|
@ -8,7 +8,7 @@ const RadioCard = (props) => {
|
||||||
const checkbox = getCheckboxProps();
|
const checkbox = getCheckboxProps();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex as="label" h="fill-availible" onClick={() => console.log('hello2')}>
|
<Flex as="label" h="fill-availible">
|
||||||
<input {...input} />
|
<input {...input} />
|
||||||
<Box
|
<Box
|
||||||
justifyContent="left"
|
justifyContent="left"
|
||||||
|
|
|
@ -1,19 +1,44 @@
|
||||||
import { Flex, Box } from "@chakra-ui/react";
|
import { Flex, Box } from "@chakra-ui/react";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { useRouter } from "../core/hooks";
|
import { useRouter, useAnalytics } from "../core/hooks";
|
||||||
const Scrollable = (props) => {
|
const Scrollable = (props) => {
|
||||||
const scrollerRef = useRef();
|
const scrollerRef = useRef();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [path, setPath] = useState();
|
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(() => {
|
useEffect(() => {
|
||||||
setPath(router.nextRouter.pathname);
|
setPath(router.nextRouter.pathname);
|
||||||
}, [router.nextRouter.pathname]);
|
}, [router.nextRouter.pathname]);
|
||||||
|
|
||||||
scrollerRef?.current?.scrollTo({
|
useEffect(() => {
|
||||||
top: 0,
|
scrollerRef?.current?.scrollTo({
|
||||||
left: 0,
|
top: 0,
|
||||||
behavior: path === router.nextRouter.pathname ? "smooth" : "auto",
|
left: 0,
|
||||||
});
|
behavior: path === router.nextRouter.pathname ? "smooth" : "auto",
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [path]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
@ -28,6 +53,7 @@ const Scrollable = (props) => {
|
||||||
direction="column"
|
direction="column"
|
||||||
ref={scrollerRef}
|
ref={scrollerRef}
|
||||||
overflowY="scroll"
|
overflowY="scroll"
|
||||||
|
onScroll={(e) => handleScroll(e)}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Box>
|
</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,
|
Input,
|
||||||
InputRightElement,
|
InputRightElement,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import CustomIcon from "./CustomIcon"
|
import CustomIcon from "./CustomIcon";
|
||||||
import { useLogin } from "../core/hooks";
|
import { useLogin } from "../core/hooks";
|
||||||
import PasswordInput from "./PasswordInput";
|
import PasswordInput from "./PasswordInput";
|
||||||
import Modal from "./Modal";
|
import Modal from "./Modal";
|
||||||
|
@ -51,7 +51,7 @@ const SignIn = ({ toggleModal }) => {
|
||||||
colorScheme="primary"
|
colorScheme="primary"
|
||||||
placeholder="Your Bugout username"
|
placeholder="Your Bugout username"
|
||||||
name="username"
|
name="username"
|
||||||
{...register('username', { required: true })}
|
{...register("username", { required: true })}
|
||||||
ref={register({ required: "Username is required!" })}
|
ref={register({ required: "Username is required!" })}
|
||||||
/>
|
/>
|
||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
|
|
|
@ -26,11 +26,11 @@ const SignUp = ({ toggleModal }) => {
|
||||||
const { signUp, isLoading, isSuccess } = useSignUp();
|
const { signUp, isLoading, isSuccess } = useSignUp();
|
||||||
const ui = useContext(UIContext);
|
const ui = useContext(UIContext);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
ui.toggleModal(null);
|
ui.toggleModal(null);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
}, [isSuccess, toggleModal]);
|
}, [isSuccess, toggleModal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -14,15 +14,10 @@ import {
|
||||||
useBreakpointValue,
|
useBreakpointValue,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
// import Xarrow, { useXarrow } from "react-xarrows";
|
// import Xarrow, { useXarrow } from "react-xarrows";
|
||||||
import React, { useContext, useEffect } from "react";
|
import React, { useContext } from "react";
|
||||||
import UIContext from "../core/providers/UIProvider/context";
|
import UIContext from "../core/providers/UIProvider/context";
|
||||||
|
|
||||||
const Feature = ({ text, icon, iconBg, bullets }) => {
|
const Feature = ({ text, icon, iconBg, bullets }) => {
|
||||||
// const updateXarrow = useXarrow();
|
|
||||||
useEffect(() => {
|
|
||||||
// updateXarrow();
|
|
||||||
}, []);
|
|
||||||
console.log("bullets;", bullets);
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column">
|
<Flex direction="column">
|
||||||
<Stack direction={"row"} align={"center"}>
|
<Stack direction={"row"} align={"center"}>
|
||||||
|
@ -83,11 +78,6 @@ const SplitWithImage = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const ui = useContext(UIContext);
|
const ui = useContext(UIContext);
|
||||||
// const updateXarrow = useXarrow();
|
|
||||||
const iconBgColor = useColorModeValue(
|
|
||||||
`${colorScheme}.100`,
|
|
||||||
`${colorScheme}.900`
|
|
||||||
);
|
|
||||||
|
|
||||||
const [isVisible, setVisible] = React.useState(true);
|
const [isVisible, setVisible] = React.useState(true);
|
||||||
const domRef = React.useRef();
|
const domRef = React.useRef();
|
||||||
|
@ -106,7 +96,6 @@ const SplitWithImage = ({
|
||||||
py={0}
|
py={0}
|
||||||
className={`fade-in-section ${isVisible ? "is-visible" : ""}`}
|
className={`fade-in-section ${isVisible ? "is-visible" : ""}`}
|
||||||
ref={domRef}
|
ref={domRef}
|
||||||
// onAnimationIteration={() => updateXarrow()}
|
|
||||||
>
|
>
|
||||||
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={[0, 0, 10, null, 10]}>
|
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={[0, 0, 10, null, 10]}>
|
||||||
{mirror && !ui.isMobileView && (
|
{mirror && !ui.isMobileView && (
|
||||||
|
@ -119,7 +108,7 @@ const SplitWithImage = ({
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4} justifyContent="center">
|
||||||
<Text
|
<Text
|
||||||
id={`MoonBadge ${elementName}`}
|
id={`MoonBadge ${elementName}`}
|
||||||
// id={`MoonBadge${elementName}`}
|
// id={`MoonBadge${elementName}`}
|
||||||
|
@ -134,17 +123,6 @@ const SplitWithImage = ({
|
||||||
>
|
>
|
||||||
{badge}
|
{badge}
|
||||||
</Text>
|
</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>
|
<Heading>{title}</Heading>
|
||||||
<Text color={`primary.500`} fontSize={"lg"}>
|
<Text color={`primary.500`} fontSize={"lg"}>
|
||||||
{body}
|
{body}
|
||||||
|
@ -158,7 +136,6 @@ const SplitWithImage = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{bullets?.map((bullet, idx) => {
|
{bullets?.map((bullet, idx) => {
|
||||||
console.log("bullet1", bullet?.bullets);
|
|
||||||
return (
|
return (
|
||||||
<Feature
|
<Feature
|
||||||
key={`splitWImageBullet-${idx}-${title}`}
|
key={`splitWImageBullet-${idx}-${title}`}
|
||||||
|
@ -177,23 +154,24 @@ const SplitWithImage = ({
|
||||||
colorScheme={colorScheme}
|
colorScheme={colorScheme}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
mt={[0, 0, null, 16]}
|
mt={[0, 0, null, 16]}
|
||||||
textTransform={"uppercase"}
|
|
||||||
fontSize={["xs", "sm", "lg", null, "lg"]}
|
fontSize={["xs", "sm", "lg", null, "lg"]}
|
||||||
size={buttonSize}
|
size={buttonSize}
|
||||||
|
onClick={cta.onClick}
|
||||||
>
|
>
|
||||||
{cta}
|
{cta.label}
|
||||||
</Button>
|
</Button>
|
||||||
</Center>
|
</Center>
|
||||||
</Container>
|
</Container>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
{(!mirror || ui.isMobileView) && (
|
{(!mirror || ui.isMobileView) && (
|
||||||
<Flex>
|
<Flex justifyContent="center">
|
||||||
<Image
|
<Image
|
||||||
rounded={"md"}
|
rounded={"md"}
|
||||||
alt={"feature image"}
|
alt={"feature image"}
|
||||||
src={imgURL}
|
src={imgURL}
|
||||||
objectFit={"cover"}
|
objectFit={"contain"}
|
||||||
|
// boxSize={ui.isMobileView ? "lg" : null}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</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 { useContext } from "react";
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
const useAnalytics = () => {
|
const useAnalytics = () => {
|
||||||
const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } = useContext(
|
const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } =
|
||||||
AnalyticsContext
|
useContext(AnalyticsContext);
|
||||||
);
|
|
||||||
const [trackProps, setTrackProps] = useState({
|
const [trackProps, setTrackProps] = useState({
|
||||||
event: null,
|
event: null,
|
||||||
props: null,
|
props: null,
|
||||||
|
|
|
@ -8,7 +8,11 @@ const useGroup = (groupId) => {
|
||||||
const cache = useQueryCache();
|
const cache = useQueryCache();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const { data: GroupUsersResponse, isLoading, refetch: getUsers } = useQuery(
|
const {
|
||||||
|
data: GroupUsersResponse,
|
||||||
|
isLoading,
|
||||||
|
refetch: getUsers,
|
||||||
|
} = useQuery(
|
||||||
["group-users", groupId],
|
["group-users", groupId],
|
||||||
GroupService.getGroupUsers,
|
GroupService.getGroupUsers,
|
||||||
queryCacheProps
|
queryCacheProps
|
||||||
|
|
|
@ -15,11 +15,11 @@ const useGroups = () => {
|
||||||
return response?.data?.groups;
|
return response?.data?.groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, isLoading, refetch: getGroups } = useQuery(
|
const {
|
||||||
"groups",
|
data,
|
||||||
fetchGroups,
|
isLoading,
|
||||||
queryCacheProps
|
refetch: getGroups,
|
||||||
);
|
} = useQuery("groups", fetchGroups, queryCacheProps);
|
||||||
|
|
||||||
const [createGroup, createStatus] = useMutation(
|
const [createGroup, createStatus] = useMutation(
|
||||||
(groupName) => GroupService.createGroup(groupName),
|
(groupName) => GroupService.createGroup(groupName),
|
||||||
|
|
|
@ -158,10 +158,6 @@ const useJournalPermissions = (journalId, journalScope) => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const holders = data;
|
const holders = data;
|
||||||
return {
|
return {
|
||||||
holders,
|
holders,
|
||||||
|
|
|
@ -36,10 +36,12 @@ const useLogin = (loginType) => {
|
||||||
getUser();
|
getUser();
|
||||||
if (analytics.isLoaded) {
|
if (analytics.isLoaded) {
|
||||||
analytics.mixpanel.people.set_once({
|
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.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.track(
|
||||||
`${analytics.MIXPANEL_EVENTS.USER_LOGS_IN}`,
|
`${analytics.MIXPANEL_EVENTS.USER_LOGS_IN}`,
|
||||||
|
|
|
@ -8,7 +8,7 @@ const useLogout = () => {
|
||||||
const { setLoggingOut } = useContext(UIContext);
|
const { setLoggingOut } = useContext(UIContext);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const analytics = useAnalytics();
|
const analytics = useAnalytics();
|
||||||
const {mutate: revoke, data } = useMutation(AuthService.revoke, {
|
const { mutate: revoke, data } = useMutation(AuthService.revoke, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
if (analytics.isLoaded) {
|
if (analytics.isLoaded) {
|
||||||
analytics.mixpanel.track(
|
analytics.mixpanel.track(
|
||||||
|
|
|
@ -15,7 +15,7 @@ const useSignUp = (source) => {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
data,
|
data,
|
||||||
isSuccess
|
isSuccess,
|
||||||
} = useMutation(AuthService.register(), {
|
} = useMutation(AuthService.register(), {
|
||||||
onSuccess: (response) => {
|
onSuccess: (response) => {
|
||||||
localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token);
|
localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token);
|
||||||
|
|
|
@ -18,13 +18,6 @@ const useJournalEntries = ({
|
||||||
pageParam = 0;
|
pageParam = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchTags = searchTerm.split(" ").filter(function (n) {
|
|
||||||
if (n.startsWith("#")) return n;
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await SubscriptionsService.getStream({
|
const response = await SubscriptionsService.getStream({
|
||||||
searchTerm,
|
searchTerm,
|
||||||
isContent,
|
isContent,
|
||||||
|
@ -58,8 +51,7 @@ const useJournalEntries = ({
|
||||||
getNextPageParam: (lastGroup) => {
|
getNextPageParam: (lastGroup) => {
|
||||||
return lastGroup.next_offset === null ? false : lastGroup.next_offset;
|
return lastGroup.next_offset === null ? false : lastGroup.next_offset;
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
onSuccess: () => {},
|
||||||
},
|
|
||||||
enabled: !!enabled,
|
enabled: !!enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,22 +9,6 @@ const useSubscriptions = () => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const stripe = useStripe();
|
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 getSubscriptions = async () => {
|
||||||
const response = await SubscriptionsService.getSubscriptions();
|
const response = await SubscriptionsService.getSubscriptions();
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
|
@ -68,19 +52,28 @@ const useSubscriptions = () => {
|
||||||
|
|
||||||
const changeNote = useMutation(SubscriptionsService.modifySubscription(), {
|
const changeNote = useMutation(SubscriptionsService.modifySubscription(), {
|
||||||
onError: (error) => toast(error, "error"),
|
onError: (error) => toast(error, "error"),
|
||||||
onSuccess: (response) => {
|
onSuccess: () => {
|
||||||
subscriptionsCache.refetch();
|
subscriptionsCache.refetch();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const deleteSubscription = useMutation(SubscriptionsService.deleteSubscription(), {
|
const deleteSubscription = useMutation(
|
||||||
onError: (error) => toast(error, "error"),
|
SubscriptionsService.deleteSubscription(),
|
||||||
onSuccess: (response) => {
|
{
|
||||||
subscriptionsCache.refetch();
|
onError: (error) => toast(error, "error"),
|
||||||
},
|
onSuccess: () => {
|
||||||
});
|
subscriptionsCache.refetch();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return { createSubscription, subscriptionsCache, typesCache, changeNote, deleteSubscription };
|
return {
|
||||||
|
createSubscription,
|
||||||
|
subscriptionsCache,
|
||||||
|
typesCache,
|
||||||
|
changeNote,
|
||||||
|
deleteSubscription,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useSubscriptions;
|
export default useSubscriptions;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
|
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { useToast as useChakraToast, Box } from "@chakra-ui/react";
|
import { useToast as useChakraToast, Box } from "@chakra-ui/react";
|
||||||
import { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
import { useAnalytics } from ".";
|
import { useAnalytics } from ".";
|
||||||
|
|
||||||
const useToast = () => {
|
const useToast = () => {
|
||||||
|
|
|
@ -12,13 +12,14 @@ export const MIXPANEL_EVENTS = {
|
||||||
LAST_LOGIN_DATE: "Last login date",
|
LAST_LOGIN_DATE: "Last login date",
|
||||||
LAST_VISITED: "Last visited",
|
LAST_VISITED: "Last visited",
|
||||||
TOAST_ERROR_DISPLAYED: "Error Toast",
|
TOAST_ERROR_DISPLAYED: "Error Toast",
|
||||||
HOMEPAGE_SCROLL_DEPTH: "Homepage scroll depth",
|
SCROLL_DEPTH: "Homepage scroll depth",
|
||||||
CONVERT_TO_USER: "User Signs up",
|
CONVERT_TO_USER: "User Signs up",
|
||||||
USER_LOGS_IN: "User Logs in",
|
USER_LOGS_IN: "User Logs in",
|
||||||
USER_LOGS_OUT: "User Logs out",
|
USER_LOGS_OUT: "User Logs out",
|
||||||
PAGEVIEW: "Page view",
|
PAGEVIEW: "Page view",
|
||||||
PRICING_PLAN_CLICKED: "Pricing Plan clicked",
|
PRICING_PLAN_CLICKED: "Pricing Plan clicked",
|
||||||
BUTTON_CLICKED: "Button clicked",
|
BUTTON_CLICKED: "Button clicked",
|
||||||
|
LEFT_PAGE: "Left page",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MIXPANEL_EVENTS;
|
export default MIXPANEL_EVENTS;
|
||||||
|
|
|
@ -12,6 +12,37 @@ const AnalyticsProvider = ({ children }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
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 &&
|
isLoaded &&
|
||||||
mixpanel.track(MIXPANEL_EVENTS.PAGEVIEW, {
|
mixpanel.track(MIXPANEL_EVENTS.PAGEVIEW, {
|
||||||
url: router.nextRouter.pathname,
|
url: router.nextRouter.pathname,
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { http } from "../utils";
|
||||||
const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
||||||
|
|
||||||
export const login = ({ username, password }) => {
|
export const login = ({ username, password }) => {
|
||||||
console.log('login',username, password)
|
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
data.append("username", username);
|
data.append("username", username);
|
||||||
data.append("password", password);
|
data.append("password", password);
|
||||||
|
@ -22,24 +21,26 @@ export const revoke = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const register = () => ({ username, email, password }) => {
|
export const register =
|
||||||
const data = new FormData();
|
() =>
|
||||||
data.append("username", username);
|
({ username, email, password }) => {
|
||||||
data.append("email", email);
|
const data = new FormData();
|
||||||
data.append("password", password);
|
data.append("username", username);
|
||||||
|
data.append("email", email);
|
||||||
|
data.append("password", password);
|
||||||
|
|
||||||
return http({
|
return http({
|
||||||
method: "POST",
|
|
||||||
url: `${AUTH_URL}/user`,
|
|
||||||
data,
|
|
||||||
}).then(() =>
|
|
||||||
http({
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${AUTH_URL}/token`,
|
url: `${AUTH_URL}/user`,
|
||||||
data,
|
data,
|
||||||
})
|
}).then(() =>
|
||||||
);
|
http({
|
||||||
};
|
method: "POST",
|
||||||
|
url: `${AUTH_URL}/token`,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const verify = ({ code }) => {
|
export const verify = ({ code }) => {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
|
|
@ -50,20 +50,19 @@ export const getTokens = (humbugId) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createRestrictedToken = (humbugId) => ({
|
export const createRestrictedToken =
|
||||||
appName,
|
(humbugId) =>
|
||||||
appVersion,
|
({ appName, appVersion }) => {
|
||||||
}) => {
|
const data = new FormData();
|
||||||
const data = new FormData();
|
data.append("app_name", appName);
|
||||||
data.append("app_name", appName);
|
data.append("app_version", appVersion);
|
||||||
data.append("app_version", appVersion);
|
|
||||||
|
|
||||||
return http({
|
return http({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${API}/humbug/${humbugId}/tokens`,
|
url: `${API}/humbug/${humbugId}/tokens`,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteRestrictedToken = (humbugId) => (tokenId) => {
|
export const deleteRestrictedToken = (humbugId) => (tokenId) => {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
|
|
@ -62,35 +62,31 @@ export const getJournalsScopes = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setJournalPermission = (journalId) => ({
|
export const setJournalPermission =
|
||||||
holder_type,
|
(journalId) =>
|
||||||
holder_id,
|
({ holder_type, holder_id, permission_list }) => {
|
||||||
permission_list,
|
const data = new FormData();
|
||||||
}) => {
|
data.append("holder_type", holder_type);
|
||||||
const data = new FormData();
|
data.append("holder_id", holder_id);
|
||||||
data.append("holder_type", holder_type);
|
data.append("permission_list", permission_list);
|
||||||
data.append("holder_id", holder_id);
|
|
||||||
data.append("permission_list", permission_list);
|
|
||||||
|
|
||||||
return http({
|
return http({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${API}/journals/${journalId}/scopes`,
|
url: `${API}/journals/${journalId}/scopes`,
|
||||||
data: { holder_type, holder_id, permission_list },
|
data: { holder_type, holder_id, permission_list },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteJournalPermission = (journalId) => ({
|
export const deleteJournalPermission =
|
||||||
holder_type,
|
(journalId) =>
|
||||||
holder_id,
|
({ holder_type, holder_id, permission_list }) => {
|
||||||
permission_list,
|
return http({
|
||||||
}) => {
|
method: "DELETE",
|
||||||
return http({
|
url: `${API}/journals/${journalId}/scopes`,
|
||||||
method: "DELETE",
|
data: { holder_type, holder_id, permission_list },
|
||||||
url: `${API}/journals/${journalId}/scopes`,
|
// permission_list: ["read"]
|
||||||
data: { holder_type, holder_id, permission_list },
|
});
|
||||||
// permission_list: ["read"]
|
};
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getPublicJournals = () =>
|
export const getPublicJournals = () =>
|
||||||
http({
|
http({
|
||||||
|
@ -98,32 +94,30 @@ export const getPublicJournals = () =>
|
||||||
url: `${API}/public/`,
|
url: `${API}/public/`,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const searchEntries = ({ journalId }) => ({
|
export const searchEntries =
|
||||||
searchTerm,
|
({ journalId }) =>
|
||||||
limit,
|
({ searchTerm, limit, offset, isContent, journalType }) => {
|
||||||
offset,
|
const journalScope = journalType === "personal" ? "journals" : "public";
|
||||||
isContent,
|
return http({
|
||||||
journalType,
|
method: "GET",
|
||||||
}) => {
|
url: `${API}/${journalScope}/${journalId}/search`,
|
||||||
const journalScope = journalType === "personal" ? "journals" : "public";
|
params: {
|
||||||
return http({
|
// filters: searchTags,
|
||||||
method: "GET",
|
q: searchTerm,
|
||||||
url: `${API}/${journalScope}/${journalId}/search`,
|
limit: encodeURIComponent(limit),
|
||||||
params: {
|
offset: encodeURIComponent(offset),
|
||||||
// filters: searchTags,
|
content: encodeURIComponent(isContent),
|
||||||
q: searchTerm,
|
},
|
||||||
limit: encodeURIComponent(limit),
|
});
|
||||||
offset: encodeURIComponent(offset),
|
};
|
||||||
content: encodeURIComponent(isContent),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const publicSearchEntries = ({ journalId }) => (query) =>
|
export const publicSearchEntries =
|
||||||
http({
|
({ journalId }) =>
|
||||||
method: "GET",
|
(query) =>
|
||||||
url: `${API}/public/${journalId}/search?q=${query}`,
|
http({
|
||||||
});
|
method: "GET",
|
||||||
|
url: `${API}/public/${journalId}/search?q=${query}`,
|
||||||
|
});
|
||||||
|
|
||||||
export const getPublicJournal = (key, { journalId }) =>
|
export const getPublicJournal = (key, { journalId }) =>
|
||||||
http({
|
http({
|
||||||
|
@ -131,9 +125,11 @@ export const getPublicJournal = (key, { journalId }) =>
|
||||||
url: `${API}/public/${journalId}`,
|
url: `${API}/public/${journalId}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getJournalStats = (key, { journalId }) => () =>
|
export const getJournalStats =
|
||||||
http({
|
(key, { journalId }) =>
|
||||||
method: "GET",
|
() =>
|
||||||
url: `${API}/journals/${journalId}/stats`,
|
http({
|
||||||
params: { stats_version: 5 },
|
method: "GET",
|
||||||
});
|
url: `${API}/journals/${journalId}/stats`,
|
||||||
|
params: { stats_version: 5 },
|
||||||
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
const MOCK_API = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
const MOCK_API = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
||||||
var MockAdapter = require("axios-mock-adapter");
|
var MockAdapter = require("axios-mock-adapter");
|
||||||
const makeid = (length) => {
|
export const makeid = (length) => {
|
||||||
var result = "";
|
var result = "";
|
||||||
var characters =
|
var characters =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
@ -12,7 +12,7 @@ const makeid = (length) => {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const makenum = (length) => {
|
export const makenum = (length) => {
|
||||||
var result = "";
|
var result = "";
|
||||||
var characters = "0123456789";
|
var characters = "0123456789";
|
||||||
var charactersLength = characters.length;
|
var charactersLength = characters.length;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "@emotion/react";
|
import React from "react";
|
||||||
import { Box } from "@chakra-ui/react";
|
import { Box } from "@chakra-ui/react";
|
||||||
import { getLayout as getSiteLayout } from "./AppLayout";
|
import { getLayout as getSiteLayout } from "./AppLayout";
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { Flex } from "@chakra-ui/react";
|
import { Flex } from "@chakra-ui/react";
|
||||||
import { getLayout as getSiteLayout } from "./RootLayout";
|
import { getLayout as getSiteLayout } from "./RootLayout";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React from "@emotion/react";
|
import React from "react";
|
||||||
import { Scrollable, Footer } from "../components";
|
import { Scrollable, Footer } from "../components";
|
||||||
import { getLayout as getSiteLayout } from "./index";
|
import { getLayout as getSiteLayout } from "./index";
|
||||||
|
|
||||||
const DefaultLayout = (props) => {
|
const DefaultLayout = (props) => {
|
||||||
return (
|
return (
|
||||||
<Scrollable>
|
<Scrollable bgImg={""}>
|
||||||
{props.children}
|
{props.children}
|
||||||
<Footer />
|
<Footer />
|
||||||
</Scrollable>
|
</Scrollable>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { jsx } from "@emotion/react";
|
|
||||||
import { Flex, Spinner } from "@chakra-ui/react";
|
import { Flex, Spinner } from "@chakra-ui/react";
|
||||||
import React, { Suspense, useContext, useState, useEffect } from "react";
|
import React, { Suspense, useContext, useState, useEffect } from "react";
|
||||||
const Sidebar = React.lazy(() => import("../components/Sidebar"));
|
const Sidebar = React.lazy(() => import("../components/Sidebar"));
|
||||||
|
|
Ładowanie…
Reference in New Issue