diff --git a/src/app/app.component.html b/src/app/app.component.html index 2934ad1..6659729 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1 +1,2 @@ - + + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f33c411..eab0f81 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,12 +1,14 @@ import { Component } from '@angular/core'; import { HomeComponent } from './pages/home/home.component'; +import { RouterOutlet } from '@angular/router'; +import { NavbarComponent } from './components/navbar/navbar.component'; @Component({ selector: 'app-root', standalone: true, - imports: [HomeComponent], + imports: [HomeComponent, RouterOutlet, NavbarComponent], templateUrl: './app.component.html', - styleUrl: './app.component.css' + styleUrl: './app.component.css', }) export class AppComponent { title = 'TASK-NG-Routing'; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dc39edb..9c62ae0 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,3 +1,25 @@ import { Routes } from '@angular/router'; -export const routes: Routes = []; +export const routes: Routes = [ + { + path: '', + loadComponent: () => + import('./pages/home/home.component').then((m) => m.HomeComponent), + }, + { + path: 'trips', + loadComponent: () => + import('./pages/trips-list/trips-list.component').then( + (m) => m.TripsListComponent + ), + }, + { + path: 'trips/:slug', + loadComponent: () => + import('./pages/trip/trip.component').then((m) => m.TripComponent), + }, + { + path: '**', + redirectTo: '', + }, +]; diff --git a/src/app/components/navbar/navbar.component.css b/src/app/components/navbar/navbar.component.css index d01d5b5..529333f 100644 --- a/src/app/components/navbar/navbar.component.css +++ b/src/app/components/navbar/navbar.component.css @@ -47,6 +47,10 @@ .navbar-link:hover { color: #1abc9c; } +.active-link { + color: lightpink; + font-weight: bold; +} @media (min-width: 768px) { .navbar-links { diff --git a/src/app/components/navbar/navbar.component.html b/src/app/components/navbar/navbar.component.html index 86bcc47..474cb31 100644 --- a/src/app/components/navbar/navbar.component.html +++ b/src/app/components/navbar/navbar.component.html @@ -6,10 +6,15 @@ diff --git a/src/app/components/navbar/navbar.component.ts b/src/app/components/navbar/navbar.component.ts index aef9405..a997e0e 100644 --- a/src/app/components/navbar/navbar.component.ts +++ b/src/app/components/navbar/navbar.component.ts @@ -1,12 +1,11 @@ import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; @Component({ selector: 'app-navbar', standalone: true, - imports: [], + imports: [RouterLink], templateUrl: './navbar.component.html', - styleUrl: './navbar.component.css' + styleUrl: './navbar.component.css', }) -export class NavbarComponent { - -} +export class NavbarComponent {} diff --git a/src/app/components/trip-card/trip-card.component.html b/src/app/components/trip-card/trip-card.component.html index 0428d14..44b8f55 100644 --- a/src/app/components/trip-card/trip-card.component.html +++ b/src/app/components/trip-card/trip-card.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/app/components/trip-card/trip-card.component.ts b/src/app/components/trip-card/trip-card.component.ts index eb6eee8..644f9ef 100644 --- a/src/app/components/trip-card/trip-card.component.ts +++ b/src/app/components/trip-card/trip-card.component.ts @@ -1,5 +1,6 @@ import { Component, Input } from '@angular/core'; import { Trip } from '../../../data/trips'; +import { Router } from '@angular/router'; @Component({ selector: 'app-trip-card', @@ -10,4 +11,10 @@ import { Trip } from '../../../data/trips'; }) export class TripCardComponent { @Input() trip!: Trip; + + constructor(private router: Router) {} + + navigateToTrip(slug: string) { + this.router.navigate(['/trips', slug]); + } } diff --git a/src/app/components/trip-details/trip-details.component.ts b/src/app/components/trip-details/trip-details.component.ts index ad029f7..3c7f3d2 100644 --- a/src/app/components/trip-details/trip-details.component.ts +++ b/src/app/components/trip-details/trip-details.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, Output } from '@angular/core'; import { Trip } from '../../../data/trips'; import { DividerComponent } from '../divider/divider.component'; @@ -7,7 +7,7 @@ import { DividerComponent } from '../divider/divider.component'; standalone: true, imports: [DividerComponent], templateUrl: './trip-details.component.html', - styleUrl: './trip-details.component.css' + styleUrl: './trip-details.component.css', }) export class TripDetailsComponent { @Input() trip!: Trip; diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index 08171ab..9f2c545 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -1,25 +1,4 @@ - - - -
-
-

Explore Trips

-
- - - -
-
- -@if (selectedTrip) { - -} diff --git a/src/app/pages/trip/trip.component.css b/src/app/pages/trip/trip.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/trip/trip.component.html b/src/app/pages/trip/trip.component.html new file mode 100644 index 0000000..3c5275f --- /dev/null +++ b/src/app/pages/trip/trip.component.html @@ -0,0 +1,3 @@ +@if (selectedTrip) { + +} diff --git a/src/app/pages/trip/trip.component.spec.ts b/src/app/pages/trip/trip.component.spec.ts new file mode 100644 index 0000000..4c19a5b --- /dev/null +++ b/src/app/pages/trip/trip.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TripComponent } from './trip.component'; + +describe('TripComponent', () => { + let component: TripComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TripComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TripComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/trip/trip.component.ts b/src/app/pages/trip/trip.component.ts new file mode 100644 index 0000000..92b9e32 --- /dev/null +++ b/src/app/pages/trip/trip.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { Trip, trips } from '../../../data/trips'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TripDetailsComponent } from '../../components/trip-details/trip-details.component'; + +@Component({ + selector: 'app-trip', + standalone: true, + imports: [TripDetailsComponent], + templateUrl: './trip.component.html', + styleUrl: './trip.component.css', +}) +export class TripComponent { + selectedTrip: Trip | undefined; + + constructor(private route: ActivatedRoute, private router: Router) { + const id = this.route.snapshot.paramMap.get('slug')!; + this.selectedTrip = trips.find((trip) => trip.slug === id); + if (!this.selectedTrip) { + this.router.navigate(['/trips']); + } + } + + goBack() { + this.router.navigate(['trips']); + } +} diff --git a/src/app/pages/trips-list/trips-list.component.css b/src/app/pages/trips-list/trips-list.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/trips-list/trips-list.component.html b/src/app/pages/trips-list/trips-list.component.html new file mode 100644 index 0000000..d1163a1 --- /dev/null +++ b/src/app/pages/trips-list/trips-list.component.html @@ -0,0 +1,12 @@ +
+
+

Explore Trips

+
+ + + +
+
diff --git a/src/app/pages/trips-list/trips-list.component.spec.ts b/src/app/pages/trips-list/trips-list.component.spec.ts new file mode 100644 index 0000000..354f397 --- /dev/null +++ b/src/app/pages/trips-list/trips-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TripsListComponent } from './trips-list.component'; + +describe('TripsListComponent', () => { + let component: TripsListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TripsListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TripsListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/trips-list/trips-list.component.ts b/src/app/pages/trips-list/trips-list.component.ts new file mode 100644 index 0000000..d17cedb --- /dev/null +++ b/src/app/pages/trips-list/trips-list.component.ts @@ -0,0 +1,72 @@ +import { Component } from '@angular/core'; +import { BannerComponent } from '../../components/banner/banner.component'; +import { SearchFilterComponent } from '../../components/search-filter/search-filter.component'; +import { DividerComponent } from '../../components/divider/divider.component'; +import { TripsGridComponent } from '../../components/trips-grid/trips-grid.component'; +import { TripDetailsComponent } from '../../components/trip-details/trip-details.component'; +import { DifficultyLevel, Trip, trips } from '../../../data/trips'; +import { NavbarComponent } from '../../components/navbar/navbar.component'; +import { ActivatedRoute, Router } from '@angular/router'; + +@Component({ + selector: 'app-trips-list', + standalone: true, + imports: [ + BannerComponent, + SearchFilterComponent, + DividerComponent, + TripsGridComponent, + TripDetailsComponent, + NavbarComponent, + ], + templateUrl: './trips-list.component.html', + styleUrl: './trips-list.component.css', +}) +export class TripsListComponent { + trips: Trip[] = trips; + filteredTrips: Trip[] = [...trips]; + selectedTrip: Trip = trips[0]; + searchQuery: string = ''; + activeDifficultyFilter: DifficultyLevel = 'All'; + + constructor(private route: ActivatedRoute, private router: Router) { + this.route.queryParams.subscribe((params) => { + const difficulty = params['difficulty'] as DifficultyLevel; + if (difficulty && ['Easy', 'Medium', 'Hard'].includes(difficulty)) { + this.activeDifficultyFilter = difficulty; + this.applyFilters(); + } + }); + } + + handleSearch(searchTerm: string) { + this.searchQuery = searchTerm.toLowerCase(); + this.applyFilters(); + } + + handleFilter(difficulty: DifficultyLevel) { + this.activeDifficultyFilter = difficulty; + + this.router.navigate([], { + queryParams: { difficulty: difficulty !== 'All' ? difficulty : null }, + queryParamsHandling: 'merge', + }); + + this.applyFilters(); + } + + private applyFilters() { + this.filteredTrips = this.trips.filter((trip) => { + const matchesSearch = + !this.searchQuery || + trip.name.toLowerCase().includes(this.searchQuery.toLowerCase()) || + trip.city.toLowerCase().includes(this.searchQuery.toLowerCase()); + + const matchesDifficulty = + this.activeDifficultyFilter === 'All' || + trip.difficulty === this.activeDifficultyFilter; + + return matchesSearch && matchesDifficulty; + }); + } +}