diff --git a/css/colors.css b/css/colors.css new file mode 100644 index 000000000..9ebca4a70 --- /dev/null +++ b/css/colors.css @@ -0,0 +1,16 @@ +:root { + --primary: #6D6AFE; + --red: #FF5B56; + --black: #111322; + --white: #ffffff; + + --gray-100: #3E3E43; + --gray-60: #9FA6B2; + --gray-20: #CCD5E3; + --gray-10: #E7EFFB; + + --bg: #F0F6FF; + + /* --linkbrary-gradation: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); + --fandom-k-gra-blue-to-pink: linear-gradient(271deg, #FE578F -9.84%, #68E8F9 107.18%); */ +} \ No newline at end of file diff --git a/css/global.css b/css/global.css new file mode 100644 index 000000000..fc4428003 --- /dev/null +++ b/css/global.css @@ -0,0 +1,2 @@ +@import "./colors.css"; +@import "./reset.css"; \ No newline at end of file diff --git a/css/landing.css b/css/landing.css new file mode 100644 index 000000000..8c154e6cd --- /dev/null +++ b/css/landing.css @@ -0,0 +1,343 @@ +@import "./global.css"; + +body { + display: flex; + flex-direction: column; + align-items: center; +} + +nav { + display: flex; + justify-content: center; + position: sticky; + top: 0; + width: 100%; + background-color: #edf7ff; +} + +.gnb { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + height: 6.3rem; + padding: 0 3.2rem; + + /* Tablet */ + @media (min-width: 768px) { + height: 9.4rem; + max-width: 86.3rem; + } + + /* PC */ + @media (min-width: 1200px) { + height: 9.4rem; + max-width: 192rem; + padding: 0 20rem; + } +} + +.logo { + height: 1.6rem; + + @media (min-width: 768px) { + height: 2.4rem; + } +} + +header { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + background-color: #edf7ff; +} + +.hero-header { + display: flex; + flex-direction: column; + align-items: center; + row-gap: 2.4rem; + padding: 2.8rem 3.2rem 0; + + @media (min-width: 768px) { + padding: 3.9rem 0 0; + row-gap: 4rem; + } + + @media (min-width: 1200px) { + padding: 7rem 0 0; + } +} + +.cta { + display: flex; + justify-content: center; + align-items: center; + height: 3.7rem; + cursor: pointer; + background-image: linear-gradient(135deg, var(--primary) 0%, #6ae3fe 100%); + border-radius: 0.8rem; + color: #f5f5f5; + font-size: 1.4rem; + font-weight: 600; + + @media (min-width: 768px) { + height: 5.4rem; + border-radius: 0.8rem; + font-size: 1.8rem; + } +} + +.cta-short { + width: 8rem; + + @media (min-width: 768px) { + width: 12.8rem; + } +} + +.cta-long { + width: 20rem; + + @media (min-width: 768px) { + width: 35rem; + } +} + +.slogan { + width: 24rem; + text-align: center; + font-size: 3.2rem; + line-height: 131.25%; + font-weight: 700; + + @media (min-width: 768px) { + width: 48rem; + font-size: 6.4rem; + line-height: 125%; + } + + @media (min-width: 1200px) { + width: 80rem; + } +} + +.slogan-gradient { + background-image: linear-gradient(119deg, var(--primary) 0%, #ff9f9f 100%); +} + +.background-clip-text { + background-clip: text; + -webkit-background-clip: text; + color: transparent; +} + +.hero-image { + width: 100%; + height: fit-content; + @media (min-width: 768px) { + width: 69.8rem; + height: 34.3rem; + } + + @media (min-width: 1200px) { + width: 120rem; + height: 59rem; + } +} + +article { + padding-bottom: 4rem; + + @media (min-width: 768px) { + padding-top: 3rem; + padding-bottom: 12rem; + } + + @media (min-width: 1200px) { + padding-top: 7rem; + } +} + +section { + display: grid; + justify-content: center; + row-gap: 1.6rem; + width: 100%; + height: fit-content; + padding: 4rem 3.2rem; + + @media (min-width: 768px) { + height: 41.5rem; + column-gap: 5.1rem; + row-gap: 1rem; + padding: 5rem 0; + } + + @media (min-width: 1200px) { + height: 55rem; + column-gap: 15.7rem; + } +} + +section:nth-of-type(odd) { + grid-template-areas: + "title" + "image" + "description"; + + @media (min-width: 768px) { + grid-template-areas: + ". image" + "title image" + "description image" + ". image"; + grid-template-columns: 26.2rem 38.5rem; + } + + @media (min-width: 1200px) { + grid-template-columns: 29.1rem 55rem; + } +} + +section:nth-of-type(even) { + grid-template: + "title" + "image" + "description"; + + @media (min-width: 768px) { + grid-template-areas: + "image ." + "image title" + "image description" + "image ."; + grid-template-columns: 38.5rem 26.2rem; + } + + @media (min-width: 1200px) { + grid-template-columns: 55rem 29.1rem; + } +} + +.title { + grid-area: title; + font-weight: 700; + letter-spacing: -0.03rem; + font-size: 2.4rem; + + @media (min-width: 768px) { + font-size: 4.8rem; + line-height: 5.8rem; + } +} + +.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.5rem; + font-weight: 500; + color: #6b6b6b; + line-height: 150%; + + @media (min-width: 768px) { + font-size: 1.6rem; + } +} + +.line-break-tablet-desktop { + display: none; + + @media (min-width: 768px) { + display: inline; + } +} + +.content-image { + grid-area: image; + width: 100%; + padding-top: 0.4rem; + + @media (min-width: 768px) { + width: 38.5rem; + height: 31.5rem; + padding-top: 0; + } + + @media (min-width: 1200px) { + width: 55rem; + height: 45rem; + } +} + +footer { + display: flex; + justify-content: center; + width: 100%; + height: 16rem; + background-color: var(--black); +} + +.footer-box { + display: grid; + justify-content: space-between; + grid-template: + "footer-links sns" + ". ." 1fr + "copyright ."; + width: 100%; + padding: 3.2rem; + + @media (min-width: 768px) { + display: flex; + justify-content: space-between; + grid-template: "copyright footer-links sns"; + height: fit-content; + max-width: 192rem; + padding: 3.2rem 10.4rem 0; + } +} + +.copyright { + grid-area: copyright; + color: #676767; + font-family: Arial; + font-size: 1.6rem; +} + +.footer-links { + grid-area: footer-links; + display: flex; + column-gap: 3rem; + padding-right: 1.8rem; +} + +.footer-link { + color: #cfcfcf; + font-family: Arial; + font-size: 1.6rem; +} + +.sns { + grid-area: sns; + display: flex; + column-gap: 1.2rem; + height: 2rem; +} + +.sns img { + height: 2rem; +} diff --git a/css/reset.css b/css/reset.css new file mode 100644 index 000000000..098f48b41 --- /dev/null +++ b/css/reset.css @@ -0,0 +1,26 @@ +* { + box-sizing: border-box; + margin: 0; + font-family: "Pretendard", sans-serif; +} + +html, body { + font-size: 62.5%; +} + +a { + text-decoration: none; + cursor: pointer; + color: inherit; +} + +input:focus { + outline: none; +} + +button { + border: none; + padding: unset; + background-color: unset; + cursor: pointer; +} \ No newline at end of file diff --git a/css/sign.css b/css/sign.css new file mode 100644 index 000000000..b9a860feb --- /dev/null +++ b/css/sign.css @@ -0,0 +1,180 @@ +@import "./global.css"; + +body { + padding: 12rem 3.2rem 0; + background-color: var(--bg); + display: flex; + flex-direction: column; + align-items: center; + row-gap: 3rem; + + @media (min-width: 768px) { + padding: 20rem 0 0; + } + + @media (min-width: 1200px) { + padding: 23.8rem 0 0; + } +} + +header { + display: flex; + flex-direction: column; + row-gap: 1.6rem; +} + +.logo-link { + display: flex; + justify-content: center; +} + +.header-logo { + height: 3.8rem; +} + +.header-message { + display: flex; + column-gap: 0.8rem; + font-size: 1.6rem; + font-weight: 400; + line-height: 150%; +} + +.header-link { + height: fit-content; + font-size: 1.6rem; + font-weight: 600; + line-height: normal; + color: var(--primary); + border-bottom: 0.1rem solid var(--primary); +} + +.sign-box { + display: flex; + flex-direction: column; + align-items: center; + row-gap: 3.2rem; + width: 40rem; + + @media (min-width: 768px) { + width: 40rem; + } +} + +.sign-form { + display: flex; + flex-direction: column; + row-gap: 3rem; + width: 100%; +} + +.sign-inputs { + display: flex; + flex-direction: column; + row-gap: 2.4rem; +} + +.sign-input-box { + display: flex; + flex-direction:column; + row-gap: 1.2rem; +} + +.sign-password { + position: relative; +} + +.sign-input-label { + font-size: 1.4rem; + font-weight: 400; +} + +.sign-input { + padding: 1.8rem 1.5rem; + border-radius: 0.8rem; + border: 0.1rem solid var(--gray-20); + font-size: 1.6rem; + line-height: 150%; +} + +.sign-input:focus { + border-color: var(--primary); +} + +.sign-input.red-border { + border: 0.1rem solid var(--red); +} + +.fail-message { + margin: -0.6rem 0 0; + color: var(--red); + font-size: 1.4rem; + font-weight: 400; +} + +.hide { + display: none; +} + +.eye-button, +.eye-button2 { + position: absolute; + top: 5.1rem; + right: 1.5rem; + width: 1.6rem; + height: 1.6rem; +} + +.cta { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 5.4rem; + background-image: linear-gradient(135deg, var(--primary) 0%, #6ae3fe 100%); + border-radius: 0.8rem; + color: #f5f5f5; + font-size: 1.8rem; + font-weight: 600; +} + +.sns-box { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 1.2rem 2.4rem; + border-radius: 0.8rem; + border: 0.1rem solid var(--gray-20); + background-color: var(--gray-10); +} + +.sns-links { + display: flex; + column-gap: 1.6rem; +} + +.sns-link { + display: flex; + justify-content: center; + align-items: center; + width: 4.2rem; + height: 4.2rem; + border-radius: 50%; +} + +.sns-text { + font-size: 1.4rem; + font-weight: 400; + color: var(--gray-100); +} + +.google-link { + background-color: var(--white); + border: 0.1rem solid #d3d4dd; +} + +.kakao-link { + padding-top: 0.2rem; + background-color: #f5e14b; +} \ No newline at end of file diff --git a/faq.html b/faq.html new file mode 100644 index 000000000..e69de29bb diff --git a/folder.html b/folder.html new file mode 100644 index 000000000..7d6ee8ef0 --- /dev/null +++ b/folder.html @@ -0,0 +1,10 @@ + + + + + 폴더 + + + 로그인 성공! + + \ No newline at end of file diff --git a/img/default.png b/img/default.png new file mode 100644 index 000000000..2ed0923ef Binary files /dev/null and b/img/default.png differ diff --git a/img/eye-off.png b/img/eye-off.png deleted file mode 100644 index 2427f86dc..000000000 Binary files a/img/eye-off.png and /dev/null differ diff --git a/img/eye-off.svg b/img/eye-off.svg new file mode 100644 index 000000000..bec50d66f --- /dev/null +++ b/img/eye-off.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/img/eye-on.svg b/img/eye-on.svg new file mode 100644 index 000000000..61afee898 --- /dev/null +++ b/img/eye-on.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/img/image 25.png b/img/hero.png similarity index 100% rename from img/image 25.png rename to img/hero.png diff --git a/img/meta-image.png b/img/meta-image.png new file mode 100644 index 000000000..38a9b47b9 Binary files /dev/null and b/img/meta-image.png differ diff --git a/index.css b/index.css deleted file mode 100644 index ea2d2848f..000000000 --- a/index.css +++ /dev/null @@ -1,231 +0,0 @@ -:root { - --linkbrary-primary: #6D6AFE; - --linkbrary-red: #FF5B56; - --linkbrary-black: #111322; - --linkbrary-white: #ffffff; - --linkbrary-gray-100: #3E3E43; - --linkbrary-gray-60: #9FA6B2; - --linkbrary-gray-20: #CCD5E3; - --linkbrary-gray-10: #E7EFFB; - --linkbrary-bg: #F0F6FF; - --linkbrary-gradation: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); - --fandom-k-gra-blue-to-pink: linear-gradient(271deg, #FE578F -9.84%, #68E8F9 107.18%); -} - -* { - box-sizing: border-box; -} - -html { - font-family: Pretendard, sans-serif; - word-break: keep-all; -} - -body { - margin: 0; - color: var(--linkbrary-black); - background-color: var(--linkbrary-white); -} - -.gnb-default { - position: fixed; - top: 0; - left: 0; - right: 0; - height: 94px; - padding: 20px; - background-color: var(--linkbrary-bg); -} - -.gnb-wrap { - display: flex; - justify-content: space-between; - align-items: center; - margin: 0 auto; - max-width: 1480px; - width: 100% -} - -.logo { - width: 133px; - height: 24px; -} - -.bnt-cta.large { - display: flex; - justify-content: center; - align-items: center; - padding: 16px 20px; - border-radius: 8px; - text-decoration: none; - font-size: 18px; - font-weight: 600; - color: #f5f5f5; - background-image: var(--linkbrary-gradation); - cursor: pointer; -} - -.gnb-wrap .bnt-cta.large { - width: 128px; -} - -.main-contents .bnt-cta.large { - width: 350px; -} - -main { - margin-top: 94px; - background-color: var(--linkbrary-bg); -} - -.main-contents { - display: flex; - flex-direction: column; - align-items: center; - gap: 40px; - max-width: 1200px; - width: 100%; - margin: 70px auto 0; - padding-top: 70px; -} - -.heading { - margin: 0; - text-align: center; - font-size: 64px; - font-weight: 700; - line-height: 1.25; -} - -.heading-point { - /* font-gradient-filter */ - background: linear-gradient(91deg, #6D6AFE 17.28%, #ff9f9f 74.98%); - background-clip: text; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; -} - -.main-img { - flex: 1 1 auto; - max-width: 1200px; - width: 100%; -} - -.section-wrap { - margin: 70px 0 0; -} - -.boxes { - display: flex; - justify-content: space-between; - align-items: center; - gap: 24px; - max-width: 1118px; - margin: 0 auto; - padding: 50px 60px; -} - -.box-img { - /* flex-shrink: 0; */ - width: 550px; - height: 450px; -} - -.box-img img{ - width: 100%; -} - -.box-text { - /* flex-shrink: 0; */ - width: 291px; -} - -.box-text h2 { - margin: 0 0 10px; - color: #000; - font-size: 48px; - font-weight: 700; - line-height: normal; - letter-spacing: -0.3px; -} - -.box-text p { - margin: 0; - font-size: 16px; - font-weight: 500; - line-height: 1.5; /* 24px */ - color: #6B6B6B; -} - -.box-point-1 { - background: linear-gradient(96deg, #FE8A8A 1.72%, #A4CEFF 74.97%); - background-clip: text; -} - -.box-point-2 { - background: linear-gradient(277deg, #6FBAFF 59.22%, #FFD88B 93.66%); - background-clip: text; -} - -.box-point-3 { - background: linear-gradient(99deg, #6D7CCD 19.76%, rgba(82, 136, 133, 0.22) 52.69%); - background-clip: text; -} - -.box-point-4 { - background: var(--fandom-k-gra-blue-to-pink); - background-clip: text; -} - -.box-point-1, -.box-point-2, -.box-point-3, -.box-point-4 { - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; -} - -footer { - height: 160px; - margin: 120px 0 0; - background-color: var(--linkbrary-black); -} - -.footer-wrap { - display: flex; - justify-content: space-between; - margin: 32px auto 76px; - padding: 32px; - font-family: Arial; - font-size: 16px; - font-weight: 400; - text-align: center; -} - -.footer-company { - color: #676767; -} - - -.footer-menu { - display: flex; - gap: 30px; -} - -.footer-menu a { - text-decoration: none; - color: #CFCFCF; - cursor: pointer; -} - -.footer-sns { - display: flex; - justify-content: flex-end; - gap: 12px; -} - -.footer-sns a img { - width: 20px; - height: 20px; -} - diff --git a/index.html b/index.html index fdba91109..7607d2d15 100644 --- a/index.html +++ b/index.html @@ -1,115 +1,131 @@ - - - - Linkbrary - - - - -
-
- - 로그인 -
-
-
-
-

- 세상의 모든 정보
- 쉽게 저장하고 관리해 보세요 -

- 링크 추가하기 - 메인 홈페이지 이미지 -
-
-
-
-
-

- 원하는 링크
- 저장하세요

+ + + + Linkbrary + + + + + + + + + + + + + + +
+
+

+ 세상의 모든 정보를 +
+ 쉽게 저장하고 관리해 보세요 +

+ + 링크 추가하기 + + Linkbrary 서비스 소개 +
+
+
+
+

+ 원하는 링크를 저장하세요 +

- 나중에 읽고 싶은 글, 다시 보고 싶은 영상,
- 사고 싶은 옷, 기억하고 싶은 모든 것을
+ 나중에 읽고 싶은 글, 다시 보고 싶은 영상, +
+ 사고 싶은 옷, 기억하고 싶은 모든 것을 +
한 공간에 저장하세요.

-
-
- 링크 저장 이미지 -
- -
- -
-
- 폴더 관리 이미지 -
-
-

- 링크를 폴더로
- 관리로 관리하세요

+ 링크의 내용이 담긴 카드들 +
+
+

+ 링크를 폴더로 + 관리하세요 +

- 나만의 폴더를 무제한으로 만들고
+ 나만의 폴더를 무제한으로 만들고 +
다양하게 활용할 수 있습니다.

- - - -
-
-

- 저장한 링크를
- 공유해보세요 + 폴더 이름 변경 기능 +

+
+

+ 저장한 링크를 + 공유해 보세요

- 여러 링크를 폴더에 담고 공유할 수 있습니다.
- 가족, 친구, 동료들에게 쉽고 빠르게 링크를
+ 여러 링크를 폴더에 담고 공유할 수 있습니다. 가족, 친구, 동료들에게 쉽고 빠르게 링크를 공유해 보세요.

+ 폴더 공유 기능 +
+
+

+ 저장한 링크를 + 검색해 보세요 +

+

중요한 정보들을 검색으로 쉽게 찾아보세요.

+ 링크 검색 기능 +
+ + + + diff --git a/privacy.html b/privacy.html new file mode 100644 index 000000000..e69de29bb diff --git a/screenshot/index1.png b/screenshot/index1.png deleted file mode 100644 index f9862112c..000000000 Binary files a/screenshot/index1.png and /dev/null differ diff --git a/screenshot/index2.png b/screenshot/index2.png deleted file mode 100644 index b69a72159..000000000 Binary files a/screenshot/index2.png and /dev/null differ diff --git a/screenshot/index3.png b/screenshot/index3.png deleted file mode 100644 index 329de5a7d..000000000 Binary files a/screenshot/index3.png and /dev/null differ diff --git a/screenshot/index4.png b/screenshot/index4.png deleted file mode 100644 index 59b16fc49..000000000 Binary files a/screenshot/index4.png and /dev/null differ diff --git a/screenshot/signin.png b/screenshot/signin.png deleted file mode 100644 index cb6d9565b..000000000 Binary files a/screenshot/signin.png and /dev/null differ diff --git a/screenshot/signup.png b/screenshot/signup.png deleted file mode 100644 index 4d2d6ce1a..000000000 Binary files a/screenshot/signup.png and /dev/null differ diff --git a/sign.css b/sign.css deleted file mode 100644 index 1bd783993..000000000 --- a/sign.css +++ /dev/null @@ -1,181 +0,0 @@ -:root { - --linkbrary-primary: #6D6AFE; - --linkbrary-red: #FF5B56; - --linkbrary-black: #111322; - --linkbrary-white: #ffffff; - --linkbrary-gray-100: #3E3E43; - --linkbrary-gray-60: #9FA6B2; - --linkbrary-gray-20: #CCD5E3; - --linkbrary-gray-10: #E7EFFB; - --linkbrary-bg: #F0F6FF; - --linkbrary-gradation: linear-gradient(91deg, #6D6AFE 0.12%, #6AE3FE 101.84%); - --fandom-k-gra-blue-to-pink: linear-gradient(271deg, #FE578F -9.84%, #68E8F9 107.18%); - --black: #000 -} - -* { - box-sizing: border-box; -} - -/* input { - outline: none; - border: none; - background-color: none; -} */ - -html { - font-family: Pretendard, sans-serif; - word-break: keep-all; -} - -body { - margin: 0; - font-size: 16px; - font-weight: 400; - line-height: 1.5; - color: var(--black); - background-color: var(--linkbrary-bg); -} - -.wrap { - margin: 238px auto; - width: 400px; -} - -.logo-sign { - display: flex; - flex-direction: column; - align-items: center; - gap: 16px; - margin-bottom: 30px; -} - -.logo-btn { - margin: 0; - height: 38px; -} - -.logo-sign p { - margin: 0; - text-align: center; -} - -.sign-box { - display: flex; - justify-content: center; - align-items: flex-start; - gap: 8px; -} - -.sign-btn { - display: flex; - flex-direction: column; - align-items: center; - gap: 0; -} - -.sign-btn a{ - text-decoration: none; - font-weight: 600; - line-height: normal; - color: var(--linkbrary-primary); -} - -.underline { - width: 100%; - height: 1px; - background-color: var(--linkbrary-primary); -} - -.input-box { - position: relative; - display: flex; - flex-direction: column; - gap: 12px; - margin-bottom: 24px; -} - -.label { - font-size: 14px; - line-height: normal; -} - -.box { - padding: 18px 15px; - height: 60px; - border-radius: 8px; - border: 1px solid var(--linkbrary-gray-20); - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 1.5; - background-color: var(--linkbrary-white); -} - -.box:focus{ - outline: none; - border: 1px solid var(--linkbrary-primary); -} - -.show-hide-icon { - position: absolute; - bottom: 22px; - right: 15px; - width: 16px; - height: 16px; -} - -.login-btn { - width: 100%; - height: 60px; -} - -.bnt-cta.large { - display: flex; - justify-content: center; - align-items: center; - width: 400px; - margin: 30px 0 32px; - padding: 16px 20px; - border: none; - border-radius: 8px; - text-decoration: none; - font-size: 18px; - font-weight: 600; - color: #f5f5f5; - background-image: var(--linkbrary-gradation); - cursor: pointer; -} - -.sns-login-btn { - display: flex; - justify-content: space-between; - align-items: center; - gap: 16px; - width: 400px; - padding: 12px 24px; - border-radius: 8px; - border: 1px solid var(--linkbrary-gray-20); - background: var(--linkbrary-gray-10); - cursor: pointer; -} - -.sns-login-btn p { - flex-grow: 1; - margin: 0; - font-size: 14px; - font-weight: 400; - line-height: normal; - color: var(--linkbrary-gray-100, #373740); -} - -.sns-btn { - margin: 0; - width: 42px; - height: 42px; - cursor: pointer; -} - -.sns-btn img { - width: 100%; -} \ No newline at end of file diff --git a/signin.html b/signin.html deleted file mode 100644 index 55ba9e070..000000000 --- a/signin.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - -
-
-
- - 로고 - -
- 회원이 아니신가요? - -
-
-
- - -
-
- - -
-
- -
-
-

소셜 로그인

- - 구글 - - - 카카오톡 - -
-
- - \ No newline at end of file diff --git a/signin/signIn.js b/signin/signIn.js new file mode 100644 index 000000000..d199c61c7 --- /dev/null +++ b/signin/signIn.js @@ -0,0 +1,104 @@ +import { + EMAIL_REGEX, + PW_REGEX, + resetErr, + printErr, + codeitApi, +} from "../utils/utils.js"; + +export const userEmail = document.querySelector('#user-email'); +export const userPw = document.querySelector('#user-password'); +export const eyeImg = document.querySelector('.eye-image'); +export const signInForm = document.querySelector('.sign-form'); + +/* 이메일 체크 (미입력, 유효성) */ +function emailChk( email ) { + resetErr( email ); + if( email.value.length === 0 ){ + printErr( email, '이메일을 입력해주세요.'); + return false; + } + if( !EMAIL_REGEX.test( email.value )){ + printErr( email, '올바른 이메일 주소가 아닙니다.'); + return false; + } + return true; +} + +userEmail.addEventListener('focusout',(e) => emailChk( e.target ) ); + +/* 비밀번호 체크 (미입력, 유효성) */ +export function pwChk( pw ){ + resetErr( pw ); + if ( pw.value.length === 0 ){ + printErr( pw, '비밀번호를 입력해주세요.'); + return false; + } + if ( !PW_REGEX.test( pw.value ) ){ + printErr( pw, '비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요.'); + return false; + } + return true; +} + +userPw.addEventListener('focusout', (e) => pwChk( e.target ) ); + +/* 눈이미지와 비번 감추기 */ +export function pwShowHide(){ + if( userPw.type === "password"){ + eyeImg.src = "../img/eye-on.svg" + userPw.type = "text"; + } else if (userPw.type === "text"){ + eyeImg.src = "../img/eye-off.svg" + userPw.type = "password"; + } +} + +eyeImg.addEventListener('click', (e)=>{ + e.preventDefault(); + pwShowHide(); +} ); + +/* 로그인 시도 함수 */ +async function signInSubmit(e) { + e.preventDefault(); + + const emailResult = emailChk( userEmail ); + const pwResult = pwChk( userPw ); + const userInfo = { + email : userEmail.value, + password : userPw.value, + }; + const p = new Promise(( resolve, reject ) => { + if( emailResult && pwResult ){ + resolve( accessApi( userInfo, 'sign-in' ) ), + reject( + resetErr( userEmail ), + resetErr( userPw ), + printErr( userEmail, '이메일을 확인해주세요.'), + printErr( userPw, '비밀번호를 확인해주세요.'),) + } + }) +} + +/* 로그인, 회원가입시 api 요청과 응답을 받기 */ +export async function accessApi( userInfo, path ){ + try { + const response = await fetch(`${codeitApi}/${path}`,{ + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify( userInfo ), + }); + if( response.ok ){ + const result = await response.json(); + localStorage.setItem( 'signInAccessToken', result.accessToken ); + location.href = "../folder.html"; + } + } catch (error){ + throw new Error('실패했습니다.'); + } +} + +signInForm.addEventListener( 'submit', signInSubmit ); diff --git a/signin/signin.html b/signin/signin.html new file mode 100644 index 000000000..9ed6f73a9 --- /dev/null +++ b/signin/signin.html @@ -0,0 +1,50 @@ + + + + + 로그인 + + + + +
+ + + +

+ 회원이 아니신가요?회원 가입하기 +

+
+
+
+
+
+ + +
+
+ + + +
+
+ +
+
+ 소셜 로그인 + +
+
+ + + + \ No newline at end of file diff --git a/signup.html b/signup.html deleted file mode 100644 index a4d345b3b..000000000 --- a/signup.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - -
-
-
- - 로고 - -
- 이미 회원이신가요? - -
-
-
- - -
-
- - -
-
-
- - -
-
- -
-
-

다른 방식으로 가입하기

- - 구글 - - - 카카오톡 - -
-
- - \ No newline at end of file diff --git a/signup/signUp.js b/signup/signUp.js new file mode 100644 index 000000000..be3efd40c --- /dev/null +++ b/signup/signUp.js @@ -0,0 +1,126 @@ +import { + EMAIL_REGEX, + PW_REGEX, + resetErr, + printErr, + codeitApi, +} from "../utils/utils.js"; + +import { + userEmail, + userPw, + signInForm, + pwChk, + accessApi, +} from "../signin/signIn.js"; + +const userPw2 = document.querySelector('#user-password-confrim'); +const eyeImg2 = document.querySelector('.eye-image2'); + +/* 이메일 체크 (미입력, 유효성, 가입이력조회) */ +async function emailChk( email ) { + resetErr( email ); + if( email.value.length === 0 ){ + printErr( email, '이메일을 입력해주세요.'); + return false; + } + if( !EMAIL_REGEX.test( email.value )){ + printErr( email, '올바른 이메일 주소가 아닙니다.'); + return false; + } + if( email.value && EMAIL_REGEX.test( email.value ) ){ + const result = await emailDuplicateChk( userEmail, 'check-email' ); + if( !result ){ + printErr( email, '이미 사용 중인 이메일입니다.'); + return false; + } + } + return true; +} + +userEmail.addEventListener('focusout',(e) => emailChk( e.target ) ); + +/* 이메일 중복 체크 (서버에 요청) */ +async function emailDuplicateChk( email, path ){ + const inputEmail = { + "email" : email.value, + }; + try { + const response = await fetch(`${codeitApi}/${path}`,{ + method: "POST", + headers: { + "Content-Type" : "application/json", + }, + body: JSON.stringify( inputEmail ), + }); + if ( response.ok ){ + const result = await response.json(); + return result; + } + } catch (error){ + console.log(error); + } +}; + +/* 비밀번호 체크 (미입력, 유효성) */ +userPw.addEventListener('focusout', (e) => pwChk( e.target ) ); + +/* 비밀번호 확인 체크 (미입력, 유효성, 일치성) */ +export function pw2Chk( pw2 ){ + resetErr( pw2 ); + if ( pw2.value.length === 0 ){ + printErr( pw2, '비밀번호를 입력해주세요.'); + return false; + } + if ( !PW_REGEX.test( pw2.value ) ){ + printErr( pw2, '비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요.'); + return false; + } + if ( pw2.value !== userPw.value ){ + printErr( pw2, '비밀번호가 일치하지 않아요.'); + return false; + } + return true; +} + +userPw2.addEventListener('focusout', (e) => pw2Chk( e.target ) ); + +/* 눈이미지와 비번 감추기 _ 비번 확인 */ +export function pw2ShowHide(e){ + if( userPw2.type === "password"){ + eyeImg2.src = "../img/eye-on.svg" + userPw2.type = "text"; + } else if (userPw2.type === "text"){ + eyeImg2.src = "../img/eye-off.svg" + userPw2.type = "password"; + } +} + +eyeImg2.addEventListener('click', (e)=>{ + e.preventDefault(); + pw2ShowHide(); +} ); + +/* 회원가입 시도 함수 */ +async function signInSubmit(e) { + e.preventDefault(); + + const emailResult = emailChk( userEmail ); + const pwResult = pwChk( userPw ); + const pw2Result = pw2Chk( userPw2 ); + const userInfo = { + email : userEmail.value, + password : userPw.value, + }; + const p = new Promise(( resolve, reject ) => { + if( emailResult && pwResult && pw2Result ){ + resolve( accessApi( userInfo, 'api/sign-up' ) ), + reject( + printErr( userEmail, '이메일을 확인해주세요.'), + printErr( userPw, '비밀번호를 확인해주세요.'), + printErr( userPw2, '비밀번호를 확인해주세요.')) + } + }) +} + +signInForm.addEventListener( 'submit', signInSubmit ); diff --git a/signup/signup.html b/signup/signup.html new file mode 100644 index 000000000..e1839eedf --- /dev/null +++ b/signup/signup.html @@ -0,0 +1,71 @@ + + + + + 회원가입 + + + + + +
+ + + +

+ 이미 회원이신가요?로그인 하기 +

+
+ +
+
+
+ +
+ + +
+ +
+ + + +
+ +
+ + + +
+
+ +
+
+ 다른 방식으로 가입하기 + +
+
+ + + + + + + + + + diff --git a/utils/utils.js b/utils/utils.js new file mode 100644 index 000000000..00406b81f --- /dev/null +++ b/utils/utils.js @@ -0,0 +1,23 @@ +export const EMAIL_REGEX = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/; +export const PW_REGEX = /^[A-Za-z0-9`~!@#\$%\^&\*\(\)\{\}\[\]\-_=\+\\|;:'"<>,\./\?]{8,20}$/; +export const testUser = { email: "test@codeit.com", pw: "codeit101", } +export const codeitApi = 'https://bootcamp-api.codeit.kr/api'; + +/* 빨간 테두리와 에러 문구 리셋 함수 */ +export function resetErr ( el ){ + const errText = el.parentNode.querySelector( '.fail-message' ); + if( errText ){ + errText.remove(); + el.classList.remove( 'red-border' ); + } +} + +/* 빨간 테두리와 에러 문구 추가 함수 */ +/* 근데 이게 적용되면 입력칸 색이 바뀝니다 -> (크롬)브라우저의 문제 */ +export function printErr( el, text ) { + el.classList.add('red-border'); + const span = document.createElement('span'); + span.classList.add('fail-message'); + span.textContent = text; + el.after(span); +}