From d83587e917deb5b103e45350031a89c02888d363 Mon Sep 17 00:00:00 2001
From: Mathias Handeland <127216029+MathiasHandeland@users.noreply.github.com>
Date: Mon, 8 Sep 2025 11:47:58 +0200
Subject: [PATCH 1/4] feat: contacts list and menu
---
angular.json | 3 ++
src/app/app-routing.module.ts | 10 ++++++-
src/app/app.component.html | 2 +-
src/app/app.module.ts | 5 +++-
src/app/contacts/add/add.component.css | 0
src/app/contacts/add/add.component.html | 1 +
src/app/contacts/add/add.component.spec.ts | 23 ++++++++++++++++
src/app/contacts/add/add.component.ts | 11 ++++++++
src/app/contacts/contacts.module.ts | 18 ++++++++++++
src/app/contacts/contacts.service.ts | 16 +++++++++++
src/app/contacts/list/list.component.css | 22 +++++++++++++++
src/app/contacts/list/list.component.html | 19 +++++++++++++
src/app/contacts/list/list.component.spec.ts | 23 ++++++++++++++++
src/app/contacts/list/list.component.ts | 16 +++++++++++
src/app/contacts/view/view.component.css | 0
src/app/contacts/view/view.component.html | 1 +
src/app/contacts/view/view.component.spec.ts | 23 ++++++++++++++++
src/app/contacts/view/view.component.ts | 11 ++++++++
src/app/data/contacts.ts | 18 ++++++++++++
src/app/layout/menu/menu.component.css | 29 ++++++++++++++++++--
src/app/layout/menu/menu.component.html | 6 ++--
src/app/models/contact.ts | 7 +++++
22 files changed, 256 insertions(+), 8 deletions(-)
create mode 100644 src/app/contacts/add/add.component.css
create mode 100644 src/app/contacts/add/add.component.html
create mode 100644 src/app/contacts/add/add.component.spec.ts
create mode 100644 src/app/contacts/add/add.component.ts
create mode 100644 src/app/contacts/contacts.module.ts
create mode 100644 src/app/contacts/contacts.service.ts
create mode 100644 src/app/contacts/list/list.component.css
create mode 100644 src/app/contacts/list/list.component.html
create mode 100644 src/app/contacts/list/list.component.spec.ts
create mode 100644 src/app/contacts/list/list.component.ts
create mode 100644 src/app/contacts/view/view.component.css
create mode 100644 src/app/contacts/view/view.component.html
create mode 100644 src/app/contacts/view/view.component.spec.ts
create mode 100644 src/app/contacts/view/view.component.ts
create mode 100644 src/app/data/contacts.ts
create mode 100644 src/app/models/contact.ts
diff --git a/angular.json b/angular.json
index 7a4f1ef7..be4c78d3 100644
--- a/angular.json
+++ b/angular.json
@@ -94,5 +94,8 @@
}
}
}
+ },
+ "cli": {
+ "analytics": false
}
}
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 02972627..8134f4dd 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,7 +1,15 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
+import { AddComponent } from './contacts/add/add.component';
+import { ListComponent } from './contacts/list/list.component';
+import { ViewComponent } from './contacts/view/view.component';
+import { MenuComponent } from './layout/menu/menu.component';
-const routes: Routes = [];
+const routes: Routes = [
+ { path: 'contacts', component: ListComponent },
+ { path: 'contacts/add', component: AddComponent },
+ { path: 'contacts/:id', component: ViewComponent },
+];
@NgModule({
imports: [RouterModule.forRoot(routes)],
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 17aaa0c6..e04ea729 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,4 +1,4 @@
-
+
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 8207184c..cec2d2a2 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -4,10 +4,13 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LayoutModule } from './layout/layout.module';
+import { ContactsModule } from './contacts/contacts.module';
+import { CommonModule } from '@angular/common';
@NgModule({
declarations: [AppComponent],
- imports: [BrowserModule, AppRoutingModule, LayoutModule],
+ imports: [BrowserModule, AppRoutingModule, CommonModule, ContactsModule, LayoutModule],
+ providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
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..fa723f3a
--- /dev/null
+++ b/src/app/contacts/add/add.component.html
@@ -0,0 +1 @@
+add works!
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..a9be8c06
--- /dev/null
+++ b/src/app/contacts/add/add.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-add',
+ standalone: false,
+ templateUrl: './add.component.html',
+ styleUrls: ['./add.component.css']
+})
+export class AddComponent {
+
+}
diff --git a/src/app/contacts/contacts.module.ts b/src/app/contacts/contacts.module.ts
new file mode 100644
index 00000000..b83dc506
--- /dev/null
+++ b/src/app/contacts/contacts.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { AddComponent } from './add/add.component';
+import { ListComponent } from './list/list.component';
+import { ViewComponent } from './view/view.component';
+import { RouterModule } from '@angular/router';
+import { ReactiveFormsModule } from '@angular/forms';
+
+@NgModule({
+ declarations: [AddComponent, ListComponent, ViewComponent],
+ imports: [
+ CommonModule,
+ RouterModule,
+ ReactiveFormsModule
+ ],
+ exports: [AddComponent, ListComponent, ViewComponent]
+})
+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..4b19a424
--- /dev/null
+++ b/src/app/contacts/contacts.service.ts
@@ -0,0 +1,16 @@
+import { Injectable } from '@angular/core';
+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);
+ }
+
+
+}
diff --git a/src/app/contacts/list/list.component.css b/src/app/contacts/list/list.component.css
new file mode 100644
index 00000000..484ffe78
--- /dev/null
+++ b/src/app/contacts/list/list.component.css
@@ -0,0 +1,22 @@
+.contacts-table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-bottom: 2em;
+ font-family: Arial, sans-serif;
+}
+
+.contacts-table th,
+.contacts-table td {
+ padding: 1em 1em;
+ text-align: left;
+ border-bottom: 1px solid #ccc;
+}
+
+.contacts-table th {
+ background-color: #f0f0f0;
+ font-weight: 600;
+}
+
+.contacts-table tr:hover {
+ background-color: #f9f9f9;
+}
diff --git a/src/app/contacts/list/list.component.html b/src/app/contacts/list/list.component.html
new file mode 100644
index 00000000..634ae548
--- /dev/null
+++ b/src/app/contacts/list/list.component.html
@@ -0,0 +1,19 @@
+Contacts
+
\ No newline at end of file
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..f5bd040d
--- /dev/null
+++ b/src/app/contacts/list/list.component.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+import { Contact } from '../../models/contact';
+import { ContactsService } from '../contacts.service';
+
+@Component({
+ selector: 'app-list',
+ standalone: false,
+ templateUrl: './list.component.html',
+ styleUrls: ['./list.component.css']
+})
+export class ListComponent {
+ contacts: Contact[] = [];
+ constructor(private readonly contactsService: ContactsService) {
+ this.contacts = this.contactsService.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..48dbfee6
--- /dev/null
+++ b/src/app/contacts/view/view.component.html
@@ -0,0 +1 @@
+view works!
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..fa9fb981
--- /dev/null
+++ b/src/app/contacts/view/view.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-view',
+ standalone: false,
+ templateUrl: './view.component.html',
+ styleUrls: ['./view.component.css']
+})
+export class ViewComponent {
+
+}
diff --git a/src/app/data/contacts.ts b/src/app/data/contacts.ts
new file mode 100644
index 00000000..78403266
--- /dev/null
+++ b/src/app/data/contacts.ts
@@ -0,0 +1,18 @@
+import { Contact } from '../models/contact';
+
+export const CONTACTS: Contact[] = [
+ {
+ id: 1,
+ firstName: 'John',
+ lastName: 'Doe',
+ street: '123 Main St',
+ city: 'Anytown'
+ },
+ {
+ id: 2,
+ firstName: 'Jane',
+ lastName: 'Smith',
+ street: '456 Elm St',
+ city: 'Othertown'
+ },
+];
\ No newline at end of file
diff --git a/src/app/layout/menu/menu.component.css b/src/app/layout/menu/menu.component.css
index 75955b3c..6fd952d2 100644
--- a/src/app/layout/menu/menu.component.css
+++ b/src/app/layout/menu/menu.component.css
@@ -1,10 +1,35 @@
-:host {
- padding: 0 0.5em;
+h2 {
+ margin-bottom: 1em;
+ font-size: 50px;
+ color: #333;
+}
+
+h2 a {
+ text-decoration: none;
+ color: inherit;
+}
+
+h2 a:hover {
+ text-decoration: underline;
}
ul {
padding: 0;
}
+
li {
list-style: none;
+ text-decoration: none;
+ border: 1px solid #ccc;
+ border-radius: 8px;
+ background: #f9f9f9;
+ margin-bottom: 0.75em;
+ padding: 1em;
+}
+
+li a {
+ text-decoration: none;
+ font-size: 25px;
+ font-weight: bold;
+ color: #333;
}
diff --git a/src/app/layout/menu/menu.component.html b/src/app/layout/menu/menu.component.html
index 7c5ec7a2..d39cc06c 100644
--- a/src/app/layout/menu/menu.component.html
+++ b/src/app/layout/menu/menu.component.html
@@ -1,5 +1,5 @@
-Menu
+
diff --git a/src/app/models/contact.ts b/src/app/models/contact.ts
new file mode 100644
index 00000000..8ccb8326
--- /dev/null
+++ b/src/app/models/contact.ts
@@ -0,0 +1,7 @@
+export interface Contact {
+ id: number | null;
+ firstName: string;
+ lastName: string;
+ street: string;
+ city: string;
+}
\ No newline at end of file
From 0c13b90adba2721b0903f62d4c4af1b154cbfe59 Mon Sep 17 00:00:00 2001
From: Mathias Handeland <127216029+MathiasHandeland@users.noreply.github.com>
Date: Mon, 8 Sep 2025 12:58:15 +0200
Subject: [PATCH 2/4] feat: add + view
---
src/app/contacts/add/add.component.css | 33 +++++++++++++++++++++++
src/app/contacts/add/add.component.html | 23 +++++++++++++++-
src/app/contacts/add/add.component.ts | 33 +++++++++++++++++++++++
src/app/contacts/contacts.service.ts | 6 ++++-
src/app/contacts/list/list.component.css | 15 +++++++++++
src/app/contacts/list/list.component.html | 2 ++
src/app/contacts/view/view.component.html | 3 ++-
src/app/contacts/view/view.component.ts | 20 ++++++++++++--
src/app/layout/menu/menu.component.html | 2 +-
9 files changed, 131 insertions(+), 6 deletions(-)
diff --git a/src/app/contacts/add/add.component.css b/src/app/contacts/add/add.component.css
index e69de29b..ddc82f51 100644
--- a/src/app/contacts/add/add.component.css
+++ b/src/app/contacts/add/add.component.css
@@ -0,0 +1,33 @@
+h2 {
+ font-size: 2em;
+}
+
+form div {
+ margin-bottom: 1em;
+ display: flex;
+ flex-direction: column;
+}
+
+label {
+ margin-bottom: 0.25em;
+ font-weight: bold;
+}
+
+input[type="text"] {
+ padding: 0.5em;
+ font-size: 1em;
+}
+
+button {
+ padding: 0.5em 1em;
+ font-size: 1em;
+ font-weight: bold;
+ color: #fff;
+ background-color: #054992;
+ cursor: pointer;
+}
+
+button:disabled {
+ background-color: #999;
+ cursor: not-allowed;
+}
diff --git a/src/app/contacts/add/add.component.html b/src/app/contacts/add/add.component.html
index fa723f3a..de9583ea 100644
--- a/src/app/contacts/add/add.component.html
+++ b/src/app/contacts/add/add.component.html
@@ -1 +1,22 @@
-add works!
+
\ No newline at end of file
diff --git a/src/app/contacts/add/add.component.ts b/src/app/contacts/add/add.component.ts
index a9be8c06..3a82bd55 100644
--- a/src/app/contacts/add/add.component.ts
+++ b/src/app/contacts/add/add.component.ts
@@ -1,4 +1,9 @@
import { Component } from '@angular/core';
+import { Router } from '@angular/router';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Contact } from 'src/app/models/contact';
+import { ContactsService } from '../contacts.service';
+import { first } from 'rxjs';
@Component({
selector: 'app-add',
@@ -7,5 +12,33 @@ import { Component } from '@angular/core';
styleUrls: ['./add.component.css']
})
export class AddComponent {
+ contactForm: FormGroup;
+ constructor(
+ private readonly formBuilder: FormBuilder,
+ private readonly contactsService: ContactsService,
+ private readonly router: Router
+ ) {
+ this.contactForm = this.formBuilder.group({
+ firstName: ['', Validators.required],
+ lastName: ['', Validators.required],
+ street: ['', Validators.required],
+ city: ['', Validators.required],
+ });
+ }
+
+ addContact() {
+ const newContact: Contact = {
+ id: 0,
+ firstName: this.contactForm.value.firstName,
+ lastName: this.contactForm.value.lastName,
+ street: this.contactForm.value.street,
+ city: this.contactForm.value.city,
+ };
+ this.contactsService.AddContact(newContact);
+ this.contactForm.reset();
+ this.router.navigate(['/contacts']);
+ }
}
+
+
diff --git a/src/app/contacts/contacts.service.ts b/src/app/contacts/contacts.service.ts
index 4b19a424..fe329360 100644
--- a/src/app/contacts/contacts.service.ts
+++ b/src/app/contacts/contacts.service.ts
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { Contact } from '../models/contact';
import { CONTACTS } from '../data/contacts';
+import { of, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
@@ -12,5 +13,8 @@ export class ContactsService {
this.contacts.push(contact);
}
-
+ public GetContactById(id: number): Observable {
+ const contact = this.contacts.find(contact => contact.id === id);
+ return of(contact);
+ }
}
diff --git a/src/app/contacts/list/list.component.css b/src/app/contacts/list/list.component.css
index 484ffe78..f2bbd77b 100644
--- a/src/app/contacts/list/list.component.css
+++ b/src/app/contacts/list/list.component.css
@@ -20,3 +20,18 @@
.contacts-table tr:hover {
background-color: #f9f9f9;
}
+
+.view-button {
+ padding: 0.5em 1em;
+ cursor: pointer;
+ border-radius: 4px;
+}
+
+.view-button:hover {
+ background-color: #e0e0e0;
+}
+
+.view-button a {
+ text-decoration: none;
+ color: #040404;
+ font-weight: bold;}
diff --git a/src/app/contacts/list/list.component.html b/src/app/contacts/list/list.component.html
index 634ae548..420b6962 100644
--- a/src/app/contacts/list/list.component.html
+++ b/src/app/contacts/list/list.component.html
@@ -6,6 +6,7 @@ Contacts
Last Name
Street
City
+ Details
@@ -14,6 +15,7 @@ Contacts
{{ contact.lastName }}
{{ contact.street }}
{{ contact.city }}
+ View
\ No newline at end of file
diff --git a/src/app/contacts/view/view.component.html b/src/app/contacts/view/view.component.html
index 48dbfee6..a863f5aa 100644
--- a/src/app/contacts/view/view.component.html
+++ b/src/app/contacts/view/view.component.html
@@ -1 +1,2 @@
-view works!
+{{ contact?.firstName }} {{ contact?.lastName }}
+{{ contact?.street }}, {{ contact?.city }}
diff --git a/src/app/contacts/view/view.component.ts b/src/app/contacts/view/view.component.ts
index fa9fb981..611e5f9e 100644
--- a/src/app/contacts/view/view.component.ts
+++ b/src/app/contacts/view/view.component.ts
@@ -1,4 +1,7 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
+import { Contact } from '../../models/contact';
+import { ActivatedRoute, } from '@angular/router';
+import { ContactsService } from '../contacts.service';
@Component({
selector: 'app-view',
@@ -6,6 +9,19 @@ import { Component } from '@angular/core';
templateUrl: './view.component.html',
styleUrls: ['./view.component.css']
})
-export class ViewComponent {
+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.contactService.GetContactById(this.contactId).subscribe(contact => {
+ this.contact = contact!;
+ });
+ }
}
diff --git a/src/app/layout/menu/menu.component.html b/src/app/layout/menu/menu.component.html
index d39cc06c..aed3259d 100644
--- a/src/app/layout/menu/menu.component.html
+++ b/src/app/layout/menu/menu.component.html
@@ -1,4 +1,4 @@
-
+Menu
Contacts list
Add new contact
From 43147a7852b55a974fd90c7d18039ac1c9b14a35 Mon Sep 17 00:00:00 2001
From: Mathias Handeland <127216029+MathiasHandeland@users.noreply.github.com>
Date: Mon, 8 Sep 2025 13:55:26 +0200
Subject: [PATCH 3/4] feat: edit contact
---
src/app/app-routing.module.ts | 3 +-
src/app/contacts/add/add.component.ts | 1 -
src/app/contacts/contacts.module.ts | 5 +-
src/app/contacts/contacts.service.ts | 10 +++-
src/app/contacts/edit/edit.component.css | 33 +++++++++++++
src/app/contacts/edit/edit.component.html | 22 +++++++++
src/app/contacts/edit/edit.component.spec.ts | 23 +++++++++
src/app/contacts/edit/edit.component.ts | 52 ++++++++++++++++++++
src/app/contacts/list/list.component.css | 5 --
src/app/contacts/list/list.component.html | 2 +-
src/app/contacts/view/view.component.css | 9 ++++
src/app/contacts/view/view.component.html | 2 +
12 files changed, 156 insertions(+), 11 deletions(-)
create mode 100644 src/app/contacts/edit/edit.component.css
create mode 100644 src/app/contacts/edit/edit.component.html
create mode 100644 src/app/contacts/edit/edit.component.spec.ts
create mode 100644 src/app/contacts/edit/edit.component.ts
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 8134f4dd..45de819e 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -3,12 +3,13 @@ import { RouterModule, Routes } from '@angular/router';
import { AddComponent } from './contacts/add/add.component';
import { ListComponent } from './contacts/list/list.component';
import { ViewComponent } from './contacts/view/view.component';
-import { MenuComponent } from './layout/menu/menu.component';
+import { EditComponent } from './contacts/edit/edit.component';
const routes: Routes = [
{ path: 'contacts', component: ListComponent },
{ path: 'contacts/add', component: AddComponent },
{ path: 'contacts/:id', component: ViewComponent },
+ { path: 'contacts/edit/:id', component: EditComponent }
];
@NgModule({
diff --git a/src/app/contacts/add/add.component.ts b/src/app/contacts/add/add.component.ts
index 3a82bd55..bf8d0e37 100644
--- a/src/app/contacts/add/add.component.ts
+++ b/src/app/contacts/add/add.component.ts
@@ -3,7 +3,6 @@ import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Contact } from 'src/app/models/contact';
import { ContactsService } from '../contacts.service';
-import { first } from 'rxjs';
@Component({
selector: 'app-add',
diff --git a/src/app/contacts/contacts.module.ts b/src/app/contacts/contacts.module.ts
index b83dc506..1444e43f 100644
--- a/src/app/contacts/contacts.module.ts
+++ b/src/app/contacts/contacts.module.ts
@@ -3,16 +3,17 @@ import { CommonModule } from '@angular/common';
import { AddComponent } from './add/add.component';
import { ListComponent } from './list/list.component';
import { ViewComponent } from './view/view.component';
+import { EditComponent } from './edit/edit.component';
import { RouterModule } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
- declarations: [AddComponent, ListComponent, ViewComponent],
+ declarations: [AddComponent, ListComponent, ViewComponent, EditComponent],
imports: [
CommonModule,
RouterModule,
ReactiveFormsModule
],
- exports: [AddComponent, ListComponent, ViewComponent]
+ exports: [AddComponent, ListComponent, ViewComponent, EditComponent]
})
export class ContactsModule { }
diff --git a/src/app/contacts/contacts.service.ts b/src/app/contacts/contacts.service.ts
index fe329360..95c373e7 100644
--- a/src/app/contacts/contacts.service.ts
+++ b/src/app/contacts/contacts.service.ts
@@ -17,4 +17,12 @@ export class ContactsService {
const contact = this.contacts.find(contact => contact.id === id);
return of(contact);
}
-}
+
+ public updateContact(updatedContact: Contact): Observable {
+ const index = this.contacts.findIndex(contact => contact.id === updatedContact.id);
+ if (index !== -1) {
+ this.contacts[index] = updatedContact;
+ }
+ return of(undefined);
+ }
+}
\ No newline at end of file
diff --git a/src/app/contacts/edit/edit.component.css b/src/app/contacts/edit/edit.component.css
new file mode 100644
index 00000000..ddc82f51
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.css
@@ -0,0 +1,33 @@
+h2 {
+ font-size: 2em;
+}
+
+form div {
+ margin-bottom: 1em;
+ display: flex;
+ flex-direction: column;
+}
+
+label {
+ margin-bottom: 0.25em;
+ font-weight: bold;
+}
+
+input[type="text"] {
+ padding: 0.5em;
+ font-size: 1em;
+}
+
+button {
+ padding: 0.5em 1em;
+ font-size: 1em;
+ font-weight: bold;
+ color: #fff;
+ background-color: #054992;
+ cursor: pointer;
+}
+
+button:disabled {
+ background-color: #999;
+ cursor: not-allowed;
+}
diff --git a/src/app/contacts/edit/edit.component.html b/src/app/contacts/edit/edit.component.html
new file mode 100644
index 00000000..62d5238a
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.html
@@ -0,0 +1,22 @@
+
\ No newline at end of file
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..69d77b80
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.ts
@@ -0,0 +1,52 @@
+import { Component } from '@angular/core';
+import { Router, ActivatedRoute } from '@angular/router';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Contact } from 'src/app/models/contact';
+import { ContactsService } from '../contacts.service';
+
+@Component({
+ selector: 'app-edit',
+ templateUrl: './edit.component.html',
+ styleUrls: ['./edit.component.css']
+})
+export class EditComponent {
+ contactForm: FormGroup;
+
+ constructor(
+ private fb: FormBuilder,
+ private contactsService: ContactsService,
+ private router: Router,
+ private route: ActivatedRoute
+ ) {
+ this.contactForm = this.fb.group({
+ firstName: [''],
+ lastName: [''],
+ street: [''],
+ city: ['']
+ });
+ }
+
+ ngOnInit(): void {
+ const id = Number(this.route.snapshot.paramMap.get('id'));
+ this.contactsService.GetContactById(id).subscribe(contact => {
+ if (contact) {
+ this.contactForm.patchValue(contact);
+ }
+ });
+}
+
+ updateContact() {
+ const updatedContact: Contact = {
+ id: 0,
+ firstName: this.contactForm.value.firstName,
+ lastName: this.contactForm.value.lastName,
+ street: this.contactForm.value.street,
+ city: this.contactForm.value.city,
+ };
+ this.contactsService.updateContact(updatedContact).subscribe(() => {
+ this.contactForm.reset();
+ this.router.navigate(['/contacts']);
+ });
+ }
+}
+
diff --git a/src/app/contacts/list/list.component.css b/src/app/contacts/list/list.component.css
index f2bbd77b..a043e153 100644
--- a/src/app/contacts/list/list.component.css
+++ b/src/app/contacts/list/list.component.css
@@ -30,8 +30,3 @@
.view-button:hover {
background-color: #e0e0e0;
}
-
-.view-button a {
- text-decoration: none;
- color: #040404;
- font-weight: bold;}
diff --git a/src/app/contacts/list/list.component.html b/src/app/contacts/list/list.component.html
index 420b6962..7bec054b 100644
--- a/src/app/contacts/list/list.component.html
+++ b/src/app/contacts/list/list.component.html
@@ -15,7 +15,7 @@ Contacts
{{ contact.lastName }}
{{ contact.street }}
{{ contact.city }}
- View
+ View
\ No newline at end of file
diff --git a/src/app/contacts/view/view.component.css b/src/app/contacts/view/view.component.css
index e69de29b..0f404cfc 100644
--- a/src/app/contacts/view/view.component.css
+++ b/src/app/contacts/view/view.component.css
@@ -0,0 +1,9 @@
+button {
+ padding: 0.5em 1em;
+ cursor: pointer;
+ border-radius: 4px;
+}
+
+button:hover {
+ background-color: #e0e0e0;
+}
diff --git a/src/app/contacts/view/view.component.html b/src/app/contacts/view/view.component.html
index a863f5aa..65fce4c9 100644
--- a/src/app/contacts/view/view.component.html
+++ b/src/app/contacts/view/view.component.html
@@ -1,2 +1,4 @@
{{ contact?.firstName }} {{ contact?.lastName }}
{{ contact?.street }}, {{ contact?.city }}
+Back
+Edit
From 18adbfc965746af802fabc88f3d27f0158f31fdf Mon Sep 17 00:00:00 2001
From: Mathias Handeland <127216029+MathiasHandeland@users.noreply.github.com>
Date: Mon, 8 Sep 2025 14:38:08 +0200
Subject: [PATCH 4/4] edit css
---
src/app/contacts/edit/edit.component.ts | 17 +++++++++--------
src/app/contacts/view/view.component.css | 15 +++++++++++++--
src/app/contacts/view/view.component.html | 4 ++--
src/app/contacts/view/view.component.ts | 1 +
4 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/src/app/contacts/edit/edit.component.ts b/src/app/contacts/edit/edit.component.ts
index 69d77b80..1a5ddee6 100644
--- a/src/app/contacts/edit/edit.component.ts
+++ b/src/app/contacts/edit/edit.component.ts
@@ -6,6 +6,7 @@ import { ContactsService } from '../contacts.service';
@Component({
selector: 'app-edit',
+ standalone: false,
templateUrl: './edit.component.html',
styleUrls: ['./edit.component.css']
})
@@ -27,17 +28,17 @@ export class EditComponent {
}
ngOnInit(): void {
- const id = Number(this.route.snapshot.paramMap.get('id'));
- this.contactsService.GetContactById(id).subscribe(contact => {
- if (contact) {
- this.contactForm.patchValue(contact);
- }
- });
-}
+ const id = Number(this.route.snapshot.paramMap.get('id'));
+ this.contactsService.GetContactById(id).subscribe(contact => {
+ if (contact) {
+ this.contactForm.patchValue(contact);
+ }
+ });
+ }
updateContact() {
const updatedContact: Contact = {
- id: 0,
+ id: Number(this.route.snapshot.paramMap.get('id')),
firstName: this.contactForm.value.firstName,
lastName: this.contactForm.value.lastName,
street: this.contactForm.value.street,
diff --git a/src/app/contacts/view/view.component.css b/src/app/contacts/view/view.component.css
index 0f404cfc..4837853d 100644
--- a/src/app/contacts/view/view.component.css
+++ b/src/app/contacts/view/view.component.css
@@ -1,9 +1,20 @@
-button {
+#edit-button {
padding: 0.5em 1em;
cursor: pointer;
border-radius: 4px;
+ margin-right: 1em;
}
-button:hover {
+#edit-button:hover {
+ background-color: #e0e0e0;
+}
+
+#back-button {
+ padding: 0.5em 1em;
+ cursor: pointer;
+ border-radius: 4px;
+}
+
+#back-button:hover {
background-color: #e0e0e0;
}
diff --git a/src/app/contacts/view/view.component.html b/src/app/contacts/view/view.component.html
index 65fce4c9..a83b0f21 100644
--- a/src/app/contacts/view/view.component.html
+++ b/src/app/contacts/view/view.component.html
@@ -1,4 +1,4 @@
{{ contact?.firstName }} {{ contact?.lastName }}
{{ contact?.street }}, {{ contact?.city }}
-Back
-Edit
+Edit
+Back
diff --git a/src/app/contacts/view/view.component.ts b/src/app/contacts/view/view.component.ts
index 611e5f9e..32fc6d8c 100644
--- a/src/app/contacts/view/view.component.ts
+++ b/src/app/contacts/view/view.component.ts
@@ -9,6 +9,7 @@ import { ContactsService } from '../contacts.service';
templateUrl: './view.component.html',
styleUrls: ['./view.component.css']
})
+
export class ViewComponent implements OnInit {
contact: Contact | null = null;
contactId: number | null = null;