diff --git a/src/app/contacts/add/add.component.css b/src/app/contacts/add/add.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/contacts/add/add.component.html b/src/app/contacts/add/add.component.html
new file mode 100644
index 00000000..ee3d58dd
--- /dev/null
+++ b/src/app/contacts/add/add.component.html
@@ -0,0 +1,49 @@
+
diff --git a/src/app/contacts/add/add.component.spec.ts b/src/app/contacts/add/add.component.spec.ts
new file mode 100644
index 00000000..f4528470
--- /dev/null
+++ b/src/app/contacts/add/add.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddComponent } from './add.component';
+
+describe('AddComponent', () => {
+ let component: AddComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [AddComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(AddComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/contacts/add/add.component.ts b/src/app/contacts/add/add.component.ts
new file mode 100644
index 00000000..5c57de55
--- /dev/null
+++ b/src/app/contacts/add/add.component.ts
@@ -0,0 +1,40 @@
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { ContactsService } from '../contacts.service';
+import { Contact } from 'src/app/models/contact';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-add',
+ standalone: false,
+ templateUrl: './add.component.html',
+ styleUrl: './add.component.css'
+})
+export class AddComponent {
+ contactForm: FormGroup;
+ constructor(
+ private readonly formBuilder: FormBuilder,
+ private readonly contactService: ContactsService,
+ private readonly router: Router
+ ){
+ this.contactForm = this.formBuilder.group({
+ name: ['', Validators.required],
+ phone: ['', Validators.required],
+ email: ['', Validators.required],
+ address: ['', Validators.required],
+ });
+ }
+ addContact(): void {
+ const contactsMax = Math.max(...this.contactService.contacts.map(c => c.id).filter((id): id is number => id !== null));
+ const newContact: Contact = {
+ id: contactsMax + 1,
+ name: this.contactForm.value.name,
+ phone: this.contactForm.value.phone,
+ email: this.contactForm.value.email,
+ address: this.contactForm.value.address
+ }
+ this.contactService.AddContact(newContact);
+ this.contactForm.reset();
+ this.router.navigate(['/contacts'])
+ }
+}
diff --git a/src/app/contacts/contacts.module.ts b/src/app/contacts/contacts.module.ts
new file mode 100644
index 00000000..1311a5ba
--- /dev/null
+++ b/src/app/contacts/contacts.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ListComponent } from './list/list.component';
+import { AddComponent } from './add/add.component';
+import { ViewComponent } from './view/view.component';
+import { RouterModule } from '@angular/router';
+import { ReactiveFormsModule } from '@angular/forms';
+import { EditComponent } from './edit/edit.component';
+
+
+@NgModule({
+ declarations: [ListComponent, AddComponent, ViewComponent, EditComponent],
+ imports: [CommonModule, ReactiveFormsModule, RouterModule],
+ exports: [AddComponent, ListComponent, ViewComponent, EditComponent]
+})
+export class ContactsModule { }
diff --git a/src/app/contacts/contacts.service.ts b/src/app/contacts/contacts.service.ts
new file mode 100644
index 00000000..be30a300
--- /dev/null
+++ b/src/app/contacts/contacts.service.ts
@@ -0,0 +1,37 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable, of } from 'rxjs';
+import { Contact } from '../models/contact';
+import { CONTACTS } from '../data/contacts';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ContactsService {
+ public contacts: Contact[] = CONTACTS;
+
+ public AddContact(contact: Contact): void {
+ this.contacts.push(contact)
+ }
+
+ public GetContactById(id: number | null){
+ const contact = this.contacts.find((c) => c.id === id);
+ if(contact == null){
+ return null;
+ }
+ return contact;
+ }
+
+ public EditContact(contact:Contact): void {
+ const thisContact = this.GetContactById(contact.id)
+ if (thisContact != null){
+ thisContact.name = contact.name,
+ thisContact.phone = contact.phone,
+ thisContact.email = contact.email,
+ thisContact.address = contact.address
+
+ }
+ }
+
+ //constructor() { }
+}
diff --git a/src/app/contacts/edit/edit.component.css b/src/app/contacts/edit/edit.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/contacts/edit/edit.component.html b/src/app/contacts/edit/edit.component.html
new file mode 100644
index 00000000..c0effad8
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.html
@@ -0,0 +1,49 @@
+
diff --git a/src/app/contacts/edit/edit.component.spec.ts b/src/app/contacts/edit/edit.component.spec.ts
new file mode 100644
index 00000000..6676ccfd
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditComponent } from './edit.component';
+
+describe('EditComponent', () => {
+ let component: EditComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [EditComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(EditComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/contacts/edit/edit.component.ts b/src/app/contacts/edit/edit.component.ts
new file mode 100644
index 00000000..43e66e58
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.ts
@@ -0,0 +1,52 @@
+import { Component, OnInit } from '@angular/core';
+import { Contact } from 'src/app/models/contact';
+import { ContactsService } from '../contacts.service';
+import { ActivatedRoute, Router } from '@angular/router';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+ selector: 'app-edit',
+ standalone: false,
+ templateUrl: './edit.component.html',
+ styleUrl: './edit.component.css'
+})
+export class EditComponent implements OnInit {
+ contact: Contact | null = null;
+ contactId: number | null = null;
+ contactForm: FormGroup;
+
+ constructor(
+ private route: ActivatedRoute,
+ private readonly formBuilder: FormBuilder,
+ private readonly contactService: ContactsService,
+ private readonly router: Router
+ ) {
+ this.contactId = Number(this.route.snapshot.paramMap.get('id'));
+ this.contact = this.contactService.GetContactById(this.contactId);
+ this.contactForm = this.formBuilder.group({
+ name: [this.contact?.name, Validators.required],
+ phone: [this.contact?.phone, Validators.required],
+ email: [this.contact?.email, Validators.required],
+ address: [this.contact?.address, Validators.required],
+ });
+ }
+
+ ngOnInit(): void {
+ this.contactId = Number(this.route.snapshot.paramMap.get('id'));
+ this.contact = this.contactService.GetContactById(this.contactId);
+ }
+
+
+ editContact(): void {
+ const editContact: Contact = {
+ id: this.contactId,
+ name: this.contactForm.value.name,
+ phone: this.contactForm.value.phone,
+ email: this.contactForm.value.email,
+ address: this.contactForm.value.address
+ }
+ this.contactService.EditContact(editContact);
+ this.contactForm.reset();
+ this.router.navigate(['/contacts'])
+ }
+}
\ No newline at end of file
diff --git a/src/app/contacts/list/list.component.css b/src/app/contacts/list/list.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/contacts/list/list.component.html b/src/app/contacts/list/list.component.html
new file mode 100644
index 00000000..1b6a6101
--- /dev/null
+++ b/src/app/contacts/list/list.component.html
@@ -0,0 +1,22 @@
+
+
+ | Id |
+ Name |
+ Phone |
+ Email |
+ Address |
+
+
+
+ |
+
+ {{ contact.id }}
+
+ |
+ {{ contact.name }} |
+ {{ contact.phone }} |
+ {{ contact.email }} |
+ {{ contact.address }} |
+
+
+
diff --git a/src/app/contacts/list/list.component.spec.ts b/src/app/contacts/list/list.component.spec.ts
new file mode 100644
index 00000000..b602c867
--- /dev/null
+++ b/src/app/contacts/list/list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ListComponent } from './list.component';
+
+describe('ListComponent', () => {
+ let component: ListComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ListComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/contacts/list/list.component.ts b/src/app/contacts/list/list.component.ts
new file mode 100644
index 00000000..b2cab5ca
--- /dev/null
+++ b/src/app/contacts/list/list.component.ts
@@ -0,0 +1,17 @@
+import { Component } from '@angular/core';
+import { Injectable } from '@angular/core';
+import { Contact } from 'src/app/models/contact';
+import { ContactsService } from '../contacts.service';
+
+@Component({
+ selector: 'app-list',
+ standalone: false,
+ templateUrl: './list.component.html',
+ styleUrl: './list.component.css'
+})
+export class ListComponent {
+ contacts: Contact[] = [];
+ constructor(private readonly contactService: ContactsService){
+ this.contacts = this.contactService.contacts;
+ }
+}
diff --git a/src/app/contacts/view/view.component.css b/src/app/contacts/view/view.component.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/contacts/view/view.component.html b/src/app/contacts/view/view.component.html
new file mode 100644
index 00000000..2f3c13fd
--- /dev/null
+++ b/src/app/contacts/view/view.component.html
@@ -0,0 +1,13 @@
+
+
{{ contact.name }}
+
Phone: {{ contact.phone}}
+
Email: {{ contact.email}}
+
Address: {{ contact.address}}
+
+
+
+
+
+
+ Loading contact details...
+
diff --git a/src/app/contacts/view/view.component.spec.ts b/src/app/contacts/view/view.component.spec.ts
new file mode 100644
index 00000000..380ab164
--- /dev/null
+++ b/src/app/contacts/view/view.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ViewComponent } from './view.component';
+
+describe('ViewComponent', () => {
+ let component: ViewComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ViewComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ViewComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/contacts/view/view.component.ts b/src/app/contacts/view/view.component.ts
new file mode 100644
index 00000000..0cec4050
--- /dev/null
+++ b/src/app/contacts/view/view.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit } from '@angular/core';
+import { ContactsService } from '../contacts.service';
+import { Contact } from 'src/app/models/contact';
+import { ActivatedRoute } from '@angular/router';
+
+@Component({
+ selector: 'app-view',
+ standalone: false,
+ templateUrl: './view.component.html',
+ styleUrl: './view.component.css'
+})
+export class ViewComponent implements OnInit {
+ contact: Contact | null = null;
+ contactId: number | null = null;
+
+ constructor(
+ private route: ActivatedRoute,
+ private contactService: ContactsService
+ ) {}
+
+ ngOnInit(): void {
+ this.contactId = Number(this.route.snapshot.paramMap.get('id'));
+ this.contact = this.contactService.GetContactById(this.contactId);
+ }
+}
\ No newline at end of file