diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7da2a6b..68a3bb1 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -6,6 +6,7 @@ import {CourseComponent} from './course/course.component';
import {courseResolver} from './services/course.resolver';
import {LoginComponent} from './login/login.component';
import {CreateCourseComponent} from './create-course/create-course.component';
+import { LoginReactiveComponent } from './login-reactive/login-reactive.component';
const routes: Routes = [
{
@@ -30,7 +31,7 @@ const routes: Routes = [
},
{
path: 'login',
- component: LoginComponent
+ component: LoginReactiveComponent
},
{
path: '**',
diff --git a/src/app/app.component.css b/src/app/app.component.css
index 3516e92..fecf65e 100644
--- a/src/app/app.component.css
+++ b/src/app/app.component.css
@@ -1,5 +1,5 @@
->>> body {
+body {
margin: 0;
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 8410579..538ec82 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -27,7 +27,7 @@ import { MatToolbarModule } from "@angular/material/toolbar";
import {CoursesService} from "./services/courses.service";
import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http";
import { CourseDialogComponent } from './course-dialog/course-dialog.component';
-import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {LoginComponent} from './login/login.component';
import { CreateCourseComponent } from './create-course/create-course.component';
import {MatNativeDateModule} from '@angular/material/core';
@@ -41,6 +41,8 @@ import {CreateCourseStep1Component} from './create-course/create-course-step-1/c
import {FileUploadComponent} from './file-upload/file-upload.component';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {LoginReactiveComponent} from './login-reactive/login-reactive.component';
+import { PasswordStrengthDirective } from './directives/password-strength.directive';
+import { OnlyOneErrorPipe } from './pipes/only-one-error.pipe';
@NgModule({ declarations: [
AppComponent,
@@ -56,7 +58,9 @@ import {LoginReactiveComponent} from './login-reactive/login-reactive.component'
CreateCourseStep3Component,
AddressFormComponent,
FileUploadComponent,
- LoginReactiveComponent
+ LoginReactiveComponent,
+ PasswordStrengthDirective,
+ OnlyOneErrorPipe
],
bootstrap: [AppComponent], imports: [BrowserModule,
BrowserAnimationsModule,
diff --git a/src/app/create-course/create-course-step-1/create-course-step-1.component.html b/src/app/create-course/create-course-step-1/create-course-step-1.component.html
index e69de29..fcfd83b 100644
--- a/src/app/create-course/create-course-step-1/create-course-step-1.component.html
+++ b/src/app/create-course/create-course-step-1/create-course-step-1.component.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+ {{title.value.length}} / 60
+
+
+
+
+
diff --git a/src/app/create-course/create-course-step-1/create-course-step-1.component.ts b/src/app/create-course/create-course-step-1/create-course-step-1.component.ts
index 42ecaad..6bdf364 100644
--- a/src/app/create-course/create-course-step-1/create-course-step-1.component.ts
+++ b/src/app/create-course/create-course-step-1/create-course-step-1.component.ts
@@ -1,18 +1,23 @@
-import {Component, OnInit} from '@angular/core';
-import {FormBuilder, FormGroup, Validators} from '@angular/forms';
-import {CoursesService} from '../../services/courses.service';
-import {Observable} from 'rxjs';
-import {filter} from 'rxjs/operators';
+import { Component, OnInit } from "@angular/core";
+import { FormBuilder, FormGroup, Validators } from "@angular/forms";
+import { CoursesService } from "../../services/courses.service";
+import { Observable } from "rxjs";
+import { filter } from "rxjs/operators";
@Component({
- selector: 'create-course-step-1',
- templateUrl: './create-course-step-1.component.html',
- styleUrls: ['./create-course-step-1.component.scss']
+ selector: "create-course-step-1",
+ templateUrl: "./create-course-step-1.component.html",
+ styleUrls: ["./create-course-step-1.component.scss"],
})
export class CreateCourseStep1Component implements OnInit {
+ form = this.fb.group({
+ title: [
+ "",
+ [Validators.required, Validators.minLength(5), Validators.maxLength(60)],
+ ],
+ });
- ngOnInit() {
-
- }
+ constructor(private fb: FormBuilder) {}
+ ngOnInit() {}
}
diff --git a/src/app/create-course/create-course.component.html b/src/app/create-course/create-course.component.html
index 6bfb728..da414ff 100644
--- a/src/app/create-course/create-course.component.html
+++ b/src/app/create-course/create-course.component.html
@@ -1,8 +1,17 @@
-
-
Create New Course
-
+
+
+ course landing page details
+
+
+
+
+
+
+
diff --git a/src/app/directives/password-strength.directive.ts b/src/app/directives/password-strength.directive.ts
new file mode 100644
index 0000000..12108ae
--- /dev/null
+++ b/src/app/directives/password-strength.directive.ts
@@ -0,0 +1,21 @@
+import { Directive } from "@angular/core";
+import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, Validators } from "@angular/forms";
+import { createPasswordStrengthValidator } from "../validators/password-strength.validator";
+
+
+@Directive({
+ selector: '[passwordStrength]',
+ providers: [{
+ provide: NG_VALIDATORS,
+ useExisting: PasswordStrengthDirective,
+ multi: true
+ }]
+
+
+})
+export class PasswordStrengthDirective implements Validator {
+
+ validate(control: AbstractControl): ValidationErrors | null{
+ return createPasswordStrengthValidator()(control);
+ }
+}
diff --git a/src/app/login-reactive/login-reactive.component.css b/src/app/login-reactive/login-reactive.component.css
index a780a9f..c3d8164 100644
--- a/src/app/login-reactive/login-reactive.component.css
+++ b/src/app/login-reactive/login-reactive.component.css
@@ -14,5 +14,10 @@
border-bottom: 1px solid grey;
margin-bottom: 10px;
}
+.field-message {
+ color: red; /* Example styling */
+ font-size: 12px;
+ margin-top: 5px;
+}
diff --git a/src/app/login-reactive/login-reactive.component.html b/src/app/login-reactive/login-reactive.component.html
index 4e9b389..def85f8 100644
--- a/src/app/login-reactive/login-reactive.component.html
+++ b/src/app/login-reactive/login-reactive.component.html
@@ -1,27 +1,68 @@
Login (Reactive)
-
-
+
+ {{ form.value | json }}
+
+
+
+ {{ form.valid | json }}
+
diff --git a/src/app/login-reactive/login-reactive.component.ts b/src/app/login-reactive/login-reactive.component.ts
index c73b78a..651c3df 100644
--- a/src/app/login-reactive/login-reactive.component.ts
+++ b/src/app/login-reactive/login-reactive.component.ts
@@ -1,21 +1,54 @@
-import { Component, OnInit } from '@angular/core';
-
+import { Component, OnInit } from "@angular/core";
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ NonNullableFormBuilder,
+ Validators,
+} from "@angular/forms";
+import { createPasswordStrengthValidator } from "../validators/password-strength.validator";
@Component({
- selector: 'login',
- templateUrl: './login-reactive.component.html',
- styleUrls: ['./login-reactive.component.css']
+ selector: "login",
+ templateUrl: "./login-reactive.component.html",
+ styleUrls: ["./login-reactive.component.css"],
})
export class LoginReactiveComponent implements OnInit {
+ form = this.fb.group({
+ email: [
+ "",
+ {
+ validators: [Validators.required, Validators.email],
+ updateOn: "blur",
+ },
+ ],
+ password: [
+ "",
+ [
+ Validators.required,
+ Validators.minLength(8),
+ createPasswordStrengthValidator(),
+ ],
+ ],
+ });
+
+ constructor(private fb: NonNullableFormBuilder) {}
+
+ ngOnInit() {}
+
+ get email() {
+ return this.form.controls["email"];
+ }
-
- constructor() {
-
-
+ get password() {
+ return this.form.controls["password"];
}
- ngOnInit() {
+ login() {}
- }
+ reset() {
+ this.form.reset();
+ console.log(this.form.value);
+ }
}
diff --git a/src/app/login/login.component.css b/src/app/login/login.component.css
index a780a9f..7756bdc 100644
--- a/src/app/login/login.component.css
+++ b/src/app/login/login.component.css
@@ -15,4 +15,10 @@
margin-bottom: 10px;
}
+.field-message {
+ color: red; /* Example styling */
+ font-size: 12px;
+ margin-top: 5px;
+}
+
diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html
index e4ed4db..c4104ae 100644
--- a/src/app/login/login.component.html
+++ b/src/app/login/login.component.html
@@ -1,27 +1,73 @@
- Login
+ Login (Template-Driven-Form)
-
-
-
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts
index 84905e8..4fcade4 100644
--- a/src/app/login/login.component.ts
+++ b/src/app/login/login.component.ts
@@ -1,21 +1,26 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit } from "@angular/core";
+import { NgForm } from "@angular/forms";
@Component({
- selector: 'login',
- templateUrl: './login.component.html',
- styleUrls: ['./login.component.css']
+ selector: "login",
+ templateUrl: "./login.component.html",
+ styleUrls: ["./login.component.css"],
})
export class LoginComponent implements OnInit {
-
- constructor() {
-
-
+ val = {
+ email: "hello@gmail.com",
+ password: "123456"
}
+ constructor() {}
- ngOnInit() {
+ ngOnInit() {}
+ login(loginForm: NgForm) {
+ console.log(loginForm.value, loginForm.valid);
+ console.log(this.val);
}
+
}
diff --git a/src/app/pipes/only-one-error.pipe.ts b/src/app/pipes/only-one-error.pipe.ts
new file mode 100644
index 0000000..89d7e7c
--- /dev/null
+++ b/src/app/pipes/only-one-error.pipe.ts
@@ -0,0 +1,22 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+ name: "onlyOneError",
+})
+export class OnlyOneErrorPipe implements PipeTransform {
+ transform(allErrors: any, errorsPriority: string[]): any {
+ if (!allErrors) {
+ return null;
+ }
+ const onlyOneError: any = {};
+
+ for (let error of errorsPriority) {
+ if (allErrors[error]) {
+ onlyOneError[error] = allErrors[error];
+ break;
+ }
+ }
+
+ return onlyOneError;
+ }
+}
diff --git a/src/app/validators/password-strength.validator.ts b/src/app/validators/password-strength.validator.ts
new file mode 100644
index 0000000..5f9175e
--- /dev/null
+++ b/src/app/validators/password-strength.validator.ts
@@ -0,0 +1,28 @@
+import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms";
+
+export function createPasswordStrengthValidator(): ValidatorFn {
+ return (control: AbstractControl) : ValidationErrors | null => {
+
+ const value = control.value;
+
+ if (!value) {
+ return null;
+ }
+
+ const hasUpperCase = /[A-Z]+/.test(value);
+
+ const hasLowerCase = /[a-z]+/.test(value);
+
+ const hasNumeric = /[0-9]+/.test(value);
+
+ const passwordValid = hasUpperCase && hasLowerCase && hasNumeric;
+
+ return !passwordValid ? {passwordStrength: true} : null;
+
+
+ }
+
+ }
+
+
+