Add approve and answer functionality to Questions page
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { type FC, useState } from 'react'
|
||||
import { useGetProductQuestions } from './hooks/useProductData'
|
||||
import { useGetProductQuestions, useApproveProductQuestion, useAnswerProductQuestion } from './hooks/useProductData'
|
||||
import { type ProductQuestionType } from './types/Types'
|
||||
import PageLoading from '../../components/PageLoading'
|
||||
import Error from '../../components/Error'
|
||||
@@ -14,7 +14,9 @@ const Questions: FC = () => {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [selectedQuestion, setSelectedQuestion] = useState<ProductQuestionType | null>(null);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const { data, isLoading, error } = useGetProductQuestions(currentPage);
|
||||
const { data, isLoading, error, refetch } = useGetProductQuestions(currentPage);
|
||||
const approveMutation = useApproveProductQuestion();
|
||||
const answerMutation = useAnswerProductQuestion();
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -63,6 +65,26 @@ const Questions: FC = () => {
|
||||
setSelectedQuestion(null);
|
||||
};
|
||||
|
||||
const handleApproveQuestion = async (questionId: string) => {
|
||||
try {
|
||||
await approveMutation.mutateAsync(questionId);
|
||||
await refetch();
|
||||
handleCloseModal();
|
||||
} catch (error) {
|
||||
console.error('خطا در تایید سوال:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAnswerQuestion = async (questionId: string, answer: string) => {
|
||||
try {
|
||||
await answerMutation.mutateAsync({ id: questionId, answer });
|
||||
await refetch();
|
||||
handleCloseModal();
|
||||
} catch (error) {
|
||||
console.error('خطا در پاسخ به سوال:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageTitle />
|
||||
@@ -152,6 +174,10 @@ const Questions: FC = () => {
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
question={selectedQuestion}
|
||||
onApprove={handleApproveQuestion}
|
||||
onAnswer={handleAnswerQuestion}
|
||||
isApproving={approveMutation.isPending}
|
||||
isAnswering={answerMutation.isPending}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { type FC } from 'react'
|
||||
import { type FC, useState } from 'react'
|
||||
import { type ProductQuestionType } from '../types/Types'
|
||||
import DefaulModal from '../../../components/DefaulModal'
|
||||
import StatusWithText from '../../../components/StatusWithText'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { Textarea } from '@/components/Textarea'
|
||||
import { TickCircle, Send } from 'iconsax-react'
|
||||
|
||||
interface QuestionModalProps {
|
||||
isOpen: boolean
|
||||
onClose: () => void
|
||||
question: ProductQuestionType | null
|
||||
onApprove?: (questionId: string) => void
|
||||
onAnswer?: (questionId: string, answer: string) => void
|
||||
isApproving?: boolean
|
||||
isAnswering?: boolean
|
||||
}
|
||||
|
||||
const QuestionModal: FC<QuestionModalProps> = ({
|
||||
@@ -18,8 +21,11 @@ const QuestionModal: FC<QuestionModalProps> = ({
|
||||
onClose,
|
||||
question,
|
||||
onApprove,
|
||||
isApproving = false
|
||||
onAnswer,
|
||||
isApproving = false,
|
||||
isAnswering = false
|
||||
}) => {
|
||||
const [answer, setAnswer] = useState('');
|
||||
const getStatusVariant = (status: string) => {
|
||||
switch (status) {
|
||||
case 'accepted': return 'success';
|
||||
@@ -44,6 +50,13 @@ const QuestionModal: FC<QuestionModalProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const handleAnswer = () => {
|
||||
if (question && onAnswer && answer.trim()) {
|
||||
onAnswer(question._id, answer.trim());
|
||||
setAnswer('');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DefaulModal
|
||||
open={isOpen}
|
||||
@@ -125,6 +138,29 @@ const QuestionModal: FC<QuestionModalProps> = ({
|
||||
تاریخ ارسال: {question.createdAt}
|
||||
</div>
|
||||
|
||||
{/* بخش پاسخ دادن */}
|
||||
{onAnswer && (
|
||||
<div className="bg-blue-50 p-4 rounded-lg border-t mt-4">
|
||||
<h4 className="font-medium text-blue-900 mb-3">پاسخ به سوال:</h4>
|
||||
<Textarea
|
||||
value={answer}
|
||||
onChange={(e) => setAnswer(e.target.value)}
|
||||
placeholder="پاسخ خود را اینجا تایپ کنید..."
|
||||
className="w-full min-h-[100px] mb-3"
|
||||
/>
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
onClick={handleAnswer}
|
||||
disabled={isAnswering || !answer.trim()}
|
||||
className="bg-blue-600 hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
<Send color="#fff" size={16} className="ml-2" />
|
||||
{isAnswering ? 'در حال ارسال...' : 'ارسال پاسخ'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* دکمه تایید */}
|
||||
{question.status !== 'accepted' && onApprove && (
|
||||
<div className="flex justify-end pt-4 border-t">
|
||||
|
||||
@@ -123,4 +123,16 @@ export const useGetProductQuestions = (page: number = 1, limit: number = 10) =>
|
||||
queryKey: ['product-questions', page, limit],
|
||||
queryFn: () => api.getProductQuestions(page, limit),
|
||||
});
|
||||
};
|
||||
|
||||
export const useApproveProductQuestion = () => {
|
||||
return useMutation({
|
||||
mutationFn: api.approveProductQuestion,
|
||||
});
|
||||
};
|
||||
|
||||
export const useAnswerProductQuestion = () => {
|
||||
return useMutation({
|
||||
mutationFn: api.answerProductQuestion,
|
||||
});
|
||||
};
|
||||
@@ -117,4 +117,14 @@ export const getProductQuestions = async (page: number = 1, limit: number = 10):
|
||||
const params: Record<string, string | number> = { page, limit };
|
||||
const { data } = await axios.get(`admin/products/questions`, { params });
|
||||
return data;
|
||||
};
|
||||
|
||||
export const approveProductQuestion = async (id: string) => {
|
||||
const { data } = await axios.post(`/admin/products/questions/${id}/approve`);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const answerProductQuestion = async (params: {id: string, answer: string}) => {
|
||||
const { data } = await axios.post(`/product/questions/${params.id}/answer`, { content:params.answer });
|
||||
return data;
|
||||
};
|
||||
Reference in New Issue
Block a user