diff --git a/.github/delete-merged-branch-config.yml b/.github/delete-merged-branch-config.yml new file mode 100644 index 000000000..2a6d27bef --- /dev/null +++ b/.github/delete-merged-branch-config.yml @@ -0,0 +1,15 @@ +name: delete branch on close pr + +on: + pull_request: + types: [closed] + +permissions: + pull-requests: write + +jobs: + delete-branch: + runs-on: ubuntu-latest + steps: + - name: delete branch + uses: SvanBoxel/delete-merged-branch@main diff --git a/2-Weekly-Mission b/2-Weekly-Mission new file mode 160000 index 000000000..93a0e9352 --- /dev/null +++ b/2-Weekly-Mission @@ -0,0 +1 @@ +Subproject commit 93a0e935257144cb8f10c3a57d08d93a74f7ab2f diff --git a/asset/landing/KakaoTalk_20231103_112314340.png b/asset/landing/KakaoTalk_20231103_112314340.png new file mode 100644 index 000000000..fec0ee0b4 Binary files /dev/null and b/asset/landing/KakaoTalk_20231103_112314340.png differ diff --git a/asset/landing/_img1.png b/asset/landing/_img1.png new file mode 100644 index 000000000..6c6c327e5 Binary files /dev/null and b/asset/landing/_img1.png differ diff --git a/asset/landing/_img4.png b/asset/landing/_img4.png new file mode 100644 index 000000000..1c0365c9f Binary files /dev/null and b/asset/landing/_img4.png differ diff --git a/asset/landing/eye-on.png b/asset/landing/eye-on.png new file mode 100644 index 000000000..923096a66 Binary files /dev/null and b/asset/landing/eye-on.png differ diff --git a/asset/landing/img2.png b/asset/landing/img2.png new file mode 100644 index 000000000..95456f74e Binary files /dev/null and b/asset/landing/img2.png differ diff --git a/asset/landing/img3.png b/asset/landing/img3.png new file mode 100644 index 000000000..125c36b1c Binary files /dev/null and b/asset/landing/img3.png differ diff --git a/asset/signin/Component 2.png b/asset/signin/Component 2.png new file mode 100644 index 000000000..c7518e8b3 Binary files /dev/null and b/asset/signin/Component 2.png differ diff --git a/css/week1.css b/css/week1.css new file mode 100644 index 000000000..40fcf4cd6 --- /dev/null +++ b/css/week1.css @@ -0,0 +1,318 @@ +/* header */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; + border: 0; +} + +header { + display: flex; + flex-direction: column; + justify-content: center; + width: 100%; + align-items: center; + background-color: #f0f6ff; + padding-top: 4rem; +} +nav { + position: fixed; + top: 0; +} + +.navbar { + display: flex; + padding: 1.25rem 12.5rem; + justify-content: space-between; + align-items: center; + width: 100vw; + background-color: #f0f6ff; +} +.hero-header { + display: flex; + flex-direction: column; + align-items: center; + row-gap: 2.5rem; + padding: 4rem 22.5rem 0 22.5rem; + background-color: #f0f6ff; + width: 100%; +} +.cta { + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + color: #f5f5f5; + background-image: linear-gradient(135deg, #6d6af6 0%, #6ae3fe 100%); + font-size: 1.125rem; + font-style: normal; + font-weight: 600; + line-height: normal; + border-radius: 0.5rem; + text-decoration: none; + padding: 1rem 1.25rem; + gap: 1rem; +} +.cta-short { + width: 12.8rem; +} +.cta-long { + width: 35rem; +} +.slogan { + text-align: center; + font-size: 4rem; + font-weight: 700; + width: 44.25rem; +} +.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: 70rem; +} + +section { + display: flex; + justify-content: center; + align-items: center; + column-gap: 9.9rem; + row-gap: 1rem; + width: 100%; + padding: 3rem 29rem; +} +.section1 { + flex-direction: row-reverse; +} +.section_main { + padding-top: 7.5rem; +} + +.title { + grid-area: title; + font-size: 3rem; + font-weight: 700; + letter-spacing: -0.03rem; + width: 19rem; +} /* 왜 안되는지 모르겠음*/ +.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: 1rem; + font-weight: 500; + color: #6b6b6b; + line-height: 150%; + width: 20rem; +} +.mobileText { + display: none; +} + +.content-image { + grid-area: image; + width: 34rem; +} + +footer { + display: flex; + justify-content: center; + width: 100%; + padding-top: 7.5rem; + position: relative; + bottom: -7.5px; +} + +.footer_box { + display: flex; + justify-content: space-between; + width: 100%; + max-width: 192rem; + height: fit-content; + padding: 2rem 6.5rem 4rem 6.5rem; + align-items: center; + background-color: #111322; +} + +.copyright { + color: #676767; + font-family: Arial; + font-size: 1rem; +} +.footer-links { + display: flex; + column-gap: 3rem; + padding-right: 1.8rem; +} +.footer-link { + color: #cfcfcf; + font-family: Arial; + font-size: 1rem; + text-decoration: none; +} +.sns { + display: flex; + column-gap: 1.2rem; +} +.all { + display: block; +} +/*week2*/ + +@media (max-width: 1199px) { + .navbar { + padding: 1.25rem 12.5rem; + } + .hero-image { + width: 40rem; + } + .slogan { + font-size: 4rem; + } + .hero-header { + padding: 2.4rem 15rem 0 15rem; + margin: 0 auto; + width: 100%; + } + section { + gap: 3rem; + padding: 3rem 15rem; + } + .section_main { + padding-top: 5rem; + } + + .logo { + width: 8rem; + } + .cta { + font-size: 1rem; + padding: 1rem 1.25rem; + text-align: center; + } + .title { + font-size: 3rem; + } + .content-image { + width: 24rem; + } + .description { + font-size: 1rem; + } + + footer { + padding-top: 7.5rem; + } + .footer_box { + padding: 2rem 6.5rem 4rem 6.5rem; + } +} + +@media (max-width: 767px) { + nav { + width: 24.375rem; + } + .navbar { + padding: 0.8rem 2rem; + width: 100%; + } + .logo { + width: 5.5rem; + } + .cta { + font-size: 0.8rem; + padding: 0.6rem 1rem; + } + .hero-header { + padding: 1.75rem 2rem 0 2rem; + gap: 1.5rem; + } + .slogan { + font-size: 2rem; + width: 18rem; + } + .hero-image { + margin: 0.85rem 0.7rem 0rem 0.7rem; + width: 19rem; + } + .title { + font-size: 1.5rem; + width: 20rem; + } + .description { + font-size: 0.9rem; + width: 22rem; + margin-top: 0.6rem; + } + .ex > .description { + display: none; + } + .mobileText { + display: flex; + } + section { + flex-direction: column; + align-items: center; + padding: 2.5rem 2rem 2.6rem 2rem; + gap: 1.5rem; + } + + .section_main { + padding-bottom: 2.2rem; + } + + .content-image { + width: 22rem; + } + .section1 { + flex-direction: column; + } + footer { + padding-top: 2.5rem; + } + .footer_box { + padding: 2rem 2rem 4rem 2rem; + position: relative; + } + .footer_left { + display: flex; + flex-direction: column-reverse; + gap: 3.75rem; + } + .footer_links { + gap: 1.875rem; + font-size: 1rem; + } + + .sns { + gap: 0.75rem; + } + .copyright { + margin-top: 6.875rem; + position: absolute; + } + + .sec2 { + order: 2; + } + .sec3 { + order: 1; + } +} diff --git a/css/week2-1.css b/css/week2-1.css new file mode 100644 index 000000000..c089b0904 --- /dev/null +++ b/css/week2-1.css @@ -0,0 +1,169 @@ +:root { + --blue: #6d6afe; + --red: #ff5b56; + --black: #111322; + --white: #ffffff; + --gray: #3e3e43; + --light_gray: #9fa6b2; + --blue_gray: #ccd5e3; + --mint_gray: #e7effb; +} +html { + font-size: 62.5%; +} +.frame { + padding-top: 23.8rem; + padding-bottom: 25.2rem; + display: flex; + + align-items: center; + flex-direction: column; + text-align: center; +} +body { + background: var(--linkbrary-bg, #f0f6ff); +} + +.logo { + width: 21.0583rem; + height: 3.8rem; + margin-bottom: 1.6rem; +} + +.join { + color: var(--black, #000); + font-family: Pretendard; + font-size: 1.6rem; + font-style: normal; + font-weight: 400; + line-height: 2.4rem; + width: 100%; +} +.join_go { + color: var(--linkbrary-primary-color, #6d6afe); + font-family: Pretendard; + font-weight: 600; + line-height: normal; +} +.email, +.password, +.password2 { + margin-top: 3rem; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 1.2rem; +} +.email > input, +.password > input, +.password2 > input { + display: flex; + width: 40rem; + padding: 1.8rem 1.5rem; + justify-content: center; + align-items: center; + border-radius: 0.8rem; + border: 0.1rem solid gray; + background: var(--linkbrary-white, #fff); +} +.email > input > #signup-email:focus, +.password > input > #signup-password:focus, +.password2 > input > #signup-password2:focus { + border-color: var(--blue); +} + +.password > img, +.password2 > img { + position: relative; + top: -4.5rem; + left: 40rem; +} +button { + border-color: #f5f5f5; + color: #f5f5f5; + margin-top: 3rem; + display: flex; + width: 44.1rem; + padding: 1.6rem 2rem; + justify-content: center; + align-items: center; + gap: 1rem; + border-radius: 0.8rem; + background: var( + --gra-purpleblue-to-skyblue, + linear-gradient(91deg, #6d6afe 0.12%, #6ae3fe 101.84%) + ); +} +.social_login { + margin-top: 3rem; + display: flex; + width: 40rem; + padding: 1.2rem 2.4rem; + justify-content: space-between; + align-items: center; + border-radius: 0.8rem; + border: 1px solid var(--blue_gray); + background: var(--mint_gray); +} +@media (max-width: 1199px) { + .frame { + padding: 20rem 40rem 29rem 40rem; + } +} +@media (max-width: 767px) { + .frame { + padding: 12rem 3.2rem 23.2rem 3.2rem; + } + .email { + margin-top: 3rem; + } + .email > input, + .password > input, + .password2 > input { + width: 32.5rem; + } + .password, + .password2 { + margin-top: 2.4rem; + } + .password > img, + .password2 > img { + left: 32rem; + } + button { + width: 36.5rem; + } + .social_login { + width: 32.5rem; + } + .join { + font-size: 1.4rem; + width: 100%; + } + .social_login { + padding: 0.6rem 2.4rem; + } +} +.email input:focus { + border: 1px solid blue; + outline: none; +} +.password input:focus { + border: 1px solid blue; + outline: none; +} +.password2 input:focus { + border: 1px solid blue; + outline: none; +} +.error { + border: 1px solid red; +} + +.error-message, +.error-message2, +.error-message2-omt, +.join-message { + color: red; + display: none; +} diff --git a/css/week2.css b/css/week2.css new file mode 100644 index 000000000..66638fe8c --- /dev/null +++ b/css/week2.css @@ -0,0 +1,110 @@ +.frame { + padding-top: 238px; + padding-bottom: 252px; + display: flex; + + align-items: center; + flex-direction: column; + text-align: center; +} +body { + background: var(--linkbrary-bg, #f0f6ff); +} + +.logo { + width: 210.583px1; + height: 38px; + margin-bottom: 16px; +} + +.join { + color: var(--black, #000); + font-family: Pretendard; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + width: 90%; +} +.join_go { + color: var(--linkbrary-primary-color, #6d6afe); + font-family: Pretendard; + font-weight: 600; + line-height: normal; +} +.email, +.password { + margin-top: 30px; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 12px; +} +.email > input, +.password > input { + display: flex; + width: 400px; + padding: 18px 15px; + justify-content: center; + align-items: center; + border-radius: 8px; + border: 1px solid gray; + background: var(--linkbrary-white, #fff); +} + +.password > img { + position: relative; + top: -45px; + left: 400px; +} +button { + border-color: #f5f5f5; + color: #f5f5f5; + margin-top: 30px; + display: flex; + width: 441px; + padding: 16px 20px; + justify-content: center; + align-items: center; + gap: 10px; + border-radius: 8px; + background: var( + --gra-purpleblue-to-skyblue, + linear-gradient(91deg, #6d6afe 0.12%, #6ae3fe 101.84%) + ); +} +.social_login { + margin-top: 30px; + display: flex; + width: 400px; + padding: 12px 24px; + justify-content: space-between; + align-items: center; + border-radius: 8px; + border: 1px solid var(--linkbrary-gray-20, #ccd5e3); + background: var(--linkbrary-gray-10, #e7effb); +} + +.email input:focus { + border: 1px solid blue; + outline: none; +} +.password input:focus { + border: 1px solid blue; + outline: none; +} +.error { + border: 1px solid red; +} + +.error-message, +.error-message2, +.login-message { + color: red; + display: none; +} +.open-eye { + position: relative; + top: -45px; + left: 400px; +} diff --git a/signin/Component 3.png b/signin/Component 3.png new file mode 100644 index 000000000..d38e36cc0 Binary files /dev/null and b/signin/Component 3.png differ diff --git a/signin/eye-off.png b/signin/eye-off.png new file mode 100644 index 000000000..1e6b21540 Binary files /dev/null and b/signin/eye-off.png differ diff --git a/signin/logo.png b/signin/logo.png new file mode 100644 index 000000000..617557cc7 Binary files /dev/null and b/signin/logo.png differ diff --git a/signup.html b/signup.html new file mode 100644 index 000000000..769d4e05a --- /dev/null +++ b/signup.html @@ -0,0 +1,33 @@ + + + + + landinPage + + + +
+ ... +
+

WITHJ.NETLIFY.APP

+

Linkbrary

+

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

+
+
+ + + + diff --git a/signup/eye-on.png b/signup/eye-on.png new file mode 100644 index 000000000..923096a66 Binary files /dev/null and b/signup/eye-on.png differ diff --git a/week1.html b/week1.html new file mode 100644 index 000000000..650c61d1d --- /dev/null +++ b/week1.html @@ -0,0 +1,216 @@ + + + + + Linkbrary + + + +
+ +
+

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

+ + 링크 추가하기 + + +
+
+
+
+
+

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

+

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

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

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

+
+
+
+
+

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

+

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

+
+
+ 폴더 이름 변경 기능 +
+
+

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

+
+
+
+
+

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

+ +

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

+
+
+ 폴더 공유 기능 +
+
+

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

+
+
+ +
+
+

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

+

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

+
+
+ 링크 검색 기능 +
+
+

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

+
+
+
+ + + diff --git a/week2-1.html b/week2-1.html new file mode 100644 index 000000000..a340c8791 --- /dev/null +++ b/week2-1.html @@ -0,0 +1,60 @@ + + + + + + + + + +
+
+
+ +
+이미 회원이신가요? +로그인 하기 +
+ +
+ +
+ +
+ + +
+ +
+
+ + +
+ +
+ + + +
+ + +
+ + + +
+ + + \ No newline at end of file diff --git a/week2-1.js b/week2-1.js new file mode 100644 index 000000000..586cfcc41 --- /dev/null +++ b/week2-1.js @@ -0,0 +1,83 @@ +const emailInput = document.getElementById("signup-email"); +const errorMessage = document.getElementById("error-message"); +const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/; + +function showError(input, errorElement, errorMessage) { + input.classList.add("error"); + errorElement.innerText = errorMessage; + errorElement.style.display = "block"; + input.style.border = "1px solid #FF5B56"; +} + +function clearError(input, errorElement) { + input.classList.remove("error"); + errorElement.style.display = "none"; + errorElement.innerText = " "; + input.style.border = "1px solid #CCD5E3"; + button.style.border = "none"; +} +emailInput.addEventListener("focusout", function () { + if (emailInput.value === "") { + showError(emailInput, errorMessage, "이메일을 입력해주세요."); + } else if (!emailRegex.test(emailInput.value)) { + showError(emailInput, errorMessage, "올바른 이메일 주소가 아닙니다."); + } else if (emailInput.value === "test@codeit.com") { + showError(emailInput, errorMessage, "이미 사용 중인 이메일입니다."); + } else { + clearError(emailInput, errorMessage); + } +}); + +const passwordInput = document.getElementById("signup-password"); +const errorMessage2 = document.getElementById("error-message2"); +const passwordInputOmt = document.getElementById("signup-password2"); +const errorMessage2Omt = document.getElementById("error-message2-omt"); +passwordInput.addEventListener("focusout", function () { + if ( + passwordInput.value.length < 8 || + !/^(?=.*[a-zA-Z])(?=.*\d)/.test(passwordInput.value) + ) { + showError( + passwordInput, + errorMessage2, + "비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요." + ); + } else { + clearError(passwordInput, errorMessage2); + } +}); + +passwordInputOmt.addEventListener("input", function () { + if (passwordInput.value === passwordInputOmt.value) { + clearError(passwordInputOmt, errorMessage2Omt); + } else { + showError( + passwordInputOmt, + errorMessage2Omt, + "비밀번호가 일치하지 않습니다." + ); + } +}); + +const joinButtons = document.getElementsByTagName("button")[0]; +const joinMessage = document.getElementsByClassName("join-message")[0]; + +for (let i = 0; i < joinButtons.length; i++) { + joinButtons[i].addEventListener("click", function (event) { + event.preventDefault(); // 폼 제출 방지 + + // 이메일 유효성 검사 + if ( + (emailInput.value === "" && + !emailRegex.test(emailInput.value) && + emailInput.value === "test@codeit.com") || + !/^(?=.*[a-zA-Z])(?=.*\d)/.test(passwordInput.value) || + passwordInput.value.length < 8 || + passwordInput.value !== passwordInputOmt.value + ) { + showError(joinButtons[i], joinMessage, "다시 확인하세요."); + } else { + window.location.href = "/folder"; + } + }); +} diff --git a/week2.html b/week2.html new file mode 100644 index 000000000..c70fa31ca --- /dev/null +++ b/week2.html @@ -0,0 +1,55 @@ + + + + + + + + + +
+
+
+ +
+회원이 아니신가요? +회원 가입하기 +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+ + + + + + + + +
+ + + \ No newline at end of file diff --git a/week2.js b/week2.js new file mode 100644 index 000000000..17a0e8f85 --- /dev/null +++ b/week2.js @@ -0,0 +1,99 @@ +const emailInput = document.getElementById("signup-email"); +const errorMessage = document.getElementById("error-message"); +const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/; + +function showError(input, errorElement, errorMessage) { + input.classList.add("error"); + errorElement.innerText = errorMessage; + errorElement.style.display = "block"; + input.style.border = "1px solid #FF5B56"; +} + +function clearError(input, errorElement) { + input.classList.remove("error"); + errorElement.style.display = "none"; + errorElement.innerText = " "; + input.style.border = "1px solid #CCD5E3"; +} + +emailInput.addEventListener("focusout", function () { + if (emailInput.value === "") { + showError(emailInput, errorMessage, "이메일을 입력해주세요."); + } else if (!emailRegex.test(emailInput.value)) { + showError(emailInput, errorMessage, "올바른 이메일 주소가 아닙니다."); + } else if (emailInput.value === "test@codeit.com") { + showError(emailInput, errorMessage, "이미 사용 중인 이메일입니다."); + } else { + clearError(emailInput, errorMessage); + } +}); + +const passwordInput = document.getElementById("signup-password"); +const errorMessage2 = document.getElementById("error-message2"); +passwordInput.addEventListener("focusout", function () { + if ( + passwordInput.value.length < 8 || + !/^(?=.*[a-zA-Z])(?=.*\d)/.test(passwordInput.value) + ) { + showError( + passwordInput, + errorMessage2, + "비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요." + ); + passwordInput.classList.add("error"); + } else { + clearError(passwordInput, errorMessage2); + } +}); +const loginButtons = document.getElementsByTagName("button")[0]; +const loginMessage = document.getElementsByClassName("login-message")[0]; + +loginButtons.addEventListener("click", function (event) { + event.preventDefault(); + if ( + emailInput.value === "test@codeit.com" && + passwordInput.value === "codeit101" + ) { + window.location.href = "/folder"; + } else { + loginMessage.innerText = "이메일 또는 비밀번호가 올바르지 않습니다."; + loginMessage.style.display = "block"; + } +}); + +passwordInput.addEventListener("focusout", function () { + if (passwordInput.value.trim() === "") { + showError(passwordInput, errorMessage2, "비밀번호를 입력해주세요."); + } else { + clearError(passwordInput, errorMessage2); + } +}); + +for (let i = 0; i < loginButtons.length; i++) { + loginButtons[i].addEventListener("click", function (event) { + event.preventDefault(); // 폼 제출 방지 + + // 이메일 유효성 검사 + if ( + (emailInput.value === "" && + !emailRegex.test(emailInput.value) && + emailInput.value === "test@codeit.com") || + !/^(?=.*[a-zA-Z])(?=.*\d)/.test(passwordInput.value) || + passwordInput.value.length < 8 + ) { + showError(emailInput, errorMessage, "이메일을 확인하세요."); + showError(passwordInput, errorMessage2, "비밀번호를 확인하세요."); + } + }); +} + +function togglePasswordVisibility() { + const eyeIcon = document.getElementById("eye-icon"); + if (passwordInput.type === "password") { + passwordInput.type = "text"; + eyeIcon.src = "asset/landing/eye-on.png"; + } else { + passwordInput.type = "password"; + eyeIcon.src = "signin/eye-off.png"; + } +}