Skip to content
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
cef2a3b
init project, create file structure
18AN Jul 18, 2022
3f53991
installed webpack and all dependencies, added sources, configured web…
18AN Jul 19, 2022
761dd6a
add responsive layout and styles
18AN Jul 23, 2022
318cd5f
add animations for form elements and svg, split js on modules
18AN Jul 26, 2022
cf5f0d9
corrected styles for popup
18AN Jul 27, 2022
01dfea8
add functions for showing and hiding image in email input item
18AN Jul 27, 2022
2a64f3d
delete not allowed attribute from svg tag
18AN Jul 27, 2022
c3d5434
add use strict mode
18AN Jul 27, 2022
3234613
explicitly set the width attribute for img tags
18AN Jul 27, 2022
06446e5
fixed previous commit changes
18AN Jul 27, 2022
ba2415f
delete unnecessary font
18AN Jul 27, 2022
e6664d2
delete font-face for unnecessary font
18AN Jul 27, 2022
87b3617
correct settings for animations in normalize file
18AN Jul 27, 2022
183e241
add fallback font
18AN Jul 27, 2022
ca10c66
add width and height attributes for img tags
18AN Jul 27, 2022
9a2d06d
delete unnecessary js code
18AN Jul 27, 2022
c43c338
defer non-critical javascript using async
18AN Jul 27, 2022
43da2de
delete previous changes
18AN Jul 27, 2022
a976dfc
delete unnecessry styles from normalize
18AN Jul 27, 2022
99b09d7
delete unnecessry styles from normalize
18AN Jul 27, 2022
cf18624
delete previous changes
18AN Jul 27, 2022
acaa799
add use strict mode in functions.js
18AN Jul 27, 2022
61d3bc3
add use strict mode in consts.js
18AN Jul 27, 2022
0c443e7
delete use strict mode in consts.js
18AN Jul 27, 2022
0105c04
refactor
18AN Jul 27, 2022
3fcbd9a
Update README.md
18AN Jul 27, 2022
5aa1e1f
Update README.md
18AN Jul 27, 2022
2be90aa
Update README.md
18AN Aug 3, 2022
84aa679
Update README.md
18AN Aug 3, 2022
4ab6695
Update README.md
18AN Aug 3, 2022
4978e98
Update README.md
18AN Aug 3, 2022
01ef3cf
Update README.md
18AN Aug 3, 2022
72d4ec6
Update README.md
18AN Aug 3, 2022
5f15aec
Update README.md
18AN Aug 3, 2022
3bc302e
Update README.md
18AN Aug 3, 2022
4dad322
Update README.md
18AN Aug 3, 2022
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/package-lock.json
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# Репозиторий для тестового задания на должность верстальщика
# Form
## Is available here: [form](https://master--musical-cocada-cdfd84.netlify.app/)
42 changes: 42 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "test-form",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "set NODE_ENV=development&&webpack serve",
"dev": "set NODE_ENV=development&&webpack",
"build": "set NODE_ENV=production&&webpack",
"clean": "rd /s /q dist"
},
"browserslist": ">0.25%, not dead",
"repository": {
"type": "git",
"url": "git+https://github.com/18AN/test-form.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/18AN/test-form/issues"
},
"homepage": "https://github.com/18AN/test-form#readme",
"devDependencies": {
"@babel/core": "^7.18.9",
"@babel/preset-env": "^7.18.9",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"html-loader": "^4.1.0",
"html-webpack-plugin": "^5.5.0",
"image-webpack-loader": "^8.1.0",
"mini-css-extract-plugin": "^2.6.1",
"sass": "^1.53.0",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.3"
},
"dependencies": {
"@babel/polyfill": "^7.12.1"
}
}
3 changes: 3 additions & 0 deletions src/assets/Arrow-black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/Arrow-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/fonts/PTSans-Regular.woff
Binary file not shown.
Binary file added src/fonts/WorkSans-Light.woff
Binary file not shown.
Binary file added src/fonts/WorkSans-Medium.woff
Binary file not shown.
Binary file added src/fonts/WorkSans-Regular.woff
Binary file not shown.
128 changes: 128 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Form</title>
</head>
<body>
<div class="container">
<div class="wrapper">
<div class="header" >
<div >Sign up</div>
</div>
<div class="main">
<form action="#" class="form" id="form" >
<div>
<div class="form__header appear first">New user?</div>
<div class="form__hint appear second">Use the form below to create your account.</div>
<div class="form__container">
<div class="item appear third">
<div class="item__title">First Name</div>
<div class="item__container">
<input id="first-name" name="first-name" class="item__input" type="text">
</div>
</div>
<div class="item appear fourth">
<div class="item__title">Last Name</div>
<div class="item__container">
<input id="second-name" name="second-name" class="item__input" type="text">
</div>
</div>
</div>
<div class="form__container">
<div class="item appear fifth">
<div class="item__title">Nationality</div>
<div class="select">
<div id="nationality" class="select__item">American</div><img src="./assets/Arrow-black.svg" alt="open" width="7.62" height="4.07">
</div>
</div>
<div class="item appear sixth">
<div class="item__title"><span>E-mail</span></div>
<div class="item__container">
<input id="email" name="email" class="item__input check" type="text">
<img id="valid" class="hide" src="./assets/Arrow-blue.svg" alt="valid" width="11" height="8">
</div>
<div class="warning" id="email-warn"></div>
</div>
</div>
<div class="form__container">
<div class="item appear seventh">
<div class="item__title">Date of birth</div>
<div class="date">
<div class="date__container day">
<span>21</span>
<img src="./assets/Arrow-black.svg" alt="open" width="7.62" height="4.07">
</div>
<div class="date__container mounth">
<span>December</span>
<img src="./assets/Arrow-black.svg" alt="open" width="7.62" height="4.07">
</div>
<div class="date__container year">
<span>1995</span>
<img src="./assets/Arrow-black.svg" alt="open" width="7.62" height="4.07">
</div>
</div>
</div>
<div class="item appear eighth">
<div class="item__title">Gender</div>
<div class="options">
<input id="male" type="radio" name="gender" value="male" class="options__radio">
<label for="male" class="options__label"><span>Male</span></label>
<input id="female" checked type="radio" name="gender" value="female" class="options__radio">
<label for="female" class="options__label"><span>Female</span></label>
</div>
</div>
</div>
<div class="form__container">
<div class="item appear ninth">
<div class="item__title">Password</div>
<div class="item__container">
<input id="password" name="password" class="item__input check" type="password">
</div>
<div class="warning"></div>
</div>
<div class="item appear tenth">
<div class="item__title">Confirm password</div>
<div class="item__container">
<input id="confirm-password" name="confirm-password" class="item__input check" type="password">
</div>
<div class="warning"></div>
</div>
</div>
</div>
<div class="form__container">
<div class="form__link appear eleventh">
Have an account?
<a href="#">Login</a>
</div>
<button class="form__button appear twelfth" type="submit">Complete Signup</button>
</div>
</form>
</div>
<div id="svg" class="svg">
<svg xmlns="http://www.w3.org/2000/svg" width="307" height="355" viewBox="0 0 307 355" fill="none" style class>
<path xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" style="fill: none; stroke: #F9FAFF; stroke-width: 5px" clip-rule="evenodd" d="M205.5 411C92.236 411 0 318.764 0 205.5C0 92.236 92.236 0 205.5 0C318.764 0 411 92.236 411 205.5C411 271.362 379.812 330.113 331.438 367.754C333.781 365.394 335.295 362.201 335.521 358.578C336 354.751 336 351.881 336 348.533V343.749C335.879 337.683 335.35 331.725 334.44 325.901C363.927 294.343 382 251.99 382 205.5C382 108.186 302.814 29 205.5 29C108.186 29 29 108.186 29 205.5C29 252.377 47.3746 295.047 77.2988 326.686C76.282 333.801 75.8485 341.1 76.0469 348.533C76.0469 351.403 76.0469 354.751 76.5256 358.578C77.0044 366.71 83.7067 372.451 91.8452 371.972C99.9836 371.494 105.728 364.797 105.25 356.665C104.892 354.163 104.802 352.196 104.779 350.363C133.361 370.298 168.091 382 205.5 382C243.357 382 278.471 370.016 307.247 349.643C307.207 350.468 307.131 351.336 307.053 352.232C306.928 353.664 306.797 355.164 306.797 356.665C306.318 364.318 312.063 371.494 320.202 371.972H321.159C323.791 371.972 326.253 371.294 328.371 370.094C294.07 395.773 251.521 411 205.5 411ZM307.247 349.643C317.103 342.665 326.215 334.703 334.44 325.901C324.506 262.367 269.17 214.712 203.39 216.027C138.589 217.313 86.0983 265.111 77.2988 326.686C85.6155 335.48 94.8243 343.421 104.779 350.363C104.771 349.743 104.771 349.138 104.771 348.533V344.227C105.728 288.259 152.166 243.771 208.178 245.207C264.19 246.163 308.712 292.564 307.276 348.533C307.276 348.892 307.265 349.263 307.247 349.643ZM328.371 370.094C329.401 369.324 330.423 368.543 331.438 367.754C330.531 368.667 329.5 369.455 328.371 370.094ZM147 142.5C147 174.339 172.661 200 204.5 200C236.339 200 262 174.339 262 142.5C262 110.661 236.339 85 204.5 85C172.661 85 147 110.661 147 142.5ZM205.5 114C189.057 114 176 127.057 176 143.5C176 159.943 189.057 173 205.5 173C221.943 173 235 159.943 235 143.5C235 127.057 221.943 114 205.5 114Z" class="LINenIOe_0"/>
<style data-made-with="vivus-instant">
.LINenIOe_0{stroke-dasharray:3811 3813;stroke-dashoffset:3812;animation:LINenIOe_draw 6500ms ease-in 0ms forwards;}@keyframes LINenIOe_draw{100%{stroke-dashoffset:0;}}@keyframes LINenIOe_fade{0%{stroke-opacity:1;}96.26168224299066%{stroke-opacity:1;}100%{stroke-opacity:0;}}
</style>
</svg>
</div>
</div>
<div class="popup">
<div class="popup__header"><div>Sign up</div></div>
<div class="popup-main">
<div class="popup-main__container">
<div class="popup-main__header">Thank You</div>
<div class="popup-main__text">you registered!</div>
</div>
<div class="popup-main__link">
Have an account?
<a href="#">Login</a>
</div>
</div>
</div>
</div>
</body>
</html>
45 changes: 45 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"use strict"

