From 349b24947b1869dcda13387c9e16a2aa6ab69ff4 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Sun, 23 Oct 2022 07:54:10 +0800 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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 }