diff --git a/.prettierrc b/.prettierrc
index 97fcc09..9f47b0b 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -3,6 +3,5 @@
"semi": true,
"useTabs": false,
"tabWidth": 2,
- "trailingComma": "all",
"printWidth": 80
}
diff --git a/src/apis/auth.ts b/src/apis/auth.ts
index 85ca60c..64f2b5f 100644
--- a/src/apis/auth.ts
+++ b/src/apis/auth.ts
@@ -1,4 +1,3 @@
-
// import { BASE_API_URL } from "./const";
import { BASE_API_AUTH_URL } from "./const";
@@ -6,9 +5,9 @@ export async function postSignup(
nickname: string,
username: string,
password1: string,
- password2: string,
+ password2: string
) {
- return fetch(`${BASE_API_AUTH_URL}/auth/register/`, {
+ return fetch(`${BASE_API_AUTH_URL}/auth/token/register/`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -18,9 +17,7 @@ export async function postSignup(
}
export async function postLogin(username: string, password: string) {
-
return fetch(`${BASE_API_AUTH_URL}/auth/token/`, {
-
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -34,9 +31,7 @@ export async function postLogin(username: string, password: string) {
}
export async function getMyUserData(accessToken: string) {
-
return fetch(`${BASE_API_AUTH_URL}/users/mypage/`, {
-
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
@@ -46,24 +41,19 @@ export async function getMyUserData(accessToken: string) {
// 리프레시 토큰 및 엑세스 토큰을 갱신. 자동로그인을 위해 사용
export async function postNewToken() {
-
return fetch(`${BASE_API_AUTH_URL}/auth/token/refresh/new/`, {
-
method: "POST",
credentials: "include",
});
}
export async function postLogout() {
-
return fetch(`${BASE_API_AUTH_URL}/auth/token/logout/`, {
-
method: "POST",
credentials: "include",
});
}
-
export async function getKakaoAutoCallback(code: string | null) {
return fetch(`${BASE_API_AUTH_URL}/auth/kakao/login?code=${code}`);
}
@@ -71,14 +61,12 @@ export async function getKakaoAutoCallback(code: string | null) {
// 카카오 회원탈퇴 기능이 구현되어 있는 엔드포인트이나, 기본 탈퇴 기능도 구현되어 있어서 이 api만 사용
export async function deleteWithDrawalUser(accessToken: string) {
return fetch(`${BASE_API_AUTH_URL}/users/mypage/delete/kakao_unlink/`, {
-
method: "DELETE",
credentials: "include",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
-
}
/*
@@ -91,4 +79,3 @@ export async function deleteWithDrawalUser(accessToken: string) {
},
});
}*/
-
diff --git a/src/apis/comment.ts b/src/apis/comment.ts
new file mode 100644
index 0000000..29fba9c
--- /dev/null
+++ b/src/apis/comment.ts
@@ -0,0 +1,83 @@
+import { BASE_API_URL } from "./const";
+
+// 아직 영화리스트가 없어서 받아보기 어려움
+// type은 추후에 enum으로 수정
+export async function getCommentListRequest(movieCD: string) {
+ return fetch(`${BASE_API_URL}/contents/${movieCD}/comments`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+}
+
+export async function createCommentRequest(
+ movieCD: string,
+ accessToken: string,
+ content: string,
+ has_spoiler: boolean
+) {
+ return fetch(`${BASE_API_URL}/contents/${movieCD}/comments/`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ body: JSON.stringify({
+ content,
+ has_spoiler: has_spoiler,
+ }),
+ });
+}
+
+//특정 코멘트 아이디의 코멘트를 알 수 있다.
+export async function getCommentRequest(commentId: number) {
+ return fetch(`${BASE_API_URL}/comments/${commentId}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ credentials: "include",
+ });
+}
+
+export async function updateCommentRequest(
+ commentId: number,
+ accessToken: string,
+ content: string,
+ hasSpoiler: boolean
+) {
+ return fetch(`${BASE_API_URL}/comments/${commentId}`, {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ credentials: "include",
+ body: JSON.stringify({
+ content,
+ has_spoiler: hasSpoiler,
+ }),
+ });
+}
+
+export async function deleteCommentRequest(id: number, accessToken: string) {
+ return fetch(`${BASE_API_URL}/comments/${id}`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ credentials: "include",
+ });
+}
+
+export async function getCommentReplies(commentId: number) {
+ return fetch(`${BASE_API_URL}/comments/${commentId}/replies`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ credentials: "include",
+ });
+}
diff --git a/src/apis/content.ts b/src/apis/content.ts
new file mode 100644
index 0000000..92b1619
--- /dev/null
+++ b/src/apis/content.ts
@@ -0,0 +1,76 @@
+import { BASE_API_URL } from "./const";
+
+// 아직 영화리스트가 없어서 받아보기 어려움
+// type은 추후에 enum으로 수정
+export async function getContentListRequest(order: string) {
+ return fetch(`${BASE_API_URL}/contents?order=${order}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ credentials: "include",
+ });
+}
+
+export async function getContentRequest(movieCD: string, accessToken?: string) {
+ const headers: HeadersInit = accessToken
+ ? {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ }
+ : {
+ "Content-Type": "application/json",
+ };
+ return fetch(`${BASE_API_URL}/contents/${movieCD}`, {
+ method: "GET",
+ headers,
+ // credentials: "include",
+ });
+}
+
+export async function createRatingRequest(
+ movieCD: string,
+ rate: number,
+ accessToken: string
+) {
+ return fetch(`${BASE_API_URL}/contents/${movieCD}/rate`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ credentials: "include",
+ body: JSON.stringify({
+ rate,
+ }),
+ });
+}
+
+export async function updateRatingRequest(
+ rateId: number,
+ rate: number,
+ accessToken: string
+) {
+ return fetch(`${BASE_API_URL}/contents/rates/${rateId}`, {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ credentials: "include",
+ body: JSON.stringify({
+ rate,
+ }),
+ });
+}
+
+export async function deleteRatingRequest(rateId: number, accessToken: string) {
+ return fetch(`${BASE_API_URL}/contents/rates/${rateId}`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + accessToken,
+ },
+ credentials: "include",
+ });
+}
diff --git a/src/apis/user.ts b/src/apis/user.ts
index c2ea6ba..2ea12b1 100644
--- a/src/apis/user.ts
+++ b/src/apis/user.ts
@@ -1,25 +1,25 @@
// 모두가 접근 가능한 유저페이지에 대한 api
import { BASE_API_URL } from "./const";
-export async function getUserDetail(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/`);
+export async function getUserDetail(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/`);
}
-export async function getFollowingList(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/followings/`);
+export async function getFollowingList(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/followings/`);
}
-export async function getFollowerList(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/followers/`);
+export async function getFollowerList(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/followers/`);
}
-export async function postAddFollow(accessToken: string, id: number) {
+export async function postAddFollow(accessToken: string, userId: number) {
return fetch(`${BASE_API_URL}/users/add/follow/`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
- body: JSON.stringify({ user_id: id }),
+ body: JSON.stringify({ user_id: userId }),
});
}
@@ -41,24 +41,24 @@ export async function getUserLikesComments(id: number) {
}
export async function getUserWrittenComments(
- id: number,
- query: "like" | "created" | "high-rating" | "low-rating" | undefined,
+ userId: number,
+ query?: "like" | "created" | "high-rating" | "low-rating"
) {
if (query === undefined) {
- return fetch(`${BASE_API_URL}/users/${id}/comments/`);
+ return fetch(`${BASE_API_URL}/users/${userId}/comments/`);
}
- return fetch(`${BASE_API_URL}/users/${id}/comments/?order=${query}`);
+ return fetch(`${BASE_API_URL}/users/${userId}/comments/?order=${query}`);
}
-export async function getUserRatings(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/ratings/`);
+export async function getUserRatings(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/ratings/`);
}
-export async function getUserDoings(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/movies/watching/`);
+export async function getUserDoings(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/movies/watching/`);
}
-export async function getUserWishes(id: number) {
- return fetch(`${BASE_API_URL}/users/${id}/movies/want_to_watch/`);
+export async function getUserWishes(userId: number) {
+ return fetch(`${BASE_API_URL}/users/${userId}/movies/want_to_watch/`);
}
/*
diff --git a/src/components/CommentCard.tsx b/src/components/CommentCard.tsx
index e039e17..06f4f6e 100644
--- a/src/components/CommentCard.tsx
+++ b/src/components/CommentCard.tsx
@@ -1,51 +1,50 @@
-import styles from "./CommentCard.module.scss";
+import { CommentType, CommentInUserPageType } from "../type";
-type CommentCardProp = {
- comment: {
- user: {
- img: string;
- name: string;
- };
- reviewRating: number;
- text: string;
- likeCount: number;
- subcommentCount: number;
- };
-};
+import styles from "./CommentCard.module.scss";
+import profileDefault from "../assets/user_default.jpg";
+import { Link } from "react-router-dom";
-export default function CommentCard({ comment }: CommentCardProp) {
+export default function CommentCard({
+ comment,
+}: {
+ comment: CommentType | CommentInUserPageType;
+}) {
return (
-
-
- {comment.user.name}
-
-
-
- {comment.reviewRating}
-
+
+
+ {comment.created_by.nickname}
+
+ {comment.rating && (
+
+
+ {comment.rating}
+
+ )}
- {comment.likeCount}
+ {/* {comment.like_count}*/}
- {comment.subcommentCount}
+ {"replyCount"}
diff --git a/src/components/CommentInfo.tsx b/src/components/CommentInfo.tsx
index 511c564..324de6d 100644
--- a/src/components/CommentInfo.tsx
+++ b/src/components/CommentInfo.tsx
@@ -4,6 +4,7 @@ import styles from "./CommentInfo.module.scss";
import { MovieType } from "./ContentList";
import ReplyList from "./ReplyList";
import elapsedTime from "../utils/elapsedTime";
+import { CommentType } from "../type";
export type ReplyType = {
userName: string;
@@ -13,18 +14,6 @@ export type ReplyType = {
liked: boolean;
};
-type CommentType = {
- userName: string;
- movie: MovieType;
- rating: number;
- content: string;
- date: Date;
- likes: number;
- liked: boolean;
- replyNumber: number;
- replies: ReplyType[];
-};
-
function CommentHeader({
userName,
movie,
@@ -158,19 +147,35 @@ function LikeReplyBar({ liked }: { liked: boolean }) {
);
}
+/*
+{
+ id: number;
+ created_by: {
+ id: number;
+ nickname: string;
+ profile_photo: string | null;
+ };
+ rating: null | string;
+ like_count: number;
+ content: string;
+ has_spoiler: boolean;
+ created_at: string;
+ updated_at: string;
+*/
export default function CommentInfo({ comment }: { comment: CommentType }) {
return (
-
-
-
-
-
+ {" "}
+
+
+
+ */}
);
}
diff --git a/src/components/Content.module.scss b/src/components/Content.module.scss
index dd4505c..aabffd3 100644
--- a/src/components/Content.module.scss
+++ b/src/components/Content.module.scss
@@ -57,9 +57,7 @@
width: 280px;
height: 400px;
margin-bottom: 30px;
- transition:
- width 0.3s,
- height 0.3s;
+ transition: width 0.3s, height 0.3s;
@media (max-width: #{$medium-screen + 100}) {
width: 200px;
@@ -184,109 +182,7 @@
}
}
}
- .userCommentCon {
- width: 100%;
- border-top: 1px solid $light-gray;
- padding: 20px 0;
-
- h3 {
- margin-bottom: 10px;
- line-height: 12px;
- font-size: 12px;
- font-weight: 500;
- }
- .userCommentBox {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- border: solid 1px $light-gray;
- border-radius: 6px;
- padding: 12px 20px;
- background-color: $white;
-
- @media (max-width: $small-screen) {
- flex-direction: column;
- }
-
- .userCommentText {
- width: 100%;
- margin-right: 20px;
- line-height: 20px;
- font-size: 15px;
- font-weight: 400;
- color: $light-black;
- @media (max-width: $small-screen) {
- text-align: center;
- }
- }
- .commentCreateBtn {
- width: 256px;
- height: 40px;
- border: 1px solid $light-gray;
- border-radius: 6px;
- background-color: inherit;
- font-size: 17px;
- font-weight: 500;
- text-align: center;
- color: $dark-black;
- cursor: pointer;
-
- @media (max-width: $small-screen) {
- margin-top: 10px;
- }
- }
- .userImage {
- width: 56px;
- height: 56px;
- margin-right: 20px;
- border: 1px solid $extra-light-gray;
- border-radius: 50%;
-
- @media (max-width: $small-screen) {
- margin-bottom: 10px;
- }
- }
- .commentBtnBox {
- display: flex;
- align-items: center;
-
- button {
- display: flex;
- align-items: center;
- border-style: none;
- padding: 16px 0 13px 0;
- line-height: 16px;
- font-size: 12px;
- font-weight: 400;
- color: $medium-gray;
- background-color: inherit;
- white-space: nowrap;
- cursor: pointer;
-
- img {
- width: 18px;
- height: 18px;
- margin-right: 4px;
- }
- }
- .virtualLineBox {
- display: flex;
- justify-content: center;
- align-items: center;
-
- width: 40px;
- height: 100%;
- .virtualLine {
- width: 1px;
- height: 8px;
- background-color: $medium-gray;
- }
- }
- }
- }
- }
.overviewBox {
min-height: 150px;
padding: 20px 0;
diff --git a/src/components/Content.tsx b/src/components/Content.tsx
index bf31038..9f8af3a 100644
--- a/src/components/Content.tsx
+++ b/src/components/Content.tsx
@@ -1,79 +1,89 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
import styles from "./Content.module.scss";
import { Carousel } from "./Carousel";
import profileDefault from "../assets/user_default.jpg";
import StarRating from "./StarRating";
import CommentCard from "./CommentCard";
+import { CommentsResType, CommentType, ContentType } from "../type";
+// import { convertKeysToCamelCase } from "../utils/snackToCamel";
+import { Link } from "react-router-dom";
+import { defaultResponseHandler } from "../apis/custom";
+import {
+ createCommentRequest,
+ getCommentListRequest,
+ getCommentRequest,
+ updateCommentRequest,
+} from "../apis/comment";
+import MyCommentBox from "./MyCommentBox";
+import WritingModal from "./WritingModal";
+import { useAuthContext } from "../contexts/authContext";
-function ContentHeader() {
- // 임시
- const content = {
- backGroundImg:
- "https://an2-img.amz.wtchn.net/image/v2/Oc4xhq9o4_2YVAmvyR8MFw.jpg?jwt=ZXlKaGJHY2lPaUpJVXpJMU5pSjkuZXlKdmNIUnpJanBiSW1SZk1Ua3lNSGd4TURnd2NUZ3dJbDBzSW5BaU9pSXZkakl2YzNSdmNtVXZhVzFoWjJVdk1UWTNNVFF4T0RJM01UUTBNelE1Tmpnek5pSjkuRlNwNURGdzlQenhIN1BaSmhwWEwweElXR1Z2NUlZYUxjX2dBcWh6X2ZGaw",
- title: "오펜하이머",
- titleEn: "Oppenheimer",
- genre: "2023 스릴러",
- runningTime: "3시간 00분",
- };
-
+function ContentHeader({ content }: { content: ContentType }) {
const backGroundStyle = {
- backgroundImage: `url(${content.backGroundImg})`,
+ backgroundImage: `url(https://an2-ast.amz.wtchn.net/ayg/images/asContentFallbackVideo1.207fd38cdebff49ccde8.jpg)`,
backgroundSize: "cover",
backgroundPosition: "center",
};
+ const genres = content.genres.map((item) => item.genre).join("/");
+ const hours = Math.floor(content.runtime / 60);
+ const remainingMinutes = content.runtime % 60;
+ const runtime =
+ hours > 0 ? `${hours}시간 ${remainingMinutes}분` : `${remainingMinutes}분`;
+
return (
-
-
{content.title}
-
{content.titleEn}
-
{content.genre}
-
{content.runningTime}
-
+ {content && (
+
+
{content.titleKo}
+
{content.titleOriginal}
+
{`${content.releaseDate} · ${genres} · ${content.prodCountry}`}
+
{runtime}
+
+ )}
);
}
-function ContentPanel() {
- const content = {
- posterSrc:
- "https://an2-img.amz.wtchn.net/image/v2/TnfLooyFVulaY3fZhLMNIw.jpg?jwt=ZXlKaGJHY2lPaUpJVXpJMU5pSjkuZXlKdmNIUnpJanBiSW1SZk5Ea3dlRGN3TUhFNE1DSmRMQ0p3SWpvaUwzWXlMM04wYjNKbEwybHRZV2RsTHpFMk9UQTFNRFk1TWpBNU9ERTVNamt5TkRNaWZRLmdfM0lvai1JZGVCbjVFRXhYQ3VFODMwdEN4MnNEa2JKbXV4VEk3QlJPYVE",
- avgRating: 4.0,
- ratingCount: 1000,
- overView: `
- “나는 이제 죽음이요, 세상의 파괴자가 되었다.”
-
- 세상을 구하기 위해 세상을 파괴할 지도 모르는 선택을 해야 하는 천재 과학자의 핵개발 프로젝트.
- `,
- };
- const user = {
- name: "WOOJIN",
- reviewedRating: 2.5,
- comment: "오펜하이머는 얼마나 좋았을까...",
- };
- // 추후에 hook으로 수정
- const [rating, setRating] = useState(2 * user.reviewedRating);
+function ContentPanel({
+ content,
+ setContent,
+}: {
+ content: ContentType;
+ setContent: (content: ContentType) => void;
+}) {
+ const [currentModal, setCurrentModal] = useState<
+ "updateComment" | "createComment" | null
+ >(null);
+
+ const { accessToken } = useAuthContext();
return (
-
+
평점 그래프
보고싶어요
-
+ {
+ // mycommentapi가 있어야함
+
+ setCurrentModal("createComment");
+ }}
+ >
+ {currentModal && accessToken && (
+
+ )}
);
}
-function ContentCast() {
- // 임시
- const cast = {
- img: "https://an2-img.amz.wtchn.net/image/v2/MsLKK8t7W1kQuIr3SztdjQ.jpg?jwt=ZXlKaGJHY2lPaUpJVXpJMU5pSjkuZXlKdmNIUnpJanBiSW1SZk1qUXdlREkwTUNKZExDSndJam9pTDNZeEwzQmxiM0JzWlM5dFpXUnBkVzB2WWpKa016TTRZMll4TmpsbE5qSXpPRGsxTVdRdWFuQm5JbjAuVWJRSHJiR0d0Q2V3WjFvdlFPdEk1ZE5wUnppUHNoc2tCcDE0ZDJGQjhGTQ",
- name: "크리스토퍼 놀란",
- role: "출연",
- };
- const castList = [
- { img: profileDefault, name: "크리스토퍼 놀란", role: "감독" },
- ];
- for (let i = 0; i < 23; i++) castList.push(cast);
-
+function ContentCast({ content }: { content: ContentType }) {
return (
출연/제작
@@ -175,39 +174,43 @@ function ContentCast() {
);
}
-function ContentComments() {
- const comment = {
- user: {
- img: profileDefault,
- name: "이동진",
- },
- reviewRating: 4.5,
- text: `줄리어스 로버트 오펜하이머..
-줄리어스 로버트 오펜하이머..
-자기 이야기가 영화로 만들어진다니.
-로버트는 얼마나 좋았을까.
- `,
- likeCount: 200,
- subcommentCount: 1000,
- };
- const comments = [];
+function ContentComments({ content }: { content: ContentType }) {
+ const [comments, setComments] = useState([]);
+
+ useEffect(() => {
+ getCommentListRequest(content.movieCD)
+ .then(defaultResponseHandler)
+ .then((data: CommentsResType) => {
+ const commentsResponse = data;
+ const comments = commentsResponse.results;
+
+ const repComment =
+ comments.length <= 4 ? comments : comments.slice(0, 4);
+ console.log(repComment);
+ setComments(repComment);
+ })
+ .catch(() => alert("잘못된 요청입니다"));
+ }, [content.movieCD]);
- for (let i = 0; i < 8; i++) {
- comments.push(comment);
- }
return (
코멘트 10000+
- 더보기
+
+ 더보기
+
- {comments.map((comment) => (
-
- ))}
+ {comments.map((comment) => {
+ console.log(comment);
+ return ;
+ })}
diff --git a/src/components/ContentList.tsx b/src/components/ContentList.tsx
index 5d1fe94..3d02121 100644
--- a/src/components/ContentList.tsx
+++ b/src/components/ContentList.tsx
@@ -18,7 +18,7 @@ export type ContentListProps = {
function ContentCell(content: MovieType, rank: number) {
return (
-
+
{rank}
diff --git a/src/components/Modal.module.scss b/src/components/Modal.module.scss
new file mode 100644
index 0000000..83409c3
--- /dev/null
+++ b/src/components/Modal.module.scss
@@ -0,0 +1,14 @@
+@import "../utils/common.module.scss";
+
+.modalContainer {
+ z-index: 100;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx
new file mode 100644
index 0000000..acf5aab
--- /dev/null
+++ b/src/components/Modal.tsx
@@ -0,0 +1,21 @@
+import { ReactNode } from "react";
+import styles from "./Modal.module.scss";
+
+type ModalProps = {
+ onClose: () => void;
+ children: ReactNode;
+};
+
+export default function Modal({ onClose, children }: ModalProps) {
+ const handleClickOutside = (e: React.MouseEvent) => {
+ if (e.target === e.currentTarget) {
+ onClose();
+ }
+ };
+ return (
+
+ {children}
+
+ );
+}
+
\ No newline at end of file
diff --git a/src/components/MyCommentBox.module.scss b/src/components/MyCommentBox.module.scss
new file mode 100644
index 0000000..e4f8443
--- /dev/null
+++ b/src/components/MyCommentBox.module.scss
@@ -0,0 +1,105 @@
+@import "../utils/common.module.scss";
+
+.commentCon {
+ width: 100%;
+ border-top: 1px solid $light-gray;
+ padding: 20px 0;
+
+ h3 {
+ margin-bottom: 10px;
+ line-height: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ }
+ .commentBox {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ border: solid 1px $light-gray;
+ border-radius: 6px;
+ padding: 12px 20px;
+ background-color: $white;
+
+ @media (max-width: $small-screen) {
+ flex-direction: column;
+ }
+
+ .commentText {
+ width: 100%;
+ margin-right: 20px;
+ line-height: 20px;
+ font-size: 15px;
+ font-weight: 400;
+ color: $light-black;
+
+ @media (max-width: $small-screen) {
+ text-align: center;
+ }
+ }
+ .commentCreateBtn {
+ width: 256px;
+ height: 40px;
+ border: 1px solid $light-gray;
+ border-radius: 6px;
+ background-color: inherit;
+ font-size: 17px;
+ font-weight: 500;
+ text-align: center;
+ color: $dark-black;
+ cursor: pointer;
+
+ @media (max-width: $small-screen) {
+ margin-top: 10px;
+ }
+ }
+ .userImage {
+ width: 56px;
+ height: 56px;
+ margin-right: 20px;
+ border: 1px solid $extra-light-gray;
+ border-radius: 50%;
+
+ @media (max-width: $small-screen) {
+ margin-bottom: 10px;
+ }
+ }
+ .commentBtnBox {
+ display: flex;
+ align-items: center;
+
+ button {
+ display: flex;
+ align-items: center;
+ border-style: none;
+ padding: 16px 0 13px 0;
+ line-height: 16px;
+ font-size: 12px;
+ font-weight: 400;
+ color: $medium-gray;
+ background-color: inherit;
+ white-space: nowrap;
+ cursor: pointer;
+
+ img {
+ width: 18px;
+ height: 18px;
+ margin-right: 4px;
+ }
+ }
+ .virtualLineBox {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ width: 40px;
+ height: 100%;
+ .virtualLine {
+ width: 1px;
+ height: 8px;
+ background-color: $medium-gray;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/MyCommentBox.tsx b/src/components/MyCommentBox.tsx
new file mode 100644
index 0000000..45559a7
--- /dev/null
+++ b/src/components/MyCommentBox.tsx
@@ -0,0 +1,84 @@
+import { useAuthContext } from "../contexts/authContext";
+import styles from "./MyCommentBox.module.scss";
+import profileDefault from "../assets/user_default.jpg";
+import { Link } from "react-router-dom";
+import { ContentType, MyCommentType } from "../type";
+import { deleteCommentRequest } from "../apis/comment";
+import { defaultResponseHandler } from "../apis/custom";
+
+export default function MyCommentBox({
+ openModal,
+ content,
+ setContent,
+ closeModal,
+}: {
+ openModal: (type: "updateComment" | "createComment") => void;
+ closeModal: () => void;
+ content: ContentType;
+ setContent: (content: ContentType) => void;
+}) {
+ const { isLogined, myUserData, accessToken } = useAuthContext();
+ const my_comment = content.my_comment;
+ return (
+ isLogined && (
+ <>
+ {my_comment ? (
+
+
내가 쓴 코멘트
+
+
+
+ {my_comment.my_comment}
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+ 대단한 작품이군요! {myUserData?.nickname} 님의 감동을 글로
+ 남겨보세요
+
+
+
+
+ )}
+ >
+ )
+ );
+}
diff --git a/src/components/StarRating.tsx b/src/components/StarRating.tsx
index f7c9044..08bb4e4 100644
--- a/src/components/StarRating.tsx
+++ b/src/components/StarRating.tsx
@@ -1,5 +1,13 @@
import { useState } from "react";
import styles from "./StarRating.module.scss";
+import { RateType } from "../type";
+import {
+ createRatingRequest,
+ deleteRatingRequest,
+ updateRatingRequest,
+} from "../apis/content";
+import { defaultResponseHandler } from "../apis/custom";
+import { useAuthContext } from "../contexts/authContext";
type StarProps = {
fill: "full" | "half" | "empty";
@@ -19,9 +27,9 @@ function Star(props: StarProps) {
onMouseEnterStar(rating + 1)}
+ onMouseOver={() => onMouseEnterStar(rating + 0.5)}
onMouseLeave={onMouseLeaveStar}
- onClick={() => onClickStar(rating + 1)}
+ onClick={() => onClickStar(rating + 0.5)}
>
onMouseEnterStar(rating + 2)}
+ onMouseOver={() => onMouseEnterStar(rating + 1)}
onMouseLeave={onMouseLeaveStar}
- onClick={() => onClickStar(rating + 2)}
+ onClick={() => onClickStar(rating + 1)}
>