Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add alphabetical contact grouping and sectioning #995

Merged
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
42 changes: 30 additions & 12 deletions Angular-JS-Projects/Advanced/Contact-Manager/db.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
{
"contacts": [
{
"id": "ac05",
"name": "John Doe",
"email": "jonhn@gmail.com",
"phone": "123456789"
"id": "0dc5",
"name": "Alice",
"email": "alice@example.com",
"phone": "1234567890"
},
{
"id": "c548",
"name": "Mr Adam Shmitz",
"email": "shmitz@gmail.com",
"phone": "987654321"
"id": "1fa3",
"name": "Abba",
"email": "abba@example.com",
"phone": "2345678901"
},
{
"id": "64d5",
"name": "Mouhamadou Awalou",
"email": "[email protected]",
"phone": "741852963"
"id": "2bb6",
"name": "Charlie",
"email": "[email protected]",
"phone": "3456789012"
},
{
"id": "3ac8",
"name": "David",
"email": "[email protected]",
"phone": "4567890123"
},
{
"id": "4ef7",
"name": "Emma",
"email": "[email protected]",
"phone": "5678901234"
},
{
"id": "5ff9",
"name": "Frank",
"email": "[email protected]",
"phone": "6789012345"
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Angular-JS-Projects/Advanced/Contact-Manager/screenshot.webp
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,56 @@
</div>
</li>
<!-- If contacts are found -->
<li class="py-3 px-3 rounded-xl" *ngFor="let contact of filteredContacts">
<div class="flex items-center space-x-4">
<div
class="flex-shrink-0 h-10 w-10 grid place-items-center rounded-full border-2"
>
<i class="fa fa-user text-gray-400"></i>
</div>
<div class="flex-1">
<p
class="text-sm font-medium text-white truncate capitalize tracking-wide"
>
{{ contact.name }}
</p>
<p class="text-sm text-gray-500 truncate">
{{ contact.phone }}
</p>
</div>
<div class="flex-1">
<p class="text-sm text-gray-400 truncate">
{{ contact.email }}
</p>
<ng-container *ngFor="let group of groupedContacts | keyvalue">
<!-- Below we have the header of each section -->
<div class="relative">
<div class="absolute inset-0 flex items-center" aria-hidden="true">
<div class="w-full border-t ml-5 border-gray-300"></div>
</div>
<div
(click)="toggleEditContact(contact)"
class="items-center text-base font-semibold text-blue-950 bg-blue-400 hover:bg-blue-500 rounded-md w-10 h-8 grid place-items-center"
>
<i class="fa fa-pencil"></i>
</div>
<div
(click)="deleteContact(contact)"
class="items-center text-base font-semibold text-red-800 bg-red-400 hover:bg-red-500 rounded-md w-10 h-8 grid place-items-center"
>
<i class="fa fa-trash"></i>
<div class="relative flex justify-start">
<span class="py-2 text-xl font-semibold text-blue-400">{{
group.key
}}</span>
</div>
</div>
</li>

<li class="py-3 px-3 rounded-xl" *ngFor="let contact of group.value">
<div class="flex items-center space-x-4">
<div
class="flex-shrink-0 h-10 w-10 grid place-items-center rounded-full border-2"
>
<i class="fa fa-user text-gray-400"></i>
</div>
<div class="flex-1">
<p
class="text-sm font-medium text-white truncate capitalize tracking-wide"
>
{{ contact.name }}
</p>
<p class="text-sm text-gray-500 truncate">
{{ contact.phone }}
</p>
</div>
<div class="flex-1">
<p class="text-sm text-gray-400 truncate">
{{ contact.email }}
</p>
</div>
<div
(click)="toggleEditContact(contact)"
class="items-center text-base font-semibold text-blue-950 bg-blue-400 hover:bg-blue-500 rounded-md w-10 h-8 grid place-items-center"
>
<i class="fa fa-pencil"></i>
</div>
<div
(click)="deleteContact(contact)"
class="items-center text-base font-semibold text-red-800 bg-red-400 hover:bg-red-500 rounded-md w-10 h-8 grid place-items-center"
>
<i class="fa fa-trash"></i>
</div>
</div>
</li>
</ng-container>
</ul>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,30 @@ export class ContactListComponent implements OnInit, OnChanges {
private notificationPopup: ToastrService
) {}

groupedContacts = new Map<string, any[]>();

getAllTasks(): void {
this.contactService.getAllContacts().subscribe(
(res) => {
this.contacts = res.sort((a, b) => a.name.localeCompare(b.name));
this.contactService.getAllContacts().subscribe({
next: (response) => {
this.contacts = response.sort((a, b) => a.name.localeCompare(b.name));
this.filteredContacts = this.contacts;
this.groupContacts();
},
(err) => {
console.log(err);
error: (err) => {
this.notificationPopup.error("An Error Occured", "Error!");
},
});
}

groupContacts(): void {
this.groupedContacts.clear();
this.filteredContacts.forEach((contact) => {
const firstLetter = contact.name.charAt(0).toUpperCase();
if (!this.groupedContacts.has(firstLetter)) {
this.groupedContacts.set(firstLetter, []);
}
);
this.groupedContacts.get(firstLetter)?.push(contact);
});
}

deleteContact(contact: Contact): void {
Expand All @@ -78,10 +92,13 @@ export class ContactListComponent implements OnInit, OnChanges {
}

searchContacts(): void {
this.filteredContacts = this.contacts.filter(
const filtered = this.contacts.filter(
(contact) =>
contact.name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
contact.phone.includes(this.searchQuery)
);

this.filteredContacts = filtered;
this.groupContacts();
}
}