Skip to content

Commit

Permalink
Merge pull request #54 from Soongmile/feat/#35_questionRead
Browse files Browse the repository at this point in the history
[#35] 게시물 조회 기능 API 연결
  • Loading branch information
seocylucky authored Oct 3, 2023
2 parents e71c58b + 011b174 commit 4c2e797
Show file tree
Hide file tree
Showing 20 changed files with 344 additions and 101 deletions.
9 changes: 9 additions & 0 deletions apis/getQuestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { GetQuestionResponse } from '@/types/question.type';
import client from './client';

const getQuestion = async (id: number): Promise<GetQuestionResponse> => {
const response = await client.get(`/user/question/${id}`);
return response.data;
};

export default getQuestion;
26 changes: 26 additions & 0 deletions apis/postAnswer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { AnswerWriteRequest, PostAnswerWriteResponse } from '@/types/answer.type';
import client from './client';

const postAnswer = async ({
questionId,
fileIds,
content,
}: AnswerWriteRequest): Promise<PostAnswerWriteResponse> => {
const response = await client.post(
'/user/answer',
{
questionId,
fileIds,
content,
},
{
headers: {
Authorization:
'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJha211QGdtYWlsLmNvbSIsInJvbGVzIjpbXSwiaWF0IjoxNjk1OTgyNTI1LCJleHAiOjE2OTYwNjg5MjV9.N5UWZD4xvULjHk7EaKblTM7kJwEdZrQ3cfII1jZMuAE',
},
},
);
return response.data;
};

export default postAnswer;
4 changes: 2 additions & 2 deletions apis/postQuestionWrite.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PostQuestionWriteResponse, QuestionWriteRequest } from '@/types/questionWrite.type';
import { PostQuestionWriteResponse, QuestionWriteRequest } from '@/types/question.type';
import client from './client';

