{
"name": "react_board",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.12.2",
"bootstrap": "^5.3.8",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-router-dom": "^7.9.1"
},
"devDependencies": {
"@eslint/js": "^9.35.0",
"@types/react": "^19.1.13",
"@types/react-dom": "^19.1.9",
"@vitejs/plugin-react": "^5.0.2",
"eslint": "^9.35.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.4.0",
"vite": "^7.1.6"
}
}
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Header from './components/Header';
import BoardList from './components/BoardList';
import PostView from './components/PostView';
import PostForm from './components/PostForm';
import './App.css';
function App() {
return (
<Router>
<Header />
<main>
<Routes>
<Route path="/list" element={<BoardList />} />
<Route path="/post/:id" element={<PostView />} />
<Route path="/new" element={<PostForm />} />
</Routes>
</main>
</Router>
);
}
export default App;
import React from 'react';
import { useParams, Link } from 'react-router-dom';
const PostView = () => {
const { id } = useParams();
// In a real app, you would fetch the post data based on the id
const post = { id: id, title: `Post ${id}`, author: `User${id}`, content: `This is the full content of post ${id}.` };
return (
<>
<h2>{post.title}</h2>
<p><strong>Author:</strong> {post.author}</p>
<p>{post.content}</p>
<Link to="/" className="btn btn-secondary">Back to List</Link>
</>
);
};
export default PostView;
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import Pagination from './Pagination';
const BoardList = () => {
const [posts, setPosts] = useState([
{"rnum":1,"hitCnt":18,"idx":5756,"title":"BatchTitle2","creaNm":"관리자","creaDtm":"2025-09-16"},
]);
const [searchTerm, setSearchTerm] = useState('');
const [submittedSearchTerm, setSubmittedSearchTerm] = useState('');
const [searchType, setSearchType] = useState('title');
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(100);
const handleSearch = () => {
console.log(searchTerm);
console.log(searchType);
setSubmittedSearchTerm(searchTerm);
setCurrentPage(1); // Reset to first page on new search
};
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
handleSearch();
}
};
//서버 주소 처리
const retriveBoard = (type, keyword) => {
axios.get("<http://localhost:8080/RestBoard/board/api/list>"
, {params: {
type: type,
keyword: keyword,
page: currentPage,
}})
.then(response => {
setPosts(response.data.list);
setTotalPages(response.data.totalpage);
console.log(response);
}).catch(error=>{
console.log(error);
})
};
useEffect(() => {
retriveBoard();
}, []);
useEffect(()=>{
retriveBoard(searchType, submittedSearchTerm);
}, [submittedSearchTerm, currentPage])
// Change page
const handlePageChange = (page) => setCurrentPage(page);
return (
<>
<h2>Board</h2>
<div className="row justify-content-between mb-3">
<div className="col-md-auto">
<Link to="/new" className="btn btn-primary">New Post</Link>
</div>
<div className="col-md-7">
<div className="input-group">
<select className="form-select" style={{ flex: '0 0 120px' }} value={searchType} onChange={e => setSearchType(e.target.value)}>
<option value="title">Title</option>
<option value="content">Content</option>
<option value="author">Author</option>
</select>
<input
type="text"
className="form-control"
placeholder={`Search by ${searchType}...`}
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
onKeyPress={handleKeyPress}
/>
<button className="btn btn-outline-secondary" type="button" onClick={handleSearch}>Search</button>
</div>
</div>
</div>
{/* Post List */}
<ul className="list-group mb-4">
{posts.map(post => (
<li key={post.id} className="list-group-item d-flex justify-content-between align-items-center">
<Link to={`/post/${post.id}`}>{post.title}</Link>
<span>{post.author}</span>
</li>
))}
</ul>
{/* Pagination
*/}
<Pagination currentPage={currentPage} totalPages={totalPages} onPageChange={handlePageChange} />
</>
);
};
export default BoardList;