-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ADDED FORUM * added testing for faqForum * half baked * Frontend for forum
- Loading branch information
1 parent
e6519c7
commit 5a5744d
Showing
6 changed files
with
252 additions
and
1 deletion.
There are no files selected for viewing
80 changes: 80 additions & 0 deletions
80
scruter-nextjs/app/(routes)/(footerPages)/forum/components/NewQuestionForm.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
'use client'; | ||
|
||
import { createQuestion } from '@/actions/forum/Question'; | ||
import { Button } from '@/components/ui/button'; | ||
import { Label } from '@/components/ui/label'; | ||
import { Spinner } from '@/components/ui/spinner'; | ||
import { Textarea } from '@/components/ui/textarea'; | ||
import { useSession } from 'next-auth/react'; | ||
import { SyntheticEvent, useEffect, useState } from 'react'; | ||
|
||
const NewQuestionForm = () => { | ||
const [questionContent, setQuestionContent] = useState(''); | ||
const [submissionError, setSubmissionError] = useState(''); | ||
|
||
const [isMounted, setIsMounted] = useState(false); | ||
const [isAuthenticated, setIsAuthenticated] = useState(false); | ||
|
||
const session = useSession(); | ||
|
||
useEffect(() => { | ||
setIsMounted(true); | ||
if (!(session.status === 'loading')) { | ||
if (session.status === 'authenticated') { | ||
setIsAuthenticated(true); | ||
// console.log("hereeeeeeeeee"+isAuthenticated+session.status) | ||
} | ||
} | ||
}, [session.status]); | ||
|
||
if (!isMounted) { | ||
return <Spinner />; | ||
} | ||
|
||
const handleSubmit = async (e: SyntheticEvent) => { | ||
e.preventDefault(); | ||
try { | ||
const response = await createQuestion(questionContent); | ||
if (!response.success && response.error) { | ||
setSubmissionError(response.error); | ||
} else { | ||
setQuestionContent(''); | ||
setSubmissionError(''); | ||
} | ||
} catch (error) { | ||
setSubmissionError( | ||
'An error occurred while submitting your question. Please try again.' | ||
); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
{isAuthenticated ? ( | ||
<form onSubmit={handleSubmit} className="space-y-4"> | ||
<Label htmlFor="new-question" className="text-gray-700 font-medium"> | ||
Your Question | ||
</Label> | ||
<Textarea | ||
id="new-question" | ||
value={questionContent} | ||
onChange={e => setQuestionContent(e.target.value)} | ||
placeholder="Type your question here..." | ||
className="resize-none w-full rounded-md border-gray-300 focus:border-indigo-500" | ||
required | ||
/> | ||
{submissionError && <p className="text-red-600">{submissionError}</p>} | ||
<Button type="submit" className="w-full bg-green-500 text-white"> | ||
Submit Question | ||
</Button> | ||
</form> | ||
) : ( | ||
<p className="text-red-500 text-sm"> | ||
Please authenticate yourself to post a question. | ||
</p> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
export default NewQuestionForm; |
93 changes: 93 additions & 0 deletions
93
scruter-nextjs/app/(routes)/(footerPages)/forum/components/unAnsweredQuestions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"use client"; | ||
|
||
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Label } from "@/components/ui/label"; | ||
import { Textarea } from "@/components/ui/textarea"; | ||
import { Spinner } from "@/components/ui/spinner"; | ||
import { useEffect, useState } from "react"; | ||
import { useSession } from "next-auth/react"; | ||
import toast from "react-hot-toast"; // Assuming you're using React Hot Toast for notifications | ||
import { createAnswer } from "@/actions/forum/Answer"; // Import the server action | ||
|
||
interface UnansweredQuestionCardProps { | ||
question: { | ||
id: string; | ||
content: string; | ||
}; | ||
} | ||
|
||
const UnansweredQuestionCard: React.FC<UnansweredQuestionCardProps> = ({ question }) => { | ||
const [answer, setAnswer] = useState(""); | ||
const [isMounted, setIsMounted] = useState(false); | ||
const [isAuthenticated, setIsAuthenticated] = useState(false); | ||
const [isSubmitting, setIsSubmitting] = useState(false); | ||
|
||
const { status: sessionStatus } = useSession(); | ||
|
||
useEffect(() => { | ||
setIsMounted(true); | ||
if (sessionStatus === "authenticated") { | ||
setIsAuthenticated(true); | ||
} | ||
}, [sessionStatus]); | ||
|
||
if (!isMounted) { | ||
return <Spinner />; | ||
} | ||
|
||
const handleSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
setIsSubmitting(true); | ||
|
||
try { | ||
const response = await createAnswer(question.id, answer); | ||
|
||
if (response.success) { | ||
toast.success("Answer submitted successfully!"); | ||
setAnswer(""); // Clear the textarea on success | ||
} else { | ||
toast.error(response.error || "An error occurred while submitting your answer."); | ||
} | ||
} catch (error) { | ||
toast.error("An error occurred while submitting your answer. Please try again."); | ||
} finally { | ||
setIsSubmitting(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<Card key={question.id} className="shadow-lg"> | ||
<CardHeader> | ||
<CardTitle>{question.content}</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
{isAuthenticated ? ( | ||
<form onSubmit={handleSubmit}> | ||
<div className="space-y-4"> | ||
<Label htmlFor={`answer-${question.id}`} className="block text-sm font-medium text-gray-600"> | ||
Your Answer | ||
</Label> | ||
<Textarea | ||
id={`answer-${question.id}`} | ||
value={answer} | ||
onChange={(e) => setAnswer(e.target.value)} | ||
placeholder="Type your answer here..." | ||
className="resize-none w-full rounded-md border-gray-300 focus:border-indigo-500" | ||
required | ||
disabled={isSubmitting} | ||
/> | ||
</div> | ||
<Button type="submit" className="mt-4 w-full bg-blue-500 text-white" disabled={isSubmitting}> | ||
{isSubmitting ? "Submitting..." : "Submit Answer"} | ||
</Button> | ||
</form> | ||
) : ( | ||
<p className="text-red-500 text-sm">Please authenticate yourself to answer the question.</p> | ||
)} | ||
</CardContent> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default UnansweredQuestionCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
|
||
import { getAnsweredQuestions, getUnansweredQuestions, createQuestion } from "@/actions/forum/Question"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; | ||
import { Label } from "@/components/ui/label"; | ||
import { Textarea } from "@/components/ui/textarea"; | ||
import { SyntheticEvent, useState } from "react"; // Import useState for client-side form handling | ||
import NewQuestionForm from "./components/NewQuestionForm"; | ||
import UnansweredQuestionCard from "./components/unAnsweredQuestions"; | ||
|
||
const Forum = async () => { | ||
// Fetch unanswered and answered questions using server actions | ||
const unansweredResp = await getUnansweredQuestions(); | ||
const answeredResp = await getAnsweredQuestions(); | ||
|
||
return ( | ||
<div className="container mx-auto p-6 space-y-8"> | ||
{/* Page Title */} | ||
<h1 className="text-3xl font-bold text-center text-gray-800">Forum</h1> | ||
|
||
{/* Ask a New Question Section */} | ||
<section className="space-y-4"> | ||
<h2 className="text-2xl font-semibold text-gray-700">Ask a Question</h2> | ||
<NewQuestionForm /> | ||
</section> | ||
|
||
{/* Unanswered Questions Section */} | ||
<section className="space-y-6"> | ||
<h2 className="text-2xl font-semibold text-gray-700">Unanswered Questions</h2> | ||
|
||
{unansweredResp.success ? ( | ||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> | ||
{unansweredResp.data?.map((question) => ( | ||
<UnansweredQuestionCard | ||
key={question.id} | ||
question={question} | ||
/> | ||
))} | ||
</div> | ||
) : ( | ||
<p className="text-gray-600">{unansweredResp.error || "No unanswered questions available."}</p> | ||
)} | ||
</section> | ||
|
||
{/* Answered Questions Section */} | ||
<section className="space-y-6"> | ||
<h2 className="text-2xl font-semibold text-gray-700">Answered Questions</h2> | ||
|
||
{answeredResp.success ? ( | ||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> | ||
{answeredResp.data?.map((question) => ( | ||
<Card key={question.id} className="shadow-lg"> | ||
<CardHeader> | ||
<CardTitle>{question.content}</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
<div className="space-y-2"> | ||
<p className="text-sm font-medium text-gray-700">Answers:</p> | ||
{question.answers?.map((answer) => ( | ||
<div key={answer.id} className="p-3 bg-gray-100 rounded-md"> | ||
<p className="text-gray-800">{answer.content}</p> | ||
</div> | ||
))} | ||
</div> | ||
</CardContent> | ||
</Card> | ||
))} | ||
</div> | ||
) : ( | ||
<p className="text-gray-600">{answeredResp.error || "No answered questions available."}</p> | ||
)} | ||
</section> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Forum |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.