commit 0d1b0550767714acf90beee37fd1aa7870ca05ff
Author: Václav Jirák <jirakv95@gmail.com>
Date:   Tue Apr 23 15:28:22 2019 +0200

    Re #7263 Static view for employer initialized
    
    Re #7263 Day picker component implemented
    
    Re #7263 Day picker component modified
    
    Re #7253 Off days component implemented
    
    Re #7263 User approval component implemented
    
    Re #7263 Minor changes
    
    Re #7263 Free days approval component implemented
    
    Re #7263 Free days renamed to Off days
    
    Re #7263 Created simple menu with a service and mock data
    
    Re #7263 Implemented routing for dashboard and employee list
    
    Re #7263 Added simple page for employee route
    
    Re #7263 Off days approval component modified
    
    Re #7263 Days off info component modified
    
    Re #7263 Oncoming days off component implemented
    
    Re #7263 Employer dashboard component implemented
    
    Re #7263 Basic employer's dashboard completed
    
    Re #7263 Menu items correctly displayed when selected
    
    Re #7263 Changed click behavior in menu list
    
    Re #7263 Removed information about remaining sick days

diff --git a/frontend/package.json b/frontend/package.json
index 1aef716..93fbac5 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -16,14 +16,19 @@
     "@angular/compiler": "~7.2.0",
     "@angular/core": "~7.2.0",
     "@angular/forms": "~7.2.0",
+    "@angular/http": "latest",
     "@angular/platform-browser": "~7.2.0",
     "@angular/platform-browser-dynamic": "~7.2.0",
     "@angular/router": "~7.2.0",
+    "@ng-bootstrap/ng-bootstrap": "^4.1.1",
+    "angular-calendar": "^0.27.5",
+    "angularx-flatpickr": "^6.1.0",
     "core-js": "^2.5.4",
+    "date-fns": "^1.30.1",
+    "flatpickr": "^4.5.7",
     "rxjs": "~6.3.3",
     "tslib": "^1.9.0",