import './index.html';
import './index.scss';
import {showPopup,hidePopup, formValidate} from './modules/functions';
import {svg,button,popup,form,date,nationality} from './modules/consts';

//Making svg animation start right after all styles loaded
document.addEventListener('DOMContentLoaded', function(){
svg.classList.add('hide');
})

window.addEventListener('load', function(){
svg.classList.remove('hide');
})

//Removing appearing animation from button after it ends
setTimeout(() => {
button.classList.add('opacity');
button.classList.remove('appear','twelfth');
}, 6500);

popup.addEventListener('click', hidePopup);

form.addEventListener('submit', formSend);
function formSend(e){
e.preventDefault();
let valid = formValidate();

if(valid === 0){
let formData = new FormData(form);
formData.append('nationality', nationality);
formData.append('date', date);
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify(formData),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
})
.then(()=>showPopup())
.then(()=>form.reset())
.catch((error)=>console.log(error))
}
}
14 changes: 14 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@import 'normalize/normalize.scss';
@import 'style/fonts.scss';
@import 'style/var.scss';
@import 'style/general.scss';
@import 'style/header.scss';
@import 'style/main.scss';
@import 'style/form.scss';
@import 'style/item.scss';
@import 'style/select.scss';
@import 'style/options.scss';
@import 'style/popup.scss';
@import 'style/error.scss';
@import 'style/animations.scss';
@import 'style/media.scss';
14 changes: 14 additions & 0 deletions src/modules/consts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { dateAssemble } from "./functions";

