Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ 4주차 기본/생각 과제 ] 🍁 로그인/회원가입 #4

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e673489
[init] 초기세팅
doyn511 Nov 14, 2023
2bc9baa
[init] react-router-dom 설치
doyn511 Nov 15, 2023
d24817a
[feat] 로그인 화면 구현
doyn511 Nov 16, 2023
b537dd7
[feat] Router 파일 생성
doyn511 Nov 16, 2023
7f4ab7c
[style] input style 변경
doyn511 Nov 16, 2023
bacdc53
[feat] 회원가입 페이지 구현
doyn511 Nov 16, 2023
903464f
[style] 회원가입 버튼 수정
doyn511 Nov 16, 2023
63df661
[feat] DATA.js Profile Img 추가
doyn511 Nov 16, 2023
27140e7
[fix] DATA.js export에 따른 import 변경
doyn511 Nov 16, 2023
469fee1
[feat] 마이페이지 구현
doyn511 Nov 16, 2023
b3956c6
[feat] axios 설치
doyn511 Nov 16, 2023
5ce52c5
[feat] Main page 추가
doyn511 Nov 16, 2023
9e7c626
[feat] Router 추가
doyn511 Nov 16, 2023
caec88f
[feat] button type 추가
doyn511 Nov 16, 2023
a97364d
[style] Wrapper tag 수정
doyn511 Nov 16, 2023
2a65b25
[feat] DATA.js type 변경
doyn511 Nov 16, 2023
0b1b762
[feat] loginPage import 삭제
doyn511 Nov 16, 2023
9873f07
[feat] .gitignore 수정
doyn511 Nov 17, 2023
4f8b13c
[feat] input props 수정
doyn511 Nov 17, 2023
fcf2000
[feat] SignUp POST 구현
doyn511 Nov 17, 2023
4f4421e
[feat] signupInput props 수정
doyn511 Nov 17, 2023
fd3977f
[feat] LoginBtn props 추가
doyn511 Nov 17, 2023
477e9a7
[feat] signupBtn props 추가
doyn511 Nov 17, 2023
c247726
[feat] Login시 mypage/{userid}로 이동
doyn511 Nov 17, 2023
e7a501a
[feat] input disabled 속성 추가
doyn511 Nov 17, 2023
d54eaf7
[feat] Wrapper tag 변경
doyn511 Nov 17, 2023
cc2e5db
[feat] mypage ID, 닉네임 get으로 불러오기
doyn511 Nov 17, 2023
4980045
[feat] 중복체크 구현
doyn511 Nov 17, 2023
accd7d9
[feat] 모든 input이 채워졌을 때 버튼 활성화
doyn511 Nov 17, 2023
16eca54
[feat] login 후 navigate 경로 변경
doyn511 Nov 17, 2023
7a8d682
[feat] id 중복체크 구현2
doyn511 Nov 17, 2023
3f1d999
[feat] 페이지 별 signup 버튼 수정
doyn511 Nov 17, 2023
7ca5a5d
[fix] 불필요 파일 제거 및 디렉토리 이동
doyn511 Nov 17, 2023
4edd7b2
[fix] .gitignore 추가
doyn511 Nov 17, 2023
a0b8299
[docs] 생각과제
doyn511 Nov 17, 2023
8ac8639
[fix] 필요없는 파일 및 주석 제거
doyn511 Nov 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
.DS_Store
.DS_Store

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

.env
20 changes: 20 additions & 0 deletions week4/assignment/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
26 changes: 26 additions & 0 deletions week4/assignment/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

.env
8 changes: 8 additions & 0 deletions week4/assignment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
12 changes: 12 additions & 0 deletions week4/assignment/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>로그인 | 회원가입</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
28 changes: 28 additions & 0 deletions week4/assignment/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "assignment",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"vite": "^4.4.5"
}
}
15 changes: 15 additions & 0 deletions week4/assignment/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// import Router from "./components/Router";
import LogInPage from "./pages/login/LoginPage";
import MyPage from "./pages/mypage/MyPage";
import SignUp from "./pages/signup/SignupPage";
import Router from "./Router";

function App() {
return (
<>
<Router />
</>
);
}

export default App;
22 changes: 22 additions & 0 deletions week4/assignment/src/Router.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BrowserRouter, Route, Routes } from "react-router-dom";
import MainPage from "./pages/main/MainPage";
import LogIn from "./pages/login/LoginPage";
import SignUp from "./pages/signup/SignupPage";
import MyPage from "./pages/mypage/MyPage";

