From 15024480aa7fc549382ff1fe9fcba37d658746bd Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Mon, 17 Oct 2022 22:47:42 -0500 Subject: [PATCH 01/18] Integrations Page --- .../web/components/patterns/DropdownMenu.tsx | 5 ++ .../web/components/patterns/PrimaryHeader.tsx | 3 + packages/web/pages/settings/integrations.tsx | 84 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 packages/web/pages/settings/integrations.tsx diff --git a/packages/web/components/patterns/DropdownMenu.tsx b/packages/web/components/patterns/DropdownMenu.tsx index 248b692de..5d39cc1cb 100644 --- a/packages/web/components/patterns/DropdownMenu.tsx +++ b/packages/web/components/patterns/DropdownMenu.tsx @@ -21,6 +21,7 @@ export type HeaderDropdownAction = | 'navigate-to-profile' | 'navigate-to-subscriptions' | 'navigate-to-api' + | 'navigate-to-integrations' | 'increaseFontSize' | 'decreaseFontSize' | 'logout' @@ -87,6 +88,10 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { onSelect={() => props.actionHandler('navigate-to-api')} title="API Keys" /> + props.actionHandler('navigate-to-integrations')} + title="Integrations" + /> window.Intercom('show')} title="Feedback" diff --git a/packages/web/components/patterns/PrimaryHeader.tsx b/packages/web/components/patterns/PrimaryHeader.tsx index bf70b245e..cb8f65a81 100644 --- a/packages/web/components/patterns/PrimaryHeader.tsx +++ b/packages/web/components/patterns/PrimaryHeader.tsx @@ -95,6 +95,9 @@ export function PrimaryHeader(props: HeaderProps): JSX.Element { case 'navigate-to-api': router.push('/settings/api') break + case 'navigate-to-integrations': + router.push('/settings/integrations') + break case 'logout': props.setShowLogoutConfirmation(true) break diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx new file mode 100644 index 000000000..6ac25eecb --- /dev/null +++ b/packages/web/pages/settings/integrations.tsx @@ -0,0 +1,84 @@ +import { styled } from '@stitches/react' +import { Toaster } from 'react-hot-toast' +import { Box, HStack, VStack } from '../../components/elements/LayoutPrimitives' +import { PrimaryLayout } from '../../components/templates/PrimaryLayout' +import { applyStoredTheme } from '../../lib/themeUpdater' + +// Styles +const Header = styled(Box, { + width: '100%', + color: '$utilityTextDefault', + fontSize: 'x-large', + margin: '10px', +}) + +const Para = styled(Box, { + width: '100%', + padding: '20px', + color: '$utilityTextDefault', + borderBottom: '0.5px solid $utilityTextDefault', +}) + +const IntegrationsCard = styled(Box, { + width: '100%', + borderRadius: '5px', + height: '100px', + backgroundColor: '$grayBg', +}) + +const IntegrationBrand = styled(Box, { + height: '100%', + border: '1px solid green', + width: '10%', +}) + +//interface +interface Integrations { + id: string +} + +type integrationsCard = { + icon: string + title: string + subText?: string + button?: string +} +export default function Integrations(): JSX.Element { + applyStoredTheme(false) + + return ( + + + +
Integrations
+
+ + + + Connect with other applications can help enhance and streamline your + experience with Omnivore, below are some useful apps to connect your + Omnivore account to. + + + +
Applications
+ {/* create an integration array with integration props and loop over it */} + + + +
+
+ ) +} From 5c2d61e8ddd047c0d2545db0072de24f085f0345 Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Wed, 19 Oct 2022 16:52:03 -0500 Subject: [PATCH 02/18] Basic Layout for desktop and themes --- packages/web/pages/settings/integrations.tsx | 108 +++++++++++++++--- packages/web/public/static/icons/logseq.svg | 14 +++ packages/web/public/static/icons/readwise.svg | 9 ++ packages/web/public/static/icons/webhooks.svg | 9 ++ 4 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 packages/web/public/static/icons/logseq.svg create mode 100644 packages/web/public/static/icons/readwise.svg create mode 100644 packages/web/public/static/icons/webhooks.svg diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 6ac25eecb..eaea4b2fe 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -1,19 +1,29 @@ +import { useEffect, useState } from 'react' import { styled } from '@stitches/react' import { Toaster } from 'react-hot-toast' -import { Box, HStack, VStack } from '../../components/elements/LayoutPrimitives' +import { Plus } from 'phosphor-react' +import Image from 'next/image' + +import { + Box, + HStack, + SpanBox, + VStack, +} from '../../components/elements/LayoutPrimitives' import { PrimaryLayout } from '../../components/templates/PrimaryLayout' import { applyStoredTheme } from '../../lib/themeUpdater' +import { Button } from '../../components/elements/Button' // Styles const Header = styled(Box, { - width: '100%', + //width: '100%', color: '$utilityTextDefault', fontSize: 'x-large', margin: '10px', }) const Para = styled(Box, { - width: '100%', + //width: '100%', padding: '20px', color: '$utilityTextDefault', borderBottom: '0.5px solid $utilityTextDefault', @@ -22,14 +32,22 @@ const Para = styled(Box, { const IntegrationsCard = styled(Box, { width: '100%', borderRadius: '5px', - height: '100px', backgroundColor: '$grayBg', + margin: '10px 0', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', }) -const IntegrationBrand = styled(Box, { - height: '100%', - border: '1px solid green', - width: '10%', +const IntegrationContent = styled(Box, { + width: '60%', + minWidth: '200px', + padding: '10px', + color: '$utilityTextDefault', + m: '10px', + 'h3, p': { + margin: '0', + }, }) //interface @@ -46,6 +64,33 @@ type integrationsCard = { export default function Integrations(): JSX.Element { applyStoredTheme(false) + const [integrationsArray, setIntegrationsArray] = useState( + Array() + ) + + useEffect(() => { + setIntegrationsArray([ + { + icon: '/static/icons/logseq.svg', + title: 'Logseq', + subText: 'Organize your personal knowledge base', + button: 'install Logseq Plugin', + }, + { + icon: '/static/icons/readwise.svg', + title: 'ReadWise', + subText: 'Synchronize ebooks & articles from Readwise account', + button: 'Connect to Readwise', + }, + { + icon: '/static/icons/webhooks.svg', + title: 'Webhooks', + subText: '## Webhooks', + button: 'View Webhooks', + }, + ]) + }, []) + return ( - +
Integrations
- + Connect with other applications can help enhance and streamline your experience with Omnivore, below are some useful apps to connect your @@ -65,19 +110,48 @@ export default function Integrations(): JSX.Element {
Applications
- {/* create an integration array with integration props and loop over it */} - - - + {integrationsArray.map((item) => { + return ( + + integration Image + +

{item.title}

+

{item.subText}

+
+ +
+ ) + })}
) diff --git a/packages/web/public/static/icons/logseq.svg b/packages/web/public/static/icons/logseq.svg new file mode 100644 index 000000000..9aaf43643 --- /dev/null +++ b/packages/web/public/static/icons/logseq.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/web/public/static/icons/readwise.svg b/packages/web/public/static/icons/readwise.svg new file mode 100644 index 000000000..d40b7fa81 --- /dev/null +++ b/packages/web/public/static/icons/readwise.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/web/public/static/icons/webhooks.svg b/packages/web/public/static/icons/webhooks.svg new file mode 100644 index 000000000..81377821e --- /dev/null +++ b/packages/web/public/static/icons/webhooks.svg @@ -0,0 +1,9 @@ + + + + + + + + + From ba39860929d288362df329eb7c9f76019f60bc60 Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Thu, 20 Oct 2022 17:43:00 -0500 Subject: [PATCH 03/18] CSS polishing --- packages/web/pages/settings/integrations.tsx | 49 ++++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index eaea4b2fe..252cbc8ad 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import { styled } from '@stitches/react' import { Toaster } from 'react-hot-toast' -import { Plus } from 'phosphor-react' +import { DownloadSimple, Eye, Link, Plus } from 'phosphor-react' import Image from 'next/image' import { @@ -26,14 +26,15 @@ const Para = styled(Box, { //width: '100%', padding: '20px', color: '$utilityTextDefault', - borderBottom: '0.5px solid $utilityTextDefault', + borderBottom: '1px solid $grayLine', }) -const IntegrationsCard = styled(Box, { +const IntegrationCard = styled(Box, { width: '100%', borderRadius: '5px', backgroundColor: '$grayBg', margin: '10px 0', + padding: '20px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', @@ -59,7 +60,11 @@ type integrationsCard = { icon: string title: string subText?: string - button?: string + button: { + text: string + icon?: JSX.Element + style: string + } } export default function Integrations(): JSX.Element { applyStoredTheme(false) @@ -74,19 +79,31 @@ export default function Integrations(): JSX.Element { icon: '/static/icons/logseq.svg', title: 'Logseq', subText: 'Organize your personal knowledge base', - button: 'install Logseq Plugin', + button: { + text: `Install Logseq Plugin`, + icon: , + style: 'ctaDarkYellow', + }, }, { icon: '/static/icons/readwise.svg', title: 'ReadWise', subText: 'Synchronize ebooks & articles from Readwise account', - button: 'Connect to Readwise', + button: { + text: 'Connect to Readwise', + icon: , + style: 'ctaDarkYellow', + }, }, { icon: '/static/icons/webhooks.svg', title: 'Webhooks', subText: '## Webhooks', - button: 'View Webhooks', + button: { + text: 'View Webhooks', + icon: , + style: 'ctaWhite', + }, }, ]) }, []) @@ -120,19 +137,23 @@ export default function Integrations(): JSX.Element {
Applications
{integrationsArray.map((item) => { return ( - + integration Image

{item.title}

{item.subText}

-
+ ) })} From 3b7ad0fe19a72f53843a2c6f2f6f5444aad48f3d Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Thu, 20 Oct 2022 18:35:44 -0500 Subject: [PATCH 04/18] Mobile Layout clean up --- packages/web/pages/settings/integrations.tsx | 124 +++++++++---------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 252cbc8ad..971ba8bf7 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -16,39 +16,17 @@ import { Button } from '../../components/elements/Button' // Styles const Header = styled(Box, { - //width: '100%', color: '$utilityTextDefault', fontSize: 'x-large', margin: '10px', }) -const Para = styled(Box, { - //width: '100%', +const Subheader = styled(Box, { padding: '20px', color: '$utilityTextDefault', borderBottom: '1px solid $grayLine', -}) - -const IntegrationCard = styled(Box, { - width: '100%', - borderRadius: '5px', - backgroundColor: '$grayBg', - margin: '10px 0', - padding: '20px', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', -}) - -const IntegrationContent = styled(Box, { - width: '60%', - minWidth: '200px', - padding: '10px', - color: '$utilityTextDefault', - m: '10px', - 'h3, p': { - margin: '0', - }, + margin: '0 auto', + width: '80%', }) //interface @@ -115,17 +93,12 @@ export default function Integrations(): JSX.Element { top: '5rem', }} /> - -
Integrations
-
- - - - Connect with other applications can help enhance and streamline your - experience with Omnivore, below are some useful apps to connect your - Omnivore account to. - - +
Integrations
+ + Connect with other applications can help enhance and streamline your + experience with Omnivore, below are some useful apps to connect your + Omnivore account to. +
Applications
+ {integrationsArray.map((item) => { return ( - + integration Image - -

{item.title}

-

{item.subText}

-
- -
+ {item.button.icon} + + {item.button.text} + + + + ) })}
From 349b24947b1869dcda13387c9e16a2aa6ab69ff4 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 23 Oct 2022 07:54:10 +0800 Subject: [PATCH 05/18] GQL for the integrations APIs --- .../mutations/setIntegrationMutation.ts | 65 ++++++++++++++++ .../queries/useGetIntegrationsQuery.tsx | 76 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 packages/web/lib/networking/mutations/setIntegrationMutation.ts create mode 100644 packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx diff --git a/packages/web/lib/networking/mutations/setIntegrationMutation.ts b/packages/web/lib/networking/mutations/setIntegrationMutation.ts new file mode 100644 index 000000000..83b567b8d --- /dev/null +++ b/packages/web/lib/networking/mutations/setIntegrationMutation.ts @@ -0,0 +1,65 @@ +import { gql } from 'graphql-request' +import { gqlFetcher } from '../networkHelpers' + +type IntegrationType = 'readwise' + +export type SetIntegrationInput = { + id?: string + type: IntegrationType + token: string, + enabled: boolean +} + +type SetIntegrationResult = { + setIntegration?: SetIntegrationSuccess + errorCodes?: unknown[] +} + +type SetIntegrationSuccess = { + integration: Integration +} + +type Integration = { + id: string + type: IntegrationType + token: string + enabled: boolean + createdAt: Date + updatedAt: Date +} + +export async function setIntegrationMutation( + input: SetIntegrationInput +): Promise { + const mutation = gql` + mutation SetIntegration( + $input: SetIntegrationInput! + ) { + setIntegration(input: $input) { + ... on SetIntegrationSuccess { + integration { + id + type + token + enabled + createdAt + updatedAt + } + } + ... on SetIntegrationError { + errorCodes + } + } + } + ` + + try { + const data = await gqlFetcher(mutation) as SetIntegrationResult + console.log(input, data); + const output = data as any + console.log(output) + return output?.updatedLabel + } catch (err) { + return undefined + } +} diff --git a/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx new file mode 100644 index 000000000..48f7718e6 --- /dev/null +++ b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx @@ -0,0 +1,76 @@ +import { gql } from 'graphql-request' +import useSWR from 'swr' +import { publicGqlFetcher } from '../networkHelpers' + +export interface Integration { + id: String + type: IntegrationType + token: String + enabled: Boolean + createdAt: Date + updatedAt: Date +} + +export type IntegrationType = + | 'READWISE' + +interface IntegrationsQueryResponse { + isValidating: boolean + integrations: Integration[] + revalidate: () => void +} + +interface IntegrationsQueryResponseData { + integrations: IntegrationsData +} + +interface IntegrationsData { + integrations: unknown +} + +export function useGetIntegrationsQuery(): IntegrationsQueryResponse { + const query = gql` + query GetIntegrations { + integrations { + ... on IntegrationsSuccess { + integrations { + id + type + token + enabled + createdAt + updatedAt + } + } + ... on IntegrationsError { + errorCodes + } + } + } + ` + + const { data, mutate, error, isValidating } = useSWR(query, publicGqlFetcher) + console.log('integrations data', data) + + try { + if (data) { + const result = data as IntegrationsQueryResponseData + const integrations = result.integrations.integrations as Integration[] + return { + isValidating, + integrations, + revalidate: () => { + mutate() + }, + } + } + } catch (error) { + console.log('error', error) + } + return { + isValidating: false, + integrations: [], + // eslint-disable-next-line @typescript-eslint/no-empty-function + revalidate: () => {}, + } +} From 63ac113c5575c39991d91ab9865c2cb9c00213ca Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 23 Oct 2022 08:01:05 +0800 Subject: [PATCH 06/18] Check to see if readwise is connected when displaying button --- packages/web/pages/settings/integrations.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 971ba8bf7..5c785deff 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { styled } from '@stitches/react' import { Toaster } from 'react-hot-toast' import { DownloadSimple, Eye, Link, Plus } from 'phosphor-react' @@ -13,6 +13,7 @@ import { import { PrimaryLayout } from '../../components/templates/PrimaryLayout' import { applyStoredTheme } from '../../lib/themeUpdater' import { Button } from '../../components/elements/Button' +import { useGetIntegrationsQuery } from '../../lib/networking/queries/useGetIntegrationsQuery' // Styles const Header = styled(Box, { @@ -46,11 +47,16 @@ type integrationsCard = { } export default function Integrations(): JSX.Element { applyStoredTheme(false) + const { integrations } = useGetIntegrationsQuery() const [integrationsArray, setIntegrationsArray] = useState( Array() ) + const readwiseConnected = useMemo(() => { + return integrations.some((i) => i.type == 'READWISE') + }, [integrations]) + useEffect(() => { setIntegrationsArray([ { @@ -68,7 +74,7 @@ export default function Integrations(): JSX.Element { title: 'ReadWise', subText: 'Synchronize ebooks & articles from Readwise account', button: { - text: 'Connect to Readwise', + text: readwiseConnected ? 'Remove' : 'Connect to Readwise', icon: , style: 'ctaDarkYellow', }, From 24893f1cd40394bfb08b380a13c489c5f493cd18 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 23 Oct 2022 08:04:22 +0800 Subject: [PATCH 07/18] Pass input into setIntegration mutation --- .../web/lib/networking/mutations/setIntegrationMutation.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/web/lib/networking/mutations/setIntegrationMutation.ts b/packages/web/lib/networking/mutations/setIntegrationMutation.ts index 83b567b8d..dda03aacc 100644 --- a/packages/web/lib/networking/mutations/setIntegrationMutation.ts +++ b/packages/web/lib/networking/mutations/setIntegrationMutation.ts @@ -1,7 +1,6 @@ import { gql } from 'graphql-request' import { gqlFetcher } from '../networkHelpers' - -type IntegrationType = 'readwise' +import { IntegrationType } from '../queries/useGetIntegrationsQuery' export type SetIntegrationInput = { id?: string @@ -54,7 +53,7 @@ export async function setIntegrationMutation( ` try { - const data = await gqlFetcher(mutation) as SetIntegrationResult + const data = await gqlFetcher(mutation, { input }) as SetIntegrationResult console.log(input, data); const output = data as any console.log(output) From e0611f242908d74362eccfcada50f332d356fbed Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 23 Oct 2022 08:12:47 +0800 Subject: [PATCH 08/18] Add a basic readwise integration page for testing --- .../web/pages/settings/integrations/readwise.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 packages/web/pages/settings/integrations/readwise.tsx diff --git a/packages/web/pages/settings/integrations/readwise.tsx b/packages/web/pages/settings/integrations/readwise.tsx new file mode 100644 index 000000000..a8fcc5c5c --- /dev/null +++ b/packages/web/pages/settings/integrations/readwise.tsx @@ -0,0 +1,15 @@ +import { PageMetaData } from '../../../components/patterns/PageMetaData' +import { Readwise } from '../../../components/templates/integrations/Readwise' +import { SettingsLayout } from '../../../components/templates/SettingsLayout' + +export default function ReadwisePage(): JSX.Element { + return ( + <> + + + + +
+ + ) +} From 3ab3910b12ae29aa27a6ca71422a42ec19d0283b Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 24 Oct 2022 08:39:03 +0800 Subject: [PATCH 09/18] Add missing component --- .../templates/integrations/Readwise.tsx | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 packages/web/components/templates/integrations/Readwise.tsx diff --git a/packages/web/components/templates/integrations/Readwise.tsx b/packages/web/components/templates/integrations/Readwise.tsx new file mode 100644 index 000000000..7575be6f9 --- /dev/null +++ b/packages/web/components/templates/integrations/Readwise.tsx @@ -0,0 +1,63 @@ +import { SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { Button } from '../../elements/Button' +import { StyledText } from '../../elements/StyledText' +import { useCallback, useEffect, useState } from 'react' +import { FormInput } from '../../elements/FormElements' +import { styled } from '@stitches/react' +import { setIntegrationMutation } from '../../../lib/networking/mutations/setIntegrationMutation' + +const BorderedFormInput = styled(FormInput, { + height: '40px', + paddingLeft: '6px', + borderRadius: '6px', + background: 'white', + color: '$omnivoreGray', + border: `1px solid 1px solid rgba(0, 0, 0, 0.06)`, +}) + +const FormLabel = styled('label', { + fontSize: '16px', + color: '$omnivoreGray', +}) + +export function Readwise(): JSX.Element { + const [token, setToken] = useState('') + const [errorMessage, setErrorMessage] = useState(undefined) + + const setReadwiseToken = useCallback(() => { + setIntegrationMutation({ + token, + type: 'READWISE', + enabled: true, + }) + console.log("SETTING READWISE TOKEN", token) + }, [token]) + + return ( + + + + + Enter your Readwise API token. You can get your token + {' '} + here. + + { e.preventDefault(); setToken(e.target.value); }} + /> + + + + {errorMessage && ( + {errorMessage} + )} + + + ) +} From 64c708986fd2667daa48b66335e781b015c09b38 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 25 Oct 2022 11:14:28 +0800 Subject: [PATCH 10/18] Fix types --- .../web/lib/networking/queries/useGetIntegrationsQuery.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx index 48f7718e6..6c0aafbae 100644 --- a/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx +++ b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx @@ -3,10 +3,10 @@ import useSWR from 'swr' import { publicGqlFetcher } from '../networkHelpers' export interface Integration { - id: String + id: string type: IntegrationType - token: String - enabled: Boolean + token: string + enabled: boolean createdAt: Date updatedAt: Date } From 28b42a09c25cd82d3e325c1aa4dd179e4dbcb641 Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Tue, 25 Oct 2022 14:06:51 -0500 Subject: [PATCH 11/18] Calling WEbhooks api and updating Integrations --- packages/web/pages/settings/integrations.tsx | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 5c785deff..f28b08877 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -1,7 +1,7 @@ import { useEffect, useMemo, useState } from 'react' import { styled } from '@stitches/react' import { Toaster } from 'react-hot-toast' -import { DownloadSimple, Eye, Link, Plus } from 'phosphor-react' +import { DownloadSimple, Eye, Link } from 'phosphor-react' import Image from 'next/image' import { @@ -14,6 +14,7 @@ import { PrimaryLayout } from '../../components/templates/PrimaryLayout' import { applyStoredTheme } from '../../lib/themeUpdater' import { Button } from '../../components/elements/Button' import { useGetIntegrationsQuery } from '../../lib/networking/queries/useGetIntegrationsQuery' +import { useGetWebhooksQuery } from '../../lib/networking/queries/useGetWebhooksQuery' // Styles const Header = styled(Box, { @@ -43,11 +44,13 @@ type integrationsCard = { text: string icon?: JSX.Element style: string + action: () => void } } export default function Integrations(): JSX.Element { applyStoredTheme(false) const { integrations } = useGetIntegrationsQuery() + const { webhooks } = useGetWebhooksQuery() const [integrationsArray, setIntegrationsArray] = useState( Array() @@ -56,6 +59,7 @@ export default function Integrations(): JSX.Element { const readwiseConnected = useMemo(() => { return integrations.some((i) => i.type == 'READWISE') }, [integrations]) + useEffect(() => { setIntegrationsArray([ @@ -67,6 +71,7 @@ export default function Integrations(): JSX.Element { text: `Install Logseq Plugin`, icon: , style: 'ctaDarkYellow', + action: () => alert('You may already have it'), }, }, { @@ -76,21 +81,23 @@ export default function Integrations(): JSX.Element { button: { text: readwiseConnected ? 'Remove' : 'Connect to Readwise', icon: , - style: 'ctaDarkYellow', + style: readwiseConnected ? 'ctaWhite' : 'ctaDarkYellow', + action: () => alert('readwise'), }, }, { icon: '/static/icons/webhooks.svg', title: 'Webhooks', - subText: '## Webhooks', + subText: `${webhooks.length} Webhooks`, button: { text: 'View Webhooks', icon: , style: 'ctaWhite', + action: () => alert('readwise - Open new Page'), }, }, ]) - }, []) + }, [readwiseConnected, webhooks]) return ( @@ -152,7 +159,7 @@ export default function Integrations(): JSX.Element {

{item.title}

{item.subText}

- + - - {errorMessage && ( - {errorMessage} - )} - - +
) } diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index f28b08877..47279928a 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -1,4 +1,5 @@ -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useState} from 'react' +import { useRouter } from 'next/router' import { styled } from '@stitches/react' import { Toaster } from 'react-hot-toast' import { DownloadSimple, Eye, Link } from 'phosphor-react' @@ -55,6 +56,7 @@ export default function Integrations(): JSX.Element { const [integrationsArray, setIntegrationsArray] = useState( Array() ) + const router = useRouter() const readwiseConnected = useMemo(() => { return integrations.some((i) => i.type == 'READWISE') @@ -71,7 +73,7 @@ export default function Integrations(): JSX.Element { text: `Install Logseq Plugin`, icon: , style: 'ctaDarkYellow', - action: () => alert('You may already have it'), + action: () => alert('New LInk required') }, }, { @@ -82,7 +84,7 @@ export default function Integrations(): JSX.Element { text: readwiseConnected ? 'Remove' : 'Connect to Readwise', icon: , style: readwiseConnected ? 'ctaWhite' : 'ctaDarkYellow', - action: () => alert('readwise'), + action: () => router.push("/settings/integrations/readwise") }, }, { @@ -93,7 +95,7 @@ export default function Integrations(): JSX.Element { text: 'View Webhooks', icon: , style: 'ctaWhite', - action: () => alert('readwise - Open new Page'), + action: () =>router.push("/settings/webhooks"), }, }, ]) From 9cda32b64d0905aa650cb9e8115c372b0445f36d Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Tue, 25 Oct 2022 17:54:33 -0500 Subject: [PATCH 13/18] Updating Readwise Page and template + Webhooks Page and Template --- .../templates/integrations/Readwise.tsx | 14 +--- .../templates/integrations/Webhooks.tsx | 68 +++++++++++++++++++ packages/web/pages/settings/integrations.tsx | 2 +- .../pages/settings/integrations/webhooks.tsx | 15 ++++ 4 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 packages/web/components/templates/integrations/Webhooks.tsx create mode 100644 packages/web/pages/settings/integrations/webhooks.tsx diff --git a/packages/web/components/templates/integrations/Readwise.tsx b/packages/web/components/templates/integrations/Readwise.tsx index 215cceb96..695cd7568 100644 --- a/packages/web/components/templates/integrations/Readwise.tsx +++ b/packages/web/components/templates/integrations/Readwise.tsx @@ -1,10 +1,7 @@ import { useCallback, useState } from 'react' import { styled } from '@stitches/react' -import { Toaster } from 'react-hot-toast' import Link from 'next/link' -import { PrimaryLayout } from '../PrimaryLayout' - import { Box, VStack } from '../../elements/LayoutPrimitives' import { Button } from '../../elements/Button' import { StyledText } from '../../elements/StyledText' @@ -34,12 +31,7 @@ export function Readwise(): JSX.Element { }, [token]) return ( - - + <>
Readwise
-
+ ) } diff --git a/packages/web/components/templates/integrations/Webhooks.tsx b/packages/web/components/templates/integrations/Webhooks.tsx new file mode 100644 index 000000000..1698f1fde --- /dev/null +++ b/packages/web/components/templates/integrations/Webhooks.tsx @@ -0,0 +1,68 @@ +import { styled } from '@stitches/react' +import Image from 'next/image' + +import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { Button } from '../../elements/Button' + +import { Plus } from 'phosphor-react' + +// Styles +const Header = styled(Box, { + color: '$utilityTextDefault', + fontSize: 'x-large', + margin: '20px', +}) + +export function Webhooks(): JSX.Element { + return ( + + + integration Image +
WebHooks
+ + + +
+
+ ) +} diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 47279928a..12e8c8052 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -95,7 +95,7 @@ export default function Integrations(): JSX.Element { text: 'View Webhooks', icon: , style: 'ctaWhite', - action: () =>router.push("/settings/webhooks"), + action: () =>router.push("/settings/integrations/webhooks"), }, }, ]) diff --git a/packages/web/pages/settings/integrations/webhooks.tsx b/packages/web/pages/settings/integrations/webhooks.tsx new file mode 100644 index 000000000..212ff18cf --- /dev/null +++ b/packages/web/pages/settings/integrations/webhooks.tsx @@ -0,0 +1,15 @@ +import { PageMetaData } from '../../../components/patterns/PageMetaData' +import { Webhooks } from '../../../components/templates/integrations/Webhooks' +import { SettingsLayout } from '../../../components/templates/SettingsLayout' + +export default function ReadwisePage(): JSX.Element { + return ( + <> + + + + +
+ + ) +} From 1586eee8f67235cf8b219cf55869e17c5b822556 Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Tue, 25 Oct 2022 18:08:28 -0500 Subject: [PATCH 14/18] Laying out webhooks page --- .../templates/integrations/Webhooks.tsx | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/integrations/Webhooks.tsx b/packages/web/components/templates/integrations/Webhooks.tsx index 1698f1fde..5aa736f32 100644 --- a/packages/web/components/templates/integrations/Webhooks.tsx +++ b/packages/web/components/templates/integrations/Webhooks.tsx @@ -39,7 +39,8 @@ export function Webhooks(): JSX.Element { width={75} height={75} /> -
WebHooks
+
Webhooks
+ + + + Use Webhooks to Ut enim ad minim veniam, quis nostrud exercitation. + Tityre, tu patulae recubans sub tegmine fagi dolor. Etiam habebis sem + dicantur magna mollis euismod. + + + + + + ) } From 526078c4feb1ecddd5c405980899dfac6bc605b6 Mon Sep 17 00:00:00 2001 From: Rupin Khandelwal Date: Tue, 25 Oct 2022 19:00:58 -0500 Subject: [PATCH 15/18] Updating Readwise and Webhooks and making page consistent --- .../templates/integrations/Readwise.tsx | 133 +++++++++++------- .../templates/integrations/Webhooks.tsx | 40 +++++- 2 files changed, 114 insertions(+), 59 deletions(-) diff --git a/packages/web/components/templates/integrations/Readwise.tsx b/packages/web/components/templates/integrations/Readwise.tsx index 695cd7568..5e2b6f2a4 100644 --- a/packages/web/components/templates/integrations/Readwise.tsx +++ b/packages/web/components/templates/integrations/Readwise.tsx @@ -1,8 +1,9 @@ import { useCallback, useState } from 'react' import { styled } from '@stitches/react' import Link from 'next/link' +import Image from 'next/image' -import { Box, VStack } from '../../elements/LayoutPrimitives' +import { Box, HStack, VStack } from '../../elements/LayoutPrimitives' import { Button } from '../../elements/Button' import { StyledText } from '../../elements/StyledText' import { FormInput } from '../../elements/FormElements' @@ -13,7 +14,7 @@ import { setIntegrationMutation } from '../../../lib/networking/mutations/setInt const Header = styled(Box, { color: '$utilityTextDefault', fontSize: 'x-large', - margin: '20px auto 20px auto', + margin: '20px', }) export function Readwise(): JSX.Element { @@ -31,63 +32,87 @@ export function Readwise(): JSX.Element { }, [token]) return ( - <> -
Readwise
- + -
- Enter your API key from Readwise below. You can get your token{' '} - - here - -
- { - e.preventDefault() - setToken(e.target.value) - }} - disabled={false} - hidden={false} - required={true} - css={{ - border: '1px solid $textNonessential', - borderRadius: '8px', - width: '80%', - bg: 'transparent', - fontSize: '16px', - textIndent: '8px', - margin: '20px auto 20px auto', - height: '38px', - color: '$grayTextContrast', - '&:focus': { - outline: 'none', - boxShadow: '0px 0px 2px 2px rgba(255, 234, 159, 0.56)', - }, - }} - min={200} + integration Image - {errorMessage && {errorMessage}} - -
- + here + + + + { + e.preventDefault() + setToken(e.target.value) + }} + disabled={false} + hidden={false} + required={true} + css={{ + border: '1px solid $textNonessential', + borderRadius: '8px', + width: '80%', + bg: 'transparent', + fontSize: '16px', + textIndent: '8px', + margin: '20px', + height: '38px', + color: '$grayTextContrast', + '&:focus': { + outline: 'none', + boxShadow: '0px 0px 2px 2px rgba(255, 234, 159, 0.56)', + }, + }} + min={200} + /> + {errorMessage && {errorMessage}} + + ) } diff --git a/packages/web/components/templates/integrations/Webhooks.tsx b/packages/web/components/templates/integrations/Webhooks.tsx index 5aa736f32..0a9acd18d 100644 --- a/packages/web/components/templates/integrations/Webhooks.tsx +++ b/packages/web/components/templates/integrations/Webhooks.tsx @@ -5,6 +5,8 @@ import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' import { Button } from '../../elements/Button' import { Plus } from 'phosphor-react' +import { useGetWebhooksQuery } from '../../../lib/networking/queries/useGetWebhooksQuery' +import { useMemo } from 'react' // Styles const Header = styled(Box, { @@ -13,12 +15,41 @@ const Header = styled(Box, { margin: '20px', }) +interface Webhook { + id?: string + url: string + eventTypes: string + contentType?: string + method?: string + enabled?: string + createdAt?: Date + updatedAt?: Date + } + export function Webhooks(): JSX.Element { + + const { webhooks } = useGetWebhooksQuery() + + const webhooksList = useMemo(() => { + const webhooksList = new Map() + webhooks.forEach((webhook) => + webhooksList.set(webhook.id, { + url: webhook.url, + eventTypes: webhook.eventTypes.join(', '), + method: webhook.method, + contentType: webhook.contentType, + createdAt: webhook.createdAt, + }) + ) + return webhooksList + }, [webhooks]) + + console.log('webhooksList', webhooksList) return ( @@ -79,9 +109,9 @@ export function Webhooks(): JSX.Element { From 4b287f0a6946911613976ad1ce59252429b1b2c0 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 26 Oct 2022 16:45:24 +0800 Subject: [PATCH 16/18] Remove Integrations from menu so we can deploy it and test --- packages/web/components/patterns/DropdownMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/components/patterns/DropdownMenu.tsx b/packages/web/components/patterns/DropdownMenu.tsx index 5d39cc1cb..6d72af9cd 100644 --- a/packages/web/components/patterns/DropdownMenu.tsx +++ b/packages/web/components/patterns/DropdownMenu.tsx @@ -88,10 +88,10 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element { onSelect={() => props.actionHandler('navigate-to-api')} title="API Keys" /> - props.actionHandler('navigate-to-integrations')} title="Integrations" - /> + /> */} window.Intercom('show')} title="Feedback" From d9add568583fbad22b2373d512fe2df6a5e4b57d Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 26 Oct 2022 16:45:56 +0800 Subject: [PATCH 17/18] Handle errors when setting readwise API token --- .../templates/integrations/Readwise.tsx | 30 ++++++++++++------- .../mutations/setIntegrationMutation.ts | 22 ++++++++------ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/web/components/templates/integrations/Readwise.tsx b/packages/web/components/templates/integrations/Readwise.tsx index 5e2b6f2a4..da5e62472 100644 --- a/packages/web/components/templates/integrations/Readwise.tsx +++ b/packages/web/components/templates/integrations/Readwise.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { styled } from '@stitches/react' import Link from 'next/link' import Image from 'next/image' @@ -9,6 +9,9 @@ import { StyledText } from '../../elements/StyledText' import { FormInput } from '../../elements/FormElements' import { setIntegrationMutation } from '../../../lib/networking/mutations/setIntegrationMutation' +import { Integration, useGetIntegrationsQuery } from '../../../lib/networking/queries/useGetIntegrationsQuery' +import { Router, useRouter } from 'next/router' +import { showSuccessToast } from '../../../lib/toastHelpers' // Styles const Header = styled(Box, { @@ -18,17 +21,23 @@ const Header = styled(Box, { }) export function Readwise(): JSX.Element { + const router = useRouter() const [token, setToken] = useState('') const [errorMessage, setErrorMessage] = useState(undefined) - const setReadwiseToken = useCallback(() => { - setIntegrationMutation({ - token, - type: 'READWISE', - enabled: true, - }) - console.log('SETTING READWISE TOKEN', token) + const setReadwiseToken = useCallback(async () => { + try { + const result = await setIntegrationMutation({ + token, + type: 'READWISE', + enabled: true, + }) + router.push(`/settings/integrations`) + showSuccessToast('Your Readwise API token has been set.') + } catch (err) { + setErrorMessage('Error: ' + err) + } }, [token]) return ( @@ -65,15 +74,16 @@ export function Readwise(): JSX.Element { fontSize: '18px', color: '$utilityTextDefault', m: '20px', + whiteSpace: 'pre-wrap' }} > - Enter your API key from Readwise below. You can get your token + Enter your API key from Readwise below. You can get your token{' '} here - + . { +): Promise { const mutation = gql` mutation SetIntegration( $input: SetIntegrationInput! @@ -52,13 +56,13 @@ export async function setIntegrationMutation( } ` - try { - const data = await gqlFetcher(mutation, { input }) as SetIntegrationResult - console.log(input, data); - const output = data as any - console.log(output) - return output?.updatedLabel - } catch (err) { - return undefined + const data = await gqlFetcher(mutation, { input }) as SetIntegrationResult + const output = data as any + const error = data.setIntegration?.errorCodes?.find(() => true) + if (error) { + if (error === 'INVALID_TOKEN') + throw 'Your token is invalid.' + throw error } + return output.setIntegration?.setIntegration?.integration } From 1ab504c4f2b689a224c730793f4c7495263e3b23 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Wed, 26 Oct 2022 17:09:39 +0800 Subject: [PATCH 18/18] Update the readwise integration page to handle errors, update descriptions --- packages/web/pages/settings/integrations.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx index 12e8c8052..d59320c9e 100644 --- a/packages/web/pages/settings/integrations.tsx +++ b/packages/web/pages/settings/integrations.tsx @@ -61,25 +61,26 @@ export default function Integrations(): JSX.Element { const readwiseConnected = useMemo(() => { return integrations.some((i) => i.type == 'READWISE') }, [integrations]) - useEffect(() => { setIntegrationsArray([ { icon: '/static/icons/logseq.svg', title: 'Logseq', - subText: 'Organize your personal knowledge base', + subText: 'Logseq is an open-source knowledge base. Use the Omnivore Logseq plugin to sync articles, highlights, and notes to Logseq.', button: { text: `Install Logseq Plugin`, icon: , style: 'ctaDarkYellow', - action: () => alert('New LInk required') + action: () => { + router.push(`https://github.com/omnivore-app/logseq-omnivore`) + } }, }, { icon: '/static/icons/readwise.svg', title: 'ReadWise', - subText: 'Synchronize ebooks & articles from Readwise account', + subText: 'Readwise makes it easy to revisit and learn from your ebook & article highlights. Use our Readwise integration to sync your highlights from Omnivore to Readwise.', button: { text: readwiseConnected ? 'Remove' : 'Connect to Readwise', icon: , @@ -99,7 +100,7 @@ export default function Integrations(): JSX.Element { }, }, ]) - }, [readwiseConnected, webhooks]) + }, [readwiseConnected, integrations, webhooks]) return (