Skip to content

Commit

Permalink
refactor: add editable button
Browse files Browse the repository at this point in the history
  • Loading branch information
swgvenghy committed Sep 16, 2024
1 parent cead150 commit 62e432e
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 137 deletions.
29 changes: 21 additions & 8 deletions src/store/admin/check-question-answer-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,46 @@ export interface QuestionAnswerState {
interface CheckQuestionAnswerState {
questionData: QuestionAnswerState[];
updateQuestionData: (firstData: QuestionAnswerState[]) => void;
inputQuestionData: (data: QuestionAnswerState) => void;
updateCheck: (id: number, isChecked: boolean) => void;
updateQuestion: (id: number, content: string) => void;
updateIsChecked: (id: number) => void;
updateAnswer: (answerId: number, answerContent: string) => void;
deleteQuestion: (id: number) => void;
deleteQuestion: (id: number) => void; // 삭제 함수 추가
findQuestion: (id: number) => QuestionAnswerState | undefined;
}

const useCheckQuestionAnswerStore = create<CheckQuestionAnswerState>((set, get) => ({
questionData: [],

updateQuestionData: (firstData) => set({ questionData: firstData }),
inputQuestionData: (data) => set((state) => ({ questionData: [...state.questionData, data] })),
updateCheck: (id, isChecked) =>

updateQuestion: (id, content) =>
set((state) => ({
questionData: state.questionData.map((question) =>
question.id === id ? { ...question, content, isChecked: true } : question,
),
})),

updateIsChecked: (id) =>
set((state) => ({
questionData: state.questionData.map((question) => (question.id === id ? { ...question, isChecked } : question)),
questionData: state.questionData.map((question) =>
question.id === id ? { ...question, isChecked: true } : question,
),
})),

updateAnswer: (answerId, answerContent) =>
set((state) => ({
questionData: state.questionData.map((question) =>
question.answer.id === answerId
? { ...question, answer: { ...question.answer, content: answerContent } }
? { ...question, answer: { ...question.answer, content: answerContent }, isChecked: true }
: question,
),
})),

deleteQuestion: (id) =>
set((state) => ({
questionData: state.questionData.filter((question) => question.id !== id),
questionData: state.questionData.filter((question) => question.id !== id), // 삭제 로직
})),

findQuestion: (id) => get().questionData.find((question) => question.id === id),
}));

Expand Down
123 changes: 38 additions & 85 deletions src/ui/components/admin/modal/edit-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { Button, Modal } from 'antd';
import TextArea from 'antd/es/input/TextArea';
import React, { useEffect, useState } from 'react';
import { AdminEditAnswer } from '../../../../api/admin/question-manage/admin-edit-answer';
import { AdminCheckQuestionAnswer } from '../../../../api/admin/question-manage/admin-check-question-answer';
import { adminEditQuestion } from '../../../../api/admin/question-manage/admin-edit-question';
import useCheckQuestionAnswerStore from '../../../../store/admin/check-question-answer-store';
import { adminDeleteQuestion } from '../../../../api/admin/question-manage/admin-delete-question';

interface CustomModalProps {
open: boolean;
Expand All @@ -13,114 +12,68 @@ interface CustomModalProps {
}

const EditModal = ({ open, setOpen, questionId }: CustomModalProps) => {
const { findQuestion, updateCheck, updateAnswer, deleteQuestion } = useCheckQuestionAnswerStore();
const { findQuestion, updateQuestion, updateAnswer } = useCheckQuestionAnswerStore();
const question = findQuestion(questionId);

const [editStatus, setEditStatus] = useState(false);
const [loading, setLoading] = useState(false);
const [content, setContent] = useState('');
const [questionContent, setQuestionContent] = useState('');
const [answerContent, setAnswerContent] = useState('');

useEffect(() => {
if (question) {
setContent(question.answer.content);
setQuestionContent(question.content);
setAnswerContent(question.answer.content);
}
}, [question]);

const executeWithLoading = async (action: () => Promise<void>) => {
setLoading(true);
try {
await action();
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};

const handleEditSubmit = async () => {
if (question?.answer.id !== undefined) {
await executeWithLoading(async () => {
try {
await AdminEditAnswer(question.answer.id, content);
updateAnswer(question.answer.id, content);
if (!question.isChecked) {
await AdminCheckQuestionAnswer({ questionId });
updateCheck(questionId, true);
}
handleClose();
} catch (err) {
console.error(err);
throw err;
}
}).catch(() => setEditStatus(false));
}
};

const handleCheckToggle = async () => {
const newCheckStatus = !question?.isChecked;
if (question) {
await executeWithLoading(async () => {
await AdminCheckQuestionAnswer({ questionId });
updateCheck(questionId, newCheckStatus);
});
if (question?.id !== undefined && question?.answer.id !== undefined) {
setLoading(true);
try {
await adminEditQuestion(question.id, questionContent);
await AdminEditAnswer(question.answer.id, answerContent);
updateQuestion(question.id, questionContent);
updateAnswer(question.answer.id, answerContent);
setOpen(false);
} catch (error) {
console.error('Error editing question/answer:', error);
} finally {
setLoading(false);
}
}
};

const handleClose = () => {
setOpen(false);
setEditStatus(false);
};

const handleDelete = async () => {
if (question?.id !== undefined) {
await adminDeleteQuestion(question.id);
deleteQuestion(question.id);
handleClose();
}
};

const enableEditMode = () => {
setEditStatus(true);
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setContent(e.target.value);
};

return question ? (
<Modal
open={open}
title={`${question.content} - ${question.isChecked ? '질문 확인됨' : '질문 미확인'}`}
title="질문 및 답변 수정"
onCancel={handleClose}
footer={[
editStatus ? (
<Button key="submit" onClick={handleEditSubmit} loading={loading} type="primary">
편집완료
</Button>
) : (
<Button key="edit" onClick={enableEditMode} type="primary">
편집하기
</Button>
),
!question.isChecked ? (
<Button key="checked" onClick={handleCheckToggle} loading={loading} type="dashed">
질문-답변 확인 상태 변경
</Button>
) : (
<Button key="checked" onClick={handleCheckToggle} loading={loading} type="dashed" danger>
질문-답변 미확인 상태 변경
</Button>
),
<Button key="close" onClick={handleDelete} danger>
질문삭제하기
<Button key="submit" onClick={handleEditSubmit} loading={loading} type="dashed">
수정 완료
</Button>,
]}
>
{editStatus ? (
<TextArea rows={25} value={content} onChange={handleChange} />
) : (
<div>{question.answer.content}</div>
)}
<div>
<h3>질문 수정</h3>
<TextArea
rows={4}
value={questionContent}
onChange={(e) => setQuestionContent(e.target.value)}
placeholder="질문 내용을 수정하세요"
/>
<h3 className="mt-4">답변 수정</h3>
<TextArea
rows={4}
value={answerContent}
onChange={(e) => setAnswerContent(e.target.value)}
placeholder="답변 내용을 수정하세요"
/>
</div>
</Modal>
) : null;
};
Expand Down
117 changes: 73 additions & 44 deletions src/ui/pages/admin/question-check.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,14 @@
import { Divider, Select, Table, TableProps, Tag, AutoComplete, Input } from 'antd';
import React, { useEffect, useState } from 'react';
import { Divider, Select, Table, TableProps, Tag, AutoComplete, Input, Button, Popconfirm } from 'antd';
import React, { useEffect, useState, useMemo } from 'react';
import { adminQuestionCheck } from '../../../api/admin/question-manage/admin-question-check';
import EditModal from '../../components/admin/modal/edit-modal';
import useCheckQuestionAnswerStore, { QuestionAnswerState } from '../../../store/admin/check-question-answer-store';
import { searchAutoComplete } from '../../../api/search-auto-complete';
import { SearchById } from '../../../api/admin/question-manage/admin-search-by-id';

const columns: TableProps<QuestionAnswerState>['columns'] = [
{
title: '질문내용',
dataIndex: 'content',
key: 'content',
width: 500,
},
{
title: '질문횟수',
dataIndex: 'viewCount',
key: 'viewCount',
sorter: (a, b) => +b.viewCount - +a.viewCount,
},
{
title: '질문확인여부',
dataIndex: 'isChecked',
key: 'isChecked',
filters: [
{
text: '확인',
value: true,
},
{
text: '미확인',
value: false,
},
],
onFilter: (value, record) => record.isChecked === value,
render: (isChecked) => (isChecked ? <Tag color="green">확인</Tag> : <Tag color="red">미확인</Tag>),
},
];
import { adminDeleteQuestion } from '../../../api/admin/question-manage/admin-delete-question';

const QuestionCheck = () => {
const { questionData, updateQuestionData } = useCheckQuestionAnswerStore();
const { questionData, updateQuestionData, deleteQuestion } = useCheckQuestionAnswerStore();
const [type, setType] = useState('SUSI');
const [category, setCategory] = useState('');
const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -98,6 +67,74 @@ const QuestionCheck = () => {
}
};

const handleDelete = async (id: number) => {
try {
await adminDeleteQuestion(id);
deleteQuestion(id);
} catch (error) {
console.error('Error deleting question:', error);
}
};

const columns: TableProps<QuestionAnswerState>['columns'] = useMemo(
() => [
{
title: '질문내용',
dataIndex: 'content',
key: 'content',
},
{
title: '질문횟수',
dataIndex: 'viewCount',
key: 'viewCount',
width: 140,
sorter: (a, b) => +b.viewCount - +a.viewCount,
},
{
title: '질문확인여부',
dataIndex: 'isChecked',
width: 140,
key: 'isChecked',
filters: [
{
text: '확인',
value: true,
},
{
text: '미확인',
value: false,
},
],
onFilter: (value, record) => record.isChecked === value,
render: (isChecked) => (isChecked ? <Tag color="green">확인</Tag> : <Tag color="red">미확인</Tag>),
},
{
title: '편집',
key: 'edit',
width: 150,
render: (text, record) => <Button onClick={() => handleRowClick(record)}>편집하기</Button>,
},
{
title: '삭제',
key: 'action',
width: 150,
render: (text, record) => (
<Popconfirm
title="정말 삭제하시겠습니까?"
onConfirm={() => handleDelete(record.id)}
okText="예"
cancelText="아니오"
>
<Button type="primary" danger>
삭제
</Button>
</Popconfirm>
),
},
],
[handleDelete],
);

useEffect(() => {
const fetchData = async () => {
setLoading(true);
Expand Down Expand Up @@ -160,15 +197,7 @@ const QuestionCheck = () => {
/>
</div>
<div className="mx-8 my-3">
<Table
columns={columns}
dataSource={questionData}
loading={loading}
rowKey="id"
onRow={(record) => ({
onClick: () => handleRowClick(record),
})}
/>
<Table columns={columns} dataSource={questionData} loading={loading} rowKey="id" />
</div>

{selectedQuestion && <EditModal open={modalOpen} setOpen={setModalOpen} questionId={selectedQuestion.id} />}
Expand Down

0 comments on commit 62e432e

Please sign in to comment.