function Router() {
return (
<>
<BrowserRouter>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/login" element={<LogIn />} />
<Route path="/signup" element={<SignUp />}></Route>
<Route path="/mypage/:userId" element={<MyPage />}></Route>
</Routes>
</BrowserRouter>
</>
);
}

export default Router;
29 changes: 29 additions & 0 deletions week4/assignment/src/assets/DATA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const TypeList = [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

완전 깔끔하네요!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수 이름은 주로 대문자 + 스네이크 표기법을 이용합니다!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그러면 TYPE_LIST가 되겠네요!

{
key: "ID",
title: "ID",
type: "text",
placeholder: "아이디를 입력해주세요",
},
{
key: "Password",
title: "비밀번호",
type: "text",
placeholder: "비밀번호를 입력해주세요",
},
{
key: "ConfirmPassword",
title: "비밀번호 확인",
type: "text",
placeholder: "비밀번호를 다시 한 번 입력해주세요",
},
{
key: "Nickname",
title: "닉네임",
type: "text",
placeholder: "닉네임을 입력해주세요",
},
];

export const Profile =
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 마찬가지로 PROFILE로 바꿔줄 수 있겠네요!

"https://mblogthumb-phinf.pstatic.net/MjAyMjEwMjRfMjMy/MDAxNjY2NTQxNTAzMzI5.xQSPMKxEVSKTshiz7jCMBkKoHZcKWN7DPiSY5uFXj-4g.UrtqDuXKmjWV5delpGbQQ_JIiexPpsMQAEpnIKa304Eg.JPEG.gogoa25/IMG_7098.JPG?type=w800";
39 changes: 39 additions & 0 deletions week4/assignment/src/components/common/idCheckBtn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import styled from "styled-components";

const IdCheckBtn = ({ onClick, isIdValid }) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요고 파일이 소문자로 시작하는 거 같은데,,,! 컴포넌트는 대문자로 시작해야 하니까 파일이름들도 대문자로 바꿔주는 게 좋을 것 같은데,,,!

return (
<>
{isIdValid === null && <Button onClick={onClick}>중복 체크</Button>}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하나씩 스타일컴포넌트로 만든지 않고 스타일 컴포넌트에서 조건부 스타일링으로 하는게 나을거같아요!

{isIdValid === true && (
<IsValidBtn onClick={onClick}>중복 체크</IsValidBtn>
)}
{isIdValid === false && (
<IsNotValidBtn onClick={onClick}>중복 체크</IsNotValidBtn>
)}
</>
);
};

export default IdCheckBtn;

const Button = styled.button`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 스타일컴포넌트도 컴포넌트니까 이 컴포넌트가 무엇을 하는 친구인지 바로 알수 있는 이름을 지어야 나중에 헷갈리지 않겠죵?

width: 5.5rem;
height: 2.2rem;

padding: 0.3rem;

border: none;

background-color: #000000;
color: #ffffff;

cursor: pointer;
`;

const IsValidBtn = styled(Button)`
background-color: #23ac21;
`;

const IsNotValidBtn = styled(Button)`
background-color: #f75757;
`;
Comment on lines +4 to +39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (
<>
{isIdValid === null && <Button onClick={onClick}>중복 체크</Button>}
{isIdValid === true && (
<IsValidBtn onClick={onClick}>중복 체크</IsValidBtn>
)}
{isIdValid === false && (
<IsNotValidBtn onClick={onClick}>중복 체크</IsNotValidBtn>
)}
</>
);
};
export default IdCheckBtn;
const Button = styled.button`
width: 5.5rem;
height: 2.2rem;
padding: 0.3rem;
border: none;
background-color: #000000;
color: #ffffff;
cursor: pointer;
`;
const IsValidBtn = styled(Button)`
background-color: #23ac21;
`;
const IsNotValidBtn = styled(Button)`
background-color: #f75757;
`;
return (
<>
<IsValidButton isValid={isValid} onClick={onClick}>중복 체크</IsValidButton>
</>
);
};
export default IdCheckBtn;
const IsValidButton = styled.button`
width: 5.5rem;
height: 2.2rem;
padding: 0.3rem;
border: none;
background-color: ${({ isValid, theme} => isValid == null ? theme.color.black : isValid ? theme.color.green: theme.color.red)}
cursor: pointer;
`;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런식으로!! 아그리고 요것도 공부해보는 게 좋을 것 같아! 나도 아직 익숙하지는 않지만,,, styledcomponent transient props

