AnswerList
import { useEffect, useState } from 'react';
import styled from 'styled-components';
import axios from 'axios';
import AnswerEditor from './AnswerEditor';
import AnswerItem from './AnswerItem';
const AnswersWrapper = styled.div`
padding: 24px 0;
`;
const Answer = styled.div`
padding-bottom: 24px;
border-bottom: 1px solid #d6d9dc;
`;
const AnswerList = ({ questionId }) => {
const [answers, setAnswers] = useState([]);
useEffect(() => {
const fetchData = async () => {
const url = `http://localhost:3001/answer?questionId=${questionId}`;
try {
await axios.get(url).then((res) => {
setAnswers(res.data);
});
} catch (err) {
console.log('error', err);
}
};
fetchData();
}, [questionId]);
return (
<AnswersWrapper>
{answers
? answers.map((answer) => {
return (
<>
<AnswerItem key={answer.answerId} answer={answer} />
</>
);
})
: null}
<AnswerEditor
questionId={questionId}
answers={answers}
setAnswers={setAnswers}
/>
</AnswersWrapper>
);
};
export default AnswerList;
AnswerEditor
import axios from 'axios';
import { useState } from 'react';
import styled from 'styled-components';
import { useParams } from 'react-router-dom';
const AnswerEditorWrapper = styled.div`
/* border-top: 1px solid #d6d9dc; */
padding: 24px 0;
textarea {
width: 100%;
height: 200px;
margin-bottom: 24px;
}
`;
const AnswerEditor = ({ questionId, answers, setAnswers }) => {
const [answer, setAnswer] = useState([]);
const onChange = (e) => {
setAnswer(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
const data = {
// eslint-disable-next-line no-const-assign, no-undef
questionId: 2,
body: answer,
};
const fetchData = async () => {
try {
// const url = `${process.env.REACT_APP_ANSWER}`;
const url = `http://localhost:3001/answer`;
await axios.post(url, data);
window.location.reload();
} catch (err) {
console.log('error', err);
}
};
fetchData();
};
return (
<>
<AnswerEditorWrapper className="answerEditor">
<h2>Your Answer</h2>
<form onSubmit={handleSubmit}>
<textarea onChange={onChange} />
<button className="button">Post Your Answer</button>
</form>
</AnswerEditorWrapper>
</>
);
};
export default AnswerEditor;
AnswerItem
import styled from 'styled-components';
import Writer from '../components/Writer';
import axios from 'axios';
import { useEffect, useState } from 'react';
import AnswerEditor from './AnswerEditor';
import AnswerUpdate from './AnswerUpdate';
const Answer = styled.div`
padding-bottom: 24px;
border-bottom: 1px solid #d6d9dc;
.handleBtns {
button {
border: none;
margin: 4px;
color: #6a737c;
font-size: 13px;
cursor: pointer;
}
}
`;
const AnswerItem = ({ answer }) => {
const [isEdit, setIsEdit] = useState(false);
const { id, body, userId } = answer;
//DELETE
const handleDelete = () => {
console.log(id, body);
const url = `http://localhost:3001/answer/${id}`;
const fetchData = async () => {
try {
await axios.delete(url).then(() => {
console.log(id, body);
window.location.reload();
});
} catch (err) {
console.log('error', err);
}
};
fetchData();
};
const handleEditBtn = () => {
setIsEdit(!isEdit);
};
return (
<>
{answer ? (
<Answer id={id}>
<div>
<h2>Answers</h2>
{isEdit ? (
<AnswerUpdate
body={body}
setIsEdit={setIsEdit}
isEdit={isEdit}
answerId={id}
/>
) : (
<div>{body}</div>
)}
</div>
<Writer props={userId} />
<div className="handleBtns">
<button onClick={handleEditBtn}>edit</button>
<button onClick={handleDelete}>delete</button>
</div>
</Answer>
) : null}
</>
);
};
export default AnswerItem;
AnswerUpdate
import axios from 'axios';
import { useEffect, useState } from 'react';
import styled from 'styled-components';
const Button = styled.button`
background-color: #0a95ff;
padding: 0.8em;
border-radius: 5px;
color: white;
border: 1px solid transparent;
white-space: nowrap;
font-size: 13px;
cursor: pointer;
&:hover {
background-color: #0074cc;
}
`;
const Textarea = styled.textarea`
width: 100%;
height: 200px;
margin-bottom: 24px;
`;
const AnswerUpdate = ({ setIsEdit, isEdit, body, answerId }) => {
const [editText, setEditText] = useState();
// UPDATE
const onChange = (e) => {
setEditText(e.target.value);
};
const handleEditBtn = () => {
// const url = REACT_APP_ANSWER + ${answerId};
const url = `http://localhost:3001/answer/${answerId}`;
const data = {
id: answerId,
answerStatus: 'ANSWER_NOT_EXIST',
body: editText,
};
const fetchData = async () => {
try {
await axios.patch(url, data).then((res) => {
console.log(res);
setIsEdit(false);
});
} catch (err) {
console.log('error', err);
}
};
fetchData();
};
return (
<>
<Textarea value={editText ? editText : body} onChange={onChange} />
<Button onClick={handleEditBtn}>Save Edits</Button>
</>
);
};
export default AnswerUpdate;
detail
import Footer from '../components/Footer';
import Header from '../components/Header';
import Nav, { headerHeight } from '../components/Nav';
import Sidebar from '../components/Sidebar';
import styled from 'styled-components';
import Writer from '../components/Writer';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';
import AnswerList from '../components/AnswerList';
const Container = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
max-width: 1264px;
margin: 0 auto;
min-height: 100vh;
font-size: 13px;
a {
text-decoration: none;
}
.wrapper {
margin-top: ${headerHeight}px;
border-left: 1px solid #d6d9dc;
width: 100%;
h1 {
line-height: 1.35;
font-weight: normal;
margin: 0;
}
.content {
max-width: 1100px;
padding: 24px;
.header {
width: 100%;
border-bottom: 1px solid #d6d9dc;
.title {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
div {
margin-left: 12px;
}
}
.detail {
display: flex;
flex-direction: row;
div {
margin: 8px 16px 8px 0;
span {
margin-right: 4px;
}
}
}
}
.contentBody {
display: flex;
flex-direction: row;
justify-content: space-between;
.mainbar {
width: 100%;
max-width: 728px;
font-size: 15px;
.post {
padding-right: 16px;
}
}
}
}
}
.button {
background-color: #0a95ff;
padding: 0.8em;
border-radius: 5px;
color: white;
border: 1px solid transparent;
white-space: nowrap;
font-size: 13px;
cursor: pointer;
&:hover {
background-color: #0074cc;
}
}
h2 {
font-weight: 400;
font-size: 19px;
}
`;
const Detail = () => {
let { id } = useParams();
const [question, setQuestion] = useState(null);
useEffect(() => {
const url = `http://localhost:3001/question?questionId=${id}`;
const fetchData = async () => {
try {
await axios.get(url).then((res) => {
setQuestion(res.data[0]);
});
} catch (err) {
console.log('error', err);
}
};
fetchData();
}, []);
return (
<>
(
<Header />
<Container>
<Nav />
<div className="wrapper">
<div className="content">
<div className="header">
<div className="title">
{<h1>{question?.title}</h1>}
<div>
<button href="#!" className="button">
Ask Question
</button>
</div>
</div>
<div className="detail">
<div>
<span>Asked</span>
{question?.createdAt}
</div>
<div>
<span>Modified</span>
며칠전
</div>
<div>
<span>Viewed</span>
{question?.view}
</div>
</div>
</div>
<div className="contentBody">
<div className="mainbar">
<div className="post">
<p>{question?.body}</p>
</div>
<Writer props={question?.questionId} />
<AnswerList questionId={id} />
</div>
<Sidebar />
</div>
</div>
</div>
</Container>
<Footer />)
</>
);
};
export default Detail;
mock data
{
"question": {
"data": [
{
"questionId": 5,
"questionStatus": "QUESTION_EXIST",
"title": "string",
"body": "string",
"view": 0,
"createdAt": "2022-11-02T20:12:47.809521",
"updatedAt": "2022-11-02T20:12:47.719745"
},
{
"questionId": 4,
"questionStatus": "QUESTION_EXIST",
"title": "test",
"body": "qwdawdawdawdawd",
"view": 0,
"createdAt": "2022-11-02T15:23:23.614035",
"updatedAt": "2022-11-02T15:23:23.523276"
},
{
"questionId": 3,
"questionStatus": "QUESTION_EXIST",
"title": "string",
"body": "string",
"view": 0,
"createdAt": "2022-11-02T15:02:40.439374",
"updatedAt": "2022-11-02T15:02:40.381612"
},
{
"questionId": 2,
"questionStatus": "QUESTION_EXIST",
"title": "string1",
"body": "string2",
"view": 0,
"createdAt": "2022-11-02T14:18:35.093064",
"updatedAt": "2022-11-02T14:18:35.076376"
}
],
"pageInfo": {
"page": 1,
"size": 10,
"totalElements": 4,
"totalPages": 1
}
},
"answer": [
{
"id": 2,
"questionId": 2,
"userId": "바쁘다",
"body": "bye world!aa",
"answerStatus": "ANSWER_NOT_EXIST"
},
{
"questionId": 2,
"body": "sdfs",
"id": 3
}
]
}