diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html index 0791e0c..7edd313 100644 --- a/ui/src/app/app.component.html +++ b/ui/src/app/app.component.html @@ -2,3 +2,4 @@
+ diff --git a/ui/src/app/app.component.scss b/ui/src/app/app.component.scss index a1d32de..1c34f52 100644 --- a/ui/src/app/app.component.scss +++ b/ui/src/app/app.component.scss @@ -1,4 +1,13 @@ +:host { + display: flex; + flex-direction: column; + height: 100vh; + overflow: hidden; +} + main { - min-height: calc(100vh - 64px); + flex: 1; + overflow-y: auto; + overflow-x: hidden; background: #fafafa; } diff --git a/ui/src/app/app.component.spec.ts b/ui/src/app/app.component.spec.ts index f495654..a79495a 100644 --- a/ui/src/app/app.component.spec.ts +++ b/ui/src/app/app.component.spec.ts @@ -29,4 +29,11 @@ describe('AppComponent', () => { const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('app-header')).toBeTruthy(); }); + + it('should render footer', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('app-footer')).toBeTruthy(); + }); }); diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index d02beed..8c546b7 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -1,11 +1,12 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { HeaderComponent } from './components/header/header.component'; +import { FooterComponent } from './components/footer/footer.component'; @Component({ selector: 'app-root', standalone: true, - imports: [RouterOutlet, HeaderComponent], + imports: [RouterOutlet, HeaderComponent, FooterComponent], templateUrl: './app.component.html', styleUrl: './app.component.scss', }) diff --git a/ui/src/app/app.config.ts b/ui/src/app/app.config.ts index ec69408..fff2d5f 100644 --- a/ui/src/app/app.config.ts +++ b/ui/src/app/app.config.ts @@ -1,5 +1,6 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; import { routes } from './app.routes'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; @@ -9,5 +10,6 @@ export const appConfig: ApplicationConfig = { provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync(), + provideHttpClient(), ], }; diff --git a/ui/src/app/components/footer/footer.component.html b/ui/src/app/components/footer/footer.component.html new file mode 100644 index 0000000..4821060 --- /dev/null +++ b/ui/src/app/components/footer/footer.component.html @@ -0,0 +1,6 @@ + diff --git a/ui/src/app/components/footer/footer.component.scss b/ui/src/app/components/footer/footer.component.scss new file mode 100644 index 0000000..2296b10 --- /dev/null +++ b/ui/src/app/components/footer/footer.component.scss @@ -0,0 +1,28 @@ +footer { + background: #263238; + color: #90a4ae; + font-size: 13px; + flex-shrink: 0; + z-index: 100; + box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.15); +} + +.footer-content { + max-width: 1200px; + margin: 0 auto; + padding: 14px 24px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 16px; + flex-wrap: wrap; +} + +.project { + color: #cfd8dc; + font-weight: 500; +} + +.credits { + color: #78909c; +} diff --git a/ui/src/app/components/footer/footer.component.spec.ts b/ui/src/app/components/footer/footer.component.spec.ts new file mode 100644 index 0000000..db64482 --- /dev/null +++ b/ui/src/app/components/footer/footer.component.spec.ts @@ -0,0 +1,38 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FooterComponent } from './footer.component'; + +describe('FooterComponent', () => { + let fixture: ComponentFixture; + let compiled: HTMLElement; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FooterComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(FooterComponent); + fixture.detectChanges(); + compiled = fixture.nativeElement as HTMLElement; + }); + + it('should create', () => { + expect(fixture.componentInstance).toBeTruthy(); + }); + + it('should render a