34 changes: 34 additions & 0 deletions week4/assignment/src/components/common/input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from "styled-components";

const PerInput = ({ title, type, placeholder, value, onChange, disabled }) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 받아오는 인자가 많을 땐 하나의 인자로 받아서 그 부분을 구조 분해 할당으로 바꿔주는 건 어때요?

Suggested change
const PerInput = ({ title, type, placeholder, value, onChange, disabled }) => {
const PerInput = ({ title, type, placeholder, value, onChange, disabled }) => {
CONST PerInput = (props) => {
const {title, type, placeholder, value, onChange, disabled}= props

return (
<InputWrapper>
<Title>{title}</Title>
<Input
type={type}
placeholder={placeholder}
value={value}
onChange={onChange}
disabled={disabled}
/>
</InputWrapper>
);
};

export default PerInput;

const InputWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;

const Title = styled.h2`
font-size: 1.1rem;
`;

const Input = styled.input`
width: 60%;
height: 1.5rem;
padding: 0.3rem;
`;
17 changes: 17 additions & 0 deletions week4/assignment/src/components/common/loginBtn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import styled from "styled-components";
import { Btn } from "../../styles/CommonStyle";

const LoginBtn = ({ onClick }) => {
return (
<>
<Button onClick={onClick}>로그인</Button>
</>
);
};

export default LoginBtn;

const Button = styled(Btn)`
background-color: #030046;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우리 담에는 꼬옥 theme 반영해볼까!!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

딱 필요한 부분만 빼서 쓸 수 있고 정말 편해! 그리고 스닙챗 설치해 놓았다면
scpt 하나로 바로 theme 불러오는 로직이 또로록 생기니까 더 편하답니당!

color: #ffffff;
`;
9 changes: 9 additions & 0 deletions week4/assignment/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";

ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
71 changes: 71 additions & 0 deletions week4/assignment/src/pages/login/loginPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import axios from "axios";
import styled from "styled-components";
import PerInput from "../../components/common/input";
import { Wrapper, Title, Btn } from "../../styles/CommonStyle";
import { TypeList } from "../../assets/DATA";
import LoginBtn from "../../components/common/loginBtn";
import { useNavigate } from "react-router-dom";
import { useState } from "react";

const LogInPage = () => {
const [inputUsername, setInputUsername] = useState("");
const [inputPW, setInputPW] = useState("");
const [isLoginPage, setIsLoginPage] = useState(true);

const navigate = useNavigate();

const handlePost = async () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 이런 부분 함수 따로 빼주는 것도 너무 좋겠다!

try {
const response = await axios.post(
`${import.meta.env.VITE_APP_BASE_URL}/api/v1/members/sign-in`,
{
username: inputUsername,
password: inputPW,
}
);
navigate(`/mypage/${response.data.id}`);
} catch (error) {
console.log(error);
}
};

const GoToSignUp = () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 한번에 이동하는 거니까 Link 컴포넌트를 사용하는 게 더 좋을 것 같아요!
useNavigate랑 Link랑 차이점을 알고 있으면 더 편하겠죠?
Link vs useNavigate

navigate("/signup");
};

return (
<>
<Wrapper>
<Title>로그인</Title>
<PerInput
title={TypeList[0].title}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요부분도 상수에서 가지고 온 부분이니까 TYPE_LIST가 되겠죠?근데 두개 쓰고 있는 것 같은데,,, 차라리, const LOGIN_TYPE = TYPE_LIST[0] 이런식으로 상수를 하나 더 지정해주고 넣으면 어때요?

type={TypeList[0].type}
placeholder={TypeList[0].placeholder}
value={inputUsername}
onChange={(e) => {
setInputUsername(e.target.value);
}}
/>
<PerInput
title={TypeList[1].title}
type={TypeList[1].type}
placeholder={TypeList[1].placeholder}
value={inputPW}
onChange={(e) => {
setInputPW(e.target.value);
}}
/>
<LoginBtn onClick={handlePost} />
<SignUpBtn type="button" onClick={GoToSignUp} isLoginPage={isLoginPage}>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isLoginPage는 혹시 기능이 뭘ㄲㅏ요?

회원가입
</SignUpBtn>
</Wrapper>
</>
);
};

export default LogInPage;

const SignUpBtn = styled(Btn)`
background-color: #fffffff;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기 f가 7개 들어갔다!!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혜인언니 말대로 theme 한번 써보는 거 추천!!!!

`;
Loading