.gitignore package-lock.json package.json public README.md src tailwind.config.js =========================================================== \src\App.css =========================================================== .App { text-align: center; } .App-logo { height: 40vmin; pointer-events: none; } @media (prefers-reduced-motion: no-preference) { .App-logo { animation: App-logo-spin infinite 20s linear; } } .App-header { background-color: #282c34; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: calc(10px + 2vmin); color: white; } .App-link { color: #61dafb; } @keyframes App-logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } =========================================================== \src\App.js =========================================================== import {RouterProvider} from "react-router-dom"; import root from "./router/root"; function App() { return ( ); } export default App; =========================================================== \src\App.test.js =========================================================== import { render, screen } from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { render(); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); }); =========================================================== \src\components\menus\BasicMenu.js =========================================================== import { Link } from "react-router-dom"; const BasicMenu = () => { return ( ); } export default BasicMenu; =========================================================== \src\index.css =========================================================== @tailwind base; @tailwind components; @tailwind utilities; =========================================================== \src\index.js =========================================================== import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); =========================================================== \src\layouts\BasicLayout.js =========================================================== import BasicMenu from "../components/menus/BasicMenu"; const BasicLayout = ({children}) => { return ( <> {/* 기존 헤더 대신 BasicMenu*/ } {/* 상단 여백 my-5 제거 */}
{/* 상단 여백 py-40 변경 flex 제거 */} {children}
); } export default BasicLayout; =========================================================== \src\logo.svg =========================================================== =========================================================== \src\pages\AboutPage.js =========================================================== import BasicLayout from "../layouts/BasicLayout"; const AboutPage = () => { return (
About Page
); } export default AboutPage; =========================================================== \src\pages\MainPage.js =========================================================== import BasicLayout from "../layouts/BasicLayout"; const MainPage = () => { return (
Main Page
); } export default MainPage; =========================================================== \src\pages\todo\AddPage.js =========================================================== const AddPage = () => { return (
Todo Add Page
); } export default AddPage; =========================================================== \src\pages\todo\IndexPage.js =========================================================== import { Outlet, useNavigate } from "react-router-dom"; import BasicLayout from "../../layouts/BasicLayout"; import { useCallback } from "react"; const IndexPage = () => { const navigate = useNavigate() const handleClickList = useCallback(() => { navigate({ pathname:'list' }) }) const handleClickAdd = useCallback(() => { navigate({ pathname:'add' }) }) return (
LIST
ADD
); } export default IndexPage; =========================================================== \src\pages\todo\ListPage.js =========================================================== import { useSearchParams } from "react-router-dom"; const ListPage = () => { const [queryParams] = useSearchParams() const page = queryParams.get("page") ? parseInt(queryParams.get("page")) : 1 const size = queryParams.get("size") ? parseInt(queryParams.get("size")) : 10 return (
Todo List Page Component {page} --- {size}
); } export default ListPage; =========================================================== \src\pages\todo\ModifyPage.js =========================================================== import { useNavigate } from "react-router-dom"; const ModifyPage = ({tno}) => { const navigate = useNavigate() const moveToRead = () => { navigate({pathname:`/todo/read/${tno}`}) } const moveToList = () => { navigate({pathname:`/todo/list`}) } return (
Todo Modify Page
); } export default ModifyPage; =========================================================== \src\pages\todo\ReadPage.js =========================================================== import { useCallback } from "react"; import { createSearchParams, useNavigate, useParams, useSearchParams } from "react-router-dom"; const ReadPage = () => { const {tno} = useParams() const navigate = useNavigate() const [queryParams] = useSearchParams() const page = queryParams.get("page") ? parseInt(queryParams.get("page")) : 1 const size = queryParams.get("size") ? parseInt(queryParams.get("size")) : 10 const queryStr = createSearchParams({page,size}).toString() const moveToModify = useCallback((tno) => { navigate({ pathname: `/todo/modify/${tno}`, search: queryStr }) },[tno, page, size]) const moveToList = useCallback(() => { navigate({pathname:`/todo/list`, search: queryStr}) }, [page, size]) return (
Todo Read Page Component {tno}
); } export default ReadPage; =========================================================== \src\reportWebVitals.js =========================================================== const reportWebVitals = onPerfEntry => { if (onPerfEntry && onPerfEntry instanceof Function) { import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { getCLS(onPerfEntry); getFID(onPerfEntry); getFCP(onPerfEntry); getLCP(onPerfEntry); getTTFB(onPerfEntry); }); } }; export default reportWebVitals; =========================================================== \src\router\root.js =========================================================== import { Suspense, lazy } from "react"; import todoRouter from "./todoRouter"; const { createBrowserRouter } = require("react-router-dom"); const Loading =
Loading....
const Main = lazy(() => import("../pages/MainPage")) const About = lazy(() => import("../pages/AboutPage")) const TodoIndex = lazy(() => import("../pages/todo/IndexPage")) const TodoList = lazy(() => import("../pages/todo/ListPage")) const root = createBrowserRouter([ { path: "", element:
}, { path: "about", element: }, { path: "todo", element: , children: todoRouter() } ]) export default root; =========================================================== \src\router\todoRouter.js =========================================================== import { Suspense, lazy } from "react"; import { Navigate } from "react-router-dom"; const Loading =
Loading....
const TodoList = lazy(() => import("../pages/todo/ListPage")) const TodoRead = lazy(() => import("../pages/todo/ReadPage")) const TodoAdd = lazy(() => import("../pages/todo/AddPage")) const TodoModify = lazy(() => import("../pages/todo/ModifyPage")) const todoRouter = () => { return [ { path: "list", element: }, { path: "", element: }, { path: "read/:tno", element: }, { path: "add", element: }, { path: "modify/:tno", element: } ] } export default todoRouter; =========================================================== \src\setupTests.js =========================================================== // jest-dom adds custom jest matchers for asserting on DOM nodes. // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom';