diff --git a/README.md b/README.md index 2ca95fa..603864d 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ ┣ 📦components
┃ ┣ 📜[Component1].jsx
┃ ┗ 📜[Component2].jsx
-┣ 📜App.jsx
+┣ 📜App.tsx
┣ 📜App.css
-┣ 📜main.jsx
+┣ 📜main.tsx
## 커밋 컨벤션 diff --git a/index.html b/index.html index 0c589ec..891a938 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,6 @@
- + diff --git a/package-lock.json b/package-lock.json index 8cc038c..20635ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,13 +13,14 @@ }, "devDependencies": { "@eslint/js": "^9.30.1", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", + "@types/react": "^19.1.9", + "@types/react-dom": "^19.1.7", "@vitejs/plugin-react": "^4.6.0", "eslint": "^9.30.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", + "typescript": "^5.8.3", "vite": "^7.0.4" } }, @@ -1367,9 +1368,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "version": "19.1.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz", + "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==", "dev": true, "license": "MIT", "dependencies": { @@ -1377,9 +1378,9 @@ } }, "node_modules/@types/react-dom": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", - "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", + "version": "19.1.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz", + "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2630,6 +2631,20 @@ "node": ">= 0.8.0" } }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", diff --git a/package.json b/package.json index 44a8fc0..ae19500 100644 --- a/package.json +++ b/package.json @@ -15,13 +15,14 @@ }, "devDependencies": { "@eslint/js": "^9.30.1", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", + "@types/react": "^19.1.9", + "@types/react-dom": "^19.1.7", "@vitejs/plugin-react": "^4.6.0", "eslint": "^9.30.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", + "typescript": "^5.8.3", "vite": "^7.0.4" } } diff --git a/src/App.jsx b/src/App.jsx deleted file mode 100644 index 5d62758..0000000 --- a/src/App.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; -import "./App.css"; - -function App() { - const [count, setCount] = useState(0); - const name = "류승찬"; - - return ( - <> - 화이팅 - - ); -} - -export default App; diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..ea1e7b9 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,40 @@ +import React, {useEffect, useState} from "react"; +import "./App.css"; +import SignIn from './components/SignInModal'; +import SignUp from './components/SignUpModal'; + +function App() { + const [signIn, setSignIn] = useState(false); + const [signUp, setSignUp] = useState(false); + const mainStyle: React.CSSProperties = { + display: "flex", + gap: "2rem", + } + useEffect(() => { + const isModalOpen: boolean = signIn || signUp; + if (isModalOpen) document.body.style.overflow = "hidden"; + else document.body.style.overflow = ""; + return () => { + document.body.style.overflow = ""; + } + }, [signIn, signUp]) + + const openSignInModal = () => { + setSignIn(true); + setSignUp(false); + } + const openSignUpModal = () => { + setSignUp(true); + setSignIn(false); + } + return ( +
+ + + {signIn && } + {signUp && } +
+ ); +} + +export default App; diff --git a/src/components/ModalContainer.tsx b/src/components/ModalContainer.tsx new file mode 100644 index 0000000..40e1168 --- /dev/null +++ b/src/components/ModalContainer.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +const inputStyle: React.CSSProperties = { + width: "100%", + height: "2rem", +} +interface ModalContainerProps { + width: string | number, + height: string | number, + children?: React.ReactNode, +} +const ModalContainer: React.FC = ({width, height, children}: ModalContainerProps) => { + const modalStyle: React.CSSProperties = { + width: width, + height: height, + position: 'fixed', + left: '50%', + top: '50%', + transform: 'translate(-50%, -50%)', + zIndex: 2, + backgroundColor: 'white', + border: '1px solid #777', + borderRadius: '2rem', + padding: '2rem', + display: 'flex', + flexDirection: 'column', + gap: '1rem', + } + return ( +
+ {children} +
+ ) +} + +export default ModalContainer +export { inputStyle } \ No newline at end of file diff --git a/src/components/SignInModal.tsx b/src/components/SignInModal.tsx new file mode 100644 index 0000000..8634346 --- /dev/null +++ b/src/components/SignInModal.tsx @@ -0,0 +1,38 @@ +import React, {useRef, useState} from 'react'; +import ModalContainer, { inputStyle } from "./ModalContainer"; + +interface SignInModalProps { + setSignIn: React.Dispatch>; +} +const SignInModal: React.FC = ({setSignIn}: SignInModalProps) => { + const idRef = useRef(null); + const passwordRef = useRef(null); + const [errorMsg, setErrorMsg] = useState(null); + const check = () => { + if(idRef.current?.value.length as number <= 0) { + idRef.current?.focus(); + setErrorMsg("id를 입력해주세요."); + return; + } + else if(passwordRef.current?.value.length as number <= 0) { + passwordRef.current?.focus(); + setErrorMsg("password를 입력해주세요."); + return; + } + alert("SignIn 성공"); + setSignIn(false); + } + return ( + + + +

{errorMsg}

+
+ + +
+
+ ) +} + +export default SignInModal; \ No newline at end of file diff --git a/src/components/SignUpModal.tsx b/src/components/SignUpModal.tsx new file mode 100644 index 0000000..2395c74 --- /dev/null +++ b/src/components/SignUpModal.tsx @@ -0,0 +1,45 @@ +import React, {useRef, useState} from 'react'; +import ModalContainer, { inputStyle } from "./ModalContainer"; + +interface SignUpModalProps { + setSignUp: React.Dispatch>; +} +const SignUpModal: React.FC = ({setSignUp}: SignUpModalProps) => { + const nameRef = useRef(null); + const idRef = useRef(null); + const passwordRef = useRef(null); + const [errorMsg, setErrorMsg] = useState(null); + const check = () => { + if(nameRef.current?.value.length as number <= 0) { + nameRef.current?.focus(); + setErrorMsg("name를 입력해주세요."); + return; + } + if(idRef.current?.value.length as number <= 0) { + idRef.current?.focus(); + setErrorMsg("id를 입력해주세요."); + return; + } + else if(passwordRef.current?.value.length as number <= 0) { + passwordRef.current?.focus(); + setErrorMsg("password를 입력해주세요."); + return; + } + alert("SignUp 성공"); + setSignUp(false); + } + return ( + + + + +

{errorMsg}

+
+ + +
+
+ ) +} + +export default SignUpModal; \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx deleted file mode 100644 index b9a1a6d..0000000 --- a/src/main.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.jsx' - -createRoot(document.getElementById('root')).render( - - - , -) diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..6924277 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,5 @@ +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')).render() diff --git a/vite.config.js b/vite.config.ts similarity index 82% rename from vite.config.js rename to vite.config.ts index 8b0f57b..9ffcc67 100644 --- a/vite.config.js +++ b/vite.config.ts @@ -1,7 +1,6 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' -// https://vite.dev/config/ export default defineConfig({ plugins: [react()], })