added & design login component
This commit is contained in:
parent
fbf7c314a4
commit
a436dd364d
8 changed files with 230 additions and 8 deletions
|
|
@ -4,5 +4,6 @@ import { RegisterComponent } from './components/auth/register/register.component
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', component: HomeComponent },
|
{ path: '', component: HomeComponent },
|
||||||
|
{ path: 'login', component: HomeComponent },
|
||||||
{ path: 'register', component: HomeComponent },
|
{ path: 'register', component: HomeComponent },
|
||||||
];
|
];
|
||||||
|
|
|
||||||
67
frontend/src/app/components/auth/login/login.component.html
Normal file
67
frontend/src/app/components/auth/login/login.component.html
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
<section>
|
||||||
|
<div class="content">
|
||||||
|
<div class="headline">Log in</div>
|
||||||
|
<form
|
||||||
|
id="form"
|
||||||
|
class="login-form"
|
||||||
|
#loginForm="ngForm"
|
||||||
|
(ngSubmit)="onSubmit(loginForm)"
|
||||||
|
onsubmit="return false"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="mail"
|
||||||
|
id="mail"
|
||||||
|
name="mail"
|
||||||
|
#mail="ngModel"
|
||||||
|
placeholder="Email Address"
|
||||||
|
autocomplete="email"
|
||||||
|
[(ngModel)]="authData.mail"
|
||||||
|
[class.error-border]="
|
||||||
|
(!mail.valid && mail.touched) ||
|
||||||
|
(mail.touched &&
|
||||||
|
!isUserEmailValid(authData.mail.toLowerCase()) &&
|
||||||
|
authData.mail.length > 0)
|
||||||
|
"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div class="error-msg">
|
||||||
|
@if (!mail.valid && mail.touched) {
|
||||||
|
<p>Please enter your email</p>
|
||||||
|
} @else { @if (mail.touched && authData.mail.length > 0 &&
|
||||||
|
!isUserEmailValid(authData.mail.toLowerCase())) {
|
||||||
|
<p>This is not a valid email format</p>
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
#password="ngModel"
|
||||||
|
placeholder="Enter a password"
|
||||||
|
autocomplete="new-password"
|
||||||
|
[(ngModel)]="authData.password"
|
||||||
|
pattern="[^<>]*"
|
||||||
|
minlength="6"
|
||||||
|
[class.error-border]="
|
||||||
|
password.invalid && password.touched && authData.password.length > 0
|
||||||
|
"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div class="error-msg">
|
||||||
|
@if (!password.valid && password.touched && authData.password.length <
|
||||||
|
1) {
|
||||||
|
<p>Please enter your password</p>
|
||||||
|
} @else { @if (authData.password.length < 6 && password.touched) {
|
||||||
|
<p>Password is too short, min 6 characters</p>
|
||||||
|
} }
|
||||||
|
</div>
|
||||||
|
<app-btn-large
|
||||||
|
[value]="'Log in'"
|
||||||
|
[disabled]="
|
||||||
|
(!isUserEmailValid(authData.mail) && authData.mail.length > 0) ||
|
||||||
|
!password.valid
|
||||||
|
"
|
||||||
|
></app-btn-large>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
91
frontend/src/app/components/auth/login/login.component.scss
Normal file
91
frontend/src/app/components/auth/login/login.component.scss
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
@import "./../../../../assets/style/colors.scss";
|
||||||
|
|
||||||
|
section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
text-align: center;
|
||||||
|
background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)),
|
||||||
|
url(./../../../../assets/img/backgrounds/register.png);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 520px;
|
||||||
|
height: 492px;
|
||||||
|
padding: 43px 56px;
|
||||||
|
border-radius: 48px;
|
||||||
|
background-color: $white;
|
||||||
|
.headline {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $blue;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
app-btn-large {
|
||||||
|
margin-top: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-msg {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 24px;
|
||||||
|
padding: 6px;
|
||||||
|
width: 120%;
|
||||||
|
p {
|
||||||
|
color: $red;
|
||||||
|
font-size: 12px !important;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: $red;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
input {
|
||||||
|
width: 90%;
|
||||||
|
padding: 12px 18px;
|
||||||
|
margin: 8px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: transparent;
|
||||||
|
color: $blue;
|
||||||
|
border: 1px solid $blue;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
transition: background-color 250ms ease-in-out, color 250ms ease-in-out,
|
||||||
|
border-color 250ms ease-in-out;
|
||||||
|
&::placeholder {
|
||||||
|
color: rgba($blue, 0.6);
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
background-color: rgba($white, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.error-border {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [LoginComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
33
frontend/src/app/components/auth/login/login.component.ts
Normal file
33
frontend/src/app/components/auth/login/login.component.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { BtnLargeComponent } from '../../../shared/components/btn-large/btn-large.component';
|
||||||
|
import { FormsModule, NgForm } from '@angular/forms';
|
||||||
|
import { RouterLink } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
standalone: true,
|
||||||
|
imports: [BtnLargeComponent, FormsModule, RouterLink],
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrl: './login.component.scss',
|
||||||
|
})
|
||||||
|
export class LoginComponent {
|
||||||
|
authData = {
|
||||||
|
mail: '',
|
||||||
|
password: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
isUserEmailValid(emailValue: string) {
|
||||||
|
const emailRegex = /^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}$/;
|
||||||
|
return emailRegex.test(emailValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(ngForm: NgForm) {
|
||||||
|
if (ngForm.submitted && ngForm.form.valid) {
|
||||||
|
console.log(this.authData);
|
||||||
|
this.authData.mail = '';
|
||||||
|
this.authData.password = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
<form
|
<form
|
||||||
id="form"
|
id="form"
|
||||||
class="register-form"
|
class="register-form"
|
||||||
#taskForm="ngForm"
|
#registerForm="ngForm"
|
||||||
(ngSubmit)="onSubmit(taskForm)"
|
(ngSubmit)="onSubmit(registerForm)"
|
||||||
onsubmit="return false"
|
onsubmit="return false"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
<section class="bg-home">
|
<section class="bg-home">
|
||||||
<app-header></app-header>
|
<app-header></app-header>
|
||||||
@if (currentRoute === '') {
|
<app-auth *ngIf="currentRoute === ''"></app-auth>
|
||||||
<app-auth></app-auth>
|
<app-login *ngIf="currentRoute === 'login'"></app-login>
|
||||||
} @if (currentRoute === 'register') {
|
<app-register *ngIf="currentRoute === 'register'"></app-register>
|
||||||
<app-register></app-register>
|
|
||||||
}
|
|
||||||
<app-footer></app-footer>
|
<app-footer></app-footer>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,20 @@ import { FooterComponent } from './footer/footer.component';
|
||||||
import { AuthComponent } from '../auth/auth.component';
|
import { AuthComponent } from '../auth/auth.component';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { RegisterComponent } from '../auth/register/register.component';
|
import { RegisterComponent } from '../auth/register/register.component';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { LoginComponent } from '../auth/login/login.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [HeaderComponent, FooterComponent, AuthComponent, RegisterComponent],
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
HeaderComponent,
|
||||||
|
FooterComponent,
|
||||||
|
AuthComponent,
|
||||||
|
RegisterComponent,
|
||||||
|
LoginComponent,
|
||||||
|
],
|
||||||
templateUrl: './home.component.html',
|
templateUrl: './home.component.html',
|
||||||
styleUrl: './home.component.scss',
|
styleUrl: './home.component.scss',
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue