Merge branch 'v0' of github.com:peersky/moonstock into v0

pull/20/head
Andrey Dolgolev 2021-07-27 20:02:21 +03:00
commit 77a1f5a321
30 zmienionych plików z 1014 dodań i 1799 usunięć

BIN
.DS_Store vendored

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -1,4 +0,0 @@
{
"editor.formatOnSave": true,
"eslint.format.enable": true
}

Wyświetl plik

@ -0,0 +1,249 @@
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;

Wyświetl plik

@ -1,96 +0,0 @@
import { jsx } from "@emotion/react";
import { useEffect, useRef, Fragment } from "react";
import {
FormControl,
FormErrorMessage,
InputGroup,
Input,
Select,
Td,
Tr,
} from "@chakra-ui/react";
import { CloseIcon } from "@chakra-ui/icons";
import IconButton from "./IconButton";
const AddUserForm = ({ isOpen, toggleSelf, errors, register }) => {
const inputRef = useRef(null);
useEffect(() => {
if (isOpen) {
//without timeout input is not catching focus on chrome and firefox..
//probably because it is hidden within accordion
setTimeout(() => {
inputRef.current.focus();
}, 100);
}
}, [inputRef, isOpen]);
return (
<Fragment>
{isOpen && (
<Tr transition="0.3s" _hover={{ bg: "white.200" }}>
<Td></Td>
<Td>
<FormControl isInvalid={errors.email}>
<InputGroup>
<Input
fontSize="sm"
border="none"
width="60%"
height="fit-content"
placeholder="email"
name="email"
ref={(e) => {
register(e, { required: "email is required" });
inputRef.current = e;
}}
/>
</InputGroup>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.email && errors.email.message}
</FormErrorMessage>
</FormControl>
</Td>
<Td>
<FormControl isInvalid={errors.role}>
<Select
_focus={{ outline: "solid 1px", outlineColor: "primary.500" }}
fontSize="sm"
border="none"
placeholder="Select role"
name="role"
width="200px"
height="fit-content"
bgColor="white.200"
ref={(e) => {
register(e, {
required: "Role is required",
});
}}
>
<option>member</option>
{/* <option>admin</option> */}
<option>owner</option>
</Select>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.role && errors.role.message}
</FormErrorMessage>
</FormControl>
</Td>
<Td>
<IconButton type="submit" />
<IconButton
onClick={() => toggleSelf(false)}
icon={<CloseIcon />}
/>
</Td>
</Tr>
)}
</Fragment>
);
};
export default AddUserForm;

Wyświetl plik

