diff --git a/.github/workflows/delete-merged-branch-config.yml b/.github/workflows/delete-merged-branch-config.yml
new file mode 100644
index 000000000..d54933615
--- /dev/null
+++ b/.github/workflows/delete-merged-branch-config.yml
@@ -0,0 +1,14 @@
+name: delete branch on close pr
+
+on:
+ pull_request:
+ types: [closed]
+
+jobs:
+ delete-branch:
+ runs-on: ubuntu-latest
+ steps:
+ - name: delete branch
+ uses: SvanBoxel/delete-merged-branch@main
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/1-weekly-mission-week1-main/.gitignore b/1-weekly-mission-week1-main/.gitignore
deleted file mode 100644
index 722d5e71d..000000000
--- a/1-weekly-mission-week1-main/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.vscode
diff --git a/1-weekly-mission-week1-main/faq.html b/1-weekly-mission-week1-main/faq.html
deleted file mode 100644
index 6612ae103..000000000
--- a/1-weekly-mission-week1-main/faq.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
- FAQ
-
-
diff --git a/1-weekly-mission-week1-main/images/facebook.svg b/1-weekly-mission-week1-main/images/facebook.svg
deleted file mode 100644
index b9c9d4939..000000000
--- a/1-weekly-mission-week1-main/images/facebook.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/1-weekly-mission-week1-main/images/hero.png b/1-weekly-mission-week1-main/images/hero.png
deleted file mode 100644
index 11dc528fb..000000000
Binary files a/1-weekly-mission-week1-main/images/hero.png and /dev/null differ
diff --git a/1-weekly-mission-week1-main/images/image1.png b/1-weekly-mission-week1-main/images/image1.png
deleted file mode 100644
index f6355852b..000000000
Binary files a/1-weekly-mission-week1-main/images/image1.png and /dev/null differ
diff --git a/1-weekly-mission-week1-main/images/image2.png b/1-weekly-mission-week1-main/images/image2.png
deleted file mode 100644
index b9a3c674a..000000000
Binary files a/1-weekly-mission-week1-main/images/image2.png and /dev/null differ
diff --git a/1-weekly-mission-week1-main/images/image3.png b/1-weekly-mission-week1-main/images/image3.png
deleted file mode 100644
index 986a39679..000000000
Binary files a/1-weekly-mission-week1-main/images/image3.png and /dev/null differ
diff --git a/1-weekly-mission-week1-main/images/image4.png b/1-weekly-mission-week1-main/images/image4.png
deleted file mode 100644
index 762bdc960..000000000
Binary files a/1-weekly-mission-week1-main/images/image4.png and /dev/null differ
diff --git a/1-weekly-mission-week1-main/images/instagram.svg b/1-weekly-mission-week1-main/images/instagram.svg
deleted file mode 100644
index 0b9337b07..000000000
--- a/1-weekly-mission-week1-main/images/instagram.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/1-weekly-mission-week1-main/images/logo.svg b/1-weekly-mission-week1-main/images/logo.svg
deleted file mode 100644
index 282022090..000000000
--- a/1-weekly-mission-week1-main/images/logo.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/1-weekly-mission-week1-main/images/twitter.svg b/1-weekly-mission-week1-main/images/twitter.svg
deleted file mode 100644
index 14a6069a1..000000000
--- a/1-weekly-mission-week1-main/images/twitter.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/1-weekly-mission-week1-main/images/youtube.svg b/1-weekly-mission-week1-main/images/youtube.svg
deleted file mode 100644
index 28ed0e8ba..000000000
--- a/1-weekly-mission-week1-main/images/youtube.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
diff --git a/1-weekly-mission-week1-main/index.html b/1-weekly-mission-week1-main/index.html
deleted file mode 100644
index ead157b64..000000000
--- a/1-weekly-mission-week1-main/index.html
+++ /dev/null
@@ -1,114 +0,0 @@
-
-
-
-
- Linkbrary
-
-
-
-
-
-
-
-
-
- 원하는 링크를
-
- 저장하세요
-
-
- 나중에 읽고 싶은 글, 다시 보고 싶은 영상,
-
- 사고 싶은 옷, 기억하고 싶은 모든 것을
-
- 한 공간에 저장하세요.
-
-
-
-
-
- 링크를 폴더로
-
- 관리하세요
-
-
- 나만의 폴더를 무제한으로 만들고
-
- 다양하게 활용할 수 있습니다.
-
-
-
-
-
- 저장한 링크를
-
- 공유해 보세요
-
-
- 여러 링크를 폴더에 담고 공유할 수 있습니다.
-
- 가족, 친구, 동료들에게 쉽고 빠르게 링크를
-
- 공유해 보세요.
-
-
-
-
-
- 저장한 링크를
-
- 검색해 보세요
-
- 중요한 정보들을 검색으로 쉽게 찾아보세요.
-
-
-
-
-
-
diff --git a/1-weekly-mission-week1-main/privacy.html b/1-weekly-mission-week1-main/privacy.html
deleted file mode 100644
index abf71aaaf..000000000
--- a/1-weekly-mission-week1-main/privacy.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
- Privacy
-
-
diff --git a/1-weekly-mission-week1-main/signin.html b/1-weekly-mission-week1-main/signin.html
deleted file mode 100644
index 5dcac9576..000000000
--- a/1-weekly-mission-week1-main/signin.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
- 로그인
-
-
diff --git a/1-weekly-mission-week1-main/signup.html b/1-weekly-mission-week1-main/signup.html
deleted file mode 100644
index e7f60c281..000000000
--- a/1-weekly-mission-week1-main/signup.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
- 회원가입
-
-
diff --git a/1-weekly-mission-week1-main/src/reset.css b/1-weekly-mission-week1-main/src/reset.css
deleted file mode 100644
index ec6265ebe..000000000
--- a/1-weekly-mission-week1-main/src/reset.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* user agent stylesheet 초기화 */
-
-* {
- box-sizing: border-box;
- margin: 0;
- font-family: "Pretendard";
-}
-
-html,
-body {
- font-size: 62.5%;
-}
-
-a {
- color: inherit;
- text-decoration: none;
-}
diff --git a/1-weekly-mission-week1-main/src/style.css b/1-weekly-mission-week1-main/src/style.css
deleted file mode 100644
index 5759d920e..000000000
--- a/1-weekly-mission-week1-main/src/style.css
+++ /dev/null
@@ -1,180 +0,0 @@
-header {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 100%;
- background-color: #edf7ff;
-}
-
-nav {
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: fixed;
- top: 0;
- width: 100%;
- max-width: 192rem;
- height: 9.4rem;
- padding: 0 20rem;
-}
-
-.hero-header {
- display: flex;
- flex-direction: column;
- align-items: center;
- row-gap: 4rem;
- padding-top: 7rem;
-}
-
-.cta {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 5.4rem;
- cursor: pointer;
- background-image: linear-gradient(135deg, #6d6afe 0%, #6ae3fe 100%);
- border-radius: 0.8rem;
- color: #f5f5f5;
- font-size: 1.8rem;
- font-weight: 600;
-}
-
-.cta-short {
- width: 12.8rem;
-}
-
-.cta-long {
- width: 35rem;
-}
-
-.slogan {
- text-align: center;
- font-size: 6.4rem;
- font-weight: 700;
- line-height: 8rem;
-}
-
-.slogan-gradient {
- background-image: linear-gradient(119deg, #6d6afe 0%, #ff9f9f 100%);
-}
-
-.background-clip-text {
- background-clip: text;
- -webkit-background-clip: text;
- color: transparent;
-}
-
-.hero-image {
- width: 120rem;
- height: 59rem;
-}
-
-article {
- padding-top: 7rem;
- padding-bottom: 12rem;
-}
-
-section {
- display: grid;
- justify-content: center;
- column-gap: 15.7rem;
- row-gap: 1rem;
- width: 100%;
- height: 55rem;
- padding: 50px 0;
-}
-
-section:nth-of-type(odd) {
- grid-template:
- ". image"
- "title image"
- "description image"
- ". image"
- /291px 55rem;
-}
-
-section:nth-of-type(even) {
- grid-template:
- "image ."
- "image title"
- "image description"
- "image ."
- /550px 29.1rem;
-}
-
-.title {
- grid-area: title;
- font-size: 4.8rem;
- font-weight: 700;
- line-height: 5.8rem;
- letter-spacing: -0.03rem;
-}
-
-.title-1-gradient {
- background-image: linear-gradient(117deg, #fe8a8a 2.29%, #a4ceff 100%);
-}
-.title-2-gradient {
- background-image: linear-gradient(304deg, #6fbaff 0%, #ffd88b 100%);
-}
-.title-3-gradient {
- background-image: linear-gradient(133deg, #2945c7 0%, #dbe1f8 100%);
-}
-.title-4-gradient {
- background-image: linear-gradient(310deg, #fe578f 0%, #68e8f9 100%);
-}
-
-.description {
- grid-area: description;
- font-size: 1.6rem;
- font-weight: 500;
- color: #6b6b6b;
- line-height: 150%;
-}
-
-.content-image {
- grid-area: image;
- width: 55rem;
- height: 45rem;
-}
-
-footer {
- display: flex;
- justify-content: center;
- width: 100%;
- height: 16rem;
- padding-top: 3.2rem;
- background-color: #111322;
-}
-
-.footer-box {
- display: flex;
- justify-content: space-between;
- width: 100%;
- max-width: 192rem;
- height: fit-content;
- padding: 0 10.4rem;
-}
-
-.copyright {
- color: #676767;
- font-family: Arial;
- font-size: 1.6rem;
-}
-
-.footer-links {
- display: flex;
- column-gap: 3rem;
- padding-right: 1.8rem;
-}
-
-.footer-link {
- color: #cfcfcf;
- font-family: Arial;
- font-size: 1.6rem;
-}
-
-.sns {
- display: flex;
- column-gap: 1.2rem;
- height: 2rem;
-}
diff --git a/css/style.css b/css/style.css
index d16f1eef4..c47afe844 100644
--- a/css/style.css
+++ b/css/style.css
@@ -8,6 +8,7 @@
--black-color: #373740;
--btn-color: #f5f5f5;
--sns-bg-color: #e7effb;
+ --red-color: #ff5b56;
}
body {
@@ -32,6 +33,10 @@ body {
text-align: center;
}
+.join-member .logo img {
+ width: 210px;
+}
+
.join-member .logo span {
overflow: hidden;
position: absolute;
@@ -55,18 +60,18 @@ body {
border-bottom: 1px solid var(--primary-color);
}
-.form-box {
+.form-wrap {
margin: 30px 0 0;
}
-.form-box label {
+.form-wrap label {
display: block;
margin: 0 0 12px 0;
font-size: 14px;
line-height: 16px;
}
-.form-box input {
+.form-wrap input {
width: 100%;
padding: 18px 15px;
color: var(--black-color);
@@ -75,19 +80,42 @@ body {
background-color: var(--white-color);
}
-.form-box input:focus {
+.form-wrap input:focus {
border: 1px solid var(--primary-color);
}
-.form-box .password-box {
- margin: 24px 0;
+.active {
+ border: 1px solid var(--red-color) !important;
+}
+
+.error-messeage {
+ margin: 6px 0 0;
+ color: var(--red-color);
+ font-size: 14px;
+ line-height: 16px;
+}
+
+.form-box + .form-box {
+ margin: 24px 0 0;
+}
+
+.form-box .user-password {
+ position: relative;
+}
+
+.form-box .user-password img[class*="eye"] {
+ position: absolute;
+ top: 50%;
+ right: 15px;
+ transform: translateY(-50%);
+ cursor: pointer;
}
-.form-box .btn-box {
+.btn-box {
margin: 30px 0 0;
}
-.form-box .btn-box button {
+.btn-box button {
display: block;
width: 100%;
padding: 16px 20px;
@@ -102,18 +130,6 @@ body {
background: linear-gradient(90.99deg, #6D6AFE 0.12%, #6AE3FE 101.84%);
}
-.form-box .user-password {
- position: relative;
-}
-
-.form-box .user-password img[class*="eye"] {
- position: absolute;
- top: 50%;
- right: 15px;
- transform: translateY(-50%);
- cursor: pointer;
-}
-
.sns-login {
display: flex;
justify-content: space-between;
@@ -157,11 +173,11 @@ body {
}
.sns-login ul li .google {
- background: url('/images/ico-google.png') no-repeat;
+ background: url('../images/ico-google.png') no-repeat;
background-size: 100% 42px;
}
.sns-login ul li .kakao {
- background: url('/images/ico-kakao.png') no-repeat;
+ background: url('../images/ico-kakao.png') no-repeat;
background-size: 100% 42px;
}
\ No newline at end of file
diff --git a/folder.html b/folder.html
new file mode 100644
index 000000000..0cc50450c
--- /dev/null
+++ b/folder.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+ folder
+
+
\ No newline at end of file
diff --git a/js/signin.js b/js/signin.js
new file mode 100644
index 000000000..2878ef18a
--- /dev/null
+++ b/js/signin.js
@@ -0,0 +1,77 @@
+import { correct, errorMessage, emptyInput, errorPrint } from "./utils.js";
+const input = document.querySelectorAll('.input');
+const eye = document.querySelectorAll('.eye');
+const pwInput = document.getElementById('signin-password');
+const emailInput = document.getElementById('signin-email');
+const btnLogin = document.querySelector('.btn-login');
+
+// 로그인 버튼 클릭 시 페이지 이동
+function login(){
+ const { email, password } = correct.userInfo;
+
+ if(emailInput.value !== '' && pwInput.value !== ''){
+ if(emailInput.value === email && pwInput.value === password){
+ location.href = './folder.html';
+ }else{
+ emailInput.classList.add('active');
+ pwInput.classList.add('active');
+ errorPrint(emailInput, errorMessage.check);
+ errorPrint(pwInput, errorMessage.check);
+ }
+ }else{
+ emailInput.classList.add('active');
+ pwInput.classList.add('active');
+ errorPrint(emailInput, errorMessage.empty);
+ errorPrint(pwInput, errorMessage.empty);
+ }
+}
+
+// 눈 아이콘 클릭 시 이미지 및 타입 변경
+function eyeToggle(e){
+ e.preventDefault();
+
+ if(e.target.src.indexOf('off') > -1){
+ e.target.src = './images/ico-eye-on.svg';
+ pwInput.type = 'password';
+ }else{
+ e.target.src = './images/ico-eye-off.svg';
+ pwInput.type = 'text';
+ }
+}
+
+// 로그인 api
+async function userLogin(){
+ try{
+ const data = {
+ email: 'test@codeit.com',
+ password: 'sprint101',
+ }
+ const response = await fetch('https://bootcamp-api.codeit.kr/api/sign-in',{
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(data),
+ })
+
+ const { email, password } = data;
+ const takeToken = await response.json();
+ const token = await takeToken.data.accessToken;
+ localStorage.setItem('accessToken', token);
+
+ if(localStorage.getItem('accessToken')) login(email, password);
+ }catch(error){
+ console.log(error);
+ }
+}
+
+btnLogin.addEventListener('click', (e) => {
+ e.preventDefault();
+ login();
+ userLogin(emailInput, pwInput);
+});
+eye.forEach((el) => el.addEventListener('click', eyeToggle))
+input.forEach((el) => {el.addEventListener('focusout', emptyInput)})
+
+
+
diff --git a/js/signup.js b/js/signup.js
new file mode 100644
index 000000000..40393a44a
--- /dev/null
+++ b/js/signup.js
@@ -0,0 +1,118 @@
+import { correct, errorMessage, emptyInput, errorPrint, pwCheckInput } from "./utils.js";
+
+const input = document.querySelectorAll('.input');
+const pwInput = document.getElementById('signup-password');
+const emailInput = document.getElementById('signup-email');
+const eye = document.querySelectorAll('.eye');
+const btnJoin = document.querySelector('.btn-box .btn-join');
+
+// 회원가입 버튼 클릭 시 페이지 이동
+function join(){
+ const { email } = correct.userInfo;
+
+ if(emailInput.value !== email){
+ if(pwInput.value !== '' && pwCheckInput.value !== '') location.href = './folder.html';
+ }else{
+ emailInput.classList.add('active');
+ errorPrint(emailInput, errorMessage.incorrect);
+ }
+
+ if(emailInput.value === '' && pwInput.value === '') {
+ emailInput.classList.add('active');
+ pwInput.classList.add('active');
+ errorPrint(emailInput, errorMessage.empty);
+ errorPrint(pwInput, errorMessage.empty);
+ }
+}
+
+// 비밀번호, 비밀번호 확인 일치여부
+function pwCheck(){
+ if(pwInput.value !== '' && pwCheckInput.value !== ''){
+ if(pwInput.value !== pwCheckInput.value){
+ pwCheckInput.classList.add('active');
+ errorPrint(pwCheckInput, errorMessage.incorrect)
+ }
+ }
+}
+
+// 눈 아이콘 클릭 시 이미지 및 타입 변경
+function eyeToggle(e){
+ e.preventDefault();
+
+ if(e.target.src.indexOf('off') > -1){
+ e.target.src = './images/ico-eye-on.svg';
+ pwInput.type = 'password';
+ }else{
+ e.target.src = './images/ico-eye-off.svg';
+ pwInput.type = 'text';
+ }
+}
+
+// 이메일 중복체크 api
+async function emailCheck(){
+ if(emailInput.value === '') return;
+
+ try{
+ const data = {
+ email: emailInput.value,
+ }
+
+ const response = await fetch('https://bootcamp-api.codeit.kr/api/check-email',{
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(data),
+ })
+
+ if(response.status === 200){
+ const { email } = data;
+ join(email);
+ }
+ }catch(error){
+ console.log(error);
+ }
+}
+
+// 회원가입 api
+async function userJoin(emailInput, pwInput, pwCheckInput){
+ if(emailInput.value === '' && pwInput.value === '') return;
+
+ try{
+ const data = {
+ email: emailInput.value,
+ password: pwInput.value,
+ passwordCheck: pwCheckInput,
+ }
+
+ const response = await fetch('https://bootcamp-api.codeit.kr/api/sign-up',{
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(data),
+ })
+
+ const { email, password } = data;
+ const takeToken = await response.json();
+ const token = await takeToken.data.accessToken;
+ localStorage.setItem('accessToken', token);
+
+ if(localStorage.getItem('accessToken')) join(email, password);
+ }catch(error){
+ console.log(error);
+ }
+}
+
+btnJoin.addEventListener('click', (e) => {
+ e.preventDefault();
+ join();
+ emailCheck(emailInput);
+ userJoin(emailInput, pwInput);
+});
+eye.forEach((el) => el.addEventListener('click', eyeToggle))
+input.forEach((el) => {el.addEventListener('focusout', ({ target }) => {
+ emptyInput({ target });
+ pwCheck();
+})})
+
diff --git a/js/utils.js b/js/utils.js
new file mode 100644
index 000000000..7255d2350
--- /dev/null
+++ b/js/utils.js
@@ -0,0 +1,65 @@
+const pwCheckInput = document.getElementById('signup-check-password');
+const correct = {
+ pattern: {
+ email: /^[A-Za-z0-9.\-_]+@([A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/,
+ password: /^(?=.*[a-zA-Z])(?=.*[0-9]).{8,25}$/,
+ },
+ userInfo: {
+ email: 'test@codeit.com',
+ password: 'codeit101',
+ },
+}
+const errorMessage = {
+ empty: {
+ email: '이메일을 입력하세요',
+ password: '비밀번호를 입력하세요',
+ },
+ validation: {
+ email: '올바른 이메일 주소가 아닙니다.',
+ password: '비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요.',
+ },
+ check: {
+ email: '이메일을 확인해주세요.',
+ password: '비밀번호를 확인해주세요.',
+ },
+ incorrect : {
+ email: '이미 사용 중인 이메일입니다.',
+ password: '비밀번호가 일치하지않아요.',
+ },
+}
+
+// 에러 메세지
+function errorPrint(target, { email, password } = '') {
+ const errorText = document.querySelectorAll('.error-messeage');
+ if(target.type === 'email') return errorText[0].textContent = email;
+ if(pwCheckInput){
+ if(target.type === 'password'){
+ target !== pwCheckInput ? errorText[1].textContent = password : errorText[2].textContent = password;
+ }
+ }else{
+ errorText[1].textContent = password;
+ }
+}
+
+// 이메일, 비밀번호 비어있는 값 확인
+function emptyInput({ target }){
+ if(target.value === ''){
+ target.classList.add('active');
+ errorPrint(target, errorMessage.empty);
+ }else{
+ target.classList.remove('active');
+ errorPrint(target);
+ validate(target);
+ }
+}
+
+// 이메일, 비밀번호 유효성 검사
+function validate(target){
+ const { email, password } = correct.pattern;
+ if(email.test(target.value)) return;
+ if(password.test(target.value)) return;
+ target.classList.add('active');
+ errorPrint(target, errorMessage.validation);
+}
+
+export { pwCheckInput, correct, errorMessage, errorPrint, emptyInput }
\ No newline at end of file
diff --git a/signin.html b/signin.html
index 145012623..d61804810 100644
--- a/signin.html
+++ b/signin.html
@@ -5,8 +5,8 @@
로그인
-
-
+
+