Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
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/view/:id', component: ViewComponent },
{ path: 'contacts/edit/:id', component: EditComponent },
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
Expand Down
5 changes: 3 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ 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';

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, LayoutModule],
imports: [BrowserModule, AppRoutingModule, LayoutModule, ContactsModule, LayoutModule],
bootstrap: [AppComponent],
})
export class AppModule {}
export class AppModule { }
25 changes: 25 additions & 0 deletions src/app/contacts/add/add.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
:host {
display: flex;
box-sizing: border-box;
width: 40vw;
flex-direction: column;
}

form {
display: flex;
flex-direction: column;
flex: 1;
gap: 0.5em;
}

label {
font-weight: bold;
}

.actions {
display: flex;
}

.spacer {
flex: 1;
}
38 changes: 38 additions & 0 deletions src/app/contacts/add/add.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<h1>Add Contact</h1>
<form [formGroup]="contactForm" (ngSubmit)="addContact()" class="form-group">
<label for="firstName" class="form-control">First Name:</label>
<br />
<input
type="text"
id="firstName"
formControlName="firstName"
class="form-control"
/>

<label for="lastName" class="form-control">Last Name:</label>
<br />
<input
type="text"
id="lastName"
formControlName="lastName"
class="form-control"
/>

<label for="street" class="form-control">Street:</label>
<br />
<input
type="text"
id="street"
formControlName="street"
class="form-control"
/>

<label for="city" class="form-control">City:</label>
<br />
<input type="text" id="city" formControlName="city" class="form-control" />

<div class="actions">
<div class="spacer"></div>
<button type="submit" [disabled]="contactForm.invalid">Add Contact</button>
</div>
</form>
43 changes: 43 additions & 0 deletions src/app/contacts/add/add.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Contact } from 'src/app/models/Contact';
import { ContactForm } from 'src/app/models/ContactForm';
import { ContactsService } from '../contacts.service';
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 contactsService: ContactsService,
private readonly router: Router
) {
this.contactForm = this.formBuilder.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
street: ['', Validators.required],
city: ['', Validators.required],
})
}

addContact(): void {
const newContact: Contact = {
id: this.contactsService.GetNextId(),
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'])
}
}
15 changes: 15 additions & 0 deletions src/app/contacts/contacts.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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 { ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { EditComponent } from './edit/edit.component';

@NgModule({
declarations: [ListComponent, AddComponent, ViewComponent, EditComponent],
imports: [CommonModule, ReactiveFormsModule, RouterModule],
exports: [AddComponent, ListComponent, ViewComponent, EditComponent]
})
export class ContactsModule { }
41 changes: 41 additions & 0 deletions src/app/contacts/contacts.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Injectable } from '@angular/core';
import { Contact } from '../models/Contact';
import { testContacts } from '../data/testContactData';
import { Observable, of } from 'rxjs';

@Injectable({
providedIn: 'root'
})
export class ContactsService {
public contacts: Contact[] = testContacts;

public AddContact(c: Contact): void {
this.contacts.push(c);
}

public EditContact(c: Contact): boolean {
const iToReplace = this.contacts.findIndex((curr) => (curr.id === c.id));

if (iToReplace > -1) {
this.contacts[iToReplace] = c;
return true;
} else {
return false;
}
}

public GetContactById(id: number): Observable<Contact | undefined> {
const beer = this.contacts.find((c) => c.id === id);
return of(beer);
}

public GetNextId(): number {
if (this.contacts.length === 0) {
return 1;
}

return Math.max(...this.contacts.map(c => c.id)) + 1;
}

// constructor() { }
}
Empty file.
67 changes: 67 additions & 0 deletions src/app/contacts/edit/edit.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@if (contact) {
<div>
<h2>Edit Contact</h2>
<form [formGroup]="contactForm" (ngSubmit)="editContact()" class="form-group">
<div>
<label for="firstName" class="form-control">First Name:</label>
<br />
<input
type="text"
id="firstName"
formControlName="firstName"
class="form-control"
/>
</div>

<div>
<label for="lastName" class="form-control">Last Name:</label>
<br />
<input
type="text"
id="lastName"
formControlName="lastName"
class="form-control"
/>
</div>

<div>
<label for="street" class="form-control">Street:</label>
<br />
<input
type="text"
id="street"
formControlName="street"
class="form-control"
/>
</div>

<div>
<label for="city" class="form-control">City:</label>
<br />
<input
type="text"
id="city"
formControlName="city"
class="form-control"
/>
</div>

<div class="actions">
<div class="spacer"></div>

<button
type="submit"
[disabled]="contactForm.invalid"
class="btn btn-success"
>
Edit Contact
</button>
</div>
</form>
</div>

} @else {
<ng-container>
<h1>Contact not found</h1>
</ng-container>
}
76 changes: 76 additions & 0 deletions src/app/contacts/edit/edit.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Contact } from 'src/app/models/Contact';
import { ContactForm } from 'src/app/models/ContactForm';
import { ContactsService } from '../contacts.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
selector: 'app-edit',
standalone: false,
templateUrl: './edit.component.html',
styleUrl: './edit.component.css'
})
export class EditComponent {
contact: Contact | null = null;
contactId: number | null = null;
contactForm: FormGroup;

constructor(
private route: ActivatedRoute,
private readonly formBuilder: FormBuilder,
private readonly contactsService: ContactsService,
private readonly router: Router
) {
this.contactForm = this.formBuilder.group({
firstName: [this.contact?.firstName],
lastName: [this.contact?.lastName],
street: [this.contact?.street],
city: [this.contact?.city],
})
}

ngOnInit(): void {
this.contactId = Number(this.route.snapshot.paramMap.get('id'));

if (!this.contactId) {
alert("Contact does not exist!")
this.router.navigate(['/contacts']);
return;
}

this.contactsService.GetContactById(this.contactId).subscribe(contact => {
this.contact = contact ?? null;

if (this.contact) {
this.contactForm.patchValue({
firstName: this.contact.firstName ?? '',
lastName: this.contact.lastName ?? '',
street: this.contact.street ?? '',
city: this.contact.city ?? ''
});
} else {
alert("Contact does not exist!")
this.router.navigate(['/contacts']);
return;
}
});
}

editContact(): void {
const newContact: Contact = {
id: this.contactId!,
firstName: this.contactForm.value.firstName,
lastName: this.contactForm.value.lastName,
street: this.contactForm.value.street,
city: this.contactForm.value.city,
}

const isUpdated: boolean = this.contactsService.EditContact(newContact);
if (!isUpdated) {
alert("Something went wrong when editing! Contact not updated!")
}
this.contactForm.reset()
this.router.navigate(['/contacts'])
}
}
13 changes: 13 additions & 0 deletions src/app/contacts/list/list.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
:host {
display: flex;
box-sizing: border-box;
width: 40vw;
flex-direction: column;
}

.contact {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ddd;
padding: 0.5em 0;
}
19 changes: 19 additions & 0 deletions src/app/contacts/list/list.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<h1>Contacts</h1>

@if (contacts) {
<div class="contact-container" *ngFor="let c of contacts">
<div class="contact">
<span>{{ c.firstName }} {{ c.lastName }}</span>
<span>
<button routerLink="/contacts/view/{{ c.id }}">
View
</button>
<button routerLink="/contacts/edit/{{ c.id }}">
Edit
</button>
</span>
</div>
</div>
} @else {
<div>No contacts yet</div>
}
17 changes: 17 additions & 0 deletions src/app/contacts/list/list.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Component } 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 contactsService: ContactsService) {
this.contacts = this.contactsService.contacts;
}
}
Empty file.
Loading