const postQuestionWrite = async ({
Expand All @@ -20,7 +20,7 @@ const postQuestionWrite = async ({
{
headers: {
Authorization:
'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJha211QGdtYWlsLmNvbSIsInJvbGVzIjpbIlJPTEVfVVNFUiJdLCJpYXQiOjE2OTU2MjY5NzAsImV4cCI6MTY5NTcxMzM3MH0.Qp-tus5vuO7r1wTsIQJAp_T80zQePo96y_LLH7w89OU',
'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJha211QGdtYWlsLmNvbSIsInJvbGVzIjpbXSwiaWF0IjoxNjk1OTgyNTI1LCJleHAiOjE2OTYwNjg5MjV9.N5UWZD4xvULjHk7EaKblTM7kJwEdZrQ3cfII1jZMuAE',
},
},
);
Expand Down
2 changes: 1 addition & 1 deletion components/reusable/MarkDown/MarkdownEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const MarkdownEditor = ({ onChange }: MarkdownEditorProps) => {
<Editor
ref={editorRef}
onChange={() => onChange(editorRef)}
// initialValue="hello react editor world!"
initialValue=""
previewStyle="tab"
height="600px"
initialEditType="markdown"
Expand Down
8 changes: 6 additions & 2 deletions components/reusable/MarkDown/MarkdownViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import '@toast-ui/editor/dist/toastui-editor.css';
import { Viewer } from '@toast-ui/react-editor';

const MarkdownViewer = () => {
return <Viewer initialValue="#hello react editor world!" el="dkdkd" />;
interface MarkdownViewerProps {
content?: string;
}

const MarkdownViewer = ({ content }: MarkdownViewerProps) => {
return <Viewer initialValue={content} />;
};

export default MarkdownViewer;
9 changes: 9 additions & 0 deletions hooks/useGetQuestionRead.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import getQuestion from '@/apis/getQuestion';
import { GetQuestionResponse } from '@/types/question.type';
import { useQuery } from 'react-query';

const useGetQuestionRead = (id: number) => {
return useQuery<GetQuestionResponse>(['getQuestion', id], () => getQuestion(id));
};

export default useGetQuestionRead;
22 changes: 22 additions & 0 deletions hooks/usePostAnswer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import postAnswer from '@/apis/postAnswer';
import { queryClient } from '@/pages/_app';
import { AxiosError } from 'axios';
import { useRouter } from 'next/router';
import { useMutation } from 'react-query';

const usePostAnswer = (pId: number) => {
const router = useRouter();
return useMutation(postAnswer, {
onSuccess: () => {
queryClient.invalidateQueries(['getQuestion']);
router.push(`/questionRead/${pId}`);
},
onError: (error) => {
const Error = error as AxiosError;

console.log(Error);
},
});
};

export default usePostAnswer;
2 changes: 1 addition & 1 deletion hooks/useQuestionWrite.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldType, QuestionWriteRequest } from '@/types/questionWrite.type';
import { FieldType, QuestionWriteRequest } from '@/types/question.type';
import { RefObject, useState } from 'react';
import { Editor } from '@toast-ui/react-editor';

Expand Down
3 changes: 2 additions & 1 deletion pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};

export const queryClient = new QueryClient();

const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => page);
const queryClient = new QueryClient();

return (
<QueryClientProvider client={queryClient}>
Expand Down
15 changes: 9 additions & 6 deletions pages/questionRead/[pid].tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import theme from '@/styles/theme';
// import { useRouter } from 'next/router';
import styled from 'styled-components';
import Spacing from '@/components/reusable/Spacing';
import { useRouter } from 'next/router';
import useGetQuestionRead from '@/hooks/useGetQuestionRead';
import Search from '../../components/reusable/Search';
import Question from './atoms/Question';
import Answer from './atoms/Answer';
import MyAnswer from './atoms/MyAnswer';

const QuestionRead = () => {
// const router = useRouter();
// const { pid } = router.query;
const router = useRouter();
const { pid } = router.query;

const { data } = useGetQuestionRead(Number(pid) as number);

return (
<Container>
<Spacing direction="vertical" size={64} />
<Search />
<Spacing direction="vertical" size={64} />
<Question />
<Answer />
<MyAnswer />
<Question data={data} />
<Answer answers={data?.answerList} />
<MyAnswer pId={Number(pid) as number} />
</Container>
);
};
Expand Down
18 changes: 12 additions & 6 deletions pages/questionRead/atoms/Answer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import theme from '@/styles/theme';
import styled from 'styled-components';
import Spacing from '@/components/reusable/Spacing';
import { AnswerType } from '@/types/question.type';
import AnswerBox from './AnswerBox';

const Answer = () => {
const AnswerBoxes = ['경영 마스터', '박숭실'];

const Answer = ({ answers }: { answers?: AnswerType[] }) => {
return (
<AnswerContainer>
{AnswerBoxes.map((item, idx) => (
{answers?.map((item, idx) => (
<>
<AnswerBox userName={item} />
{idx < AnswerBoxes.length - 1 && <Spacing size={48} direction="vertical" />}
{/* userName 수정 예정 */}
<AnswerBox
key={item.id}
userName="userName"
content={item.content}
postTime={item.postTime}
likes={item.likes}
/>
{idx < answers.length - 1 && <Spacing size={48} direction="vertical" />}
</>
))}
</AnswerContainer>
Expand Down
33 changes: 12 additions & 21 deletions pages/questionRead/atoms/AnswerBox.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import Spacing from '@/components/reusable/Spacing';
import theme from '@/styles/theme';
import dynamic from 'next/dynamic';
import dateConvertor from '@/utils/dateConverter';
import styled from 'styled-components';

interface AnswerBoxProps {
// 추후 데이터 넘어오는 방식에 따라서 변경 예정
userName: string;
content: string;
postTime: string;
likes: number;
}

const AnswerBox = ({ userName }: AnswerBoxProps) => {
const Viewer = dynamic(() => import('../../../components/reusable/MarkDown/MarkdownViewer'), {
ssr: false,
});

const AnswerBox = ({ userName, content, postTime }: AnswerBoxProps) => {
return (
<StyledAnswerBox>
<TitleWrap>
Expand All @@ -19,28 +28,10 @@ const AnswerBox = ({ userName }: AnswerBoxProps) => {
</TitleWrap>
<Spacing size={24} direction="vertical" />
<AnswerContent>
경영학을 심도깊게 배우고자 하는 경우, 다음과 같은 인강 사이트와 공부 방법, 그리고 추천
도서를 고려해볼 수 있습니다. <br />
<br />
인강 사이트: <br />
1. Coursera (https://www.coursera.org/): Coursera는 유명 대학의 경영학 강의를 비롯한 다양한
온라인 강의를 제공합니다. 경영학에 관련된 강좌들을 찾아보고, 강의 퀄리티와 교수진을 확인하여
선택할 수 있습니다. <br /> 2. edX (https://www.edx.org/): edX도 Coursera와 마찬가지로
세계적인 대학들의 경영학 관련 강의를 제공합니다. 고품질의 강의와 다양한 주제를 제공하므로
참고해보세요. <br /> 3. Harvard Business School Online (https://online.hbs.edu/): 하버드
비즈니스 스쿨에서 운영하는 온라인 강의 플랫폼으로, 다양한 경영 관련 강의를 제공합니다.
전문적이고 광범위한 주제를 다루므로 심도깊게 학습할 수 있습니다. <br />
<br />
공부 방법: <br /> 1. 체계적인 계획 수립: 경영학의 다양한 분야를 다루기 위해 체계적인 학습
계획을 수립해야 합니다. 주제를 구분하고 순서를 정하여 조금씩 꾸준히 학습하도록 계획해보세요.
<br />
2. 참고 자료 활용: 강의 외에도 경영학에 대한 참고 자료들을 활용하세요. 논문, 서적, 학술지
등을 통해 심층적인 이해를 도모할 수 있습니다. <br />
3. 실전 적용: 이론을 학습한 후, 실제 비즈니스 상황에 적용해보세요. 케이스 스터디, 프로젝트,
시뮬레이션 등을 통해 경영 이론을 실전에 적용하며 실력을 향상시킬 수 있습니다.
<Viewer content={content} />
</AnswerContent>
<Spacing size={24} direction="vertical" />
<Date>07/07</Date>
<Date>{dateConvertor(postTime)}</Date>
</StyledAnswerBox>
);
};
Expand Down
32 changes: 29 additions & 3 deletions pages/questionRead/atoms/MyAnswer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import SquareBtn from '@/components/reusable/Buttons/SquareBtn';
import MarkdownEditorSkeleton from '@/components/reusable/MarkDown/MarkdownEditorSkeleton';
import Spacing from '@/components/reusable/Spacing';
import usePostAnswer from '@/hooks/usePostAnswer';
import theme from '@/styles/theme';
import { Editor } from '@toast-ui/react-editor';
import dynamic from 'next/dynamic';
import { RefObject, useEffect, useState } from 'react';
import styled from 'styled-components';

const MarkdownEditor = dynamic(
Expand All @@ -15,7 +18,23 @@ const MarkdownEditor = dynamic(
},
);

const MyAnswer = () => {
interface MyAnswerProps {
pId: number;
}

const MyAnswer = ({ pId }: MyAnswerProps) => {
const [answerContent, setAnswerContent] = useState<string>('');

const handleContent = (editorRef: RefObject<Editor>) => {
const data = editorRef?.current?.getInstance().getMarkdown();
setAnswerContent(data as string);
};

const { mutate: postAnswer, isSuccess } = usePostAnswer(pId);

useEffect(() => {
setAnswerContent('');
}, [isSuccess]);
return (
<MyAnswerContainer>
<MyAnswerWrap>
Expand All @@ -34,9 +53,16 @@ const MyAnswer = () => {
</Guide>
</section>
<Spacing size={32} direction="vertical" />
<MarkdownEditor />
<MarkdownEditor onChange={handleContent} />
<Spacing size={32} direction="vertical" />
<AlignedSquareBtn>답변 게시</AlignedSquareBtn>
<AlignedSquareBtn
able={answerContent !== ''}
onClick={() => {
postAnswer({ content: answerContent, fileIds: [], questionId: pId });
}}
>
답변 게시
</AlignedSquareBtn>
</MyAnswerWrap>
</MyAnswerContainer>
);
Expand Down
Loading

0 comments on commit 4c2e797

Please sign in to comment.