diff --git a/components/Shell.tsx b/components/Shell.tsx
index 07cad0bae7..0d32940b5e 100644
--- a/components/Shell.tsx
+++ b/components/Shell.tsx
@@ -1,3 +1,4 @@
+import Link from 'next/link';
import { useState } from "react";
import { signOut, useSession } from 'next-auth/client';
@@ -22,11 +23,21 @@ export default function Shell(props) {
diff --git a/pages/api/integrations.ts b/pages/api/integrations.ts
index a5e406341e..7401a98de5 100644
--- a/pages/api/integrations.ts
+++ b/pages/api/integrations.ts
@@ -8,14 +8,23 @@ export default async function handler(req, res) {
if (!session) { res.status(401).json({message: 'You must be logged in to do this'}); return; }
- // TODO: Add user ID so filtering works properly. User object does not include ID currently.
+ // TODO: Add user ID to user session object
+ const user = await prisma.user.findFirst({
+ where: {
+ email: session.user.email,
+ },
+ select: {
+ id: true
+ }
+ });
const credentials = await prisma.credential.findMany({
where: {
- userId: session.user.id,
+ userId: user.id,
},
select: {
- type: true
+ type: true,
+ key: true
}
});
diff --git a/pages/api/integrations/googlecalendar/add.ts b/pages/api/integrations/googlecalendar/add.ts
new file mode 100644
index 0000000000..18520ae0af
--- /dev/null
+++ b/pages/api/integrations/googlecalendar/add.ts
@@ -0,0 +1,37 @@
+import type { NextApiRequest, NextApiResponse } from 'next'
+import { getSession } from 'next-auth/client';
+import prisma from '../../../../lib/prisma';
+const {google} = require('googleapis');
+
+const credentials = process.env.GOOGLE_API_CREDENTIALS;
+const scopes = ['https://www.googleapis.com/auth/calendar.readonly', 'https://www.googleapis.com/auth/calendar.events'];
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ if (req.method === 'GET') {
+ // Check that user is authenticated
+ const session = await getSession({req: req});
+
+ if (!session) { res.status(401).json({message: 'You must be logged in to do this'}); return; }
+
+ // TODO: Add user ID to user session object
+ const user = await prisma.user.findFirst({
+ where: {
+ email: session.user.email,
+ },
+ select: {
+ id: true
+ }
+ });
+
+ // Get token from Google Calendar API
+ const {client_secret, client_id, redirect_uris} = JSON.parse(credentials).web;
+ const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
+
+ const authUrl = oAuth2Client.generateAuthUrl({
+ access_type: 'offline',
+ scope: scopes,
+ });
+
+ res.status(200).json({url: authUrl});
+ }
+}
\ No newline at end of file
diff --git a/pages/api/integrations/googlecalendar/callback.ts b/pages/api/integrations/googlecalendar/callback.ts
new file mode 100644
index 0000000000..6e0c2f220b
--- /dev/null
+++ b/pages/api/integrations/googlecalendar/callback.ts
@@ -0,0 +1,45 @@
+import type { NextApiRequest, NextApiResponse } from 'next'
+import { getSession } from 'next-auth/client';
+import prisma from '../../../../lib/prisma';
+const {google} = require('googleapis');
+
+const credentials = process.env.GOOGLE_API_CREDENTIALS;
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ const { code } = req.query
+
+ // Check that user is authenticated
+ const session = await getSession({req: req});
+
+ if (!session) { res.status(401).json({message: 'You must be logged in to do this'}); return; }
+
+ // TODO: Add user ID to user session object
+ const user = await prisma.user.findFirst({
+ where: {
+ email: session.user.email,
+ },
+ select: {
+ id: true
+ }
+ });
+
+ const {client_secret, client_id, redirect_uris} = JSON.parse(credentials).web;
+ const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
+
+ // Convert to token
+ oAuth2Client.getToken(code, async (err, token) => {
+ if (err) return console.error('Error retrieving access token', err);
+
+ const credential = await prisma.credential.create({
+ data: {
+ type: 'google_calendar',
+ key: token,
+ userId: user.id
+ }
+ });
+ });
+
+ // Add the credential
+
+ res.redirect('/integrations');
+}
\ No newline at end of file
diff --git a/pages/integrations.tsx b/pages/integrations.tsx
index 4b2e8d0a66..445845fa7f 100644
--- a/pages/integrations.tsx
+++ b/pages/integrations.tsx
@@ -4,14 +4,15 @@ import { useState } from 'react';
import { useSession, getSession } from 'next-auth/client';
export default function Home() {
- const [ session, loading ] = useSession();
- const [ integrations, setIntegrations ] = useState([]);
+ const [session, loading] = useSession();
+ const [integrations, setIntegrations] = useState([]);
+ const [showAddModal, setShowAddModal] = useState(false);
if (loading) {
return Loading...
;
} else {
if (!session) {
- window.location.href="/";
+ window.location.href = "/";
}
}
@@ -21,8 +22,19 @@ export default function Home() {
.then((data) => setIntegrations(data));
}
+ // TODO: Stop this function from running repeatedly
getIntegrations()
+ function toggleAddModal() {
+ setShowAddModal(!showAddModal);
+ }
+
+ function googleCalendarHandler() {
+ fetch('/api/integrations/googlecalendar/add')
+ .then((response) => response.json())
+ .then((data) => window.location.href = data.url);
+ }
+
return (
@@ -39,7 +51,7 @@ export default function Home() {
- {integration.type == 'google_calendar' &&

}
+ {integration.type == 'google_calendar' &&

}
@@ -59,10 +71,10 @@ export default function Home() {
}
{!integration.key &&
-
-
+
+
Not connected
}
@@ -72,10 +84,10 @@ export default function Home() {
@@ -83,7 +95,99 @@ export default function Home() {
)}
+ {integrations.length == 0 &&
+
+
+
+
+
+ You don't have any integrations added.
+
+
+
+ You currently do not have any integrations set up. Add your first integration to get started.
+
+
+
+
+
+
+
+
+ }
+ {showAddModal &&
+
+
+ {/* */}
+
+
+ {/* */}
+
+
+
+
+
+ Add a new integration
+
+
+
+ Link a new integration to your account.
+
+
+
+
+
+
+ -
+
+

+
+
+
Google Calendar
+
For personal and business accounts
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
);