diff --git a/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx
index 9c28e2505..9b2623414 100644
--- a/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx
+++ b/packages/web/lib/networking/queries/useGetIntegrationsQuery.tsx
@@ -11,6 +11,7 @@ export interface Integration {
createdAt: Date
updatedAt: Date
taskName?: string
+ settings?: unknown
}
export type IntegrationType = 'EXPORT' | 'IMPORT'
@@ -43,6 +44,7 @@ export function useGetIntegrationsQuery(): IntegrationsQueryResponse {
createdAt
updatedAt
taskName
+ settings
}
}
... on IntegrationsError {
diff --git a/packages/web/pages/settings/integrations.tsx b/packages/web/pages/settings/integrations.tsx
index 4d549b217..14c019ab7 100644
--- a/packages/web/pages/settings/integrations.tsx
+++ b/packages/web/pages/settings/integrations.tsx
@@ -110,11 +110,14 @@ export default function Integrations(): JSX.Element {
}
}
- const redirectToPocket = (importItemState: ImportItemState) => {
+ const redirectToIntegration = (
+ name: string,
+ importItemState: ImportItemState
+ ) => {
// create a form and submit it to the backend
const form = document.createElement('form')
form.method = 'POST'
- form.action = `${fetchEndpoint}/integration/pocket/auth`
+ form.action = `${fetchEndpoint}/integration/${name.toLowerCase()}/auth`
const input = document.createElement('input')
input.type = 'hidden'
input.name = 'state'
@@ -158,10 +161,39 @@ export default function Integrations(): JSX.Element {
router.replace('/settings/integrations')
}
}
+
+ const connectWithNotion = async () => {
+ try {
+ // get the token from query string
+ const token = router.query.code as string
+ const result = await setIntegrationMutation({
+ token,
+ name: 'NOTION',
+ type: 'EXPORT',
+ enabled: true,
+ })
+ if (result) {
+ revalidate()
+ showSuccessToast('Connected with Notion.')
+ } else {
+ showErrorToast('There was an error connecting to Notion.')
+ }
+ } catch (err) {
+ showErrorToast(
+ 'There was an error connecting to Notion. Please try again.',
+ { duration: 5000 }
+ )
+ } finally {
+ router.replace('/settings/integrations')
+ }
+ }
if (!router.isReady) return
if (router.query.pocketToken && router.query.state && !pocketConnected) {
connectToPocket()
}
+ if (router.query.code) {
+ connectWithNotion()
+ }
}, [router])
useEffect(() => {
@@ -210,7 +242,7 @@ export default function Integrations(): JSX.Element {
action: () => {
pocketConnected
? deleteIntegration(pocketConnected.id)
- : redirectToPocket(ImportItemState.Unarchived)
+ : redirectToIntegration('pocket', ImportItemState.Unarchived)
},
disabled: isImporting(pocketConnected),
isDropdown: !pocketConnected,
@@ -218,18 +250,33 @@ export default function Integrations(): JSX.Element {
{
text: 'Import All',
action: () => {
- redirectToPocket(ImportItemState.All)
+ redirectToIntegration('pocket', ImportItemState.All)
},
},
{
text: 'Import Unarchived',
action: () => {
- redirectToPocket(ImportItemState.Unarchived)
+ redirectToIntegration('pocket', ImportItemState.Unarchived)
},
},
],
},
},
+ {
+ icon: '/static/icons/notion.png',
+ title: 'Notion',
+ subText:
+ 'Notion is an all-in-one workspace. Use our Notion integration to sync your Omnivore items to Notion.',
+ button: {
+ text: 'Settings',
+ icon: ,
+ style: 'ctaWhite',
+ action: () =>
+ router.push(
+ '/settings/integrations/notion'
+ ),
+ },
+ },
{
icon: '/static/icons/webhooks.svg',
title: 'Webhooks',
diff --git a/packages/web/pages/settings/integrations/notion.tsx b/packages/web/pages/settings/integrations/notion.tsx
new file mode 100644
index 000000000..4b956065e
--- /dev/null
+++ b/packages/web/pages/settings/integrations/notion.tsx
@@ -0,0 +1,97 @@
+import { styled } from '@stitches/react'
+import { Button, Checkbox, Form, Input, Switch } from 'antd'
+import 'antd/dist/antd.compact.css'
+import Image from 'next/image'
+import { useMemo } from 'react'
+import {
+ Box,
+ HStack,
+ VStack,
+} from '../../../components/elements/LayoutPrimitives'
+import { PageMetaData } from '../../../components/patterns/PageMetaData'
+import { SettingsLayout } from '../../../components/templates/SettingsLayout'
+import { useGetIntegrationsQuery } from '../../../lib/networking/queries/useGetIntegrationsQuery'
+
+// Styles
+const Header = styled(Box, {
+ color: '$utilityTextDefault',
+ fontSize: 'x-large',
+ margin: '20px',
+})
+
+export default function Notion(): JSX.Element {
+ const { integrations, revalidate } = useGetIntegrationsQuery()
+ const notion = useMemo(() => {
+ return integrations.find((i) => i.name == 'NOTION' && i.type == 'EXPORT')
+ }, [integrations])
+
+ return (
+ <>
+
+
+
+
+
+ Notion integration settings
+
+
+ {notion && (
+
+ )}
+
+
+ >
+ )
+}
diff --git a/packages/web/public/static/icons/notion.png b/packages/web/public/static/icons/notion.png
new file mode 100644
index 000000000..391051679
Binary files /dev/null and b/packages/web/public/static/icons/notion.png differ