export const form = document.getElementById('form');
export const nationality = document.getElementById('nationality').textContent;
export const day = document.querySelector('.day');
export const mounth = document.querySelector('.mounth');
export const year = document.querySelector('.year');
export const popup = document.querySelector('.popup');
export const wrapper = document.querySelector('.wrapper');
export const image = document.getElementById('valid');
export const emailWarning = document.getElementById('email-warn');
export const button = document.querySelector('.form__button');
export const date = dateAssemble(day,mounth,year);
export const svg = document.getElementById('svg');
104 changes: 104 additions & 0 deletions src/modules/functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"use strict"
import { button, emailWarning, image, popup, wrapper } from "./consts";
import { passwordRegEx, emailRegEx, mismatch, uncorrect, wrongEmail } from "./strings";

function addError(input){
input.parentElement.classList.add('error');
}

function removeError(input){
input.parentElement.classList.remove('error');
}

function testEmail(input){
return !emailRegEx.test(input.value);
}
function testPassword(input){
return !passwordRegEx.test(input.value);
}
function compare(array){
let r =(array[0] === array[1]);
return !r ;
}
export function dateAssemble(...array){
let date = '';
array.forEach(function(item){
date = date + item.textContent + '.';
})
return date;
}
export function showPopup(){
popup.classList.add('show');
wrapper.classList.add('hide');
}

export function hidePopup(){
popup.classList.remove('show');
wrapper.classList.remove('hide');
}

function showImage(){
image.classList.add('block');
}

function hideImage(){
image.classList.remove('block');
}

function shake(){
button.classList.add('shake');
setTimeout(()=>{removeShake()},500);

}
function removeShake(){
button.classList.remove('shake');
}

export function formValidate(){
let error = 0;
let formCheck = document.querySelectorAll('.check');
let passwords = [];
let passwordElements = [];

for (let i = 0; i < formCheck.length; i++){
let input = formCheck[i];
removeError(input);

if(input.id === 'email'){
if(testEmail(input)){
hideImage();
emailWarning.textContent = wrongEmail;
addError(input);
error++;
}else{
showImage();
emailWarning.textContent='';
}
}
else{
passwordElements.push(input);
passwords.push(input.value);
if(testPassword(input)){
input.closest('.item').lastElementChild.textContent = uncorrect;
addError(input);
error++
}else{
input.closest('.item').lastElementChild.textContent='';
if(passwords.length === 2){
if(compare(passwords)){
passwordElements.forEach(input => {
input.closest('.item').lastElementChild.textContent = mismatch;
addError(input);
error++
});
}
}
}
}

}
if(error!==0){
shake();
}
return error;
}
5 changes: 5 additions & 0 deletions src/modules/strings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const uncorrect = 'Password must contain at least 8 characters, uppercase and lowercase letters, and numbers';
export const wrongEmail = 'wrong e-mail address';
export const mismatch = 'passwords do not match';
export const passwordRegEx = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;
export const emailRegEx = /^\w+@\w+\.\w+$/;
Loading