diff --git a/assets/Arrow.svg b/assets/Arrow.svg new file mode 100644 index 000000000..e3f0dfb18 --- /dev/null +++ b/assets/Arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/Info.svg b/assets/Info.svg new file mode 100644 index 000000000..cb0add793 --- /dev/null +++ b/assets/Info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/Person.svg b/assets/Person.svg new file mode 100644 index 000000000..a0dd8ef51 --- /dev/null +++ b/assets/Person.svg @@ -0,0 +1,3 @@ + + + diff --git "a/assets/\320\241heck.svg" "b/assets/\320\241heck.svg" new file mode 100644 index 000000000..bfb8be1f6 --- /dev/null +++ "b/assets/\320\241heck.svg" @@ -0,0 +1,3 @@ + + + diff --git a/css/anim.css b/css/anim.css new file mode 100644 index 000000000..2abf61d4c --- /dev/null +++ b/css/anim.css @@ -0,0 +1,77 @@ +.i-1, +.i-2, +.i-3, +.i-4, +.i-5, +.i-6, +.i-7, +.i-8 { + animation-name: spawnInput; + animation-iteration-count: 1; + animation-timing-function: ease-in-out; + + transform: translateY(0px); + opacity: 1; +} + +.i-1 { + animation-duration: 0.9s; +} +.i-2 { + animation-duration: 1.1s; +} +.i-3 { + animation-duration: 1.3s; +} +.i-4 { + animation-duration: 1.5s; +} +.i-5 { + animation-duration: 1.7s; +} +.i-6 { + animation-duration: 1.9s; +} +.i-7 { + animation-duration: 2.1s; +} +.i-8 { + animation-duration: 2.3s; +} + +@keyframes spawnInput { + from { + transform: translateY(140px); + opacity: 0; + } + to { + transform: translateY(0px); + opacity: 1; + } +} + +.er-sub { + animation-name: error; + animation-duration: 0.5s; +} + +@keyframes error { + 0% { + transform: translateX(-2px); + } + 50% { + transform: translateX(2px); + } + 100% { + transform: translateX(0px); + } +} + +@keyframes final { + from { + opacity: 0; + } + to { + opacity: 1; + } +} \ No newline at end of file diff --git a/css/input.css b/css/input.css new file mode 100644 index 000000000..8b3a3e288 --- /dev/null +++ b/css/input.css @@ -0,0 +1,180 @@ +.inpt { + width: 100%; + min-height: 42px; + + border-bottom: 2px solid #f2f2f2; + + display: flex; + flex-direction: column; + justify-content: center; + + transform: translateY(140px); + opacity: 0; + + transition: all 0.2s; + + position: relative; +} + +.inpt__title { + color: #7c7c7c; + font-size: calc(var(--size-mp) * 0.86); + font-weight: 300; +} + +.inpt input, +select { + width: 100%; + margin: 2px 0px 5px 0px; + + background-color: transparent; + + font-family: Work Sans; + font-size: calc(var(--size-mp) * 1); + font-weight: 600; + letter-spacing: 0.55px; + + border: none; + outline: none; +} + +.inpt select { + font-family: Work Sans; + font-size: calc(var(--size-mp) * 1); + font-weight: 600; + letter-spacing: 0.55px; + + appearance: none; +} + +.inpt-svg { + position: absolute; + bottom: 25%; + right: 1px; + + pointer-events: none; +} + +.esvg { + opacity: 0; +} + +.svg-date { + bottom: 40%; +} + +.date { + margin-top: -7px; + border-bottom: none; +} + +.inpt__date { + display: flex; + justify-content: flex-start; + gap: 9.8px; +} + +.inpt__mini { + margin-bottom: -6px; + border-bottom: 2px solid #f2f2f2; + + position: relative; +} + +.inpt__mini.day { + flex: 1; + width: 24.44%; +} +.inpt__mini.mounth { + flex: 1.6; + width: 38.45%; +} +.inpt__mini.year { + width: 29.5%; +} + +.gender { + margin: 1px 0px 4px 0px; + + border-bottom: none; + justify-content: space-between; +} + +.inpt__checkbox-list { + margin: 2px 0px 5px 0px; + + font-size: calc(var(--size-mp) * 1); + + display: flex; + gap: 21px; +} + +.accept { + padding-left: 8%; + position: relative; +} +.accept input { + height: 0; + width: 0; + + opacity: 0; + cursor: pointer; + + position: absolute; +} + +.checkmark { + height: calc(var(--size-mp) * 0.86); + width: calc(var(--size-mp) * 0.86); + + background-color: #fff; + border-radius: 100%; + border: 0.7px solid var(--addit-color); + + position: absolute; + bottom: 1px; + left: -1px; +} + +.accept:hover input ~ .checkmark { + background-color: #fff; +} + +.accept input:checked ~ .checkmark { + background-color: #fff; + + display: flex; + justify-content: center; + align-items: center; +} + +.checkmark:after { + content: ""; + position: absolute; + display: none; +} + +.accept input:checked ~ .checkmark:after { + display: block; +} + +.accept .checkmark:after { + height: calc(var(--size-mp) * 0.55); + width: calc(var(--size-mp) * 0.55); + + background-color: var(--addit-color); + border-radius: 100%; +} + +.btn-sub { + width: 25.75vh; + height: 5.4vh; + + background-color: var(--addit-color); + border: none; + outline: none; + + color: #fff; + font-size: calc(var(--size-mp) * 1); + font-family: PT Sans; +} diff --git a/css/main.css b/css/main.css new file mode 100644 index 000000000..1707ad2d0 --- /dev/null +++ b/css/main.css @@ -0,0 +1,203 @@ +@import url("https://fonts.googleapis.com/css2?family=PT+Sans&display=swap"); +@import url("https://fonts.googleapis.com/css2?family=Work+Sans:wght@300&display=swap"); + +* { + margin: 0; + padding: 0; +} + +body { + min-height: 100vh; + background-color: #f4f5fc; + + font-family: Work Sans !important; + color: #111; + + display: flex; + justify-content: center; + align-items: center; +} + +:root { + --size-mp: calc(1vw + 1vh); + --main-color: #fff; + --addit-color: #5a61ed; +} + +.block-register { + width: 83vw; + height: 80vh; + + background-color: var(--main-color); + + position: relative; +} + +.block-register__main-container { + width: 100%; + height: 100%; + + display: flex; +} + +.main-container__info { + width: 20.6%; + height: 100%; + + background-color: var(--addit-color); + + position: relative; +} + +.main-container__info h1 { + color: #fff; + font-size: calc(var(--size-mp) * 3.505); + font-weight: 400; + font-family: PT Sans; + letter-spacing: 0.5px; + + white-space: nowrap; + writing-mode: vertical-lr; + + transform: rotate(-180deg); + + position: absolute; + bottom: 21px; + right: 5px; +} + +/* Right menu */ +.main-container__reg, +.main-container__final-reg { + z-index: 2; + flex: 1; + + margin: 40px 21px 32px 21px; + + flex-direction: column; + justify-content: space-between; +} + +.main-container__reg { + display: flex; +} + +.main-container__final-reg { + display: none; + opacity: 0; + animation: final 1s 1; + opacity: 1; +} + +.main-container__reg h2, +.main-container__final-reg h2 { + font-size: calc(var(--size-mp) * 1.571); + font-weight: 600; + letter-spacing: 0.45px; +} + +p { + font-size: calc(var(--size-mp) * 1); + font-weight: 300; +} + +.reg__inpt-area { + justify-self: flex-start; + width: 100%; + margin: 20px 0px 0px 0px; + + display: grid; + grid-template-columns: 1fr 1fr; + gap: 13px; +} + +.reg__submit { + z-index: 2; + + display: flex; + justify-content: space-between; + align-items: center; +} + +.reg__submit p { + margin-bottom: 5px; + + color: #000; + font-size: calc(var(--size-mp) * 0.93); + font-family: Work Sans; + font-weight: 300; +} + +.reg__submit p a { + color: var(--addit-color); +} + +/* Final Block */ +.final-reg__msg { + margin: auto 0; + padding: 25px 0px 0px 43px; + + display: flex; + flex-direction: column; + gap: 10px; +} + +.final-reg__submit p { + margin-bottom: 11px; + + color: #000; + font-size: calc(var(--size-mp) * 0.93); + font-family: Work Sans; + font-weight: 300; +} + +.final-reg__submit p a { + color: var(--addit-color); +} + +/* Reg Error */ +.error-msg { + min-height: 30px; + width: 83vw; + padding: 3px 0; + + background-color: rgb(255, 147, 147); + + position: absolute; + bottom: -10%; + + display: flex; + justify-content: flex-start; + align-items: center; + + opacity: 0; + + transition: all 0.2s; +} + +.error-content { + width: 100%; + height: 100%; + margin: 0 5px; + + display: flex; + justify-content: flex-start; + align-items: center; + gap: 10px; +} + +.info-svg { + width: 3%; + height: 3%; +} + +.svg-person { + z-index: 1; + + width: 38.3vw; + height: 60vh; + + position: absolute; + bottom: 0; + right: 0; +} \ No newline at end of file diff --git a/css/mobile.css b/css/mobile.css new file mode 100644 index 000000000..ce925d10e --- /dev/null +++ b/css/mobile.css @@ -0,0 +1,52 @@ +@media (max-width: 767px) { + body { + display: flex; + justify-content: center; + align-items: center; + } + + .block-register { + height: auto; + min-height: 80vh; + margin: 5% 0; + } + .block-register__main-container { + display: block; + height: 100%; + } + + .main-container__info { + width: 100%; + height: 14.6vh; + + background-color: var(--addit-color); + + position: relative; + } + + .main-container__info h1 { + writing-mode: horizontal-tb; + transform: rotate(0deg); + + position: absolute; + bottom: 10px; + left: 10px; + } + + .main-container__reg { + margin: 20px 11px 22px 11px; + padding-bottom: 20px; + } + + .main-container__final-reg { + height: 58vh; + } + + .reg__inpt-area { + margin: 20px 0px 30px 0px; + + display: grid; + grid-template-columns: 1fr; + gap: 13px; + } +} diff --git a/index.html b/index.html new file mode 100644 index 000000000..bcda136b0 --- /dev/null +++ b/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + + HTMLTestTask + + + +
+ +
+
+ +
+

Sign up

+
+ +
+
+

New user?

+

Use the form below to create your account.

+ + +
+ +
+
First Name
+ +
+ + +
+
Last Name
+ +
+ + +
+
Nationality
+ + + + +
+ + +
+
E-mail
+ + + + +
+ + +
+
Date of Birth
+ +
+ +
+ + + + +
+ + +
+ + + + +
+ + +
+ + + + +
+
+
+ + +
+
Gender
+
+ + +
+
+ + +
+
Password
+ +
+ + +
+
Confirm Password
+ +
+
+
+ + +
+

Have an account? Login

+ + +
+
+ +
+
+

Thank You!

+

you registered!

+
+
+

Have an account? Login

+
+
+
+ +
+
+
+ + + + +
+
+ + + + + + + diff --git a/js/app.js b/js/app.js new file mode 100644 index 000000000..45e0b607f --- /dev/null +++ b/js/app.js @@ -0,0 +1,7 @@ +const personIcon = new Vivus( + "person", + { + type: "oneByOne", + duration: 500, + } +); diff --git a/js/fill.js b/js/fill.js new file mode 100644 index 000000000..07cb48cd1 --- /dev/null +++ b/js/fill.js @@ -0,0 +1,104 @@ +const vNationality = document.getElementById("Nationality"); +const vDay = document.getElementById("Day"); +const vMounth = document.getElementById("Mounth"); +const vYear = document.getElementById("Year"); +const aInpt = document.querySelectorAll(".inpt"); + +const countries = [ + { code: "AF", name: "Afghanistan" }, + { code: "AL", name: "Albania" }, + { code: "DZ", name: "Algeria" }, + { code: "AR", name: "Argentina" }, + { code: "AU", name: "Australia" }, + { code: "AT", name: "Austria" }, + { code: "BD", name: "Bangladesh" }, + { code: "BY", name: "Belarus" }, + { code: "BE", name: "Belgium" }, + { code: "BR", name: "Brazil" }, + { code: "BG", name: "Bulgaria" }, + { code: "KH", name: "Cambodia" }, + { code: "CA", name: "Canada" }, + { code: "CL", name: "Chile" }, + { code: "CN", name: "China" }, + { code: "CO", name: "Colombia" }, + { code: "HR", name: "Croatia" }, + { code: "CU", name: "Cuba" }, + { code: "CZ", name: "Czech Republic" }, + { code: "DK", name: "Denmark" }, + { code: "EG", name: "Egypt" }, + { code: "FI", name: "Finland" }, + { code: "FR", name: "France" }, + { code: "DE", name: "Germany" }, + { code: "GR", name: "Greece" }, + { code: "HU", name: "Hungary" }, + { code: "IN", name: "India" }, + { code: "ID", name: "Indonesia" }, + { code: "IR", name: "Iran" }, + { code: "IE", name: "Ireland" }, + { code: "IL", name: "Israel" }, + { code: "IT", name: "Italy" }, + { code: "JP", name: "Japan" }, + { code: "KZ", name: "Kazakhstan" }, + { code: "KR", name: "South Korea" }, + { code: "KW", name: "Kuwait" }, + { code: "LB", name: "Lebanon" }, + { code: "MY", name: "Malaysia" }, + { code: "MX", name: "Mexico" }, + { code: "MA", name: "Morocco" }, + { code: "NL", name: "Netherlands" }, + { code: "NZ", name: "New Zealand" }, + { code: "NG", name: "Nigeria" }, + { code: "NO", name: "Norway" }, + { code: "PK", name: "Pakistan" }, + { code: "PH", name: "Philippines" }, + { code: "PL", name: "Poland" }, + { code: "PT", name: "Portugal" }, + { code: "RU", name: "Russia" }, + { code: "SA", name: "Saudi Arabia" }, + { code: "SG", name: "Singapore" }, + { code: "ZA", name: "South Africa" }, + { code: "ES", name: "Spain" }, + { code: "SE", name: "Sweden" }, + { code: "CH", name: "Switzerland" }, + { code: "TR", name: "Turkey" }, + { code: "UA", name: "Ukraine" }, + { code: "GB", name: "United Kingdom" }, + { code: "US", name: "United States" }, +]; + +for (let i = 0; i < countries.length; i++) { + vNationality.innerHTML += ``; +} + +for (let i = 1; i < 32; i++) { + if (i < 10) { + vDay.innerHTML += ``; + + continue; + } + + vDay.innerHTML += ``; +} + +const months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +]; + +for (let i = 0; i < months.length; i++) { + vMounth.innerHTML += ``; +} + +for (let i = 2023; i >= 1800; i--) { + vYear.innerHTML += ``; +} \ No newline at end of file diff --git a/js/reg.js b/js/reg.js new file mode 100644 index 000000000..d0602c3f0 --- /dev/null +++ b/js/reg.js @@ -0,0 +1,186 @@ +const oErrorBlock = document.querySelector(".error-msg"); +const contentErrorBlock = document.querySelector(".error-content"); +const inptSubmit = document.querySelector(".btn-sub"); + +function fShowError(border, color, msg) { + if (border !== null) { + border.style.borderBottom = `2px solid #ff2222`; + color.style.color = `#ff2222`; + } + + oErrorBlock.style.opacity = "1"; + contentErrorBlock.innerHTML = ` + + + +

${msg}

+ `; + + inptSubmit.classList.add("er-sub"); + + setTimeout(() => { + if (border !== null) { + border.style.borderBottom = `2px solid #f2f2f2`; + color.style.color = `#111`; + } + + oErrorBlock.style.opacity = "0"; + inptSubmit.classList.remove("er-sub"); + }, 4000); +} + +const aMiniInpt = document.querySelectorAll(".inpt__mini"); +const sFirstName = document.getElementById("f-name"); +const sLastName = document.getElementById("l-name"); +const sEmail = document.getElementById("email"); +const bGender = document.getElementsByName("gender"); +const sPass = document.getElementById("pass"); +const sConfPass = document.getElementById("conf-pass"); + +const confSvg = document.querySelector(".esvg"); + +function fCheckReg() { + const allowedRegex = /^[a-z]+$/i; + + // First Name + if (sFirstName.value.length === 0) { + return fShowError( + aInpt[0], + sFirstName, + "The 'First Name' field cannot be left empty." + ); + } + if (!allowedRegex.test(sFirstName.value)) { + return fShowError( + aInpt[0], + sFirstName, + "Fist name must contain only letters." + ); + } + + // Last Name + if (sLastName.value.length === 0) { + return fShowError( + aInpt[1], + sLastName, + "The 'Last Name' field cannot be left empty." + ); + } + if (!allowedRegex.test(sLastName.value)) { + return fShowError( + aInpt[1], + sLastName, + "Last name must contain only letters." + ); + } + + // Nationality + if (vNationality.value === "null") { + return fShowError( + aInpt[2], + vNationality, + "The 'Nationality' field cannot be left empty." + ); + } + + // E-mail + if (!sEmail.value.includes("@")) { + confSvg.style.opacity = "0"; + + return fShowError(aInpt[3], sEmail, "The 'Email' field must contain @."); + } + + // Date of Birth + confSvg.style.opacity = "1"; + + if (vDay.value === "null") { + return fShowError( + aMiniInpt[0], + vDay, + "The 'Date of Birth' field cannot be left empty." + ); + } + + if (vMounth.value === "null") { + return fShowError( + aMiniInpt[1], + vMounth, + "The 'Date of Birth' field cannot be left empty." + ); + } + + if (vYear.value === "null") { + return fShowError( + aMiniInpt[2], + vYear, + "The 'Date of Birth' field cannot be left empty." + ); + } + + // Gender + if (!bGender[0].checked && !bGender[1].checked) { + return fShowError(null, null, "The 'Gender' field cannot be left empty."); + } + + // Password + let hasUppercase = false; + let hasLowercase = false; + let hasNumber = false; + + if (sPass.value.length < 8) { + return fShowError( + aInpt[6], + sPass, + "The password must contain at least 8 characters, uppercase and lowercase letters, as well as numbers." + ); + } + + for (let i = 0; i < sPass.value.length; i++) { + const char = sPass.value[i]; + if (char >= "A" && char <= "Z") { + hasUppercase = true; + } else if (char >= "a" && char <= "z") { + hasLowercase = true; + } else if (char >= "0" && char <= "9") { + hasNumber = true; + } + } + + if (!hasUppercase || !hasLowercase || !hasNumber) { + return fShowError( + aInpt[6], + sPass, + "The password must contain at least 8 characters, uppercase and lowercase letters, as well as numbers." + ); + } + + // Confirm Password + if (sConfPass.value !== sPass.value) { + return fShowError(aInpt[7], sConfPass, "Passwords must match."); + } + + sFirstName.value = ""; + sLastName.value = ""; + vNationality.value = "null" + sEmail.value = ""; + vDay.value = "null"; + vMounth.value = "null"; + vYear.value = "null"; + bGender[0].checked = false; + bGender[1].checked = false; + sPass.value = ""; + sConfPass.value = ""; + + const oRegBlock = document.querySelector(".main-container__reg"); + const oFinalBlock = document.querySelector(".main-container__final-reg"); + + oRegBlock.style.display = "none"; + oFinalBlock.style.display = "flex"; + oFinalBlock.style.opacity = "1"; +}