Skip to content

Commit

Permalink
Merge pull request #18 from Likelion12-KNU/registerAPI
Browse files Browse the repository at this point in the history
[Feat] - 등록API 제작 중 500에러
  • Loading branch information
Kim-jaeyeon authored Jun 1, 2024
2 parents f57663d + 1e2f3d0 commit ec71e6e
Show file tree
Hide file tree
Showing 10 changed files with 321 additions and 76 deletions.
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://kit.fontawesome.com/31122b6516.js" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<title>너의 아파트는</title>
</head>
<body>
Expand Down
4 changes: 2 additions & 2 deletions src/Post.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import axios from "axios";
/**
* 좋아요 수 댓글 수를 관리합니다.
*/

function Post({ sortURL,key, id, nickname, aptname, isLiked, likeCount, commentCount }) { //postList 컴포넌트에서 json props를 받아온다.
//+ 등록 URL
function Post({ sortURL, id, nickname, aptname, isLiked, likeCount, commentCount }) { //postList 컴포넌트에서 json props를 받아온다.
// isHeartClicked 상태 변수와 setIsHeartClicked 함수: 하트 아이콘 클릭 여부를 관리
const [isHeartClicked, setIsHeartClicked] = useState(isLiked);
// heart 상태 변수와 setHeart 함수: 하트 숫자를 관리
Expand Down
113 changes: 69 additions & 44 deletions src/PostForm.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,92 @@
import React, { useState, useEffect} from "react";
import React, { useState, useEffect } from "react";
import "./PostForm.css";
import axios from "axios";

/**
* 등록 폼을 관리 합니다. (입력 부분)
*/

function PostForm({registerPost}) {
function PostForm({ registerPost }) {
const [aptName, setAptName] = useState(""); //useState를 활용한 상태관리입니다!
const [password, setPassword] = useState("");
// 아파트 이름 자동완성 결과 상태 관리
const [apartmentSearchResult, setApartmentSearchResult] = useState([]);

// 폼 제출 핸들러 함수
// 폼이 제출될 때 실행되는 함수.
// 데이터 처리, 서버 요청 작업 진행

// 아파트 이름 자동완성 결과 상태 관리
const [apartmentSearchResult, setApartmentSearchResult] = useState([]);
// 아파트 이름을 입력할 시, 아파트의 ID를 백으로 전달
// 선택된 아파트의 ID 상태
const [selectedAptId, setSelectedAptId] = useState("");


// 폼 제출 핸들러 함수
// 폼이 제출될 때 실행되는 함수.
// 데이터 처리, 서버 요청 작업 진행
const handleSubmit = (event) => {

event.preventDefault(); //브라우저마다 이벤트 이름부터 시작해서 이벤트 종류나 이벤트가 처리되는 방식이 달라서 이를 동일하게 처리하도록 하는 게 필요하다고 합니다.

// 아파트 이름과 비밀번호를 사용하여 게시글 등록 함수 호출
registerPost(aptName, password);
registerPost(selectedAptId, password);
//폼 제출 후
setAptName(""); // 입력 필드 초기화
setPassword(""); // 입력 필드 초기화
setSelectedAptId(""); // 선택된 아파트 ID 초기화

//아파트 이름과 비밀번호가 잘 찍히나 확인해보기 위해 두었습니다.
console.log("아파트 이름:", aptName);
console.log("비밀번호:", password);
console.log("비밀번호:", password);

};

/**
* 사용자가 아파트 이름을 입력할 때, 백엔드 서버에서 해당 이름과 일치하는 아파트 이름을
* 자동완성 목록으로 가져와 표시, 그렇게 고른 아파트 이름은 백앤드의 id로 전달됩니다.
*
* 이부분은 아직 미완성된 부분이므로 주석처리 하였습니다.
*/
// useEffect(() => {
// if (aptName) {
// const fetchAptNames = async () => {
// try {
// const response = await fetch(
// encodeURI(`https://apt-api.blbt.app/v1/apartment/name?query=${aptName}`)
// //https://apt-api.blbt.app/v1/apartment/name?query=${aptName}
// );
// const data = await response.json();
// setApartmentSearchResult(data.data); // 자동완성 결과 상태 업데이트
// }

// catch (error) {
// console.error("Error fetching apartment names:", error);
// }

// };
// fetchAptNames();
// }

// else {
// setApartmentSearchResult([]); // 입력값이 없으면 결과 초기화
// }
// }, [aptName]);
/**
* 사용자가 아파트 이름을 입력할 때, 백엔드 서버에서 해당 이름과 일치하는 아파트 이름을
* 자동완성 목록으로 가져와 표시, 그렇게 고른 아파트 이름은 백앤드의 id로 전달됩니다.
*/

useEffect(() => {
if (aptName) {

const fetchAptNames = async () => {
try {
let config = {
method: 'get',
maxBodyLength: Infinity,
url: encodeURI(`https://apt-api.blbt.app/v1/apartment/name?query=${aptName}`),
headers: {}
};

const response = await axios.request(config);
console.log("API 응답: ", response.data);
setApartmentSearchResult(response.data.data); // 자동완성 결과 상태 업데이트
} catch (error) {
console.error("Error fetching apartment names:", error);
}
};

// 함수 호출로 아파트 이름 목록 가져옴
fetchAptNames();
}
else {
setApartmentSearchResult([]); // 입력값이 없으면 결과 초기화
}
}, [aptName]); // 아파트 이름이 변경될 때 마다 새로운 API 요청, 자동완성 결과 업뎃


// 아파트 이름 선택 핸들러 함수
const handleAptNameSelect = (event) => {
const selectedAptName = event.target.value;
setAptName(selectedAptName);

// 선택된 아파트 이름에 해당하는 아파트 ID 찾기
const selectedApt = apartmentSearchResult.find(apt => apt.apartmentName === selectedAptName);
if (selectedApt) {
setSelectedAptId(selectedApt._id); // 선택된 아파트 ID 설정
} else {
setSelectedAptId(""); // 일치하는 아파트가 없으면 ID 초기화
}
};



// 제출된 폼을 백앤드로 보낸다.
return (
<div id="postForm">
<form onSubmit={handleSubmit}> {/* handleSubmit 함수 호출 */}
Expand All @@ -70,12 +95,12 @@ function PostForm({registerPost}) {
type="text"
placeholder="당신이 살고 있는 쌈@@뽕한 아파트의 이름은 무엇인가요?"
value={aptName}
onChange={(e) => setAptName(e.target.value)} //input에 입력한 정보로 변수값을 바꿔주기 위해서는 e.target.value 를 인자로 넘겨야한다!
list="apartment-names"
onChange={handleAptNameSelect} //input에 입력한 정보로 변수값을 바꿔주기 위해서는 e.target.value 를 인자로 넘겨야한다!{(e) => setAptName(e.target.value)}
list="apartment-names"
/>
<datalist id="apartment-names">
{apartmentSearchResult.map((apt) => (
<option key={apt.id} value={apt.name} />
<option key={apt._id} value={apt.apartmentName} />
))}
</datalist>
<div id="password_div">
Expand Down
98 changes: 68 additions & 30 deletions src/PostList.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import React, {useState, useEffect} from 'react';
import Post from './Post';
import PostForm from './PostForm';
import {useEffect} from 'react';
// import {useEffect} from 'react';
import './PostList.css';
import axios from 'axios';
/**
Expand All @@ -10,70 +10,108 @@ import axios from 'axios';

// 게시글 등록 함수

function PostList({sortURL}) { //API URL을 app.jsx로부터 받아옴
function PostList({sortURL, postURL}) { //API URL을 app.jsx로부터 받아옴
const [posts, setPosts] = useState([]); //게시글 리스트 상태 - 초기값을 빈 배열로

const generateUserName = () => {
const randomNumber = Math.floor(Math.random() * 1000);
return `아기사자${randomNumber}`;
};

// /**
// * 등록 폼 설정 함수 아파트 이름, 비번을 받으면,
// * 이름 생성 함수가 그 폼에대한 닉네임을 만든다.
// */
// const registerPost = (aptName, password) => {
// const generateUserName = () => {
// const randomNumber = Math.floor(Math.random() * 1000);
// return `아기사자${randomNumber}`;
// };

// // 새로운 게시글 데이터를 저장하기위한 객체
// // 각 게시물 구분을 위한 고유ID
// // 닉네임, 아파트 이름, 공감 수, 댓글들을 관리.
// const newPost = {
// id: Date.now(),// 고유 ID를 사용하여 각 게시물을 구분
// nickname: generateUserName(), // 랜덤 익명 닉네임 생성
// aptname: aptName,
// heart: 0, // 새로운 게시글의 초기 좋아요 개수는 0으로 설정
// comment: [], // 새로운 게시글의 초기 댓글 리스트는 빈 배열로 설정
// };
// setPosts([newPost, ...posts]);
// // 새로운 게시글을 이전의 게시글 리스트 앞에 추가하는 상태 업데이트 함수이다.
// const fetchData = async () => {
// try {
// const config = {
// method: 'get',
// maxBodyLength: Infinity,
// url: sortURL,
// headers: {
// 'Content-Type': 'application/json',
// },
// };
// const response = await axios.request(config);
// setPosts(response.data.data);
// } catch (error) {
// console.error("Error fetching posts:", error);
// }
// };



/**
* 등록 폼 설정 함수 아파트 이름, 비번을 받으면,
* 이름 생성 함수가 그 폼에대한 닉네임을 만든다.
* 아파트 ID를 가져온다.
*/
const registerPost = async (aptId, password) => {
try {
const newPostData = {
apartmentId: aptId,
password: password,
nickname: generateUserName(), // 랜덤 닉네임 생성
};

//디버깅
console.log("POST 요청을 보낼 URL:", postURL); // URL 로그 출력
console.log("보낼 데이터:", newPostData); // 데이터 로그 출력

const response = await axios.post(postURL, newPostData, {
headers: {
'Content-Type': 'application/json',
},
});

console.log("서버 응답:", response);

fetchData(); // 새로운 게시글 등록 후 게시글 목록을 다시 가져옵니다.
//게시글 등록 중 에러 발생: 이부분이 작동합니다..
} catch (error) {
console.error("게시글 등록 중 에러 발생:", error);
if (error.response) {
// 서버 응답 데이터: 이부분도 작동합니다..
console.error("서버 응답 데이터:", error.response.data);
}
}
};


useEffect(() => { //api에서 가져온 게시물 리스트들이 변할 때마다 리렌더링!
const fetchData = async () => {
try {
// 무한 호출 확인
console.log("Fetching data...");
const config = {
method: 'get',
maxBodyLength: Infinity,
url: `${sortURL}`, //최신순을 클릭했는지, 랭킹순을 클릭했는지에 따라서 API url 주소가 바뀝니다!
url: `${sortURL}`, //${sortURL} 최신순을 클릭했는지, 랭킹순을 클릭했는지에 따라서 API url 주소가 바뀝니다!
headers: {
'Content-Type': 'application/json',
},
};

const response = await axios.request(config);
setPosts(response.data.data); // posts를 api에서 가져온 데이터로 설정
} catch (error) {
console.error(error);
}
}
};

fetchData();
}, [posts]); //posts를 관찰!
}, [sortURL]); //posts를 관찰! sortURL


// 게시물들을 렌더링 하는 하는 부분이다.

return (
<div id='PostList_div'>
<div id="fixed-form-container">
<PostForm />
{/*<PostForm registerPost={registerPost} />*/}
{/* // PostForm 컴포넌트에 registerPost 함수 전달 */}
</div>

<div id="posts-container">
{posts.map((post) => //api에서 가져온 데이터
<Post
sortURL={sortURL}
// sortURL={sortURL}
key={post._id} // React에서 리스트 항목을 고유하게 식별하기 위해 사용 --> 게시글의 댓글, 공감이 독립적으로 관리되도록한다.
id={post._id} // 컴포넌트에 post의 ID 값을 전달하여 게시물을 식별하고 관련 데이터를 처리
nickname={post.nickname} //닉네임을 전달
Expand Down
Loading

0 comments on commit ec71e6e

Please sign in to comment.