Skip to content

Commit

Permalink
Merge pull request #225 from oreumi-dreamer/jihun
Browse files Browse the repository at this point in the history
게시글 수정 기능 구현
  • Loading branch information
jihun-io authored Dec 20, 2024
2 parents d847f57 + c84b100 commit 7a31f36
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 183 deletions.
6 changes: 5 additions & 1 deletion src/components/dropDown/DropDown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import styles from "./DropDown.module.css";
import { fetchWithAuth } from "@/utils/auth/tokenUtils";

export const MyPost = forwardRef(
({ style, togglePostPrivacy, postId, postIsPrivate }, ref) => {
(
{ style, togglePostPrivacy, postId, postIsPrivate, setIsWriteModalOpen },
ref
) => {
async function deletePost() {
try {
const response = await fetchWithAuth(`/api/post/delete/${postId}`, {
Expand All @@ -22,6 +25,7 @@ export const MyPost = forwardRef(
<li className={styles["drop-down-items"]}>
<button
className={`${styles["edit-btn"]} ${styles["drop-down-item"]}`}
onClick={() => setIsWriteModalOpen(true)}
>
수정하기
</button>
Expand Down
11 changes: 11 additions & 0 deletions src/components/main/Post.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MyPost, OtherPost } from "../dropDown/DropDown";
import { outsideClickModalClose } from "@/utils/outsideClickModalClose";
import { Divider, ShareModal } from "../Controls";
import useTheme from "@/hooks/styling/useTheme";
import WritePost from "../write/WritePost";

export default function Post({
styles,
Expand All @@ -17,6 +18,7 @@ export default function Post({
const [isOpen, setIsOpen] = useState(false);
const [modalStyle, setModalStyle] = useState({});
const [shareModalOpen, setShareModalOpen] = useState(false);
const [isWriteModalOpen, setIsWriteModalOpen] = useState(false);
const modalRef = useRef(null);
const buttonRef = useRef(null);
const containerRef = useRef(null);
Expand Down Expand Up @@ -246,6 +248,7 @@ export default function Post({
}}
postId={post.id}
postIsPrivate={post.isPrivate}
setIsWriteModalOpen={setIsWriteModalOpen}
/>
)}
{isOpen && !post.isMyself && (
Expand Down Expand Up @@ -357,6 +360,14 @@ export default function Post({
link={`${baseUrl}/post/${post.id}`}
/>
)}
{isWriteModalOpen && (
<WritePost
key={`${post.id}-modify`}
modifyId={post.id}
isWriteModalOpen={isWriteModalOpen}
closeWriteModal={() => setIsWriteModalOpen(false)}
/>
)}
</>
);
}
12 changes: 12 additions & 0 deletions src/components/post/PostContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import useTheme from "@/hooks/styling/useTheme";
import Loading from "@/components/Loading";
import { outsideClickModalClose } from "@/utils/outsideClickModalClose";
import { useRouter } from "next/navigation";
import PostModal from "../modal/PostModal";
import WritePost from "../write/WritePost";

export default function PostContent({
type,
Expand Down Expand Up @@ -42,6 +44,7 @@ export default function PostContent({
const buttonRef = useRef(null);
const [showConfirmModal, setShowConfirmModal] = useState(false);
const [shareModalOpen, setShareModalOpen] = useState(false);
const [isWriteModalOpen, setIsWriteModalOpen] = useState(false);
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
const router = useRouter();

Expand Down Expand Up @@ -388,6 +391,7 @@ export default function PostContent({
}
postId={postId}
postIsPrivate={postData.isPrivate}
setIsWriteModalOpen={setIsWriteModalOpen}
/>
)}
{isOpen && modalType === "isNotMyPost" && (
Expand Down Expand Up @@ -591,6 +595,14 @@ export default function PostContent({
link={`${baseUrl}/post/${postId}`}
/>
)}
{isWriteModalOpen && (
<WritePost
key={`${postId}-modify`}
isWriteModalOpen={isWriteModalOpen}
closeWriteModal={() => setIsWriteModalOpen(false)}
modifyId={postId}
/>
)}
</>
)}
</>
Expand Down
196 changes: 108 additions & 88 deletions src/components/profile/PostList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fetchWithAuth } from "@/utils/auth/tokenUtils";
import useTheme from "@/hooks/styling/useTheme";
import { MyPost, OtherPost } from "../dropDown/DropDown";
import { outsideClickModalClose } from "@/utils/outsideClickModalClose";
import WritePost from "../write/WritePost";

export default function PostList({
posts,
Expand Down Expand Up @@ -30,6 +31,12 @@ export default function PostList({
};
}
}, [modalRef, buttonRef, isOpen]);

const [isWriteModalOpen, setIsWriteModalOpen] = useState(false);
const closeWriteModal = () => {
setIsWriteModalOpen(false);
};

const togglePostPrivacy = async (postId, postIsPrivate) => {
setIsOpen(false);
try {
Expand Down Expand Up @@ -125,103 +132,116 @@ export default function PostList({
return (
<>
{posts.posts.map((post) => (
<article
className={styles["post-wrap"]}
key={post.id}
onClick={(e) => {
const target = e.target.textContent;
if (
target !== "수정하기" &&
target !== "삭제하기" &&
target !== "공개글로 변경하기" &&
target !== "비밀글로 변경하기" &&
target !== "신고하기"
) {
setSelectedPostId(post.id);
}
}}
>
{post.isTomong && (
<img
src={tomongStampUrl}
className={styles["tomong-stamp"]}
alt="해몽이 존재함"
/>
)}

<h3 className={`${styles["post-title"]}`}>
{post.isPrivate && (
<>
<article
className={styles["post-wrap"]}
key={post.id}
onClick={(e) => {
const target = e.target.textContent;
if (
target !== "수정하기" &&
target !== "삭제하기" &&
target !== "공개글로 변경하기" &&
target !== "비밀글로 변경하기" &&
target !== "신고하기"
) {
setSelectedPostId(post.id);
}
}}
>
{post.isTomong && (
<img
src="/images/lock.svg"
alt="비밀글"
className={styles["private-post"]}
src={tomongStampUrl}
className={styles["tomong-stamp"]}
alt="해몽이 존재함"
/>
)}
{post.title}
</h3>
{post.hasImages && (
<img
src="/images/image.svg"
alt="이미지"
className={styles["include-img"]}
/>
)}
<p className={styles["post-text"]}>{post.content}</p>
<div className={styles["post-btn-container"]}>
<button
onClick={(e) => {
e.stopPropagation(); // article 클릭 이벤트 방지
sparkHandle(post.id);
}}
>
<img
src={
post.hasUserSparked
? "/images/star-fill.svg"
: "/images/star.svg"
}
alt={post.hasUserSparked ? "반짝 취소" : "반짝"}
/>
<span>{post.sparkCount}</span>
</button>
<button onClick={() => setSelectedPostId(post.id)}>
<img src="/images/message.svg" alt="댓글" />
<span>{post.commentsCount}</span>
</button>
{isOpen && modalType === "isMyPost" && activePostId === post.id && (
<MyPost
ref={modalRef}
style={modalStyle}
className={styles["more-modal"]}
postId={post.id}
postIsPrivate={post.isPrivate}
togglePostPrivacy={() =>
togglePostPrivacy(post.id, post.isPrivate)
}
/>
)}
{isOpen &&
modalType === "isNotMyPost" &&
activePostId === post.id && (
<OtherPost
ref={modalRef}
style={modalStyle}
className={styles["more-modal"]}

<h3 className={`${styles["post-title"]}`}>
{post.isPrivate && (
<img
src="/images/lock.svg"
alt="비밀글"
className={styles["private-post"]}
/>
)}
<button>
{post.title}
</h3>
{post.hasImages && (
<img
src="/images/more.svg"
alt="더보기"
ref={buttonRef}
src="/images/image.svg"
alt="이미지"
className={styles["include-img"]}
/>
)}
<p className={styles["post-text"]}>{post.content}</p>
<div className={styles["post-btn-container"]}>
<button
onClick={(e) => {
e.stopPropagation(); // article 클릭 이벤트 방지
handlePostMoreBtnClick(post.id);
sparkHandle(post.id);
}}
/>
</button>
</div>
</article>
>
<img
src={
post.hasUserSparked
? "/images/star-fill.svg"
: "/images/star.svg"
}
alt={post.hasUserSparked ? "반짝 취소" : "반짝"}
/>
<span>{post.sparkCount}</span>
</button>
<button onClick={() => setSelectedPostId(post.id)}>
<img src="/images/message.svg" alt="댓글" />
<span>{post.commentsCount}</span>
</button>
{isOpen &&
modalType === "isMyPost" &&
activePostId === post.id && (
<MyPost
ref={modalRef}
style={modalStyle}
className={styles["more-modal"]}
postId={post.id}
postIsPrivate={post.isPrivate}
togglePostPrivacy={() =>
togglePostPrivacy(post.id, post.isPrivate)
}
setIsWriteModalOpen={setIsWriteModalOpen}
/>
)}
{isOpen &&
modalType === "isNotMyPost" &&
activePostId === post.id && (
<OtherPost
ref={modalRef}
style={modalStyle}
className={styles["more-modal"]}
/>
)}
<button>
<img
src="/images/more.svg"
alt="더보기"
ref={buttonRef}
onClick={(e) => {
e.stopPropagation(); // article 클릭 이벤트 방지
handlePostMoreBtnClick(post.id);
}}
/>
</button>
</div>
</article>
{isWriteModalOpen && (
<WritePost
key={`${post.id}-modify`}
isWriteModalOpen={isWriteModalOpen}
closeWriteModal={closeWriteModal}
modifyId={post.id}
/>
)}
</>
))}
</>
);
Expand Down
16 changes: 13 additions & 3 deletions src/components/write/HashtagModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const HashtagModal = forwardRef(
dialogRef.current.close();
}
}, [isModalOpen]);

const handleBackgroundClick = (e) => {
if (e.target === e.currentTarget) {
onConfirm(selectedGenres);
Expand All @@ -32,14 +33,19 @@ const HashtagModal = forwardRef(
const maxSelect = 5;

const handleCheckboxChange = (item) => {
if (selectedGenres.includes(item)) {
setSelectedGenres((prev) => prev.filter((i) => i !== item));
const isSelected = selectedGenres.some((genre) => genre.id === item.id);

if (isSelected) {
setSelectedGenres((prev) =>
prev.filter((genre) => genre.id !== item.id)
);
} else {
if (selectedGenres.length < maxSelect) {
setSelectedGenres((prev) => [...prev, item]);
}
}
};

const handleConfirm = () => {
onConfirm(selectedGenres);
closeModal();
Expand Down Expand Up @@ -73,7 +79,9 @@ const HashtagModal = forwardRef(
<li key={item.id}>
<input
type="checkbox"
checked={selectedGenres.includes(item)}
checked={selectedGenres.some(
(genre) => genre.id === item.id
)}
onChange={() => handleCheckboxChange(item)}
className={styles["hashtag-picker"]}
id={item.id}
Expand All @@ -93,4 +101,6 @@ const HashtagModal = forwardRef(
}
);

HashtagModal.displayName = "HashtagModal";

export default HashtagModal;
Loading

0 comments on commit 7a31f36

Please sign in to comment.