diff --git a/angular.json b/angular.json index 6319ade..3464a2b 100644 --- a/angular.json +++ b/angular.json @@ -91,5 +91,8 @@ } } } + }, + "cli": { + "analytics": false } } diff --git a/package-lock.json b/package-lock.json index 22ade84..34c8788 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ "@angular/platform-browser": "^17.3.0", "@angular/platform-browser-dynamic": "^17.3.0", "@angular/router": "^17.3.0", - "@tailwindcss/postcss": "^4.1.3", + "@tailwindcss/postcss": "^4.1.4", "postcss": "^8.5.3", "rxjs": "~7.8.0", - "tailwindcss": "^4.1.3", + "tailwindcss": "^4.1.4", "tslib": "^2.3.0", "zone.js": "~0.14.3" }, @@ -3624,15 +3624,15 @@ "license": "MIT" }, "node_modules/@tailwindcss/node": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.3.tgz", - "integrity": "sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.4.tgz", + "integrity": "sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.29.2", - "tailwindcss": "4.1.3" + "tailwindcss": "4.1.4" } }, "node_modules/@tailwindcss/node/node_modules/jiti": { @@ -3645,31 +3645,32 @@ } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.3.tgz", - "integrity": "sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.4.tgz", + "integrity": "sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==", "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-x64": "4.1.3", - "@tailwindcss/oxide-freebsd-x64": "4.1.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-x64-musl": "4.1.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.3" + "@tailwindcss/oxide-android-arm64": "4.1.4", + "@tailwindcss/oxide-darwin-arm64": "4.1.4", + "@tailwindcss/oxide-darwin-x64": "4.1.4", + "@tailwindcss/oxide-freebsd-x64": "4.1.4", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.4", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.4", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.4", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.4", + "@tailwindcss/oxide-linux-x64-musl": "4.1.4", + "@tailwindcss/oxide-wasm32-wasi": "4.1.4", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.4", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.4" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.3.tgz", - "integrity": "sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.4.tgz", + "integrity": "sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==", "cpu": [ "arm64" ], @@ -3683,9 +3684,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.3.tgz", - "integrity": "sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.4.tgz", + "integrity": "sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==", "cpu": [ "arm64" ], @@ -3699,9 +3700,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.3.tgz", - "integrity": "sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.4.tgz", + "integrity": "sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==", "cpu": [ "x64" ], @@ -3715,9 +3716,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.3.tgz", - "integrity": "sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.4.tgz", + "integrity": "sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==", "cpu": [ "x64" ], @@ -3731,9 +3732,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.3.tgz", - "integrity": "sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.4.tgz", + "integrity": "sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==", "cpu": [ "arm" ], @@ -3747,9 +3748,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.3.tgz", - "integrity": "sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.4.tgz", + "integrity": "sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==", "cpu": [ "arm64" ], @@ -3763,9 +3764,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.3.tgz", - "integrity": "sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.4.tgz", + "integrity": "sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==", "cpu": [ "arm64" ], @@ -3779,9 +3780,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.3.tgz", - "integrity": "sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.4.tgz", + "integrity": "sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==", "cpu": [ "x64" ], @@ -3795,9 +3796,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.3.tgz", - "integrity": "sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.4.tgz", + "integrity": "sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==", "cpu": [ "x64" ], @@ -3810,10 +3811,39 @@ "node": ">= 10" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.4.tgz", + "integrity": "sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.0", + "@emnapi/runtime": "^1.4.0", + "@emnapi/wasi-threads": "^1.0.1", + "@napi-rs/wasm-runtime": "^0.2.8", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.3.tgz", - "integrity": "sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.4.tgz", + "integrity": "sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==", "cpu": [ "arm64" ], @@ -3827,9 +3857,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.3.tgz", - "integrity": "sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.4.tgz", + "integrity": "sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==", "cpu": [ "x64" ], @@ -3843,16 +3873,16 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.3.tgz", - "integrity": "sha512-6s5nJODm98F++QT49qn8xJKHQRamhYHfMi3X7/ltxiSQ9dyRsaFSfFkfaMsanWzf+TMYQtbk8mt5f6cCVXJwfg==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.4.tgz", + "integrity": "sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.3", - "@tailwindcss/oxide": "4.1.3", + "@tailwindcss/node": "4.1.4", + "@tailwindcss/oxide": "4.1.4", "postcss": "^8.4.41", - "tailwindcss": "4.1.3" + "tailwindcss": "4.1.4" } }, "node_modules/@tufjs/canonical-json": { @@ -12090,9 +12120,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz", - "integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.4.tgz", + "integrity": "sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==", "license": "MIT" }, "node_modules/tapable": { diff --git a/package.json b/package.json index d2bc696..6f70b8f 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,10 @@ "@angular/platform-browser": "^17.3.0", "@angular/platform-browser-dynamic": "^17.3.0", "@angular/router": "^17.3.0", - "@tailwindcss/postcss": "^4.1.3", + "@tailwindcss/postcss": "^4.1.4", "postcss": "^8.5.3", "rxjs": "~7.8.0", - "tailwindcss": "^4.1.3", + "tailwindcss": "^4.1.4", "tslib": "^2.3.0", "zone.js": "~0.14.3" }, diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 6c6ef60..484010c 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,8 +1,9 @@ -import { ApplicationConfig } from '@angular/core'; +import { ApplicationConfig, importProvidersFrom } from '@angular/core'; import { provideRouter } from '@angular/router'; +import { HttpClientModule } from '@angular/common/http'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { - providers: [provideRouter(routes)] + providers: [provideRouter(routes), importProvidersFrom(HttpClientModule)], }; diff --git a/src/app/components/add-pet-form/add-pet-form.component.ts b/src/app/components/add-pet-form/add-pet-form.component.ts index ef653ec..5c04f7b 100644 --- a/src/app/components/add-pet-form/add-pet-form.component.ts +++ b/src/app/components/add-pet-form/add-pet-form.component.ts @@ -1,7 +1,8 @@ import { Component, inject } from '@angular/core'; import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; -import { ModalService } from '../../shared/services/modal.service'; import { CommonModule } from '@angular/common'; +import { ModalService } from '../../shared/services/modal.service'; +import { PetService } from '../../shared/services/pet.service'; @Component({ selector: 'app-add-pet-form', @@ -13,20 +14,26 @@ import { CommonModule } from '@angular/common'; export class AddPetFormComponent { private fb = inject(FormBuilder); private modalService = inject(ModalService); + private petService = inject(PetService); - petForm = this.fb.group({ + petForm = this.fb.nonNullable.group({ name: ['', Validators.required], type: ['', Validators.required], image: ['', Validators.required], - adopted: [0], }); - handleSubmit() { - if (this.petForm.valid) { - console.log('Submitted pet:', this.petForm.value); - this.modalService.close(); - } else { - console.log('Form is invalid'); + handleSubmit(): void { + if (this.petForm.invalid) { + return; } + + const payload = this.petForm.getRawValue(); + this.petService.addPet(payload).subscribe({ + next: (created) => { + console.log('Pet added:', created); + this.modalService.close(); + }, + error: (err) => console.error('Add pet failed', err), + }); } } diff --git a/src/app/pages/pet-details/pet-details.component.html b/src/app/pages/pet-details/pet-details.component.html index 689c304..f498927 100644 --- a/src/app/pages/pet-details/pet-details.component.html +++ b/src/app/pages/pet-details/pet-details.component.html @@ -1,30 +1,61 @@ -
+
+

Loading pet details…

+
+ +
-
-

Name: {{ pet?.name }}

-

Type: {{ pet?.type }}

-

Adopted: {{ pet?.adopted ? "yes" : "no" }}

+
+

Name: {{ p.name }}

+

Type: {{ p.type }}

+

+ Adopted: + Yes + No +

- @if (!pet?.adopted) { - } -
+ +
+
+

+ Pet not found. It may have been removed or never existed. +

+ +
+
diff --git a/src/app/pages/pet-details/pet-details.component.ts b/src/app/pages/pet-details/pet-details.component.ts index 7159e7b..3c6dfab 100644 --- a/src/app/pages/pet-details/pet-details.component.ts +++ b/src/app/pages/pet-details/pet-details.component.ts @@ -1,26 +1,53 @@ -import { Component } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { Pet, pets } from '../../../data/pets'; +import { Component, effect, signal, computed } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { ActivatedRoute, Router, RouterModule } from '@angular/router'; +import { CommonModule } from '@angular/common'; +import { PetService } from '../../shared/services/pet.service'; +import { Pet } from '../../../data/pets'; @Component({ selector: 'app-pet-details', standalone: true, - imports: [], + imports: [CommonModule, RouterModule], templateUrl: './pet-details.component.html', - styleUrl: './pet-details.component.css' + styleUrl: './pet-details.component.css', }) export class PetDetailsComponent { - pet: Pet | null = null; - pets = pets; + private id = Number(this.route.snapshot.paramMap.get('id') ?? ''); - constructor(private route: ActivatedRoute, private router: Router) { - const id = Number(this.route.snapshot.paramMap.get('id')); - const foundPet = pets.find((p) => p.id === id); + readonly pet = toSignal(this.petService.getPet(this.id), { + initialValue: null, + }); + readonly loading = signal(true); + readonly notFound = computed(() => this.pet() === null); - if (!foundPet) { - this.router.navigate(['/pets']); - } else { - this.pet = foundPet; - } + constructor( + private route: ActivatedRoute, + private router: Router, + private petService: PetService + ) { + effect(() => { + if (this.pet() !== null) { + this.loading.set(false); + } + }); + } + + adopt(): void { + const p = this.pet(); + if (!p) return; + this.petService.deletePet(p.id).subscribe({ + next: () => this.router.navigate(['/pets']), + error: (err: any) => console.error('Failed to adopt pet', err), + }); + } + + deletePet(): void { + const p = this.pet(); + if (!p) return; + this.petService.deletePet(p.id).subscribe({ + next: () => this.router.navigate(['/pets']), + error: (err: any) => console.error('Failed to delete pet', err), + }); } } diff --git a/src/app/pages/pets/pets.component.html b/src/app/pages/pets/pets.component.html index 645e370..10e033f 100644 --- a/src/app/pages/pets/pets.component.html +++ b/src/app/pages/pets/pets.component.html @@ -1,4 +1,4 @@
- +
diff --git a/src/app/pages/pets/pets.component.ts b/src/app/pages/pets/pets.component.ts index 5628fb3..ec1580f 100644 --- a/src/app/pages/pets/pets.component.ts +++ b/src/app/pages/pets/pets.component.ts @@ -1,7 +1,9 @@ -import { Component } from '@angular/core'; +// src/app/pages/pets/pets.component.ts +import { Component, computed, signal } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; import { PetsHeaderComponent } from '../../components/pets-header/pets-header.component'; import { PetsListComponent } from '../../components/pets-list/pets-list.component'; -import { pets } from '../../../data/pets'; +import { PetService } from '../../shared/services/pet.service'; @Component({ selector: 'app-pets', @@ -11,16 +13,20 @@ import { pets } from '../../../data/pets'; styleUrl: './pets.component.css', }) export class PetsComponent { - query = ''; - allPets = pets; + readonly petsArray = toSignal(this.petService.getPets(), { + initialValue: [], + }); - setQuery(query: string) { - this.query = query; - } + readonly query = signal(''); + + readonly filteredPets = computed(() => { + const q = this.query().toLowerCase(); + return this.petsArray().filter((p) => p.name.toLowerCase().includes(q)); + }); + + constructor(private petService: PetService) {} - get filteredPets() { - return this.allPets.filter((pet) => - pet.name.toLowerCase().includes(this.query.toLowerCase()) - ); + setQuery(q: string): void { + this.query.set(q); } } diff --git a/src/app/shared/services/pet.service.spec.ts b/src/app/shared/services/pet.service.spec.ts new file mode 100644 index 0000000..d56a968 --- /dev/null +++ b/src/app/shared/services/pet.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { PetService } from './pet.service'; + +describe('PetService', () => { + let service: PetService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(PetService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/shared/services/pet.service.ts b/src/app/shared/services/pet.service.ts new file mode 100644 index 0000000..da6a5b3 --- /dev/null +++ b/src/app/shared/services/pet.service.ts @@ -0,0 +1,28 @@ +// src/app/shared/services/pet.service.ts +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Pet } from '../../../data/pets'; +import { Observable } from 'rxjs'; + +@Injectable({ providedIn: 'root' }) +export class PetService { + private baseUrl = 'https://pets-react-query-backend.eapi.joincoded.com/pets'; + + constructor(private http: HttpClient) {} + + getPets(): Observable { + return this.http.get(this.baseUrl); + } + + getPet(id: number): Observable { + return this.http.get(`${this.baseUrl}/${id}`); + } + + addPet(pet: Pick): Observable { + return this.http.post(this.baseUrl, { ...pet, adopted: 0 }); + } + + deletePet(id: number): Observable { + return this.http.delete(`${this.baseUrl}/${id}`); + } +}