Skip to content

Commit

Permalink
added youtube channels
Browse files Browse the repository at this point in the history
  • Loading branch information
anoopkarnik committed Jul 22, 2024
1 parent d5708f5 commit 22825d0
Show file tree
Hide file tree
Showing 33 changed files with 524 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface notionProps {
}

export const onNotionConnection = async ({access_token, notion_connected, workspace_id, workspace_icon, workspace_name,
userId}: notionProps) => {
userId}: any) => {
if(access_token){
const notion_connected = await getNotionByAccessToken(access_token)
if (!notion_connected){
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard-app/actions/connections/openai-connections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ interface Props {
userId: string
}

export const onOpenAIConnection = async ({apiKey,userId}:Props) => {
export const onOpenAIConnection = async ({apiKey,userId}:any) => {
if(apiKey){
const openai_connected = await getOpenAIByAPIKey(apiKey)
if (!openai_connected){
await createOpenAI({apiKey,openai_connected, userId})
await createOpenAI({name: 'My OpenAI Key',apiKey,openai_connected, userId})
}
}

Expand Down
21 changes: 21 additions & 0 deletions apps/dashboard-app/actions/connections/user-connections.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
'use server'
import { getConnectionByUser} from '@repo/prisma-db/repo/user'

import { updateConnection,deleteConnection, deleteYoutubeConnection, deleteNotionConnection, deleteOpenAIConnection } from '@repo/prisma-db/repo/connection'
export const getUserInfo = async (userId: string) => {
const user_info:any = await getConnectionByUser(userId);
return user_info;
}

export const updateConnectionById = async (id: string, name: string) => {
const conn = await updateConnection(id,name);
return conn;
}

export const deleteConnectionById = async (id: string) => {
const conn = await deleteConnection(id);
if (conn.type === 'Youtube') {
await deleteYoutubeConnection(conn.youtubeId as string);
}
else if (conn.type === 'OpenAI') {
await deleteOpenAIConnection(conn.openaiId as string);
}
else if (conn.type === 'Notion') {
await deleteNotionConnection(conn.notionId as string);
}
return conn;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
'use server'

import { createYoutube, getYoutubeByAccessToken, getYoutubeByUserId } from '@repo/prisma-db/repo/youtube'
import { get } from 'http'


export const onYoutubeConnection = async ({access_token, refresh_token, scopes, userId}: any) => {
if(access_token){
console.log('access_token in actions', access_token)
const connected = await getYoutubeByAccessToken(access_token)
console.log('connected', connected)
if (!connected){
const youtube = await createYoutube({access_token, refresh_token, scopes, userId})
const youtube = await createYoutube({name:'My Youtube Account', access_token, refresh_token, scopes, userId})
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'
import React, { useContext, useEffect, useState } from 'react'
import { CONNECTIONS } from '../../../../lib/constant'
import { useSession } from 'next-auth/react'
import { getUserInfo } from '../../../../actions/connections/user-connections'
import { ConnectionsContext } from '../../../../providers/connections-provider'
import ConnectedCard from '../../../../components/ConnectedCard'

const Connected = () => {

const session = useSession()
const [connections,setConnections] = useState<any>([])

useEffect(() => {
const getConnections = async () => {
if (session?.data?.user?.id) {
const userInfo = await getUserInfo(session.data.user.id);
const newConnections: any = [];
for (let connection of userInfo?.connections) {
const cons = CONNECTIONS.find((con) => con.title === connection.type);
if (cons) {
const newConnection = { ...cons, ...connection };
console.log()
if (!connections.some((conn:any) => conn.id === newConnection.id)) {
newConnections.push(newConnection);
}
}
};
setConnections(newConnections);
}
};

getConnections();
}, [session]);

if (!session) {
return <div>loading...</div>
}

return (
<div className='m-6'>
<div>
These are the apps correctly corrected
</div>
<div className='mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4'>

{connections?.map((connection:any) => (
<ConnectedCard
key={connection.title}
connection={connection}
/>
))}
</div>
</div>
)
}

export default Connected;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'
import React from 'react'
import { CONNECTIONS } from '../../../../lib/constant'
import ConnectionCard from '../../../../components/ConnectionCard'

type Props = {
searchParams?: { [key: string]: string | undefined }
}

const Connections = () => {

return (
<div className='m-6'>
<div>
Connect all your apps directly from here. You may need to connect these apps regularly to refresh verfication.
</div>
<div className='mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4'>
{CONNECTIONS.map((connection) => (
<ConnectionCard
key={connection.title}
connection={connection}
/>
))}
</div>
</div>
)
}

export default Connections;
143 changes: 88 additions & 55 deletions apps/dashboard-app/app/(dashboard)/connections/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
'use client'
import React, { useContext, useEffect, useState } from 'react'
import { CONNECTIONS } from '../../../lib/constant'
import { useSession } from 'next-auth/react'
import { onNotionConnection } from '../../../actions/connections/notion-connections'
import { getUserInfo } from '../../../actions/connections/user-connections'
import { useSearchParams } from 'next/navigation'
import ConnectionClient from '../../../components/ConnectionClient'
import { onOpenAIConnection } from '../../../actions/connections/openai-connections'
import { ConnectionsContext } from '../../../providers/connections-provider'
import { onYoutubeConnection } from '../../../actions/connections/youtube-connections'

type Props = {
searchParams?: { [key: string]: string | undefined }
}
import React, { useContext, useEffect, useState } from 'react'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@repo/ui/molecules/shadcn/Tabs'

const Connections = () => {
import { useMedia } from "react-use";
import { Select, SelectContent, SelectItem, SelectTrigger } from '@repo/ui/molecules/shadcn/Select'
import { useRouter, useSearchParams } from 'next/navigation'
import { ConnectionsContext } from '../../../providers/connections-provider'
import Connected from './_components/Connected'
import Connections from './_components/Connections'
import { useSession } from 'next-auth/react';
import { getUserInfo } from '../../../actions/connections/user-connections';
import { onNotionConnection } from '../../../actions/connections/notion-connections';
import { onOpenAIConnection } from '../../../actions/connections/openai-connections';
import { onYoutubeConnection } from '../../../actions/connections/youtube-connections';

const PlannerPage = () => {
const isMobile = useMedia("(max-width: 1324px)", false);
const [selectedValue, setSelectedValue] = useState('Connected Apps')
const params = useSearchParams();
const access_token = params.get('access_token')
const refresh_token = params.get('refresh_token')
Expand All @@ -31,54 +32,86 @@ const Connections = () => {
const userId = user?.id


const handleSelect = (value:any) => {
setSelectedValue(value)
}

const [connections,setConnections] = useState<Record<string,boolean>>({})

useEffect(() =>{
const onUserConnection = async () =>{
if (type === 'Notion'){
// @ts-ignore
await onNotionConnection({access_token,workspace_id,workspace_icon,workspace_name,database_id,userId})
}
if (type === 'OpenAI'){
// @ts-ignore
await onOpenAIConnection({apiKey,userId})
}
if (type === 'Youtube'){
// @ts-ignore
await onYoutubeConnection({access_token,refresh_token,scopes,userId})
}
const user_info = await getUserInfo(userId || '')
const newConnections: Record<string, boolean> = {}
user_info?.connections.forEach((connection: any) => {
newConnections[connection.type] = true
})
setConnections(newConnections)
if (user){
if (type === 'Notion'){
await onNotionConnection({access_token,workspace_id,workspace_icon,workspace_name,database_id,userId})
}
if (type === 'OpenAI'){
await onOpenAIConnection({apiKey,userId})
}
if (type === 'Youtube'){
await onYoutubeConnection({access_token,refresh_token,scopes,userId})
}
const user_info = await getUserInfo(userId || '')
const newConnections: Record<string, boolean> = {}
user_info?.connections.forEach((connection: any) => {
newConnections[connection.type] = true
})
setConnections(newConnections)
}
}
onUserConnection()
},[access_token,refresh_token, scopes, workspace_id,workspace_icon,workspace_name,database_id,apiKey,userId,type])
},[access_token,refresh_token, scopes, workspace_id,workspace_icon,workspace_name,database_id,apiKey,user,type])

return (
<div className='m-6'>
<div>
Connect all your apps directly from here. You may need to connect these apps regularly to refresh verfication.
</div>
<div className='mt-10 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4'>
{CONNECTIONS.map((connection) => (
<ConnectionClient
key={connection.title}
description={connection.description}
title={connection.title}
icon={connection.image}
type={connection.title}
connected={connections}
published={connection.published}
showModal={connection.showModal}
formElements={connection.formElements}
/>
))}

if (!session) {
return <div>loading...</div>
}


if (isMobile){
return (
<div className='flex flex-col items-center w-full my-6'>
<Select onValueChange={handleSelect}>
<SelectTrigger className='my-4 mx-8 w-[200px]'>
<div>{selectedValue}</div>
</SelectTrigger>
<SelectContent className='w-[200px]'>
<SelectItem key={"Connected Apps"} value={"Connected Apps"}>
<div className='flex items-center justify-start gap-4 w-[200px]'>
<div>{"Connected Apps"}</div>
</div>
</SelectItem>
<SelectItem key={"Connections"} value={"Connections"}>
<div className='flex items-center justify-start gap-4 w-[200px]'>
<div>{"Connections"}</div>
</div>
</SelectItem>
</SelectContent>
</Select>
{selectedValue === 'Connected Apps' && <Connected/>}
{selectedValue === 'Connections' && <Connections/>}
</div>
</div>
)
}

return (
<Tabs className='w-full' defaultValue='Connected Apps'>
<TabsList className='flex items-center justify-start flex-wrap rounded-none my-4 gap-4 bg-inherit'>
<TabsTrigger key={"Connected Apps"} value={"Connected Apps"} className='flex gap-1 border-b-2 shadow-md shadow-border/10 hover:bg-accent ' >
<div>{"Connected Apps"}</div>
</TabsTrigger>
<TabsTrigger key={'Connections'} value={'Connections'} className='flex gap-1 border-b-2 shadow-md shadow-border/10 hover:bg-accent ' >
<div>{'Connections'}</div>
</TabsTrigger>
</TabsList>
<TabsContent value='Connected Apps'>
<Connected/>
</TabsContent>
<TabsContent value='Connections'>
<Connections/>
</TabsContent>

</Tabs>
)
}

export default Connections;
export default PlannerPage
2 changes: 1 addition & 1 deletion apps/dashboard-app/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function Layout({children}:{children: React.ReactNode}){
<NavbarClient />
<div className="flex flex-grow overflow-hidden">
<LeftSidebarClient />
<div className="flex-grow overflow-auto">
<div className="flex-grow overflow-auto px-10">
{children}
</div>
</div>
Expand Down
1 change: 0 additions & 1 deletion apps/dashboard-app/app/api/callback/youtube/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import axios from 'axios';
import { NextRequest, NextResponse } from 'next/server';
import { google } from 'googleapis';

Expand Down
27 changes: 27 additions & 0 deletions apps/dashboard-app/app/api/oauth/calendar/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios from 'axios';
import { NextRequest, NextResponse } from 'next/server';
import { google } from 'googleapis';


export async function GET(req: NextRequest) {

const oauth2Client = new google.auth.OAuth2(
process.env.NEXT_PUBLIC_CALENDAR_CLIENT_ID,
process.env.NEXT_PUBLIC_CALENDAR_CLIENT_SECRET,
process.env.NEXT_PUBLIC_CALENDAR_REDIRECT_URI
);

// generate a url that asks permissions for Blogger and Google Calendar scopes
const scopes = [
'https://www.googleapis.com/auth/calendar',
];

const url = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',

// If you only need one scope you can pass it as a string
scope: scopes
});
return NextResponse.redirect(url);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FormProvider, useForm } from 'react-hook-form'
import { FormControl, FormField, FormItem, FormLabel } from '../molecules/shadcn/Form'
import { Input } from '../molecules/shadcn/Input'
import { Button } from '../molecules/shadcn/Button'
import { FormControl, FormField, FormItem, FormLabel } from '@repo/ui/molecules/shadcn/Form'
import { Input } from '@repo/ui/molecules/shadcn/Input'
import { Button } from '@repo/ui/molecules/shadcn/Button'
import { useRouter } from 'next/navigation';

type Props = {
Expand Down
Loading

0 comments on commit 22825d0

Please sign in to comment.