diff --git a/src/components/rating/Rating.tsx b/src/components/rating/Rating.tsx index b1bdb81..1b47819 100644 --- a/src/components/rating/Rating.tsx +++ b/src/components/rating/Rating.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef, useState } from "react"; import { ThumbDownIcon, ThumbUpIcon } from "@/chakra/custom-chakra-icons"; -import { SupaBaseDatabase } from "@/database/database"; +import { isSupabaseInitialized, addFeedback } from "@/database/database"; import { AnswerQuality, FeedbackPayload, Ratings } from "@/types"; import { Button, Flex, Text } from "@chakra-ui/react"; @@ -52,15 +52,13 @@ const Rating = ({ isResponseGenerated, feedbackId }: RatingProps) => { if (feedback.rating === Ratings.NEGATIVE && !feedback.answerQuality) { return; } - const { status, error } = await SupaBaseDatabase.getInstance().addFeedback({ - ...feedback, - feedbackId, - }); - if (status >= 200 && status < 300 && !error) { - setIsFeedbackSubmitted(true); - console.log("Feedback sent successfully"); + if (isSupabaseInitialized) { + await addFeedback(feedback, feedbackId); + } else { + console.error('Cannot submit rating because supabase is not initialized'); } + setIsFeedbackSubmitted(true); }; if (!isResponseGenerated) { diff --git a/src/database/database.ts b/src/database/database.ts index 891d31d..110b127 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -8,12 +8,23 @@ const SUPABASE_URL = publicRuntimeConfig.SUPABASE_URL; const SUPABASE_ANON_KEY = publicRuntimeConfig.SUPABASE_ANON_KEY; const DB_NAME = publicRuntimeConfig.DB_NAME; +export const isSupabaseInitialized = SUPABASE_URL !== undefined && SUPABASE_ANON_KEY !== undefined && SUPABASE_URL !== "" && SUPABASE_ANON_KEY !== ""; + // Initialize Supabase client -let supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY); +let supabase = null; + +if (SUPABASE_URL) { + supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY); +} else { + console.error('SUPABASE_URL is not defined in .env file'); +} // Example usage: Fetch all rows from a table named "tasks" export class SupaBaseDatabase { static getInstance() { + if (!supabase) { + throw new Error('Supabase has not been initialized because SUPABASE_URL is not defined'); + } return new SupaBaseDatabase(); } @@ -83,3 +94,56 @@ export class SupaBaseDatabase { } } } + +export const getCachedAnswer = async (question: string, author?: string) => { + question = question.toLowerCase(); + author = author?.toLocaleLowerCase(); + const answers = await SupaBaseDatabase.getInstance().getAnswerByQuestion( + question, + author + ); + + if (!answers || answers.length === 0) { + console.error("Error fetching answer: No answers found."); + return null; + } + + // Use JavaScript .find() method to get first element where answer is not an empty string + const nonEmptyAnswer = answers.find((item) => item.answer.trim() !== ""); + + if (!nonEmptyAnswer) { + console.error("Error fetching answer: No non-empty answers found."); + return null; + } + + // Return the nonEmptyAnswer directly as a string + return createReadableStream(nonEmptyAnswer.answer); +}; + +export const addDocumentToSupabase = async (payload: any) => { + await SupaBaseDatabase.getInstance().insertData(payload); +}; + +function createReadableStream(text: string) { + const encoder = new TextEncoder(); + const readable = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode(text)); + controller.close(); + }, + }); + return readable; +} + +export const addFeedback = async (feedback: FeedbackPayload, feedbackId: string) => { + const { status, error } = await SupaBaseDatabase.getInstance().addFeedback({ + ...feedback, + feedbackId, + }); + + if (status >= 200 && status < 300 && !error) { + console.log("Feedback sent successfully"); + return true; + } + return false; +}; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 39d845c..9fb48d3 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -13,7 +13,7 @@ import { isMobile } from "react-device-detect"; import MessageBox, { Message } from "@/components/message/message"; import { defaultErrorMessage } from "@/config/error-config"; import { v4 as uuidv4 } from "uuid"; -import { SupaBaseDatabase } from "@/database/database"; +import { isSupabaseInitialized, getCachedAnswer, addDocumentToSupabase } from "@/database/database"; import BackgroundHelper from "@/components/background/BackgroundHelper"; import Rating from "@/components/rating/Rating"; import { useRouter } from "next/router"; @@ -36,42 +36,6 @@ interface FeedbackStatus { [messageId: string]: "submitted" | undefined; } -function createReadableStream(text: string) { - const encoder = new TextEncoder(); - const readable = new ReadableStream({ - start(controller) { - controller.enqueue(encoder.encode(text)); - controller.close(); - }, - }); - return readable; -} - -const getCachedAnswer = async (question: string, author?: string) => { - question = question.toLowerCase(); - author = author?.toLocaleLowerCase(); - const answers = await SupaBaseDatabase.getInstance().getAnswerByQuestion( - question, - author - ); - - if (!answers || answers.length === 0) { - console.error("Error fetching answer: No answers found."); - return null; - } - - // Use JavaScript .find() method to get first element where answer is not an empty string - const nonEmptyAnswer = answers.find((item) => item.answer.trim() !== ""); - - if (!nonEmptyAnswer) { - console.error("Error fetching answer: No non-empty answers found."); - return null; - } - - // Return the nonEmptyAnswer directly as a string - return createReadableStream(nonEmptyAnswer.answer); -}; - function formatDate(date: Date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); // Months are 0-based, so we need to add 1 @@ -260,16 +224,24 @@ export default function Home() { const errMessage = "Something went wrong. Try again later"; try { - const cachedAnswer = await getCachedAnswer(query, author); - let data = null; - if (!cachedAnswer) { + let data; + if (isSupabaseInitialized) { + const cachedAnswer = await getCachedAnswer(query, author); + if (!cachedAnswer) { + const response: Response = await fetchResult(query, author); + if (!response.ok) { + throw new Error(errMessage); + } + data = response.body; + } else { + data = cachedAnswer; + } + } else { const response: Response = await fetchResult(query, author); if (!response.ok) { throw new Error(errMessage); } data = response.body; - } else { - data = cachedAnswer; } const reader = data?.getReader(); @@ -308,7 +280,7 @@ export default function Home() { const dateObject = new Date(dateTimeString); const formattedDateTime = formatDate(dateObject); - if (!errorMessages.includes(answer)) { + if (isSupabaseInitialized && !errorMessages.includes(answer)) { let payload = { uniqueId: uniqueIDD, question: question, @@ -319,8 +291,8 @@ export default function Home() { updatedAt: null, releasedAt: formattedDateTime, }; - await SupaBaseDatabase.getInstance().insertData(payload); - } else { + addDocumentToSupabase(payload); + } else if (isSupabaseInitialized) { // If answer contains error messages, only add the question to DB let payload = { uniqueId: uniqueIDD, @@ -332,7 +304,7 @@ export default function Home() { updatedAt: null, releasedAt: formattedDateTime, }; - await SupaBaseDatabase.getInstance().insertData(payload); + addDocumentToSupabase(payload); } await updateMessages(finalAnswerWithLinks, uuid); } catch (err: any) {