diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 02972627..59096dbc 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,7 +1,28 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
+import { ListComponent } from './contacts/list/list.component';
+import { ViewComponent } from './contacts/view/view.component';
+import { AddComponent } from './contacts/add/add.component';
+import { EditComponent } from './contacts/edit/edit.component';
-const routes: Routes = [];
+const routes: Routes = [
+ {
+ path: "contacts",
+ component: ListComponent
+ },
+ {
+ path: "contacts/add",
+ component: AddComponent
+ },
+ {
+ path: "contacts/update/:id",
+ component: EditComponent
+ },
+ {
+ path: "contacts/:id",
+ component: ViewComponent
+ },
+];
@NgModule({
imports: [RouterModule.forRoot(routes)],
diff --git a/src/app/app.component.css b/src/app/app.component.css
index 31d9e249..793a9e8a 100644
--- a/src/app/app.component.css
+++ b/src/app/app.component.css
@@ -5,5 +5,10 @@
.page {
flex: 1;
display: flex;
+ flex-direction: column;
justify-content: center;
}
+
+.contact-list {
+ display: grid;
+}
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 17aaa0c6..66e41277 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,4 +1,11 @@
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index b82791ab..c2ea089f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -3,8 +3,9 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
+ standalone: false,
styleUrls: ['./app.component.css']
})
export class AppComponent {
- title = 'angular-address-book';
+ title = 'Address-book';
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 8207184c..9bf6af34 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -4,10 +4,12 @@ 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, LayoutModule, ContactsModule, CommonModule],
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..9df020cf
--- /dev/null
+++ b/src/app/contacts/add/add.component.html
@@ -0,0 +1,23 @@
+
+
diff --git a/src/app/contacts/add/add.component.ts b/src/app/contacts/add/add.component.ts
new file mode 100644
index 00000000..7f3186ce
--- /dev/null
+++ b/src/app/contacts/add/add.component.ts
@@ -0,0 +1,39 @@
+import { Component, inject } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Router } from '@angular/router';
+import { ContactService } from 'src/app/services/contact.service';
+import { Contact } from '../models/contact';
+
+@Component({
+ selector: 'app-add',
+ standalone: false,
+ templateUrl: './add.component.html',
+ styleUrl: './add.component.css'
+})
+export class AddComponent {
+ contactForm: FormGroup;
+ formBuilder = inject(FormBuilder);
+ contactService = inject(ContactService)
+ router = inject(Router)
+
+ constructor() {
+ 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.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..1cfbe17e
--- /dev/null
+++ b/src/app/contacts/contacts.module.ts
@@ -0,0 +1,26 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ListComponent } from './list/list.component';
+import { RouterModule } from '@angular/router';
+import { AddComponent } from './add/add.component';
+import { ViewComponent } from './view/view.component';
+import { ReactiveFormsModule } from '@angular/forms';
+import { EditComponent } from './edit/edit.component';
+
+
+
+@NgModule({
+ declarations: [
+ ListComponent,
+ AddComponent,
+ ViewComponent,
+ EditComponent
+ ],
+ imports: [
+ CommonModule,
+ RouterModule,
+ ReactiveFormsModule
+ ],
+ exports: [ListComponent, ViewComponent, AddComponent, EditComponent]
+})
+export class ContactsModule { }
diff --git a/src/app/contacts/data/contacts.ts b/src/app/contacts/data/contacts.ts
new file mode 100644
index 00000000..e587d867
--- /dev/null
+++ b/src/app/contacts/data/contacts.ts
@@ -0,0 +1,33 @@
+
+import { Contact } from "../models/contact";
+
+export const CONTACTS: Contact[] = [
+ {
+ id: 1,
+ firstName: "Magnus",
+ lastName: "Hissingby",
+ street: "someStreet",
+ city: "someCity"
+ },
+ {
+ id: 2,
+ firstName: "Birk",
+ lastName: "Sala",
+ street: "someStreet",
+ city: "someCity"
+ },
+ {
+ id: 3,
+ firstName: "Cru",
+ lastName: "Lavender",
+ street: "someStreet",
+ city: "someCity"
+ },
+ {
+ id: 4,
+ firstName: "Unc",
+ lastName: "Rivand",
+ street: "someStreet",
+ city: "someCity"
+ }
+]
\ 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..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..831bb919
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.html
@@ -0,0 +1,27 @@
+
+@if (this.contact === null) {
+ Contact does not exist!!!
+} @else {
+
+}
\ No newline at end of file
diff --git a/src/app/contacts/edit/edit.component.ts b/src/app/contacts/edit/edit.component.ts
new file mode 100644
index 00000000..d2cb4202
--- /dev/null
+++ b/src/app/contacts/edit/edit.component.ts
@@ -0,0 +1,58 @@
+import { Component, inject } from '@angular/core';
+import { Contact } from '../models/contact';
+import { Form, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ContactService } from 'src/app/services/contact.service';
+import { ActivatedRoute, Router } from '@angular/router';
+
+@Component({
+ selector: 'app-edit',
+ templateUrl: './edit.component.html',
+ styleUrl: './edit.component.css'
+})
+export class EditComponent {
+ contact: Contact | null = null;
+ contactId: number | null = null;
+ contactForm: FormGroup;
+ formBuilder: FormBuilder = inject(FormBuilder)
+ contactService: ContactService = inject(ContactService)
+ router: Router = inject(Router)
+ route: ActivatedRoute = inject(ActivatedRoute)
+
+ constructor() {
+ this.contactForm = this.formBuilder.group({
+ firstName: ['', Validators.required],
+ lastName: ['', Validators.required],
+ street: ['', Validators.required],
+ city: ['', Validators.required]
+ });
+ }
+
+ ngOnInit() {
+ this.contactId = Number(this.route.snapshot.paramMap.get('id'));
+ this.contact = this.contactService.getContactById(this.contactId)
+ if (this.contact !== null && this.contact !== undefined) {
+ this.contactForm.patchValue({
+ firstName: this.contact.firstName,
+ lastName: this.contact.lastName,
+ street: this.contact.street,
+ city: this.contact.city
+ })
+ }
+ }
+
+ editContact() {
+ if (!this.contactId) return;
+
+ const updatedContact: Contact = {
+ id: this.contactId,
+ firstName: this.contactForm.value.firstName,
+ lastName: this.contactForm.value.lastName,
+ street: this.contactForm.value.street,
+ city: this.contactForm.value.city
+ }
+ this.contactService.editContact(updatedContact);
+ 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
new file mode 100644
index 00000000..a528e60c
--- /dev/null
+++ b/src/app/contacts/list/list.component.css
@@ -0,0 +1,7 @@
+
+.contact-list {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: .9rem;
+ border: 1px solid black;
+}
\ No newline at end of file
diff --git a/src/app/contacts/list/list.component.html b/src/app/contacts/list/list.component.html
new file mode 100644
index 00000000..45e269eb
--- /dev/null
+++ b/src/app/contacts/list/list.component.html
@@ -0,0 +1,21 @@
+
+Contacts
+
+@if (this.contacts.length===0){
+ No contacts yet
+} @else {
+
+}
+
diff --git a/src/app/contacts/list/list.component.ts b/src/app/contacts/list/list.component.ts
new file mode 100644
index 00000000..c4bc4fad
--- /dev/null
+++ b/src/app/contacts/list/list.component.ts
@@ -0,0 +1,14 @@
+import { Component, inject } from '@angular/core';
+import { ContactService } from 'src/app/services/contact.service';
+import { Contact } from '../models/contact';
+
+@Component({
+ selector: 'app-list',
+ standalone: false,
+ templateUrl: './list.component.html',
+ styleUrl: './list.component.css'
+})
+export class ListComponent {
+ contactService = inject(ContactService)
+ contacts: Contact[] = this.contactService.getAllContacts();
+}
diff --git a/src/app/contacts/models/contact.ts b/src/app/contacts/models/contact.ts
new file mode 100644
index 00000000..d293255f
--- /dev/null
+++ b/src/app/contacts/models/contact.ts
@@ -0,0 +1,9 @@
+
+
+export interface Contact {
+ id: number;
+ firstName: string;
+ lastName: string;
+ street: string;
+ city: string
+}
\ No newline at end of file
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..aa9a48b2
--- /dev/null
+++ b/src/app/contacts/view/view.component.html
@@ -0,0 +1,12 @@
+
+@if (this.contact === null) {
+
+} @else {
+
+
{{this.contact.firstName}} {{this.contact.lastName}}
+ Street: {{this.contact.street}}
+ City: {{this.contact.city}}
+
+}
\ No newline at end of file
diff --git a/src/app/contacts/view/view.component.ts b/src/app/contacts/view/view.component.ts
new file mode 100644
index 00000000..0cab924f
--- /dev/null
+++ b/src/app/contacts/view/view.component.ts
@@ -0,0 +1,18 @@
+import { Component, inject } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { ContactService } from 'src/app/services/contact.service';
+import { Contact } from '../models/contact';
+
+@Component({
+ selector: 'app-view',
+ standalone: false,
+ templateUrl: './view.component.html',
+ styleUrl: './view.component.css'
+})
+export class ViewComponent {
+ contactService = inject(ContactService)
+ route = inject(ActivatedRoute)
+
+ id = this.route.snapshot.paramMap.get('id')
+ contact: Contact | null = this.contactService.getContactById(Number(this.id))
+}
diff --git a/src/app/layout/layout.module.ts b/src/app/layout/layout.module.ts
index 501b6585..388e3a70 100644
--- a/src/app/layout/layout.module.ts
+++ b/src/app/layout/layout.module.ts
@@ -1,7 +1,7 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
-import { RouterModule } from '@angular/router';
import { MenuComponent } from './menu/menu.component';
+import { RouterModule } from '@angular/router';
@NgModule({
declarations: [MenuComponent],
diff --git a/src/app/layout/menu/menu.component.html b/src/app/layout/menu/menu.component.html
index 7c5ec7a2..95fe5dc8 100644
--- a/src/app/layout/menu/menu.component.html
+++ b/src/app/layout/menu/menu.component.html
@@ -1,5 +1,6 @@
Menu
diff --git a/src/app/layout/menu/menu.component.ts b/src/app/layout/menu/menu.component.ts
index 1c826c99..33c5f00d 100644
--- a/src/app/layout/menu/menu.component.ts
+++ b/src/app/layout/menu/menu.component.ts
@@ -2,6 +2,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'app-menu',
+ standalone: false,
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.css'],
})
diff --git a/src/app/services/contact.service.ts b/src/app/services/contact.service.ts
new file mode 100644
index 00000000..fb5816fa
--- /dev/null
+++ b/src/app/services/contact.service.ts
@@ -0,0 +1,38 @@
+import { Injectable } from '@angular/core';
+import { Contact } from '../contacts/models/contact';
+import { CONTACTS } from '../contacts/data/contacts';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ContactService {
+ private contacts: Contact[] = CONTACTS;
+ private currentId: number = this.contacts.length
+
+ public getContactById(id: number | null): Contact | null {
+ const contact = this.contacts.find((curr) => curr.id === id)
+ if (!contact) {
+ return null
+ }
+ return contact
+ }
+
+ public getAllContacts(): Contact[] {
+ return this.contacts;
+ }
+
+ public addContact(contact: Contact) {
+ this.currentId++;
+ contact.id = this.currentId
+ this.contacts.push(contact)
+ }
+
+ public editContact(updatedContact: Contact) {
+ const cont = this.contacts.find((contact) => contact.id === updatedContact.id)
+ if (cont === undefined) return;
+ cont.firstName = updatedContact.firstName;
+ cont.lastName = updatedContact.lastName;
+ cont.street = updatedContact.street;
+ cont.city = updatedContact.city;
+ }
+}
diff --git a/src/styles.css b/src/styles.css
index 90d4ee00..843c287c 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1 +1,23 @@
-/* You can add global styles to this file, and also import other style files */
+
+
+.side-page {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ text-align: center;
+ margin-left: 50px;
+}
+
+form {
+ display: grid;
+ grid-template-columns: 150px 1fr; /* første kolonne labels, andre inputs */
+ gap: 0.5rem 1rem; /* rad- og kolonneavstand */
+ max-width: 400px;
+}
+form label {
+ text-align: right; /* høyrejustert label */
+ padding-right: 0.5rem;
+}
+form input {
+ width: 100%;
+}