From 2b84e07048fdd42f299d739204d56775071e6f31 Mon Sep 17 00:00:00 2001 From: JohanDelao Date: Sat, 6 Jan 2024 18:03:16 -0500 Subject: [PATCH 1/2] fixed delay of loading in submitting --- .../src/app/components/loadingSubmission.tsx | 16 +++++ client/src/app/start/interview/page.tsx | 12 +++- client/src/app/styles/loading.css | 2 + server/yarn.lock | 59 +++++++------------ 4 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 client/src/app/components/loadingSubmission.tsx diff --git a/client/src/app/components/loadingSubmission.tsx b/client/src/app/components/loadingSubmission.tsx new file mode 100644 index 0000000..07676ec --- /dev/null +++ b/client/src/app/components/loadingSubmission.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { Spin } from 'antd'; +import { LoadingOutlined } from '@ant-design/icons'; + +export default function LoadingSubmission() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ } + size="large" + /> +

This may take several minutes, hold tight!

+
+ ); +} \ No newline at end of file diff --git a/client/src/app/start/interview/page.tsx b/client/src/app/start/interview/page.tsx index 4e540af..04c8eb9 100644 --- a/client/src/app/start/interview/page.tsx +++ b/client/src/app/start/interview/page.tsx @@ -7,11 +7,15 @@ import Card from 'antd/es/card/Card'; import { AudioOutlined, AudioMutedOutlined } from '@ant-design/icons'; import { Button, Progress, Modal } from 'antd'; import { ReactMic } from 'react-mic'; +import LoadingSubmission from '../../components/loadingSubmission'; import axios from 'axios'; export default function Interview() { const params = useSearchParams(); const router = useRouter(); + + const [loading, setLoading] = useState(false); + const profession = getProfessionType(params.get('profession')); const numQs = parseInt( params.get('numberQs') ? String(params.get('numberQs')) : '0', @@ -60,6 +64,12 @@ export default function Interview() { const formData = new FormData(); let currIdx = blobs.length - 1; + + // means this is the last question, for good UI we want to execute the loading to hide the delay of this response evaluation and saving to mongodb + if(blobs.length === numQs){ + setLoading(true); + } + formData.append('question', questions[currIdx] as string); formData.append('profession', profession as string); formData.append('audio', blobs[currIdx]); @@ -191,7 +201,7 @@ export default function Interview() { restartQuestion(); }; - return ( + return loading ? : (
diff --git a/client/src/app/styles/loading.css b/client/src/app/styles/loading.css index f0cabe2..a113966 100644 --- a/client/src/app/styles/loading.css +++ b/client/src/app/styles/loading.css @@ -3,4 +3,6 @@ justify-content: center; align-items: center; min-height: 100vh; + flex-direction: column; + gap: 1rem; } \ No newline at end of file diff --git a/server/yarn.lock b/server/yarn.lock index 78e3370..760d1f8 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -464,13 +464,6 @@ crypt@0.0.2: resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -485,12 +478,19 @@ debug@4.x: dependencies: ms "2.1.2" +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~2.0.0, depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -735,7 +735,7 @@ ignore-by-default@^1.0.1: resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -inherits@^2.0.3, inherits@~2.0.3, inherits@2.0.4: +inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -926,22 +926,17 @@ mquery@5.0.0: dependencies: debug "4.x" -ms@^2.0.0, ms@2.0.0: +ms@2.0.0, ms@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -1019,13 +1014,6 @@ object-inspect@^1.9.0: resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -1033,6 +1021,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" @@ -1190,17 +1185,7 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -safe-buffer@~5.1.0: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.1.2: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -1389,7 +1374,7 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^5.2.2, typescript@>=2.7: +typescript@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== @@ -1411,7 +1396,7 @@ undefsafe@^2.0.5: resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -1421,7 +1406,7 @@ util-deprecate@~1.0.1: resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utils-merge@^1.0.1, utils-merge@1.0.1, utils-merge@1.x.x: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== From 68cb37a40c83bbf917be793f1801677c358c82db Mon Sep 17 00:00:00 2001 From: JohanDelao Date: Sat, 3 Feb 2024 20:07:40 -0500 Subject: [PATCH 2/2] feat: added history + feedback functionality --- client/public/images/coverImage.png | Bin 0 -> 54240 bytes client/src/app/interfaces.ts | 12 ++ client/src/app/start/feedback/page.tsx | 78 +++++++++++- client/src/app/start/history/page.tsx | 150 ++++++++++++++++++++++-- client/src/app/start/interview/page.tsx | 9 +- client/src/app/start/layout.tsx | 2 +- server/routes/mongo.ts | 22 +++- server/utils/getAllInterviews.ts | 21 ++++ server/utils/getLatestInterview.ts | 25 ++-- 9 files changed, 286 insertions(+), 33 deletions(-) create mode 100644 client/public/images/coverImage.png create mode 100644 server/utils/getAllInterviews.ts diff --git a/client/public/images/coverImage.png b/client/public/images/coverImage.png new file mode 100644 index 0000000000000000000000000000000000000000..edcd2f7dbe5b3997738a38172360768ead6f1f69 GIT binary patch literal 54240 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–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 IO6KAJ0}YjYumAu6 literal 0 HcmV?d00001 diff --git a/client/src/app/interfaces.ts b/client/src/app/interfaces.ts index f5e83be..db7aba0 100644 --- a/client/src/app/interfaces.ts +++ b/client/src/app/interfaces.ts @@ -5,6 +5,18 @@ export interface User { _id: string; } +export interface Feedback { + answer: string; + created_at: string; + explanation: string; + feedback: string; + interview_id: string; + question: string; + score: number; + __v: number; + _id: string; +} + export enum ProfessionType { ALL = 'all', SOFTWARE_ENGINEER = 'Software Engineer', diff --git a/client/src/app/start/feedback/page.tsx b/client/src/app/start/feedback/page.tsx index d81771c..2193b42 100644 --- a/client/src/app/start/feedback/page.tsx +++ b/client/src/app/start/feedback/page.tsx @@ -1,12 +1,80 @@ 'use client'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { Feedback } from '../../interfaces'; +import LoadingSubmission from '../../components/loadingSubmission'; +import { Card, Tooltip } from 'antd'; +import { useSearchParams } from 'next/navigation' +import { InfoCircleOutlined } from '@ant-design/icons'; + +function FeedbackCard( props: Feedback ) { + const { answer, explanation, feedback, question, score } = props; -export default function Feedback() { return ( -
-
+ +
+
+

{question}

+
+
+
+

"{answer}"

+
+
+
+
+

Feedback:

+

{feedback}

+
+
+

Score:

+

{score}

+
+
+
+
+
+
+ ) +} + +export default function FeedbackPage() { + const [feedback, setFeedback] = useState(null); + const [loading, setLoading] = useState(true); + + const searchParams = useSearchParams(); + const interviewID = searchParams.get('id'); + + useEffect(() => { + const getLatestInterview = async () => { + try { + const resp = await axios.get( + `http://localhost:4000/mongo/get-interview${interviewID ? `?interviewID=${interviewID}` : ''}`, + { + withCredentials: true, + }, + ); + setFeedback(resp.data); + } catch (error) { + console.log(error) + } + } + setLoading(true); + getLatestInterview().then(() => setTimeout(() => setLoading(false), 500)); + }, []) + + return loading ? : feedback ? ( +
+

Feedback

+
+ {feedback.map((feedback) => { + return ( + + ) + })} +
- ); + ) : <> No Feedback ; } diff --git a/client/src/app/start/history/page.tsx b/client/src/app/start/history/page.tsx index 119cb98..939eaa5 100644 --- a/client/src/app/start/history/page.tsx +++ b/client/src/app/start/history/page.tsx @@ -1,19 +1,151 @@ 'use client'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; +import { + CaretDownOutlined, + CaretUpOutlined, + LoadingOutlined, +} from '@ant-design/icons'; +import { Spin } from 'antd'; +import { useRouter } from 'next/navigation'; export default function History() { - const [previousInterviews, setPreviousInterviews] = useState([]); + const [previousInterviews, setPreviousInterviews] = useState([]); + const [loading, setLoading] = useState(true); + + const router = useRouter(); + + function getAverageScore(feedbacks: any) { + const length = feedbacks.length; + const totalScore = feedbacks.reduce( + (accumulator: number, feedback: any) => accumulator + feedback.score, + 0, + ); + return Math.floor(totalScore / length); + } + + function extractDateFromTimestamp(timestamp: any) { + const dateObject = new Date(timestamp); + const year = dateObject.getFullYear(); + const month = String(dateObject.getMonth() + 1).padStart(2, '0'); // Months are zero-indexed + const day = String(dateObject.getDate()).padStart(2, '0'); + + return `${month}-${day}-${year}`; + } + + useEffect(() => { + const getAllUserInterviews = async () => { + try { + const resp = await axios.get( + 'http://localhost:4000/mongo/get-all-interviews', + { + withCredentials: true, + }, + ); + setPreviousInterviews(resp.data); + } catch (error) { + console.log('error: ' + error); + } + }; + getAllUserInterviews().then(() => setTimeout(() => setLoading(false), 500)); + }, []); return ( -
-
+
+

History

-
- {previousInterviews.length === 0 ?

You have no history of interviews, schedule one today!

: previousInterviews.map((interview) => { - return
{interview}
- })} -
+ {!loading ? ( +
+ {previousInterviews.length === 0 ? ( +

You have no history of interviews, schedule one today!

+ ) : ( +
+ + + + + + + + + + + + {/* TO DO: fix this type, make interface */} + {previousInterviews + .reverse() + .map((previousInterview: any) => { + const { interview, feedback } = previousInterview; + const score = getAverageScore(feedback); + + if (feedback.length <= 0) { + return; + } else { + return ( + { + router.push(`/start/feedback?id=${interview._id}`); + }} + > + + + + + + + ); + } + })} + +
+ Position + +

Duration

+
+ + +
+
+ Questions + + Score + + Date +
+ Software Engineer + + 00:30 + + {feedback.length} + 90 + ? 'text-[#389e0d]' + : score > 75 + ? 'text-[#73d13d]' + : score > 50 + ? 'text-[#ffa940]' + : 'text-[#f5222d]' + }`} + > + {getAverageScore(feedback)} + + {extractDateFromTimestamp(interview.created_at)} +
+
+ )} +
+ ) : ( +
+ } + size="large" + /> +
+ )}
); } diff --git a/client/src/app/start/interview/page.tsx b/client/src/app/start/interview/page.tsx index d15d474..54aa123 100644 --- a/client/src/app/start/interview/page.tsx +++ b/client/src/app/start/interview/page.tsx @@ -1,8 +1,8 @@ 'use client'; import React, { useEffect, useState } from 'react'; -import GetQuestions from '@/app/utils/get-questions'; +import GetQuestions from '../../utils/get-questions'; import { useRouter, useSearchParams } from 'next/navigation'; -import getProfessionType from '@/app/utils/get-profession-type'; +import getProfessionType from '../../utils/get-profession-type'; import Card from 'antd/es/card/Card'; import { AudioOutlined, AudioMutedOutlined } from '@ant-design/icons'; import { Button, Progress, Modal } from 'antd'; @@ -53,7 +53,6 @@ export default function Interview() { withCredentials: true, }, ); - console.log('Success', evaluations, resp); router.push('/start/feedback'); }; if (evaluations.length == numQs) saveToMongo(); @@ -128,10 +127,6 @@ export default function Interview() { const [muted, setMuted] = useState(false); - function handleData(recordedBlob: any) { - console.log('chunk of real-time data is: ', recordedBlob); - } - useEffect(() => { const questions = GetQuestions(profession ? profession : undefined, numQs); setQuestions(questions); diff --git a/client/src/app/start/layout.tsx b/client/src/app/start/layout.tsx index 96a7df7..60bc7ee 100644 --- a/client/src/app/start/layout.tsx +++ b/client/src/app/start/layout.tsx @@ -165,7 +165,7 @@ export default function RegularLayout({ style={{ background: 'white' }} >
-
+
}>{children}
diff --git a/server/routes/mongo.ts b/server/routes/mongo.ts index 90cf0c6..f74e9a7 100644 --- a/server/routes/mongo.ts +++ b/server/routes/mongo.ts @@ -5,6 +5,7 @@ import { Schema } from 'mongoose'; //utils import { saveToMongo } from '../utils/saveToMongo'; import { getLatestInterview } from '../utils/getLatestInterview'; +import { getAllInterviews } from '../utils/getAllInterviews'; //configs const router = Router(); @@ -23,9 +24,26 @@ router.post('/save-interview', async (req, res) => { router.get('/get-interview', async (req, res) => { const userId = (req.user as { _id: Schema.Types.ObjectId })._id; + const interviewID = req.query.interviewID as string | null; + + try { + if (!interviewID) { + const interview = await getLatestInterview(userId, null); + res.status(200).send(interview); + } else { + const interview = await getLatestInterview(userId, interviewID); + res.status(200).send(interview); + } + } catch (err) { + res.status(400).send({ error: `❌ Mongo error: ${err}` }); + } +}); + +router.get('/get-all-interviews', async (req, res) => { + const userId = (req.user as {_id: Schema.Types.ObjectId })._id; try { - const interview = await getLatestInterview(userId); - res.status(200).send(interview); + const interviews = await getAllInterviews(userId); + res.status(200).send(interviews); } catch (err) { res.status(400).send({ error: `❌ Mongo error: ${err}` }); } diff --git a/server/utils/getAllInterviews.ts b/server/utils/getAllInterviews.ts new file mode 100644 index 0000000..b7c22eb --- /dev/null +++ b/server/utils/getAllInterviews.ts @@ -0,0 +1,21 @@ +import interviewModel from '../Models/interviewModel'; +import qa_feedbackModel from '../Models/qa_feedbackModel'; + +export async function getAllInterviews(userId) { + const interviews = await interviewModel + .find({ user_id: userId }); + + // This means that map would return an array of promises of the results we want. + const feedback = interviews.map(async (interview) => { + const feedbacks = await qa_feedbackModel.find({ + interview_id: interview._id, + }); + return { + interview: interview, + feedback: feedbacks + } + }) + + // We can then use Promise.all to get the result when all the promises return. + return Promise.all(feedback); +} \ No newline at end of file diff --git a/server/utils/getLatestInterview.ts b/server/utils/getLatestInterview.ts index 009a5ea..820b083 100644 --- a/server/utils/getLatestInterview.ts +++ b/server/utils/getLatestInterview.ts @@ -1,14 +1,21 @@ -import mongoose from 'mongoose'; import interviewModel from '../Models/interviewModel'; import qa_feedbackModel from '../Models/qa_feedbackModel'; -export async function getLatestInterview(userId) { - const interview = await interviewModel - .findOne({ user_id: userId }) - .sort({ _id: -1 }); +export async function getLatestInterview(userId, interviewID: string | null) { + if(interviewID !== null){ + const interview = await interviewModel.findOne({user_id: userId, _id: interviewID}); + const feedbacks = await qa_feedbackModel.find({ + interview_id: interview._id, + }) + return feedbacks; + } else { + const interview = await interviewModel + .findOne({ user_id: userId }) + .sort({ _id: -1 }); - const feedbacks = await qa_feedbackModel.find({ - interview_id: interview._id, - }); - return feedbacks; + const feedbacks = await qa_feedbackModel.find({ + interview_id: interview._id, + }); + return feedbacks; + } }