Merge pull request #408 from kabrunko-dev/challenge-1-projection-augment

refactor(challenge-1): augment challenge developer experience
This commit is contained in:
Laforge Thomas
2023-12-14 14:40:15 +01:00
committed by GitHub
9 changed files with 73 additions and 38 deletions

View File

@@ -0,0 +1,23 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { City } from '../model/city.model';
@Injectable({
providedIn: 'root',
})
export class CityStore {
private cities = new BehaviorSubject<City[]>([]);
cities$ = this.cities.asObservable();
addAll(cities: City[]) {
this.cities.next(cities);
}
addOne(student: City) {
this.cities.next([...this.cities.value, student]);
}
deleteOne(id: number) {
this.cities.next(this.cities.value.filter((s) => s.id !== id));
}
}

View File

@@ -12,14 +12,14 @@ import {
import { map, timer } from 'rxjs';
import { City } from '../model/city.model';
import { Student } from '../model/student.model';
import { subject, Teacher } from '../model/teacher.model';
import { Teacher, subject } from '../model/teacher.model';
const factoryTeacher = incrementalNumber();
export const randTeacher = () => ({
id: factoryTeacher(),
firstname: randFirstName(),
lastname: randLastName(),
firstName: randFirstName(),
lastName: randLastName(),
subject: rand(subject),
});
@@ -34,8 +34,8 @@ const factoryStudent = incrementalNumber();
export const randStudent = (): Student => ({
id: factoryStudent(),
firstname: randFirstName(),
lastname: randLastName(),
firstName: randFirstName(),
lastName: randLastName(),
mainTeacher: teachers[randNumber({ max: teachers.length - 1 })],
school: randWord(),
});

View File

@@ -2,8 +2,8 @@ import { Teacher } from './teacher.model';
export interface Student {
id: number;
firstname: string;
lastname: string;
firstName: string;
lastName: string;
mainTeacher: Teacher;
school: string;
}

View File

@@ -9,7 +9,7 @@ export type Subject = (typeof subject)[number];
export interface Teacher {
id: number;
firstname: string;
lastname: string;
firstName: string;
lastName: string;
subject: Subject;
}

View File

@@ -1,27 +0,0 @@
<div
class="border-2 border-black rounded-md p-4 w-fit flex flex-col gap-3"
[class]="customClass">
<img
*ngIf="type === CardType.TEACHER"
src="assets/img/teacher.png"
width="200px" />
<img
*ngIf="type === CardType.STUDENT"
src="assets/img/student.webp"
width="200px" />
<section>
<app-list-item
*ngFor="let item of list"
[name]="item.firstname"
[id]="item.id"
[type]="type">
</app-list-item>
</section>
<button
class="border border-blue-500 bg-blue-300 p-2 rounded-sm"
(click)="addNewItem()">
Add
</button>
</div>

View File

@@ -8,7 +8,34 @@ import { ListItemComponent } from '../list-item/list-item.component';
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
template: `
<div
class="flex w-fit flex-col gap-3 rounded-md border-2 border-black p-4"
[class]="customClass">
<img
*ngIf="type === CardType.TEACHER"
src="assets/img/teacher.png"
width="200px" />
<img
*ngIf="type === CardType.STUDENT"
src="assets/img/student.webp"
width="200px" />
<section>
<app-list-item
*ngFor="let item of list"
[name]="item.firstName"
[id]="item.id"
[type]="type"></app-list-item>
</section>
<button
class="rounded-sm border border-blue-500 bg-blue-300 p-2"
(click)="addNewItem()">
Add
</button>
</div>
`,
standalone: true,
imports: [NgIf, NgFor, ListItemComponent],
})
@@ -21,7 +48,7 @@ export class CardComponent {
constructor(
private teacherStore: TeacherStore,
private studentStore: StudentStore
private studentStore: StudentStore,
) {}
addNewItem() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -35,3 +35,9 @@ While the application works, the developer experience is far from being optimal.
- The `NgFor` directive must be declared and remain inside the `CardComponent`. You might be tempted to move it to the `ParentCardComponent` like `TeacherCardComponent`.
- `CardComponent` should not contain any `NgIf` or `NgSwitch`.
- CSS: try to avoid using `::ng-deep`. Find a better way to handle CSS styling.
## Bonus Challenges
- Try to work with the new built-in control flow syntax for loops and conditionals (documentation [here](https://angular.dev/guide/templates/control-flow))
- Use the signal API to manage your components state (documentation [here](https://angular.dev/guide/signals))
- To reference the template, use a directive instead of magic strings

View File

@@ -35,3 +35,9 @@ Apesar da aplicação funcionar, a experiência do desenvolvedor (DX) está nem
- A diretiva `NgFor` deve ser declarada e permanecer dentro do `CardComponent`. Você pode ficar instigado em querer mover ela para o `ParentCardComponent` como `TeacherCardComponent`.
- `CardComponent` não deve conter nenhum `NgIf` ou `NgSwitch`.
- CSS: tente evitar usar `::ng-deep`. Ache uma maneira melhor para lidar com o CSS.
## Desafios Bônus
- Tente trabalhar com a nova sintaxe nativa de controle de fluxo para laços e condicionais (documentação [aqui](https://angular.dev/guide/templates/control-flow))
- Usa a signal API para gerenciar o estado de seus componentes (documentação [aqui](https://angular.dev/guide/signals))
- Para referenciar o template, use uma diretiva ao invés de strings mágicas