Skip to content

Commit

Permalink
Feature: #128
Browse files Browse the repository at this point in the history
Feature: #128 ๋ฆฌ๋ทฐ ์ˆ˜์ •, ์‚ญ์ œ ์—๋Ÿฌ ๊ด€๋ จ
  • Loading branch information
hwi-woong committed Mar 11, 2024
1 parent a030104 commit 073621c
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 83 deletions.
95 changes: 53 additions & 42 deletions src/components/MovieModal/MyWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,23 @@ const MyWrite = ({ programId }) => {
setMyReviews([...myReviews, newReview]); // ์ด์ „ ๋ฆฌ๋ทฐ ๋ฐฐ์—ด์— ์ƒˆ๋กœ์šด ๋ฆฌ๋ทฐ ์ถ”๊ฐ€
};

// ๋ฆฌ๋ทฐ๋ฅผ ์‚ญ์ œํ•˜๋Š” ํ•จ์ˆ˜
const handleDeleteReview = async (id) => {
try {
await axios.delete(`http://52.79.200.90:8080/api/v1/review/${id}`);
const updatedReviews = myReviews.filter((review) => review.id !== id);
setMyReviews(updatedReviews); // ์‚ญ์ œ๋œ ๋ฆฌ๋ทฐ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋ฆฌ๋ทฐ๋กœ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
} catch (error) {
console.error("Deleting review failed", error);
}
};
const handleDeleteReview = async (id) => {
try {
const userConfirmed = window.confirm("๋ฆฌ๋ทฐ๋ฅผ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?");

if (userConfirmed) {
// ์‚ฌ์šฉ์ž๊ฐ€ ํ™•์ธ์„ ๋ˆŒ๋ €์„ ๋•Œ๋งŒ ์‚ญ์ œ ์ž‘์—… ์ˆ˜ํ–‰
await axios.delete(`http://52.79.200.90:8080/api/v1/review/${id}`);
const updatedReviews = myReviews.filter((review) => review.id !== id);
setMyReviews(updatedReviews); // ์‚ญ์ œ๋œ ๋ฆฌ๋ทฐ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋ฆฌ๋ทฐ๋กœ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
} else {
console.log("User canceled deletion.");
}
} catch (error) {
console.error("Deleting review failed", error);
}
};