@ -1,52 +1,90 @@
import React, { useRef, useEffect, useContext } from "react";
import React, { useRef, useEffect, useContext, useState } from "react";
import {
Flex,
Spinner,
Button,
Center,
Text,
Tabs,
TabList,
TabPanels,
Tab,
TabPanel,
Heading,
Menu,
MenuButton,
MenuList,
MenuItem,
MenuGroup,
IconButton,
Input,
Select,
Drawer,
DrawerBody,
DrawerFooter,
DrawerHeader,
DrawerOverlay,
DrawerContent,
DrawerCloseButton,
useDisclosure,
Tag,
TagLabel,
TagCloseButton,
Spacer,
} from "@chakra-ui/react";
import { useJournalEntries, useJournalPermissions } from "../core/hooks";
import EntryList from "./EntryList";
import { useSubscriptions } from "../core/hooks";
import StreamEntry from "./StreamEntry";
import UIContext from "../core/providers/UIProvider/context";
import HubspotForm from "react-hubspot-form";
import { FaFilter } from "react-icons/fa";
import useStream from "../core/hooks/useStream";
import { ImCancelCircle } from "react-icons/im";
const pageSize = 25;
const isContent = false;
const FILTER_TYPES = {
ADDRESS: 0,
GAS: 1,
GAS_PRICE: 2,
AMMOUNT: 3,
HASH: 4,
DISABLED: 99,
};
const DIRECTIONS = { SOURCE: 0, DESTINATION: 1 };
const CONDITION = {
EQUAL: 0,
CONTAINS: 1,
LESS: 2,
LESS_EQUAL: 3,
GREATER: 4,
GREATER_EQUAL: 5,
NOT_EQUAL: 6,
};
const EntriesNavigation = () => {
const ui = useContext(UIContext);
const { isOpen, onOpen, onClose } = useDisclosure();
const { subscriptionsCache } = useSubscriptions();
const [newFilterState, _setNewFilterState] = useState([
{
type: FILTER_TYPES.ADDRESS,
direction: DIRECTIONS.SOURCE,
condition: CONDITION.EQUAL,
value: null,
},
]);
const [filterState, setFilterState] = useState([]);
const { currentUserPermissions: permissions } = useJournalPermissions(
`9b0d7567-4634-4bf7-946d-60ef4414aa93`,
`personal`
);
const setNewFilterState = (props) => {
console.log(
"setNewFilterState",
props,
subscriptionsCache.data.subscriptions[0].id
);
_setNewFilterState(props);
};
const loadMoreButtonRef = useRef(null);
const journalId = `9b0d7567-4634-4bf7-946d-60ef4414aa93`;
const appScope = `personal`;
const {
fetchMore,
isFetchingMore,
canFetchMore,
refetch,
EntriesPages,
isLoading,
setSearchTerm,
} = useJournalEntries({
journalId,
journalType: appScope,
pageSize,
isContent,
searchQuery: ui.searchTerm,
});
const { fetchMore, isFetchingMore, canFetchMore, EntriesPages, isLoading } =
useStream({
pageSize,
refreshRate: 1500,
searchQuery: ui.searchTerm,
enabled: true,
isContent: false,
});
const handleScroll = ({ currentTarget }) => {
if (
@ -59,11 +97,22 @@ const EntriesNavigation = () => {
}
};
const setFilterProps = (filterIdx, props) => {
const newFilterProps = [...newFilterState];
newFilterProps[filterIdx] = { ...newFilterProps[filterIdx], ...props };
setNewFilterState(newFilterProps);
};
useEffect(() => {
if (journalId) {
refetch();
if (
subscriptionsCache.data?.subscriptions[0]?.id &&
newFilterState[0].value === null
) {
setFilterProps(0, {
value: subscriptionsCache.data.subscriptions[0].address,
});
}
}, [journalId, ui.searchTerm, refetch, setSearchTerm]);
}, [subscriptionsCache.isLoading]);
const entriesPagesData = EntriesPages
? EntriesPages.pages.map((page) => {
@ -72,13 +121,45 @@ const EntriesNavigation = () => {
: [""];
const entries = entriesPagesData.flat();
const canCreate = false;
const canCreate =
appScope !== "public" && permissions?.includes("journals.entries.create");
const canDelete = false;
const canDelete =
appScope !== "public" && permissions?.includes("journals.entries.delete");
const dropNewFilterArrayItem = (idx) => {
const newArray = [...newFilterState];
delete newArray[idx];
setNewFilterState(newArray);
};
const dropFilterArrayItem = (idx) => {
console.log("dropFilterArrayItem", idx, filterState);
const newArray = [...filterState];
newArray[idx].type = FILTER_TYPES.DISABLED;
setFilterState(newArray);
};
const handleFilterSubmit = () => {
setFilterState(newFilterState);
onClose();
};
const handleAddressChange = (idx) => (e) => {
setFilterProps(idx, { value: e.target.value });
};
const handleConditionChange = (idx) => (e) => {
console.log("handleConditionChange", idx, e.target.value);
setFilterProps(idx, { condition: parseInt(e.target.value) });
};
const handleFilterStateCallback = (props) => {
console.log("handleFilterStateCallback", props);
const newFilterState = [...filterState];
newFilterState.push({ ...props });
setFilterState(newFilterState);
};
if (subscriptionsCache.isLoading) return "";
console.log("filterstate test", filterState);
return (
<Flex
id="JournalNavigation"
@ -88,278 +169,223 @@ const EntriesNavigation = () => {
direction="column"
flexGrow={1}
>
<Tabs colorScheme="red" variant="solid" isLazy isFitted h="100%">
<TabList>
<Tab
fontWeight="600"
h="3rem"
transition="0.5s"
_hover={{ bg: "secondary.100" }}
bgColor="white.200"
_selected={{
color: "white",
bg: "secondary.900",
boxShadow: "lg",
}}
>
Live view
</Tab>
<Tab
fontWeight="600"
h="3rem"
transition="0.5s"
_hover={{ bg: "secondary.100" }}
bgColor="white.200"
_selected={{
color: "white",
bg: "secondary.900",
boxShadow: "lg",
}}
>
Analysis
</Tab>
</TabList>
<TabPanels px={0} h="calc(100% - 3rem)">
<TabPanel p={0} h="100%">
{entries && !isLoading ? (
<>
<Flex h="3rem" w="100%" bgColor="white.200">
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Status</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Source</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Alias</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Ammount</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Date</Text>
</Flex>
</Flex>
<Flex
className="ScrollableWrapper"
w="100%"
overflowY="hidden"
// maxH="100%"
h="calc(100% - 3rem)"
>
<Flex
className="Scrollable"
id="entryList"
// flexGrow={1}
overflowY="scroll"
direction="column"
height="100%"
w="100%"
onScroll={(e) => handleScroll(e)}
>
{entries.map((entry) => (
<EntryList
key={`entry-list-${entry.id}`}
entry={entry}
disableDelete={!canDelete}
disableCopy={!canCreate}
/>
))}
{canFetchMore && !isFetchingMore && (
<Center>
<Button
onClick={() => fetchMore()}
variant="outline"
colorScheme="suggested"
>
Load more entries
</Button>
</Center>
)}
{canFetchMore && isFetchingMore && (
<Center>
<Spinner
hidden={!isFetchingMore}
ref={loadMoreButtonRef}
my={8}
size="lg"
color="primary.500"
thickness="4px"
speed="1.5s"
{entries && !isLoading ? (
<>
<Drawer onClose={onClose} isOpen={isOpen} size="lg">
<DrawerOverlay />
<DrawerContent bgColor="gray.100">
<DrawerCloseButton />
<DrawerHeader>{`Filter results`}</DrawerHeader>
<DrawerBody>
<Text pt={2} fontWeight="600">
Source:
</Text>
{newFilterState.map((filter, idx) => {
if (filter.type === FILTER_TYPES.DISABLED) return "";
return (
<Flex
key={`subscription-filter-item-${idx}`}
direction="column"
>
<Flex
mt={4}
direction="row"
flexWrap="nowrap"
placeItems="center"
bgColor="gray.300"
borderRadius="md"
>
{filter.type === FILTER_TYPES.ADDRESS && (
<>
<Flex w="120px" placeContent="center">
{filter.direction === DIRECTIONS.SOURCE
? `From:`
: `To:`}
</Flex>
<Select
pr={2}
w="180px"
onChange={handleConditionChange(idx)}
>
<option value={CONDITION.EQUAL}>Is</option>
<option value={CONDITION.NOT_EQUAL}>
Is not
</option>
</Select>
{filter.direction === DIRECTIONS.SOURCE && (
<Select
variant="solid"
colorScheme="primary"
name="address"
onChange={handleAddressChange(idx)}
>
{!subscriptionsCache.isLoading &&
subscriptionsCache.data.subscriptions.map(
(subscription, idx) => {
return (
<option
value={subscription.address}
key={`subscription-filter-item-${idx}`}
>
{`${
subscription.label
} - ${subscription.address.slice(
0,
5
)}...${subscription.address.slice(
-3
)}`}
</option>
);
}
)}
</Select>
)}
{filter.direction === DIRECTIONS.DESTINATION && (
<Input
type="text"
onChange={(e) =>
setFilterProps(idx, {
value: e.target.value,
})
}
placeholder="Type in address"
/>
)}
</>
)}
<IconButton
placeItems="center"
colorScheme="primary"
variant="ghost"
onClick={() => dropNewFilterArrayItem(idx)}
icon={<ImCancelCircle />}
/>
</Center>
</Flex>
</Flex>
);
})}
<Menu>
<MenuButton
as={Button}
mt={4}
colorScheme="secondary"
variant="solid"
>
Add filter row
</MenuButton>
<MenuList>
<MenuGroup title="source"></MenuGroup>
<MenuItem
onClick={() =>
setNewFilterState([
...newFilterState,
{
type: FILTER_TYPES.ADDRESS,
direction: DIRECTIONS.SOURCE,
condition: CONDITION.EQUAL,
value: subscriptionsCache.data.subscriptions[0].id,
},
])
}
>
Source
</MenuItem>
<MenuItem
onClick={() =>
setNewFilterState([
...newFilterState,
{
type: FILTER_TYPES.ADDRESS,
direction: DIRECTIONS.DESTINATION,
condition: CONDITION.EQUAL,
value: null,
},
])
}
>
Destination
</MenuItem>
</MenuList>
</Menu>
</DrawerBody>
<DrawerFooter pb={16} placeContent="center">
<Button
colorScheme="suggested"
variant="solid"
// type="submit"
onClick={() => handleFilterSubmit()}
>
Apply selected filters
</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
<Flex h="3rem" w="100%" bgColor="gray.200" alignItems="center">
<Flex maxW="90%">
{filterState.map((filter, idx) => {
if (filter.type === FILTER_TYPES.DISABLED) return "";
return (
<Tag
key={`filter-badge-display-${idx}`}
mx={1}
size="lg"
variant="solid"
colorScheme="secondary"
>
{filter?.type === FILTER_TYPES.ADDRESS && (
<TagLabel>
{filter.condition === CONDITION.NOT_EQUAL && "Not "}
{filter.direction === DIRECTIONS.SOURCE
? "From: "
: "To: "}
{subscriptionsCache?.data?.subscriptions.find(
(subscription) =>
subscription.address === filter.value
)?.label ?? filter.value}
</TagLabel>
)}
</Flex>
</Flex>
</>
) : (
<Center>
<Spinner
mt="50%"
size="lg"
color="primary.500"
thickness="4px"
speed="1.5s"
/>
</Center>
)}
</TabPanel>
<TabPanel>
<Heading as="h1">This section is under construction</Heading>
<Heading as="h2" size="sm">Message us to tell your needs for this page</Heading>
<HubspotForm
portalId="8018701"
formId="b9b3da3d-f47d-41da-863c-eb8229c3bfc0"
loading={<Spinner colorScheme="primary" speed="1s" />}
/>
</TabPanel>
</TabPanels>
</Tabs>
</Flex>
);
};
export default EntriesNavigation;
{
/* {entries && !isLoading ? (
<Flex
className="ScrollableWrapper"
height="100%"
maxH="100%"
overflow="hidden"
direction="column"
flexGrow={1}
>
<Flex h="3rem">
<Button
isActive={mode === "live"}
colorScheme="secondary"
bgColor="white.100"
textColor="primary.900"
_active={{
bgColor: "secondary.900",
textColor: "white.100",
}}
_hover={{
textColor: "white.100",
bgColor: "secondary.600",
}}
m={0}
h="100%"
w="50%"
borderRadius="0"
onClick={() => setMode("live")}
>
Live view
</Button>
<Button
m={0}
isActive={mode == "analysis"}
_active={{
bgColor: "secondary.900",
textColor: "white.100",
}}
_hover={{
textColor: "white.100",
bgColor: "secondary.600",
}}
bgColor="white.100"
textColor="primary.900"
colorScheme="secondary"
h="100%"
w="50%"
onClick={() => setMode("analysis")}
borderRadius="0"
>
Analysis view
</Button>
</Flex>
<Flex h="3rem" w="100%" bgColor="white.200">
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Status</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Source</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Alias</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Ammount</Text>
</Flex>
<Flex
flexBasis="50px"
flexGrow={1}
justifyContent="center"
alignItems="center"
>
<Text fontWeight="600">Date</Text>
</Flex>
<TagCloseButton onClick={() => dropFilterArrayItem(idx)} />
</Tag>
);
})}
</Flex>
<Spacer />
<IconButton
mr={4}
onClick={onOpen}
colorScheme="primary"
variant="ghost"
icon={<FaFilter />}
/>
</Flex>
<Flex
className="ScrollableWrapper"
w="100%"
overflowY="hidden"
// maxH="100%"
h="calc(100% - 3rem)"
>
<Flex
className="Scrollable"
id="entryList"
id="StreamEntry"
// flexGrow={1}
overflowY="scroll"
direction="column"
height="100%"
w="100%"
onScroll={(e) => handleScroll(e)}
>
{entries.map((entry) => (
<EntryList
key={`entry-list-${entry.id}`}
{entries.map((entry, idx) => (
<StreamEntry
key={`entry-list-${idx}`}
entry={entry}
disableDelete={!canDelete}
disableCopy={!canCreate}
filterCallback={handleFilterStateCallback}
filterConstants={{ DIRECTIONS, CONDITION, FILTER_TYPES }}
/>
))}
{canFetchMore && !isFetchingMore && (
@ -387,10 +413,8 @@ export default EntriesNavigation;
</Center>
)}
</Flex>
{/* {mode === "analysis" && <Flex>tell us morex</Flex>}
<Fade in={mode === "analysis"}> tell me moar</Fade>
</Flex>
</Flex>
</>
) : (
<Center>
<Spinner
@ -401,5 +425,9 @@ export default EntriesNavigation;
speed="1.5s"
/>
</Center>
)} */
}
)}
</Flex>
);
};
export default EntriesNavigation;

Wyświetl plik

@ -1,22 +0,0 @@
import { jsx } from "@emotion/react";
import { Box } from "@chakra-ui/react";
const EntryCard = (props) => {
const background = props.isActive ? "secondary.500" : "transparent";
return (
<Box
py={2}
px={6}
borderTop="1px"
borderColor="white.300"
bg={background}
transition="0.1s"
_hover={props.isActive ? null : { bg: "secondary.200" }}
>
{props.children}
</Box>
);
};
export default EntryCard;

Wyświetl plik

@ -1,53 +0,0 @@
import React, { useContext } from "react";
import { Flex, Heading, Text, IconButton } from "@chakra-ui/react";
import moment from "moment";
import { ViewIcon } from "@chakra-ui/icons";
import { useRouter } from "../core/hooks";
import UIContext from "../core/providers/UIProvider/context";
const EntryList = ({ entry }) => {
const ui = useContext(UIContext);
const router = useRouter();
const handleViewClicked = (entryId) => {
ui.setEntryId(entryId);
ui.setEntriesViewMode("entry");
router.push({
pathname: `/stream/${entry.id}`,
query: router.query,
});
};
return (
<Flex
px={6}
borderTop="1px"
borderColor="white.300"
transition="0.1s"
_hover={{ bg: "secondary.200" }}
width="100%"
direction="row"
justifyContent="normal"
alignItems="baseline"
>
<Flex flexGrow={1}>
<Heading as="h3" fontWeight="500" fontSize="md">
{entry.title}
</Heading>
</Flex>
<Text opacity="0.5" fontSize="xs" alignSelf="baseline">
{moment(entry.created_at).format("DD MMM, YYYY, h:mm:ss")}{" "}
</Text>
<IconButton
p={0}
variant="ghost"
boxSize="32px"
colorScheme="primary"
icon={<ViewIcon />}
onClick={() => handleViewClicked(entry.id)}
/>
</Flex>
);
};
export default EntryList;

Wyświetl plik

@ -1,81 +0,0 @@
import { jsx } from "@emotion/react";
import {
Box,
Spinner,
Center,
RadioGroup,
Radio,
Stack,
Divider,
} from "@chakra-ui/react";
import { ErrorIndicators } from ".";
import { useMemo, useState } from "react";
//
const ErrorsStats = ({ data, isLoading }) => {
const [tagType, setTagType] = useState("common");
const LoadingSpinner = () => (
<Box px="12%" my={12} width="100%">
<Center>
<Spinner
hidden={false}
my={0}
size="lg"
color="primary.500"
thickness="4px"
speed="1.5s"
/>
</Center>
</Box>
);
const highest_entropy_indicators = useMemo(
() =>
data &&
Object.keys(data?.highest_entropy_tags)?.map((key) => {
return {
key: key,
value: data?.highest_entropy_tags[key],
timeseries: [...data?.errors_time_series[key]],
};
}),
[data]
);
const most_common_indicators = useMemo(
() =>
data &&
Object.keys(data?.most_common_errors)?.map((key) => {
return {
key: key,
value: data?.most_common_errors[key],
timeseries: [...data?.errors_time_series[key]],
};
}),
[data]
);
if (isLoading || !data) return <LoadingSpinner />;
return (
<Box w="100%">
<RadioGroup onChange={setTagType} value={tagType}>
<Stack direction="row">
{/* <Radio value="all">all</Radio> */}
<Radio value="entropy">highest entropy</Radio>
<Radio value="common">most common</Radio>
</Stack>
</RadioGroup>
<Divider />
{tagType === "common" && (
<ErrorIndicators data={most_common_indicators} />
)}
{tagType === "entropy" && (
<ErrorIndicators data={highest_entropy_indicators} />
)}
</Box>
);
};
export default ErrorsStats;

Wyświetl plik

@ -1,157 +0,0 @@
import { jsx } from "@emotion/react";
import { Link, Text } from "@chakra-ui/react";
const Topics = [
{
title: "Welcome!",
body: [
{
text: [
<Text key={"github-content-1"}>
If you just installed Bugout, thank you for becoming a part of our
community!
</Text>,
],
},
],
},
{
title: "Pull request checklists with @bugout-dev",
body: [
{
text: [
<Text key={"github-content-2"}>
Sometimes, you need human oversight on your pull requests before you
can merge them. This is really useful for pull requests that change
database schema, introduce new environment variables, or introduce
changes with security or legal implications.
</Text>,
<Text key={"github-content-3"}>
You can use Bugout to create checklists on your pull requests. Just
mention{" "}
<Link
href="https://github.com/bugout-dev"
isExternal
color="primary.400"
>
@bugout-dev
</Link>
:
</Text>,
<Text key={"github-content-4"}>
<i>@bugout-dev check require something important</i>
</Text>,
<Text key={"github-content-5"}>For example:</Text>,
],
},
{
image: {
path: "/images/welcome/github/image2.png",
annotation: "github example",
},
},
{
text: [
<Text key={"github-content-6"}>
When the manual step is finished, mention <i>@bugout-dev</i> again:
</Text>,
<Text key={"github-content-7"}>
<i>@bugout-dev check accept something important</i>
</Text>,
<Text key={"github-content-8"}>
At any time, you can see the status of your checklist by clicking on
the <i>Details</i> link next to the <i>@bugout-dev</i> continuous
integration check.
</Text>,
<Text key={"github-content-9"}>This is what it looks like:</Text>,
],
},
{
image: {
path: "/images/welcome/github/image1.png",
annotation: "github example2",
},
},
{
text: [
<Text key={"github-content-10"}>
Play with @bugout-dev on our demo PR:{" "}
<Link
href="https://github.com/bugout-dev/github-demo/pull/2"
isExternal
color="primary.400"
>
https://github.com/bugout-dev/github-demo/pull/2
</Link>
</Text>,
],
},
],
},
{
title: "Installing Bugout",
body: [
{
text: [
<Text key={"github-content-11"}>
You can install Bugout to your organization or to individual
repositories. Click here to install:{" "}
<Link
href="https://github.com/apps/bugout-dev"
color="primary.400"
isExternal
>
https://github.com/apps/bugout-dev
</Link>
</Text>,
<Text key={"github-content-12"}>
To see what else you can do with Bugout on GitHub, check out our
demo repository:{" "}
<Link
href="https://github.com/apps/bugout-dev"
color="primary.400"
isExternal
>
https://github.com/bugout-dev/github-demo
</Link>
</Text>,
],
},
],
},
{
title: "Contact us",
body: [
{
text: [
<Text key={"github-content-13"}>
If you have any questions or would like to suggest improvements to
Bugout, you can contact us by email: Neeraj -{" "}
<Link color="primary.400" href="mailto:neeraj@bugout.dev">
neeraj@bugout.dev
</Link>
, Sophia -{" "}
<Link color="primary.400" href="mailto:sophia@bugout.dev">
sophia@bugout.dev
</Link>
.
</Text>,
<Text key={"github-content-14"}>
You can also reach us on the{" "}
<Link
color="primary.400"
a
href="https://join.slack.com/t/bugout-dev/shared_invite/zt-fhepyt87-5XcJLy0iu702SO_hMFKNhQ"
isExternal
>
Bugout community Slack channel
</Link>
. Direct message Neeraj (@zomglings) or Sophia (@Sophia).
</Text>,
],
},
],
},
];
export default Topics;

Wyświetl plik

@ -1,38 +0,0 @@
import { jsx } from "@emotion/react";
import { Box, LinkBox } from "@chakra-ui/react";
const JournalLinkBox = (props) => {
return (
<LinkBox
as={Box}
alignItems="baseline"
px={2}
py={1}
my={1}
mx={1}
bg={props.isActive ? "secondary.900" : "none"}
color={props.isActive ? "white.200" : "white.200"}
fontWeight={600}
// transition="0.3s"
fontSize="md"
_hover={{
boxShadow: "md",
bg: props.isActive ? "secondary.900" : "primary.500",
color: "white.200",
}}
borderRadius="sm"
boxShadow={props.isActive ? "md" : "none"}
variant="ghost"
display="flex"
flex="row"
textOverflow="ellipsis"
overflow="visible"
{...props.props}
>
{props.children}
</LinkBox>
);
};
export default JournalLinkBox;

Wyświetl plik

@ -1,177 +0,0 @@
import { jsx } from "@emotion/react";
import {
Button,
Grid,
GridItem,
NumberInput,
NumberInputField,
NumberInputStepper,
NumberIncrementStepper,
NumberDecrementStepper,
Heading,
Input,
Center,
Spinner,
Text,
Flex,
} from "@chakra-ui/react";
import { useSubscriptions } from "../core/hooks";
import { Fragment } from "react";
import { useForm } from "react-hook-form";
const ManageSubscription = ({ groupId, onAddSeatsClose }) => {
const { manageSubscriptionMutation, subscriptionsCache } = useSubscriptions(
groupId
);
const {
handleSubmit: addSeatsHandleSubmit,
register: addSeatsRegister,
} = useForm();
const {
handleSubmit: addEventsHandleSubmit,
register: addEventsRegister,
} = useForm();
const updateSubscriptionHandler = ({ groupId, units, planType }) => {
const desiredUnits = Math.trunc(units);
manageSubscriptionMutation.manageSubscription({
groupId,
desiredUnits,
planType,
});
onAddSeatsClose();
};
if (subscriptionsCache.isLoading)
return (
<Center>
<Spinner
hidden={false}
my={32}
size="lg"
color="primary.500"
thickness="4px"
speed="1.5s"
/>
</Center>
);
const eventPlan = subscriptionsCache.data.find(
(subscription) => subscription.plan_type === "events"
);
const seatPlan = subscriptionsCache.data.find(
(subscription) => subscription.plan_type === "seats"
);
return (
<Fragment>
<Heading mt={2} as="h2" fontSize={["lg", "xl"]}>
Total number of seats?
</Heading>
<form onSubmit={addSeatsHandleSubmit(updateSubscriptionHandler)}>
<Input
type="hidden"
name="groupId"
ref={addSeatsRegister}
defaultValue={groupId}
/>
<Input
type="hidden"
name="planType"
ref={addSeatsRegister}
defaultValue="seats"
/>
<NumberInput
defaultValue={seatPlan?.units ? seatPlan.units : "5"}
min={5}
size="md"
>
<NumberInputField name="units" ref={addSeatsRegister} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Grid
templateColumns="repeat(8, 1fr)"
gap={1}
alignItems="baseline"
mt="1"
>
<GridItem colSpan={7} />
<GridItem>
<Button
mt={4}
variant="outline"
colorScheme="suggested"
type="submit"
>
Update seats
</Button>
</GridItem>
</Grid>
</form>
<form onSubmit={addEventsHandleSubmit(updateSubscriptionHandler)}>
<Heading mt={2} as="h2" fontSize={["lg", "xl"]} pt={16}>
Number of reports
</Heading>
<Input
type="hidden"
name="groupId"
ref={addEventsRegister}
defaultValue={groupId}
/>
<Input
type="hidden"
name="planType"
ref={addEventsRegister}
defaultValue="events"
/>
<Flex direction={["column", "row", null, "row"]}>
<NumberInput
w={["100%", "100%", null, "30%"]}
minW="10rem"
defaultValue={eventPlan?.units ? eventPlan.units : "5"}
min={5}
size="md"
precision={0}
step={1}
>
<NumberInputField name="units" ref={addEventsRegister} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<Text ml={4} fontWeight="700" fontSize="xl">
x1000 Reports/Month
</Text>
</Flex>
<Grid
templateColumns="repeat(8, 1fr)"
gap={1}
alignItems="baseline"
mt="1"
>
<GridItem colSpan={7} />
<GridItem>
<Button
mt={4}
variant="outline"
colorScheme="suggested"
type="submit"
>
Update reports
</Button>
</GridItem>
</Grid>
</form>
</Fragment>
);
};
export default ManageSubscription;

Wyświetl plik

@ -1,73 +0,0 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from "@emotion/react";
import { useState, useEffect } from "react";
import {
HStack,
Editable,
EditablePreview,
EditableInput,
} from "@chakra-ui/react";
const NameEditable = ({ team, rename }) => {
const [name, setName] = useState(team.group_name);
useEffect(() => {
setName(team.group_name);
}, [team.group_name]);
const handleSubmit = () => {
rename.renameGroup({ name, groupId: team.group_id });
};
return (
<Editable
selectAllOnFocus={true}
overflow="hidden"
maxWidth="100%"
width="100%"
height="auto"
minH="36px"
style={{ marginLeft: "0" }}
m={0}
p={0}
fontWeight="600"
fontSize="md"
textAlign="left"
isPreviewFocusable={true}
submitOnBlur={true}
onSubmit={() => handleSubmit()}
value={name}
onChange={(value) => setName(value)}
>
{() => (
<HStack
width="auto"
maxWidth="calc(100%)"
textOverflow="ellipsis"
overflow="hidden"
>
<EditablePreview
wordBreak="break-all"
maxWidth="fit-content"
width="fit-content"
flex="auto"
textOverflow="ellipsis"
p={0}
m={0}
/>
<EditableInput
wordBreak="break-all"
maxWidth="calc(100% - 48px)"
width="calc(100% - 48px)"
flex="auto"
textOverflow="ellipsis"
p={0}
_focus={{ outline: "none" }}
/>
</HStack>
)}
</Editable>
);
};
export default NameEditable;

Wyświetl plik

@ -1,12 +1,10 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from "@emotion/react";
import React, { useEffect, Suspense, useContext } from "react";
import React, { Suspense, useContext } from "react";
import { Flex } from "@chakra-ui/react";
import { useUser } from "../core/hooks";
import UIContext from "../core/providers/UIProvider/context";
const ForgotPassword = React.lazy(() => import("./ForgotPassword"));
const Verify = React.lazy(() => import("./Verify"));
const SignIn = React.lazy(() => import("./SignIn"));
const SignUp = React.lazy(() => import("./SignUp"));
const LandingNavbar = React.lazy(() => import("./LandingNavbar"));
@ -14,17 +12,7 @@ const AppNavbar = React.lazy(() => import("./AppNavbar"));
const Navbar = () => {
const { modal, toggleModal, isAppView, isLoggedIn } = useContext(UIContext);
const { user } = useUser();
useEffect(() => {
if (user && !user.verified) {
toggleModal("verify");
}
}, [user, toggleModal]);
// ToDo: move this to constants
//Feature flag for email verification
const verificationEnabled = false;
return (
<Flex
@ -48,13 +36,8 @@ const Navbar = () => {
{modal === "login" && <SignIn toggleModal={toggleModal} />}
{verificationEnabled && modal === "verify" && (
<Verify toggleModal={toggleModal} />
)}
{modal === "forgot" && <ForgotPassword toggleModal={toggleModal} />}
{(!isAppView || !isLoggedIn) && <LandingNavbar />}
{isAppView && isLoggedIn && <AppNavbar />}
</Suspense>

Wyświetl plik

@ -1,87 +0,0 @@
import { jsx } from "@emotion/react";
import { useRef, useEffect } from "react";
import {
Box,
Button,
GridItem,
Grid,
Text,
Heading,
Input,
FormErrorMessage,
FormControl,
InputGroup,
} from "@chakra-ui/react";
import { useHumbugs } from "../core/hooks";
import { useForm } from "react-hook-form";
const NewHumbugIntegration = ({ team }) => {
const { createHumbugMutation } = useHumbugs();
const inputRef = useRef();
const {
handleSubmit: addHumbugHandleSubmit,
register: addHumbugRegister,
errors: errorHambugRegister,
} = useForm();
const addHumbugHandler = ({ groupId, journalName }) => {
createHumbugMutation.createHumbug({ groupId, journalName });
};
useEffect(() => {
setTimeout(() => inputRef.current.focus(), 100);
}, [inputRef]);
return (
<form onSubmit={addHumbugHandleSubmit(addHumbugHandler)}>
<Box justifyContent="space-evenly">
<Heading size="md">New Usage reports project</Heading>
<Box>
<Text>How would you like to name it? </Text>
<FormControl isInvalid={errorHambugRegister.journalName}>
<InputGroup>
<Input
name="journalName"
placeholder="Usage report project name"
ref={(e) => {
addHumbugRegister(e, { required: "Name is required" });
inputRef.current = e;
}}
/>
</InputGroup>
<FormErrorMessage color="unsafe.400" pl="1">
{errorHambugRegister.journalName &&
errorHambugRegister.journalName.message}
</FormErrorMessage>
</FormControl>
<Input
type="hidden"
name="groupId"
ref={addHumbugRegister}
defaultValue={team.group_id}
></Input>
<Grid
templateColumns="repeat(8, 1fr)"
gap={1}
alignItems="baseline"
mt="1"
>
<GridItem colSpan={7} />
<GridItem></GridItem>
</Grid>
</Box>
<Button
variant="outline"
colorScheme="suggested"
type="submit"
isLoading={createHumbugMutation.isLoading}
>
Create
</Button>
</Box>
</form>
);
};
export default NewHumbugIntegration;

Wyświetl plik

@ -1,84 +0,0 @@
import { jsx } from "@emotion/react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import {
Heading,
Box,
FormControl,
FormErrorMessage,
InputGroup,
Button,
Input,
} from "@chakra-ui/react";
import Modal from "./Modal";
import { useCreateJournal } from "../core/hooks";
const NewJournalModal = ({ toggleModal }) => {
const { handleSubmit, errors, register } = useForm();
const [inputCount, setInputCount] = useState("0");
const [createJournal, { isLoading, data }] = useCreateJournal();
const handleInput = (e) => {
if (inputCount === 50) {
return;
}
setInputCount(e.target.value.length);
};
useEffect(() => {
if (!data) {
return;
}
toggleModal(null);
}, [data, toggleModal]);
return (
<Modal onClose={() => toggleModal(null)}>
<Heading mt={2} size="lg">
Create Journal
</Heading>
<form onSubmit={handleSubmit(createJournal)}>
<FormControl position="relative" isInvalid={errors.name}>
<InputGroup pt={4} width="100%">
<Input
colorScheme="primary"
variant="filled"
onChange={(e) => handleInput(e)}
placeholder="Journal name"
name="name"
ref={register({ required: "name is required!" })}
/>
</InputGroup>
<Box
right="0"
position="absolute"
fontSize="sm"
color="gray.200"
as="span"
>
{inputCount}/50
</Box>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.name && errors.name.message}
</FormErrorMessage>
</FormControl>
<Box height="1px" width="100%" background="#eaebf8" mb="1.875rem" />
<Button
mt={8}
type="submit"
width="100%"
variant="solid"
colorScheme="primary"
isLoading={isLoading}
>
Create
</Button>
</form>
</Modal>
);
};
export default NewJournalModal;

Wyświetl plik

@ -50,9 +50,25 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
<ModalHeader>Subscribe to a new address</ModalHeader>
<ModalCloseButton />
<ModalBody>
<FormControl isInvalid={errors.label}>
<Input
my={2}
type="text"
autoComplete="off"
placeholder="Enter label"
name="label"
ref={register({ required: "label is required!" })}
></Input>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.label && errors.label.message}
</FormErrorMessage>
</FormControl>
<FormControl isInvalid={errors.address}>
<Input
placeholder="new address"
type="text"
autoComplete="off"
my={2}
placeholder="Enter address"
name="address"
ref={register({ required: "address is required!" })}
></Input>
@ -92,11 +108,6 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
</FormControl>
</Stack>
<Input placeholder="color" name="color" ref={register()}></Input>
<Input
placeholder="Add some notes"
name="label"
ref={register()}
></Input>
</ModalBody>
<ModalFooter>
<Button

Wyświetl plik

@ -1,51 +0,0 @@
import { jsx } from "@emotion/react";
import { useEffect, useRef } from "react";
import { useForm } from "react-hook-form";
import {
FormControl,
FormErrorMessage,
InputGroup,
HStack,
Input,
} from "@chakra-ui/react";
import { CloseIcon } from "@chakra-ui/icons";
import IconButton from "./IconButton";
const NewTeamForm = ({ createTeamCallback, toggleSelf }) => {
const { handleSubmit, errors, register } = useForm();
const inputRef = useRef();
useEffect(() => {
inputRef.current.focus();
}, [inputRef]);
return (
<form onSubmit={handleSubmit(createTeamCallback)}>
<HStack py={2} width="100%">
<FormControl isInvalid={errors.teamName}>
<InputGroup>
<Input
border="none"
width="60%"
placeholder="Team name"
name="teamName"
ref={(e) => {
register(e, { required: "Name is required" });
inputRef.current = e;
}}
/>
</InputGroup>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.teamName && errors.teamName.message}
</FormErrorMessage>
</FormControl>
<IconButton type="submit" />
<IconButton onClick={() => toggleSelf(false)} icon={<CloseIcon />} />
</HStack>
</form>
);
};
export default NewTeamForm;

Wyświetl plik

@ -1,87 +0,0 @@
import { jsx } from "@emotion/react";
import { useEffect, useRef, Fragment } from "react";
import {
FormControl,
FormErrorMessage,
InputGroup,
Input,
Td,
Tr,
} from "@chakra-ui/react";
import { CloseIcon } from "@chakra-ui/icons";
import IconButton from "./IconButton";
const NewTokenTr = ({ isOpen, toggleSelf, errors, register, journalName }) => {
const inputRef = useRef(null);
useEffect(() => {
if (isOpen) {
//without timeout input is not catching focus on chrome and firefox..
//probably because it is hidden within accordion
setTimeout(() => {
inputRef.current.focus();
}, 100);
}
}, [inputRef, isOpen]);
return (
<Fragment>
{isOpen && (
<Tr transition="0.3s" _hover={{ bg: "white.200" }}>
<Td>New Token:</Td>
<Td>
<FormControl isInvalid={errors.appName}>
<InputGroup>
<Input
fontSize="sm"
border="none"
width="60%"
defaultValue={journalName}
height="fit-content"
placeholder="App name"
name="appName"
ref={(e) => {
register(e, { required: "app name is required" });
inputRef.current = e;
}}
/>
</InputGroup>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.appName && errors.appName.message}
</FormErrorMessage>
</FormControl>
</Td>
<Td>
<FormControl isInvalid={errors.appVersion}>
<InputGroup>
<Input
fontSize="sm"
border="none"
width="60%"
height="fit-content"
placeholder="App Version"
name="appVersion"
ref={(e) => {
register(e, { required: "app name is required" });
}}
/>
</InputGroup>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.appVersion && errors.appVersion.message}
</FormErrorMessage>
</FormControl>
</Td>
<Td>
<IconButton type="submit" />
<IconButton
onClick={() => toggleSelf(false)}
icon={<CloseIcon />}
/>
</Td>
</Tr>
)}
</Fragment>
);
};
export default NewTokenTr;

Wyświetl plik

@ -1,23 +0,0 @@
import { jsx } from "@emotion/react";
import { ListItem, UnorderedList } from "@chakra-ui/react";
import { useJournalsScopes } from "../core/hooks";
const ScopeDescription = () => {
const { scopesCache } = useJournalsScopes();
if (scopesCache.isLoading) return "";
const scopes = scopesCache.data;
return (
<UnorderedList>
{scopes?.map((scope, idx) => (
<ListItem key={`li-scopes-${idx}`} fontSize="sm" my={0}>
{`${scope.scope} --> ${scope.description}`}
</ListItem>
))}
</UnorderedList>
);
};
export default ScopeDescription;

Wyświetl plik

@ -11,7 +11,7 @@ import RouterLink from "next/link";
import { Flex, Image, IconButton } from "@chakra-ui/react";
import UIContext from "../core/providers/UIProvider/context";
import React from "react";
import { HamburgerIcon } from "@chakra-ui/icons";
import { HamburgerIcon, ArrowLeftIcon, ArrowRightIcon } from "@chakra-ui/icons";
import { MdTimeline, MdSettings } from "react-icons/md";
import { ImStatsBars } from "react-icons/im";
@ -19,6 +19,7 @@ const Sidebar = () => {
const ui = useContext(UIContext);
return (
<ProSidebar
width="240px"
breakPoint="lg"
toggled={ui.sidebarToggled}
onToggle={ui.setSidebarToggled}
@ -32,7 +33,15 @@ const Sidebar = () => {
justifySelf="flex-start"
colorScheme="primary"
aria-label="App navigation"
icon={<HamburgerIcon />}
icon={
ui.isMobileView ? (
<HamburgerIcon />
) : ui.sidebarCollapsed ? (
<ArrowRightIcon />
) : (
<ArrowLeftIcon />
)
}
onClick={() => {
ui.isMobileView
? ui.setSidebarToggled(!ui.sidebarToggled)
@ -42,7 +51,7 @@ const Sidebar = () => {
<Image
// as={Link}
// to="/"
h="3rem"
w="150px"
py="0.75rem"
pl={5}
src="/icons/bugout-dev-white.svg"

Wyświetl plik

@ -1,7 +1,7 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from "@emotion/react";
import { useEffect } from "react";
import { useContext, useEffect } from "react";
import { useForm } from "react-hook-form";
import {
Heading,
@ -15,24 +15,26 @@ import {
Input,
InputRightElement,
} from "@chakra-ui/react";
import CustomIcon from "./CustomIcon"
import CustomIcon from "./CustomIcon";
import { useSignUp } from "../core/hooks";
import Modal from "./Modal";
import PasswordInput from "./PasswordInput";
import UIContext from "../core/providers/UIProvider/context";
const SignUp = ({ toggleModal }) => {
const { handleSubmit, errors, register } = useForm();
const { signUp, isLoading, data } = useSignUp();
const { signUp, isLoading, isSuccess } = useSignUp();
const ui = useContext(UIContext);
useEffect(() => {
if (!data) {
return;
if (isSuccess) {
ui.toggleModal(null);
}
toggleModal("verify");
}, [data, toggleModal]);
}, [isSuccess, toggleModal]);
return (
<Modal onClose={() => toggleModal(null)}>
<Modal onClose={() => ui.toggleModal(null)}>
<Heading mt={2} size="md">
Create an account
</Heading>

Wyświetl plik

@ -1,285 +0,0 @@
import { jsx } from "@emotion/react";
import { Link, Text, Image } from "@chakra-ui/react";
const Topics = [
{
title: "Welcome!",
body: [
{
text: [
<Text key={"slack-welcome-content-1"}>
If you just installed Bugout, thank you for becoming a part of our
community!
</Text>,
<Text key={"slack-welcome-content-2"}>
<b>@bugout</b> turns your Slack workspace into a knowledge base.
Keep reading to learn how.
</Text>,
],
},
],
},
{
title: "Contact us",
body: [
{
text: [
<Text key={"slack-welcome-content-3"}>
If you have any questions or would like to suggest improvements to
Bugout, you can contact us by email: Neeraj -{" "}
<Link color="primary.400" href="mailto:neeraj@bugout.dev">
neeraj@bugout.dev
</Link>
, Sophia -{" "}
<Link color="primary.400" href="mailto:sophia@bugout.dev">
sophia@bugout.dev
</Link>
.
</Text>,
"You can also reach us on the Bugout community Slack channel. Direct message Neeraj (@zomglings) or Sophia (@Sophia).",
],
},
],
},
{
title: "Using @bugout",
body: [
{
text: [
<Text key={"slack-welcome-content-4"}>
The <b>@bugout</b> bot does not know about conversations in channels
that it has not been invited to. To invite <b>@bugout</b> to a
channel, simply mention it in that channel:
</Text>,
],
},
{
image: {
path: "/images/welcome/slack/image1.png",
annotation: "Mention it in that channel and hit Enter.",
},
},
{
text: ["and hit Enter. You will see a prompt like this:"],
},
{
image: {
path: "/images/welcome/slack/image5.png",
annotation: "Invite slack modal",
},
},
{
text: [
<Text key={"slack-welcome-content-5"}>
Click Invite to Channel. Once you have successfully added{" "}
<b>@bugout</b> to a channel, you will see a message like the one
below:
</Text>,
],
},
{
image: {
path: "/images/welcome/slack/image2.png",
annotation: "Invite slack modal",
},
},
],
},
{
title: "Creating your team knowledge base",
body: [
{
text: [
<Text key={"slack-welcome-content-6"}>
You can work with your team knowledge base from the Bugout web app
by going to{" "}
<Link color="primary.400" href="https://bugout.dev">
https://bugout.dev
</Link>{" "}
and registering for an account using the Register button at the
top right
</Text>,
],
},
{
image: {
path: "/images/welcome/slack/image9.png",
annotation: "Bugout header",
},
},
{
text: [
"Once you have a Bugout account, you can connect it to your Slack knowledge base by going back into Slack, starting a direct message with Bugout (under Apps):",
],
},
{
image: {
path: "/images/welcome/slack/image3.png",
annotation: "slack bugout",
},
},
{
text: [
"and typing:",
<Text key={"slack-welcome-content-7"}>
<b>@bugout</b> admin authorize {`<your Bugout username>`}
</Text>,
],
},
{
image: {
path: "/images/welcome/slack/image10.png",
annotation: "authorize bugout",
},
},
{
text: ["If this is successful, you will see a thread like this:"],
},
{
image: {
path: "/images/welcome/slack/image13.png",
annotation: "authorize bugout resopnse",
},
},
{
text: [
"After this, you will see your team knowledge base under the “Journals” tab on the Bugout website.",
],
},
],
},
{
title: "Adding knowledge!",
body: [
{
text: [
"There are multiple ways of adding knowledge to your Bugout team knowledge base",
],
},
{
title: "From the Bugout website",
body: [
{
image: {
path: "/images/welcome/slack/image7.gif",
annotation: "website adding knowledge",
},
},
],
},
{
title: "From Slack using the global shortcut",
body: [
{
image: {
path: "/images/welcome/slack/image8.gif",
annotation: "slack adding knowledge",
},
},
],
},
{
title: "From Slack using the bugout emoji",
body: [
{
text: [
<Text key={"slack-welcome-content-8"}>
If you have added the{" "}
<Image
display="inline-block"
width="28px"
src="/images/logo.png"
alt="emoji ant"
/>
bugout emoji to your Slack workspace, you can react to messages
with it to add them into your teams knowledge base:
</Text>,
],
},
{
image: {
path: "/images/welcome/slack/image11.gif",
annotation: "slack adding knowledge",
},
},
],
},
],
},
{
title: "Discovering knowledge",
body: [
{
text: [
"Any knowledge you add to your knowledge base is immediately accessible and discoverable to you, wherever you work.",
],
},
{
title: "From the Bugout website",
body: [
{
image: {
path: "/images/welcome/slack/image6.png",
annotation: "website knowledge",
},
},
],
},
{
title: "From Slack using the global shortcut",
body: [
{
image: {
path: "/images/welcome/slack/image12.gif",
annotation: "slack knowledge",
},
},
],
},
{
title: "From Slack using @bugout",
body: [
{
image: {
path: "/images/welcome/slack/image4.gif",
annotation: "slack command line knowledge",
},
},
],
},
],
},
{
title: "Installing Bugout",
body: [
{
text: [
<Link
key={"slack-welcome-content-9"}
color="primary.400"
a
href="https://slack.com/workspace-signin?redir=%2Foauth%3Fclient_id%3D655293806690.1251550900407%26scope%3Dapp_mentions%253Aread%252Cchannels%253Ahistory%252Cchannels%253Aread%252Cchat%253Awrite%252Cemoji%253Aread%252Cgroups%253Ahistory%252Cgroups%253Aread%252Cim%253Ahistory%252Cim%253Aread%252Cim%253Awrite%252Clinks%253Aread%252Cmpim%253Ahistory%252Cmpim%253Aread%252Creactions%253Aread%252Creactions%253Awrite%252Cusers.profile%253Aread%252Ccommands%26user_scope%3D%26redirect_uri%3D%26state%3D%26granular_bot_scope%3D1%26single_channel%3D0%26install_redirect%3D%26team%3D"
>
Click here to install Bugout
</Link>,
<Text key={"slack-welcome-content-10"}>
If youd like to find out more, reach out to Neeraj{" "}
<Link
isExternal
color="primary.400"
a
href="mailto:neeraj@bugout.dev"
>
neeraj@bugout.dev
</Link>{" "}
and Sophia -{" "}
<Link color="primary.400" a href="mailto:sophia@bugout.dev">
sophia@bugout.dev
</Link>
</Text>,
],
},
],
},
];
export default Topics;

Wyświetl plik

@ -0,0 +1,107 @@
import React, { useContext } from "react";
import { Flex, Text, IconButton, Tag } from "@chakra-ui/react";
import moment from "moment";
import { ViewIcon } from "@chakra-ui/icons";
import { useRouter } from "../core/hooks";
import UIContext from "../core/providers/UIProvider/context";
const StreamEntry = ({ entry, filterCallback, filterConstants }) => {
const ui = useContext(UIContext);
const router = useRouter();
const handleViewClicked = (entryId) => {
ui.setEntryId(entryId);
ui.setEntriesViewMode("entry");
router.push({
pathname: `/stream/${entry.id}`,
query: router.query,
});
};
return (
<Flex
px={6}
m={1}
mr={2}
maxH="3rem"
borderRadius="md"
borderTop="1px"
bgColor="gray.100"
borderColor="white.300"
boxSizing="border-box"
transition="0.1s"
_hover={{ bg: "secondary.200" }}
flexBasis="100px"
flexGrow={1}
h="3rem"
direction="row"
justifySelf="center"
justifyContent="normal"
alignItems="baseline"
boxShadow="lg"
>
<Flex flexGrow={1} placeSelf="center">
<Tag
alignSelf="center"
colorScheme="secondary"
variant="subtle"
onClick={() =>
filterCallback({
direction: filterConstants.DIRECTIONS.SOURCE,
type: filterConstants.FILTER_TYPES.ADDRESS,
value: entry.from,
conditon: filterConstants.CONDITION.EQUAL,
})
}
>
{"From:"}
{`${entry.from_label} - ${entry.from.slice(
0,
5
)}...${entry.from.slice(-3, -1)}`}
</Tag>{" "}
<Tag
alignSelf="center"
colorScheme="secondary"
variant="subtle"
onClick={() =>
filterCallback({
direction: filterConstants.DIRECTIONS.DESTINATION,
type: filterConstants.FILTER_TYPES.ADDRESS,
value: entry.to,
conditon: filterConstants.CONDITION.EQUAL,
})
}
>
{"To:"}
{`${entry.to_label} - ${entry.to.slice(0, 5)}...${entry.to.slice(
-3,
-1
)}`}
</Tag>{" "}
<Tag alignSelf="center" colorScheme="secondary" variant="subtle">
Gas Price: {entry.gasPrice}
</Tag>
<Tag colorScheme="secondary" variant="subtle">
Gas: {entry.gas}
</Tag>
<Tag colorScheme="secondary" variant="subtle">
Value: {entry.value}
</Tag>
</Flex>
<Text opacity="0.5" fontSize="xs" alignSelf="baseline">
{moment(entry.created_at).format("DD MMM, YYYY, h:mm:ss")}{" "}
</Text>
<IconButton
p={0}
variant="ghost"
boxSize="32px"
colorScheme="primary"
icon={<ViewIcon />}
onClick={() => handleViewClicked(entry.id)}
/>
</Flex>
);
};
export default StreamEntry;

Wyświetl plik

@ -23,6 +23,7 @@ const List = (data) => {
useSubscriptions();
const updateCallback = ({ id, note }) => {
console.log("updateCallback", id);
changeNote.mutate({ id, note });
};
console.log(data);
@ -44,9 +45,9 @@ const List = (data) => {
<Thead>
<Tr>
<Th>Token</Th>
<Th>Label</Th>
<Th>Address</Th>
<Th>Date Created</Th>
<Th>label</Th>
<Th>Actions</Th>
</Tr>
</Thead>
@ -78,10 +79,6 @@ const List = (data) => {
<Td>
<Image h="32px" src={iconLink} alt="pool icon" />
</Td>
<Td mr={4} p={0}>
<CopyButton>{subscription.address}</CopyButton>
</Td>
<Td py={0}>{moment(subscription.created_at).format("L")}</Td>
<Td py={0}>
<Editable
colorScheme="primary"
@ -101,6 +98,11 @@ const List = (data) => {
<EditableInput maxW="40rem" />
</Editable>
</Td>
<Td mr={4} p={0}>
<CopyButton>{subscription.address}</CopyButton>
</Td>
<Td py={0}>{moment(subscription.created_at).format("L")}</Td>
<Td py={0}>
<ConfirmationRequest
bodyMessage={"please confirm"}

Wyświetl plik

@ -1,82 +0,0 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from "@emotion/react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { useMutation } from "react-query";
import {
Heading,
Text,
Box,
FormControl,
FormErrorMessage,
Input,
Button,
} from "@chakra-ui/react";
import Modal from "./Modal";
import { AuthService } from "../core/services";
import { useToast, useUser } from "../core/hooks";
const Verify = ({ toggleModal }) => {
const { handleSubmit, errors, register } = useForm();
const toast = useToast();
const [verify, { isLoading, error, data }] = useMutation(async (data) => {
const verificationResponse = await AuthService.verify(data);
return verificationResponse.data;
});
const { getUser } = useUser();
useEffect(() => {
if (!data) {
return;
}
getUser();
toggleModal(null);
}, [data, getUser, toggleModal]);
useEffect(() => {
if (error?.response?.data?.detail) {
toast(error.response.data.detail, "error");
}
}, [error, toast]);
return (
<Modal onClose={() => toggleModal(null)}>
<Heading mt={2} size="lg">
Verify account
</Heading>
<form onSubmit={handleSubmit(verify)}>
<FormControl isInvalid={errors.code} my={8}>
<Input
placeholder="Your code here"
name="code"
ref={register({ required: "code field is required!" })}
/>
<FormErrorMessage color="unsafe.400" pl="1">
{errors.code && errors.code.message}
</FormErrorMessage>
</FormControl>
<Button
type="submit"
verify="primary"
colorScheme="primary"
width="100%"
isLoading={isLoading}
>
Verify
</Button>
</form>
<Box height="1px" width="100%" background="#eaebf8" mb="1.875rem" />
<Text fontSize="sm" color="gray.1200">
We just sent you a verification code by email.
</Text>
<Text fontSize="sm" color="gray.1200">
Please enter the code here so we can verify that you are who you say you
are.
</Text>
</Modal>
);
};
export default Verify;

Wyświetl plik

@ -10,28 +10,31 @@ const useSignUp = (source) => {
const { inviteAccept } = useInviteAccept();
const analytics = useAnalytics();
const [signUp, { isLoading, error, data }] = useMutation(
AuthService.register(),
{
onSuccess: (response) => {
localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token);
const invite_code = window.sessionStorage.getItem("invite_code");
if (invite_code) {
inviteAccept(invite_code);
}
const {
mutate: signUp,
isLoading,
error,
data,
isSuccess
} = useMutation(AuthService.register(), {
onSuccess: (response) => {
localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token);
const invite_code = window.sessionStorage.getItem("invite_code");
if (invite_code) {
inviteAccept(invite_code);
}
if (analytics.isLoaded) {
analytics.mixpanel.track(
`${analytics.MIXPANEL_EVENTS.CONVERT_TO_USER}`,
{ full_url: router.nextRouter.asPath, code: source }
);
}
},
onError: (error) => {
toast(error, "error");
},
}
);
if (analytics.isLoaded) {
analytics.mixpanel.track(
`${analytics.MIXPANEL_EVENTS.CONVERT_TO_USER}`,
{ full_url: router.nextRouter.asPath, code: source }
);
}
},
onError: (error) => {
toast(error, "error");
},
});
useEffect(() => {
if (!data) {
@ -54,6 +57,7 @@ const useSignUp = (source) => {
isLoading,
data,
error,
isSuccess,
};
};

Wyświetl plik

@ -0,0 +1,76 @@
import { useInfiniteQuery } from "react-query";
import { queryCacheProps } from "./hookCommon";
import { SubscriptionsService } from "../services";
const useJournalEntries = ({
refreshRate,
isContent,
pageSize,
searchQuery,
enabled,
}) => {
const limit = pageSize ? pageSize : 25;
const getStream =
(searchTerm) =>
async ({ pageParam = 0 }) => {
if (!pageParam) {
pageParam = 0;
}
const searchTags = searchTerm.split(" ").filter(function (n) {
if (n.startsWith("#")) return n;
else {
return null;
}
});
const response = await SubscriptionsService.getStream({
searchTerm,
isContent,
limit,
offset: pageParam,
});
const newEntryList = response.data.stream.map((entry) => ({
...entry,
}));
return {
data: [...newEntryList],
pageParams: {
pageParam: pageParam + 1,
next_offset: response.data.next_offset,
total_results: response.data.total_results,
offset: response.data.offset,
},
};
};
const {
data: EntriesPages,
isFetchingMore,
isLoading,
canFetchMore,
fetchMore,
refetch,
} = useInfiniteQuery(["stream", { searchQuery }], getStream(searchQuery), {
refetchInterval: refreshRate,
...queryCacheProps,
getNextPageParam: (lastGroup) => {
return lastGroup.next_offset === null ? false : lastGroup.next_offset;
},
onSuccess: (data) => {
},
enabled: !!enabled,
});
return {
EntriesPages,
fetchMore,
isFetchingMore,
canFetchMore,
refetch,
isLoading,
};
};
export default useJournalEntries;

Wyświetl plik

@ -42,13 +42,13 @@ const UIProvider = ({ children }) => {
useEffect(() => {
if (isAppView && isAppReady && !user?.username && !isLoggingOut) {
toggleModal("login");
// toggleModal("login");
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isAppView, isAppReady, user, isLoggingOut]);
useEffect(() => {
if (isLoggingOut && !isAppView && !user) {
if (isLoggingOut && !isAppView && user) {
setLoggingOut(false);
}
}, [isAppView, user, isLoggingOut]);
@ -90,7 +90,7 @@ const UIProvider = ({ children }) => {
const [sidebarCollapsed, setSidebarCollapsed] = useStorage(
window.sessionStorage,
"sidebarCollapsed",
true
false
);
// Whether sidebar should be toggled in mobile view

Wyświetl plik

@ -4,17 +4,17 @@ import { http } from "../utils";
const API = process.env.NEXT_PUBLIC_MOONSTREAM_API_URL;
console.log(API);
// export const getTypes = () =>
// http({
// method: "GET",
// url: `${API}/subscription_types/`,
// });
// export const getSubscriptions = () =>
// http({
// method: "GET",
// url: `${API}/subscriptions/`,
// });
export const getStream = ({ searchTerm, limit, offset, isContent }) =>
http({
method: "GET",
url: `${API}/stream`,
params: {
q: searchTerm,
limit: encodeURIComponent(limit),
offset: encodeURIComponent(offset),
content: encodeURIComponent(isContent),
},
});
export const getTypes = () =>
http({
@ -65,7 +65,6 @@ export const createSubscription =
export const modifySubscription =
() =>
({ id, note }) => {
console.log("modifySubscription: ", note, id);
const data = new FormData();
data.append("note", note);
data.append("id", id);
@ -77,10 +76,9 @@ export const modifySubscription =
};
export const deleteSubscription = () => (id) => {
console.log("deleteSubscription: ", id);
return http({
method: "DELETE",
url: `${API}/subscription/${id}`,
url: `${API}/subscriptions/${id}`,
});
};

Wyświetl plik

@ -12,6 +12,16 @@ const makeid = (length) => {
return result;
};
const makenum = (length) => {
var result = "";
var characters = "0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
const randDate = () => {
return moment(
new Date(+new Date() - Math.floor(Math.random() * 10000000000))
@ -19,35 +29,40 @@ const randDate = () => {
};
let MockSubscriptions = [
{
address: makeid(24),
label: "Bobs wallet",
address: `0x` + makeid(24),
id: makeid(24),
notes: "lorem", //ToDo: rename in to label
created_at: randDate(),
subscription_type: "ethereum_blockchain",
},
{
address: makeid(24),
label: "Alices wallet",
address: `0x` + makeid(40),
id: makeid(24),
notes: "lorem",
created_at: randDate(),
subscription_type: "ethereum_txpool",
},
{
address: makeid(24),
label: "Alogrand Ricks Wallet",
address: `0x` + makeid(40),
id: makeid(24),
notes: "lorem",
created_at: randDate(),
subscription_type: "algorand_blockchain",
},
{
address: makeid(24),
label: "Unknown wallet",
address: `0x` + makeid(40),
id: makeid(24),
notes: "lorem",
created_at: randDate(),
subscription_type: "ethereum_blockchain",
},
{
address: makeid(24),
label: "Unknown wallet",
address: `0x` + makeid(40),
id: makeid(24),
notes: "lorem",
created_at: randDate(),
@ -90,6 +105,136 @@ const enableMockupRequests = (axiosInstance) => {
],
});
mock.onGet(`${MOCK_API}/stream`).reply(200, {
stream: [
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
{
from_label: "Bobs wallet",
to_label: "Alices wallet",
to: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420AG",
from: "0x2E337E0Fb68F5e51ce9295E80BCd02273d7420c4",
gas: 2265656,
gasPrice: 1000000000,
hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6",
value: 0,
input:
"0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca",
},
],
pageParams: {
next_offset: 25,
total_results: 4,
offset: 0,
},
});
// mock.onGet(`${MOCK_API}/subscriptions/`).reply(200, {
// data: {
// is_free_subscription_availible: true,
@ -97,19 +242,20 @@ const enableMockupRequests = (axiosInstance) => {
// },
// });
mock.onPost(`${MOCK_API}/subscriptions/`).reply((config) => {
const params = config.data; // FormData of {name: ..., file: ...}
const id = params.get("id");
const note = params.get("note");
// mock.onPost(`${MOCK_API}/subscriptions/`).reply((config) => {
// const params = config.data; // FormData of {name: ..., file: ...}
// const id = params.get("id");
// const label = params.get("label");
// const address = params.get("address");
// const subscription_type = params.get("subscription_type");
return new Promise(function (resolve) {
setTimeout(function () {
const data = { id, note };
console.log("mock", id, note);
MockSubscriptions.push({ ...data });
resolve([200, { message: "OK", result: true }]);
}, 1000);
});
});
// return new Promise(function (resolve) {
// setTimeout(function () {
// const data = { id, label, address, subscription_type };
// MockSubscriptions.push({ ...data });
// resolve([200, { message: "OK", result: true }]);
// }, 1000);
// });
// });
};
export default enableMockupRequests;