kopia lustrzana https://github.com/bugout-dev/moonstream
commit
49600ad1d6
|
@ -2,10 +2,10 @@
|
|||
The Moonstream users HTTP API
|
||||
"""
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
from typing import Any, Dict, Optional
|
||||
import uuid
|
||||
|
||||
from bugout.data import BugoutToken, BugoutUser, BugoutResource
|
||||
from bugout.data import BugoutToken, BugoutUser, BugoutResource, BugoutUserTokens
|
||||
from bugout.exceptions import BugoutResponseException
|
||||
|
||||
from fastapi import (
|
||||
|
@ -149,23 +149,71 @@ async def delete_user_handler(
|
|||
|
||||
@app.post("/token", tags=["tokens"], response_model=BugoutToken)
|
||||
async def login_handler(
|
||||
username: str = Form(...), password: str = Form(...)
|
||||
username: str = Form(...),
|
||||
password: str = Form(...),
|
||||
token_note: Optional[str] = Form(None),
|
||||
) -> BugoutToken:
|
||||
try:
|
||||
token: BugoutToken = bc.create_token(
|
||||
username=username,
|
||||
password=password,
|
||||
application_id=MOONSTREAM_APPLICATION_ID,
|
||||
token_note=token_note,
|
||||
)
|
||||
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(
|
||||
status_code=e.status_code, detail=f"Error from Brood API: {e.detail}"
|
||||
)
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return token
|
||||
|
||||
|
||||
@app.get("/tokens", tags=["tokens"], response_model=BugoutUserTokens)
|
||||
async def tokens_handler(request: Request) -> BugoutUserTokens:
|
||||
token = request.state.token
|
||||
try:
|
||||
response = bc.get_user_tokens(
|
||||
token, timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS, active=True
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return response
|
||||
|
||||
|
||||
@app.put("/token", tags=["tokens"], response_model=BugoutToken)
|
||||
async def token_update_handler(
|
||||
request: Request, token_note: str = Form(...), access_token: str = Form(...)
|
||||
) -> BugoutToken:
|
||||
token = request.state.token
|
||||
try:
|
||||
response = bc.update_token(token, token_note=token_note)
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return response
|
||||
|
||||
|
||||
@app.post("/revoke/{access_token}", tags=["tokens"], response_model=uuid.UUID)
|
||||
async def delete_token_by_id_handler(
|
||||
request: Request, access_token: uuid.UUID
|
||||
) -> uuid.UUID:
|
||||
token = request.state.token
|
||||
try:
|
||||
response = bc.revoke_token(
|
||||
token=token,
|
||||
target_token=access_token,
|
||||
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
|
||||
)
|
||||
except BugoutResponseException as e:
|
||||
raise MoonstreamHTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
raise MoonstreamHTTPException(status_code=500, internal_error=e)
|
||||
return response
|
||||
|
||||
|
||||
@app.delete("/token", tags=["tokens"], response_model=uuid.UUID)
|
||||
async def logout_handler(request: Request) -> uuid.UUID:
|
||||
token = request.state.token
|
||||
|
|
|
@ -3,7 +3,7 @@ asgiref==3.4.1
|
|||
black==21.7b0
|
||||
boto3==1.18.1
|
||||
botocore==1.21.1
|
||||
bugout==0.1.17
|
||||
bugout==0.1.18
|
||||
certifi==2021.5.30
|
||||
charset-normalizer==2.0.3
|
||||
click==8.0.1
|
||||
|
|
|
@ -12,7 +12,7 @@ setup(
|
|||
packages=find_packages(),
|
||||
install_requires=[
|
||||
"boto3",
|
||||
"bugout >= 0.1.17",
|
||||
"bugout >= 0.1.18",
|
||||
"fastapi",
|
||||
"humbug>=0.2.7",
|
||||
"python-dateutil",
|
||||
|
|
|
@ -23,7 +23,7 @@ const Security = () => {
|
|||
pt: 2,
|
||||
mb: 4,
|
||||
borderBottom: "solid",
|
||||
borderColor: "primary.50",
|
||||
borderColor: "blue.50",
|
||||
borderBottomWidth: "2px",
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,7 @@ const Security = () => {
|
|||
<Icon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.newPassword && errors.newPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -110,7 +110,7 @@ const Security = () => {
|
|||
<Icon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.newPassword && errors.newPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -129,7 +129,7 @@ const Security = () => {
|
|||
<Icon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.confirmPassword && errors.confirmPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -139,7 +139,7 @@ const Security = () => {
|
|||
<Button
|
||||
my={8}
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
import React, { useState, useEffect, useLayoutEffect } from "react";
|
||||
import TokensList from "../../src/components/TokensList";
|
||||
import TokenRequest from "../../src/components/TokenRequest";
|
||||
import { useTokens } from "../../src/core/hooks";
|
||||
import {
|
||||
VStack,
|
||||
Box,
|
||||
Center,
|
||||
Spinner,
|
||||
ScaleFade,
|
||||
Button,
|
||||
Heading,
|
||||
useDisclosure,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
} from "@chakra-ui/react";
|
||||
import { getLayout } from "../../src/layouts/AccountLayout";
|
||||
|
||||
const Tokens = () => {
|
||||
const { onOpen, onClose, isOpen } = useDisclosure();
|
||||
const [newToken, setNewToken] = useState(null);
|
||||
const [tokens, setTokens] = useState();
|
||||
const { list, update, revoke, isLoading, data } = useTokens();
|
||||
|
||||
useEffect(() => {
|
||||
list();
|
||||
//eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (newToken) {
|
||||
const newData = { ...tokens };
|
||||
newData.token.push(newToken);
|
||||
setTokens(newData);
|
||||
setNewToken(null);
|
||||
}
|
||||
}, [newToken, list, data, tokens]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (data?.data?.user_id) {
|
||||
setTokens(data.data);
|
||||
}
|
||||
}, [data?.data, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = `Tokens`;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{isLoading && !tokens ? (
|
||||
<Center>
|
||||
<Spinner
|
||||
hidden={false}
|
||||
my={8}
|
||||
size="lg"
|
||||
color="blue.500"
|
||||
thickness="4px"
|
||||
speed="1.5s"
|
||||
/>
|
||||
</Center>
|
||||
) : (
|
||||
<ScaleFade in>
|
||||
<Modal isOpen={isOpen} onClose={onClose} size="lg" trapFocus={false}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>New API access token</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<TokenRequest setNewToken={setNewToken} onClose={onClose} />
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
<Heading variant="tokensScreen"> My access tokens </Heading>
|
||||
<VStack overflow="initial" maxH="unset" height="100%">
|
||||
<Button
|
||||
alignSelf="flex-end"
|
||||
onClick={onOpen}
|
||||
colorScheme="orange"
|
||||
variant="solid"
|
||||
size="sm"
|
||||
>
|
||||
Add new token
|
||||
</Button>
|
||||
<TokensList
|
||||
data={tokens}
|
||||
revoke={revoke}
|
||||
isLoading={isLoading}
|
||||
updateCallback={update}
|
||||
/>
|
||||
</VStack>
|
||||
</ScaleFade>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Tokens.getLayout = getLayout;
|
||||
export default Tokens;
|
|
@ -30,7 +30,7 @@ const Analytics = () => {
|
|||
<HubspotForm
|
||||
portalId="8018701"
|
||||
formId="39bc0fbe-41c4-430a-b885-46eba66c59c2"
|
||||
loading={<Spinner colorScheme="primary" speed="1s" />}
|
||||
loading={<Spinner colorScheme="blue" speed="1s" />}
|
||||
/>
|
||||
</Flex>
|
||||
</Scrollable>
|
||||
|
|
|
@ -229,7 +229,6 @@ const Homepage = () => {
|
|||
colSpan="12"
|
||||
pb={[1, 2, null, 8]}
|
||||
minH="100vh"
|
||||
// bgColor="primary.1200"
|
||||
>
|
||||
<chakra.header boxSize="full" minH="100vh">
|
||||
<Box
|
||||
|
@ -261,7 +260,7 @@ const Homepage = () => {
|
|||
my={12}
|
||||
fontSize={["md", "2xl", "3xl", "3xl", "3xl", "4xl"]}
|
||||
display="inline-block"
|
||||
color="primary.200"
|
||||
color="blue.200"
|
||||
>
|
||||
Get all the crypto data you need in a single stream.
|
||||
From pending transactions in the Ethereum transaction
|
||||
|
@ -270,7 +269,7 @@ const Homepage = () => {
|
|||
<chakra.span
|
||||
fontSize={["md", "2xl", "3xl", "3xl", "3xl", "4xl"]}
|
||||
display="inline-block"
|
||||
color="primary.300"
|
||||
color="blue.300"
|
||||
>
|
||||
Access this data through the Moonstream dashboard or
|
||||
API
|
||||
|
@ -305,10 +304,7 @@ const Homepage = () => {
|
|||
{` We believe in financial inclusion. Proprietary technologies
|
||||
are not financially inclusive. That's why all our software
|
||||
is `}
|
||||
<chakra.span
|
||||
display="inline-block"
|
||||
textColor="secondary.900"
|
||||
>
|
||||
<chakra.span display="inline-block" textColor="orange.900">
|
||||
<i>open source</i>
|
||||
</chakra.span>
|
||||
</Text>
|
||||
|
@ -430,7 +426,7 @@ const Homepage = () => {
|
|||
},
|
||||
}}
|
||||
elementName={"element1"}
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
badge={`For crypto traders`}
|
||||
title={``}
|
||||
body={``}
|
||||
|
@ -438,21 +434,21 @@ const Homepage = () => {
|
|||
{
|
||||
text: `Subscribe to the defi contracts you care about`,
|
||||
icon: FaFileContract,
|
||||
color: "suggested.50",
|
||||
bgColor: "suggested.900",
|
||||
color: "green.50",
|
||||
bgColor: "green.900",
|
||||
},
|
||||
{
|
||||
text: `Make sense of how others are calling these contracts using Moonstream dashboards.
|
||||
`,
|
||||
icon: RiDashboardFill,
|
||||
color: "suggested.50",
|
||||
bgColor: "suggested.900",
|
||||
color: "green.50",
|
||||
bgColor: "green.900",
|
||||
},
|
||||
{
|
||||
text: `Get data directly from the transaction pool through our global network of Ethereum nodes`,
|
||||
icon: GiMeshBall,
|
||||
color: "suggested.50",
|
||||
bgColor: "suggested.900",
|
||||
color: "green.50",
|
||||
bgColor: "green.900",
|
||||
},
|
||||
]}
|
||||
imgURL={assets["cryptoTraders"]}
|
||||
|
@ -479,26 +475,26 @@ const Homepage = () => {
|
|||
}}
|
||||
elementName={"element2"}
|
||||
mirror={true}
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
badge={`For algorithmic funds`}
|
||||
bullets={[
|
||||
{
|
||||
text: `Get API access to your stream`,
|
||||
icon: AiFillApi,
|
||||
color: "secondary.50",
|
||||
bgColor: "secondary.900",
|
||||
color: "orange.50",
|
||||
bgColor: "orange.900",
|
||||
},
|
||||
{
|
||||
text: `Set conditions that trigger predefined actions`,
|
||||
icon: GiLogicGateXor,
|
||||
color: "secondary.50",
|
||||
bgColor: "secondary.900",
|
||||
color: "orange.50",
|
||||
bgColor: "orange.900",
|
||||
},
|
||||
{
|
||||
text: `Execute transactions directly on Moonstream nodes`,
|
||||
icon: BiTransfer,
|
||||
color: "secondary.50",
|
||||
bgColor: "secondary.900",
|
||||
color: "orange.50",
|
||||
bgColor: "orange.900",
|
||||
},
|
||||
]}
|
||||
imgURL={assets["algorithmicFunds"]}
|
||||
|
@ -535,26 +531,26 @@ const Homepage = () => {
|
|||
},
|
||||
}}
|
||||
elementName={"element3"}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
badge={`For smart contract developers`}
|
||||
bullets={[
|
||||
{
|
||||
text: `See how people use your smart contracts`,
|
||||
icon: IoTelescopeSharp,
|
||||
color: "primary.50",
|
||||
bgColor: "primary.900",
|
||||
color: "blue.50",
|
||||
bgColor: "blue.900",
|
||||
},
|
||||
{
|
||||
text: `Set up alerts on suspicious activity`,
|
||||
icon: GiSuspicious,
|
||||
color: "primary.50",
|
||||
bgColor: "primary.900",
|
||||
color: "blue.50",
|
||||
bgColor: "blue.900",
|
||||
},
|
||||
{
|
||||
text: `Register webhooks to connect your off-chain infrastructure`,
|
||||
icon: GiHook,
|
||||
color: "primary.50",
|
||||
bgColor: "primary.900",
|
||||
color: "blue.50",
|
||||
bgColor: "blue.900",
|
||||
},
|
||||
]}
|
||||
imgURL={assets["smartDevelopers"]}
|
||||
|
@ -574,7 +570,7 @@ const Homepage = () => {
|
|||
href={"https://discord.gg/K56VNUQGvA"}
|
||||
size="lg"
|
||||
variant="solid"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
id="test"
|
||||
onClick={() => {
|
||||
mixpanel.get_distinct_id() &&
|
||||
|
|
|
@ -178,7 +178,7 @@ const Product = () => {
|
|||
<Text mb={3}>
|
||||
You can read{" "}
|
||||
<Link
|
||||
textColor="secondary.900"
|
||||
textColor="orange.900"
|
||||
isExternal
|
||||
href="https://github.com/bugout-dev/moonstream"
|
||||
>
|
||||
|
@ -186,7 +186,7 @@ const Product = () => {
|
|||
</Link>{" "}
|
||||
and keep track of our progress using{" "}
|
||||
<Link
|
||||
textColor="secondary.900"
|
||||
textColor="orange.900"
|
||||
isExternal
|
||||
href="https://github.com/bugout-dev/moonstream/milestones"
|
||||
>
|
||||
|
|
|
@ -53,7 +53,7 @@ const Register = () => {
|
|||
<InputGroup>
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your username here"
|
||||
name="username"
|
||||
ref={register({ required: "Username is required!" })}
|
||||
|
@ -62,7 +62,7 @@ const Register = () => {
|
|||
<Icon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.username && errors.username.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -71,7 +71,7 @@ const Register = () => {
|
|||
{!email && (
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your email here"
|
||||
name="email"
|
||||
ref={register({ required: "Email is required!" })}
|
||||
|
@ -80,7 +80,7 @@ const Register = () => {
|
|||
{email && (
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your email here"
|
||||
defaultValue={email}
|
||||
isReadOnly={true}
|
||||
|
@ -92,7 +92,7 @@ const Register = () => {
|
|||
<Icon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.email && errors.email.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -100,7 +100,7 @@ const Register = () => {
|
|||
<InputGroup>
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
autoComplete="new-password"
|
||||
placeholder="Add password"
|
||||
name="password"
|
||||
|
@ -111,7 +111,7 @@ const Register = () => {
|
|||
<Icon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -119,7 +119,7 @@ const Register = () => {
|
|||
<Button
|
||||
my={8}
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
width="100%"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
|
|
|
@ -54,7 +54,7 @@ const Entry = () => {
|
|||
<RouteButton
|
||||
variant="solid"
|
||||
size="md"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
href="/welcome"
|
||||
>
|
||||
Learn how to use moonstream
|
||||
|
|
|
@ -36,7 +36,7 @@ const Subscriptions = () => {
|
|||
pt: 2,
|
||||
mb: 4,
|
||||
borderBottom: "solid",
|
||||
borderColor: "primary.50",
|
||||
borderColor: "blue.50",
|
||||
borderBottomWidth: "2px",
|
||||
};
|
||||
|
||||
|
@ -72,7 +72,7 @@ const Subscriptions = () => {
|
|||
hidden={false}
|
||||
my={8}
|
||||
size="lg"
|
||||
color="primary.500"
|
||||
color="blue.500"
|
||||
thickness="4px"
|
||||
speed="1.5s"
|
||||
/>
|
||||
|
@ -90,7 +90,7 @@ const Subscriptions = () => {
|
|||
<Flex
|
||||
h="3rem"
|
||||
w="100%"
|
||||
bgColor="primary.50"
|
||||
bgColor="blue.50"
|
||||
borderTopRadius="xl"
|
||||
justifyContent="flex-end"
|
||||
alignItems="center"
|
||||
|
@ -99,7 +99,7 @@ const Subscriptions = () => {
|
|||
<Button
|
||||
onClick={() => newSubscriptionClicked(true)}
|
||||
mr={8}
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
variant="solid"
|
||||
size="sm"
|
||||
rightIcon={<AiOutlinePlusCircle />}
|
||||
|
@ -110,7 +110,7 @@ const Subscriptions = () => {
|
|||
<Button
|
||||
onClick={() => newSubscriptionClicked(false)}
|
||||
mr={8}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
size="sm"
|
||||
rightIcon={<AiOutlinePlusCircle />}
|
||||
|
|
|
@ -194,10 +194,7 @@ const Product = () => {
|
|||
We are always looking to hire new talents, regardless of their
|
||||
backgrounds. If you are interested in working with us, send us a
|
||||
message at{" "}
|
||||
<Link
|
||||
textColor="secondary.900"
|
||||
href="mailto: careers@moonstream.to"
|
||||
>
|
||||
<Link textColor="orange.900" href="mailto: careers@moonstream.to">
|
||||
careers@moonstream.to
|
||||
</Link>
|
||||
</Text>
|
||||
|
|
|
@ -82,7 +82,7 @@ const Welcome = () => {
|
|||
<StepProgress
|
||||
numSteps={ui.onboardingSteps.length}
|
||||
currentStep={ui.onboardingStep}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
buttonCallback={progressButtonCallback}
|
||||
buttonTitles={[
|
||||
"Moonstream basics",
|
||||
|
@ -278,7 +278,7 @@ const Welcome = () => {
|
|||
onChange={setProfile}
|
||||
value={profile}
|
||||
// fontWeight="bold"
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
// py={0}
|
||||
// my={0}
|
||||
>
|
||||
|
@ -361,7 +361,7 @@ const Welcome = () => {
|
|||
)}
|
||||
{!showSubscriptionForm && (
|
||||
<Button
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
variant="solid"
|
||||
onClick={() => setShowSubscriptionForm.on()}
|
||||
>
|
||||
|
@ -437,7 +437,7 @@ const Welcome = () => {
|
|||
<IconButton
|
||||
mr={4}
|
||||
// onClick={onOpen}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="ghost"
|
||||
icon={<FaFilter />}
|
||||
/>
|
||||
|
@ -482,7 +482,7 @@ const Welcome = () => {
|
|||
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
leftIcon={<ArrowLeftIcon />}
|
||||
variant="outline"
|
||||
hidden={ui.onboardingStep === 0}
|
||||
|
@ -498,8 +498,8 @@ const Welcome = () => {
|
|||
<Button
|
||||
colorScheme={
|
||||
ui.onboardingStep < ui.onboardingSteps.length - 1
|
||||
? `secondary`
|
||||
: `suggested`
|
||||
? `orange`
|
||||
: `green`
|
||||
}
|
||||
variant={
|
||||
ui.onboardingStep < ui.onboardingSteps.length - 1
|
||||
|
|
|
@ -44,7 +44,7 @@ const baseStyleControl = (props) => {
|
|||
},
|
||||
|
||||
_invalid: {
|
||||
borderColor: mode("unsafe.500", "unsafe.300")(props),
|
||||
borderColor: mode("red.500", "red.300")(props),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ const Checkbox = {
|
|||
control: baseStyleControl(props),
|
||||
}),
|
||||
defaultProps: {
|
||||
colorScheme: "primary",
|
||||
colorScheme: "blue",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
const baseStyle = {
|
||||
fontFamily: "heading",
|
||||
fontWeight: "bold",
|
||||
};
|
||||
|
||||
const sizes = {
|
||||
"4xl": {
|
||||
fontSize: ["6xl", null, "7xl"],
|
||||
lineHeight: 1,
|
||||
},
|
||||
"3xl": {
|
||||
fontSize: ["5xl", null, "6xl"],
|
||||
lineHeight: 1,
|
||||
},
|
||||
"2xl": {
|
||||
fontSize: ["4xl", null, "5xl"],
|
||||
lineHeight: [1.2, null, 1],
|
||||
},
|
||||
xl: {
|
||||
fontSize: ["3xl", null, "4xl"],
|
||||
lineHeight: [1.33, null, 1.2],
|
||||
},
|
||||
lg: {
|
||||
fontSize: ["2xl", null, "3xl"],
|
||||
lineHeight: [1.33, null, 1.2],
|
||||
},
|
||||
md: { fontSize: "xl", lineHeight: 1.2 },
|
||||
sm: { fontSize: "md", lineHeight: 1.2 },
|
||||
xs: { fontSize: "sm", lineHeight: 1.2 },
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
size: "xl",
|
||||
};
|
||||
|
||||
const variantTokensScreen = (props) => {
|
||||
const { colorScheme: c } = props;
|
||||
return {
|
||||
as: "h2",
|
||||
pt: 2,
|
||||
mb: 4,
|
||||
borderBottom: "solid",
|
||||
borderColor: `${c}.50`,
|
||||
borderBottomWidth: "2px",
|
||||
};
|
||||
};
|
||||
|
||||
const variants = {
|
||||
tokensScreen: variantTokensScreen,
|
||||
};
|
||||
|
||||
export default {
|
||||
baseStyle,
|
||||
sizes,
|
||||
defaultProps,
|
||||
variants,
|
||||
};
|
|
@ -82,7 +82,7 @@ const Input = {
|
|||
},
|
||||
|
||||
defaultProps: {
|
||||
colorScheme: "primary",
|
||||
colorScheme: "blue",
|
||||
size: "md",
|
||||
variant: "filled",
|
||||
},
|
||||
|
|
|
@ -11,11 +11,11 @@ const Menu = {
|
|||
textColor: `${c}.900`,
|
||||
|
||||
_hover: {
|
||||
bg: `secondary.800`,
|
||||
bg: `orange.800`,
|
||||
textColor: "white.100",
|
||||
},
|
||||
_focus: {
|
||||
bg: `secondary.700`,
|
||||
bg: `orange.700`,
|
||||
textColor: "white.100",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const baseStyle = {
|
||||
color: "primary.400",
|
||||
color: "blue.400",
|
||||
thickness: "4px",
|
||||
speed: "1.5s",
|
||||
my: 8,
|
||||
|
|
|
@ -19,7 +19,7 @@ const baseStyle = (props) => {
|
|||
};
|
||||
|
||||
const variantSuggestion = (props) => {
|
||||
const bg = mode("primary.700", "primary.300")(props);
|
||||
const bg = mode("blue.700", "blue.300")(props);
|
||||
return {
|
||||
"--tooltip-bg": `colors.${bg}`,
|
||||
px: "8px",
|
||||
|
@ -37,7 +37,7 @@ const variantSuggestion = (props) => {
|
|||
};
|
||||
|
||||
const variantOnboarding = (props) => {
|
||||
const bg = mode("secondary.700", "secondary.300")(props);
|
||||
const bg = mode("orange.700", "orange.300")(props);
|
||||
return {
|
||||
"--tooltip-bg": `colors.${bg}`,
|
||||
px: "8px",
|
||||
|
|
|
@ -10,6 +10,7 @@ import Checkbox from "./Checkbox";
|
|||
import Table from "./Table";
|
||||
import Tooltip from "./Tooltip";
|
||||
import Spinner from "./Spinner";
|
||||
import Heading from "./Heading";
|
||||
import { createBreakpoints } from "@chakra-ui/theme-tools";
|
||||
|
||||
const breakpointsCustom = createBreakpoints({
|
||||
|
@ -40,7 +41,7 @@ const theme = extendTheme({
|
|||
styles: {
|
||||
global: {
|
||||
body: {
|
||||
color: "primary.1200",
|
||||
color: "blue.1200",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -57,6 +58,7 @@ const theme = extendTheme({
|
|||
Table,
|
||||
Spinner,
|
||||
Tooltip,
|
||||
Heading,
|
||||
},
|
||||
|
||||
fonts: {
|
||||
|
@ -79,19 +81,6 @@ const theme = extendTheme({
|
|||
},
|
||||
|
||||
colors: {
|
||||
blue: {
|
||||
50: "#C8CEFC",
|
||||
100: "#B3BAF9",
|
||||
200: "#9EA6F6",
|
||||
300: "#8A92F3",
|
||||
400: "#757EF0",
|
||||
500: "#606AED",
|
||||
600: "#4B56EA",
|
||||
700: "#3742E7",
|
||||
800: "#222EE4",
|
||||
900: "#0D1AE1",
|
||||
},
|
||||
|
||||
brand: {
|
||||
100: "#212C8A",
|
||||
200: "#111442",
|
||||
|
@ -100,7 +89,7 @@ const theme = extendTheme({
|
|||
500: "##F29C38",
|
||||
},
|
||||
|
||||
primary: {
|
||||
blue: {
|
||||
0: "#FFFFFFFF",
|
||||
50: "#e9eaf4",
|
||||
100: "#d3d4e9",
|
||||
|
@ -150,7 +139,7 @@ const theme = extendTheme({
|
|||
200: "#F7F8FB",
|
||||
300: "#EAEBF7",
|
||||
},
|
||||
unsafe: {
|
||||
red: {
|
||||
0: "#FFFFFFFF",
|
||||
50: "#f9eaea",
|
||||
100: "#f3d6d6",
|
||||
|
@ -164,7 +153,7 @@ const theme = extendTheme({
|
|||
900: "#C53030",
|
||||
},
|
||||
|
||||
secondary: {
|
||||
orange: {
|
||||
0: "#FFFFFFFF",
|
||||
50: "#ffeee6",
|
||||
100: "#ffddcc",
|
||||
|
@ -178,21 +167,7 @@ const theme = extendTheme({
|
|||
900: "#FD5602",
|
||||
},
|
||||
|
||||
teal: {
|
||||
0: "#FFFFFFFF",
|
||||
50: "#AEDFEA",
|
||||
100: "#9ED8E5",
|
||||
200: "#8ED2E1",
|
||||
300: "#7ECBDD",
|
||||
400: "#6EC5D8",
|
||||
500: "#53B9D1",
|
||||
600: "#4EB8D0",
|
||||
700: "#3EB2CC",
|
||||
800: "#33A7C1",
|
||||
900: "#2F99B1",
|
||||
},
|
||||
|
||||
suggested: {
|
||||
green: {
|
||||
0: "#FFFFFFFF",
|
||||
50: "#e9f6dc",
|
||||
100: "#e9f6dc", //Duplicates 50!!!!
|
||||
|
|
|
@ -35,6 +35,9 @@ const AccountIconButton = (props) => {
|
|||
<RouterLink href="/account/security" passHref>
|
||||
<MenuItem>Security</MenuItem>
|
||||
</RouterLink>
|
||||
<RouterLink href="/account/tokens" passHref>
|
||||
<MenuItem>Access tokens</MenuItem>
|
||||
</RouterLink>
|
||||
</MenuGroup>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
|
|
|
@ -57,7 +57,7 @@ const AppNavbar = () => {
|
|||
<Popover usePortal>
|
||||
<PopoverTrigger>
|
||||
<IconButton
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="link"
|
||||
h="32px"
|
||||
size="lg"
|
||||
|
@ -81,12 +81,12 @@ const AppNavbar = () => {
|
|||
<Link
|
||||
href="mailto:support@moonstream.to"
|
||||
fontWeight="600"
|
||||
textColor="primary.500"
|
||||
textColor="blue.500"
|
||||
>
|
||||
support@moonstream.to
|
||||
</Link>
|
||||
</Text>
|
||||
<Text fontWeight="700" textColor="primary.500">
|
||||
<Text fontWeight="700" textColor="blue.500">
|
||||
<Link href="https://discord.gg/K56VNUQGvA">Discord</Link>
|
||||
</Text>
|
||||
</PopoverBody>
|
||||
|
@ -102,7 +102,7 @@ const AppNavbar = () => {
|
|||
<Flex width="100%" px={2}>
|
||||
<Spacer />
|
||||
<Flex placeSelf="flex-end">
|
||||
<ButtonGroup spacing={4} colorScheme="secondary">
|
||||
<ButtonGroup spacing={4} colorScheme="orange">
|
||||
{ALL_NAV_PATHES.map((item, idx) => (
|
||||
<RouteButton
|
||||
key={`${idx}-${item.title}-landing-all-links`}
|
||||
|
@ -130,7 +130,7 @@ const AppNavbar = () => {
|
|||
</ButtonGroup>
|
||||
<SupportPopover />
|
||||
<AccountIconButton
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="link"
|
||||
color="gray.100"
|
||||
size="lg"
|
||||
|
@ -234,7 +234,7 @@ const AppNavbar = () => {
|
|||
alignContent="center"
|
||||
h="32px"
|
||||
size={iconSize}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
|
|
|
@ -71,7 +71,7 @@ const ChangePassword = () => {
|
|||
<CustomIcon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.newPassword && errors.newPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -90,7 +90,7 @@ const ChangePassword = () => {
|
|||
<CustomIcon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.newPassword && errors.newPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -109,7 +109,7 @@ const ChangePassword = () => {
|
|||
<CustomIcon icon="password" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.confirmPassword && errors.confirmPassword.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -119,7 +119,7 @@ const ChangePassword = () => {
|
|||
<Button
|
||||
my={8}
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
|
|
|
@ -58,7 +58,6 @@ const ColorSelector = (props) => {
|
|||
</Text>{" "}
|
||||
<IconButton
|
||||
size="md"
|
||||
// colorScheme="primary"
|
||||
color={"white.100"}
|
||||
_hover={{ bgColor: { color } }}
|
||||
bgColor={color}
|
||||
|
@ -87,7 +86,7 @@ const ColorSelector = (props) => {
|
|||
props.callback(color);
|
||||
onClose();
|
||||
}}
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
variant="outline"
|
||||
>
|
||||
Apply
|
||||
|
|
|
@ -23,7 +23,7 @@ const ConfirmationRequest = (props) => {
|
|||
<PopoverFooter>
|
||||
<Button
|
||||
onClick={onClose}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
|
@ -34,7 +34,7 @@ const ConfirmationRequest = (props) => {
|
|||
props.onConfirm();
|
||||
onClose();
|
||||
}}
|
||||
colorScheme="unsafe"
|
||||
colorScheme="red"
|
||||
variant="solid"
|
||||
size="sm"
|
||||
>
|
||||
|
|
|
@ -48,7 +48,7 @@ const ArrowCTA = (props) => {
|
|||
ref={box1Ref}
|
||||
boxShadow="md"
|
||||
variant="solid"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
className="MoonStockSpeciality element1"
|
||||
w={["180px", "180px", "250px", null, "250px"]}
|
||||
onClick={props.button1.onClick}
|
||||
|
@ -65,7 +65,7 @@ const ArrowCTA = (props) => {
|
|||
ref={box2Ref}
|
||||
boxShadow="md"
|
||||
variant="solid"
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
className="MoonStockSpeciality element2"
|
||||
w={["180px", "180px", "250px", null, "250px"]}
|
||||
onClick={props.button2.onClick}
|
||||
|
@ -82,7 +82,7 @@ const ArrowCTA = (props) => {
|
|||
ref={box3Ref}
|
||||
boxShadow="md"
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
w={["180px", "180px", "250px", null, "250px"]}
|
||||
onClick={props.button3.onClick}
|
||||
>
|
||||
|
|
|
@ -29,7 +29,7 @@ const CopyButton = (props) => {
|
|||
<IconButton
|
||||
onClick={onCopy}
|
||||
icon={<BiCopy />}
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
/>
|
||||
|
|
|
@ -257,7 +257,7 @@ const EntriesNavigation = () => {
|
|||
{filter.direction === DIRECTIONS.SOURCE && (
|
||||
<Select
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
name="address"
|
||||
onChange={handleAddressChange(idx)}
|
||||
>
|
||||
|
@ -298,7 +298,7 @@ const EntriesNavigation = () => {
|
|||
)}
|
||||
<IconButton
|
||||
placeItems="center"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="ghost"
|
||||
onClick={() => dropNewFilterArrayItem(idx)}
|
||||
icon={<ImCancelCircle />}
|
||||
|
@ -311,7 +311,7 @@ const EntriesNavigation = () => {
|
|||
<MenuButton
|
||||
as={Button}
|
||||
mt={4}
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
variant="solid"
|
||||
>
|
||||
Add filter row
|
||||
|
@ -357,7 +357,7 @@ const EntriesNavigation = () => {
|
|||
</DrawerBody>
|
||||
<DrawerFooter pb={16} placeContent="center">
|
||||
<Button
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
variant="solid"
|
||||
// type="submit"
|
||||
onClick={() => handleFilterSubmit()}
|
||||
|
@ -377,7 +377,7 @@ const EntriesNavigation = () => {
|
|||
mx={1}
|
||||
size="lg"
|
||||
variant="solid"
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
>
|
||||
{filter?.type === FILTER_TYPES.ADDRESS && (
|
||||
<TagLabel>
|
||||
|
@ -401,7 +401,7 @@ const EntriesNavigation = () => {
|
|||
<IconButton
|
||||
mr={4}
|
||||
onClick={onOpen}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="ghost"
|
||||
icon={<FaFilter />}
|
||||
/>
|
||||
|
@ -428,7 +428,7 @@ const EntriesNavigation = () => {
|
|||
loadNewesEventHandler();
|
||||
}}
|
||||
variant="outline"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
>
|
||||
Load newer events
|
||||
</Button>
|
||||
|
@ -437,7 +437,7 @@ const EntriesNavigation = () => {
|
|||
isLoading
|
||||
loadingText="Loading"
|
||||
variant="outline"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
></Button>
|
||||
)}
|
||||
</Stack>
|
||||
|
@ -468,7 +468,7 @@ const EntriesNavigation = () => {
|
|||
loadPreviousEventHandler();
|
||||
}}
|
||||
variant="outline"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
>
|
||||
Load older events
|
||||
</Button>
|
||||
|
@ -482,7 +482,7 @@ const EntriesNavigation = () => {
|
|||
isLoading
|
||||
loadingText="Loading"
|
||||
variant="outline"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
></Button>
|
||||
)}
|
||||
</Center>
|
||||
|
@ -495,7 +495,7 @@ const EntriesNavigation = () => {
|
|||
<Spinner
|
||||
mt="50%"
|
||||
size="lg"
|
||||
color="primary.500"
|
||||
color="blue.500"
|
||||
thickness="4px"
|
||||
speed="1.5s"
|
||||
/>
|
||||
|
|
|
@ -110,9 +110,9 @@ const Footer = () => (
|
|||
mx={2}
|
||||
mb={2}
|
||||
borderRadius="13px"
|
||||
bg="primary.800"
|
||||
bg="blue.800"
|
||||
boxSize={["3rem", "4rem", "6rem", null, "6rem"]}
|
||||
_hover={{ bg: "primary.600" }}
|
||||
_hover={{ bg: "blue.600" }}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
href={icon.link}
|
||||
|
@ -123,7 +123,7 @@ const Footer = () => (
|
|||
</Link>
|
||||
))}
|
||||
</Flex>
|
||||
<Text pt={24} alignSelf="flex-end" textColor="primary.500">
|
||||
<Text pt={24} alignSelf="flex-end" textColor="blue.500">
|
||||
All rights reserved.2021
|
||||
</Text>
|
||||
</Flex>
|
||||
|
|
|
@ -36,7 +36,7 @@ const ForgotPassword = ({ toggleModal }) => {
|
|||
<FormControl isInvalid={errors.email} my={4}>
|
||||
<InputGroup>
|
||||
<Input
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="filled"
|
||||
placeholder="Your email here"
|
||||
name="email"
|
||||
|
@ -46,14 +46,14 @@ const ForgotPassword = ({ toggleModal }) => {
|
|||
<CustomIcon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.email && errors.email.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
width="100%"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
|
|
|
@ -36,7 +36,7 @@ const RequestIntegration = ({ toggleModal, title, formId }) => {
|
|||
region="na1"
|
||||
portalId="8018701"
|
||||
formId={formId}
|
||||
loading={<Spinner colorScheme="primary" speed="1s" />}
|
||||
loading={<Spinner colorScheme="blue" speed="1s" />}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -26,7 +26,7 @@ const LandingNavbar = () => {
|
|||
<>
|
||||
<IconButton
|
||||
alignSelf="flex-start"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="solid"
|
||||
onClick={() => ui.setSidebarToggled(!ui.sidebarToggled)}
|
||||
icon={<HamburgerIcon />}
|
||||
|
@ -57,12 +57,7 @@ const LandingNavbar = () => {
|
|||
{!ui.isMobileView && (
|
||||
<>
|
||||
<Spacer />
|
||||
<ButtonGroup
|
||||
variant="link"
|
||||
colorScheme="secondary"
|
||||
spacing={4}
|
||||
pr={16}
|
||||
>
|
||||
<ButtonGroup variant="link" colorScheme="orange" spacing={4} pr={16}>
|
||||
{ALL_NAV_PATHES.map((item, idx) => (
|
||||
<RouteButton
|
||||
key={`${idx}-${item.title}-landing-all-links`}
|
||||
|
@ -79,7 +74,7 @@ const LandingNavbar = () => {
|
|||
<RouterLink href="/stream" passHref>
|
||||
<Button
|
||||
as={Link}
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
fontWeight="400"
|
||||
|
@ -111,7 +106,7 @@ const LandingNavbar = () => {
|
|||
</Button>
|
||||
)}
|
||||
{ui.isLoggedIn && (
|
||||
<ChakraAccountIconButton variant="link" colorScheme="secondary" />
|
||||
<ChakraAccountIconButton variant="link" colorScheme="orange" />
|
||||
)}
|
||||
</ButtonGroup>
|
||||
</>
|
||||
|
@ -119,7 +114,7 @@ const LandingNavbar = () => {
|
|||
{ui.isLoggedIn && ui.isMobileView && (
|
||||
<>
|
||||
<Spacer />
|
||||
<ChakraAccountIconButton variant="link" colorScheme="secondary" />
|
||||
<ChakraAccountIconButton variant="link" colorScheme="orange" />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -9,11 +9,11 @@ const Modal = ({ children, onClose }) => (
|
|||
<Flex onClick={onClose} css={styles.modal} zIndex={100002}>
|
||||
<Flex onClick={(e) => e.stopPropagation()} css={styles.flex}>
|
||||
<Image
|
||||
color="primary.900"
|
||||
color="blue.900"
|
||||
height="24px"
|
||||
width="22px"
|
||||
sx={{ filter: "grayscale: 50%" }}
|
||||
fill="primary.800"
|
||||
fill="blue.800"
|
||||
src={
|
||||
"https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/logo-black.svg"
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ const Navbar = () => {
|
|||
id="Navbar"
|
||||
minH="3rem"
|
||||
maxH="3rem"
|
||||
bgColor="primary.1200"
|
||||
bgColor="blue.1200"
|
||||
direction="row"
|
||||
w="100%"
|
||||
overflow="hidden"
|
||||
|
|
|
@ -192,7 +192,7 @@ const _NewSubscription = ({
|
|||
name="address"
|
||||
ref={register({ required: "address is required!" })}
|
||||
></Input>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors?.address && errors?.address.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -222,7 +222,7 @@ const _NewSubscription = ({
|
|||
>
|
||||
<IconButton
|
||||
size="md"
|
||||
// colorScheme="primary"
|
||||
// colorScheme="blue"
|
||||
color={"white.100"}
|
||||
_hover={{ bgColor: { color } }}
|
||||
bgColor={color}
|
||||
|
@ -278,7 +278,7 @@ const _NewSubscription = ({
|
|||
<GithubPicker onChangeComplete={handleChangeColorComplete} />
|
||||
</>
|
||||
)}
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors?.color && errors?.color.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -286,7 +286,7 @@ const _NewSubscription = ({
|
|||
<ButtonGroup direction="row" justifyContent="flex-end" w="100%">
|
||||
<Button
|
||||
type="submit"
|
||||
colorScheme="suggested"
|
||||
colorScheme="green"
|
||||
isLoading={createSubscription.isLoading}
|
||||
>
|
||||
Confirm
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
import React, { 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="red.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="red.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;
|
|
@ -9,7 +9,7 @@ const PasswordInput = ({ placeholder, name }, ref) => {
|
|||
<InputGroup>
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
autoComplete="current-password"
|
||||
placeholder={placeholder}
|
||||
name={name}
|
||||
|
|
|
@ -29,10 +29,10 @@ const RadioCard = (props) => {
|
|||
borderColor: "gray.300",
|
||||
}}
|
||||
_checked={{
|
||||
// bg: "secondary.900",
|
||||
// bg: "orange.900",
|
||||
|
||||
color: "secondary.900",
|
||||
borderColor: "secondary.900",
|
||||
color: "orange.900",
|
||||
borderColor: "orange.900",
|
||||
borderWidth: "4px",
|
||||
}}
|
||||
justifyContent="center"
|
||||
|
|
|
@ -33,7 +33,7 @@ const Sidebar = () => {
|
|||
<IconButton
|
||||
ml={4}
|
||||
justifySelf="flex-start"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
aria-label="App navigation"
|
||||
icon={
|
||||
ui.isMobileView ? (
|
||||
|
|
|
@ -49,7 +49,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
_placeholder={{ textColor: "gray.1200" }}
|
||||
autoComplete="username"
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your Moonstream username"
|
||||
name="username"
|
||||
{...register("username", { required: true })}
|
||||
|
@ -59,7 +59,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
<CustomIcon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.username && errors.username.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -69,7 +69,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
name="password"
|
||||
ref={register({ required: "Password is required!" })}
|
||||
/>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -79,7 +79,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
type="submit"
|
||||
width="100%"
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Login
|
||||
|
@ -89,7 +89,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
{" "}
|
||||
<Box
|
||||
cursor="pointer"
|
||||
color="primary.800"
|
||||
color="blue.800"
|
||||
as="span"
|
||||
onClick={() => toggleModal("forgot")}
|
||||
>
|
||||
|
@ -100,12 +100,12 @@ const SignIn = ({ toggleModal }) => {
|
|||
<Text textAlign="center" fontSize="md" color="gray.1200">
|
||||
{/* Don`t have an account?{" "} */}
|
||||
We are in early access. If you would like to use Moonstream,{" "}
|
||||
<Link href={"https://discord.gg/V3tWaP36"} color="secondary.900">
|
||||
<Link href={"https://discord.gg/V3tWaP36"} color="orange.900">
|
||||
contact us on Discord.
|
||||
</Link>
|
||||
{/* <Box
|
||||
cursor="pointer"
|
||||
color="primary.800"
|
||||
color="blue.800"
|
||||
as="span"
|
||||
onClick={() => toggleModal("register")}
|
||||
>
|
||||
|
|
|
@ -46,7 +46,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
<InputGroup>
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your username here"
|
||||
name="username"
|
||||
ref={register({ required: "Username is required!" })}
|
||||
|
@ -55,7 +55,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
<CustomIcon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.username && errors.username.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -63,7 +63,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
<InputGroup>
|
||||
<Input
|
||||
variant="filled"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="Your email here"
|
||||
name="email"
|
||||
ref={register({ required: "Email is required!" })}
|
||||
|
@ -72,7 +72,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
<CustomIcon icon="name" />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.email && errors.email.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -82,7 +82,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
name="password"
|
||||
ref={register({ required: "Password is required!" })}
|
||||
/>
|
||||
<FormErrorMessage color="unsafe.400" pl="1">
|
||||
<FormErrorMessage color="red.400" pl="1">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
|
@ -90,7 +90,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
<Button
|
||||
my={8}
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
width="100%"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
|
@ -103,7 +103,7 @@ const SignUp = ({ toggleModal }) => {
|
|||
Already have an account?{" "}
|
||||
<Box
|
||||
cursor="pointer"
|
||||
color="primary.400"
|
||||
color="blue.400"
|
||||
as="span"
|
||||
onClick={() => toggleModal("login")}
|
||||
>
|
||||
|
|
|
@ -133,7 +133,7 @@ const SplitWithImage = ({
|
|||
</Text>
|
||||
</Stack>
|
||||
<Heading>{title}</Heading>
|
||||
<Text color={`primary.500`} fontSize={"lg"}>
|
||||
<Text color={`blue.500`} fontSize={"lg"}>
|
||||
{body}
|
||||
</Text>
|
||||
<Stack
|
||||
|
@ -184,7 +184,7 @@ const SplitWithImage = ({
|
|||
mt={[0, 0, null, 16]}
|
||||
size={socialButton ? buttonSize.double : buttonSize.single}
|
||||
variant="outline"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
leftIcon={<FaGithubSquare />}
|
||||
>
|
||||
git clone moonstream
|
||||
|
|
|
@ -77,7 +77,7 @@ const StreamEntry_ = ({ entry, showOnboardingTooltips, className }) => {
|
|||
variant="solid"
|
||||
px={0}
|
||||
minW="24px"
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
icon={<ArrowRightIcon w="24px" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
|
|
@ -50,7 +50,7 @@ const SubscriptionsList = ({ emptyCTA }) => {
|
|||
borderColor="gray.200"
|
||||
borderWidth="1px"
|
||||
variant="simple"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
justifyContent="center"
|
||||
borderBottomRadius="xl"
|
||||
alignItems="baseline"
|
||||
|
@ -81,7 +81,7 @@ const SubscriptionsList = ({ emptyCTA }) => {
|
|||
</Td>
|
||||
<Td py={0}>
|
||||
<Editable
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
placeholder="enter note here"
|
||||
defaultValue={subscription.label}
|
||||
onSubmit={(nextValue) =>
|
||||
|
@ -125,7 +125,7 @@ const SubscriptionsList = ({ emptyCTA }) => {
|
|||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
icon={<DeleteIcon />}
|
||||
/>
|
||||
</ConfirmationRequest>
|
||||
|
@ -143,7 +143,7 @@ const SubscriptionsList = ({ emptyCTA }) => {
|
|||
return (
|
||||
<Container>
|
||||
{` You don't have any subscriptions at the moment.`}
|
||||
{emptyCTA && <Button variant="suggested">Create one</Button>}
|
||||
{emptyCTA && <Button variant="green">Create one</Button>}
|
||||
</Container>
|
||||
);
|
||||
} else if (subscriptionsCache.isLoading) {
|
||||
|
|
|
@ -16,7 +16,7 @@ const Tags = ({ tags }) => {
|
|||
{displayTags?.map((tag, index) => (
|
||||
<Tag
|
||||
variant="subtle"
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
key={`${tag}-${index}`}
|
||||
zIndex={1}
|
||||
>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
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, ConfirmationRequest, NewTokenTr } from ".";
|
||||
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="blue"
|
||||
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="blue"
|
||||
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;
|
|
@ -0,0 +1,131 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Box,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
FormControl,
|
||||
FormErrorMessage,
|
||||
Stack,
|
||||
Button,
|
||||
Input,
|
||||
chakra,
|
||||
} from "@chakra-ui/react";
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import { Icon } from "../../src/Theme";
|
||||
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useUser, useTokens } from "../core/hooks";
|
||||
|
||||
const TokenRequest = ({ setNewToken, onClose }) => {
|
||||
const { user } = useUser();
|
||||
const { createToken } = useTokens();
|
||||
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 (createToken.data?.data) {
|
||||
setNewToken(createToken.data.data);
|
||||
onClose();
|
||||
}
|
||||
}, [createToken.data, setNewToken, onClose]);
|
||||
|
||||
const formStyle = {
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
minWidth: "100px",
|
||||
flexFlow: "row wrap-reverse",
|
||||
aligntContent: "flex-end",
|
||||
width: "100%",
|
||||
};
|
||||
|
||||
if (!user) return ""; //loading...
|
||||
|
||||
return (
|
||||
<Box px={1} py={4}>
|
||||
<form onSubmit={handleSubmit(createToken.mutate)} style={formStyle}>
|
||||
<Stack direction="column" spacing={4} w="100%">
|
||||
<Stack direction="column" spacing={1}>
|
||||
<chakra.label for="pwd">API key label:</chakra.label>
|
||||
<Input
|
||||
w="100%"
|
||||
ref={register}
|
||||
name="token_note"
|
||||
placeholder="My API key label"
|
||||
type="search"
|
||||
/>
|
||||
</Stack>
|
||||
<Stack direction="column" spacing={1}>
|
||||
<chakra.label for="pwd">Password:</chakra.label>
|
||||
<FormControl isInvalid={errors.password}>
|
||||
<InputGroup minWidth="300px">
|
||||
<InputLeftElement onClick={togglePassword}>
|
||||
<Icon icon="password" />
|
||||
</InputLeftElement>
|
||||
|
||||
<Input
|
||||
id="pwd"
|
||||
colorScheme="blue"
|
||||
variant="filled"
|
||||
isDisabled={createToken.isLoading}
|
||||
placeholder="This action requires your password to confirm"
|
||||
name="password"
|
||||
type={showPassword}
|
||||
ref={(e) => {
|
||||
register(e, { required: "Password is required!" });
|
||||
PasswordRef.current = e;
|
||||
}}
|
||||
/>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="red.400" pl="1" justifyContent="Center">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
|
||||
<Input
|
||||
type="hidden"
|
||||
ref={register}
|
||||
name="username"
|
||||
defaultValue={user?.username}
|
||||
/>
|
||||
<Stack pt={9} direction="row" justifyContent="flex-end" w="100%">
|
||||
<Button
|
||||
m={0}
|
||||
variant="solid"
|
||||
colorScheme="blue"
|
||||
type="submit"
|
||||
isLoading={createToken.isLoading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<Button
|
||||
variant="solid"
|
||||
colorScheme="red"
|
||||
type="submit"
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default TokenRequest;
|
|
@ -0,0 +1,88 @@
|
|||
import React from "react";
|
||||
import { Skeleton, IconButton } from "@chakra-ui/react";
|
||||
import {
|
||||
Table,
|
||||
Th,
|
||||
Td,
|
||||
Tr,
|
||||
Thead,
|
||||
Tbody,
|
||||
Editable,
|
||||
EditableInput,
|
||||
EditablePreview,
|
||||
} from "@chakra-ui/react";
|
||||
import { DeleteIcon } from "@chakra-ui/icons";
|
||||
import moment from "moment";
|
||||
import CopyButton from "./CopyButton";
|
||||
|
||||
const List = ({ data, revoke, isLoading, updateCallback }) => {
|
||||
const userToken = localStorage.getItem("BUGOUT_ACCESS_TOKEN");
|
||||
|
||||
if (data) {
|
||||
return (
|
||||
<Table
|
||||
variant="simple"
|
||||
colorScheme="blue"
|
||||
justifyContent="center"
|
||||
alignItems="baseline"
|
||||
h="auto"
|
||||
size="sm"
|
||||
>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Token</Th>
|
||||
<Th>Date Created</Th>
|
||||
<Th>Note</Th>
|
||||
<Th>Actions</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{data.token.map((token) => {
|
||||
if (token.active) {
|
||||
if (userToken !== token.id) {
|
||||
return (
|
||||
<Tr key={`token-row-${token.id}`}>
|
||||
<Td mr={4} p={0}>
|
||||
<CopyButton>{token.id}</CopyButton>
|
||||
</Td>
|
||||
<Td py={0}>{moment(token.created_at).format("L")}</Td>
|
||||
<Td py={0}>
|
||||
<Editable
|
||||
colorScheme="blue"
|
||||
placeholder="enter note here"
|
||||
defaultValue={token.note}
|
||||
onSubmit={(nextValue) =>
|
||||
updateCallback({ token: token.id, note: nextValue })
|
||||
}
|
||||
>
|
||||
<EditablePreview
|
||||
maxW="40rem"
|
||||
_placeholder={{ color: "black" }}
|
||||
/>
|
||||
<EditableInput maxW="40rem" />
|
||||
</Editable>
|
||||
</Td>
|
||||
<Td py={0}>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
colorScheme="blue"
|
||||
onClick={() => revoke(token.id)}
|
||||
icon={<DeleteIcon />}
|
||||
/>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
} else return null;
|
||||
} else return null;
|
||||
})}
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
} else if (isLoading) {
|
||||
return <Skeleton />;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
export default List;
|
|
@ -215,7 +215,7 @@ const EthereumWhalewatchCard_ = ({
|
|||
<Box boxSize="min-content">
|
||||
<IconButton
|
||||
onClick={() => subscribeClicked(whaleType)}
|
||||
colorScheme="secondary"
|
||||
colorScheme="orange"
|
||||
variant="outline"
|
||||
m={0}
|
||||
boxSize="24px"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { queryCacheProps as hookCommon } from "./hookCommon";
|
||||
export { default as hookCommon } from "./hookCommon";
|
||||
export { default as useAuthResultHandler } from "./useAuthResultHandler";
|
||||
export { default as useChangePassword } from "./useChangePassword";
|
||||
export { default as useClientID } from "./useClientID";
|
||||
|
@ -15,8 +15,10 @@ export { default as useResetPassword } from "./useResetPassword";
|
|||
export { default as useRouter } from "./useRouter";
|
||||
export { default as useSignUp } from "./useSignUp";
|
||||
export { default as useStorage } from "./useStorage";
|
||||
export { default as useStream } from "./useStream";
|
||||
export { default as useStripe } from "./useStripe";
|
||||
export { default as useSubscriptions } from "./useSubscriptions";
|
||||
export { default as useToast } from "./useToast";
|
||||
export { default as useTokens } from "./useTokens";
|
||||
export { default as useTxInfo } from "./useTxInfo";
|
||||
export { default as useUser } from "./useUser";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useToast as useChakraToast, Box } from "@chakra-ui/react";
|
||||
import React, { useCallback } from "react";
|
||||
import { useToast as useChakraToast } from "@chakra-ui/react";
|
||||
import { useCallback } from "react";
|
||||
import mixpanel from "mixpanel-browser";
|
||||
import { MIXPANEL_EVENTS } from "../providers/AnalyticsProvider/constants";
|
||||
|
||||
|
@ -7,37 +7,28 @@ const useToast = () => {
|
|||
const chakraToast = useChakraToast();
|
||||
|
||||
const toast = useCallback(
|
||||
(message, type) => {
|
||||
(message, type, title) => {
|
||||
const userTitle = title ?? message?.response?.statusText ?? type;
|
||||
|
||||
const userMessage =
|
||||
message?.response?.data?.detail ??
|
||||
message ??
|
||||
(userTitle === type ? "" : type);
|
||||
|
||||
if (mixpanel.get_distinct_id() && type === "error") {
|
||||
mixpanel.track(`${MIXPANEL_EVENTS.TOAST_ERROR_DISPLAYED}`, {
|
||||
status: message?.response?.status,
|
||||
detail: message?.response?.data.detail,
|
||||
title: userTitle,
|
||||
detail: userMessage,
|
||||
});
|
||||
}
|
||||
const background = type === "error" ? "unsafe.500" : "suggested.500";
|
||||
const userMessage =
|
||||
type === "error"
|
||||
? message?.response
|
||||
? `${message.response.data.detail}..`
|
||||
: message
|
||||
? `Error:${message}`
|
||||
: "Something is very wrong"
|
||||
: message;
|
||||
|
||||
chakraToast({
|
||||
position: "bottom",
|
||||
title: userTitle,
|
||||
description: userMessage,
|
||||
status: type,
|
||||
duration: 3000,
|
||||
render: () => (
|
||||
<Box
|
||||
shadow="rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;"
|
||||
m={3}
|
||||
p={3}
|
||||
color="white.100"
|
||||
bg={background}
|
||||
>
|
||||
{userMessage}
|
||||
</Box>
|
||||
),
|
||||
});
|
||||
},
|
||||
[chakraToast]
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import useToast from "./useToast";
|
||||
import { useMutation } from "react-query";
|
||||
import { AuthService } from "../services";
|
||||
|
||||
const useTokens = () => {
|
||||
const toast = useToast();
|
||||
const {
|
||||
mutate: list,
|
||||
isLoading,
|
||||
error,
|
||||
data,
|
||||
} = useMutation(AuthService.getTokenList);
|
||||
const { mutate: revoke } = useMutation(AuthService.revokeToken, {
|
||||
onSuccess: () => {
|
||||
toast("Token destroyed", "success");
|
||||
list();
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: update } = useMutation(AuthService.updateToken, {
|
||||
onSuccess: () => {
|
||||
list();
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const createToken = useMutation(AuthService.login, {
|
||||
onSuccess: () => {
|
||||
list();
|
||||
toast("Created new token", "success");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
createToken,
|
||||
list,
|
||||
update,
|
||||
revoke,
|
||||
isLoading,
|
||||
data,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTokens;
|
|
@ -3,11 +3,13 @@ import { http } from "../utils";
|
|||
const API_URL = process.env.NEXT_PUBLIC_MOONSTREAM_API_URL;
|
||||
export const AUTH_URL = `${API_URL}/users`;
|
||||
|
||||
export const login = ({ username, password }) => {
|
||||
export const login = ({ username, password, token_note }) => {
|
||||
const data = new FormData();
|
||||
data.append("username", username);
|
||||
data.append("password", password);
|
||||
|
||||
if (token_note) {
|
||||
data.append("token_note", token_note);
|
||||
}
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/token`,
|
||||
|
@ -74,3 +76,28 @@ export const changePassword = ({ currentPassword, newPassword }) => {
|
|||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const getTokenList = () => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: `${AUTH_URL}/tokens`,
|
||||
});
|
||||
};
|
||||
|
||||
export const updateToken = ({ note, token }) => {
|
||||
const data = new FormData();
|
||||
data.append("token_note", note);
|
||||
data.append("access_token", token);
|
||||
return http({
|
||||
method: "PUT",
|
||||
url: `${AUTH_URL}/token`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const revokeToken = (token) => {
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/revoke/${token}`,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ const RootLayout = (props) => {
|
|||
minH={["6.5rem", "4.5rem", "3rem", null]}
|
||||
h={["6.5rem", "4.5rem", "3rem", null]}
|
||||
placeContent="center"
|
||||
bgColor="suggested.900"
|
||||
bgColor="green.900"
|
||||
boxShadow="md"
|
||||
position="relative"
|
||||
className="banner"
|
||||
|
@ -54,15 +54,12 @@ const RootLayout = (props) => {
|
|||
{" "}
|
||||
<Text
|
||||
fontWeight="600"
|
||||
textColor="primary.900"
|
||||
textColor="blue.900"
|
||||
fontSize={["sm", "sm", "md", null]}
|
||||
>
|
||||
Join early. Our first 1000 users get free lifetime access to
|
||||
blockchain analytics. Contact our team on{" "}
|
||||
<Link
|
||||
href={"https://discord.gg/V3tWaP36"}
|
||||
color="secondary.900"
|
||||
>
|
||||
<Link href={"https://discord.gg/V3tWaP36"} color="orange.900">
|
||||
Discord
|
||||
</Link>
|
||||
</Text>
|
||||
|
@ -73,7 +70,7 @@ const RootLayout = (props) => {
|
|||
top="0"
|
||||
right="0"
|
||||
icon={<CloseIcon />}
|
||||
colorScheme="primary"
|
||||
colorScheme="blue"
|
||||
variant="ghost"
|
||||
onClick={() => setShowBanner(false)}
|
||||
/>
|
||||
|
|
Ładowanie…
Reference in New Issue