// ๋ฆฌ๋ทฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ํŽธ์ง‘ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜
const handleEditClick = (id) => {
Expand All @@ -64,6 +71,7 @@ const handleDeleteReview = async (id) => {

// ์ˆ˜์ • ์ค‘์ธ ๋ฆฌ๋ทฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ํŽธ์ง‘ ์ƒํƒœ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ํ•จ์ˆ˜
const handleEditReview = async (id, editedReview) => {
// const accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcwOTk3NjQ3MCwiZW1haWwiOiJtYXR0bmF2ZXJAZ21haWwuY29tIn0.kWUZjTMbqP6YzKsfnkJJvR_Dt0JkgX6-5uixemDDsPszzY1WbispSlo898lFTNnJqoTkzV_IEhm6IWjb0nnAJA";
try {
// API ์š”์ฒญ์„ ํ†ตํ•ด ๋ฆฌ๋ทฐ ์ˆ˜์ •
await axios.put(`http://52.79.200.90:8080/api/v1/review/${id}`, {
Expand Down Expand Up @@ -92,40 +100,43 @@ const handleEditReview = async (id, editedReview) => {
<WriteReview handleWriteReviewSubmit={handleWriteReviewSubmit} />

{/* ์ด์ „์— ์ž‘์„ฑํ•œ ๋ฆฌ๋ทฐ ๋ฆฌ์ŠคํŠธ */}
{myReviews.map((review) => (
<div key={review.id} className="my-review">
<ReviewItem
author={review.author}
profileimg={review.profileimg}
movie={review.movie}
tag={review.tag}
content={editReview && editReview.id === review.id ? (
<div>
<input
type="text"
value={editReview.content}
onChange={(e) =>
setEditReview({ ...editReview, content: e.target.value })
}
/>
<button onClick={() => handleEditReview(editReview.id, editReview)}>
์ €์žฅ
</button>
</div>
) : (
review.content
)}
created_date={review.created_date}
evaluation={review.evaluation}
favorite={review.favorite}
id={review.id}
// ๋ฆฌ๋ทฐ ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ถ€๋ถ„
{myReviews.map((review) => (
<div key={review.id} className="my-review">
<ReviewItem
author={review.author}
profileimg={review.profileimg}
movie={review.movie}
tag={review.tag}
content={
editReview && editReview.id === review.id ? (
<div>
<textarea
value={editReview.content}
onChange={(e) =>
setEditReview({ ...editReview, content: e.target.value })
}
/>
<div className="review-buttons">
<button onClick={() => handleDeleteReview(review.id)}>์‚ญ์ œ</button>
<button onClick={() => handleEditClick(review.id)}>์ˆ˜์ •</button>
</div>
<button onClick={() => handleEditReview(editReview.id, editReview)}>
์ €์žฅ
</button>
</div>
))}
) : (
review.content
)
}
created_date={review.created_date}
evaluation={review.evaluation}
favorite={review.favorite}
id={review.id}
/>
<div className="review-buttons">
<button onClick={() => handleDeleteReview(review.id)}>์‚ญ์ œ</button>
<button onClick={() => handleEditClick(review.id)}>์ˆ˜์ •</button>
</div>
</div>
))}

</div>
</div>
);
Expand Down
109 changes: 68 additions & 41 deletions src/components/MovieModal/ReviewItem.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from "react";
import axios from "axios"; // axios import
import "./DetailReview.css";
import star from "./star1.png";
import thumb from "./thumb_up.png";
Expand All @@ -9,67 +10,93 @@ const ReviewItem = ({
like,
localDateTime,
ratings,
reviewId,
reviewTagNames,
userNickName,
userPosterPath,
}) => {
const [likes, setLikes] = useState(like); // ์ข‹์•„์š” ๊ฐœ์ˆ˜๋ฅผ ์ƒํƒœ๋กœ ๊ด€๋ฆฌ
const handleLike = () => {
setLikes(likes + 1); // ์ข‹์•„์š” ๊ฐœ์ˆ˜๋ฅผ 1 ์ฆ๊ฐ€์‹œํ‚ด
// TODO: ์„œ๋ฒ„์— ์ข‹์•„์š” ๊ฐœ์ˆ˜ ์—…๋ฐ์ดํŠธ ์š”์ฒญ ๋“ฑ์˜ ๋กœ์ง ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
const [likes, setLikes] = useState(like);
const [content, setContent] = useState(contents); // ์ปจํ…์ธ  ์ƒํƒœ ๊ด€๋ฆฌ

const handleLike = async () => {
// ์˜ˆ์‹œ URL ๋ฐ ๋ฉ”์†Œ๋“œ, ์‹ค์ œ ๊ตฌํ˜„์— ๋งž๊ฒŒ ์กฐ์ •ํ•ด์•ผ ํ•จ
try {
const response = await axios.post(`http://52.79.200.90:8080/api/v1/review/${id}/like`);
if (response.status === 200) {
setLikes(likes + 1); // ์„ฑ๊ณต ์‘๋‹ต ์‹œ์—๋งŒ ์ข‹์•„์š” ์ˆ˜ ์ฆ๊ฐ€
}
} catch (error) {
console.error("์ข‹์•„์š” ์—…๋ฐ์ดํŠธ ์‹คํŒจ:", error);
}
};

// ์˜ฌ๋ฐ”๋ฅธ ์‚ญ์ œ ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ
const handleDelete = async (reviewId) => {
const accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcwOTk3NjQ3MCwiZW1haWwiOiJtYXR0bmF2ZXJAZ21haWwuY29tIn0.kWUZjTMbqP6YzKsfnkJJvR_Dt0JkgX6-5uixemDDsPszzY1WbispSlo898lFTNnJqoTkzV_IEhm6IWjb0nnAJA"
if (window.confirm("๋ฆฌ๋ทฐ๋ฅผ ์ •๋ง ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?")) {
try {
await axios.delete(`http://52.79.200.90:8080/api/v1/review/${reviewId}`, {
headers: {
'Authorization': `Bearer ${accessToken}`, // accessToken ๋ณ€์ˆ˜์— ๋‹ด๊ธด ๊ฐ’์„ ์‚ฌ์šฉ
},
});
// ์‚ญ์ œ ํ›„ UI ์ฒ˜๋ฆฌ๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•จ
} catch (error) {
console.error(error);
}
}
};

const handleEdit = async () => {
const newContents = prompt("๋ฆฌ๋ทฐ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜์„ธ์š”", content);
const accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcwOTk3NjQ3MCwiZW1haWwiOiJtYXR0bmF2ZXJAZ21haWwuY29tIn0.kWUZjTMbqP6YzKsfnkJJvR_Dt0JkgX6-5uixemDDsPszzY1WbispSlo898lFTNnJqoTkzV_IEhm6IWjb0nnAJA"
if (newContents !== null && newContents !== content) {
try {
await axios.put(
`http://52.79.200.90:8080/api/v1/review/${id}`,
{ contents: newContents },
{
headers: {
'Authorization': `Bearer ${accessToken}`, // accessToken ๋ณ€์ˆ˜์— ๋‹ด๊ธด ๊ฐ’์„ ์‚ฌ์šฉ
},
}
);
setContent(newContents); // ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋กœ UI ๋ฐ˜์˜
} catch (error) {
console.error(error);
}
}
};

// ๋‚ ์งœ ์ฒ˜๋ฆฌ ๋กœ์ง์€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€
const targetDate = new Date(localDateTime);
const currentDate = new Date();
const timeDiff = currentDate - targetDate;
// ๋ฐ€๋ฆฌ์ดˆ๋ฅผ ์ผ๋กœ ๋ณ€ํ™˜
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));

let displayDate;
if (daysDiff < 30) {
displayDate = `${daysDiff}์ผ ์ „`;
displayDate = `${daysDiff}์ผ ์ „`;
} else if (daysDiff < 365) {
const monthsDiff = Math.floor(daysDiff / 30);
displayDate = `${monthsDiff}๋‹ฌ ์ „`;
const monthsDiff = Math.floor(daysDiff / 30); // ์—ฌ๊ธฐ๋กœ ์ด๋™
displayDate = `${monthsDiff}๋‹ฌ ์ „`;
} else {
const yearsDiff = Math.floor(daysDiff / 365);
displayDate = `${yearsDiff}๋…„ ์ „`;
const yearsDiff = Math.floor(daysDiff / 365); // ์—ฌ๊ธฐ๋กœ ์ด๋™
displayDate = `${yearsDiff}๋…„ ์ „`;
}

return (
<div className="ReviewItem" style={{ backgroundColor: "var(--neutral2)" }}>
<div className="reviewInfo">
<div className="writerInfo">
<img
src={userPosterPath}
className="writer_profile"
alt="ํ”„๋กœํ•„ ์ด๋ฏธ์ง€"
></img>
<span className="writer">{userNickName}๋‹˜์˜ ํ‰๊ฐ€</span>
</div>
<span className="writeDate">{displayDate}</span>
{/* ๊ธฐ์กด UI ์ฝ”๋“œ ์œ ์ง€ */}
<div className="reviewContent">{content}</div>
<div className="reviewActions">
<button onClick={handleEdit}>์ˆ˜์ •</button>
<button onClick={() => handleDelete(id)}>์‚ญ์ œ</button>
</div>

<div className="reviewMain">
<div className="reviewPick">
<img src={star} className="star" alt="๋ณ„์ "></img>
<span className="reviewNum">{ratings}</span>
<div className="tags">
{reviewTagNames.map((tag, index) => (
<span key={index} className={`tag_${index + 1}`}>
{tag}
</span>
))}
</div>
</div>
<div className="reviewContent">{contents}</div>
<div className="reviewFavorite">
<button onClick={handleLike}>
<img src={thumb} className="reviewthumb" alt="์ข‹์•„์š”"></img>
</button>
<span className="thumbNum">{likes}</span>
</div>
<div className="reviewFavorite">
<button onClick={handleLike}>
<img src={thumb} className="reviewthumb" alt="์ข‹์•„์š”"></img>
</button>
<span className="thumbNum">{likes}</span>
</div>
</div>
);
Expand Down

0 comments on commit 073621c

Please sign in to comment.