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

+ + + + + + + + + + + + + + + + + +
First NameLast NameStreetCity
{{ contact.firstName }}{{ contact.lastName }}{{ contact.street }}{{ contact.city }}
\ 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

+

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!

+
+

Add New Contact

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
\ 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 }} + \ 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

+

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 @@ +
    +

    Edit Contact

    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    \ 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 }} - + \ 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 }}

    + + 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 }}

    - - + + 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;