diff --git a/index2.html b/index.html similarity index 96% rename from index2.html rename to index.html index 2aa712f4..49b17485 100644 --- a/index2.html +++ b/index.html @@ -1,6 +1,5 @@ -<<<<<<< HEAD diff --git a/package-lock.json b/package-lock.json index 4823d876..500cfa9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,12 @@ "dependencies": { "@tanstack/react-query": "^4.32.0", "axios": "^1.4.0", + "jwt-decode": "^3.1.2", "react": "^18.2.0", + "react-date-range": "^1.4.0", "react-dom": "^18.2.0", "react-icons": "^4.10.1", + "react-router-dom": "^6.14.2", "scss": "^0.2.4", "vite-plugin-mkcert": "^1.16.0", "vite-plugin-sass-dts": "^1.3.8" @@ -20,6 +23,7 @@ "devDependencies": { "@types/node": "^20.4.4", "@types/react": "^18.0.37", + "@types/react-date-range": "^1.4.4", "@types/react-dom": "^18.0.11", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", @@ -352,6 +356,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", @@ -1081,6 +1096,14 @@ "@octokit/openapi-types": "^18.0.0" } }, + "node_modules/@remix-run/router": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz", + "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==", + "engines": { + "node": ">=14" + } + }, "node_modules/@swc/core": { "version": "1.3.70", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.70.tgz", @@ -1339,6 +1362,16 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-date-range": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@types/react-date-range/-/react-date-range-1.4.4.tgz", + "integrity": "sha512-9Y9NyNgaCsEVN/+O4HKuxzPbVjRVBGdOKRxMDcsTRWVG62lpYgnxefNckTXDWup8FvczoqPW0+ESZR6R1yymDg==", + "dev": true, + "dependencies": { + "@types/react": "*", + "date-fns": "^2.16.1" + } + }, "node_modules/@types/react-dom": { "version": "18.2.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", @@ -1842,6 +1875,11 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1900,6 +1938,21 @@ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", "dev": true }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2738,6 +2791,11 @@ "node": ">=6" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2913,6 +2971,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ometa": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/ometa/-/ometa-0.2.2.tgz", @@ -3109,6 +3175,16 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -3154,6 +3230,21 @@ "node": ">=0.10.0" } }, + "node_modules/react-date-range": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-date-range/-/react-date-range-1.4.0.tgz", + "integrity": "sha512-+9t0HyClbCqw1IhYbpWecjsiaftCeRN5cdhsi9v06YdimwyMR2yYHWcgVn3URwtN/txhqKpEZB6UX1fHpvK76w==", + "dependencies": { + "classnames": "^2.2.6", + "prop-types": "^15.7.2", + "react-list": "^0.8.13", + "shallow-equal": "^1.2.1" + }, + "peerDependencies": { + "date-fns": "2.0.0-alpha.7 || >=2.0.0", + "react": "^0.14 || ^15.0.0-rc || >=15.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -3174,6 +3265,22 @@ "react": "*" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-list": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.17.tgz", + "integrity": "sha512-pgmzGi0G5uGrdHzMhgO7KR1wx5ZXVvI3SsJUmkblSAKtewIhMwbQiMuQiTE83ozo04BQJbe0r3WIWzSO0dR1xg==", + "dependencies": { + "prop-types": "15" + }, + "peerDependencies": { + "react": "0.14 || 15 - 18" + } + }, "node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -3183,6 +3290,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz", + "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==", + "dependencies": { + "@remix-run/router": "1.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz", + "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==", + "dependencies": { + "@remix-run/router": "1.7.2", + "react-router": "6.14.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3195,6 +3332,11 @@ "node": ">=8.10.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3336,6 +3478,11 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 9c806241..cfc7f902 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,12 @@ "dependencies": { "@tanstack/react-query": "^4.32.0", "axios": "^1.4.0", + "jwt-decode": "^3.1.2", "react": "^18.2.0", + "react-date-range": "^1.4.0", "react-dom": "^18.2.0", "react-icons": "^4.10.1", + "react-router-dom": "^6.14.2", "scss": "^0.2.4", "vite-plugin-mkcert": "^1.16.0", "vite-plugin-sass-dts": "^1.3.8" @@ -22,6 +25,7 @@ "devDependencies": { "@types/node": "^20.4.4", "@types/react": "^18.0.37", + "@types/react-date-range": "^1.4.4", "@types/react-dom": "^18.0.11", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", diff --git a/src/@types/common.ts b/src/@types/common.ts index c49222e3..8f3836f2 100644 --- a/src/@types/common.ts +++ b/src/@types/common.ts @@ -1,7 +1,20 @@ - -declare interface Sample { +declare interface JoinUserInputType { + id: string; name: string; + joinDate: string; +} + +declare interface LoginOutputType { id: string; + name: string; joinDate: string; + accessToken: string; + refreshToken?: string; +} + +declare interface UserLoginType { + accessToken: string; + refreshToken?: string; } + // declare 사용하여 전역화 시킨다. \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index a2c194f1..5939c852 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,16 @@ +import Main from "./pages/Main/main.tsx"; +import { Route, Routes } from "react-router-dom"; +// import ProtectedRoute from "./Components/ProtectedRoute.tsx"; +// import Admin from "./pages/Admin/admin.tsx"; function App() { - return ( - <> -

라우터 필요시 생성

- + + } /> + {/*}*/} + ) } diff --git a/src/Components/Calendar-input/Calendar.tsx b/src/Components/Calendar-input/Calendar.tsx new file mode 100644 index 00000000..ccf9eae7 --- /dev/null +++ b/src/Components/Calendar-input/Calendar.tsx @@ -0,0 +1,33 @@ +import { useState } from 'react'; +import { DateRange, Range } from 'react-date-range'; +import 'react-date-range/dist/styles.css'; +import 'react-date-range/dist/theme/default.css'; + +export default function MyDateRangePicker() { + const [state, setState] = useState([ + { + startDate: new Date(), + endDate: undefined, + key: 'selection' + } + ]); + + // 선택한 날짜 범위를 받아 옵니다. 확인용 콘솔입니다. + console.log(state[0].startDate); + console.log(state[0].endDate); + + const handleSelect = (ranges: { [key: string]: Range }) => { + setState([ranges['selection']]); + } + + return ( + + ); +} + diff --git a/src/Components/Modal/Modal.css b/src/Components/Modal/Modal.css new file mode 100644 index 00000000..5b083395 --- /dev/null +++ b/src/Components/Modal/Modal.css @@ -0,0 +1,46 @@ +.modal-overlay { + position: fixed; + min-width: 100vw; + min-height: 100vh; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; + flex-direction: column; + align-items: center; + background-color: rgba(0, 0, 0, 0.375); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} + +.modal-window { + margin: auto; + display: flex; + max-width: 100vw; + height: auto; + flex-direction: column; + justify-content: center; + background-color: #fff; + align-items: center; + border-radius: 12px; + overflow: hidden; + padding-bottom: 30px; +} + +.modal-close { + bottom: 10px; + width: 200px; + height: 40px; + color: indianred; + font-size: 18px; + transition: 0.1s; + margin: 30px auto 10px; + background-color: var(--primary2); +} +.modal-close:hover { + transform: scale(1.03); + background-color: var(--primary3); +} + +/*# sourceMappingURL=Modal.css.map */ diff --git a/src/Components/Modal/Modal.css.map b/src/Components/Modal/Modal.css.map new file mode 100644 index 00000000..d8a43248 --- /dev/null +++ b/src/Components/Modal/Modal.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["Modal.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;;;AAEF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA","file":"Modal.css"} \ No newline at end of file diff --git a/src/Components/Modal/Modal.scss b/src/Components/Modal/Modal.scss new file mode 100644 index 00000000..72c07880 --- /dev/null +++ b/src/Components/Modal/Modal.scss @@ -0,0 +1,45 @@ +.modal-overlay { + position: fixed; + min-width: 100vw; + min-height: 100vh; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; + //display: flex; + flex-direction: column; + align-items: center; + //justify-content: center; + background-color: rgba(0, 0, 0, 0.375); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} +.modal-window { + // position: fixed; + margin: auto; + display: flex; + max-width: 100vw; + height: auto; + flex-direction: column; + justify-content: center; + background-color: #fff; + align-items: center; + border-radius: 12px; + overflow: hidden; + padding-bottom: 30px; +} +.modal-close { + bottom: 10px; + width: 200px; + height: 40px; + color: indianred; + font-size: 18px; + transition: 0.1s; + margin: 30px auto 10px; + background-color: var(--primary2); + &:hover { + transform: scale(1.03); + background-color: var(--primary3); + } +} diff --git a/src/Components/Modal/Modal.tsx b/src/Components/Modal/Modal.tsx new file mode 100644 index 00000000..dbbb5d5d --- /dev/null +++ b/src/Components/Modal/Modal.tsx @@ -0,0 +1,29 @@ +import { PropsWithChildren } from "react"; + +import "./Modal.scss"; + +interface ModalProps { + visibility: boolean; + toggle: (param: boolean) => void; +} + +export default function Modal(props: PropsWithChildren) { + return ( +
+
+ {props.children} + +
+
+ ); +} diff --git a/src/Components/Sample/Sample.tsx b/src/Components/Sample/Sample.tsx deleted file mode 100644 index dc09fbdc..00000000 --- a/src/Components/Sample/Sample.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Sample() { - return ( - <> -

Sample

- - ) -} diff --git a/src/Components/Sample/sample.scss b/src/Components/Sample/sample.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src/Hooks/useData-Query.tsx b/src/Hooks/useData-Query.tsx index 463ebb2c..0f3913da 100644 --- a/src/Hooks/useData-Query.tsx +++ b/src/Hooks/useData-Query.tsx @@ -1,3 +1,38 @@ +import { QueryClient, useMutation, useQuery } from "@tanstack/react-query"; +import { getLogin, postUserJoin } from "../Api/api.ts"; +// react- query 커스텀 훅 -// react- query 커스텀 훅 \ No newline at end of file +const queryClient = new QueryClient() + + +export default function useDataQuery(accessToken:string) { + + const getUserData = + useQuery(["useData", accessToken], () => { + if (accessToken) { + return getLogin(accessToken).then((res) => { + console.log(res); + return res; + }); + } else { + return []; + } + }, { staleTime: 1000 * 60 }); + + const joinUser = + useMutation((joinData: JoinUserInputType ) => postUserJoin(joinData), { + onSuccess: () => { + queryClient.invalidateQueries(["useData", accessToken]); + } + }); + + return { joinUser, getUserData }; +} + + +/* +1. provider 설정 +2. useQuery 설정 +3. 필요한 곳에서 action 실행(Mutation) +*/ diff --git a/src/main.tsx b/src/main.tsx index 6aefa40d..6af864e5 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,14 +1,17 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' -import './index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; +import "./index.css"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BrowserRouter } from "react-router-dom"; -const queryClient = new QueryClient() -ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( +const queryClient = new QueryClient(); +ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - - , -) + + + + + + +); diff --git a/src/pages/Main/main.tsx b/src/pages/Main/main.tsx index 0f66a2b7..46c9e526 100644 --- a/src/pages/Main/main.tsx +++ b/src/pages/Main/main.tsx @@ -1,7 +1,18 @@ +import Modal from "../../Components/Modal/Modal.tsx"; +import { useState } from "react"; +import MyDateRangePicker from "../../Components/Calendar-input/Calendar.tsx"; + export default function Main() { + const [visibility, setVisibility] = useState(false); return ( <>

Main

+ + + {/*모달 사용시 모달로 묶어 주시면 됩니다. state로 toggle 됩니다.*/} + + + ) } diff --git a/src/pages/Mypage/mypage.tsx b/src/pages/Mypage/mypage.tsx new file mode 100644 index 00000000..da289144 --- /dev/null +++ b/src/pages/Mypage/mypage.tsx @@ -0,0 +1,16 @@ + + +export default function Mypage() { + /* + - 개인별 + 1. 연차 목록을 리스트 한다. + 2. 당직 목록을 리스트 한다. + 3. 수정, 삭제 기능을 추가한다. + */ + return ( + <> +

MyPage

+ + ); +} + diff --git a/vite.config.ts b/vite.config.ts index 515b774f..131df9c5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,12 +1,13 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; +import sassDts from "vite-plugin-sass-dts"; import mkcert from "vite-plugin-mkcert"; import path from "path"; const __dirname = path.resolve(); // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), mkcert()], + plugins: [react(), sassDts(), mkcert()], resolve: { alias: [{ find: "@", replacement: `${__dirname}/src` }], },