design: 게시 디자인 수정

This commit is contained in:
jhynsoo 2024-08-08 17:33:35 +09:00
parent fbe28153f8
commit ae278070b7
26 changed files with 173 additions and 157 deletions

View File

@ -5,7 +5,6 @@ import HomePage from './pages/HomePage';
import NotFoundPage from './pages/NotFoundPage';
import { lazy, Suspense } from 'react';
import MyPageLayout from './components/Layout/MyPageLayout';
// import LivePage from './pages/LivePage';
import ErrorPage from './pages/ErrorPage';
import { LectureLayout } from './components/Layout';

View File

@ -75,9 +75,8 @@ export default function ArticleDetail({
)}
</div>
</header>
<div>
<p className={styles.content}>{content}</p>
</div>
<p className={styles.content}>{content}</p>
<div></div>
{/* TODO: 이 부분에서 answer 만든다음 뒤로가기로 나갔다가 돌아오면 0.1초 정도 input 칸이 보였다가 answer 로 바뀜. 수정필요 */}
{isQna &&
(submittedAnswer && !isEditing ? (

View File

@ -53,7 +53,7 @@
line-height: 1.4;
font-weight: 400;
margin: 0;
white-space: pre-line;
white-space: pre-wrap;
}
.icon {
@ -61,6 +61,7 @@
}
.actionGroup {
flex-shrink: 0;
display: flex;
align-items: end;
gap: 20px;

View File

@ -27,6 +27,7 @@
}
.actionGroup {
flex-shrink: 0;
display: flex;
gap: 12px;
}

View File

@ -3,6 +3,8 @@ import { useAnswerWrite } from '../../../../hooks/api/useAnswerWrite';
import { useParams } from 'react-router-dom';
import { useState } from 'react';
import SendIcon from '/src/assets/icons/send.svg?react';
export default function ArticleDetailAnswerInput({ onSubmit, initialAnswer }) {
const { answerWrite } = useAnswerWrite();
const { questionId } = useParams();
@ -19,19 +21,19 @@ export default function ArticleDetailAnswerInput({ onSubmit, initialAnswer }) {
onSubmit={handleSubmit}
className={styles.answer}
>
{/* TODO: 여기 css 부분은 내가 임의로 넣었음 */}
<input
type="text"
maxLength={255}
value={newAnswer}
onChange={(e) => setNewAnswer(e.target.value)}
placeholder="답변 작성"
placeholder="답변 작성하기"
className={styles.input}
/>
<button
type="submit"
className={styles.button}
>
작성
<SendIcon />
</button>
</form>
);

View File

@ -1,6 +1,6 @@
.answer {
border: 1px solid #ccc;
padding: 16px;
border: 1px solid var(--border-color);
padding: 8px;
border-radius: 8px;
display: flex;
align-items: center;
@ -17,14 +17,13 @@
}
.button {
padding: 8px 16px;
font-size: 16px;
line-height: 1.4;
font-weight: 700;
display: flex;
justify-content: center;
align-items: center;
padding: 12px 16px;
background-color: var(--primary-color);
color: var(--on-primary);
stroke: var(--on-primary);
border: 1px solid var(--primary-color);
border: none;
border-radius: 8px;
cursor: pointer;
}

View File

@ -34,6 +34,7 @@ export default function CreateArticle({ topic, title, onSubmit }) {
<label className={styles.label}>제목</label>
<input
type="text"
maxLength={255}
className={styles.titleInput}
placeholder="제목을 입력하세요"
value={articleTitle}

View File

@ -48,6 +48,7 @@ export default function EditArticle({ topic, title, prevTitle, prevContent, onSu
<label className={styles.label}>제목</label>
<input
type="text"
maxLength={255}
className={styles.titleInput}
placeholder="제목을 입력하세요"
value={articleTitle}

View File

@ -34,6 +34,7 @@ export default function EditFreeboard({ topic, title, prevContent, prevTitle, on
<label className={styles.label}>제목</label>
<input
type="text"
maxLength={255}
className={styles.titleInput}
placeholder={'제목을 입력하세요'}
value={articleTitle}

View File

@ -34,6 +34,7 @@ export default function EditQna({ topic, title, prevContent, prevTitle, onSubmit
<label className={styles.label}>제목</label>
<input
type="text"
maxLength={255}
className={styles.titleInput}
placeholder={'제목을 입력하세요'}
value={articleTitle}

View File

@ -4,7 +4,9 @@ import { useCommentDelete } from '../../../../hooks/api/useCommentDelete';
import { useState } from 'react';
import { useCommentEdit } from '../../../../hooks/api/useCommentEdit';
export default function FreeboardComment({ content, author, onDeleteSubmit, onEditSubmit, commentId }) {
import SendIcon from '/src/assets/icons/send.svg?react';
export default function FreeboardComment({ content, author, onDeleteSubmit, onEditSubmit, commentId, isMine }) {
const [isEditing, setIsEditing] = useState(false);
const { commentDelete } = useCommentDelete();
const { commentEdit } = useCommentEdit();
@ -40,7 +42,7 @@ export default function FreeboardComment({ content, author, onDeleteSubmit, onEd
type="text"
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
placeholder="답변 작성"
placeholder="댓글 수정하기"
className={styles.input}
required
/>
@ -48,30 +50,38 @@ export default function FreeboardComment({ content, author, onDeleteSubmit, onEd
type="submit"
className={styles.button}
>
작성
<SendIcon />
</button>
</form>
) : (
<section className={styles.comment}>
<div className={styles.commentHeader}>
<ReplyIcon />
<div className={styles.author}>{author} 답변</div>
<div className={styles.title}>
<ReplyIcon />
<div className={styles.author}>{author}</div>
</div>
{isMine && (
<div className={styles.actionGroup}>
<button
type="button"
className={styles.edit}
to={'edit'}
onClick={onEditClick}
>
수정
</button>
<button
type="button"
className={styles.delete}
onClick={handleDeleteSubmit}
>
삭제
</button>
</div>
)}
</div>
<p className={styles.content}>{content}</p>
<button
type="button"
className={styles.deleteButton}
onClick={handleDeleteSubmit}
>
<div>삭제</div>
</button>
<button
type="button"
className={styles.editButton}
onClick={onEditClick}
>
수정
</button>
</section>
)}
</>

View File

@ -10,8 +10,8 @@
}
.commentEdit {
border: 1px solid #ccc;
padding: 16px;
border: 1px solid var(--border-color);
padding: 8px;
border-radius: 8px;
display: flex;
flex-direction: row;
@ -20,6 +20,11 @@
}
.commentHeader {
display: flex;
justify-content: space-between;
}
.title {
display: flex;
gap: 4px;
color: var(--text-color-secondary);
@ -40,40 +45,6 @@
color: var(--text-color);
}
.editButton {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
border: 1px solid var(--primary-color);
background-color: var(--primary-color);
color: var(--on-primary);
stroke: var(--on-primary);
font-size: 16px;
line-height: 1.4;
font-weight: 700;
align-self: end;
border-radius: 8px;
cursor: pointer;
}
.deleteButton {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
border: 1px solid var(--error-color);
background-color: var(--error-color);
color: var(--on-primary);
stroke: var(--on-primary);
font-size: 16px;
line-height: 1.4;
font-weight: 700;
align-self: end;
border-radius: 8px;
cursor: pointer;
}
.input {
flex: 1;
border: none;
@ -84,14 +55,39 @@
}
.button {
padding: 8px 16px;
font-size: 16px;
line-height: 1.4;
font-weight: 700;
display: flex;
justify-content: center;
align-items: center;
padding: 12px 16px;
background-color: var(--primary-color);
color: var(--on-primary);
stroke: var(--on-primary);
border: 1px solid var(--primary-color);
border: none;
border-radius: 8px;
cursor: pointer;
}
.actionGroup {
flex-shrink: 0;
display: flex;
align-items: end;
gap: 16px;
color: var(--text-color);
margin-right: 8px;
}
.edit,
.delete {
padding: 0;
margin: 0;
border: none;
background-color: var(--background);
color: var(--text-color-tertiary);
font-size: 14px;
line-height: 1.4;
font-weight: 500;
cursor: pointer;
}
.delete {
color: var(--error-color);
}

View File

@ -1,5 +1,6 @@
import styles from './FreeboardCommentInput.module.css';
import { useState } from 'react';
import SendIcon from '/src/assets/icons/send.svg?react';
export default function FreeboardCommentInput({ onCommentSubmit }) {
const [newComment, setNewComment] = useState('');
@ -19,7 +20,7 @@ export default function FreeboardCommentInput({ onCommentSubmit }) {
type="text"
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
placeholder="답변 작성"
placeholder="댓글 작성하기"
className={styles.input}
required
/>
@ -27,7 +28,7 @@ export default function FreeboardCommentInput({ onCommentSubmit }) {
type="submit"
className={styles.button}
>
작성
<SendIcon />
</button>
</form>
);

View File

@ -1,6 +1,6 @@
.comment {
border: 1px solid #ccc;
padding: 16px;
border: 1px solid var(--border-color);
padding: 8px;
border-radius: 8px;
display: flex;
align-items: center;
@ -17,14 +17,12 @@
}
.button {
padding: 8px 16px;
font-size: 16px;
line-height: 1.4;
font-weight: 700;
display: flex;
align-items: center;
padding: 12px 16px;
background-color: var(--primary-color);
color: var(--on-primary);
stroke: var(--on-primary);
border: 1px solid var(--primary-color);
border: none;
border-radius: 8px;
cursor: pointer;
}

View File

@ -5,10 +5,9 @@ import FreeboardCommentInput from './FreeDetailComments/FreeboardCommentInput';
import FreeboardComment from './FreeDetailComments/FreeboardComment';
import { useComments } from '../../../hooks/api/useComments';
import { useCommentWrite } from '../../../hooks/api/useCommentWrite';
import EditIcon from '/src/assets/icons/edit.svg?react';
import { useParams } from 'react-router-dom';
export default function FreeboardDetail({ topic, title, author, content, onDelete }) {
export default function FreeboardDetail({ topic, title, author, content, onDelete, isMine }) {
const { freeboardId } = useParams();
const { data, refetch } = useComments(freeboardId);
const { commentWrite } = useCommentWrite();
@ -19,14 +18,6 @@ export default function FreeboardDetail({ topic, title, author, content, onDelet
refetch();
};
const handleDeleteSubmit = () => {
refetch();
};
const handleEditSubmit = () => {
refetch();
};
return (
<div className={styles.freeboardDetail}>
<header className={styles.header}>
@ -43,22 +34,24 @@ export default function FreeboardDetail({ topic, title, author, content, onDelet
{author && <span className={styles.author}>{author}</span>}
</div>
</div>
<Link
type="button"
className={styles.editButton}
to={'edit'}
state={{ title: title, content: content }}
>
<EditIcon className={styles.icon} />
<span>수정하기</span>
</Link>
<button
type="button"
className={styles.deleteButton}
onClick={onDelete}
>
삭제하기
</button>
{isMine && (
<div className={styles.actionGroup}>
<Link
to="edit"
className={styles.edit}
state={{ title: title, content: content }}
>
수정
</Link>
<button
type="button"
className={styles.delete}
onClick={onDelete}
>
<div>삭제</div>
</button>
</div>
)}
</header>
<div>
<p className={styles.content}>{content}</p>
@ -70,8 +63,9 @@ export default function FreeboardDetail({ topic, title, author, content, onDelet
content={comment.content}
author={comment.name}
commentId={comment.id}
onDeleteSubmit={handleDeleteSubmit}
onEditSubmit={handleEditSubmit}
isMine={comment.mine}
onDeleteSubmit={refetch}
onEditSubmit={refetch}
/>
))}
<FreeboardCommentInput onCommentSubmit={handleCommentSubmit} />

View File

@ -13,7 +13,7 @@
.header {
display: flex;
justify-content: space-between;
align-items: start;
align-items: end;
}
.headerInside {
@ -91,3 +91,26 @@
border-radius: 8px;
cursor: pointer;
}
.actionGroup {
flex-shrink: 0;
display: flex;
gap: 12px;
}
.edit,
.delete {
padding: 0;
margin: 0;
border: none;
background-color: var(--background);
font-size: 14px;
line-height: 1.4;
font-weight: 500;
color: var(--text-color-tertiary);
cursor: pointer;
}
.delete {
color: var(--error-color);
}

View File

@ -17,7 +17,6 @@ export default function LectureLayout() {
const { lectureDelete } = useLectureDelete();
const { data } = useLectureInfo(lectureId);
const lecture = data?.data;
console.log(lecture);
const userType = useBoundStore((state) => state.userType);
const handleDelete = () => {
confirm('강의를 삭제할까요??') &&

View File

@ -57,6 +57,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit, initialV
<input
className={styles.input}
type="text"
maxLength={255}
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="퀴즈셋 제목을 입력해주세요"

View File

@ -19,9 +19,9 @@ export default function QuizSet({ quizSetId, reportSetId, finish }) {
const requestData = {
answer: data,
};
instance.post(`${API_URL}/report/submit/${reportSetId}/quizset/${quizSetId}`, requestData).catch(() => {});
instance.post(`${API_URL}/report/submit/quizSet/${reportSetId}`, requestData).catch(() => {});
},
[quizSetId, reportSetId]
[reportSetId]
);
const QuizComponents = [
...quizList.map((quiz, index) => (

View File

@ -15,6 +15,7 @@ export default function FreeboardDetailPage() {
await freeboardDelete(freeboardId);
navigate('..');
};
return (
<FreeboardDetail
topic="자유게시판"
@ -22,6 +23,7 @@ export default function FreeboardDetailPage() {
author={freeboard.name}
content={freeboard.content}
onDelete={handleDelete}
isMine={freeboard.mine}
/>
);
}

View File

@ -7,7 +7,7 @@ export default function NoticeListPage() {
const { lectureId } = useParams();
const { data } = useFreeboards(lectureId);
const notices = data?.data;
console.log(notices);
return (
<ArticleBoard
title="자유게시판"

View File

@ -47,7 +47,7 @@ export default function LectureInfoPage() {
tutor={lectureData.teacherName}
tutorImg={lectureData.tutorImg}
/>
<MaxWidthLayout hasSideBar>
<div className={styles.wrapper}>
<main>
<div className={styles.group}>
<h2>수업소개</h2>
@ -66,7 +66,7 @@ export default function LectureInfoPage() {
status={status}
/>
</aside>
</MaxWidthLayout>
</div>
</>
);
}

View File

@ -1,3 +1,25 @@
.wrapper {
display: flex;
gap: 20px;
width: 100%;
max-width: 1320px;
padding: 0 40px;
margin: 0 auto;
box-sizing: border-box;
& > main {
width: 100%;
}
& > aside {
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 32px;
width: 320px;
}
}
.group {
display: flex;
flex-direction: column;

View File

@ -1,33 +0,0 @@
import { ArticleLink } from '../../components/ArticleLink';
import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
export default function TeacherNoticeListPage() {
const { data: notices } = {
data: [
{ id: 1, title: '공지사항1', sub: '7-12 오전 11:40:57' },
{ id: 2, title: '공지사하앙2', sub: '7-12 오전 11:40:57' },
{ id: 3, title: '공지사하앙33', sub: '7-15 오전 11:40:57' },
{ id: 4, title: '제목만 있는 경우' },
],
};
return (
<ArticleBoard
title="공지사항"
canCreate={true}
>
{notices.length &&
notices.map?.((notice) => {
if (notice.sub && notice.title) {
return (
<ArticleLink
key={`${notice.title}${notice.sub}`}
title={notice.title}
sub={notice.sub}
/>
);
}
})}
</ArticleBoard>
);
}

View File

@ -1 +0,0 @@
export { default } from './TeacherNoticeListPage';

View File

@ -12,7 +12,6 @@ const instance = axios.create({
instance.interceptors.request.use((config) => {
const accessToken = useBoundStore.getState().token;
console.log(accessToken);
if (accessToken) {
config.headers.Authorization = `${accessToken}`;
}