diff --git a/components/layout/connection/ConnectionMain.js b/components/layout/connection/ConnectionMain.js index c5c26a3..4cafa7f 100644 --- a/components/layout/connection/ConnectionMain.js +++ b/components/layout/connection/ConnectionMain.js @@ -19,6 +19,8 @@ export default function ConnectionMain() { handleSlack, handleGoogleSheets, handleHubSpot, + handleNotion, + handleAirtable, } = useSocial(); const connectionTypes = [ @@ -62,6 +64,16 @@ export default function ConnectionMain() { key: "hubspot", type: "redirect", }, + { + name: "Notion", + key: "notion", + type: "redirect", + }, + { + name: "Airtable", + key: "airtable", + type: "redirect", + }, ]; const connectionType = key @@ -76,7 +88,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: "Connection not found", }, - window.location.origin + window.location.origin, ); }, 3000); } @@ -105,7 +117,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "twitter") { @@ -124,7 +136,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "linkedin") { @@ -143,7 +155,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "gmail_trigger") { @@ -162,7 +174,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "gmail_read") { @@ -181,7 +193,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "slack") { @@ -200,7 +212,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "google_sheets") { @@ -219,7 +231,7 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, ); } } else if (connectionType.key === "hubspot") { @@ -238,7 +250,45 @@ export default function ConnectionMain() { type: "SOCIAL_AUTH_ERROR", message: error.message, }, - window.location.origin + window.location.origin, + ); + } + } else if (connectionType.key === "notion") { + try { + const response = await handleNotion(workflowId); + + if (!response.data.success) { + throw new Error(response.data.message); + } + + window.location.href = response.data.authURL; + } catch (error) { + console.log(error); + window.opener.postMessage( + { + type: "SOCIAL_AUTH_ERROR", + message: error.message, + }, + window.location.origin, + ); + } + } else if (connectionType.key === "airtable") { + try { + const response = await handleAirtable(workflowId); + + if (!response.data.success) { + throw new Error(response.data.message); + } + + window.location.href = response.data.authURL; + } catch (error) { + console.log(error); + window.opener.postMessage( + { + type: "SOCIAL_AUTH_ERROR", + message: error.message, + }, + window.location.origin, ); } } diff --git a/components/layout/dashboard/files/FileList.js b/components/layout/dashboard/files/FileList.js index 2a892dd..bf121db 100644 --- a/components/layout/dashboard/files/FileList.js +++ b/components/layout/dashboard/files/FileList.js @@ -29,16 +29,18 @@ const getFilesData = async (page) => { const limit = 10; const response = await fetch( - `${process.env.API_URL}/storage/list?page=${currentPage}&limit=${limit}`, + `${process.env.API_URL}/storage/list?page=${currentPage}&limit=${limit}&t=${Date.now()}`, { method: "GET", headers: { "Content-Type": "application/json", cookie: cookieHeader, + Pragma: "no-cache", + "Cache-Control": "no-cache, no-store, must-revalidate", }, credentials: "include", cache: "no-store", - } + }, ); if (!response.ok) { @@ -76,7 +78,7 @@ const FileList = async ({ page, query }) => { if (query) { files = files.filter((file) => - file.fileName.toLowerCase().includes(query.toLowerCase()) + file.fileName.toLowerCase().includes(query.toLowerCase()), ); } @@ -203,19 +205,20 @@ const FileList = async ({ page, query }) => {
- {file.scrapeStatus && ( + {file.sourceUrl && ( )} - {file.ragStatus && ( - - )} + {(file.sourceUrl ? file.scrapeStatus === "done" : true) && + file.ragStatus && ( + + )}
diff --git a/components/layout/dashboard/files/FileMenuBox.js b/components/layout/dashboard/files/FileMenuBox.js index 8b29070..5aebd0f 100644 --- a/components/layout/dashboard/files/FileMenuBox.js +++ b/components/layout/dashboard/files/FileMenuBox.js @@ -19,7 +19,14 @@ import RagConversionDialog from "./RagConversionDialog"; const baseMenuBtn = "data-highlighted:bg-foreground/5 not-disabled:not-active:not-data-pressed:before:shadow-none px-2 min-h-5 font-normal rounded-sm text-xs [&_svg:not([class*='size-'])]:size-3 dark:not-disabled:not-active:not-data-pressed:before:shadow-none data-highlighted:text-destructive cursor-pointer dark:bg-transparent shadow-none! bg-transparent hover:bg-transparent w-full justify-start border-none"; -const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { +const FileMenuBox = ({ + fileKey, + fileName, + ragStatus, + ragTableName, + sourceUrl, + scrapeStatus, +}) => { const [showRagDialog, setShowRagDialog] = useState(false); const [showEditDialog, setShowEditDialog] = useState(false); const [showDeleteDialog, setShowDeleteDialog] = useState(false); @@ -29,6 +36,15 @@ const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { e.stopPropagation(); }; + const handleRagDialogOpen = () => { + if (sourceUrl && scrapeStatus !== "done") { + toast.error("Scrape not completed"); + return; + } + + setShowRagDialog(!showRagDialog); + }; + const handleDownload = useCallback( async (e) => { stop(e); @@ -41,7 +57,7 @@ const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ fileKey }), - } + }, ); const data = await res.json(); @@ -74,7 +90,7 @@ const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { toast.error("Failed to download file"); } }, - [fileKey, fileName] + [fileKey, fileName], ); const handleEdit = useCallback((e) => { @@ -87,10 +103,14 @@ const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { setShowDeleteDialog(true); }, []); - const handleRagConversion = useCallback((e) => { - stop(e); + const handleRagConversion = () => { + if (sourceUrl && scrapeStatus !== "done") { + toast.error("Scrape not completed"); + return; + } + setShowRagDialog(true); - }, []); + }; return ( <> @@ -182,7 +202,7 @@ const FileMenuBox = ({ fileKey, fileName, ragStatus, ragTableName }) => { ragStatus={ragStatus} ragTableName={ragTableName} open={showRagDialog} - onOpenChange={setShowRagDialog} + onOpenChange={handleRagDialogOpen} /> ); diff --git a/components/layout/dashboard/files/RagConversionDialog.js b/components/layout/dashboard/files/RagConversionDialog.js index c59530b..56fb032 100644 --- a/components/layout/dashboard/files/RagConversionDialog.js +++ b/components/layout/dashboard/files/RagConversionDialog.js @@ -10,7 +10,7 @@ import { } from "lucide-react"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; -import { useState, useEffect, useRef, useMemo } from "react"; +import { useState, useEffect, useMemo } from "react"; import { Dialog, @@ -38,11 +38,9 @@ const RagConversionDialog = ({ const [ragTableName, setRagTableName] = useState(initialRagTableName); const [ragStatus, setRagStatus] = useState( - initialRagStatus || "not-requested" + initialRagStatus || "not-requested", ); - const intervalRef = useRef(null); - const statusInfo = useMemo( () => ({ @@ -86,14 +84,14 @@ const RagConversionDialog = ({ label: "Failed", description: "Conversion failed. You can try again.", }, - }[ragStatus] || { + })[ragStatus] || { icon: Database, color: "text-gray-500", bg: "bg-gray-100 dark:bg-gray-800", label: "Not Converted", description: "This file has not been converted to RAG database yet.", - }), - [ragStatus] + }, + [ragStatus], ); const StatusIcon = statusInfo.icon; @@ -102,39 +100,12 @@ const RagConversionDialog = ({ if (open) { setRagStatus(initialRagStatus || "not-requested"); setRagTableName(initialRagTableName); - refreshStatus(); } else { - cleanupPolling(); setLoading(true); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, initialRagStatus, initialRagTableName]); - useEffect(() => { - if (!open) return; - - if (ragStatus === "queued" || ragStatus === "processing") { - startPolling(); - } else { - cleanupPolling(); - } - - return cleanupPolling; - }, [ragStatus, open]); - - const cleanupPolling = () => { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - }; - - const startPolling = () => { - if (intervalRef.current) return; - intervalRef.current = setInterval(refreshStatus, 5000); - }; - const fetchJson = async (input, init = {}) => { const res = await fetch(input, init); @@ -157,23 +128,31 @@ const RagConversionDialog = ({ try { const url = `${ process.env.NEXT_PUBLIC_API_URL - }/storage/rag-status/${encodeURIComponent(fileKey)}`; + }/storage/rag-status/${encodeURIComponent(fileKey)}?t=${Date.now()}`; const { ok, data } = await fetchJson(url, { method: "GET", cache: "no-store", credentials: "include", - headers: { "Content-Type": "application/json" }, + headers: { + Pragma: "no-cache", + "Cache-Control": "no-cache, no-store, must-revalidate", + "Content-Type": "application/json", + }, }); - if (ok && data?.success) { - const { status, tableName } = data; + if (ok && data && (data.success || data.status)) { + const { status, tableName, message } = data; setRagStatus(status); if (tableName) setRagTableName(tableName); + if (status === "failed" && message) { + // Optional: Display the error message from the backend in a toast + toast.error(message); + } + if (status === "done" || status === "failed") { - cleanupPolling(); router.refresh(); } } @@ -201,21 +180,19 @@ const RagConversionDialog = ({ if (ok && data?.success) { const { status } = data; - setRagStatus(status); - toast.success("Conversion started! This may take a few minutes."); - - if (status === "queued" || status === "processing") { - startPolling(); - } + toast.success( + ragStatus === "failed" + ? "Retry submitted! Check status shortly." + : "Conversion started! Click 'Refresh Status' to check progress.", + ); router.refresh(); } else { toast.error(data?.message || "Conversion request failed"); } } catch (error) { - // eslint-disable-next-line no-console console.error("Conversion error:", error); toast.error("An error occurred while starting conversion"); } finally { @@ -318,6 +295,7 @@ const RagConversionDialog = ({ Close + {/* Initial Convert Button */} {ragStatus === "not-requested" && ( )} + {/* Retry Button - Only shows when Failed */} {ragStatus === "failed" && ( + {initialRagStatus !== "done" && ( + + )} ); }; diff --git a/components/layout/dashboard/files/ScrapeStatusDisplay.js b/components/layout/dashboard/files/ScrapeStatusDisplay.js index 3c5dce6..ee596e3 100644 --- a/components/layout/dashboard/files/ScrapeStatusDisplay.js +++ b/components/layout/dashboard/files/ScrapeStatusDisplay.js @@ -1,9 +1,8 @@ "use client"; -import { toast } from "sonner"; -import { useState, useCallback } from "react"; +import { useCallback } from "react"; import { RefreshCw, Link as LinkIcon } from "lucide-react"; - +import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; const STATUS_COLORS = { @@ -14,52 +13,14 @@ const STATUS_COLORS = { default: "bg-gray-400", }; -const ScrapeStatusDisplay = ({ fileKey, scrapeStatus: initialStatus }) => { - const [isRefreshing, setIsRefreshing] = useState(false); - const [scrapeStatus, setScrapeStatus] = useState(initialStatus); - - if (!scrapeStatus || scrapeStatus === "not-requested") return null; +const ScrapeStatusDisplay = ({ scrapeStatus }) => { + const router = useRouter(); const statusColor = STATUS_COLORS[scrapeStatus] ?? STATUS_COLORS.default; - const handleRefresh = useCallback( - async (e) => { - e.preventDefault(); - e.stopPropagation(); - - if (!fileKey) return; - - setIsRefreshing(true); - - try { - const res = await fetch( - `${ - process.env.NEXT_PUBLIC_API_URL - }/storage/scrape-status/${encodeURIComponent(fileKey)}`, - { - method: "GET", - credentials: "include", - cache: "no-store", - } - ); - - const data = await res.json().catch(() => null); - - if (res.ok && data?.success) { - setScrapeStatus(data.status); - toast.success("Status refreshed"); - } else { - toast.error(data?.message || "Failed to refresh status"); - } - } catch (err) { - console.error("Refresh error:", err); - toast.error("Network error while refreshing"); - } finally { - setIsRefreshing(false); - } - }, - [fileKey] - ); + const handleRefresh = useCallback(async (e) => { + router.refresh(); + }, []); return (
@@ -73,15 +34,13 @@ const ScrapeStatusDisplay = ({ fileKey, scrapeStatus: initialStatus }) => {
diff --git a/components/layout/dashboard/files/UploadFileDialog.js b/components/layout/dashboard/files/UploadFileDialog.js index 4e17436..3f52488 100644 --- a/components/layout/dashboard/files/UploadFileDialog.js +++ b/components/layout/dashboard/files/UploadFileDialog.js @@ -88,7 +88,7 @@ const UploadFileDialog = ({ open, onOpenChange }) => { method: "POST", credentials: "include", body: formData, - } + }, ); const data = await res.json(); @@ -128,7 +128,7 @@ const UploadFileDialog = ({ open, onOpenChange }) => { credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ url: url.trim(), deepSearch }), - } + }, ); const data = await res.json(); @@ -208,7 +208,7 @@ const UploadFileDialog = ({ open, onOpenChange }) => {
-

+

{selectedFile.name}

diff --git a/components/layout/editor/editorWindow/nodes/generic/FilePicker.js b/components/layout/editor/editorWindow/nodes/generic/FilePicker.js index d42e869..32874fb 100644 --- a/components/layout/editor/editorWindow/nodes/generic/FilePicker.js +++ b/components/layout/editor/editorWindow/nodes/generic/FilePicker.js @@ -17,13 +17,23 @@ import { import { Skeleton } from "@/components/ui/skeleton"; import { formatDistanceToNow } from "date-fns"; import useFiles from "@/hooks/useFiles"; -import { FileQuestion, LinkIcon, RefreshCcw, Search } from "lucide-react"; +import { + Database, + FileQuestion, + FileWarning, + LinkIcon, + RefreshCcw, + Search, + Upload, +} from "lucide-react"; import { useEffect, useState } from "react"; import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; import { toast } from "sonner"; +import UploadFileDialog from "@/components/layout/dashboard/files/UploadFileDialog"; +import RagConversionDialog from "@/components/layout/dashboard/files/RagConversionDialog"; export default function FilePicker({ field, @@ -32,6 +42,8 @@ export default function FilePicker({ isTemplate = false, }) { const [open, setOpen] = useState(false); + const [showUploadDialog, setShowUploadDialog] = useState(false); + const [ragConversionDialogOpen, setRagConversionDialogOpen] = useState(false); const { files, @@ -52,6 +64,14 @@ export default function FilePicker({ addSuffix: true, }); + const handleCloseUploadDialog = () => { + if (showUploadDialog) { + getFiles(); + } + + setShowUploadDialog(false); + }; + const handleOpenChange = (open) => { if (isTemplate) { return; @@ -60,282 +80,337 @@ export default function FilePicker({ }; return ( - - - Choose File - - ) : ( - + ) : ( + - ) - } - > - -
- - - Choose File - - - Choose a file from your file library - - -
-
- setQuery(e.target.value)} - className={""} - /> + - -
+ ) + } + > + + + + + Choose File + + + Choose a file from your file library + + +
+
+ setQuery(e.target.value)} + className={""} + /> - {loading && ( -
- - - +
- )} - {!loading && files.length === 0 && ( -
-
- + {loading && ( +
+ + +
-

- No files found -

+ )} - - - -
- )} +
+ )} -
- {!loading && files.length > 0 && ( -
- {files.map((file, index) => { - const createdAt = new Date(file.createdAt || Date.now()); +
+ {!loading && files.length > 0 && ( +
+ {files.map((file, index) => { + const createdAt = new Date(file.createdAt || Date.now()); - const uploadedTimeAgo = formatDistanceToNow(createdAt, { - addSuffix: true, - }); + const uploadedTimeAgo = formatDistanceToNow(createdAt, { + addSuffix: true, + }); - return ( -
setSelectedFile(file)} - className={cn( - "flex flex-col relative hover:cursor-pointer gap-2 border w-full border-foreground/15 rounded-sm p-4 bg-foreground/2 hover:shadow-sm transition-shadow shadow-foreground/10 max-w-[1360px]", - selectedFile?.fileKey === file.fileKey && - "bg-foreground/5 border-foreground", - )} - > - {value && value?.fileKey === file?.fileKey && ( -
- Selected -
- )} -
-
- + return ( +
setSelectedFile(file)} + className={cn( + "flex flex-col relative hover:cursor-pointer gap-2 border w-full border-foreground/15 rounded-sm p-4 bg-foreground/2 hover:shadow-sm transition-shadow shadow-foreground/10 max-w-[1360px]", + selectedFile?.fileKey === file.fileKey && + "bg-foreground/5 border-foreground", + )} + > + {value && value?.fileKey === file?.fileKey && ( +
+ Selected +
+ )} +
+
+ {file?.ragStatus === "done" ? ( + + ) : ( +
+ +
+ )} -
-

- {file.fileName} -

+
+

+ {file.fileName} +

-
- {file.fileSize && ( - {formatFileSize(file.fileSize)} - )} +
+ {file.fileSize && ( + {formatFileSize(file.fileSize)} + )} - {file.fileSize && } - Uploaded {uploadedTimeAgo} + {file.fileSize && } + Uploaded {uploadedTimeAgo} +
-
- + -
-
- {file.sourceUrl && ( -
- +
+
+ {file.sourceUrl && ( +
+ - - {file.sourceUrl} - -
+ + {file.sourceUrl} + +
+ )} +
+ + {( + file?.sourceUrl + ? file?.scrapeStatus === "done" + : true + ) ? ( + file?.ragStatus !== "done" ? ( +
+ +
+ ) : ( + + RAG Processed + + ) + ) : ( + + {file?.scrapeStatus !== "failed" + ? "Processing" + : "Failed"} + )}
- - {file?.ragStatus !== "done" ? ( - - RAG Not Processed - - ) : ( - - RAG Processed - - )}
-
- ); - })} + ); + })} +
+ )} +
+ + {paginationData && paginationData.totalPages > 1 && ( +
+

+ Page {paginationData.currentPage} of{" "} + {paginationData.totalPages} +

+
+ + +
)}
- - {paginationData && paginationData.totalPages > 1 && ( -
-

- Page {paginationData.currentPage} of{" "} - {paginationData.totalPages} -

-
- - -
+ +
+ +
- )} -
- - - - - -
- } - > - Cancel - - -
, - ); - return; - } +
+ } + > + Cancel + + +
, + ); + return; + } - onChange(field.name, selectedFile); - setOpen(false); - }} - disabled={!selectedFile} - > - Select - -
- - - - + onChange(field.name, selectedFile); + setOpen(false); + }} + disabled={!selectedFile} + > + Select + +
+ + + + + ); } diff --git a/components/layout/template/LoginDialog.js b/components/layout/template/LoginDialog.js index 97af565..437a02a 100644 --- a/components/layout/template/LoginDialog.js +++ b/components/layout/template/LoginDialog.js @@ -46,7 +46,7 @@ export default function LoginDialog() { size={60} className="absolute -top-28 left-1/2 -translate-x-1/2" /> -
+
diff --git a/hooks/useSocial.js b/hooks/useSocial.js index 4e91361..f20fd3b 100644 --- a/hooks/useSocial.js +++ b/hooks/useSocial.js @@ -13,7 +13,7 @@ export default function useSocial() { const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/getSocial/${workflowId}`, - {} + {}, ); setWorkflowSocial(response.data.social); @@ -27,14 +27,11 @@ export default function useSocial() { }; const handleYouTube = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=youtube`, {}, - { headers } ); if (!response.data.success) { @@ -45,14 +42,11 @@ export default function useSocial() { }; const handleTwitter = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=twitter`, {}, - { headers } ); if (!response.data.success) { @@ -63,14 +57,11 @@ export default function useSocial() { }; const handleLinkedIn = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=linkedin`, {}, - { headers } ); if (!response.data.success) { @@ -81,14 +72,11 @@ export default function useSocial() { }; const handleGmailTrigger = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=gmail_trigger`, {}, - { headers } ); if (!response.data.success) { @@ -99,14 +87,11 @@ export default function useSocial() { }; const handleGmailRead = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=gmail_read`, {}, - { headers } ); if (!response.data.success) { @@ -117,14 +102,11 @@ export default function useSocial() { }; const handleSlack = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=slack`, {}, - { headers } ); if (!response.data.success) { @@ -135,14 +117,11 @@ export default function useSocial() { }; const handleGoogleSheets = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=google_sheets`, {}, - { headers } ); if (!response.data.success) { @@ -153,14 +132,41 @@ export default function useSocial() { }; const handleHubSpot = async (workflowId) => { - const headers = { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }; + axios.defaults.withCredentials = true; const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=hubspot`, {}, - { headers } + ); + + if (!response.data.success) { + throw new Error(response.data.message); + } + + return response; + }; + + const handleNotion = async (workflowId) => { + axios.defaults.withCredentials = true; + + const response = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=notion`, + {}, + ); + + if (!response.data.success) { + throw new Error(response.data.message); + } + + return response; + }; + + const handleAirtable = async (workflowId) => { + axios.defaults.withCredentials = true; + + const response = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/workflow/connectSocial/${workflowId}?social=airtable`, + {}, ); if (!response.data.success) { @@ -179,6 +185,8 @@ export default function useSocial() { handleSlack, handleGoogleSheets, handleHubSpot, + handleNotion, + handleAirtable, getSocial, }; }