Merge branch 'fe/infiniteScroll' into 'frontend'
[Front-End] 공지사항, 자유게시판에 무한스크롤 추가 See merge request s11-webmobile1-sub2/S11P12A701!158
This commit is contained in:
commit
d755840501
@ -31,7 +31,6 @@ export default function ArticleDetailAnswerInput({ onSubmit, initialAnswer = '',
|
|||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
console.log(isEditing);
|
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
await answerEdit(questionId, answer);
|
await answerEdit(questionId, answer);
|
||||||
} else {
|
} else {
|
||||||
@ -40,8 +39,6 @@ export default function ArticleDetailAnswerInput({ onSubmit, initialAnswer = '',
|
|||||||
onSubmit(answer);
|
onSubmit(answer);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(answer);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid var(--border-color);
|
padding: 12px 0;
|
||||||
border-radius: 16px;
|
|
||||||
padding: 12px 16px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +41,7 @@
|
|||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
|
@ -56,18 +56,22 @@ export default function FreeboardDetail({ topic, title, author, content, onDelet
|
|||||||
<div>
|
<div>
|
||||||
<p className={styles.content}>{content}</p>
|
<p className={styles.content}>{content}</p>
|
||||||
</div>
|
</div>
|
||||||
{comments &&
|
|
||||||
comments.map((comment) => (
|
{comments && (
|
||||||
<FreeboardComment
|
<div className={styles.commentWrapper}>
|
||||||
key={comment.id}
|
{comments.map((comment) => (
|
||||||
content={comment.content}
|
<FreeboardComment
|
||||||
author={comment.name}
|
key={comment.id}
|
||||||
commentId={comment.id}
|
content={comment.content}
|
||||||
isMine={comment.mine}
|
author={comment.name}
|
||||||
onDeleteSubmit={refetch}
|
commentId={comment.id}
|
||||||
onEditSubmit={refetch}
|
isMine={comment.mine}
|
||||||
/>
|
onDeleteSubmit={refetch}
|
||||||
))}
|
onEditSubmit={refetch}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<FreeboardCommentInput onCommentSubmit={handleCommentSubmit} />
|
<FreeboardCommentInput onCommentSubmit={handleCommentSubmit} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -114,3 +114,11 @@
|
|||||||
.delete {
|
.delete {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commentWrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 18px;
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
.articleLink {
|
.articleLink {
|
||||||
border-radius: 8px;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
box-sizing: border-box;
|
gap: 20px;
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
transition: background-color 0.25s;
|
transition: background-color 0.25s;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.articleLink:hover {
|
.articleLink:hover {
|
||||||
@ -17,9 +19,13 @@
|
|||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.date {
|
.date {
|
||||||
|
flex-shrink: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import styles from './ChatInput.module.css';
|
|
||||||
import { useRef } from 'react';
|
|
||||||
|
|
||||||
export default function ChattingInput() {
|
|
||||||
// TODO: 채팅이 넘어갈 시 줄바꿈이 되도록 수정
|
|
||||||
// TODO: ㅁ 을 아이콘으로 변경
|
|
||||||
const message = useRef('');
|
|
||||||
const handleSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
// TODO: 실제 메시지 전송 기능 추가
|
|
||||||
console.log(message.current.value);
|
|
||||||
message.current.value = '';
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<form
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
className={styles.chattingInput}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
ref={message}
|
|
||||||
className={styles.input}
|
|
||||||
placeholder="메시지를 입력하세요"
|
|
||||||
/>
|
|
||||||
<div onClick={handleSubmit}>ㅁ</div>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
.chattingInput {
|
|
||||||
border-radius: 9999px;
|
|
||||||
background-color: var(--background);
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 12px 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1;
|
|
||||||
color: var(--text-color);
|
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input::placeholder {
|
|
||||||
color: var(--text-color-tertiary);
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export { default as ChatInput } from './ChatInput';
|
|
@ -12,6 +12,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|
||||||
& > .quizButton {
|
& > .quizButton {
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import styles from './CreateClass.module.css';
|
|
||||||
import { useRef } from 'react';
|
|
||||||
|
|
||||||
export default function CreateClass() {
|
|
||||||
// TODO: ㅁ 아이콘으로 변경
|
|
||||||
const classTime = useRef('');
|
|
||||||
const numOfLecture = useRef('');
|
|
||||||
const significant = useRef('');
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
// TODO : 강의 생성 기능 작성
|
|
||||||
const payload = {
|
|
||||||
classTime: classTime.current.value,
|
|
||||||
numOfLecture: numOfLecture.current.value,
|
|
||||||
significant: significant.current.value,
|
|
||||||
};
|
|
||||||
alert(`특이사항 : ${payload.significant}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form
|
|
||||||
className={styles.createClass}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
>
|
|
||||||
<div className={styles.inputField}>
|
|
||||||
<label className={styles.label}>수업 시간</label>
|
|
||||||
<input
|
|
||||||
className={styles.input}
|
|
||||||
ref={classTime}
|
|
||||||
type="text"
|
|
||||||
placeholder="수업 시간을 입력하세요"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={styles.inputField}>
|
|
||||||
<label className={styles.label}>강의 수</label>
|
|
||||||
<input
|
|
||||||
className={styles.input}
|
|
||||||
ref={numOfLecture}
|
|
||||||
type="text"
|
|
||||||
placeholder="총 강의 수를 입력하세요"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={styles.inputField}>
|
|
||||||
<label className={styles.label}>특이사항</label>
|
|
||||||
<textarea
|
|
||||||
ref={significant}
|
|
||||||
className={styles.textarea}
|
|
||||||
placeholder="이 수업만의 특이사항이 있다면 입력하세요"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className={styles.button}
|
|
||||||
>
|
|
||||||
<div>ㅁ</div>
|
|
||||||
<div className={styles.buttonText}>글 쓰기</div>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
.createClass {
|
|
||||||
background: var(--background-color);
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputField {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: var(--text-color);
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
background: var(--background-color);
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 1.2;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input::placeholder {
|
|
||||||
color: var(--text-color-tertiary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.textarea {
|
|
||||||
padding: 20px;
|
|
||||||
height: 150px;
|
|
||||||
background: var(--background-color);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1.4;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textarea::placeholder {
|
|
||||||
color: var(--text-color-tertiary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
padding: 16px 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid var(--primary-color);
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
color: var(--on-primary);
|
|
||||||
gap: 8px;
|
|
||||||
align-self: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttonText {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1.4;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export { default as CreateClass } from './CreateClass';
|
|
@ -0,0 +1,33 @@
|
|||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export default function IntersectionArea({ onObserve, once = false }) {
|
||||||
|
const ref = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const callback = (entries, observer) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
onObserve();
|
||||||
|
if (once) {
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const observer = new IntersectionObserver(callback, {
|
||||||
|
root: null,
|
||||||
|
rootMargin: '0px',
|
||||||
|
threshold: 0.5,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ref.current) {
|
||||||
|
observer.observe(ref.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, [onObserve, once]);
|
||||||
|
|
||||||
|
return <div ref={ref} />;
|
||||||
|
}
|
1
frontend/src/components/IntersectionArea/index.js
Normal file
1
frontend/src/components/IntersectionArea/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as IntersectionArea } from './IntersectionArea';
|
@ -19,6 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
& > main {
|
& > main {
|
||||||
|
min-width: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ export default function LectureForm({ title, topic, to = '..', initialValues = {
|
|||||||
const timeRef = useRef('');
|
const timeRef = useRef('');
|
||||||
const imageFileRef = useRef(null);
|
const imageFileRef = useRef(null);
|
||||||
|
|
||||||
// 초기 값 설정
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialValues.title) titleRef.current.value = initialValues.title;
|
if (initialValues.title) titleRef.current.value = initialValues.title;
|
||||||
if (initialValues.description) descriptionRef.current.value = initialValues.description;
|
if (initialValues.description) descriptionRef.current.value = initialValues.description;
|
||||||
@ -60,7 +59,10 @@ export default function LectureForm({ title, topic, to = '..', initialValues = {
|
|||||||
</Link>
|
</Link>
|
||||||
<div className={styles.title}>{topic}</div>
|
<div className={styles.title}>{topic}</div>
|
||||||
</header>
|
</header>
|
||||||
<form onSubmit={handleSubmit}>
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className={styles.form}
|
||||||
|
>
|
||||||
<div className={styles.inputField}>
|
<div className={styles.inputField}>
|
||||||
<label className={styles.label}>강의명</label>
|
<label className={styles.label}>강의명</label>
|
||||||
<input
|
<input
|
||||||
@ -89,16 +91,24 @@ export default function LectureForm({ title, topic, to = '..', initialValues = {
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.inputField}>
|
<div className={styles.inputField}>
|
||||||
<label className={styles.label}>강의 기간</label>
|
<label className={styles.label}>강의 기간</label>
|
||||||
<input
|
<div className={styles.dateWrapper}>
|
||||||
className={styles.input}
|
<div className={styles.date}>
|
||||||
ref={startDateRef}
|
<input
|
||||||
type="date"
|
className={styles.input}
|
||||||
/>
|
ref={startDateRef}
|
||||||
<input
|
type="date"
|
||||||
className={styles.input}
|
/>
|
||||||
ref={endDateRef}
|
<span className={styles.label}>부터</span>
|
||||||
type="date"
|
</div>
|
||||||
/>
|
<div className={styles.date}>
|
||||||
|
<input
|
||||||
|
className={styles.input}
|
||||||
|
ref={endDateRef}
|
||||||
|
type="date"
|
||||||
|
/>
|
||||||
|
<span className={styles.label}>까지</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.inputField}>
|
<div className={styles.inputField}>
|
||||||
<label className={styles.label}>수업 시간</label>
|
<label className={styles.label}>수업 시간</label>
|
||||||
@ -117,6 +127,7 @@ export default function LectureForm({ title, topic, to = '..', initialValues = {
|
|||||||
type="file"
|
type="file"
|
||||||
ref={imageFileRef}
|
ref={imageFileRef}
|
||||||
accept=".png, .jpg, .jpeg"
|
accept=".png, .jpg, .jpeg"
|
||||||
|
className={styles.input}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -32,6 +32,33 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dateWrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
display: flex;
|
||||||
|
justify-content: stretch;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.inputField {
|
.inputField {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -47,11 +74,11 @@
|
|||||||
|
|
||||||
.input {
|
.input {
|
||||||
background: var(--background-color);
|
background: var(--background-color);
|
||||||
padding: 20px;
|
padding: 16px;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 20px;
|
font-size: 16px;
|
||||||
line-height: 1.2;
|
line-height: 1.4;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.textarea {
|
.textarea {
|
||||||
padding: 20px;
|
padding: 16px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
background: var(--background-color);
|
background: var(--background-color);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
@ -116,7 +116,7 @@ export default function LiveRoom() {
|
|||||||
<span>{participants.length}명</span>
|
<span>{participants.length}명</span>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div className="lk-video-conference">
|
<div className={`lk-video-conference ${styles.videoRoom}`}>
|
||||||
<LayoutContextProvider value={layoutContext}>
|
<LayoutContextProvider value={layoutContext}>
|
||||||
<div className="lk-video-conference-inner">
|
<div className="lk-video-conference-inner">
|
||||||
{!focusTrack ? (
|
{!focusTrack ? (
|
||||||
|
@ -30,3 +30,7 @@
|
|||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.videoRoom {
|
||||||
|
height: calc(100% - 48px) !important;
|
||||||
|
}
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
white-space: pre-line;
|
||||||
|
word-break: break-word;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
@ -2,7 +2,6 @@ import styles from './QuizCard.module.css';
|
|||||||
import { STATIC_URL } from '../../constants';
|
import { STATIC_URL } from '../../constants';
|
||||||
|
|
||||||
export default function QuizDetailCard({ index, question, answer, image, choices, userAnswer = null, correct = true }) {
|
export default function QuizDetailCard({ index, question, answer, image, choices, userAnswer = null, correct = true }) {
|
||||||
console.log(correct);
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.card} ${!correct && styles.incorrect}`}>
|
<div className={`${styles.card} ${!correct && styles.incorrect}`}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
|
@ -16,7 +16,6 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit, initialV
|
|||||||
setTitle(initialValue.title || '');
|
setTitle(initialValue.title || '');
|
||||||
setQuizzes(initialValue.quizzes || []);
|
setQuizzes(initialValue.quizzes || []);
|
||||||
setQuizId(initialValue.quizzes ? initialValue.quizzes[initialValue.quizzes.length - 1].id + 1 : 0);
|
setQuizId(initialValue.quizzes ? initialValue.quizzes[initialValue.quizzes.length - 1].id + 1 : 0);
|
||||||
console.log(initialValue.quizzes.length);
|
|
||||||
}
|
}
|
||||||
}, [initialValue]);
|
}, [initialValue]);
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit, initialV
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className={`${styles.button} ${styles.add} ${styles.create}`}
|
className={`${styles.button} ${styles.add}`}
|
||||||
>
|
>
|
||||||
<EditIcon />
|
<EditIcon />
|
||||||
<div>퀴즈 생성하기</div>
|
<div>퀴즈 생성하기</div>
|
||||||
|
@ -109,10 +109,6 @@
|
|||||||
stroke: var(--on-primary);
|
stroke: var(--on-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.create {
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit {
|
.edit {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ export default function QuizModal({ startQuiz, quizSets, closeModal }) {
|
|||||||
<li
|
<li
|
||||||
key={quizSet.quizSetId}
|
key={quizSet.quizSetId}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log(quizSet.quizSetId);
|
|
||||||
startQuiz(quizSet.quizSetId);
|
startQuiz(quizSet.quizSetId);
|
||||||
closeModal();
|
closeModal();
|
||||||
}}
|
}}
|
||||||
|
@ -91,4 +91,5 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.25s;
|
transition: background-color 0.25s;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import styles from './QuizsetDetail.module.css';
|
|||||||
import { QuizDetailCard } from '../QuizForm';
|
import { QuizDetailCard } from '../QuizForm';
|
||||||
|
|
||||||
export default function QuizsetDetail({ topic, title, quizzes = [], onDelete, onEdit, tested = false }) {
|
export default function QuizsetDetail({ topic, title, quizzes = [], onDelete, onEdit, tested = false }) {
|
||||||
console.log('topic', topic, 'title', title, 'quizzes', quizzes);
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.quizsetDetail}>
|
<div className={styles.quizsetDetail}>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
|
@ -2,3 +2,4 @@ export const API_URL = import.meta.env.VITE_API_URL;
|
|||||||
export const ROOM_URL = import.meta.env.VITE_ROOM_URL;
|
export const ROOM_URL = import.meta.env.VITE_ROOM_URL;
|
||||||
export const CHAT_URL = import.meta.env.VITE_CHAT_URL;
|
export const CHAT_URL = import.meta.env.VITE_CHAT_URL;
|
||||||
export const STATIC_URL = import.meta.env.VITE_STATIC_URL;
|
export const STATIC_URL = import.meta.env.VITE_STATIC_URL;
|
||||||
|
export const PAGE_SIZE = 20;
|
||||||
|
@ -40,12 +40,7 @@ export function useAuth() {
|
|||||||
const logout = () => {
|
const logout = () => {
|
||||||
return instance
|
return instance
|
||||||
.post(`${API_URL}/user/logout`)
|
.post(`${API_URL}/user/logout`)
|
||||||
.then((response) => {
|
.catch(() => {})
|
||||||
console.log(response);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(e);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setUserType(null);
|
setUserType(null);
|
||||||
setToken(null);
|
setToken(null);
|
||||||
@ -66,7 +61,6 @@ export function useAuth() {
|
|||||||
newPassword: newPw,
|
newPassword: newPw,
|
||||||
newPasswordCheck: newPwCheck,
|
newPasswordCheck: newPwCheck,
|
||||||
};
|
};
|
||||||
console.log(passwordBody);
|
|
||||||
return instance.put(`${API_URL}/user/updatepassword`, passwordBody);
|
return instance.put(`${API_URL}/user/updatepassword`, passwordBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
import { useSuspenseQuery } from '@tanstack/react-query';
|
import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
|
||||||
import instance from '../../utils/axios/instance';
|
import instance from '../../utils/axios/instance';
|
||||||
import { API_URL } from '../../constants';
|
import { API_URL, PAGE_SIZE } from '../../constants';
|
||||||
|
|
||||||
export function useFreeboards(lectureId, page = 0) {
|
export function useFreeboards(lectureId, page = 0) {
|
||||||
return useSuspenseQuery({
|
return useSuspenseInfiniteQuery({
|
||||||
queryKey: ['freeboardlist', lectureId, page],
|
queryKey: ['freeboardlist', lectureId, page],
|
||||||
queryFn: () => instance.get(`${API_URL}/board?lectureId=${lectureId}&category=freeboard&pageNo=${page}`),
|
queryFn: ({ pageParam = 0 }) =>
|
||||||
|
instance.get(`${API_URL}/board?lectureId=${lectureId}&category=freeboard&pageNo=${pageParam}`),
|
||||||
|
getNextPageParam: (lastPage, allPages) => {
|
||||||
|
if (lastPage.data.length < PAGE_SIZE) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return allPages.length + 1;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import { API_URL } from '../../constants';
|
|||||||
|
|
||||||
export function useLectureCreate() {
|
export function useLectureCreate() {
|
||||||
const lectureCreate = (formData) => {
|
const lectureCreate = (formData) => {
|
||||||
// return instance.post(`${API_URL}/lecture`, lectureObject, image);
|
|
||||||
return instance.post(`${API_URL}/lecture`, formData, {
|
return instance.post(`${API_URL}/lecture`, formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-type': 'multipart/form-data',
|
'Content-type': 'multipart/form-data',
|
||||||
|
@ -7,7 +7,7 @@ export function useNoticeEdit() {
|
|||||||
title,
|
title,
|
||||||
content,
|
content,
|
||||||
};
|
};
|
||||||
console.log(newNotice);
|
|
||||||
return instance.put(`${API_URL}/board/${boardId}`, newNotice);
|
return instance.put(`${API_URL}/board/${boardId}`, newNotice);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
import { useSuspenseQuery } from '@tanstack/react-query';
|
import { useSuspenseInfiniteQuery } from '@tanstack/react-query';
|
||||||
import instance from '../../utils/axios/instance';
|
import instance from '../../utils/axios/instance';
|
||||||
import { API_URL } from '../../constants';
|
import { API_URL, PAGE_SIZE } from '../../constants';
|
||||||
|
|
||||||
export function useNotices(lectureId, page = 0) {
|
export function useNotices(lectureId) {
|
||||||
return useSuspenseQuery({
|
return useSuspenseInfiniteQuery({
|
||||||
queryKey: ['noticelist', lectureId, page],
|
queryKey: ['noticelist', lectureId],
|
||||||
queryFn: () => instance.get(`${API_URL}/board?lectureId=${lectureId}&category=announcement&pageNo=${page}`),
|
queryFn: ({ pageParam = 0 }) =>
|
||||||
|
instance.get(`${API_URL}/board?lectureId=${lectureId}&category=announcement&pageNo=${pageParam}`),
|
||||||
|
getNextPageParam: (lastPage, allPages) => {
|
||||||
|
if (lastPage.data.length < PAGE_SIZE) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return allPages.length + 1;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import { API_URL } from '../../constants';
|
|||||||
|
|
||||||
export function usePasswordReset() {
|
export function usePasswordReset() {
|
||||||
const sendEmail = (email) => {
|
const sendEmail = (email) => {
|
||||||
console.log(email);
|
|
||||||
return instance.post(`${API_URL}/mail/sendcode?email=${email}`);
|
return instance.post(`${API_URL}/mail/sendcode?email=${email}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import { useLectures } from '../../hooks/api/useLectures';
|
|||||||
export default function StudentHomePage() {
|
export default function StudentHomePage() {
|
||||||
const { data: allLectures } = useLectures();
|
const { data: allLectures } = useLectures();
|
||||||
const allClasses = allLectures?.data ?? [];
|
const allClasses = allLectures?.data ?? [];
|
||||||
console.log(allClasses);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MaxWidthLayout>
|
<MaxWidthLayout>
|
||||||
|
@ -2,25 +2,28 @@ import { ArticleLink } from '../../components/ArticleLink';
|
|||||||
import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
|
import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
|
||||||
import { useFreeboards } from '../../hooks/api/useFreeboards';
|
import { useFreeboards } from '../../hooks/api/useFreeboards';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import IntersectionArea from '../../components/IntersectionArea/IntersectionObserver';
|
||||||
|
|
||||||
export default function NoticeListPage() {
|
export default function NoticeListPage() {
|
||||||
const { lectureId } = useParams();
|
const { lectureId } = useParams();
|
||||||
const { data } = useFreeboards(lectureId);
|
const { data, fetchNextPage, hasNextPage } = useFreeboards(lectureId);
|
||||||
const notices = data?.data;
|
const articles = data?.pages.flatMap((page) => page.data);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ArticleBoard
|
<ArticleBoard
|
||||||
title="자유게시판"
|
title="자유게시판"
|
||||||
canCreate={true}
|
canCreate={true}
|
||||||
>
|
>
|
||||||
{notices.map?.((notice) => (
|
{articles.length &&
|
||||||
<ArticleLink
|
articles.map?.((notice) => (
|
||||||
key={`${notice.id}`}
|
<ArticleLink
|
||||||
title={notice.title}
|
key={`${notice.id}`}
|
||||||
sub={`${new Date(notice.createdAt).toLocaleDateString()} ${new Date(notice.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`}
|
title={notice.title}
|
||||||
to={`${notice.id}`}
|
sub={`${new Date(notice.createdAt).toLocaleDateString()} ${new Date(notice.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`}
|
||||||
/>
|
to={`${notice.id}`}
|
||||||
))}
|
/>
|
||||||
|
))}
|
||||||
|
{hasNextPage && <IntersectionArea onObserve={() => fetchNextPage()} />}
|
||||||
</ArticleBoard>
|
</ArticleBoard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { useQnas } from '../../hooks/api/useQnas';
|
|||||||
export default function LearningLectureDetailPage() {
|
export default function LearningLectureDetailPage() {
|
||||||
const { lectureId } = useParams();
|
const { lectureId } = useParams();
|
||||||
const { data: noticesData } = useNotices(lectureId);
|
const { data: noticesData } = useNotices(lectureId);
|
||||||
const notices = noticesData?.data.slice(0, 3);
|
const notices = noticesData.pages[0]?.data.slice(0, 3);
|
||||||
const { data: qnasData } = useQnas(lectureId);
|
const { data: qnasData } = useQnas(lectureId);
|
||||||
const questions = qnasData?.data.slice(0, 3);
|
const questions = qnasData?.data.slice(0, 3);
|
||||||
|
|
||||||
|
@ -10,15 +10,12 @@ export default function LecutreEditPage() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { lectureEdit } = useLectureEdit();
|
const { lectureEdit } = useLectureEdit();
|
||||||
|
|
||||||
const handleSubmit = async (lectureObject) => {
|
const handleSubmit = async (lectureObject) =>
|
||||||
const response = await lectureEdit(lectureId, lectureObject)
|
await lectureEdit(lectureId, lectureObject)
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
console.log(res);
|
|
||||||
navigate('..');
|
navigate('..');
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err));
|
.catch(() => {});
|
||||||
console.log(response?.data);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -33,9 +33,7 @@ export default function LectureInfoPage() {
|
|||||||
window.alert('강사가 수강신청 수락시 수업이 시작됩니다.');
|
window.alert('강사가 수강신청 수락시 수업이 시작됩니다.');
|
||||||
navigate('/');
|
navigate('/');
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(() => {});
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ export default function MyInfoChangePage() {
|
|||||||
await updateInfo(username, useremail)
|
await updateInfo(username, useremail)
|
||||||
.then(() => navigate('/'))
|
.then(() => navigate('/'))
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
|
||||||
console.log(err.response.data);
|
|
||||||
if (err.response.data === '이미 사용 중인 이메일입니다.') {
|
if (err.response.data === '이미 사용 중인 이메일입니다.') {
|
||||||
setUsingEmail(true);
|
setUsingEmail(true);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@ import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
|
|||||||
import { useNotices } from '../../hooks/api/useNotices';
|
import { useNotices } from '../../hooks/api/useNotices';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import useBoundStore from '../../store';
|
import useBoundStore from '../../store';
|
||||||
|
import IntersectionArea from '../../components/IntersectionArea/IntersectionObserver';
|
||||||
|
|
||||||
export default function NoticeListPage() {
|
export default function NoticeListPage() {
|
||||||
const { lectureId } = useParams();
|
const { lectureId } = useParams();
|
||||||
const { data } = useNotices(lectureId);
|
const { data, fetchNextPage, hasNextPage } = useNotices(lectureId);
|
||||||
const notices = data?.data;
|
const notices = data?.pages.flatMap((page) => page.data);
|
||||||
const userType = useBoundStore((state) => state.userType);
|
const userType = useBoundStore((state) => state.userType);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -24,6 +25,7 @@ export default function NoticeListPage() {
|
|||||||
to={`${notice.id}`}
|
to={`${notice.id}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
{hasNextPage && <IntersectionArea onObserve={() => fetchNextPage()} />}
|
||||||
</ArticleBoard>
|
</ArticleBoard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,11 @@ export default function PasswordChangePage() {
|
|||||||
const { updatePassword } = useAuth();
|
const { updatePassword } = useAuth();
|
||||||
const handleSubmit = async (currentPw, newPw, newPwCheck) => {
|
const handleSubmit = async (currentPw, newPw, newPwCheck) => {
|
||||||
await updatePassword(currentPw, newPw, newPwCheck)
|
await updatePassword(currentPw, newPw, newPwCheck)
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
console.log(res);
|
|
||||||
navigate('/');
|
navigate('/');
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err.response.data);
|
|
||||||
if (err.response.data === 'Current password is incorrect') {
|
if (err.response.data === 'Current password is incorrect') {
|
||||||
console.log('현재 비밀번호 에러');
|
|
||||||
setPwError(true);
|
setPwError(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -21,14 +21,11 @@ export default function PasswordResetPage() {
|
|||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setAuthError(false);
|
setAuthError(false);
|
||||||
console.log(authNumRef.current.value, email);
|
|
||||||
verify(authNumRef.current.value, email)
|
verify(authNumRef.current.value, email)
|
||||||
.then((res) => {
|
.then(() => {
|
||||||
console.log(res);
|
|
||||||
setSentAuthNum(true);
|
setSentAuthNum(true);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
|
||||||
if (err.message === 'Request failed with status code 404') {
|
if (err.message === 'Request failed with status code 404') {
|
||||||
setAuthError(true);
|
setAuthError(true);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AuthForm, InputBox } from '../../components/AuthForm';
|
import { AuthForm, InputBox } from '../../components/AuthForm';
|
||||||
import { useRef, useState, useEffect } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import styles from './PasswordResetPage.module.css';
|
import styles from './PasswordResetPage.module.css';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { usePasswordReset } from '../../hooks/api/usePasswordReset';
|
import { usePasswordReset } from '../../hooks/api/usePasswordReset';
|
||||||
@ -11,24 +11,14 @@ export default function PasswordResetPage() {
|
|||||||
|
|
||||||
const { sendEmail } = usePasswordReset();
|
const { sendEmail } = usePasswordReset();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (emailSent) {
|
|
||||||
console.log('Updated emailSent:', emailSent);
|
|
||||||
}
|
|
||||||
}, [emailSent]);
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setNotFound(false);
|
setNotFound(false);
|
||||||
await sendEmail(emailRef.current.value)
|
await sendEmail(emailRef.current.value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const email = emailRef.current.value;
|
setEmailSent(emailRef.current.value);
|
||||||
console.log(email);
|
|
||||||
setEmailSent(email);
|
|
||||||
console.log(emailSent);
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
|
||||||
if (err.message === 'Request failed with status code 404') {
|
if (err.message === 'Request failed with status code 404') {
|
||||||
setNotFound(true);
|
setNotFound(true);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ export default function QuestionListPage() {
|
|||||||
const questions = data?.data;
|
const questions = data?.data;
|
||||||
const userType = useBoundStore((state) => state.userType);
|
const userType = useBoundStore((state) => state.userType);
|
||||||
|
|
||||||
console.log(questions);
|
|
||||||
return (
|
return (
|
||||||
<ArticleBoard
|
<ArticleBoard
|
||||||
title="Q&A"
|
title="Q&A"
|
||||||
|
@ -10,15 +10,14 @@ export default function QuizsetDetailPage() {
|
|||||||
const { data } = useTeacherQuizsetDetail(quizsetId);
|
const { data } = useTeacherQuizsetDetail(quizsetId);
|
||||||
const quizset = data.data;
|
const quizset = data.data;
|
||||||
const tested = quizset.tested;
|
const tested = quizset.tested;
|
||||||
console.log(tested);
|
|
||||||
const handleEdit = () => {
|
const handleEdit = () => {
|
||||||
navigate('edit', { state: { initialValue: quizset } });
|
navigate('edit', { state: { initialValue: quizset } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
await quizsetDelete(quizsetId);
|
await quizsetDelete(quizsetId);
|
||||||
navigate('..');
|
navigate('..');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QuizsetDetail
|
<QuizsetDetail
|
||||||
topic={'퀴즈 목록'}
|
topic={'퀴즈 목록'}
|
||||||
|
@ -9,7 +9,6 @@ export default function QuizsetEditPage() {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const initialValue = location.state.initialValue;
|
const initialValue = location.state.initialValue;
|
||||||
const { quizsetEdit } = useQuizsetEdit();
|
const { quizsetEdit } = useQuizsetEdit();
|
||||||
console.log(initialValue);
|
|
||||||
const handleSubmit = async (e, title, quizzes) => {
|
const handleSubmit = async (e, title, quizzes) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@ -42,10 +41,6 @@ export default function QuizsetEditPage() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
console.log(`FormData - Key: ${key}, Value:`, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
await quizsetEdit(formData);
|
await quizsetEdit(formData);
|
||||||
navigate('..');
|
navigate('..');
|
||||||
};
|
};
|
||||||
|
@ -2,14 +2,12 @@ import { ArticleLink } from '../../components/ArticleLink';
|
|||||||
import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
|
import ArticleBoard from '../../components/ArticleBoard/ArticleBoard';
|
||||||
import { useQuizsets } from '../../hooks/api/useQuizsets';
|
import { useQuizsets } from '../../hooks/api/useQuizsets';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
// import useBoundStore from '../../store';
|
|
||||||
|
|
||||||
export default function QuizsetListPage() {
|
export default function QuizsetListPage() {
|
||||||
const { lectureId } = useParams();
|
const { lectureId } = useParams();
|
||||||
const { data } = useQuizsets(lectureId);
|
const { data } = useQuizsets(lectureId);
|
||||||
const quizsets = data?.data ?? [];
|
const quizsets = data?.data ?? [];
|
||||||
// const userType = useBoundStore((state) => state.userType);
|
|
||||||
console.log(quizsets);
|
|
||||||
return (
|
return (
|
||||||
<ArticleBoard
|
<ArticleBoard
|
||||||
title="퀴즈 목록"
|
title="퀴즈 목록"
|
||||||
|
@ -8,7 +8,6 @@ export default function QuizsetWritePage() {
|
|||||||
|
|
||||||
const handleSubmit = async (e, title, quizzes) => {
|
const handleSubmit = async (e, title, quizzes) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
console.log(quizzes);
|
|
||||||
if (quizzes.length === 0) {
|
if (quizzes.length === 0) {
|
||||||
window.alert('퀴즈가 없는 퀴즈셋은 생성할 수 없습니다');
|
window.alert('퀴즈가 없는 퀴즈셋은 생성할 수 없습니다');
|
||||||
return;
|
return;
|
||||||
|
@ -8,7 +8,6 @@ export default function StudentReportDetailPage() {
|
|||||||
const { lectureId, reportId } = useParams();
|
const { lectureId, reportId } = useParams();
|
||||||
const { data } = useStudentReportDetail(reportId);
|
const { data } = useStudentReportDetail(reportId);
|
||||||
const report = data.data;
|
const report = data.data;
|
||||||
console.log(report);
|
|
||||||
const { allCount, correctCount, quizzes, title } = report;
|
const { allCount, correctCount, quizzes, title } = report;
|
||||||
const score = Math.round((100 * correctCount) / allCount);
|
const score = Math.round((100 * correctCount) / allCount);
|
||||||
return (
|
return (
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// userType : null, 'teacher', 'student'
|
|
||||||
|
|
||||||
export const userTypeSlice = (set) => ({
|
export const userTypeSlice = (set) => ({
|
||||||
userType: null,
|
userType: null,
|
||||||
setUserType: (userType) => set({ userType }),
|
setUserType: (userType) => set({ userType }),
|
||||||
|
@ -33,16 +33,12 @@ instance.interceptors.response.use(
|
|||||||
.then((response) => {
|
.then((response) => {
|
||||||
const { accessToken } = response.data;
|
const { accessToken } = response.data;
|
||||||
|
|
||||||
console.log(accessToken);
|
|
||||||
useBoundStore.setState({ token: accessToken });
|
useBoundStore.setState({ token: accessToken });
|
||||||
error.config.headers.Authorization = `${accessToken}`;
|
error.config.headers.Authorization = `${accessToken}`;
|
||||||
return instance(error.config);
|
return instance(error.config);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
useBoundStore.setState({ token: null, userType: null });
|
useBoundStore.setState({ token: null, userType: null });
|
||||||
console.log(error);
|
|
||||||
console.log('---로그아웃----');
|
|
||||||
// TODO: redirect to home
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user