commit
This commit is contained in:
@ -27,13 +27,13 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'com.oracle.database.jdbc:ojdbc8:19.8.0.0' // Oracle JDBC 드라이버
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web' // Spring Web 의존성
|
||||
implementation 'com.oracle.database.jdbc:ojdbc8:19.8.0.0'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'org.hibernate.orm:hibernate-core:6.5.2.Final'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0' // Jackson Databind 추가
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0'
|
||||
}
|
||||
|
||||
tasks.named('test') {
|
||||
|
@ -82,7 +82,7 @@ li {
|
||||
hr{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
/*메인*/
|
||||
|
||||
|
||||
|
||||
/* 테이블 스타일 */
|
||||
@ -93,14 +93,14 @@ table {
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
border: none; /* 모든 테두리 제거 */
|
||||
border: none;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* 세로줄, 가로줄 모두 제거 */
|
||||
|
||||
table td, table th {
|
||||
border: none; /* 완전히 모든 테두리 제거 */
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
@ -113,14 +113,50 @@ table td, table th {
|
||||
.write-button {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
/*회원가입 폼*/
|
||||
|
||||
|
||||
|
||||
h2 {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
/* 공지 게시판 */
|
||||
.notice-row {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
input {
|
||||
.top-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
}
|
||||
.write-btn {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-container input {
|
||||
padding: 8px;
|
||||
font-size: 16px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.search-container button {
|
||||
background-color: #008CBA;
|
||||
color: white;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ import BoardList from './BoardList';
|
||||
import CreatePost from './CreatePost';
|
||||
import FindId from './FindId';
|
||||
import FindPassword from './FindPassword';
|
||||
import BoardDetail from './BoardDetail';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
const [user, setUser] = useState(null); // 로그인된 사용자 정보를 저장하는 상태
|
||||
const [user, setUser] = useState(null);
|
||||
const [postCount, setPostCount] = useState(0);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
// 로그인 상태 유지
|
||||
@ -23,23 +23,27 @@ function App() {
|
||||
try {
|
||||
const response = await fetch('http://localhost:8080/users/current-user', {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
|
||||
if (response.ok) {
|
||||
const user = await response.json();
|
||||
setUser(user);
|
||||
setUser(user);
|
||||
} else if (response.status === 401) {
|
||||
setUser(null); // 인증 실패 시 로그아웃 상태로 설정
|
||||
setUser(null);
|
||||
} else {
|
||||
throw new Error('서버 응답에 문제가 있습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('현재 사용자 정보 불러오기 실패:', error);
|
||||
console.error('사용자 정보를 가져오는 중 오류 발생:', error);
|
||||
setUser(null);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCurrentUser();
|
||||
|
||||
fetchCurrentUser();
|
||||
}, []);
|
||||
|
||||
|
||||
// 게시글 개수를 상태로 저장
|
||||
useEffect(() => {
|
||||
const fetchPostCount = async () => {
|
||||
if (user) {
|
||||
@ -47,7 +51,7 @@ function App() {
|
||||
const response = await fetch(`http://localhost:8080/boards/count/${user.userId}`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setPostCount(data); // 게시글 개수를 상태로 저장
|
||||
setPostCount(data);
|
||||
} else {
|
||||
throw new Error('게시글 개수를 불러오는 중 오류 발생');
|
||||
}
|
||||
@ -62,7 +66,6 @@ function App() {
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
{/* 고정된 헤더 */}
|
||||
<header>
|
||||
<div className="home-link">홈 ></div>
|
||||
<div className="banner">메인 배너</div>
|
||||
@ -75,23 +78,24 @@ function App() {
|
||||
<ul className="category">
|
||||
<li>카테고리</li>
|
||||
<hr width="100%" color="black"></hr>
|
||||
<Link to="/">전체게시판</Link><br />
|
||||
<Link to="/shared">공지게시판</Link><br />
|
||||
<Link to="/questions">질문게시판</Link><br />
|
||||
<Link to="/free">자유게시판</Link>
|
||||
{/* 카테고리 링크 설정 */}
|
||||
<Link to="/boards/category/all">전체게시판</Link><br />
|
||||
<Link to="/boards/category/notice">공지게시판</Link><br />
|
||||
<Link to="/boards/category/free">자유게시판</Link><br />
|
||||
<Link to="/boards/category/questions">질문게시판</Link>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* 동적 콘텐츠 영역 */}
|
||||
<main>
|
||||
<Routes>
|
||||
<Route path="/" element={<BoardList />} />
|
||||
<Route path="/" element={<BoardList category="all" user={user}/>} />
|
||||
<Route path="/boards/category/:category" element={<BoardList user={user} />} />
|
||||
<Route path="/register" element={<Register />} />
|
||||
<Route path="/login" element={<Login setUser={setUser} />} />
|
||||
<Route path="/find-id" element={<FindId />} />
|
||||
<Route path="/find-password" element={<FindPassword />} />
|
||||
|
||||
<Route path="/boards/detail/:boardNumber" element={<BoardDetail />} />
|
||||
{/* 로그인 후에만 접근 가능한 페이지 */}
|
||||
{user && (
|
||||
<>
|
||||
@ -102,22 +106,19 @@ function App() {
|
||||
)}
|
||||
</Routes>
|
||||
</main>
|
||||
|
||||
{/* 글쓰기 링크 - 로그인한 사용자만 글쓰기가 가능함 */}
|
||||
{user && <Link to="/create-post">글쓰기</Link>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
//상단 사이드바 로그인 관련 처리
|
||||
function RenderAside({ user, setUser, postCount, error }) {
|
||||
const navigate = useNavigate(); // useNavigate 훅 사용
|
||||
const navigate = useNavigate();
|
||||
|
||||
// 로그아웃 처리
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:8080/users/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'include', // 세션 무효화 요청
|
||||
credentials: 'include',
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
@ -159,8 +160,7 @@ function RenderAside({ user, setUser, postCount, error }) {
|
||||
)}
|
||||
<p>닉네임: {user.userNickname}</p>
|
||||
<p>아이디: {user.userId}</p>
|
||||
<p>내가 쓴 글 개수: {postCount}</p>
|
||||
<Link to="/my-posts">내가 쓴 글</Link><br />
|
||||
<Link to="/my-posts">내가 쓴 글</Link> : {postCount} <br />
|
||||
<Link to="/edit-profile">개인정보 수정</Link><br />
|
||||
<button onClick={handleLogout}>로그아웃</button>
|
||||
</div>
|
||||
|
47
frontend/src/BoardDetail.js
Normal file
47
frontend/src/BoardDetail.js
Normal file
@ -0,0 +1,47 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
function BoardDetail() {
|
||||
const { boardNumber } = useParams(); // 게시물 번호
|
||||
const [board, setBoard] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
// 게시물 상세 정보,내용 조회
|
||||
useEffect(() => {
|
||||
const fetchBoard = async () => {
|
||||
try {
|
||||
const response = await fetch(`http://localhost:8080/boards/detail/${boardNumber}`);
|
||||
if (!response.ok) {
|
||||
setError('게시물을 불러오는 중 오류가 발생했습니다.');
|
||||
} else {
|
||||
const data = await response.json();
|
||||
setBoard(data);
|
||||
}
|
||||
} catch (err) {
|
||||
setError('네트워크 오류가 발생했습니다.');
|
||||
}
|
||||
};
|
||||
|
||||
fetchBoard();
|
||||
}, [boardNumber]);
|
||||
|
||||
if (error) {
|
||||
return <div>오류: {error}</div>;
|
||||
}
|
||||
|
||||
if (!board) {
|
||||
return <div>로딩 중...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>{board.boardTitle}</h2>
|
||||
<p>{board.boardWrite}</p>
|
||||
<p>작성자: {board.user?.userNickname}</p>
|
||||
<p>작성일: {new Date(board.createdDate).toLocaleString()}</p>
|
||||
<p>수정일: {new Date(board.updatedDate).toLocaleString()}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BoardDetail;
|
@ -1,23 +1,49 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import './App.css'; // CSS 파일 추가
|
||||
import { useParams, Link, useNavigate } from 'react-router-dom';
|
||||
import './App.css';
|
||||
|
||||
function BoardList() {
|
||||
function BoardList({ user }) {
|
||||
const { category = "all" } = useParams(); // URL 파라미터로부터 카테고리 가져오기
|
||||
const [boards, setBoards] = useState([]);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentPage, setCurrentPage] = useState(0);
|
||||
const [totalPages, setTotalPages] = useState(1); // 총 페이지 수
|
||||
const [searchTerm, setSearchTerm] = useState(''); // 검색어 상태 추가
|
||||
const [searchCategory, setSearchCategory] = useState(category); // 검색에 사용될 카테고리
|
||||
const [selectedCategory, setSelectedCategory] = useState(category); // 검색을 위한 선택된 카테고리
|
||||
const navigate = useNavigate(); // 페이지 이동을 위한 useNavigate
|
||||
|
||||
// 카테고리 한글 변환 함수
|
||||
const getCategoryNameInKorean = (categoryId) => {
|
||||
switch (categoryId) {
|
||||
case 'all':
|
||||
case 1:
|
||||
return '전체';
|
||||
case 'notice':
|
||||
case 2:
|
||||
return '공지';
|
||||
case 'questions':
|
||||
case 3:
|
||||
return '질문';
|
||||
case 'free':
|
||||
case 4:
|
||||
return '자유';
|
||||
default:
|
||||
return '알 수 없음';
|
||||
}
|
||||
};
|
||||
|
||||
// 게시물 가져오기 함수
|
||||
useEffect(() => {
|
||||
const fetchBoards = async () => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:8080/boards');
|
||||
const response = await fetch(`http://localhost:8080/boards/category/${category}`);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
setError(errorData.message || '서버에서 오류가 발생했습니다.');
|
||||
setError('서버에서 오류가 발생했습니다.');
|
||||
} else {
|
||||
const data = await response.json();
|
||||
|
||||
// 최신 글이 위로 오도록 정렬 (내림차순)
|
||||
const sortedData = data.sort((a, b) => new Date(b.updatedDate) - new Date(a.updatedDate));
|
||||
setBoards(sortedData);
|
||||
setBoards(data);
|
||||
setTotalPages(Math.ceil(data.length / 10)); // 총 페이지 수 계산
|
||||
}
|
||||
} catch (err) {
|
||||
setError('네트워크 오류가 발생했습니다.');
|
||||
@ -25,19 +51,86 @@ function BoardList() {
|
||||
};
|
||||
|
||||
fetchBoards();
|
||||
}, []);
|
||||
}, [category]);
|
||||
|
||||
const handleSearch = () => {
|
||||
setSearchCategory(selectedCategory); // 선택된 카테고리로 검색 수행
|
||||
navigate(`/boards/category/${selectedCategory}`); // 카테고리 변경 시 경로 이동
|
||||
};
|
||||
|
||||
const handleCreatePost = () => {
|
||||
if (user) {
|
||||
navigate('/create-post'); // 로그인된 경우 글쓰기 페이지로 이동
|
||||
} else {
|
||||
alert('로그인이 필요합니다.'); // 로그인되지 않은 경우 경고 메시지
|
||||
navigate('/login'); // 로그인 페이지로 이동
|
||||
}
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return <div>오류: {error}</div>;
|
||||
}
|
||||
|
||||
if (boards.length === 0) {
|
||||
return <div>게시물이 없습니다.</div>;
|
||||
}
|
||||
|
||||
// 공지사항과 기타 게시물 분리
|
||||
const noticeBoards = boards.filter(board => board.boardCategory === 2); // 공지사항
|
||||
const otherBoards = boards.filter(board => board.boardCategory !== 2); // 기타 게시물
|
||||
|
||||
// 기타 게시물 최신순으로 정렬 (updatedDate 기준 내림차순)
|
||||
otherBoards.sort((a, b) => new Date(b.updatedDate) - new Date(a.updatedDate));
|
||||
|
||||
// 제목이나 내용에 검색어가 포함된 게시물 필터링
|
||||
const filteredBoards = [...noticeBoards, ...otherBoards].filter(board =>
|
||||
board.boardTitle.includes(searchTerm) || board.boardWrite.includes(searchTerm)
|
||||
);
|
||||
|
||||
const displayedBoards = filteredBoards.slice(currentPage * 10, (currentPage + 1) * 10);
|
||||
|
||||
const handleNextPage = () => {
|
||||
if (currentPage < totalPages - 1) {
|
||||
setCurrentPage(currentPage + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePreviousPage = () => {
|
||||
if (currentPage > 0) {
|
||||
setCurrentPage(currentPage - 1);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>게시판 목록</h2>
|
||||
<table className="board-table">
|
||||
<h2>{getCategoryNameInKorean(category)} 게시판</h2>
|
||||
|
||||
{/* 검색 기능 */}
|
||||
<div className="board-controls">
|
||||
<select
|
||||
value={selectedCategory}
|
||||
onChange={(e) => setSelectedCategory(e.target.value)}
|
||||
>
|
||||
<option value="all">전체</option>
|
||||
<option value="notice">공지</option>
|
||||
<option value="questions">질문</option>
|
||||
<option value="free">자유</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder="검색어를 입력하세요"
|
||||
/>
|
||||
<button onClick={handleSearch}>검색</button>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>번호</th>
|
||||
<th>카테고리</th>
|
||||
<th>제목</th>
|
||||
<th>내용</th>
|
||||
<th>업데이트 날짜</th>
|
||||
@ -45,17 +138,41 @@ function BoardList() {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{boards.map((board) => (
|
||||
<tr key={board.boardNumber}>
|
||||
{displayedBoards.map((board) => (
|
||||
<tr key={board.boardNumber} className={board.boardCategory === 2 ? 'notice-row' : ''}>
|
||||
<td>{board.boardNumber}</td>
|
||||
<td>{board.boardTitle}</td>
|
||||
<td>{board.boardWrite.length > 10 ? board.boardWrite.substring(0, 10) + '...' : board.boardWrite}</td>
|
||||
<td>{getCategoryNameInKorean(board.boardCategory)}</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${board.boardNumber}`}>
|
||||
{board.boardTitle}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${board.boardNumber}`}>
|
||||
{board.boardWrite.substring(0, 10)}
|
||||
</Link>
|
||||
</td>
|
||||
<td>{new Date(board.updatedDate).toLocaleString()}</td>
|
||||
<td>{board.user.userNickname}</td> {/* userNickname 필드가 있는지 확인 필요 */}
|
||||
<td>{board.user?.userNickname}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="pagination">
|
||||
<button onClick={handlePreviousPage} disabled={currentPage === 0}>
|
||||
이전 페이지
|
||||
</button>
|
||||
<span>{currentPage + 1} / {totalPages}</span>
|
||||
<button onClick={handleNextPage} disabled={currentPage === totalPages - 1}>
|
||||
다음 페이지
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 글쓰기 버튼 추가 - 로그인한 사용자만 보임 */}
|
||||
<div className="create-post-button-container">
|
||||
{user && <button onClick={handleCreatePost}>글쓰기</button>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ function CreatePost() {
|
||||
|
||||
<label>카테고리:</label>
|
||||
<select value={category} onChange={(e) => setCategory(Number(e.target.value))}>
|
||||
<option value={1}>자유게시판</option>
|
||||
<option value={4}>자유게시판</option>
|
||||
<option value={2}>공지게시판</option>
|
||||
<option value={3}>질문게시판</option>
|
||||
</select>
|
||||
|
@ -1,47 +1,136 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import './App.js'; // 테이블 스타일 적용
|
||||
import { Link } from 'react-router-dom'; // React Router의 Link를 사용하여 페이지 이동 적용
|
||||
import './App.css'; // 테이블 스타일 적용
|
||||
|
||||
function MyPosts({ user }) {
|
||||
const [posts, setPosts] = useState([]);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentPage, setCurrentPage] = useState(0); // 현재 페이지 상태
|
||||
const [totalPages, setTotalPages] = useState(1); // 총 페이지 수 상태
|
||||
const pageSize = 10; // 한 페이지에 보여줄 게시물 수
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPosts = async () => {
|
||||
if (user) {
|
||||
const response = await fetch(`http://localhost:8080/boards/user/${user.userId}`);
|
||||
const data = await response.json();
|
||||
setPosts(data);
|
||||
try {
|
||||
if (user) {
|
||||
const response = await fetch(`http://localhost:8080/boards/user/${user.userId}`);
|
||||
if (!response.ok) {
|
||||
setError('게시물을 불러오는데 오류가 발생했습니다.');
|
||||
} else {
|
||||
const data = await response.json();
|
||||
setPosts(data || []); // 응답이 null이거나 undefined인 경우 빈 배열로 초기화
|
||||
setTotalPages(Math.ceil((data || []).length / pageSize)); // 총 페이지 수 계산
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
setError('네트워크 오류가 발생했습니다.');
|
||||
}
|
||||
};
|
||||
fetchPosts();
|
||||
}, [user]);
|
||||
|
||||
const getCategoryNameInKorean = (categoryId) => {
|
||||
switch (categoryId) {
|
||||
case 2:
|
||||
return '공지';
|
||||
case 3:
|
||||
return '질문';
|
||||
case 4:
|
||||
return '자유';
|
||||
default:
|
||||
return '알 수 없음';
|
||||
}
|
||||
};
|
||||
|
||||
const handleNextPage = () => {
|
||||
if (currentPage < totalPages - 1) {
|
||||
setCurrentPage(currentPage + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePreviousPage = () => {
|
||||
if (currentPage > 0) {
|
||||
setCurrentPage(currentPage - 1);
|
||||
}
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return <div>오류: {error}</div>;
|
||||
}
|
||||
|
||||
const paginatedPosts = posts.slice(currentPage * pageSize, (currentPage + 1) * pageSize);
|
||||
|
||||
const noticePosts = paginatedPosts?.filter(post => post.boardCategory === 2) || [];
|
||||
const otherPosts = paginatedPosts?.filter(post => post.boardCategory !== 2) || [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>{user?.userNickname}님의 게시물</h2>
|
||||
{posts.length > 0 ? (
|
||||
<table className="board-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>번호</th>
|
||||
<th>제목</th>
|
||||
<th>내용</th>
|
||||
<th>업데이트 날짜</th>
|
||||
<th>작성자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{posts.map((post) => (
|
||||
<tr key={post.boardNumber}>
|
||||
<td>{post.boardNumber}</td>
|
||||
<td>{post.boardTitle}</td>
|
||||
<td>{post.boardWrite.length > 10 ? post.boardWrite.substring(0, 10) + '...' : post.boardWrite}</td>
|
||||
{/* 날짜와 시간 모두 표시 */}
|
||||
<td>{new Date(post.updatedDate).toLocaleString()}</td>
|
||||
<td>{user.userNickname}</td> {/* 작성자는 항상 현재 사용자 */}
|
||||
<>
|
||||
<table className="board-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>번호</th>
|
||||
<th>카테고리</th>
|
||||
<th>제목</th>
|
||||
<th>내용</th>
|
||||
<th>업데이트 날짜</th>
|
||||
<th>작성자</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{/* 공지 게시물 먼저 표시 */}
|
||||
{noticePosts.map((post) => (
|
||||
<tr key={post.boardNumber} className="notice-row">
|
||||
<td>{post.boardNumber}</td>
|
||||
<td>{getCategoryNameInKorean(post.boardCategory)}</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${post.boardNumber}`}>
|
||||
{post.boardTitle}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${post.boardNumber}`}>
|
||||
{post.boardWrite.length > 10 ? post.boardWrite.substring(0, 10) + '...' : post.boardWrite}
|
||||
</Link>
|
||||
</td>
|
||||
<td>{new Date(post.updatedDate).toLocaleString()}</td>
|
||||
<td>{user.userNickname}</td>
|
||||
</tr>
|
||||
))}
|
||||
{/* 나머지 게시물 표시 */}
|
||||
{otherPosts.map((post) => (
|
||||
<tr key={post.boardNumber}>
|
||||
<td>{post.boardNumber}</td>
|
||||
<td>{getCategoryNameInKorean(post.boardCategory)}</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${post.boardNumber}`}>
|
||||
{post.boardTitle}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<Link to={`/boards/detail/${post.boardNumber}`}>
|
||||
{post.boardWrite.length > 10 ? post.boardWrite.substring(0, 10) + '...' : post.boardWrite}
|
||||
</Link>
|
||||
</td>
|
||||
<td>{new Date(post.updatedDate).toLocaleString()}</td>
|
||||
<td>{user.userNickname}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="pagination">
|
||||
<button onClick={handlePreviousPage} disabled={currentPage === 0}>
|
||||
이전 페이지
|
||||
</button>
|
||||
<span>{currentPage + 1} / {totalPages}</span>
|
||||
<button onClick={handleNextPage} disabled={currentPage === totalPages - 1}>
|
||||
다음 페이지
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p>게시물이 없습니다.</p>
|
||||
)}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function Register() {
|
||||
const [userId, setUserId] = useState(''); // 필드 이름 변경
|
||||
const [userPassword, setUserPassword] = useState(''); // 필드 이름 변경
|
||||
const [userId, setUserId] = useState('');
|
||||
const [userPassword, setUserPassword] = useState('');
|
||||
const [rePassword, setRePassword] = useState('');
|
||||
const [userName, setUserName] = useState(''); // 필드 이름 변경
|
||||
const [userName, setUserName] = useState('');
|
||||
const [userNickname, setUserNickname] = useState('');
|
||||
|
||||
const handleSignup = async (e) => {
|
||||
@ -14,13 +14,12 @@ function Register() {
|
||||
alert("비밀번호가 일치하지 않습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 백엔드 User 엔티티와 필드 이름을 일치시킴
|
||||
//DB에 넣을 정보
|
||||
const user = {
|
||||
userId, // userId 필드로 변경
|
||||
userPassword, // userPassword 필드로 변경
|
||||
userName, // userName 필드로 변경
|
||||
userNickname // userNickname 필드 그대로 사용
|
||||
userId,
|
||||
userPassword,
|
||||
userName,
|
||||
userNickname
|
||||
};
|
||||
|
||||
try {
|
||||
@ -50,7 +49,7 @@ function Register() {
|
||||
<input
|
||||
type="text"
|
||||
value={userId}
|
||||
onChange={(e) => setUserId(e.target.value)} // 필드 이름 변경
|
||||
onChange={(e) => setUserId(e.target.value)}
|
||||
required
|
||||
/><br />
|
||||
|
||||
@ -58,7 +57,7 @@ function Register() {
|
||||
<input
|
||||
type="password"
|
||||
value={userPassword}
|
||||
onChange={(e) => setUserPassword(e.target.value)} // 필드 이름 변경
|
||||
onChange={(e) => setUserPassword(e.target.value)}
|
||||
required
|
||||
/><br />
|
||||
|
||||
@ -74,7 +73,7 @@ function Register() {
|
||||
<input
|
||||
type="text"
|
||||
value={userName}
|
||||
onChange={(e) => setUserName(e.target.value)} // 필드 이름 변경
|
||||
onChange={(e) => setUserName(e.target.value)}
|
||||
required
|
||||
/><br />
|
||||
|
||||
|
@ -10,6 +10,9 @@ import com.example.demo.entity.Board;
|
||||
import com.example.demo.entity.User;
|
||||
import com.example.demo.service.BoardService;
|
||||
import com.example.demo.service.UserService;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/boards")
|
||||
@ -42,11 +45,11 @@ public class BoardController {
|
||||
return boardService.getPostsByUserId(userId);
|
||||
}
|
||||
|
||||
// 게시글 생성 (세션에서 로그인된 사용자 정보 사용)`
|
||||
// 게시글 생성 (로그인된 사용자 정보 사용)
|
||||
@PostMapping("/create")
|
||||
public ResponseEntity<?> createPost(@RequestBody Board board, HttpSession session) {
|
||||
try {
|
||||
// 세션에서 현재 로그인된 사용자 가져오기
|
||||
// 현재 로그인된 사용자 가져오기
|
||||
User loggedInUser = (User) session.getAttribute("user");
|
||||
if (loggedInUser == null) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("로그인이 필요합니다.");
|
||||
@ -56,7 +59,7 @@ public class BoardController {
|
||||
board.setUser(loggedInUser);
|
||||
|
||||
// 게시글 저장
|
||||
Board createdBoard = boardService.saveBoard(board, loggedInUser.getUserId()); // 두 번째 인자로 loggedInUser.getUserId() 전달
|
||||
Board createdBoard = boardService.saveBoard(board, loggedInUser.getUserId());
|
||||
return ResponseEntity.ok("게시글 작성 완료");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -70,7 +73,7 @@ public class BoardController {
|
||||
public ResponseEntity<Board> createBoard(@RequestBody Board board, HttpSession session) {
|
||||
String loggedInUser = (String) session.getAttribute("userId");
|
||||
board.setUpdatedBy(loggedInUser);
|
||||
Board createdBoard = boardService.saveBoard(board, loggedInUser);
|
||||
Board createdBoard = boardService.saveBoard(board, loggedInUser);
|
||||
return new ResponseEntity<>(createdBoard, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@ -83,4 +86,45 @@ public class BoardController {
|
||||
return ResponseEntity.ok(updatedBoard);
|
||||
}
|
||||
|
||||
}
|
||||
// 카테고리별 게시글 리스트 반환
|
||||
@GetMapping("/category/{category}")
|
||||
public List<Board> getBoardsByCategory(
|
||||
@PathVariable("category") String category) {
|
||||
|
||||
if (category.equals("all")) {
|
||||
return boardService.getAllBoards();
|
||||
} else {
|
||||
int categoryId = getCategoryId(category);
|
||||
return boardService.getBoardsByCategory(categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
// 게시판 나누기
|
||||
private int getCategoryId(String category) {
|
||||
switch (category) {
|
||||
case "notice":
|
||||
return 2;
|
||||
case "questions":
|
||||
return 3;
|
||||
case "free":
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//글 세부조회
|
||||
@GetMapping("/detail/{boardNumber}")
|
||||
public ResponseEntity<Board> getBoardById(@PathVariable Long boardNumber) {
|
||||
try {
|
||||
Board board = boardService.getBoardById(boardNumber);
|
||||
if (board != null) {
|
||||
return ResponseEntity.ok(board);
|
||||
} else {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ public class Board {
|
||||
private String boardWrite;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "USER_ID", nullable = false)
|
||||
@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID", nullable = false)
|
||||
private User user;
|
||||
|
||||
@Column(name = "CRT_DT", nullable = false)
|
||||
|
@ -15,4 +15,14 @@ public interface BoardRepository extends JpaRepository<Board, Long> {
|
||||
// 특정 사용자가 작성한 게시글 목록을 가져오는 메서드
|
||||
@Query("SELECT b FROM Board b WHERE b.user.userId = :userId")
|
||||
List<Board> findByUserUserId(@Param("userId") String userId);
|
||||
|
||||
// 카테고리별 게시글 리스트 반환
|
||||
List<Board> findByBoardCategory(Integer category);
|
||||
|
||||
// 카테고리별 게시글 리스트 및 작성자 정보 포함
|
||||
@Query("SELECT b FROM Board b JOIN FETCH b.user WHERE b.boardCategory = :category")
|
||||
List<Board> findByBoardCategoryWithUser(@Param("category") int category);
|
||||
|
||||
// 모든 게시글 리스트 반환
|
||||
List<Board> findAll();
|
||||
}
|
||||
|
@ -17,18 +17,22 @@ public class BoardService {
|
||||
this.boardRepository = boardRepository;
|
||||
}
|
||||
|
||||
// 모든 게시글 리스트 반환
|
||||
public List<Board> getAllBoards() {
|
||||
return boardRepository.findAll();
|
||||
}
|
||||
|
||||
// 특정 사용자의 게시글 개수 반환
|
||||
public int getPostCountByUserId(String userId) {
|
||||
return boardRepository.countPostsByUserId(userId);
|
||||
}
|
||||
|
||||
// 특정 사용자의 게시글 리스트 반환
|
||||
public List<Board> getPostsByUserId(String userId) {
|
||||
return boardRepository.findByUserUserId(userId);
|
||||
}
|
||||
|
||||
// 게시글 저장
|
||||
@Transactional
|
||||
public Board saveBoard(Board board, String loggedInUser) {
|
||||
if (board.getCreatedDate() == null) {
|
||||
@ -38,7 +42,7 @@ public class BoardService {
|
||||
return boardRepository.save(board);
|
||||
}
|
||||
|
||||
// createBoard 메서드 수정
|
||||
// 게시글 생성
|
||||
public void createBoard(Board board, User user) {
|
||||
board.setUser(user); // ManyToOne 관계의 user 설정
|
||||
board.setCreatedDate(LocalDateTime.now()); // 생성 시간 설정
|
||||
@ -48,4 +52,14 @@ public class BoardService {
|
||||
|
||||
boardRepository.save(board); // 데이터베이스에 저장
|
||||
}
|
||||
|
||||
// 카테고리별 게시물 목록 반환
|
||||
public List<Board> getBoardsByCategory(int category) {
|
||||
return boardRepository.findByBoardCategory(category);
|
||||
}
|
||||
|
||||
// 특정 게시글 ID로 게시글 반환
|
||||
public Board getBoardById(Long boardNumber) {
|
||||
return boardRepository.findById(boardNumber).orElse(null);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ public class UserService {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
|
||||
// Create a new user
|
||||
@Transactional
|
||||
public User saveUser(User user) {
|
||||
try {
|
||||
@ -42,7 +41,7 @@ public class UserService {
|
||||
if (user != null && user.getUserPassword().equals(userPassword)) {
|
||||
return user;
|
||||
}
|
||||
return null; // 인증 실패 시 null 반환
|
||||
return null;
|
||||
}
|
||||
|
||||
// 사용자 프로필 업데이트 메서드
|
||||
|
Reference in New Issue
Block a user