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
995 changes: 747 additions & 248 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"@tailwindcss/postcss": "^4.1.3",
"postcss": "^8.5.3",
"rxjs": "~7.8.0",
"tailwindcss": "^4.1.3",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
},
Expand All @@ -30,12 +28,15 @@
"@angular/cli": "^17.3.15",
"@angular/compiler-cli": "^17.3.0",
"@types/jasmine": "~5.1.0",
"autoprefixer": "^10.4.21",
"jasmine-core": "~5.1.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "~5.4.2"
}
}
3 changes: 2 additions & 1 deletion src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes)]
providers: [provideRouter(routes), provideHttpClient()]
};
2 changes: 1 addition & 1 deletion src/app/components/pet-card/pet-card.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Pet } from '../../../data/pets';
import { Pet } from '../../pet';

@Component({
selector: 'app-pet-card',
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/pets-list/pets-list.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core';
import { Pet } from '../../../data/pets';
import { PetCardComponent } from '../pet-card/pet-card.component';
import { Pet } from '../../pet';

@Component({
selector: 'app-pets-list',
Expand Down
20 changes: 14 additions & 6 deletions src/app/pages/pet-details/pet-details.component.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
<div class="w-screen h-[90vh] flex justify-center items-center">

@if (pet(); as pet) {
<div
class="border border-black rounded-md w-[70%] h-[70%] overflow-hidden flex flex-col md:flex-row p-5"
>
<div class="h-full w-full md:w-[35%]">
<img
[src]="pet?.image"
[alt]="pet?.name"
[src]="pet.image"
[alt]="pet.name"
class="object-contain w-full h-full"
/>
</div>
<div class="w-full md:w-[65%] h-full pt-[30px] flex flex-col p-3">
<h1>Name: {{ pet?.name }}</h1>
<h1>Type: {{ pet?.type }}</h1>
<h1>Adopted: {{ pet?.adopted ? "yes" : "no" }}</h1>
<h1>Name: {{ pet.name }}</h1>
<h1>Type: {{ pet.type }}</h1>
<h1>Adopted: {{ pet.adopted ? "yes" : "no" }}</h1>

@if (!pet?.adopted) {
@if (!pet.adopted) {
<button
class="w-[70px] border border-black rounded-md hover:bg-green-400 my-5"
>
Expand All @@ -27,4 +29,10 @@ <h1>Adopted: {{ pet?.adopted ? "yes" : "no" }}</h1>
</button>
</div>
</div>
}
@else if(errorMsg()){
<div>
<p>{{errorMsg()}}</p>
<button><a [routerLink]="['/pets']">back</a></button></div>
}
</div>
39 changes: 26 additions & 13 deletions src/app/pages/pet-details/pet-details.component.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Pet, pets } from '../../../data/pets';
import { Component, effect, inject, Signal, signal } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { PetsService } from '../../shared/services/pets.service';
import { Pet } from '../../pet';
import { catchError, Observable, of } from 'rxjs';
import { AsyncPipe } from '@angular/common';

@Component({
selector: 'app-pet-details',
standalone: true,
imports: [],
imports: [AsyncPipe, RouterLink],
templateUrl: './pet-details.component.html',
styleUrl: './pet-details.component.css'
})
export class PetDetailsComponent {
pet: Pet | null = null;
pets = pets;
petsService = inject(PetsService);
pet = signal<Pet | null>(null);
errorMsg = signal<string|null>(null);

constructor(private route: ActivatedRoute, private router: Router) {
const id = Number(this.route.snapshot.paramMap.get('id'));
const foundPet = pets.find((p) => p.id === id);

if (!foundPet) {
this.router.navigate(['/pets']);
} else {
this.pet = foundPet;
}
effect(() => {
this.petsService.getPet(id).subscribe({
next: (res) => {
if(res)
this.pet.set(res)
else
this.errorMsg.set("Pet not found. It may have been removed or never existed.")
},
error: (error) => {
this.pet.set(null);
this.errorMsg.set("Pet not found. It may have been removed or never existed.")
}}
)
});
console.log(this.pet(), this.errorMsg());

}
}
2 changes: 1 addition & 1 deletion src/app/pages/pets/pets.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="flex flex-col justify-center items-center">
<app-pets-header (search)="setQuery($event)"></app-pets-header>
<app-pets-list [pets]="filteredPets"></app-pets-list>
</div>
</div>
15 changes: 11 additions & 4 deletions src/app/pages/pets/pets.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { Component, effect, inject, signal } from '@angular/core';
import { PetsHeaderComponent } from '../../components/pets-header/pets-header.component';
import { PetsListComponent } from '../../components/pets-list/pets-list.component';
import { pets } from '../../../data/pets';
import { PetsService } from '../../shared/services/pets.service';
import { Pet } from '../../pet';

@Component({
selector: 'app-pets',
Expand All @@ -11,15 +12,21 @@ import { pets } from '../../../data/pets';
styleUrl: './pets.component.css',
})
export class PetsComponent {
private petsService = inject(PetsService);

query = '';
allPets = pets;
allPets = signal<Pet[]>([]);; //pets;

httpEffect = effect(() => {
this.petsService.getAllPets().subscribe(petsRes => this.allPets.set(petsRes));
})

setQuery(query: string) {
this.query = query;
}

get filteredPets() {
return this.allPets.filter((pet) =>
return this.allPets().filter((pet) =>
pet.name.toLowerCase().includes(this.query.toLowerCase())
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/app/pet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface Pet {
id: number;
name: string;
type: string;
adopted: number;
image: string;
}
16 changes: 16 additions & 0 deletions src/app/shared/services/pets.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { PetsService } from './pets.service';

describe('PetsService', () => {
let service: PetsService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PetsService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
31 changes: 31 additions & 0 deletions src/app/shared/services/pets.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { catchError, Observable, of } from 'rxjs';
import { Pet } from '../../pet';

@Injectable({
providedIn: 'root',
})
export class PetsService {
private http = inject(HttpClient);

getAllPets(): Observable<Pet[]> {
return this.http.get<Pet[]>('https://pets-react-query-backend.eapi.joincoded.com/pets').pipe(
catchError((error) => {
console.error('Error fetching all pets:', error); // Log the error for debugging
return of([]); // Return an empty array to prevent the app from breaking in case of an error
}));
}

getPet(id: number): Observable<Pet | null> {
return this.http.get<Pet>(`https://pets-react-query-backend.eapi.joincoded.com/pets/${id}`).pipe(
catchError((error) => {
console.error('Error fetching all pets:', error); // Log the error for debugging
return of(null); // Return an empty array to prevent the app from breaking in case of an error
}));
}

createPet(pet: Pet){
return this.http.post<Pet>('https://pets-react-query-backend.eapi.joincoded.com/pets', pet).pipe(res => res);
}
}
52 changes: 0 additions & 52 deletions src/data/pets.ts

This file was deleted.

5 changes: 4 additions & 1 deletion src/styles.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/* You can add global styles to this file, and also import other style files */
@import "tailwindcss";
/* @import "tailwindcss"; */
@tailwind base;
@tailwind components;
@tailwind utilities;
10 changes: 10 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{html,ts}"
],
theme: {
extend: {},
},
plugins: [],
}