Skip to content

Commit

Permalink
Merge pull request #48 from Happy-Dreaming/feature/24
Browse files Browse the repository at this point in the history
[#24] 꿈 일기 api 연결
  • Loading branch information
MyungJiwoo authored Apr 10, 2024
2 parents 00125d9 + e43f862 commit bfa22b1
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 133 deletions.
2 changes: 1 addition & 1 deletion app/api/service/diary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const patchDiary = async (
};

// [delete] 일기 삭제하기
export const deleteDiary = async (diaryId: number) => {
export const deleteDiary = async (diaryId: string) => {
try {
const response = await axios({
method: "DELETE",
Expand Down
334 changes: 202 additions & 132 deletions app/read/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,148 +1,218 @@
'use client';
"use client";

import React, { ChangeEvent, FormEvent, useState } from 'react';
import styles from './read.module.css';
import Comment from '../../components/Comment/Comment';
import { usePathname, useRouter } from 'next/navigation';
import React, { ChangeEvent, FormEvent, useEffect, useState } from "react";
import styles from "./read.module.css";
import Comment from "../../components/Comment/Comment";
import { usePathname, useRouter } from "next/navigation";

import { BsHeartFill } from 'react-icons/bs';
import { BsChatDotsFill } from 'react-icons/bs';
import { useAxios } from '../../hooks/useAxios';
import { postComment } from '../../api/service/comment';
import { axiosInstance } from '../../lib/api';
import { BsHeartFill } from "react-icons/bs";
import { BsChatDotsFill } from "react-icons/bs";
import { useAxios } from "../../hooks/useAxios";
import { postComment } from "../../api/service/comment";
import { axiosInstance } from "../../lib/api";
import { UserProps } from "../../diary/page";
import { getUser } from "../../api/service/user";
import { deleteDiary } from "../../api/service/diary";

interface Like {
id: string;
id: string;
}
interface Comment {
id: string;
comment: string;
writerId: string;
writerName: string;
writerPicture: string;
created_At: string;
updated_At: string;
diaryId: string;
id: string;
comment: string;
writerId: string;
writerName: string;
writerPicture: string;
created_At: string;
updated_At: string;
diaryId: string;
}
export interface ReadProps {
comments: Comment[];
contents: string;
created_At: string;
id: string;
likes: number;
isShare: boolean;
like: Like[];
title: string;
updated_At: string;
writerId: string;
writerName: string;
writerPicture: string;
comments: Comment[];
contents: string;
created_At: string;
id: string;
likes: number;
isShare: boolean;
like: Like[];
title: string;
updated_At: string;
writerId: string;
writerName: string;
writerPicture: string;
}

function ReadPage() {
const router = useRouter();
const pathname = usePathname().slice(6);

// 댓글
const [inputComment, setInputComment] = useState('');
const [saveComment, setSaveComment] = useState('');

const handleInputComment = (event: ChangeEvent<HTMLInputElement>) => {
setInputComment(event.target.value);
};

const comment = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setInputComment(inputComment);
// [api] 댓글 post 요청
await postComment(pathname, inputComment);
window.location.reload();
};

// [api] 모든 꿈 일기 get 요청
const { data, error, loading } = useAxios<ReadProps>(
`/api/diary/${pathname}`,
'get',
{},
{}
);
console.log(data);

const handleClickBsHeart = async () => {
await axiosInstance.post('/api/diary/like', {
diaryId: data?.id + '',
});
alert('완');
window.location.reload();
};

return (
<div className={styles.container}>
<div className={styles.postBox}>
<div className={styles.postHeaderBox}>
<p className={styles.postWriter}>{data?.writerName}</p>
{/* 작성자에게만 보이는 버튼 */}
<div className={styles.postBtns}>
<div className={styles.postEditBtn}>수정</div>
<div className={styles.postDelBtn}>삭제</div>
</div>
</div>
<div className={styles.postTitle}>{data?.title}</div>
<div className={styles.postContent}>{data?.contents}</div>
<div className={styles.postFooterBox}>
<div className={styles.postReactionBox}>
<BsHeartFill />
<p className={styles.postLike}>{data?.likes}</p>
<BsChatDotsFill />
<p className={styles.postComment}>{data?.comments.length}</p>
</div>
<p className={styles.postDate}>{data?.updated_At}</p>
</div>
</div>

{/* 댓글 컴포넌트 */}
<div className={styles.commentBox}>
{data?.comments && data?.comments?.length > 0
? data?.comments.map((c, index) => (
<Comment
key={c.id}
id={c.id}
comment={c.comment}
created_At={c.created_At}
diaryId={c.diaryId}
updated_At={c.updated_At}
writerId={c.writerId}
writerName={c.writerName}
writerPicture={c.writerPicture}
/>
))
: null}
</div>

{/* 리액션바 : 좋아요, 댓글 */}
{data?.isShare ? (
<div className={styles.reactionBarBg}>
<div className={styles.reactionBarBox}>
<div className={styles.reactionLike} onClick={handleClickBsHeart}>
<BsHeartFill className={styles.reactionLikeIcon} />
const router = useRouter();
const pathname = usePathname().slice(6);
const [user, setUser] = useState<UserProps[]>([]);
const [owner, setOwner] = useState<boolean>(false);

// 댓글
const [inputComment, setInputComment] = useState("");
const [saveComment, setSaveComment] = useState("");

const handleInputComment = (event: ChangeEvent<HTMLInputElement>) => {
setInputComment(event.target.value);
};

const comment = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setInputComment(inputComment);
// [api] 댓글 post 요청
await postComment(pathname, inputComment);
window.location.reload();
};

// [api] 모든 꿈 일기 get 요청
const { data, error, loading } = useAxios<ReadProps>(
`/api/diary/${pathname}`,
"get",
{},
{}
);

// [api] 좋아요
const handleClickBsHeart = async () => {
await axiosInstance.post("/api/diary/like", {
diaryId: data?.id + "",
});
alert("좋아요가 반영되었습니다.");
window.location.reload();
};

// [api] 글 삭제
const handlePostDel = (event: React.MouseEvent<HTMLDivElement>) => {
const isConfirmed = window.confirm("글을 삭제하시겠습니까?");

if (isConfirmed) {
deleteDiary(pathname);
router.back();
}
};

// [api] 글 수정
const handlePostPatch = (event: React.MouseEvent<HTMLDivElement>) => {
// const isConfirmed = window.confirm("글을 삭제하시겠습니까?");
// if (isConfirmed) {
// deleteDiary(pathname);
// router.back();
// }
};

// [api] 로그인한 유저 정보 get 요청
useEffect(() => {
const checkOwner = async () => {
try {
const userData = await getUser(); // 로그인한 유저 정보 get 요청
console.log(userData);
// 여기서 data?.writerName은 API로부터 받은 꿈 일기의 작성자 이름을 가리킵니다.
// userData.user.name은 로그인한 유저의 이름입니다.
// 이 두 값을 비교하여 owner 상태를 업데이트합니다.
if (data?.writerName && userData.user) {
setOwner(userData.user.name === data.writerName);
console.log(userData.user.name === data.writerName);
}
setUser(userData.user);
} catch (error) {
console.error("유저 정보를 불러오는데 실패했습니다.", error);
}
};

if (data) {
checkOwner(); // data가 있을 때만 checkOwner 함수를 호출합니다.
}
}, [data]); // 의존성 배열에 data를 추가하여, data가 변경될 때마다 이 useEffect가 실행되도록 합니다.

return (
<div className={styles.container}>
<div className={styles.postBox}>
<div className={styles.postHeaderBox}>
<p className={styles.postWriter}>{data?.writerName}</p>
{/* 작성자에게만 보이는 버튼 */}
{owner ? (
<>
<div className={styles.postBtns}>
<div
className={styles.postEditBtn}
onClick={handlePostPatch}
>
수정
</div>
<div
className={styles.postDelBtn}
onClick={handlePostDel}
>
삭제
</div>
</div>
</>
) : null}
</div>
<div className={styles.postTitle}>{data?.title}</div>
<div className={styles.postContent}>{data?.contents}</div>
<div className={styles.postFooterBox}>
<div className={styles.postReactionBox}>
<BsHeartFill />
<p className={styles.postLike}>{data?.likes}</p>
<BsChatDotsFill />
<p className={styles.postComment}>
{data?.comments.length}
</p>
</div>
<p className={styles.postDate}>{data?.updated_At}</p>
</div>
</div>

{/* 댓글 컴포넌트 */}
<div className={styles.commentBox}>
{data?.comments && data?.comments?.length > 0
? data?.comments.map((c, index) => (
<Comment
key={c.id}
id={c.id}
comment={c.comment}
created_At={c.created_At}
diaryId={c.diaryId}
updated_At={c.updated_At}
writerId={c.writerId}
writerName={c.writerName}
writerPicture={c.writerPicture}
/>
))
: null}
</div>
<form onSubmit={comment} className={styles.commentBarForm}>
<input
type="text"
placeholder="여기에 댓글을 입력하세요."
value={inputComment}
onChange={handleInputComment}
className={styles.commentBar}
/>
<button type="submit" className={styles.submitBtn}>
저장
</button>
</form>
</div>

{/* 리액션바 : 좋아요, 댓글 */}
{data?.isShare ? (
<div className={styles.reactionBarBg}>
<div className={styles.reactionBarBox}>
<div
className={styles.reactionLike}
onClick={handleClickBsHeart}
>
<BsHeartFill className={styles.reactionLikeIcon} />
</div>
<form
onSubmit={comment}
className={styles.commentBarForm}
>
<input
type="text"
placeholder="여기에 댓글을 입력하세요."
value={inputComment}
onChange={handleInputComment}
className={styles.commentBar}
/>
<button type="submit" className={styles.submitBtn}>
저장
</button>
</form>
</div>
</div>
) : null}
</div>
) : null}
</div>
);
);
}

export default ReadPage;

0 comments on commit bfa22b1

Please sign in to comment.