-    "zone.js": "~0.8.26",
-    "@angular/http": "latest"
+    "zone.js": "~0.8.26"
   },
   "devDependencies": {
     "@angular-devkit/build-angular": "~0.13.0",
diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index d425c6f..bfa21c7 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -1,7 +1,13 @@
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
+import {EmployeesListComponent} from './employees-list/employees-list.component';
+import {DashboardComponent} from './dashboard/dashboard.component';
 
-const routes: Routes = [];
+const routes: Routes = [
+  { path: 'employees', component: EmployeesListComponent },
+  { path: 'dashboard', component: DashboardComponent },
+  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
+];
 
 @NgModule({
   imports: [RouterModule.forRoot(routes)],
diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html
index 3c542cf..8a5ed38 100644
--- a/frontend/src/app/app.component.html
+++ b/frontend/src/app/app.component.html
@@ -1,6 +1,17 @@
-<b>Post test: </b> {{ postTestResponse }} <br>
-<b>Get test: </b> {{ getTestResponse }} <br>
-<b>EN Hello world test: </b> {{ enHelloWorldResponse }} <br>
-<b>CZ Hello world test: </b> {{ czHelloWorldResponse }} <br>
-<b>Database test: </b> {{ databaseResponse }} <br>
-<router-outlet></router-outlet>
+<div class="container-fluid h-100">
+  <div class="row header">
+    <img class="logo" src="../assets/images/logo.png" />
+    <div class="user-info">
+      <img class="user-icon" src="../assets/images/default-user.png"/>
+      <span class="user-name">Václav Jirák</span>
+    </div>
+  </div>
+  <div class="row navigation-and-content">
+    <div class="col-lg-2 navigation">
+      <app-menu></app-menu>
+    </div>
+    <div class="col-lg-10">
+      <router-outlet></router-outlet>
+    </div>
+  </div>
+</div>
diff --git a/frontend/src/app/app.component.sass b/frontend/src/app/app.component.sass
index e69de29..a9f6736 100644
--- a/frontend/src/app/app.component.sass
+++ b/frontend/src/app/app.component.sass
@@ -0,0 +1,32 @@
+.header
+  height: 50px
+  background-color: #3F425D
+  padding-left: 10px
+
+.user-info
+  height: 100%
+  margin-left: auto
+  margin-right: 0
+
+.user-icon
+  width: 35px
+  height: 35px
+  border-radius: 20px
+
+.user-name
+  height: 50px
+  line-height: 50px
+  color: white
+  margin-left: 10px
+  margin-right: 10px
+
+.navigation-and-content
+  height: calc(100% - 50px)
+
+  .content
+    padding: 0
+
+.navigation
+  background-color: #2F313F
+  margin: 0
+  padding: 0
diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts
deleted file mode 100644
index 0667b9c..0000000
--- a/frontend/src/app/app.component.spec.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { TestBed, async } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
-import { AppComponent } from './app.component';
-
-describe('AppComponent', () => {
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      imports: [
-        RouterTestingModule
-      ],
-      declarations: [
-        AppComponent
-      ],
-    }).compileComponents();
-  }));
-
-  it('should create the app', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.debugElement.componentInstance;
-    expect(app).toBeTruthy();
-  });
-
-  it(`should have as title 'ymanager-frontend'`, () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    const app = fixture.debugElement.componentInstance;
-    expect(app.title).toEqual('ymanager-frontend');
-  });
-
-  it('should render title in a h1 tag', () => {
-    const fixture = TestBed.createComponent(AppComponent);
-    fixture.detectChanges();
-    const compiled = fixture.debugElement.nativeElement;
-    expect(compiled.querySelector('h1').textContent).toContain('Welcome to ymanager-frontend!');
-  });
-});
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index c12590c..dae5871 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -1,6 +1,6 @@
-import { Component, OnInit } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
-import { environment } from '../environments/environment';
+import {Component, OnInit} from '@angular/core';
+import { registerLocaleData } from '@angular/common';
+import localeCs from '@angular/common/locales/cs';
 
 @Component({
   selector: 'app-root',
@@ -8,27 +8,11 @@ import { environment } from '../environments/environment';
   styleUrls: ['./app.component.sass']
 })
 export class AppComponent implements OnInit {
-  getTestResponse;
-  postTestResponse;
-  enHelloWorldResponse;
-  czHelloWorldResponse;
-  databaseResponse;
-  constructor(private httpClient: HttpClient) {}
 
-  ngOnInit() {
-    this.httpClient.get(environment.apiUrl + 'test', { responseType: 'text' })
-      .subscribe(data => this.getTestResponse = data);
-
-    this.httpClient.post(environment.apiUrl + 'test', {}, { responseType: 'text' })
-      .subscribe(data => this.postTestResponse = data);
-
-    this.httpClient.get(environment.apiUrl + 'hello', { responseType: 'text' })
-      .subscribe(data => this.enHelloWorldResponse = data);
+  constructor() {
+    registerLocaleData(localeCs);
+  }
 
-    this.httpClient.get(environment.apiUrl + 'hello?lang=cz', { responseType: 'text' })
-      .subscribe(data => this.czHelloWorldResponse = data);
+  ngOnInit() {}
 
-    this.httpClient.get(environment.apiUrl + 'database', { responseType: 'text' })
-      .subscribe(data => this.databaseResponse = data);
-  }
 }
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 6828360..cffbfb9 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -3,16 +3,20 @@ import { NgModule } from '@angular/core';
 
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
-import {HttpClientModule} from '@angular/common/http';
+import { MenuComponent } from './menu/menu.component';
+import { EmployeesListComponent } from './employees-list/employees-list.component';
+import { DashboardModule } from './dashboard/dashboard.module';
 
 @NgModule({
   declarations: [
-    AppComponent
+    AppComponent,
+    MenuComponent,
+    EmployeesListComponent
   ],
   imports: [
     BrowserModule,
     AppRoutingModule,
-    HttpClientModule
+    DashboardModule
   ],
   providers: [],
   bootstrap: [AppComponent]
diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html
new file mode 100644
index 0000000..719fb5c
--- /dev/null
+++ b/frontend/src/app/dashboard/dashboard.component.html
@@ -0,0 +1 @@
+<app-employer-dashboard></app-employer-dashboard>
diff --git a/frontend/src/app/dashboard/dashboard.component.sass b/frontend/src/app/dashboard/dashboard.component.sass
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/app/dashboard/dashboard.component.ts b/frontend/src/app/dashboard/dashboard.component.ts
new file mode 100644
index 0000000..fe03bc7
--- /dev/null
+++ b/frontend/src/app/dashboard/dashboard.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-dashboard',
+  templateUrl: './dashboard.component.html',
+  styleUrls: ['./dashboard.component.sass']
+})
+export class DashboardComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/frontend/src/app/dashboard/dashboard.module.ts b/frontend/src/app/dashboard/dashboard.module.ts
new file mode 100644
index 0000000..f88e309
--- /dev/null
+++ b/frontend/src/app/dashboard/dashboard.module.ts
@@ -0,0 +1,13 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {EmployerDashboardModule} from './employer-dashboard/employer-dashboard.module';
+import {DashboardComponent} from './dashboard.component';
+
+@NgModule({
+  declarations: [ DashboardComponent ],
+  exports:      [ DashboardComponent ],
+  imports: [
+    EmployerDashboardModule
+  ]
+})
+export class DashboardModule { }
diff --git a/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.html b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.html
new file mode 100644
index 0000000..d82cca1
--- /dev/null
+++ b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.html
@@ -0,0 +1,43 @@
+<div class="container-fluid h-100">
+  <div class="row">
+    <div class="col-lg-8 mid-panel">
+
+      <div *ngIf="usersToApprove.length > 0" class="employer-dashboard-user-approval">
+        <app-user-approval
+          [usersToApprove]="usersToApprove"
+          (userApprovedAction)="userApproved($event.user, $event.approved)"
+        ></app-user-approval>
+      </div>
+
+      <div *ngIf="daysOffToApprove.length > 0" class="employer-dashboard-days-off-approval">
+        <app-days-off-approval
+          [daysOffToApprove]="daysOffToApprove"
+          (daysOffApprovalAction)="daysOffApproved($event.daysOff, $event.approved)"
+        ></app-days-off-approval>
+      </div>
+
+      <div *ngIf="oncomingDaysOff.length > 0" class="employer-dashboard-coming-days-off">
+        <app-coming-days-off
+          [oncomingDaysOff]="oncomingDaysOff"
+          (daysOffRemovedAction)="daysOffRemoved($event.daysOff)"
+        ></app-coming-days-off>
+      </div>
+
+      <div class="employer-dashboard-day-picker">
+        <app-day-picker
+          (selectedDate)="onDateSelect($event)"
+        ></app-day-picker>
+      </div>
+
+    </div>
+
+    <div class="col-lg-4 right-panel">
+
+      <app-days-off-info
+        [sickDaysRemaining]="5"
+        [extraVacationRemaining]="10"
+      ></app-days-off-info>
+
+    </div>
+  </div>
+</div>
diff --git a/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.sass b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.sass
new file mode 100644
index 0000000..3862125
--- /dev/null
+++ b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.sass
@@ -0,0 +1,17 @@
+.row
+  padding: 0
+
+.mid-panel
+  padding: 10px 0 0 10px
+
+.right-panel
+  padding: 10px 10px 0 10px
+
+.employer-dashboard-user-approval
+  padding: 0 0 10px 0
+
+.employer-dashboard-days-off-approval
+  padding: 0 0 10px 0
+
+.employer-dashboard-coming-days-off
+  padding: 0 0 10px 0
diff --git a/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts
new file mode 100644
index 0000000..bdb99d9
--- /dev/null
+++ b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts
@@ -0,0 +1,91 @@
+import { Component, OnInit } from '@angular/core';
+import {UserToApprove} from '../../user-approval/user-to-approve.model';
+import {DaysOff} from '../../shared/days-off.model';
+import {OffDayType } from '../../shared/off-day-type';
+
+@Component({
+  selector: 'app-employer-dashboard',
+  templateUrl: './employer-dashboard.component.html',
+  styleUrls: ['./employer-dashboard.component.sass']
+})
+export class EmployerDashboardComponent implements OnInit {
+
+  usersToApprove: UserToApprove[] = [
+    { date: new Date(), email: 'kek@kek.cz', name: 'Václav Jirák' },
+    { date: new Date(), email: 'kuadas@kek.cz', name: 'Věnceslav Kárij' }
+  ];
+
+  daysOffToApprove: DaysOff[] = [
+    { username: 'Václav Jirák', dateFrom: new Date(2019, 10, 13), dateTo: new Date(), type: OffDayType.Sickday },
+    { username: 'Václav Jirák', dateFrom: new Date(2019, 10, 1), dateTo: new Date(), type: OffDayType.ExtraVacation },
+  ];
+
+  daysOff: DaysOff[] = [
+    {
+      username: '',
+      dateFrom: new Date(2019, 5, 5),
+      dateTo: new Date(2019, 5, 6),
+      type: OffDayType.ExtraVacation
+    },
+    {
+      username: '',
+      dateFrom: new Date(2019, 5, 8),
+      dateTo: new Date(2019, 5, 8),
+      type: OffDayType.Sickday
+    },
+    {
+      username: '',
+      dateFrom: new Date(2019, 3, 8),
+      dateTo: new Date(2019, 3, 9),
+      type: OffDayType.Sickday
+    },
+  ];
+
+  oncomingDaysOff: DaysOff[] = [];
+
+  constructor() { }
+
+  ngOnInit() {
+    this.oncomingDaysOff = this.calculateComingDaysOff();
+  }
+
+  onDateSelect( date: Date ) {
+    console.log('Date selected: ' + date.toDateString());
+  }
+
+  userApproved( user: UserToApprove, approved: boolean ) {
+    console.log(user.name + ' - approved: ' + approved);
+    this.usersToApprove.splice(
+      this.usersToApprove.indexOf(user), 1
+    );
+  }
+
+  daysOffApproved(daysOff: DaysOff, approved: boolean ) {
+    console.log(daysOff.username + ', ' + approved);
+    this.daysOffToApprove.splice(
+      this.daysOffToApprove.indexOf(daysOff), 1
+    );
+  }
+
+  daysOffRemoved(daysOff: DaysOff) {
+    this.daysOff.splice(
+      this.daysOff.indexOf(daysOff), 1
+    );
+    this.oncomingDaysOff.splice(
+      this.oncomingDaysOff.indexOf(daysOff), 1
+    );
+  }
+
+  private calculateComingDaysOff(): DaysOff[] {
+    let oncomingDaysOff: DaysOff[] = [];
+
+    const today = new Date();
+    this.daysOff.forEach((dayOff) => {
+      if (dayOff.dateTo >= today) {
+        oncomingDaysOff.push(dayOff);
+      }
+    });
+
+    return oncomingDaysOff;
+  }
+}
diff --git a/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.module.ts b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.module.ts
new file mode 100644
index 0000000..39bb3d5
--- /dev/null
+++ b/frontend/src/app/dashboard/employer-dashboard/employer-dashboard.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { EmployerDashboardComponent } from './employer-dashboard.component';
+import { DayPickerModule } from '../../day-picker/day-picker.module';
+import { DaysOffInfoModule } from '../../days-off-info/days-off-info.module';
+import { UserApprovalModule } from '../../user-approval/user-approval.module';
+import { DaysOffApprovalModule } from '../../days-off-approval/days-off-approval.module';
+import { OncomingDaysOffModule } from '../../oncoming-days-off/oncoming-days-off.module';
+
+@NgModule({
+  declarations: [ EmployerDashboardComponent ],
+  exports:      [ EmployerDashboardComponent ],
+  imports: [
+    CommonModule,
+    DayPickerModule,
+    DaysOffInfoModule,
+    UserApprovalModule,
+    DaysOffApprovalModule,
+    DayPickerModule,
+    OncomingDaysOffModule
+  ]
+})
+export class EmployerDashboardModule { }
diff --git a/frontend/src/app/day-picker/day-picker.component.html b/frontend/src/app/day-picker/day-picker.component.html
new file mode 100644
index 0000000..33de3cb
--- /dev/null
+++ b/frontend/src/app/day-picker/day-picker.component.html
@@ -0,0 +1,35 @@
+<div class="day-picker-container">
+  <div class="row text-center day-picker-month-selection">
+    <div class="col-4"></div>
+    <div class="col-1">
+      <div class="btn btn-primary"
+           mwlCalendarPreviousView
+           [view]="view"
+           [(viewDate)]="viewDate"
+      >
+        <
+      </div>
+    </div>
+    <div class="col-2">
+      <span id="day-picker-date">{{ viewDate | calendarDate:(view + 'ViewTitle'):locale }}</span>
+    </div>
+    <div class="col-1">
+      <div class="btn btn-primary"
+           mwlCalendarNextView
+           [view]="view"
+           [(viewDate)]="viewDate"
+      >
+        >
+      </div>
+      <div class="col-4"></div>
+    </div>
+  </div>
+
+  <mwl-calendar-month-view
+    [viewDate]="viewDate"
+    (dayClicked)="dayClicked($event.day)"
+    weekStartsOn="1"
+    [locale]="locale"
+  >
+  </mwl-calendar-month-view>
+</div>
diff --git a/frontend/src/app/day-picker/day-picker.component.sass b/frontend/src/app/day-picker/day-picker.component.sass
new file mode 100644
index 0000000..1ced981
--- /dev/null
+++ b/frontend/src/app/day-picker/day-picker.component.sass
@@ -0,0 +1,11 @@
+@import '../../common-styles/basic-component'
+
+.day-picker-container
+  @extend .basic-component
+
+#day-picker-date
+  font-weight: bold
+  text-transform: uppercase
+
+.day-picker-month-selection
+  margin-bottom: 10px
diff --git a/frontend/src/app/day-picker/day-picker.component.ts b/frontend/src/app/day-picker/day-picker.component.ts
new file mode 100644
index 0000000..e068c58
--- /dev/null
+++ b/frontend/src/app/day-picker/day-picker.component.ts
@@ -0,0 +1,34 @@
+import { Component, ChangeDetectionStrategy, Output, EventEmitter } from '@angular/core';
+import { CalendarView } from 'angular-calendar';
+
+@Component({
+  selector: 'app-day-picker',
+  changeDetection: ChangeDetectionStrategy.OnPush,
+  styleUrls: ['day-picker.component.sass'],
+  templateUrl: 'day-picker.component.html'
+})
+export class DayPickerComponent {
+
+  // TODO Move to language service
+  locale = 'cs';
+
+  // Type of calendar (constant)
+  view: CalendarView = CalendarView.Month;
+
+  // Selected date for this component's purpose
+  private viewDate: Date = new Date();
+
+  // EventEmitter informing about changes of selected date
+  @Output() selectedDate = new EventEmitter<Date>();
+
+  /**
+   * Method that is invoked when user clicks on a day.
+   * Sets selected date and emits event informing about new selected date.
+   *
+   * @param date Selected date
+   */
+  private dayClicked({ date }: { date: Date }): void {
+    this.viewDate = date;
+    this.selectedDate.emit(date);
+  }
+}
diff --git a/frontend/src/app/day-picker/day-picker.module.ts b/frontend/src/app/day-picker/day-picker.module.ts
new file mode 100644
index 0000000..d7c7356
--- /dev/null
+++ b/frontend/src/app/day-picker/day-picker.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+import { CalendarModule, DateAdapter } from 'angular-calendar';
+import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
+import { DayPickerComponent } from './day-picker.component';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+@NgModule({
+  declarations: [ DayPickerComponent ],
+  exports:      [ DayPickerComponent ],
+  imports:      [
+                  CalendarModule.forRoot({
+                    provide: DateAdapter,
+                    useFactory: adapterFactory
+                  }),
+                  BrowserAnimationsModule
+                ],
+})
+export class DayPickerModule {}
diff --git a/frontend/src/app/days-off-approval/days-off-approval.component.html b/frontend/src/app/days-off-approval/days-off-approval.component.html
new file mode 100644
index 0000000..06a98ca
--- /dev/null
+++ b/frontend/src/app/days-off-approval/days-off-approval.component.html
@@ -0,0 +1,38 @@
+<div class="days-off-approval-container">
+
+  <div class="component-header">
+    Schvalování volna
+  </div>
+
+  <div class="days-off-approval-list">
+    <div class="row days-off-approval-header">
+      <div class="col-md-3"> Jméno </div>
+      <div class="col-md-3"> Typ volna </div>
+      <div class="col-md-2"> Od </div>
+      <div class="col-md-2"> Do </div>
+      <div class="col-md-2"></div>
+    </div>
+
+    <div class="row days-off-approval" *ngFor="let daysOff of daysOffToApprove">
+      <div class="col-md-3">
+        {{daysOff.username}}
+      </div>
+
+      <div class="col-md-3">
+        {{daysOffTypeToString(daysOff.type)}}
+      </div>
+
+      <div class="col-md-2">
+        {{daysOff.dateFrom | date:'yyyy/MM/dd'}}
+      </div>
+      <div class="col-md-2">
+        {{daysOff.dateTo | date:'yyyy/MM/dd'}}
+      </div>
+      <div class="col-md-2">
+        <div class="btn btn-success approve-btn" (click)="daysOffApprovalCompleted(daysOff, true)">✓</div>
+        <div class="btn btn-danger reject-btn"   (click)="daysOffApprovalCompleted(daysOff, false)">X</div>
+      </div>
+    </div>
+  </div>
+
+</div>
diff --git a/frontend/src/app/days-off-approval/days-off-approval.component.sass b/frontend/src/app/days-off-approval/days-off-approval.component.sass
new file mode 100644
index 0000000..646ed53
--- /dev/null
+++ b/frontend/src/app/days-off-approval/days-off-approval.component.sass
@@ -0,0 +1,18 @@
+@import '../../common-styles/basic-component'
+
+.days-off-approval-container
+  @extend .basic-component
+
+  .days-off-approval-header
+    padding: 10px
+    margin: 0
+    font-weight: bold
+
+  .days-off-approval
+    border-bottom: 1px solid gainsboro
+    margin: 0
+    padding: 10px
+    line-height: 35px
+
+    .approve-btn
+      margin-right: 2px
diff --git a/frontend/src/app/days-off-approval/days-off-approval.component.ts b/frontend/src/app/days-off-approval/days-off-approval.component.ts
new file mode 100644
index 0000000..6fc65e2
--- /dev/null
+++ b/frontend/src/app/days-off-approval/days-off-approval.component.ts
@@ -0,0 +1,32 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { DaysOff } from '../shared/days-off.model';
+import { OffDayType } from '../shared/off-day-type';
+
+@Component({
+  selector: 'app-days-off-approval',
+  templateUrl: './days-off-approval.component.html',
+  styleUrls: ['./days-off-approval.component.sass']
+})
+export class DaysOffApprovalComponent implements OnInit {
+
+  @Input()  daysOffToApprove: DaysOff[];
+  @Output() daysOffApprovalAction = new EventEmitter<{daysOff: DaysOff, approved: boolean}>();
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+  daysOffApprovalCompleted(daysOffApproved: DaysOff, isApproved: boolean ) {
+    this.daysOffApprovalAction.emit({daysOff: daysOffApproved, approved: isApproved});
+  }
+
+  private daysOffTypeToString(taskType: OffDayType): string {
+    switch (taskType) {
+      case OffDayType.ExtraVacation:
+        return 'Extra dovolená';
+      case OffDayType.Sickday:
+        return 'Sickdays';
+    }
+  }
+}
diff --git a/frontend/src/app/days-off-approval/days-off-approval.module.ts b/frontend/src/app/days-off-approval/days-off-approval.module.ts
new file mode 100644
index 0000000..d9f6cbd
--- /dev/null
+++ b/frontend/src/app/days-off-approval/days-off-approval.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { DaysOffApprovalComponent } from './days-off-approval.component';
+import { BrowserModule } from '@angular/platform-browser';
+
+@NgModule({
+  declarations: [ DaysOffApprovalComponent ],
+  exports:      [ DaysOffApprovalComponent ],
+  imports:      [ BrowserModule ]
+})
+export class DaysOffApprovalModule { }
diff --git a/frontend/src/app/days-off-info/days-off-info.component.html b/frontend/src/app/days-off-info/days-off-info.component.html
new file mode 100644
index 0000000..48962a7
--- /dev/null
+++ b/frontend/src/app/days-off-info/days-off-info.component.html
@@ -0,0 +1,17 @@
+<div class="days-off-info-container">
+
+  <div class="component-header">
+    Zbývající volno
+  </div>
+
+  <div class="days-off-type-container">
+    <span class="days-off-remaining">{{extraVacationRemaining}}</span>
+    <span class="days-off-type">Extra dovolená</span>
+  </div>
+
+  <div class="days-off-type-container">
+    <span class="days-off-remaining">{{sickDaysRemaining}}</span>
+    <span class="days-off-type">Sickdays</span>
+  </div>
+
+</div>
diff --git a/frontend/src/app/days-off-info/days-off-info.component.sass b/frontend/src/app/days-off-info/days-off-info.component.sass
new file mode 100644
index 0000000..c0e4975
--- /dev/null
+++ b/frontend/src/app/days-off-info/days-off-info.component.sass
@@ -0,0 +1,18 @@
+@import '../../common-styles/basic-component'
+
+.days-off-info-container
+  @extend .basic-component
+
+.days-off-type-container
+  border-bottom: 1px solid gainsboro
+  padding-left: 20px
+
+.days-off-remaining
+  color: green
+  font-size: 30px
+  font-weight: bold
+
+.days-off-type
+  color: black
+  font-weight: bold
+  display: block
diff --git a/frontend/src/app/days-off-info/days-off-info.component.ts b/frontend/src/app/days-off-info/days-off-info.component.ts
new file mode 100644
index 0000000..7d74a7b
--- /dev/null
+++ b/frontend/src/app/days-off-info/days-off-info.component.ts
@@ -0,0 +1,15 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'app-days-off-info',
+  templateUrl: './days-off-info.component.html',
+  styleUrls: ['./days-off-info.component.sass']
+})
+export class DaysOffInfoComponent {
+
+  @Input() sickDaysRemaining: number;
+
+  @Input() extraVacationRemaining: number;
+
+  constructor() { }
+}
diff --git a/frontend/src/app/days-off-info/days-off-info.module.ts b/frontend/src/app/days-off-info/days-off-info.module.ts
new file mode 100644
index 0000000..02388c3
--- /dev/null
+++ b/frontend/src/app/days-off-info/days-off-info.module.ts
@@ -0,0 +1,8 @@
+import { NgModule } from '@angular/core';
+import { DaysOffInfoComponent } from './days-off-info.component';
+
+@NgModule({
+  declarations: [ DaysOffInfoComponent ],
+  exports:      [ DaysOffInfoComponent ]
+})
+export class DaysOffInfoModule { }
diff --git a/frontend/src/app/employees-list/employees-list.component.html b/frontend/src/app/employees-list/employees-list.component.html
new file mode 100644
index 0000000..56b7b68
--- /dev/null
+++ b/frontend/src/app/employees-list/employees-list.component.html
@@ -0,0 +1,10 @@
+<div>
+  <div>
+    <h3>Zaměstnanci
+      <span class="material-icons">add</span>
+      <span class="material-icons">edit</span>
+    </h3>
+
+  </div>
+  <hr>
+</div>
diff --git a/frontend/src/app/employees-list/employees-list.component.sass b/frontend/src/app/employees-list/employees-list.component.sass
new file mode 100644
index 0000000..5eee04e
--- /dev/null
+++ b/frontend/src/app/employees-list/employees-list.component.sass
@@ -0,0 +1,6 @@
+.material-icons
+    display: inline-flex
+    align-items: center
+    justify-content: center
+    vertical-align: middle
+
diff --git a/frontend/src/app/employees-list/employees-list.component.ts b/frontend/src/app/employees-list/employees-list.component.ts
new file mode 100644
index 0000000..32ab25d
--- /dev/null
+++ b/frontend/src/app/employees-list/employees-list.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-employees-list',
+  templateUrl: './employees-list.component.html',
+  styleUrls: ['./employees-list.component.sass']
+})
+export class EmployeesListComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/frontend/src/app/menu.service.ts b/frontend/src/app/menu.service.ts
new file mode 100644
index 0000000..2a2debf
--- /dev/null
+++ b/frontend/src/app/menu.service.ts
@@ -0,0 +1,16 @@
+import { Injectable } from '@angular/core';
+import { MenuItem } from './menu/menuItem';
+import { Observable, of } from 'rxjs';
+import { MENU_ITEMS } from './mock-menu-items';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MenuService {
+
+  getMenuItems(): Observable<MenuItem[]> {
+    return of(MENU_ITEMS);
+  }
+
+  constructor() { }
+}
diff --git a/frontend/src/app/menu/menu.component.html b/frontend/src/app/menu/menu.component.html
new file mode 100644
index 0000000..f6f86de
--- /dev/null
+++ b/frontend/src/app/menu/menu.component.html
@@ -0,0 +1,12 @@
+<div class="navigation">
+  <nav class="navbar">
+    <ul class="navbar-nav">
+      <li *ngFor="let item of menuItems"
+          [class.selected]="item === selectedMenuItem"
+          (click)="onSelect(item)"
+          class="nav-item">
+        <a routerLink="{{item.routePath}}"><div>{{item.name}}</div></a>
+      </li>
+    </ul>
+  </nav>
+</div>
diff --git a/frontend/src/app/menu/menu.component.sass b/frontend/src/app/menu/menu.component.sass
new file mode 100644
index 0000000..d593c40
--- /dev/null
+++ b/frontend/src/app/menu/menu.component.sass
@@ -0,0 +1,41 @@
+.navbar
+  width: 100%
+  margin: 0
+  padding: 0
+
+.navbar-nav
+  width: 100%
+
+.nav-bar
+  width: 100%
+
+.nav-item
+  height: 50px
+  line-height: 50px
+  width: 100%
+  padding-left: 20px
+  color: #404353
+  background-color: #2F313F
+  border-style: solid
+  border-width: 0 0 1px 0
+  border-color: #6D6F81
+
+  &:hover
+    background-color: #414356
+
+  a
+    color: #6D6F81
+    width: 100%
+    height: 100%
+
+
+.nav-item.selected
+  background-color: #63AA22
+
+  a
+    color: white
+
+  &:hover
+    background-color: #7ad129
+
+
diff --git a/frontend/src/app/menu/menu.component.ts b/frontend/src/app/menu/menu.component.ts
new file mode 100644
index 0000000..bd4278a
--- /dev/null
+++ b/frontend/src/app/menu/menu.component.ts
@@ -0,0 +1,31 @@
+import { Component, OnInit } from '@angular/core';
+import { MenuService } from '../menu.service';
+import { MenuItem } from './menuItem';
+
+@Component({
+  selector: 'app-menu',
+  templateUrl: './menu.component.html',
+  styleUrls: ['./menu.component.sass']
+})
+export class MenuComponent implements OnInit {
+  menuItems: MenuItem[];
+  selectedMenuItem: MenuItem;
+
+
+  getMenuItems(): void {
+    this.menuService.getMenuItems()
+      .subscribe(menuItems => this.menuItems = menuItems);
+  }
+
+  onSelect(menuItem: MenuItem): void {
+    this.selectedMenuItem = menuItem;
+  }
+
+  constructor(private menuService: MenuService) { }
+
+  ngOnInit() {
+    this.getMenuItems();
+  }
+
+
+}
diff --git a/frontend/src/app/menu/menuItem.ts b/frontend/src/app/menu/menuItem.ts
new file mode 100644
index 0000000..2fee21a
--- /dev/null
+++ b/frontend/src/app/menu/menuItem.ts
@@ -0,0 +1,4 @@
+export class MenuItem {
+  name: string;
+  routePath: string;
+}
diff --git a/frontend/src/app/mock-menu-items.ts b/frontend/src/app/mock-menu-items.ts
new file mode 100644
index 0000000..8528b18
--- /dev/null
+++ b/frontend/src/app/mock-menu-items.ts
@@ -0,0 +1,6 @@
+import { MenuItem } from './menu/menuItem';
+
+export const MENU_ITEMS: MenuItem[] = [
+  {name: 'Dashboard', routePath: 'dashboard'},
+  {name: 'Zaměstnanci', routePath: 'employees'},
+];
diff --git a/frontend/src/app/oncoming-days-off/oncoming-days-off.component.html b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.html
new file mode 100644
index 0000000..9e99bae
--- /dev/null
+++ b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.html
@@ -0,0 +1,44 @@
+<div class="oncoming-days-off-container">
+
+  <div class="component-header">
+    Mé nadcházející volno
+  </div>
+
+  <div class="tasks-list">
+    <div class="row oncoming-days-off-header">
+      <div class="col-md-6">
+        Typ volna
+      </div>
+
+      <div class="col-md-2">
+        Od
+      </div>
+
+      <div class="col-md-2">
+        Do
+      </div>
+
+      <div class="col-md-2">
+      </div>
+    </div>
+
+    <div class="row oncoming-days-off" *ngFor="let daysOff of oncomingDaysOff">
+      <div class="col-md-6">
+        {{offDayTypeToString(daysOff.type)}}
+      </div>
+
+      <div class="col-md-2">
+        {{daysOff.dateFrom | date:'yyyy/MM/dd'}}
+      </div>
+
+      <div class="col-md-2">
+        {{daysOff.dateTo | date:'yyyy/MM/dd'}}
+      </div>
+
+      <div class="col-md-2">
+        <div class="btn btn-danger reject-btn" (click)="daysOffRemoved(daysOff)">X</div>
+      </div>
+    </div>
+  </div>
+
+</div>
diff --git a/frontend/src/app/oncoming-days-off/oncoming-days-off.component.sass b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.sass
new file mode 100644
index 0000000..79dce1a
--- /dev/null
+++ b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.sass
@@ -0,0 +1,18 @@
+@import '../../common-styles/basic-component'
+
+.oncoming-days-off-container
+  @extend .basic-component
+
+  .oncoming-days-off-header
+    padding: 10px
+    margin: 0
+    font-weight: bold
+
+  .oncoming-days-off
+    border-bottom: 1px solid gainsboro
+    margin: 0
+    padding: 10px
+    line-height: 35px
+
+    .approve-btn
+      margin-right: 2px
diff --git a/frontend/src/app/oncoming-days-off/oncoming-days-off.component.ts b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.ts
new file mode 100644
index 0000000..d15e5b8
--- /dev/null
+++ b/frontend/src/app/oncoming-days-off/oncoming-days-off.component.ts
@@ -0,0 +1,34 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {DaysOff} from '../shared/days-off.model';
+import {OffDayType} from '../shared/off-day-type';
+
+@Component({
+  selector: 'app-coming-days-off',
+  templateUrl: './oncoming-days-off.component.html',
+  styleUrls: ['./oncoming-days-off.component.sass']
+})
+export class OncomingDaysOffComponent implements OnInit {
+
+  @Input()  oncomingDaysOff: DaysOff[];
+  @Output() daysOffRemovedAction = new EventEmitter<{daysOff: DaysOff}>();
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+  private daysOffRemoved( removedDaysOff: DaysOff ) {
+    this.daysOffRemovedAction.emit( {daysOff: removedDaysOff } );
+  }
+
+  // TODO
+  //  days-off-approval duplicate
+  private offDayTypeToString(taskType: OffDayType): string {
+    switch (taskType) {
+      case OffDayType.ExtraVacation:
+        return 'Extra dovolená';
+      case OffDayType.Sickday:
+        return 'Sickdays';
+    }
+  }
+}
diff --git a/frontend/src/app/oncoming-days-off/oncoming-days-off.module.ts b/frontend/src/app/oncoming-days-off/oncoming-days-off.module.ts
new file mode 100644
index 0000000..d5a480b
--- /dev/null
+++ b/frontend/src/app/oncoming-days-off/oncoming-days-off.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { OncomingDaysOffComponent } from './oncoming-days-off.component';
+import { BrowserModule } from '@angular/platform-browser';
+
+@NgModule({
+  declarations: [ OncomingDaysOffComponent ],
+  exports:      [ OncomingDaysOffComponent ],
+  imports:      [ BrowserModule ],
+})
+export class OncomingDaysOffModule {}
diff --git a/frontend/src/app/shared/days-off.model.ts b/frontend/src/app/shared/days-off.model.ts
new file mode 100644
index 0000000..e8327c9
--- /dev/null
+++ b/frontend/src/app/shared/days-off.model.ts
@@ -0,0 +1,8 @@
+import { OffDayType } from './off-day-type';
+
+export class DaysOff {
+  username: string;
+  dateFrom: Date;
+  dateTo: Date;
+  type: OffDayType;
+}
diff --git a/frontend/src/app/shared/off-day-type.ts b/frontend/src/app/shared/off-day-type.ts
new file mode 100644
index 0000000..dcb832b
--- /dev/null
+++ b/frontend/src/app/shared/off-day-type.ts
@@ -0,0 +1,4 @@
+export enum OffDayType {
+  ExtraVacation,
+  Sickday
+}
diff --git a/frontend/src/app/user-approval/user-approval.component.html b/frontend/src/app/user-approval/user-approval.component.html
new file mode 100644
index 0000000..14b9709
--- /dev/null
+++ b/frontend/src/app/user-approval/user-approval.component.html
@@ -0,0 +1,25 @@
+<div class="user-approval-container">
+
+  <div class="component-header">
+    Schvalování uživatelů
+  </div>
+
+  <div class="user-approval-list">
+    <div class="row user-to-approve-container" *ngFor="let user of usersToApprove">
+      <div class="col-md-4">
+        {{user.name}}
+      </div>
+      <div class="col-md-4">
+        {{user.email}}
+      </div>
+      <div class="col-md-2">
+        {{user.date | date:'yyyy/MM/dd'}}
+      </div>
+      <div class="col-md-2">
+        <div class="btn btn-success approve-user-btn" (click)="userApproved(user, true)">✓</div>
+        <div class="btn btn-danger reject-user-btn"   (click)="userApproved(user, false)">X</div>
+      </div>
+    </div>
+  </div>
+
+</div>
diff --git a/frontend/src/app/user-approval/user-approval.component.sass b/frontend/src/app/user-approval/user-approval.component.sass
new file mode 100644
index 0000000..252d55b
--- /dev/null
+++ b/frontend/src/app/user-approval/user-approval.component.sass
@@ -0,0 +1,13 @@
+@import '../../common-styles/basic-component'
+
+.user-approval-container
+  @extend .basic-component
+
+  .user-to-approve-container
+    border-bottom: 1px solid gainsboro
+    margin: 0
+    padding: 10px
+    line-height: 35px
+
+    .approve-user-btn
+      margin-right: 2px
diff --git a/frontend/src/app/user-approval/user-approval.component.ts b/frontend/src/app/user-approval/user-approval.component.ts
new file mode 100644
index 0000000..995bf55
--- /dev/null
+++ b/frontend/src/app/user-approval/user-approval.component.ts
@@ -0,0 +1,21 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { UserToApprove } from './user-to-approve.model';
+
+
+@Component({
+  selector: 'app-user-approval',
+  templateUrl: './user-approval.component.html',
+  styleUrls: ['./user-approval.component.sass']
+})
+export class UserApprovalComponent {
+
+  @Input()  usersToApprove: UserToApprove[];
+  @Output() userApprovedAction = new EventEmitter<{user: UserToApprove, approved: boolean}>();
+
+  constructor() { }
+
+  userApproved(approvedUser: UserToApprove, isApproved: boolean) {
+    this.userApprovedAction.emit({user: approvedUser, approved: isApproved});
+  }
+
+}
diff --git a/frontend/src/app/user-approval/user-approval.module.ts b/frontend/src/app/user-approval/user-approval.module.ts
new file mode 100644
index 0000000..7d83089
--- /dev/null
+++ b/frontend/src/app/user-approval/user-approval.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { UserApprovalComponent } from './user-approval.component';
+import { BrowserModule } from '@angular/platform-browser';
+
+@NgModule({
+  declarations: [ UserApprovalComponent ],
+  exports:      [ UserApprovalComponent ],
+  imports:      [ BrowserModule ]
+})
+export class UserApprovalModule { }
diff --git a/frontend/src/app/user-approval/user-to-approve.model.ts b/frontend/src/app/user-approval/user-to-approve.model.ts
new file mode 100644
index 0000000..a704d5e
--- /dev/null
+++ b/frontend/src/app/user-approval/user-to-approve.model.ts
@@ -0,0 +1,5 @@
+export class UserToApprove {
+  name: string;
+  email: string;
+  date: Date;
+}
diff --git a/frontend/src/assets/images/default-user.png b/frontend/src/assets/images/default-user.png
new file mode 100644
index 0000000..a2f8e95
Binary files /dev/null and b/frontend/src/assets/images/default-user.png differ
diff --git a/frontend/src/assets/images/logo.png b/frontend/src/assets/images/logo.png
new file mode 100644
index 0000000..12fab1b
Binary files /dev/null and b/frontend/src/assets/images/logo.png differ
diff --git a/frontend/src/common-styles/basic-component.sass b/frontend/src/common-styles/basic-component.sass
new file mode 100644
index 0000000..a3186f9
--- /dev/null
+++ b/frontend/src/common-styles/basic-component.sass
@@ -0,0 +1,10 @@
+.basic-component
+  background-color: white
+  padding: 10px
+  border: 1px solid gainsboro
+
+  .component-header
+    font-size: 15px
+    border-bottom: 1px solid gainsboro
+    padding: 0 0 10px 20px
+    margin: 0 -10px 0 -10px
diff --git a/frontend/src/index.html b/frontend/src/index.html
index 36ef8a0..5e73322 100644
--- a/frontend/src/index.html
+++ b/frontend/src/index.html
@@ -2,10 +2,20 @@
 <html lang="en">
 <head>
   <meta charset="utf-8">
-  <title>YmanagerFrontend</title>
+  <title>Ymanager</title>
   <base href="/">
 
   <meta name="viewport" content="width=device-width, initial-scale=1">
+
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
+
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
+  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+  <link href="https://unpkg.com/font-awesome@4.7.0/css/font-awesome.css" rel="stylesheet">
+  <link href="https://unpkg.com/angular-calendar@0.27.5/css/angular-calendar.css" rel="stylesheet">
+  <link href="https://unpkg.com/flatpickr@4.5.7/dist/flatpickr.css" rel="stylesheet">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
 </head>
 <body>
diff --git a/frontend/src/styles.sass b/frontend/src/styles.sass
index 90d4ee0..7e24cd9 100644
--- a/frontend/src/styles.sass
+++ b/frontend/src/styles.sass
@@ -1 +1,15 @@
-/* You can add global styles to this file, and also import other style files */
+*
+  margin: 0
+  padding: 0
+  font-family: "Helvetica", serif
+  font-size: 12px
+
+
+a
+  &:hover
+    text-decoration: none
+
+
+body, html
+  height: 100%
+  background-color: #F0FFFD
