Skip to content

Commit

Permalink
[Feat]피드페이지 좋아요 기능 (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
nebulaBdj committed Dec 4, 2023
1 parent ddcf636 commit ea60549
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 30 deletions.
23 changes: 22 additions & 1 deletion src/app/feed/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,37 @@ import WeatherBar from "@/component/WeatherBar";
import FeedCategory from "@/component/FeedCategory";
import FeedContenets from "@/component/FeedContents";
import Menubar from "@/component/MenuBar";
import jwt from "jsonwebtoken";
import Cookies from "js-cookie";

import { RecoilRoot } from "recoil";
import { RecoilRoot, useRecoilState } from "recoil";
import { useEffect } from "react";
import axios from "axios";

import '../../style/feed.scss';

import { FeedDecodeNickname } from "@/recoilAtom/FeedNickname";
import { FeedLoginToken } from "@/recoilAtom/FeedLoginToken";


export default function Feed(){
const [decodeNick, setNick] = useRecoilState(FeedDecodeNickname);
const [loginToken_feed, setFeedToken] = useRecoilState(FeedLoginToken);

useEffect(()=>{
const accessToken = Cookies.get("accessToken");
// console.log("accessToken 값: ", accessToken);
const decodedToken = accessToken
? (jwt.decode(accessToken) as { [key: string]: any })
: null;
const decoded_nickName = decodedToken?.sub;
// console.log("디코딩", decodedToken);
console.log("디코딩 닉네임", decoded_nickName);

setFeedToken(accessToken);
setNick(decoded_nickName);

},[])

return(<>
{/* <RecoilRoot> */}
Expand Down
2 changes: 1 addition & 1 deletion src/component/FeedCateDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default function FeedcateDetail( { categorytitle, setControl } : PROPS) {

//선택한 카테고리 useRecoilState 배열에 넣기
const cate_btn = ( btnval: string ) => {
console.log(btnval);
// console.log(btnval);
console.log("현재 카테고리", categorytitle)

//btnval값이 배열에 존재하지 않을때만 push
Expand Down
2 changes: 1 addition & 1 deletion src/component/FeedCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default function FeedCategory(){
}
}

console.log(tab_control);
// console.log(tab_control);

const tem_btn = () => {
if(tab_control == false) {
Expand Down
90 changes: 67 additions & 23 deletions src/component/FeedContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useRecoilState } from "recoil";
import { FeedContent } from "@/recoilAtom/FeedContents";
import { TemMaxControl } from "@/recoilAtom/TemMax";
import { TemMinControl } from "@/recoilAtom/TemMin";
import { FeedDecodeNickname } from "@/recoilAtom/FeedNickname";
import { FeedLoginToken } from "@/recoilAtom/FeedLoginToken";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
Expand All @@ -16,10 +18,16 @@ interface IMAGE {
imageUrl: string;
}

interface LIKE {
likeId : number;
nickName: string;
}

interface FEEDATA {
boardId: number;
images: IMAGE;
likeCount: number;
likelist: LIKE[];
nickName: string;
temperature: number;
weather: string;
Expand All @@ -29,8 +37,9 @@ interface FEEDATA {
export default function FeedContents() {
const [max, setMax] = useRecoilState(TemMaxControl);
const [min, setMin] = useRecoilState(TemMinControl);

const [feedata, setFeedd] = useRecoilState(FeedContent);
const [decodeNick, setNick] = useRecoilState(FeedDecodeNickname);
const [loginToken_feed, setFeedToken] = useRecoilState(FeedLoginToken);

const router = useRouter();

Expand All @@ -44,6 +53,8 @@ export default function FeedContents() {

console.log("받아온 데이터", req.data);

//현재 로그인한 닉네임과 각 게시물의 likelist에 같은 닉네임이 있다면

const copy: FEEDATA[] = req.data;

console.log("카피", copy);
Expand Down Expand Up @@ -71,29 +82,56 @@ export default function FeedContents() {
// // setFeedd(filter_feedata);
}, [max, min, setFeedd]);

const heart_plus = async (board_id: number) => {
console.log("리코일스테이트로 잘 들어왔는지 확인", feedata);
console.log("하트 누른 피드의 boardId", board_id);



const updateLikeStatus = async (boardId : number) => {
const url = `https://www.jerneithe.site/board/like/${boardId}`;

try {
await axios({
method: "post",
url: url,
headers: { Authorization: "Bearer " + loginToken_feed },
});
} catch (error) {
console.error("좋아요 변경 실패:", error);
}
};

//임시 하트 증가
// setFeedd((prev) => {
// const newFeed = prev.map((myarr) => {
// if (myarr.boardId === board_id) {
// return { ...myarr, likeCount: myarr.likeCount + 1 };
// }
// return myarr;
const heart_plus = async (board_id: number, isLiked:boolean) => {
console.log("하트 누른 피드의 boardId", board_id);
console.log("피드 상위에서 받아온 토큰", loginToken_feed);

await updateLikeStatus(board_id);

setFeedd((prev) => {
const newFeed = prev.map((myarr) => {
if (myarr.boardId === board_id) {
const isLiked = isUserLiked(myarr.likelist, decodeNick);
return {
...myarr,
likeCount: isLiked ? myarr.likeCount - 1 : myarr.likeCount + 1,
likelist: isLiked
? myarr.likelist.filter((like) => like.nickName !== decodeNick)
: decodeNick // decodeNick이 undefined가 아닐 때만 추가
? [...myarr.likelist, { likeId: -1, nickName: decodeNick }]
: myarr.likelist,
};
}
return myarr;
});
return newFeed;
});

// try {
// await axios({
// method: "post",
// url: `https://www.jerneithe.site/board/like/${board_id}`,
// headers: { Authorization: "Bearer " + loginToken_feed },
// });
// return newFeed;
// });

//갱신된 데이터 보내야함
//이름 유형 필수/선택
//boardId int 필수
//userId string 필수
// } catch (error) {
// console.error("좋아요 실패:", error);
// }


};

const goDetail = async (board_id: number) => {
Expand All @@ -102,6 +140,11 @@ export default function FeedContents() {
router.push('/detail');
};

const isUserLiked = (likelist:LIKE[], userNickname:string | undefined) => {
return likelist.some((like) => like.nickName === userNickname);
// some: 위의 조건을 만족할 경우 순회를 중단 한다 즉, true 값을 리턴한다.
// 만족 못한다면 false를 보냄
};

console.log("리코일스테이트로 잘 들어왔는지 확인", feedata);

Expand All @@ -110,6 +153,7 @@ export default function FeedContents() {
<div className="feed_box">
{feedata ? (
feedata.map((arr) => {
const isLiked = isUserLiked(arr.likelist, decodeNick);
return (
<div className="feed" key={arr.boardId}>
<div
Expand All @@ -130,9 +174,9 @@ export default function FeedContents() {
<div id="name_like">
<p id="nickName_feed">@{arr.nickName}</p>
<div id="like_feed_dj">
<button onClick={() => heart_plus(arr.boardId)}>
<button onClick={() => heart_plus(arr.boardId, isLiked)}>
<Image
src="/images/likeuseFeed.svg"
src={isLiked ? "/images/like.svg" : "/images/unLike.svg"}
alt="좋아요"
width={25}
height={25}
Expand Down
2 changes: 1 addition & 1 deletion src/component/FeedSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default function FeedSearch(){

//req 데이터 형식 확인 후 setFeedd로 데이터 넣기

console.log(req.data);
// console.log(req.data);
setFeedd(req.data);
}

Expand Down
4 changes: 2 additions & 2 deletions src/component/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default function LoginForm() {
// console.error(error);
// }
window.location.href =
"https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=453423602833-7db2b1dbicre47rkcrpfgn20nd16l9rs.apps.googleusercontent.com&scope=email&state=FnOs2B9peyHie3pfwVOFMaqIFqlifucO4v6jmFPEc_M%3D&redirect_uri=http://localhost:3000/socialregister";

// "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=453423602833-7db2b1dbicre47rkcrpfgn20nd16l9rs.apps.googleusercontent.com&scope=email&state=FnOs2B9peyHie3pfwVOFMaqIFqlifucO4v6jmFPEc_M%3D&redirect_uri=http://localhost:3000/socialregister";
"https://accounts.google.com/o/oauth2/v2/auth?client_id=453423602833-7db2b1dbicre47rkcrpfgn20nd16l9rs.apps.googleusercontent.com&redirect_uri=http://localhost:3000/socialregister&response_type=token&scope=email";
};

const handleLogin = async (e: FormEvent) => {
Expand Down
68 changes: 68 additions & 0 deletions src/component/MainWeather.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,72 @@
import { useEffect, useState } from "react";

export default function MainWeather() {
const API_KEY = "fa3eba61f243af3e8e69086462763172";
const kakao_API_KEY = "3a6c3035c801405eaa71ebb9dc7f474b";
const [usetemp, setTemp] = useState<string | undefined>();
const [max, setMax] = useState<string | undefined>();
const [min, setMin] = useState<string | undefined>();
const [weat, setWeat] = useState<string | undefined>();
const [address, setAddress] = useState<string | undefined>();

useEffect(() => {
// 위치 정보를 비동기적으로 가져오는 함수
const getLocation = async () => {
try {
const position = await new Promise<GeolocationPosition>(
(resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
},
);

const latitude = position.coords.latitude;
// console.log("위도", latitude);
const longitude = position.coords.longitude;
// console.log("경도", longitude);

const weatherResponse = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`,
);
const weatherData = await weatherResponse.json();
setTemp(weatherData.main.temp.toFixed(1));
setMax(weatherData.main.temp_max.toFixed(1));
setMin(weatherData.main.temp_min.toFixed(1));
setWeat(weatherData.weather[0].main);

console.log("데이터", weatherData);
// console.log(`온도 : ${temp} ,최고온도 ${max},최저온도 ${min}, 날씨 : ${weat}`);


const addressResponse = await fetch(
`https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${longitude}&y=${latitude}`,
{
method: "GET",
headers: { Authorization: `KakaoAK ${kakao_API_KEY}` },
},
);
const addressData = await addressResponse.json();
setAddress(
addressData.documents[0].address.region_1depth_name +
" " +
addressData.documents[0].address.region_2depth_name,
);

// console.log(address);
} catch (error) {
console.error("Error getting location:", error);
}
};

getLocation(); // getLocation 함수 실행
}, []);

console.log("현재온도", usetemp);
console.log("최고온도", max);
console.log("최저온도", min);
console.log("날씨", weat);



return (
<div>
<div>현재 날씨 데이터 가지고 오기</div>
Expand Down
8 changes: 7 additions & 1 deletion src/recoilAtom/FeedContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ interface IMAGE {
imageUrl: string;
}

interface LIKE {
likeId : number;
nickName: string;
}

interface FEEDATA {
boardId: number;
images: IMAGE | null;
images: IMAGE;
likeCount: number;
likelist: LIKE[];
nickName: string;
temperature: number;
weather: string;
Expand Down
7 changes: 7 additions & 0 deletions src/recoilAtom/FeedLoginToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { atom } from "recoil"


export const FeedLoginToken = atom<string | undefined>({
key:'Feed_login_token_key',//전역적으로 유일한 값
default:""
});
7 changes: 7 additions & 0 deletions src/recoilAtom/FeedNickname.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { atom } from "recoil"


export const FeedDecodeNickname = atom<string | undefined>({
key:'decode_nickname_key',//전역적으로 유일한 값
default:""
});
1 change: 1 addition & 0 deletions src/style/feedContent.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
font-weight: bold;
text-align: center;
background-color: white;
cursor: pointer;
}
}

Expand Down

0 comments on commit ea60549

Please sign in to comment.