kopia lustrzana https://github.com/bugout-dev/moonstream
Merge pull request #37 from zomglings/frontend-api-auth
Frontend now authenticates with Moonstream API.pull/39/head
commit
5946abb75b
|
@ -56,8 +56,8 @@ whitelist_paths.update(
|
|||
{
|
||||
"/users": "POST",
|
||||
"/users/token": "POST",
|
||||
"/users/password/restore": "POST",
|
||||
"/users/password/reset": "POST",
|
||||
"/users/password/reset_initiate": "POST",
|
||||
"/users/password/reset_complete": "POST",
|
||||
}
|
||||
)
|
||||
app.add_middleware(BroodAuthMiddleware, whitelist=whitelist_paths)
|
||||
|
@ -87,11 +87,10 @@ async def get_user_handler(request: Request) -> BugoutUser:
|
|||
return user
|
||||
|
||||
|
||||
@app.post("/password/restore", tags=["users"], response_model=Dict[str, Any])
|
||||
async def restore_password_handler(request: Request) -> Dict[str, Any]:
|
||||
user = request.state.user
|
||||
@app.post("/password/reset_initiate", tags=["users"], response_model=Dict[str, Any])
|
||||
async def restore_password_handler(email: str = Form(...)) -> Dict[str, Any]:
|
||||
try:
|
||||
response = bc.restore_password(email=user.email)
|
||||
response = bc.restore_password(email=email)
|
||||
except BugoutResponseException as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.detail)
|
||||
except Exception as e:
|
||||
|
@ -99,7 +98,7 @@ async def restore_password_handler(request: Request) -> Dict[str, Any]:
|
|||
return response
|
||||
|
||||
|
||||
@app.post("/password/reset", tags=["users"], response_model=BugoutUser)
|
||||
@app.post("/password/reset_complete", tags=["users"], response_model=BugoutUser)
|
||||
async def reset_password_handler(
|
||||
reset_id: str = Form(...), new_password: str = Form(...)
|
||||
) -> BugoutUser:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import FourOThree from "../src/components/FourOThree";
|
||||
|
||||
const Page403 = () => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import FourOFour from "../src/components/FourOFour";
|
||||
|
||||
const Page404 = () => {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
|
||||
import { React } from "react";
|
||||
import Document, { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
export default class MyDocument extends Document {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
type Data = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export default function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>
|
||||
) {
|
||||
res.status(200).json({ name: 'John Doe' })
|
||||
}
|
|
@ -17,7 +17,7 @@ import {
|
|||
import { Grid, GridItem } from "@chakra-ui/react";
|
||||
import { useUser, useAnalytics, useModals, useRouter } from "../src/core/hooks";
|
||||
import { openPopupWidget, InlineWidget } from "react-calendly";
|
||||
import TrustedBadge from "../src/components/TrustedBadge"
|
||||
import TrustedBadge from "../src/components/TrustedBadge";
|
||||
import { getLayout } from "../src/layouts";
|
||||
|
||||
const TEXT_PROPS = {
|
||||
|
|
|
@ -30,7 +30,7 @@ function PriceWrapper({ children }) {
|
|||
);
|
||||
}
|
||||
|
||||
const Pricing = (props) => {
|
||||
const Pricing = () => {
|
||||
return (
|
||||
<Box py={12} minH="100vh">
|
||||
<VStack spacing={2} textAlign="center">
|
||||
|
@ -225,20 +225,6 @@ export async function getStaticProps() {
|
|||
"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 },
|
||||
};
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
ModalOverlay,
|
||||
ModalContent,
|
||||
} from "@chakra-ui/react";
|
||||
import { headingStyle } from "./index";
|
||||
import NewSubscription from "../src/components/NewSubscription";
|
||||
import { AiOutlinePlusCircle } from "react-icons/ai";
|
||||
|
||||
|
@ -26,6 +25,18 @@ const Subscriptions = () => {
|
|||
|
||||
document.title = `My Subscriptions`;
|
||||
|
||||
// TODO(zomglings): This should be imported from some common location. For now, copied from
|
||||
// pages/account/security.js. It was attempting to get imported from "./index", but is not defined
|
||||
// there.
|
||||
const headingStyle = {
|
||||
as: "h2",
|
||||
pt: 2,
|
||||
mb: 4,
|
||||
borderBottom: "solid",
|
||||
borderColor: "primary.50",
|
||||
borderBottomWidth: "2px",
|
||||
};
|
||||
|
||||
const newSubscriptionClicked = (isForFree) => {
|
||||
setIsAddingFreeSubscription(isForFree);
|
||||
onOpen();
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
export NEXT_PUBLIC_SIMIOTICS_SEARCH_URL=http://localhost:5000
|
||||
export NEXT_PUBLIC_MIXPANEL_TOKEN="<YOUR MIXPANEL TOKEN HERE>"
|
||||
export NEXT_PUBLIC_SIMIOTICS_AUTH_URL=http://localhost:7474
|
||||
export NEXT_PUBLIC_SIMIOTICS_JOURNALS_URL=http://localhost:7475
|
||||
export NEXT_PUBLIC_BUGOUT_CONTACTUS_TOKEN="<Brood token for contact user>"
|
||||
export NEXT_PUBLIC_BUGOUT_CONTACTUS_JOURNAL_ID="<journal ID for contact journal>"
|
||||
export NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="<stripe publishable key>"
|
||||
export NEXT_PUBLIC_MOONSTREAM_API_URL=http://localhost:7481
|
||||
|
||||
export NEXT_PUBLIC_MOONSTREAM_API_URL=http://localhost:7481
|
|
@ -24,7 +24,7 @@ const AccountIconButton = (props) => {
|
|||
{...props}
|
||||
as={IconButton}
|
||||
aria-label="Account menu"
|
||||
icon={<RiAccountCircleLine size="26px"/>}
|
||||
icon={<RiAccountCircleLine size="26px" />}
|
||||
// variant="outline"
|
||||
color="gray.100"
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { useUser, useRouter } from "../core/hooks";
|
||||
import { useEffect, Fragment, useState } from "react";
|
||||
import { React, useEffect, Fragment, useState } from "react";
|
||||
import { Heading, Center, Spinner, Link, Button } from "@chakra-ui/react";
|
||||
import RouterLink from "next/link";
|
||||
const ACCOUNT_SCREEN_WIDGETS = {
|
||||
|
|
|
@ -21,9 +21,7 @@ import {
|
|||
} from "@chakra-ui/react";
|
||||
import {
|
||||
HamburgerIcon,
|
||||
PlusSquareIcon,
|
||||
QuestionOutlineIcon,
|
||||
BellIcon,
|
||||
ArrowLeftIcon,
|
||||
ArrowRightIcon,
|
||||
} from "@chakra-ui/icons";
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { React, useState, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useChangePassword, useRouter } from "../core/hooks";
|
||||
import {
|
|
@ -1,67 +0,0 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { GridItem } from "@chakra-ui/react";
|
||||
import { Heading, Text, Image } from "@chakra-ui/react";
|
||||
import { Fragment } from "react";
|
||||
|
||||
const Block = (content) => {
|
||||
const TitleRef = content.PrevTitle
|
||||
? `#${content.PrevTitle}-${content.title}`
|
||||
: `#${content.title}`;
|
||||
|
||||
var HeaderStyle = content.PrevTitle
|
||||
? { as: "h2", fontSize: "3xl" }
|
||||
: { as: "h1", fontSize: "4xl" };
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{content.title && (
|
||||
<GridItem colSpan="12" px="8.3%" py={1} textAlign="center">
|
||||
<Heading
|
||||
id={TitleRef}
|
||||
pt={16}
|
||||
pb={4}
|
||||
fontWeight="200"
|
||||
{...HeaderStyle}
|
||||
>
|
||||
{content.title}
|
||||
</Heading>
|
||||
</GridItem>
|
||||
)}
|
||||
{content.body.map((element, idx) => {
|
||||
if ("text" in element) {
|
||||
return (
|
||||
<GridItem key={idx} colSpan="10" px="8.3%" py={1}>
|
||||
{element.text.map((paragraph, idx) => {
|
||||
return (
|
||||
<Text key={idx} py={2} fontSize="xl">
|
||||
{paragraph}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
</GridItem>
|
||||
);
|
||||
}
|
||||
if ("image" in element) {
|
||||
return (
|
||||
<GridItem key={idx} colSpan="10" py={1} justifySelf="center">
|
||||
<Image
|
||||
justifySelf="center"
|
||||
key={idx}
|
||||
maxHeight="48rem"
|
||||
src={element.image.path}
|
||||
alt={element.image.annotation}
|
||||
/>
|
||||
</GridItem>
|
||||
);
|
||||
}
|
||||
if ("title" in element) {
|
||||
element.PrevTitle = content.title;
|
||||
return <Block key={idx} {...element} />;
|
||||
}
|
||||
return "";
|
||||
})}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
export default Block;
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { Fragment } from "react";
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Fragment, React } from "react";
|
||||
import {
|
||||
useClipboard,
|
||||
IconButton,
|
|
@ -1,95 +0,0 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import {
|
||||
Button,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
MenuGroup,
|
||||
MenuDivider,
|
||||
} from "@chakra-ui/react";
|
||||
import {
|
||||
useJournalEntry,
|
||||
useJournals,
|
||||
useRouter,
|
||||
useToast,
|
||||
} from "../core/hooks";
|
||||
import { EntryService } from "../core/services";
|
||||
import { useQueryCache } from "react-query";
|
||||
|
||||
const CopyEntryButton = ({ id, journalId }) => {
|
||||
const router = useRouter();
|
||||
const cache = useQueryCache();
|
||||
const { appScope } = router.params;
|
||||
const { data: entryToCopy, isLoading: sourceIsLoading } = useJournalEntry(
|
||||
journalId,
|
||||
id,
|
||||
appScope
|
||||
);
|
||||
const toast = useToast();
|
||||
const { journalsCache } = useJournals();
|
||||
const copyEntry = async (targetJournalId) => {
|
||||
try {
|
||||
const newEntry = { ...entryToCopy };
|
||||
newEntry.title = "Copy of " + newEntry.title;
|
||||
await EntryService.create(targetJournalId)(newEntry).then((response) => {
|
||||
journalsCache.refetch();
|
||||
setTimeout(
|
||||
() => cache.refetchQueries(["journal-entries", { journalId }]),
|
||||
500
|
||||
);
|
||||
if (response.status === 200) {
|
||||
toast("Copied!", "success");
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"Error copying entry. Please email engineering@bugout.dev if you encounter this issue.",
|
||||
e
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (journalsCache.isLoading || sourceIsLoading) return "";
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
size="xs"
|
||||
variant="link"
|
||||
colorScheme="primary"
|
||||
ml={1}
|
||||
>
|
||||
Copy
|
||||
</MenuButton>
|
||||
<MenuList maxH="sm" overflow="scroll">
|
||||
<MenuGroup title="Destination:">
|
||||
<MenuItem value={journalId} onClick={() => copyEntry(journalId)}>
|
||||
{
|
||||
journalsCache?.data?.data?.journals?.filter(
|
||||
(journal) => journal.id === journalId
|
||||
)[0]?.name
|
||||
}
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
{journalsCache?.data?.data?.journals?.map((journal) => {
|
||||
if (journal.id === journalId) return "";
|
||||
return (
|
||||
<MenuItem
|
||||
key={`option-${journal.id}`}
|
||||
value={journal.id}
|
||||
onClick={() => copyEntry(journal.id)}
|
||||
>
|
||||
{journal.name}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</MenuGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyEntryButton;
|
|
@ -1,4 +1,10 @@
|
|||
import React, { useRef, useEffect, useContext, useState } from "react";
|
||||
import React, {
|
||||
useRef,
|
||||
useEffect,
|
||||
useContext,
|
||||
useState,
|
||||
useCallback,
|
||||
} from "react";
|
||||
import {
|
||||
Flex,
|
||||
Spinner,
|
||||
|
@ -67,14 +73,17 @@ const EntriesNavigation = () => {
|
|||
]);
|
||||
const [filterState, setFilterState] = useState([]);
|
||||
|
||||
const setNewFilterState = (props) => {
|
||||
console.log(
|
||||
"setNewFilterState",
|
||||
props,
|
||||
subscriptionsCache.data.subscriptions[0].id
|
||||
);
|
||||
_setNewFilterState(props);
|
||||
};
|
||||
const setNewFilterState = useCallback(
|
||||
(props) => {
|
||||
console.log(
|
||||
"setNewFilterState",
|
||||
props,
|
||||
subscriptionsCache.data.subscriptions[0].id
|
||||
);
|
||||
_setNewFilterState(props);
|
||||
},
|
||||
[subscriptionsCache?.data?.subscriptions]
|
||||
);
|
||||
const loadMoreButtonRef = useRef(null);
|
||||
|
||||
const { fetchMore, isFetchingMore, canFetchMore, EntriesPages, isLoading } =
|
||||
|
@ -97,11 +106,14 @@ const EntriesNavigation = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const setFilterProps = (filterIdx, props) => {
|
||||
const newFilterProps = [...newFilterState];
|
||||
newFilterProps[filterIdx] = { ...newFilterProps[filterIdx], ...props };
|
||||
setNewFilterState(newFilterProps);
|
||||
};
|
||||
const setFilterProps = useCallback(
|
||||
(filterIdx, props) => {
|
||||
const newFilterProps = [...newFilterState];
|
||||
newFilterProps[filterIdx] = { ...newFilterProps[filterIdx], ...props };
|
||||
setNewFilterState(newFilterProps);
|
||||
},
|
||||
[newFilterState, setNewFilterState]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
@ -112,7 +124,7 @@ const EntriesNavigation = () => {
|
|||
value: subscriptionsCache.data.subscriptions[0].address,
|
||||
});
|
||||
}
|
||||
}, [subscriptionsCache.isLoading]);
|
||||
}, [subscriptionsCache, newFilterState, setFilterProps]);
|
||||
|
||||
const entriesPagesData = EntriesPages
|
||||
? EntriesPages.pages.map((page) => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/** @jsx jsx */
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Flex, Heading, Text, Link } from "@chakra-ui/react";
|
||||
import CustomIcon from "../components/CustomIcon"
|
||||
import CustomIcon from "../components/CustomIcon";
|
||||
import RouterLink from "next/link";
|
||||
|
||||
const ICONS = [
|
||||
|
@ -14,8 +14,7 @@ const ICONS = [
|
|||
{ social: "twit", link: "https://twitter.com/Bugout_dev" },
|
||||
{
|
||||
social: "slack",
|
||||
link:
|
||||
"https://join.slack.com/t/bugout-dev/shared_invite/zt-fhepyt87-5XcJLy0iu702SO_hMFKNhQ",
|
||||
link: "https://join.slack.com/t/bugout-dev/shared_invite/zt-fhepyt87-5XcJLy0iu702SO_hMFKNhQ",
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ import {
|
|||
Input,
|
||||
InputRightElement,
|
||||
} from "@chakra-ui/react";
|
||||
import CustomIcon from "./CustomIcon"
|
||||
import Modal from "./Modal"
|
||||
import CustomIcon from "./CustomIcon";
|
||||
import Modal from "./Modal";
|
||||
|
||||
const ForgotPassword = ({ toggleModal }) => {
|
||||
const toast = useToast();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import { Heading, Box, Text, Center, VStack } from "@chakra-ui/react";
|
||||
const Page404 = () => (
|
||||
<Box pt={8} w="100%" h="100%">
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import { Heading, Box, Text, VStack, Center } from "@chakra-ui/react";
|
||||
const Page403 = ({ location }) => (
|
||||
<Box pt={8} w="100%" h="100%">
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import Head from "next/head";
|
||||
import propTypes from "prop-types";
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import Head from "next/head";
|
||||
import propTypes from "prop-types";
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import { IconButton as IconButtonChakra } from "@chakra-ui/react";
|
||||
import { CheckIcon } from "@chakra-ui/icons";
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { React, useState, useEffect } from "react";
|
||||
import { Text } from "@chakra-ui/react";
|
||||
|
||||
const LoadingDots = (props) => {
|
|
@ -2,7 +2,7 @@
|
|||
/** @jsx jsx */
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import CustomIcon from "../CustomIcon"
|
||||
import CustomIcon from "../CustomIcon";
|
||||
import styles from "./styles";
|
||||
|
||||
const Modal = ({ children, onClose }) => (
|
||||
|
|
|
@ -13,7 +13,6 @@ const AppNavbar = React.lazy(() => import("./AppNavbar"));
|
|||
const Navbar = () => {
|
||||
const { modal, toggleModal, isAppView, isLoggedIn } = useContext(UIContext);
|
||||
|
||||
|
||||
return (
|
||||
<Flex
|
||||
boxShadow={["sm", "md"]}
|
||||
|
|
|
@ -22,7 +22,7 @@ const NewSubscription = ({ isFreeOption, onClose }) => {
|
|||
const { typesCache, createSubscription } = useSubscriptions();
|
||||
const { handleSubmit, errors, register } = useForm();
|
||||
const [radioState, setRadioState] = useState("ethereum_blockchain");
|
||||
let { getRootProps, getRadioProps, ref } = useRadioGroup({
|
||||
let { getRootProps, getRadioProps } = useRadioGroup({
|
||||
name: "type",
|
||||
defaultValue: radioState,
|
||||
onChange: setRadioState,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import { InputGroup, InputRightElement, Input } from "@chakra-ui/react";
|
||||
import CustomIcon from "./CustomIcon"
|
||||
import CustomIcon from "./CustomIcon";
|
||||
|
||||
const PasswordInput = ({ placeholder, name }, ref) => {
|
||||
const [showPassword, togglePassword] = useState(false);
|
||||
|
|
|
@ -8,7 +8,7 @@ const RadioCard = (props) => {
|
|||
const checkbox = getCheckboxProps();
|
||||
|
||||
return (
|
||||
<Flex as="label" h="fill-availible" onClick={() => console.log('hello2')}>
|
||||
<Flex as="label" h="fill-availible" onClick={() => console.log("hello2")}>
|
||||
<input {...input} />
|
||||
<Box
|
||||
justifyContent="left"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { jsx } from "@emotion/react";
|
||||
import {
|
||||
React,
|
||||
useState,
|
||||
useContext,
|
||||
useRef,
|
|
@ -15,7 +15,7 @@ import {
|
|||
Input,
|
||||
InputRightElement,
|
||||
} from "@chakra-ui/react";
|
||||
import CustomIcon from "./CustomIcon"
|
||||
import CustomIcon from "./CustomIcon";
|
||||
import { useLogin } from "../core/hooks";
|
||||
import PasswordInput from "./PasswordInput";
|
||||
import Modal from "./Modal";
|
||||
|
@ -51,7 +51,7 @@ const SignIn = ({ toggleModal }) => {
|
|||
colorScheme="primary"
|
||||
placeholder="Your Bugout username"
|
||||
name="username"
|
||||
{...register('username', { required: true })}
|
||||
{...register("username", { required: true })}
|
||||
ref={register({ required: "Username is required!" })}
|
||||
/>
|
||||
<InputRightElement>
|
||||
|
|
|
@ -26,12 +26,11 @@ const SignUp = ({ toggleModal }) => {
|
|||
const { signUp, isLoading, isSuccess } = useSignUp();
|
||||
const ui = useContext(UIContext);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
ui.toggleModal(null);
|
||||
}
|
||||
}, [isSuccess, toggleModal]);
|
||||
}, [isSuccess, toggleModal, ui]);
|
||||
|
||||
return (
|
||||
<Modal onClose={() => ui.toggleModal(null)}>
|
||||
|
|
|
@ -18,7 +18,7 @@ import CopyButton from "./CopyButton";
|
|||
import { useSubscriptions } from "../core/hooks";
|
||||
import ConfirmationRequest from "./ConfirmationRequest";
|
||||
|
||||
const List = (data) => {
|
||||
const SubscriptionsList = () => {
|
||||
const { subscriptionsCache, changeNote, deleteSubscription } =
|
||||
useSubscriptions();
|
||||
|
||||
|
@ -127,4 +127,4 @@ const List = (data) => {
|
|||
return "";
|
||||
}
|
||||
};
|
||||
export default List;
|
||||
export default SubscriptionsList;
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Tag, TagLabel, Flex, Button } from "@chakra-ui/react";
|
||||
import { useState } from "react";
|
||||
|
||||
const TAGS_DISPLAY_NUM_DEF = 5;
|
||||
const TagsList = ({ tags }) => {
|
||||
const [showAllTags, toggleAllTags] = useState(false);
|
||||
const tagButtonText = showAllTags ? "Show less" : "Show all";
|
||||
|
||||
const TagsToShow = () =>
|
||||
tags
|
||||
.filter((tag, i) => (showAllTags ? true : i < TAGS_DISPLAY_NUM_DEF))
|
||||
.map((tag, index) => {
|
||||
return (
|
||||
<Tag
|
||||
variant="subtle"
|
||||
colorScheme="primary"
|
||||
size="sm"
|
||||
key={`${tag}-${index}`}
|
||||
>
|
||||
<TagLabel>{tag}</TagLabel>
|
||||
</Tag>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex display="flex" flexWrap="wrap" align="center" spacing={1}>
|
||||
<TagsToShow />
|
||||
{tags.length > TAGS_DISPLAY_NUM_DEF && (
|
||||
<Button
|
||||
m={1}
|
||||
onClick={() => toggleAllTags(!showAllTags)}
|
||||
size="xs"
|
||||
variant="link"
|
||||
color="primary.600"
|
||||
ml={1}
|
||||
style={{ transform: "translateY(-1px)" }}
|
||||
>
|
||||
{tagButtonText}
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
export default TagsList;
|
|
@ -1,103 +0,0 @@
|
|||
import React from "react";
|
||||
import { IconButton } from "@chakra-ui/react";
|
||||
import {
|
||||
Table,
|
||||
Th,
|
||||
Td,
|
||||
Tr,
|
||||
Thead,
|
||||
Tbody,
|
||||
Text,
|
||||
Center,
|
||||
Spinner,
|
||||
} from "@chakra-ui/react";
|
||||
import { DeleteIcon } from "@chakra-ui/icons";
|
||||
import CopyButton from "./CopyEntryButton";
|
||||
import ConfirmationRequest from "./ConfirmationRequest";
|
||||
import NewTokenTr from "./NewTokenTr";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
const TokenList = ({
|
||||
tokens,
|
||||
revoke,
|
||||
isLoading,
|
||||
isNewTokenOpen,
|
||||
toggleNewToken,
|
||||
createToken,
|
||||
journalName,
|
||||
}) => {
|
||||
const { register, handleSubmit, errors } = useForm();
|
||||
if (isLoading)
|
||||
return (
|
||||
<Center>
|
||||
<Spinner />
|
||||
</Center>
|
||||
);
|
||||
|
||||
const handleTokenSubmit = ({ appName, appVersion }) => {
|
||||
createToken({ appName, appVersion }).then(() => toggleNewToken(false));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(handleTokenSubmit)}>
|
||||
<Table
|
||||
variant="simple"
|
||||
colorScheme="primary"
|
||||
justifyContent="center"
|
||||
alignItems="baseline"
|
||||
h="auto"
|
||||
size="sm"
|
||||
>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Token</Th>
|
||||
<Th>App Name</Th>
|
||||
<Th>App version</Th>
|
||||
<Th>Action</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{tokens.map((token, idx) => {
|
||||
return (
|
||||
<Tr key={`RestrictedToken-row-${idx}`}>
|
||||
<Td mr={4} p={0}>
|
||||
<CopyButton>{token.restricted_token_id}</CopyButton>
|
||||
</Td>
|
||||
<Td py={0}>{token.app_name}</Td>
|
||||
<Td py={0}>{token.app_version}</Td>
|
||||
<Td py={0}>
|
||||
<ConfirmationRequest
|
||||
bodyMessage={"please confirm"}
|
||||
header={"Delete token"}
|
||||
onConfirm={() => revoke(token.restricted_token_id)}
|
||||
>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
colorScheme="primary"
|
||||
icon={<DeleteIcon />}
|
||||
/>
|
||||
</ConfirmationRequest>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
|
||||
<NewTokenTr
|
||||
isOpen={isNewTokenOpen}
|
||||
toggleSelf={toggleNewToken}
|
||||
errors={errors}
|
||||
register={register}
|
||||
journalName={journalName}
|
||||
/>
|
||||
</Tbody>
|
||||
</Table>
|
||||
{tokens.length < 1 && (
|
||||
<Center>
|
||||
<Text my={4}>Create Usage report tokens here</Text>
|
||||
</Center>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
export default TokenList;
|
|
@ -1,109 +0,0 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import {
|
||||
Box,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
FormControl,
|
||||
FormErrorMessage,
|
||||
HStack,
|
||||
Button,
|
||||
InputRightElement,
|
||||
Input,
|
||||
} from "@chakra-ui/react";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import CustomIcon from "./CustomIcon"
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useUser, useLogin } from "../core/hooks";
|
||||
|
||||
const TokenRequest = ({ newToken, toggle }) => {
|
||||
const { user } = useUser();
|
||||
const { login, isLoading, data } = useLogin("SendLoginProp");
|
||||
const { handleSubmit, errors, register } = useForm();
|
||||
const [showPassword, setShowPassword] = useState("password");
|
||||
|
||||
const togglePassword = () => {
|
||||
if (showPassword === "password") {
|
||||
setShowPassword("text");
|
||||
} else {
|
||||
setShowPassword("password");
|
||||
}
|
||||
};
|
||||
|
||||
const PasswordRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
if (PasswordRef.current) {
|
||||
PasswordRef.current.focus();
|
||||
}
|
||||
}, [PasswordRef]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
newToken(data.data.access_token);
|
||||
toggle(null);
|
||||
}
|
||||
}, [data, newToken, toggle]);
|
||||
|
||||
const formStyle = {
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
minWidth: "100px",
|
||||
flexFlow: "row wrap-reverse",
|
||||
aligntContent: "flex-end",
|
||||
};
|
||||
|
||||
if (!user) return ""; //loading...
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<form onSubmit={handleSubmit(login)} style={formStyle}>
|
||||
<HStack>
|
||||
<Button
|
||||
variant="solid"
|
||||
colorScheme="primary"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
|
||||
<FormControl isInvalid={errors.password}>
|
||||
<InputGroup minWidth="300px">
|
||||
<InputLeftElement onClick={togglePassword}>
|
||||
<CustomIcon icon="password" />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
colorScheme="primary"
|
||||
variant="filled"
|
||||
isDisabled={isLoading}
|
||||
autoComplete="on"
|
||||
placeholder="Your Bugout password"
|
||||
name="password"
|
||||
type={showPassword}
|
||||
ref={(e) => {
|
||||
register(e, { required: "Password is required!" });
|
||||
PasswordRef.current = e;
|
||||
}}
|
||||
/>
|
||||
<InputRightElement onClick={() => toggle(null)}>
|
||||
<CloseIcon />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<FormErrorMessage color="unsafe.400" pl="1" justifyContent="Center">
|
||||
{errors.password && errors.password.message}
|
||||
</FormErrorMessage>
|
||||
</FormControl>
|
||||
<Input
|
||||
type="hidden"
|
||||
ref={register}
|
||||
name="username"
|
||||
defaultValue={user?.username}
|
||||
/>
|
||||
</HStack>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default TokenRequest;
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { React } from "react";
|
||||
import { Flex, Image, Link } from "@chakra-ui/react";
|
||||
|
||||
const TrustedBadge = ({ name, caseURL, ImgURL }) => {
|
||||
|
@ -20,7 +19,6 @@ const TrustedBadge = ({ name, caseURL, ImgURL }) => {
|
|||
alt={name}
|
||||
></Image>
|
||||
{caseURL && (
|
||||
// <RouterLink href={caseURL} passHref scroll={true}>
|
||||
<Link
|
||||
fontSize={["sm", null, "md", "lg"]}
|
||||
textColor="secondary.900"
|
||||
|
@ -28,7 +26,6 @@ const TrustedBadge = ({ name, caseURL, ImgURL }) => {
|
|||
>
|
||||
{`Read case study >`}
|
||||
</Link>
|
||||
// </RouterLink>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
|
@ -1,32 +1,15 @@
|
|||
export { default as hookCommon } from "./hookCommon";
|
||||
export { queryCacheProps as hookCommon } from "./hookCommon";
|
||||
export { default as useAnalytics } from "./useAnalytics";
|
||||
export { default as useAuthResultHandler } from "./useAuthResultHandler";
|
||||
export { default as useChangePassword } from "./useChangePassword";
|
||||
export { default as useClientID } from "./useClientID";
|
||||
export { default as useCodeVerification } from "./useCodeVerification";
|
||||
export { default as useCreateEntry } from "./useCreateEntry";
|
||||
export { default as useCreateJournal } from "./useCreateJournal";
|
||||
export { default as useDeleteEntry } from "./useDeleteEntry";
|
||||
export { default as useDeleteJournal } from "./useDeleteJournal";
|
||||
export { default as useEntriesSearch } from "./useEntriesSearch";
|
||||
export { default as useForgotPassword } from "./useForgotPassword";
|
||||
export { default as useGroup } from "./useGroup";
|
||||
export { default as useGroups } from "./useGroups";
|
||||
export { default as useHumbug } from "./useHumbug";
|
||||
export { default as useHumbugTokens } from "./useHumbugTokens";
|
||||
export { default as useHumbugs } from "./useHumbugs";
|
||||
export { default as useInviteAccept } from "./useInviteAccept";
|
||||
export { default as useJournal } from "./useJournal";
|
||||
export { default as useJournalEntries } from "./useJournalEntries";
|
||||
export { default as useJournalEntry } from "./useJournalEntry";
|
||||
export { default as useJournalPermissions } from "./useJournalPermissions";
|
||||
export { default as useJournalStats } from "./useJournalStats";
|
||||
export { default as useJournals } from "./useJournals";
|
||||
export { default as useJournalsScopes } from "./useJournalsScopes";
|
||||
export { default as useLogin } from "./useLogin";
|
||||
export { default as useLogout } from "./useLogout";
|
||||
export { default as useModals } from "./useModals";
|
||||
export { default as usePreferences } from "./usePreferences";
|
||||
export { default as usePresignedURL } from "./usePresignedURL";
|
||||
export { default as useQuery } from "./useQuery";
|
||||
export { default as useResetPassword } from "./useResetPassword";
|
||||
|
@ -36,7 +19,4 @@ export { default as useStorage } from "./useStorage";
|
|||
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 useUpdateEntry } from "./useUpdateEntry";
|
||||
export { default as useUpdateTag } from "./useUpdateTag";
|
||||
export { default as useUser } from "./useUser";
|
||||
|
|
|
@ -2,9 +2,8 @@ import AnalyticsContext from "../providers/AnalyticsProvider/context";
|
|||
import { useContext } from "react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
const useAnalytics = () => {
|
||||
const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } = useContext(
|
||||
AnalyticsContext
|
||||
);
|
||||
const { mixpanel, isLoaded, MIXPANEL_EVENTS, MIXPANEL_PROPS } =
|
||||
useContext(AnalyticsContext);
|
||||
const [trackProps, setTrackProps] = useState({
|
||||
event: null,
|
||||
props: null,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
import { useMutation, useQueryCache } from "react-query";
|
||||
import { EntryService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useCreateEntry = (journalId) => {
|
||||
const cache = useQueryCache();
|
||||
const toast = useToast();
|
||||
|
||||
const [createEntry, { isLoading, data }] = useMutation(
|
||||
EntryService.create(journalId),
|
||||
{
|
||||
onSuccess: (newEntry) => {
|
||||
const EntriesPages = cache.getQueryData([
|
||||
"journal-entries",
|
||||
{ journalId },
|
||||
]);
|
||||
EntriesPages[0].data.unshift(newEntry.data);
|
||||
EntriesPages.map((page, idx) => {
|
||||
if (idx + 1 < EntriesPages.length) {
|
||||
const ShiftedEntry = EntriesPages[idx].data.pop();
|
||||
EntriesPages[idx + 1].data.unshift(ShiftedEntry);
|
||||
}
|
||||
return page;
|
||||
});
|
||||
cache.setQueryData(["journal-entries", { journalId }], EntriesPages);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return { createEntry, isLoading, data };
|
||||
};
|
||||
|
||||
export default useCreateEntry;
|
|
@ -1,27 +0,0 @@
|
|||
import { useMutation, useQueryCache } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
|
||||
const useCreateJournal = () => {
|
||||
const cache = useQueryCache();
|
||||
|
||||
const createJournal = useMutation(JournalService.create, {
|
||||
onSuccess: (newJournal) => {
|
||||
const previousJournals = cache.getQueryData(["journals-list"]);
|
||||
const newJournals = [...previousJournals];
|
||||
newJournals.push(newJournal.data);
|
||||
newJournals.sort(function (a, b) {
|
||||
var aName = a.name.toUpperCase();
|
||||
var bName = b.name.toUpperCase();
|
||||
return aName < bName ? -1 : aName < bName ? 1 : 0;
|
||||
});
|
||||
|
||||
cache.setQueryData(["journals-list"], newJournals);
|
||||
|
||||
return () => cache.setQueryData(["journals-list"], previousJournals);
|
||||
},
|
||||
});
|
||||
|
||||
return createJournal;
|
||||
};
|
||||
|
||||
export default useCreateJournal;
|
|
@ -1,33 +0,0 @@
|
|||
import { useMutation, useQueryCache } from "react-query";
|
||||
import { EntryService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useDeleteEntry = ({ entryId, journalId }) => {
|
||||
const cache = useQueryCache();
|
||||
const toast = useToast();
|
||||
|
||||
const [deleteEntry] = useMutation(
|
||||
EntryService.deleteEntry(journalId, entryId),
|
||||
{
|
||||
onSuccess: () => {
|
||||
const previousEntriesPages = cache.getQueryData([
|
||||
"journal-entries",
|
||||
{ journalId },
|
||||
]);
|
||||
const newEntriesPages = [...previousEntriesPages];
|
||||
newEntriesPages.map((page) => {
|
||||
page.data = page.data.filter((entry) => entry.id !== entryId);
|
||||
return page;
|
||||
});
|
||||
|
||||
cache.setQueryData(["journal-entries", { journalId }], newEntriesPages);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
return deleteEntry;
|
||||
};
|
||||
|
||||
export default useDeleteEntry;
|
|
@ -1,29 +0,0 @@
|
|||
import { useMutation, useQueryCache } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useDeleteJournal = (id) => {
|
||||
const cache = useQueryCache();
|
||||
const toast = useToast();
|
||||
|
||||
const [deleteJournal] = useMutation(JournalService.deleteJournal(id), {
|
||||
onMutate: () => {
|
||||
const previousJournals = [...cache.getQueryData(["journals-list"])];
|
||||
|
||||
const newJournals = previousJournals.filter(
|
||||
(journal) => journal.id !== id
|
||||
);
|
||||
cache.setQueryData(["journals-list"], newJournals);
|
||||
|
||||
return { previousJournals };
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(["journals-list"], context.previousJournals);
|
||||
toast("Not enough permisions to delete this Journal", "error");
|
||||
},
|
||||
});
|
||||
|
||||
return { deleteJournal };
|
||||
};
|
||||
|
||||
export default useDeleteJournal;
|
|
@ -1,31 +0,0 @@
|
|||
import { useMutation } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useEntriesSearch = ({ journalId }) => {
|
||||
const toast = useToast();
|
||||
|
||||
const {
|
||||
mutateAsync: entriesSearch,
|
||||
isLoading,
|
||||
error,
|
||||
data,
|
||||
} = useMutation(
|
||||
JournalService.searchEntries({ journalId }),
|
||||
|
||||
{
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
entriesSearch,
|
||||
data,
|
||||
isLoading,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useEntriesSearch;
|
|
@ -1,223 +0,0 @@
|
|||
import { useQuery, useQueryCache, useMutation } from "react-query";
|
||||
import { GroupService, UserService } from "../services";
|
||||
import { useToast, useUser } from ".";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useGroup = (groupId) => {
|
||||
const { user } = useUser();
|
||||
const cache = useQueryCache();
|
||||
const toast = useToast();
|
||||
|
||||
const { data: GroupUsersResponse, isLoading, refetch: getUsers } = useQuery(
|
||||
["group-users", groupId],
|
||||
GroupService.getGroupUsers,
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const getInvites = async (key, groupId) => {
|
||||
var data;
|
||||
data = await GroupService.getInvites(groupId);
|
||||
const newInvites = data.data.invites;
|
||||
|
||||
return [...newInvites];
|
||||
};
|
||||
|
||||
const invitesQueryCache = useQuery(
|
||||
["group-invites", groupId],
|
||||
getInvites,
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const [addExistingUser, addUserStatus] = useMutation(
|
||||
GroupService.setGroupUser(groupId),
|
||||
{
|
||||
onMutate: (newUser) => {
|
||||
const NewGroupResponse = cache.getQueryData(["group-users", groupId]);
|
||||
const previousGroupResponse = JSON.parse(
|
||||
JSON.stringify(NewGroupResponse)
|
||||
);
|
||||
NewGroupResponse.data.users = [
|
||||
...NewGroupResponse.data.users,
|
||||
{ email: newUser.email, user_type: newUser.role },
|
||||
];
|
||||
cache.setQueryData(["group-users", groupId], {
|
||||
...NewGroupResponse,
|
||||
});
|
||||
|
||||
return previousGroupResponse;
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(["group-users", groupId], context);
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
//fetch data from backend again to fill missing fields of newly added
|
||||
//user
|
||||
onSuccess: () => {
|
||||
getUsers();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const [sendInvite, sendInviteStatus] = useMutation(
|
||||
GroupService.sendInvite(groupId),
|
||||
{
|
||||
onSuccess: () => {
|
||||
invitesQueryCache.refetch();
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* addToGroup adds to group.
|
||||
*
|
||||
* If `email` is specified and found our users DB - add user.
|
||||
*
|
||||
* If `email` is specified and not found in users DB - send invite link
|
||||
*
|
||||
* If `email` not specified - return public invite code
|
||||
*/
|
||||
const addToGroup = async (invitee) => {
|
||||
if (invitee?.email) {
|
||||
const query = `email=${invitee.email}`;
|
||||
|
||||
await UserService.findUser(query).then(
|
||||
(response) => {
|
||||
if (response.data.user_id) {
|
||||
addExistingUser(invitee);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if (invitee.email) {
|
||||
sendInvite(invitee);
|
||||
} else {
|
||||
toast("user not found", "error");
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
sendInvite();
|
||||
}
|
||||
};
|
||||
|
||||
//ToDo: const addUserMutation = useMutation(.. when upgrading to React Query 3
|
||||
const addUserMutation = {
|
||||
addUser: addToGroup,
|
||||
isLoading: addUserStatus.isLoading,
|
||||
};
|
||||
|
||||
const [removeUser, removeUserStatus] = useMutation(
|
||||
GroupService.deleteGroupUser(groupId),
|
||||
{
|
||||
onMutate: (removedUsername) => {
|
||||
const NewGroupResponse = cache.getQueryData(["group-users", groupId]);
|
||||
const previousGroupResponse = JSON.parse(
|
||||
JSON.stringify(NewGroupResponse)
|
||||
);
|
||||
NewGroupResponse.data.users = NewGroupResponse.data.users.filter(
|
||||
(user) => user.username !== removedUsername
|
||||
);
|
||||
cache.setQueryData(["group-users", groupId], {
|
||||
...NewGroupResponse,
|
||||
});
|
||||
if (user.username === removedUsername) {
|
||||
const NewGroupsResponse = cache.getQueryData(["groups"]);
|
||||
const previousGroupsResponse = JSON.parse(
|
||||
JSON.stringify(NewGroupsResponse)
|
||||
);
|
||||
NewGroupsResponse.data[groupId].user_type = "none";
|
||||
|
||||
cache.setQueryData(["groups"], {
|
||||
...NewGroupsResponse,
|
||||
});
|
||||
|
||||
return { previousGroupResponse, previousGroupsResponse };
|
||||
} else {
|
||||
return { previousGroupResponse };
|
||||
}
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(
|
||||
["group-users", groupId],
|
||||
context.previousGroupResponse
|
||||
);
|
||||
if (context.previousGroupsResponse) {
|
||||
cache.setQueryData(["groups"], context.previousGroupsResponse);
|
||||
}
|
||||
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
onSuccess: (response, username) => {
|
||||
if (user.username === username) {
|
||||
const NewGroupsResponse = cache.getQueryData(["groups"]);
|
||||
delete NewGroupsResponse.data[groupId];
|
||||
|
||||
cache.setQueryData(["groups"], {
|
||||
...NewGroupsResponse,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
//ToDo: const removeUserMutation = useMutation(.. when upgrading to React Query 3
|
||||
const removeUserMutation = {
|
||||
removeUser,
|
||||
isLoading: removeUserStatus.isLoading,
|
||||
};
|
||||
|
||||
const [revokeInvite, activatePublicInviteStatus] = useMutation(
|
||||
GroupService.deleteInvite(groupId),
|
||||
{
|
||||
onSuccess: () => {
|
||||
invitesQueryCache.refetch();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const users = {
|
||||
isLoading: isLoading,
|
||||
data: GroupUsersResponse?.data?.users,
|
||||
refetch: getUsers,
|
||||
};
|
||||
|
||||
const readInvites = ({ isPublic, isPersonal }) => {
|
||||
const allInvites = cache.getQueryData(["group-invites", groupId]);
|
||||
if (allInvites) {
|
||||
if (isPublic && isPersonal) {
|
||||
return allInvites;
|
||||
} else if (isPersonal) {
|
||||
return allInvites.filter((item) => item.email && item.active);
|
||||
} else {
|
||||
return allInvites.filter((item) => !item.email && item.active);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const invites = {
|
||||
personal: readInvites({ isPublic: false, isPersonal: true }),
|
||||
public: readInvites({ isPublic: true, isPersonal: false }),
|
||||
all: readInvites({ isPublic: true, isPersonal: true }),
|
||||
isLoading: invitesQueryCache.isLoading,
|
||||
get: () => invitesQueryCache.refetch(),
|
||||
|
||||
createPersonal: addToGroup,
|
||||
createPublic: () => addToGroup(),
|
||||
isLoadingCreate: sendInviteStatus.isLoading,
|
||||
revokeInvite: revokeInvite,
|
||||
isLoadingRevoke: activatePublicInviteStatus.isLoading,
|
||||
};
|
||||
|
||||
return {
|
||||
users,
|
||||
addUserMutation,
|
||||
removeUserMutation,
|
||||
invites,
|
||||
};
|
||||
};
|
||||
|
||||
export default useGroup;
|
|
@ -1,118 +0,0 @@
|
|||
import { useQuery, useQueryCache, useMutation } from "react-query";
|
||||
import { GroupService } from "../services";
|
||||
import { useToast } from ".";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
import { useUser } from "../hooks";
|
||||
|
||||
const useGroups = () => {
|
||||
const cache = useQueryCache();
|
||||
const toast = useToast();
|
||||
const { user } = useUser();
|
||||
|
||||
const fetchGroups = async (query) => {
|
||||
const response = await GroupService.getGroups(query);
|
||||
|
||||
return response?.data?.groups;
|
||||
};
|
||||
|
||||
const { data, isLoading, refetch: getGroups } = useQuery(
|
||||
"groups",
|
||||
fetchGroups,
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const [createGroup, createStatus] = useMutation(
|
||||
(groupName) => GroupService.createGroup(groupName),
|
||||
{
|
||||
onSuccess: (response) => {
|
||||
const currentGroups = cache.getQueryData(["groups"]);
|
||||
currentGroups.push({
|
||||
autogenerated: false,
|
||||
group_id: response.data.id,
|
||||
group_name: response.data.group_name,
|
||||
user_id: user.user_id,
|
||||
user_type: "owner",
|
||||
});
|
||||
cache.setQueryData(["groups"], currentGroups);
|
||||
cache.refetchQueries(["groups"]);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
//ToDo: const createGroupMutation = useMutation(.. when upgrading to React Query 3
|
||||
const createGroupMutation = {
|
||||
createGroup,
|
||||
isLoading: createStatus.isLoading,
|
||||
};
|
||||
|
||||
const [deleteGroup, deleteStatus] = useMutation(GroupService.deleteGroup, {
|
||||
onMutate: (groupId) => {
|
||||
const previousGroups = cache.getQueryData(["groups"]);
|
||||
|
||||
const newGroups = previousGroups.filter(
|
||||
(group) => group.group_id !== groupId
|
||||
);
|
||||
|
||||
cache.setQueryData(["groups"], [...newGroups]);
|
||||
|
||||
return previousGroups;
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(["groups"], context);
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
//ToDo: const createGroupMutation = useMutation(.. when upgrading to React Query 3
|
||||
const deleteGroupMutation = {
|
||||
deleteGroup,
|
||||
isLoading: deleteStatus.isLoading,
|
||||
};
|
||||
|
||||
const [renameGroup, renameStatus] = useMutation(GroupService.setGroupName, {
|
||||
onMutate: (data) => {
|
||||
const newGroups = cache.getQueryData(["groups"]);
|
||||
const previousGroups = [...newGroups];
|
||||
|
||||
newGroups.forEach((group) => {
|
||||
if (group.group_id === data.groupId) {
|
||||
group.group_name = data.name;
|
||||
}
|
||||
});
|
||||
|
||||
cache.setQueryData(["groups"], [...newGroups]);
|
||||
|
||||
return previousGroups;
|
||||
},
|
||||
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(["groups"], context);
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
onSuccess: () => {
|
||||
getGroups();
|
||||
},
|
||||
});
|
||||
|
||||
//ToDo: const renameGroupMutation = useMutation(.. when upgrading to React Query 3
|
||||
const renameGroupMutation = {
|
||||
renameGroup,
|
||||
isLoading: renameStatus.isLoading,
|
||||
status: { ...renameStatus },
|
||||
};
|
||||
|
||||
return {
|
||||
data,
|
||||
isLoading,
|
||||
getGroups,
|
||||
createGroupMutation,
|
||||
deleteGroupMutation,
|
||||
renameGroupMutation,
|
||||
};
|
||||
};
|
||||
|
||||
export default useGroups;
|
|
@ -1,26 +0,0 @@
|
|||
import { HumbugService } from "../services";
|
||||
import { useToast } from ".";
|
||||
import { useQuery } from "react-query";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useHumbug = (humbugId) => {
|
||||
const toast = useToast();
|
||||
|
||||
const { data, isLoading, refetch } = useQuery(
|
||||
["humbug", { humbugId }],
|
||||
HumbugService.getHumbug,
|
||||
{
|
||||
...queryCacheProps,
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
data,
|
||||
isLoading,
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
export default useHumbug;
|
|
@ -1,90 +0,0 @@
|
|||
import { HumbugService } from "../services";
|
||||
import { useToast } from ".";
|
||||
import { useMutation, useQuery, useQueryCache } from "react-query";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useHumbugTokens = (humbugId) => {
|
||||
const toast = useToast();
|
||||
const cache = useQueryCache();
|
||||
|
||||
const getTokens = async (key, { humbugId }) => {
|
||||
var data;
|
||||
data = await HumbugService.getTokens(humbugId);
|
||||
const newHumbugTokens = data.data.tokens;
|
||||
return [...newHumbugTokens];
|
||||
};
|
||||
|
||||
const humbugTokensCache = useQuery(
|
||||
[`Humbug-Tokens`, { humbugId }],
|
||||
getTokens,
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const [
|
||||
createRestrictedToken,
|
||||
{
|
||||
isLoading: isLoadingRestrictedToken,
|
||||
error: errorRestrictedToken,
|
||||
data: dataRestrictedToken,
|
||||
},
|
||||
] = useMutation(HumbugService.createRestrictedToken(humbugId), {
|
||||
onMutate: () => {},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
onSuccess: (response) => {
|
||||
const oldData = cache.getQueryData([`Humbug-Tokens`, { humbugId }]);
|
||||
const newData = [...oldData, ...response.data.tokens];
|
||||
cache.setQueryData([`Humbug-Tokens`, { humbugId }], newData);
|
||||
},
|
||||
});
|
||||
|
||||
const createRestrictedTokenMutation = {
|
||||
createRestrictedToken,
|
||||
isLoading: isLoadingRestrictedToken,
|
||||
error: errorRestrictedToken,
|
||||
data: dataRestrictedToken,
|
||||
};
|
||||
|
||||
const [
|
||||
deleteRestrictedToken,
|
||||
{
|
||||
isLoading: isLoadingDeleteRestrictedToken,
|
||||
error: errorDeleteRestrictedToken,
|
||||
data: dataDeleteRestrictedToken,
|
||||
},
|
||||
] = useMutation(HumbugService.deleteRestrictedToken(humbugId), {
|
||||
onMutate: (tokenId) => {
|
||||
var newTokens = cache.getQueryData([`Humbug-Tokens`, { humbugId }]);
|
||||
const previousTokens = [...newTokens];
|
||||
|
||||
newTokens = newTokens.filter(
|
||||
(token) => token.restricted_token_id !== tokenId
|
||||
);
|
||||
|
||||
cache.setQueryData([`Humbug-Tokens`, { humbugId }], newTokens);
|
||||
|
||||
return previousTokens;
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData([`Humbug-Tokens`, { humbugId }], context);
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const deleteRestrictedTokenMutation = {
|
||||
deleteRestrictedToken,
|
||||
isLoading: isLoadingDeleteRestrictedToken,
|
||||
error: errorDeleteRestrictedToken,
|
||||
data: dataDeleteRestrictedToken,
|
||||
};
|
||||
|
||||
return {
|
||||
humbugTokensCache,
|
||||
createRestrictedTokenMutation,
|
||||
deleteRestrictedTokenMutation,
|
||||
};
|
||||
};
|
||||
|
||||
export default useHumbugTokens;
|
|
@ -1,99 +0,0 @@
|
|||
import { HumbugService } from "../services";
|
||||
import { useToast } from ".";
|
||||
import { useMutation, useQuery, useQueryCache } from "react-query";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useHumbugs = (query) => {
|
||||
const toast = useToast();
|
||||
const cache = useQueryCache();
|
||||
|
||||
const getHumbugItegrations = async (key, { query }) => {
|
||||
var data;
|
||||
if (!query) {
|
||||
data = await HumbugService.getHumbugItegrations();
|
||||
} else {
|
||||
data = await HumbugService.getHumbugItegrations(query);
|
||||
}
|
||||
const newHumbugIntegrations = data.data.integrations;
|
||||
|
||||
return [...newHumbugIntegrations];
|
||||
};
|
||||
|
||||
const { data: humbugList } = useQuery(
|
||||
["humbugs", { query }],
|
||||
getHumbugItegrations,
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const [
|
||||
createHumbug,
|
||||
{
|
||||
isLoading: isLoadingCreateHumbug,
|
||||
error: errorCreateHumbug,
|
||||
data: dataCreateHumbug,
|
||||
},
|
||||
] = useMutation(HumbugService.createHumbug, {
|
||||
onSuccess: (response) => {
|
||||
var oldData = cache.getQueryData(["humbugs", { query }]);
|
||||
var newData = oldData ? [...oldData, response.data] : [response.data];
|
||||
cache.setQueryData(["humbugs", { query }], newData);
|
||||
cache.refetchQueries(["journals-list"]);
|
||||
|
||||
cache.refetchQueries(["humbugs"], newData);
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const [
|
||||
deleteHumbug,
|
||||
{
|
||||
isLoading: isLoadingDeleteHumbug,
|
||||
error: errorDeleteHumbug,
|
||||
data: dataDeleteHumbug,
|
||||
},
|
||||
] = useMutation(HumbugService.deleteHumbug, {
|
||||
onMutate: (humbugId) => {
|
||||
var newHumbugs = cache.getQueryData(["humbugs", { query }]);
|
||||
const previousHumbugs = [...newHumbugs];
|
||||
newHumbugs = newHumbugs.filter((humbug) => humbug.id !== humbugId);
|
||||
|
||||
cache.setQueryData(["humbugs", { query }], newHumbugs);
|
||||
|
||||
var newHumbugsAll = cache.getQueryData(["humbugs", {}]);
|
||||
const prevHumbugsAll = [...newHumbugsAll];
|
||||
newHumbugsAll = newHumbugs.filter((humbug) => humbug.id !== humbugId);
|
||||
|
||||
cache.setQueryData(["humbugs", {}], newHumbugsAll);
|
||||
|
||||
return { previousHumbugs, prevHumbugsAll };
|
||||
},
|
||||
onError: (error, variables, context) => {
|
||||
cache.setQueryData(["humbugs", { query }], context.previousHumbugs);
|
||||
cache.setQueryData(["humbugs"], context.prevHumbugsAll);
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const createHumbugMutation = {
|
||||
createHumbug,
|
||||
isLoading: isLoadingCreateHumbug,
|
||||
errorCreateHumbug,
|
||||
dataCreateHumbug,
|
||||
};
|
||||
|
||||
const deleteHumbugMutation = {
|
||||
deleteHumbug,
|
||||
isLoading: isLoadingDeleteHumbug,
|
||||
errorDeleteHumbug,
|
||||
dataDeleteHumbug,
|
||||
};
|
||||
|
||||
return {
|
||||
humbugList,
|
||||
createHumbugMutation,
|
||||
deleteHumbugMutation,
|
||||
};
|
||||
};
|
||||
export default useHumbugs;
|
|
@ -1,34 +0,0 @@
|
|||
import { useQuery } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useJournal = (journalId, journalScope) => {
|
||||
const toast = useToast();
|
||||
|
||||
const getJournal = async (query, key) => {
|
||||
const journalEndpoint =
|
||||
journalScope === "public"
|
||||
? JournalService.getPublicJournal
|
||||
: JournalService.getJournal;
|
||||
const data = await journalEndpoint(key, { journalId });
|
||||
|
||||
const entry = data.data;
|
||||
return entry;
|
||||
};
|
||||
|
||||
const { data, isLoading, refetch } = useQuery("journal", getJournal, {
|
||||
...queryCacheProps,
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
data,
|
||||
isLoading,
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournal;
|
|
@ -1,86 +0,0 @@
|
|||
import { useInfiniteQuery } from "react-query";
|
||||
import { useEntriesSearch } from ".";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useJournalEntries = ({
|
||||
journalId,
|
||||
journalType,
|
||||
isContent,
|
||||
pageSize,
|
||||
searchQuery,
|
||||
}) => {
|
||||
const limit = pageSize ? pageSize : 25;
|
||||
|
||||
const { entriesSearch } = useEntriesSearch({
|
||||
journalId,
|
||||
});
|
||||
|
||||
const getEntries =
|
||||
(searchTerm) =>
|
||||
async ({ pageParam = 0 }) => {
|
||||
if (!pageParam) {
|
||||
pageParam = 0;
|
||||
}
|
||||
|
||||
const searchTags = searchTerm.split(" ").filter(function (n) {
|
||||
if (n.startsWith("#")) return n;
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
const data = await entriesSearch({
|
||||
searchTerm,
|
||||
journalType,
|
||||
isContent,
|
||||
limit,
|
||||
offset: pageParam,
|
||||
searchTags,
|
||||
});
|
||||
const newEntryList = data.data.results.map((entry) => ({
|
||||
...entry,
|
||||
id: entry.entry_url.split("/").pop(),
|
||||
}));
|
||||
return {
|
||||
data: [...newEntryList],
|
||||
pageParams: {
|
||||
pageParam: pageParam + 1,
|
||||
next_offset: data.data.next_offset,
|
||||
total_results: data.data.total_results,
|
||||
offset: data.data.offset,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const {
|
||||
data: EntriesPages,
|
||||
isFetchingMore,
|
||||
isLoading,
|
||||
canFetchMore,
|
||||
fetchMore,
|
||||
refetch,
|
||||
} = useInfiniteQuery(
|
||||
["journal-entries", { journalId }],
|
||||
getEntries(searchQuery),
|
||||
{
|
||||
refetchInterval: 1000,
|
||||
...queryCacheProps,
|
||||
// getNextPageParam: (lastPage) => lastPage.next_offset ?? false,
|
||||
getNextPageParam: (lastGroup) => {
|
||||
return lastGroup.next_offset === null ? false : lastGroup.next_offset;
|
||||
},
|
||||
enabled: !!journalId,
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
EntriesPages,
|
||||
fetchMore,
|
||||
isFetchingMore,
|
||||
canFetchMore,
|
||||
refetch,
|
||||
isLoading,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournalEntries;
|
|
@ -1,178 +0,0 @@
|
|||
import { useQuery, useMutation, useQueryClient } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { useToast } from ".";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useJournalPermissions = (journalId, journalScope) => {
|
||||
const cache = useQueryClient();
|
||||
const toast = useToast();
|
||||
const {
|
||||
data,
|
||||
isLoading,
|
||||
refetch: getPermissions,
|
||||
error,
|
||||
} = useQuery(
|
||||
["journal-permissions", { journalId }],
|
||||
async () => {
|
||||
if (journalId) {
|
||||
if (journalScope === "personal") {
|
||||
const response = await JournalService.getJournalPermissions(
|
||||
journalId
|
||||
);
|
||||
if (!response.data || !response.data.permissions) {
|
||||
return [];
|
||||
}
|
||||
return response.data.permissions;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
const response = { data: { scopes: ["public"] } };
|
||||
return response;
|
||||
}
|
||||
},
|
||||
queryCacheProps
|
||||
);
|
||||
|
||||
const {
|
||||
data: currentUserPermissions,
|
||||
refetch: getCurrentUserPermissions,
|
||||
isLoading: currentUserPermissionsIsLoading,
|
||||
} = useQuery(
|
||||
["journal-permissions-current-user", { journalId }],
|
||||
async () => {
|
||||
if (journalId) {
|
||||
if (journalScope === "personal") {
|
||||
let response = { data: {} };
|
||||
try {
|
||||
response = await JournalService.getCurrentUserJournalPermissions(
|
||||
journalId
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn("error retrieving scopes:", error);
|
||||
}
|
||||
if (!response.data || !response.data.scopes) {
|
||||
return [];
|
||||
}
|
||||
return response.data.scopes.map((scope) => scope.permission);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
const response = { data: { scopes: ["public"] } };
|
||||
return response;
|
||||
}
|
||||
},
|
||||
{
|
||||
...queryCacheProps,
|
||||
staleTime: 720000, // 12 hours
|
||||
}
|
||||
);
|
||||
|
||||
const setJournalPermissionMutation = useMutation(
|
||||
JournalService.setJournalPermission(journalId),
|
||||
{
|
||||
onMutate: (data) => {
|
||||
const newJournalPermissionResponse = cache.getQueryData([
|
||||
"journal-permissions",
|
||||
{ journalId },
|
||||
]);
|
||||
const previousJournalPermissionResponse = JSON.parse(
|
||||
JSON.stringify(newJournalPermissionResponse)
|
||||
);
|
||||
const index = previousJournalPermissionResponse.findIndex(
|
||||
(i) => i.holder_id === data.holder_id
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
newJournalPermissionResponse.push({
|
||||
permissions: [...data.permission_list],
|
||||
holder_id: data.holder_id,
|
||||
holder_type: data.holder_type,
|
||||
});
|
||||
} else {
|
||||
newJournalPermissionResponse[index].permissions = [
|
||||
...newJournalPermissionResponse[index].permissions,
|
||||
...data.permission_list,
|
||||
];
|
||||
}
|
||||
|
||||
cache.setQueryData(
|
||||
["journal-permissions", { journalId }],
|
||||
newJournalPermissionResponse
|
||||
);
|
||||
|
||||
return previousJournalPermissionResponse;
|
||||
},
|
||||
onError: (error, value, context) => {
|
||||
cache.setQueryData(["journal-permissions", { journalId }], context);
|
||||
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
onSuccess: () => {
|
||||
getCurrentUserPermissions();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const removeJournalPermissionMutation = useMutation(
|
||||
JournalService.deleteJournalPermission(journalId),
|
||||
{
|
||||
onMutate: (data) => {
|
||||
const newJournalPermissionResponse = cache.getQueryData([
|
||||
"journal-permissions",
|
||||
{ journalId },
|
||||
]);
|
||||
const previousJournalPermissionResponse = JSON.parse(
|
||||
JSON.stringify(newJournalPermissionResponse)
|
||||
);
|
||||
const index = previousJournalPermissionResponse.findIndex(
|
||||
(i) => i.holder_id === data.holder_id
|
||||
);
|
||||
newJournalPermissionResponse[index].permissions =
|
||||
newJournalPermissionResponse[index].permissions.filter(
|
||||
(value) => !data.permission_list.includes(value)
|
||||
);
|
||||
|
||||
if (newJournalPermissionResponse[index].permissions.length < 1) {
|
||||
newJournalPermissionResponse.splice(index, 1);
|
||||
}
|
||||
|
||||
cache.setQueryData(
|
||||
["journal-permissions", { journalId }],
|
||||
newJournalPermissionResponse
|
||||
);
|
||||
|
||||
return previousJournalPermissionResponse;
|
||||
},
|
||||
onError: (error, value, context) => {
|
||||
cache.setQueryData(["journal-permissions", { journalId }], context);
|
||||
|
||||
toast(error, "error");
|
||||
},
|
||||
|
||||
onSuccess: () => {
|
||||
getCurrentUserPermissions();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const holders = data;
|
||||
return {
|
||||
holders,
|
||||
isLoading,
|
||||
getPermissions,
|
||||
error,
|
||||
setJournalPermissionMutation,
|
||||
removeJournalPermissionMutation,
|
||||
currentUserPermissions,
|
||||
currentUserPermissionsIsLoading,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournalPermissions;
|
|
@ -1,36 +0,0 @@
|
|||
import { useQuery } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useJournalStats = (journalId) => {
|
||||
const toast = useToast();
|
||||
|
||||
const getStats = async (query, key) => {
|
||||
const response = await JournalService.getJournalStats(key, { journalId })(
|
||||
query
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
const { data, isLoading, refetch } = useQuery(
|
||||
["journal-stats", { journalId }],
|
||||
getStats,
|
||||
{
|
||||
...queryCacheProps,
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
onSuccess: () => {},
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
data,
|
||||
isLoading,
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournalStats;
|
|
@ -1,58 +0,0 @@
|
|||
import { useQuery } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
import { useToast, useUser } from ".";
|
||||
|
||||
const useJournals = () => {
|
||||
const toast = useToast();
|
||||
const { user } = useUser();
|
||||
|
||||
const getAllJournals = async () => {
|
||||
const response = await JournalService.getAll();
|
||||
const newAllJournals = [...response.data.journals];
|
||||
newAllJournals.sort(function (a, b) {
|
||||
var aName = a.name.toUpperCase();
|
||||
var bName = b.name.toUpperCase();
|
||||
return aName < bName ? -1 : aName < bName ? 1 : 0;
|
||||
});
|
||||
return [...newAllJournals];
|
||||
};
|
||||
|
||||
const journalsCache = useQuery("journals-list", getAllJournals, {
|
||||
...queryCacheProps,
|
||||
placeholderData: [],
|
||||
enabled: !!user,
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
const getPublicJournals = async () => {
|
||||
const response = await JournalService.getPublicJournals();
|
||||
|
||||
const newPublicJournals = [...response.data.journals];
|
||||
newPublicJournals.sort(function (a, b) {
|
||||
var aName = a.name.toUpperCase();
|
||||
var bName = b.name.toUpperCase();
|
||||
return aName < bName ? -1 : aName < bName ? 1 : 0;
|
||||
});
|
||||
|
||||
return [...newPublicJournals];
|
||||
};
|
||||
|
||||
const publicJournalsCache = useQuery(["journals-public"], getPublicJournals, {
|
||||
placeholderData: [],
|
||||
...queryCacheProps,
|
||||
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
journalsCache,
|
||||
publicJournalsCache,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournals;
|
|
@ -1,25 +0,0 @@
|
|||
import { useQuery } from "react-query";
|
||||
import { JournalService } from "../services";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const useJournals = () => {
|
||||
const getJournalsScopes = async () => {
|
||||
var data;
|
||||
|
||||
data = await JournalService.getJournalsScopes();
|
||||
const scopes = data.data.scopes;
|
||||
|
||||
return [...scopes];
|
||||
};
|
||||
|
||||
const scopesCache = useQuery("journals-scopes", getJournalsScopes, {
|
||||
...queryCacheProps,
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
return {
|
||||
scopesCache,
|
||||
};
|
||||
};
|
||||
|
||||
export default useJournals;
|
|
@ -28,7 +28,7 @@ const useLogin = (loginType) => {
|
|||
if (!data) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("BUGOUT_ACCESS_TOKEN", data.data.access_token);
|
||||
localStorage.setItem("MOONSTREAM_ACCESS_TOKEN", data.data.id);
|
||||
const invite_code = window.sessionStorage.getItem("invite_code");
|
||||
if (invite_code) {
|
||||
inviteAccept(invite_code);
|
||||
|
@ -36,10 +36,12 @@ const useLogin = (loginType) => {
|
|||
getUser();
|
||||
if (analytics.isLoaded) {
|
||||
analytics.mixpanel.people.set_once({
|
||||
[`${analytics.MIXPANEL_EVENTS.FIRST_LOGIN_DATE}`]: new Date().toISOString(),
|
||||
[`${analytics.MIXPANEL_EVENTS.FIRST_LOGIN_DATE}`]:
|
||||
new Date().toISOString(),
|
||||
});
|
||||
analytics.mixpanel.people.set({
|
||||
[`${analytics.MIXPANEL_EVENTS.LAST_LOGIN_DATE}`]: new Date().toISOString(),
|
||||
[`${analytics.MIXPANEL_EVENTS.LAST_LOGIN_DATE}`]:
|
||||
new Date().toISOString(),
|
||||
});
|
||||
analytics.mixpanel.track(
|
||||
`${analytics.MIXPANEL_EVENTS.USER_LOGS_IN}`,
|
||||
|
|
|
@ -8,7 +8,7 @@ const useLogout = () => {
|
|||
const { setLoggingOut } = useContext(UIContext);
|
||||
const router = useRouter();
|
||||
const analytics = useAnalytics();
|
||||
const {mutate: revoke, data } = useMutation(AuthService.revoke, {
|
||||
const { mutate: revoke, data } = useMutation(AuthService.revoke, {
|
||||
onSuccess: () => {
|
||||
if (analytics.isLoaded) {
|
||||
analytics.mixpanel.track(
|
||||
|
@ -34,7 +34,7 @@ const useLogout = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
localStorage.removeItem("BUGOUT_ACCESS_TOKEN");
|
||||
localStorage.removeItem("MOONSTREAM_ACCESS_TOKEN");
|
||||
cache.clear();
|
||||
}, [data, cache]);
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
import { useQuery, useQueryCache } from "react-query";
|
||||
import { PreferencesService } from "../services";
|
||||
import { queryCacheProps } from "./hookCommon";
|
||||
|
||||
const getPreferences = async () => {
|
||||
let preferences = {};
|
||||
try {
|
||||
const defaultJournalResponse = await PreferencesService.getDefaultJournal();
|
||||
preferences.defaultJournal = defaultJournalResponse.data?.id;
|
||||
} catch {
|
||||
preferences.defaultJournal = null;
|
||||
}
|
||||
return preferences;
|
||||
};
|
||||
|
||||
const usePreferences = () => {
|
||||
const preferencesKey = "preferences-default-journal";
|
||||
const cache = useQueryCache();
|
||||
const { data, refetch } = useQuery(preferencesKey, getPreferences, {
|
||||
...queryCacheProps,
|
||||
staleTime: 300000,
|
||||
});
|
||||
|
||||
const invalidateAfter = (modifierFn) => {
|
||||
return async function (...args) {
|
||||
await modifierFn(...args);
|
||||
cache.invalidateQueries(preferencesKey);
|
||||
};
|
||||
};
|
||||
|
||||
const setPreference = {
|
||||
defaultJournal: invalidateAfter(PreferencesService.setDefaultJournal),
|
||||
};
|
||||
const unsetPreference = {
|
||||
defaultJournal: invalidateAfter(PreferencesService.unsetDefaultJournal),
|
||||
};
|
||||
return { data, refetch, setPreference, unsetPreference };
|
||||
};
|
||||
|
||||
export default usePreferences;
|
|
@ -15,10 +15,13 @@ const useSignUp = (source) => {
|
|||
isLoading,
|
||||
error,
|
||||
data,
|
||||
isSuccess
|
||||
isSuccess,
|
||||
} = useMutation(AuthService.register(), {
|
||||
onSuccess: (response) => {
|
||||
localStorage.setItem("BUGOUT_ACCESS_TOKEN", response.data.access_token);
|
||||
localStorage.setItem(
|
||||
"MOONSTREAM_ACCESS_TOKEN",
|
||||
response.data.access_token
|
||||
);
|
||||
const invite_code = window.sessionStorage.getItem("invite_code");
|
||||
if (invite_code) {
|
||||
inviteAccept(invite_code);
|
||||
|
|
|
@ -58,8 +58,7 @@ const useJournalEntries = ({
|
|||
getNextPageParam: (lastGroup) => {
|
||||
return lastGroup.next_offset === null ? false : lastGroup.next_offset;
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
},
|
||||
onSuccess: (data) => {},
|
||||
enabled: !!enabled,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { useToast as useChakraToast, Box } from "@chakra-ui/react";
|
||||
import { useCallback } from "react";
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import { useMutation } from "react-query";
|
||||
import { AuthService } from "../services";
|
||||
|
||||
const useTokens = () => {
|
||||
const {
|
||||
mutate: list,
|
||||
isLoading,
|
||||
error,
|
||||
data,
|
||||
} = useMutation(AuthService.getTokenList);
|
||||
const { mutate: revoke } = useMutation(AuthService.revokeToken, {
|
||||
onSuccess: () => {
|
||||
list();
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: update } = useMutation(AuthService.updateToken, {
|
||||
onSuccess: () => {
|
||||
list();
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
list,
|
||||
update,
|
||||
revoke,
|
||||
isLoading,
|
||||
data,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTokens;
|
|
@ -1,73 +0,0 @@
|
|||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { EntryService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useUpdateEntry = (journalId, entryId) => {
|
||||
const entriesCache = useQueryClient();
|
||||
const entryCache = useQueryClient();
|
||||
const toast = useToast();
|
||||
|
||||
const handleError = (error, variables, context) => {
|
||||
entriesCache.setQueryData(
|
||||
["journal-entries", { journalId }],
|
||||
context.prevEntriesPages
|
||||
);
|
||||
entryCache.setQueryData(
|
||||
["journal-entry", { journalId, entryId }],
|
||||
context.prevEntry
|
||||
);
|
||||
|
||||
toast(error, "error");
|
||||
};
|
||||
|
||||
const { mutate: updateEntry } = useMutation(
|
||||
EntryService.update(journalId, entryId),
|
||||
{
|
||||
onMutate: (newData) => {
|
||||
const prevEntriesPages = entriesCache.getQueryData([
|
||||
"journal-entries",
|
||||
{ journalId },
|
||||
]);
|
||||
|
||||
const newEntriesPages = JSON.parse(JSON.stringify(prevEntriesPages));
|
||||
const prevEntry = entryCache.getQueryData([
|
||||
"journal-entry",
|
||||
{ journalId, entryId },
|
||||
]);
|
||||
|
||||
const newEntry = { ...prevEntry, ...newData };
|
||||
|
||||
newEntriesPages.map((page) => {
|
||||
page.data = page.data.map((entry) => {
|
||||
if (entry.id === entryId) {
|
||||
return {
|
||||
...entry,
|
||||
...newData,
|
||||
// for tags useUpdateTag instead
|
||||
};
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
return page;
|
||||
});
|
||||
|
||||
entriesCache.setQueryData(
|
||||
["journal-entries", { journalId }],
|
||||
newEntriesPages
|
||||
);
|
||||
entryCache.setQueryData(
|
||||
["journal-entry", { journalId, entryId }],
|
||||
newEntry
|
||||
);
|
||||
|
||||
return { prevEntriesPages, prevEntry };
|
||||
},
|
||||
onError: (error, variables, context) =>
|
||||
handleError(error, variables, context),
|
||||
}
|
||||
);
|
||||
|
||||
return updateEntry;
|
||||
};
|
||||
|
||||
export default useUpdateEntry;
|
|
@ -1,100 +0,0 @@
|
|||
import { useCallback } from "react";
|
||||
import { useMutation, useQueryCache } from "react-query";
|
||||
import { TagService } from "../services";
|
||||
import { useToast } from ".";
|
||||
|
||||
const useUpdateTag = (journalId, entryId) => {
|
||||
const cache = useQueryCache();
|
||||
const entryCache = useQueryCache();
|
||||
const toast = useToast();
|
||||
|
||||
const updateCache = (tagUpdate) => {
|
||||
const prevEntriesPages = cache.getQueryData([
|
||||
"journal-entries",
|
||||
{ journalId },
|
||||
]);
|
||||
const newEntriesPages = JSON.parse(JSON.stringify(prevEntriesPages));
|
||||
const prevEntry = entryCache.getQueryData([
|
||||
"journal-entry",
|
||||
{ journalId, entryId },
|
||||
]);
|
||||
const newEntry = JSON.parse(JSON.stringify(prevEntry));
|
||||
|
||||
newEntriesPages.map((page) => {
|
||||
page.data = page.data.map((entry) => {
|
||||
if (entry.id === entryId) {
|
||||
var newTags;
|
||||
if (tagUpdate.action === "add") {
|
||||
newTags = [...entry.tags, tagUpdate.tag];
|
||||
entry.tags = newTags;
|
||||
} else {
|
||||
newTags = entry.tags.filter((item) => item !== tagUpdate.tag);
|
||||
entry.tags = newTags;
|
||||
}
|
||||
newEntry.tags = newTags;
|
||||
entryCache.setQueryData(
|
||||
["journal-entry", { journalId, entryId }],
|
||||
newEntry
|
||||
);
|
||||
}
|
||||
|
||||
return entry;
|
||||
});
|
||||
return page;
|
||||
});
|
||||
cache.setQueryData(["journal-entries", { journalId }], newEntriesPages);
|
||||
|
||||
return { prevEntriesPages, prevEntry };
|
||||
};
|
||||
|
||||
const handleError = (error, variables, context) => {
|
||||
if (context) {
|
||||
cache.setQueryData(
|
||||
["journal-entries", { journalId }],
|
||||
context.prevEntriesPages
|
||||
);
|
||||
entryCache.setQueryData(
|
||||
["journal-entry", { journalId, entryId }],
|
||||
context.prevEntry
|
||||
);
|
||||
}
|
||||
|
||||
toast(error, "error");
|
||||
};
|
||||
const [addTag] = useMutation(TagService.createTag(journalId, entryId), {
|
||||
onMutate: (data) => {
|
||||
let retval = updateCache({ tag: data.tags[0], action: "add" });
|
||||
return retval;
|
||||
},
|
||||
onError: (error, variables, context) =>
|
||||
handleError(error, variables, context),
|
||||
});
|
||||
|
||||
const [deleteTag] = useMutation(TagService.deleteTag(journalId, entryId), {
|
||||
onMutate: (data) => {
|
||||
let retval = updateCache(data);
|
||||
return retval;
|
||||
},
|
||||
onError: (error, variables, context) =>
|
||||
handleError(error, variables, context),
|
||||
});
|
||||
|
||||
const updateTag = useCallback(
|
||||
(tagUpdate) => {
|
||||
switch (tagUpdate.action) {
|
||||
case "add":
|
||||
addTag({ tags: [tagUpdate.tag] });
|
||||
break;
|
||||
case "delete":
|
||||
deleteTag({ tag: tagUpdate.tag });
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
},
|
||||
[addTag, deleteTag]
|
||||
);
|
||||
|
||||
return updateTag;
|
||||
};
|
||||
export default useUpdateTag;
|
|
@ -1 +0,0 @@
|
|||
export const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
|
@ -1,14 +1,14 @@
|
|||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import http from "axios";
|
||||
import { AUTH_URL } from "./constants";
|
||||
import UserContext from "./context";
|
||||
import { AUTH_URL } from "../../services/auth.service";
|
||||
|
||||
const UserProvider = ({ children }) => {
|
||||
const [user, setUser] = useState();
|
||||
const [isInit, setInit] = useState(false);
|
||||
|
||||
const getUser = useCallback(() => {
|
||||
const token = localStorage.getItem("BUGOUT_ACCESS_TOKEN");
|
||||
const token = localStorage.getItem("MOONSTREAM_ACCESS_TOKEN");
|
||||
if (!token) {
|
||||
setInit(true);
|
||||
return setUser(null);
|
||||
|
@ -16,7 +16,7 @@ const UserProvider = ({ children }) => {
|
|||
|
||||
const headers = { Authorization: `Bearer ${token}` };
|
||||
http
|
||||
.get(`${AUTH_URL}/user`, { headers })
|
||||
.get(`${AUTH_URL}/`, { headers })
|
||||
.then((response) => {
|
||||
setUser(response.data);
|
||||
})
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { http } from "../utils";
|
||||
|
||||
const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
||||
const API_URL = process.env.NEXT_PUBLIC_MOONSTREAM_API_URL;
|
||||
export const AUTH_URL = `${API_URL}/users`;
|
||||
|
||||
export const login = ({ username, password }) => {
|
||||
console.log('login',username, password)
|
||||
const data = new FormData();
|
||||
data.append("username", username);
|
||||
data.append("password", password);
|
||||
|
@ -17,66 +17,38 @@ export const login = ({ username, password }) => {
|
|||
|
||||
export const revoke = () => {
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/revoke/${localStorage.getItem("BUGOUT_ACCESS_TOKEN")}`,
|
||||
});
|
||||
};
|
||||
|
||||
export const register = () => ({ username, email, password }) => {
|
||||
const data = new FormData();
|
||||
data.append("username", username);
|
||||
data.append("email", email);
|
||||
data.append("password", password);
|
||||
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/user`,
|
||||
data,
|
||||
}).then(() =>
|
||||
http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/token`,
|
||||
data,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const verify = ({ code }) => {
|
||||
const data = new FormData();
|
||||
data.append("verification_code", code);
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/confirm`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const getTokenList = () => {
|
||||
const data = new FormData();
|
||||
return http({
|
||||
method: "GET",
|
||||
url: `${AUTH_URL}/tokens`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const updateToken = ({ note, token }) => {
|
||||
const data = new FormData();
|
||||
data.append("token_note", note);
|
||||
data.append("access_token", token);
|
||||
return http({
|
||||
method: "PUT",
|
||||
method: "DELETE",
|
||||
url: `${AUTH_URL}/token`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const register =
|
||||
() =>
|
||||
({ username, email, password }) => {
|
||||
const data = new FormData();
|
||||
data.append("username", username);
|
||||
data.append("email", email);
|
||||
data.append("password", password);
|
||||
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/`,
|
||||
data,
|
||||
}).then(() =>
|
||||
http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/token`,
|
||||
data,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const forgotPassword = ({ email }) => {
|
||||
const data = new FormData();
|
||||
data.append("email", email);
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/reset`,
|
||||
url: `${AUTH_URL}/password/reset_initiate`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
@ -87,18 +59,11 @@ export const resetPassword = ({ newPassword, resetId }) => {
|
|||
data.append("new_password", newPassword);
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/password/reset`,
|
||||
url: `${AUTH_URL}/password/reset_complete`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const revokeToken = (token) => {
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${AUTH_URL}/revoke/${token}`,
|
||||
});
|
||||
};
|
||||
|
||||
export const changePassword = ({ currentPassword, newPassword }) => {
|
||||
const data = new FormData();
|
||||
data.append("current_password", currentPassword);
|
||||
|
|
|
@ -50,20 +50,19 @@ export const getTokens = (humbugId) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const createRestrictedToken = (humbugId) => ({
|
||||
appName,
|
||||
appVersion,
|
||||
}) => {
|
||||
const data = new FormData();
|
||||
data.append("app_name", appName);
|
||||
data.append("app_version", appVersion);
|
||||
export const createRestrictedToken =
|
||||
(humbugId) =>
|
||||
({ appName, appVersion }) => {
|
||||
const data = new FormData();
|
||||
data.append("app_name", appName);
|
||||
data.append("app_version", appVersion);
|
||||
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${API}/humbug/${humbugId}/tokens`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${API}/humbug/${humbugId}/tokens`,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteRestrictedToken = (humbugId) => (tokenId) => {
|
||||
const data = new FormData();
|
||||
|
|
|
@ -7,7 +7,6 @@ import * as GroupService from "./group.service";
|
|||
import * as PreferencesService from "./preferences.service";
|
||||
import * as HumbugService from "./humbug.service";
|
||||
import * as InvitesService from "./invites.service";
|
||||
import * as UserService from "./user.service";
|
||||
import * as SubscriptionsService from "./subscriptions.service";
|
||||
|
||||
export {
|
||||
|
@ -20,6 +19,5 @@ export {
|
|||
PreferencesService,
|
||||
HumbugService,
|
||||
InvitesService,
|
||||
UserService,
|
||||
SubscriptionsService,
|
||||
};
|
||||
|
|
|
@ -62,35 +62,31 @@ export const getJournalsScopes = () => {
|
|||
});
|
||||
};
|
||||
|
||||
export const setJournalPermission = (journalId) => ({
|
||||
holder_type,
|
||||
holder_id,
|
||||
permission_list,
|
||||
}) => {
|
||||
const data = new FormData();
|
||||
data.append("holder_type", holder_type);
|
||||
data.append("holder_id", holder_id);
|
||||
data.append("permission_list", permission_list);
|
||||
export const setJournalPermission =
|
||||
(journalId) =>
|
||||
({ holder_type, holder_id, permission_list }) => {
|
||||
const data = new FormData();
|
||||
data.append("holder_type", holder_type);
|
||||
data.append("holder_id", holder_id);
|
||||
data.append("permission_list", permission_list);
|
||||
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${API}/journals/${journalId}/scopes`,
|
||||
data: { holder_type, holder_id, permission_list },
|
||||
});
|
||||
};
|
||||
return http({
|
||||
method: "POST",
|
||||
url: `${API}/journals/${journalId}/scopes`,
|
||||
data: { holder_type, holder_id, permission_list },
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteJournalPermission = (journalId) => ({
|
||||
holder_type,
|
||||
holder_id,
|
||||
permission_list,
|
||||
}) => {
|
||||
return http({
|
||||
method: "DELETE",
|
||||
url: `${API}/journals/${journalId}/scopes`,
|
||||
data: { holder_type, holder_id, permission_list },
|
||||
// permission_list: ["read"]
|
||||
});
|
||||
};
|
||||
export const deleteJournalPermission =
|
||||
(journalId) =>
|
||||
({ holder_type, holder_id, permission_list }) => {
|
||||
return http({
|
||||
method: "DELETE",
|
||||
url: `${API}/journals/${journalId}/scopes`,
|
||||
data: { holder_type, holder_id, permission_list },
|
||||
// permission_list: ["read"]
|
||||
});
|
||||
};
|
||||
|
||||
export const getPublicJournals = () =>
|
||||
http({
|
||||
|
@ -98,32 +94,30 @@ export const getPublicJournals = () =>
|
|||
url: `${API}/public/`,
|
||||
});
|
||||
|
||||
export const searchEntries = ({ journalId }) => ({
|
||||
searchTerm,
|
||||
limit,
|
||||
offset,
|
||||
isContent,
|
||||
journalType,
|
||||
}) => {
|
||||
const journalScope = journalType === "personal" ? "journals" : "public";
|
||||
return http({
|
||||
method: "GET",
|
||||
url: `${API}/${journalScope}/${journalId}/search`,
|
||||
params: {
|
||||
// filters: searchTags,
|
||||
q: searchTerm,
|
||||
limit: encodeURIComponent(limit),
|
||||
offset: encodeURIComponent(offset),
|
||||
content: encodeURIComponent(isContent),
|
||||
},
|
||||
});
|
||||
};
|
||||
export const searchEntries =
|
||||
({ journalId }) =>
|
||||
({ searchTerm, limit, offset, isContent, journalType }) => {
|
||||
const journalScope = journalType === "personal" ? "journals" : "public";
|
||||
return http({
|
||||
method: "GET",
|
||||
url: `${API}/${journalScope}/${journalId}/search`,
|
||||
params: {
|
||||
// filters: searchTags,
|
||||
q: searchTerm,
|
||||
limit: encodeURIComponent(limit),
|
||||
offset: encodeURIComponent(offset),
|
||||
content: encodeURIComponent(isContent),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const publicSearchEntries = ({ journalId }) => (query) =>
|
||||
http({
|
||||
method: "GET",
|
||||
url: `${API}/public/${journalId}/search?q=${query}`,
|
||||
});
|
||||
export const publicSearchEntries =
|
||||
({ journalId }) =>
|
||||
(query) =>
|
||||
http({
|
||||
method: "GET",
|
||||
url: `${API}/public/${journalId}/search?q=${query}`,
|
||||
});
|
||||
|
||||
export const getPublicJournal = (key, { journalId }) =>
|
||||
http({
|
||||
|
@ -131,9 +125,11 @@ export const getPublicJournal = (key, { journalId }) =>
|
|||
url: `${API}/public/${journalId}`,
|
||||
});
|
||||
|
||||
export const getJournalStats = (key, { journalId }) => () =>
|
||||
http({
|
||||
method: "GET",
|
||||
url: `${API}/journals/${journalId}/stats`,
|
||||
params: { stats_version: 5 },
|
||||
});
|
||||
export const getJournalStats =
|
||||
(key, { journalId }) =>
|
||||
() =>
|
||||
http({
|
||||
method: "GET",
|
||||
url: `${API}/journals/${journalId}/stats`,
|
||||
params: { stats_version: 5 },
|
||||
});
|
||||
|
|
|
@ -22,9 +22,9 @@ export const getResultsByEndpoint = async (query, endpoint, clientID) => {
|
|||
// myself, I would have to implement the logic to handle multiple origins (since the
|
||||
// Access-Control-Allow-Origins only takes one origin).
|
||||
// At that point, uncomment the following:
|
||||
// const token = localStorage.getItem('BUGOUT_ACCESS_TOKEN')
|
||||
// const token = localStorage.getItem('MOONSTREAM_ACCESS_TOKEN')
|
||||
// if (token) {
|
||||
// headers.Authorization = `Bearer ${localStorage.getItem('BUGOUT_ACCESS_TOKEN')}`
|
||||
// headers.Authorization = `Bearer ${localStorage.getItem('MOONSTREAM_ACCESS_TOKEN')}`
|
||||
// }
|
||||
|
||||
const response = await fetch(requestURL, { method, headers });
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import { http } from "../utils";
|
||||
|
||||
const AUTH_URL = process.env.NEXT_PUBLIC_SIMIOTICS_AUTH_URL;
|
||||
|
||||
export const findUser = (query) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: `${AUTH_URL}/user/find?${query}`,
|
||||
});
|
||||
};
|
|
@ -4,7 +4,7 @@ let axios = require("axios");
|
|||
enableMockupRequests(axios);
|
||||
|
||||
const http = (config) => {
|
||||
const token = localStorage.getItem("BUGOUT_ACCESS_TOKEN");
|
||||
const token = localStorage.getItem("MOONSTREAM_ACCESS_TOKEN");
|
||||
const authorization = token ? { Authorization: `Bearer ${token}` } : {};
|
||||
const defaultHeaders = config.headers ?? {};
|
||||
const options = {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
import { getLayout as getSiteLayout } from "./AppLayout";
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { getLayout as getSiteLayout } from "./RootLayout";
|
||||
import React, { useContext } from "react";
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Scrollable, Footer } from "../components";
|
||||
import { getLayout as getSiteLayout } from "./index";
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { jsx } from "@emotion/react";
|
||||
import { Flex, Spinner } from "@chakra-ui/react";
|
||||
import React, { Suspense, useContext, useState, useEffect } from "react";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Footer from "../components/Footer"
|
||||
import Scrollable from "../components/Scrollable"
|
||||
import Footer from "../components/Footer";
|
||||
import Scrollable from "../components/Scrollable";
|
||||
import RootLayout from "./RootLayout";
|
||||
|
||||
const LayoutWrapper = ({ children }) => {
|
||||
|
|
Ładowanie…
Reference in New Issue