diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html
index 79070ce79..646b9a580 100644
--- a/ui/src/app/app.component.html
+++ b/ui/src/app/app.component.html
@@ -1 +1,3 @@
-
+
+
+
diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts
index 7ec8d09c2..140ef1aef 100644
--- a/ui/src/app/app.module.ts
+++ b/ui/src/app/app.module.ts
@@ -11,10 +11,11 @@ import { NavbarComponent } from './layout/navbar/navbar.component'
import { CommonModule } from '@angular/common'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { HasAnyAuthorityDirective } from './shared/directive/has-any-authority.directive'
-import { HomeModule } from './home/home.module'
+import { HomeModule } from './home/home.module';
+import { FooterComponent } from './layout/footer/footer.component'
@NgModule({
- declarations: [AppComponent, NavbarComponent, HasAnyAuthorityDirective],
+ declarations: [AppComponent, NavbarComponent, HasAnyAuthorityDirective, FooterComponent],
imports: [
FontAwesomeModule,
AccountModule,
diff --git a/ui/src/app/layout/footer/footer.component.html b/ui/src/app/layout/footer/footer.component.html
new file mode 100644
index 000000000..1b44b11d2
--- /dev/null
+++ b/ui/src/app/layout/footer/footer.component.html
@@ -0,0 +1,20 @@
+
diff --git a/ui/src/app/layout/footer/footer.component.scss b/ui/src/app/layout/footer/footer.component.scss
new file mode 100644
index 000000000..f22083738
--- /dev/null
+++ b/ui/src/app/layout/footer/footer.component.scss
@@ -0,0 +1,67 @@
+
+a {
+ color: rgba(0,0,0,0.87);
+ font-family: "Noto Sans", sans-serif;
+ font-size: 14px;
+ font-weight: 700;
+ letter-spacing: 1.3px !important;
+ text-align: center;
+}
+
+p {
+ margin: 0 0 6px;
+ text-align: center;
+ font: 400 14px/16px "Noto Sans", sans-serif;
+}
+
+.copyright,
+.copyright > a,
+.copyright > p {
+ display: block;
+ float: left;
+}
+
+.copyright > p {
+ line-height: 33px;
+ padding-left: 16px;
+ padding-right: 16px;
+}
+
+.footer {
+ background-color: #f5f5f5;
+ font-size: 14px;
+ padding-bottom: 16px;
+ padding-top: 14px;
+ line-height: normal
+}
+
+.list-group-item {
+ border: none;
+ background-color: #f5f5f5;
+ padding: .5rem 1rem;
+}
+
+.footer-row-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 0 20px;
+}
+
+@media screen and (max-width:767px) {
+ nav > ul{
+ clear: both;
+ }
+ nav > .list-group-horizontal .list-group-item {
+ display: block;
+ clear: both;
+ width: 100%;
+ text-align: center;
+ }
+ .copyright,
+ .copyright > a,
+ .copyright > p {
+ clear: both;
+ width: 100%;
+ }
+}
\ No newline at end of file
diff --git a/ui/src/app/layout/footer/footer.component.spec.ts b/ui/src/app/layout/footer/footer.component.spec.ts
new file mode 100644
index 000000000..915b4d088
--- /dev/null
+++ b/ui/src/app/layout/footer/footer.component.spec.ts
@@ -0,0 +1,48 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing'
+
+import { FooterComponent } from './footer.component'
+import { By } from '@angular/platform-browser'
+import { AccountService } from 'src/app/account/service/account.service'
+
+describe('FooterComponent', () => {
+ let component: FooterComponent
+ let fixture: ComponentFixture
+ let accountService: jasmine.SpyObj
+
+ beforeEach(() => {
+ const accountServiceSpy = jasmine.createSpyObj('AccountService', ['isAuthenticated'])
+
+ TestBed.configureTestingModule({
+ declarations: [FooterComponent],
+ providers: [{ provide: AccountService, useValue: accountServiceSpy }],
+ }).compileComponents()
+
+ fixture = TestBed.createComponent(FooterComponent)
+ accountService = TestBed.inject(AccountService) as jasmine.SpyObj
+ fixture.detectChanges()
+ component = fixture.componentInstance
+ })
+
+ it('should create', () => {
+ expect(component).toBeTruthy()
+ })
+
+ it('should contain copyright notice', () => {
+ const copyright = fixture.debugElement.query(By.css('.copyright'))
+ expect(copyright).toBeTruthy()
+ })
+
+ it('if not authenticated, should not contain help link', () => {
+ accountService.isAuthenticated.and.returnValue(false)
+ fixture.detectChanges()
+ const helpLink = fixture.debugElement.query(By.css('#helpLink'))
+ expect(helpLink).toBeFalsy()
+ })
+
+ it('if authenticated, should contain help link', () => {
+ accountService.isAuthenticated.and.returnValue(true)
+ fixture.detectChanges()
+ const helpLink = fixture.debugElement.query(By.css('#helpLink'))
+ expect(helpLink).toBeTruthy()
+ })
+})
diff --git a/ui/src/app/layout/footer/footer.component.ts b/ui/src/app/layout/footer/footer.component.ts
new file mode 100644
index 000000000..9351a3ee1
--- /dev/null
+++ b/ui/src/app/layout/footer/footer.component.ts
@@ -0,0 +1,15 @@
+import { Component } from '@angular/core'
+import { AccountService } from 'src/app/account/service/account.service'
+
+@Component({
+ selector: 'app-footer',
+ templateUrl: './footer.component.html',
+ styleUrls: ['./footer.component.scss'],
+})
+export class FooterComponent {
+ constructor(private accountService: AccountService) {}
+
+ isAuthenticated() {
+ return this.accountService.isAuthenticated()
+ }
+}