Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+<app-navigation></app-navigation>
+<router-outlet></router-outlet>
+<app-footer></app-footer>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,29 @@
+import { TestBed } from '@angular/core/testing';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [AppComponent],
+    }).compileComponents();
+  });
+
+  it('should create the app', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app).toBeTruthy();
+  });
+
+  it(`should have the 'bus-n-go-frontend' title`, () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app.title).toEqual('bus-n-go-frontend');
+  });
+
+  it('should render title', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    fixture.detectChanges();
+    const compiled = fixture.nativeElement as HTMLElement;
+    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, bus-n-go-frontend');
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import {Component, OnInit} from '@angular/core';
+import { RouterOutlet } from '@angular/router';
+import {MatSlideToggleModule} from "@angular/material/slide-toggle";
+import {NavigationComponent} from "./components/navigation/navigation.component";
+import {FooterComponent} from "./components/footer/footer.component";
+
+@Component({
+  selector: 'app-root',
+  standalone: true,
+  imports: [RouterOutlet, MatSlideToggleModule, NavigationComponent, FooterComponent],
+  templateUrl: './app.component.html',
+  styleUrl: './app.component.css'
+})
+export class AppComponent {
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.config.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.config.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.config.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
+import { provideRouter } from '@angular/router';
+
+import { routes } from './app.routes';
+import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
+import {provideHttpClient, withInterceptors} from "@angular/common/http";
+import {authInterceptor} from "./interceptors/auth.interceptor";
+
+export const appConfig: ApplicationConfig = {
+  providers: [
+    provideZoneChangeDetection({ eventCoalescing: true }),
+    provideRouter(routes),
+    provideAnimationsAsync(),
+    provideHttpClient(withInterceptors([authInterceptor]))
+  ]
+};
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.routes.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.routes.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/app.routes.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,70 @@
+import {Routes} from '@angular/router';
+import {LoginComponent} from "./components/login/login.component";
+import {TicketsPageComponent} from "./components/tickets-page/tickets-page.component";
+import {TicketsBuyComponent} from "./components/tickets-buy/tickets-buy.component";
+import {StartRouteInstanceComponent} from "./components/route-instances/start-route-instnace/start-route-instance.component";
+import {RouteInstanceComponent} from "./components/route-instances/route-instance/route-instance.component";
+import {StartCommuteComponent} from "./components/commutes/start-commute/start-commute.component";
+import {CommuteComponent} from "./components/commutes/commute/commute.component";
+import {StartCcontrolComponent} from "./components/controls/start-ccontrol/start-ccontrol.component";
+import {ControlsComponent} from "./components/controls/controls/controls.component";
+import {ControlComponent} from "./components/controls/control/control.component";
+import {AdminPanelComponent} from "./components/admin/admin-panel/admin-panel.component";
+import {RegisterComponent} from "./components/register/register.component";
+import {authGuard} from "./guards/auth.guard";
+import {authCanmatchGuard} from "./guards/auth-canmatch.guard";
+
+export const routes: Routes = [{
+  path: 'login',
+  component: LoginComponent
+},
+  {
+    path: 'tickets',
+    component: TicketsPageComponent,
+    canActivate: [authGuard],
+    canMatch: [authCanmatchGuard]
+  },
+  {
+    path: 'tickets/buy',
+    component: TicketsBuyComponent,
+  },
+  {
+    path: 'route-instances/start',
+    component: StartRouteInstanceComponent,
+    canActivate: [authGuard],
+    canMatch: [authCanmatchGuard]
+  },
+  {
+    path: 'route-instances/:id',
+    component: RouteInstanceComponent
+  },
+  {
+    path: 'commutes/start',
+    component: StartCommuteComponent
+  },
+  {
+    path: 'commutes/:id',
+    component: CommuteComponent
+  },
+  {
+    path: 'controls/start',
+    component: StartCcontrolComponent
+  },
+  {
+    path: 'controls',
+    component: ControlsComponent
+  },
+  {
+    path: 'controls/:id',
+    component: ControlComponent
+  },
+  {
+    path: 'admin',
+    component: AdminPanelComponent
+  },
+  {
+    path: 'register',
+    component: RegisterComponent
+  }
+
+  ];
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,63 @@
+<div class="flex flex-col gap-5">
+  <table mat-table [dataSource]="users" class="mat-elevation-z8">
+
+    <ng-container matColumnDef="id">
+      <th mat-header-cell *matHeaderCellDef> id </th>
+      <td mat-cell *matCellDef="let element"> {{element.id}} </td>
+    </ng-container>
+
+    <ng-container matColumnDef="name">
+      <th mat-header-cell *matHeaderCellDef> name </th>
+      <td mat-cell *matCellDef="let element"> {{element.name}} </td>
+    </ng-container>
+
+    <!-- Weight Column -->
+    <ng-container matColumnDef="email">
+      <th mat-header-cell *matHeaderCellDef> email </th>
+      <td mat-cell *matCellDef="let element"> {{element.email}} </td>
+    </ng-container>
+
+    <!-- Symbol Column -->
+    <ng-container matColumnDef="address">
+      <th mat-header-cell *matHeaderCellDef> address </th>
+      <td mat-cell *matCellDef="let element"> {{element.address}} </td>
+    </ng-container>
+
+    <ng-container matColumnDef="phoneNumber">
+      <th mat-header-cell *matHeaderCellDef> address </th>
+      <td mat-cell *matCellDef="let element"> {{element.phoneNumber}} </td>
+    </ng-container>
+
+    <ng-container matColumnDef="roles">
+      <th mat-header-cell *matHeaderCellDef> roles </th>
+      <td mat-cell *matCellDef="let element">
+        @for(role of allRoles; track $index){
+          <mat-checkbox [name]="role" [value]="role" (change)="onSelectRole(element.id, $event)" [checked]="checked(role, element.roles)" class="example-margin">{{role}}</mat-checkbox>
+        }
+      </td>
+    </ng-container>
+
+    <ng-container matColumnDef="update">
+      <th mat-header-cell *matHeaderCellDef>Update Roles</th>
+      <td mat-cell *matCellDef="let element">
+        <button mat-flat-button (click)="updateRoles(element.id)">Update</button>
+      </td>
+    </ng-container>
+
+    <tr mat-header-row *matHeaderRowDef="usersColumns"></tr>
+    <tr mat-row *matRowDef="let row; columns: usersColumns;"></tr>
+  </table>
+
+  <div>
+    <app-pie-chart [dataFn]="getFinesPerLine()"></app-pie-chart>
+  </div>
+
+  <div>
+    <app-line-chart [dataFn]="getCommutesByHour()"></app-line-chart>
+  </div>
+
+  <div>
+    <app-income-chart [dataFn]="getTotalIncome()"></app-income-chart>
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/admin/admin-panel/admin-panel.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,88 @@
+import {Component, OnInit} from '@angular/core';
+import {MatTableModule} from '@angular/material/table';
+import {AdminService} from "../../../services/admin/admin.service";
+import {AdminUsersResponse} from "../../../model/responses/AdminUsersResponse";
+import {MatCheckboxChange, MatCheckboxModule} from '@angular/material/checkbox';
+import {MatButton} from "@angular/material/button";
+import {PieChartComponent} from "../../charts/pie-chart/pie-chart.component";
+import {map, Observable} from "rxjs";
+import {PieChartValues} from "../../../model/PieChartValues";
+import {CommutesByHour, LineChartComponent} from "../../charts/line-chart.component";
+import {IncomeChartComponent, IncomeData} from "../../charts/stacked-bar-chart.component";
+
+@Component({
+  selector: 'app-admin-panel',
+  standalone: true,
+  imports: [MatTableModule, MatCheckboxModule, MatButton, PieChartComponent, LineChartComponent, IncomeChartComponent],
+  templateUrl: './admin-panel.component.html',
+  styleUrl: './admin-panel.component.css'
+})
+export class AdminPanelComponent implements OnInit {
+
+  allRoles = ['ROLE_ADMIN', 'ROLE_DRIVER', 'ROLE_CONDUCTOR', 'ROLE_PASSENGER']
+
+  users: AdminUsersResponse[] = []
+  usersColumns: string[] = ['id', 'name', 'email', 'phoneNumber', 'address', 'roles', 'update'];
+
+  constructor(private adminService: AdminService) {
+
+  }
+
+  ngOnInit() {
+    this.adminService.getAllUsers().subscribe({
+      next: data => {
+        this.users = data
+        console.log(data)
+      }
+    })
+  }
+
+  checked(role: string, roles: string[]): boolean {
+    return roles.includes(role)
+  }
+
+  updateRoles(id: number) {
+    console.log(id)
+    const user = this.users.find(u => u.id === id)
+    console.log(user)
+    if (!user) return;
+    this.adminService.updateRolesToUser(id, user.roles).subscribe({
+      next: value => {
+        console.log(value)
+        this.users = value
+      }
+    })
+  }
+
+  onSelectRole(id: number, event: MatCheckboxChange) {
+    console.log(event)
+    const role = event.source.name
+    if (!role) return;
+    this.users.filter(u => u.id === id).forEach(
+      u => {
+        var index = u.roles.indexOf(role);
+        if (index > -1) {
+          u.roles.splice(index, 1);
+        } else {
+          u.roles.push(role);
+        }
+      }
+    )
+  }
+
+  getFinesPerLine(): Observable<PieChartValues[]> {
+    return this.adminService.getFinesPerLine()
+                .pipe(
+                    map(data => data.flatMap(finePerLine => Object({value: finePerLine.count, name: finePerLine.line.ime}))
+                    )
+                );
+  }
+
+  getCommutesByHour(): Observable<CommutesByHour[]> {
+    return this.adminService.getCommutesByHour();
+  }
+
+  getTotalIncome(): Observable<IncomeData[]> {
+    return this.adminService.getTotalIncome()
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/line-chart.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/line-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/line-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,90 @@
+import { Component, Input, OnInit, OnDestroy } from '@angular/core';
+import { Observable, Subscription } from 'rxjs';
+import {NGX_ECHARTS_CONFIG, NgxEchartsModule} from "ngx-echarts";
+import {Line} from "../../model/Line";
+
+export interface CommutesByHour {
+   id: number,
+   line: Line,
+   interval: string,
+   numberOfCommutes: number,
+}
+
+@Component({
+  selector: 'app-line-chart',
+  template: `
+    <div echarts [options]="chartOptions" class="chart"></div>`,
+  standalone: true,
+  imports: [NgxEchartsModule],
+  providers: [
+    {
+      provide: NGX_ECHARTS_CONFIG,
+      useFactory: () => ({ echarts: () => import('echarts') }),
+    },
+  ],
+  styles: [`
+    .chart {
+      width: 100%;
+      height: 400px;
+    }
+  `]
+})
+export class LineChartComponent implements OnInit, OnDestroy {
+  @Input() dataFn!: Observable<CommutesByHour[]>; // Required input
+
+  chartOptions: any;
+
+  ngOnInit(): void {
+    if (!this.dataFn) {
+      console.error('Input dataFn is required');
+      return;
+    }
+
+
+      this.dataFn.subscribe(data => {
+        console.log(data)
+        this.chartOptions = {
+          title: {
+            text: 'Number of Activities per Hour',
+            left: 'center'
+          },
+          tooltip: {
+            trigger: 'axis'
+          },
+          legend: {
+            data: ['Number of Activities'],
+            left: 'left'
+          },
+          xAxis: {
+            type: 'category',
+            data: data.sort((x, y) => Number(x.interval.slice(0,3)) - Number(y.interval.slice(0,3))).map(d => d.interval),
+            axisLabel: {
+              rotate: 45
+            }
+          },
+          yAxis: {
+            type: 'value',
+            name: 'Number of Activities'
+          },
+          series: [
+            {
+              name: 'Number of Activities',
+              type: 'line',
+              data: data.map(d => d.numberOfCommutes),
+              smooth: true,
+              lineStyle: {
+                color: '#ff6f61'
+              },
+              itemStyle: {
+                color: '#ff6f61'
+              }
+            }
+          ]
+        };
+      }
+    );
+  }
+
+  ngOnDestroy(): void {
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,1 @@
+<div echarts [options]="chartOptions" class="chart"></div>>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/pie-chart/pie-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,67 @@
+import {Component, Input, OnInit} from '@angular/core';
+import {NGX_ECHARTS_CONFIG, NgxEchartsModule} from "ngx-echarts";
+import {Observable} from "rxjs";
+import {PieChartValues} from "../../../model/PieChartValues";
+
+
+
+@Component({
+  selector: 'app-pie-chart',
+  standalone: true,
+  imports: [NgxEchartsModule],
+  providers: [
+    {
+      provide: NGX_ECHARTS_CONFIG,
+      useFactory: () => ({ echarts: () => import('echarts') }),
+    },
+  ],
+  templateUrl: './pie-chart.component.html',
+  styleUrl: './pie-chart.component.css'
+})
+export class PieChartComponent implements OnInit {
+  @Input() dataFn!: Observable<PieChartValues[]>
+  chartOptions: any;
+
+  ngOnInit(): void {
+    this.dataFn.subscribe({
+      next: value => {
+        this.chartOptions = this._getOptions(value)
+      }
+    })
+
+  }
+
+  private _getOptions(value: PieChartValues[]) {
+    return {
+      title: {
+        text: 'Fines per Line',
+          subtext: 'Current Year',
+          left: 'center'
+      },
+      tooltip: {
+        trigger: 'item'
+      },
+      legend: {
+        orient: 'vertical',
+          left: 'left'
+      },
+      series: [
+        {
+          name: 'Fines',
+          type: 'pie',
+          radius: '50%',
+          data: [
+            ...value
+          ],
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: 'rgba(0, 0, 0, 0.5)'
+            }
+          }
+        }
+      ]
+    };
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/stacked-bar-chart.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/stacked-bar-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/charts/stacked-bar-chart.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,101 @@
+import { Component, Input, OnInit, OnDestroy } from '@angular/core';
+import { Observable, Subscription } from 'rxjs';
+import {NGX_ECHARTS_CONFIG, NgxEchartsModule} from "ngx-echarts";
+
+export interface IncomeData {
+  id: number;
+  year: string;
+  finesIncome: number;
+  ticketIncome: number;
+  totalIncome: number;
+}
+
+@Component({
+  selector: 'app-income-chart',
+  template: `
+    <div echarts [options]="chartOptions" class="chart"></div>`,
+  standalone: true,
+  imports: [NgxEchartsModule],
+  providers: [
+    {
+      provide: NGX_ECHARTS_CONFIG,
+      useFactory: () => ({ echarts: () => import('echarts') }),
+    },
+  ],
+  styles: [`
+    .chart {
+      width: 100%;
+      height: 400px;
+    }
+  `]
+})
+export class IncomeChartComponent implements OnInit, OnDestroy {
+  @Input() dataFn!: Observable<IncomeData[]>; // Required input
+
+  chartOptions: any;
+
+  ngOnInit(): void {
+    if (!this.dataFn) {
+      console.error('Input dataFn is required');
+      return;
+    }
+
+      this.dataFn.subscribe(data => {
+        console.log(data)
+        this.chartOptions = {
+          title: {
+            text: 'Yearly Income from Fines and Tickets',
+            left: 'center'
+          },
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: { type: 'shadow' }
+          },
+          legend: {
+            data: ['Fines Income', 'Ticket Income', 'Total Income'],
+            left: 'left'
+          },
+          xAxis: {
+            type: 'category',
+            data: data.sort((x, y) => Number(x.year) - Number(y.year)).map(d => d.year)
+          },
+          yAxis: {
+            type: 'value',
+            name: 'Income'
+          },
+          series: [
+            {
+              name: 'Fines Income',
+              type: 'bar',
+              stack: 'total',
+              data: data.map(d => d.finesIncome),
+              itemStyle: {
+                color: '#ff6f61'
+              }
+            },
+            {
+              name: 'Ticket Income',
+              type: 'bar',
+              stack: 'total',
+              data: data.map(d => d.ticketIncome),
+              itemStyle: {
+                color: '#61a0a8'
+              }
+            },
+            {
+              name: 'Total Income',
+              type: 'bar',
+              data: data.map(d => d.totalIncome),
+              itemStyle: {
+                color: '#c23531'
+              }
+            }
+          ]
+        };
+      }
+    );
+  }
+
+  ngOnDestroy(): void {
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,1 @@
+<p>commute works!</p>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/commute/commute.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-commute',
+  standalone: true,
+  imports: [],
+  templateUrl: './commute.component.html',
+  styleUrl: './commute.component.css'
+})
+export class CommuteComponent {
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+::ng-deep .mdc-notched-outline__notch {
+  border-right: none !important;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,41 @@
+<div class="w-full h-full flex justify-center items-center">
+
+  <div class="flex flex-col">
+
+
+      <form class="flex flex-col">
+
+        <mat-form-field [appearance]="'outline'">
+          <mat-label>Select ticket</mat-label>
+          <mat-select (selectionChange)="onTicketSelect($event)">
+            @for (t of tickets; track t.id) {
+              <mat-option [value]="t.id">{{ t.tip.ime }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+
+        <mat-form-field [appearance]="'outline'">
+          <mat-label>Select station</mat-label>
+          <mat-select (selectionChange)="onStationPick($event)">
+            @for (s of stations; track s.id) {
+              <mat-option [value]="s.id">{{ s.ime }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+
+        <mat-form-field [appearance]="'outline'">
+          <mat-label>Select route</mat-label>
+          <mat-select (selectionChange)="onInstancePick($event)">
+            @for (i of routeInstances; track i.id) {
+              <mat-option [value]="i.id">{{ i.line.ime + ' -> ' + i.direction.pravec }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+
+        <button mat-flat-button (click)="startCommute()">Start commute</button>
+
+      </form>
+
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/commutes/start-commute/start-commute.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,127 @@
+import {Component, OnInit} from '@angular/core';
+import {RouteInstanceService} from "../../../services/route-instance/route-instance.service";
+import {Station} from "../../../model/Station";
+import {RouteInstanceResponse} from "../../../model/responses/RouteInstanceResponse";
+import {StationService} from "../../../services/station/station.service";
+import {MatButton} from "@angular/material/button";
+import {MatFormField, MatLabel} from "@angular/material/form-field";
+import {MatOption} from "@angular/material/core";
+import {MatSelect, MatSelectChange} from "@angular/material/select";
+import {Subject, switchMap, tap} from "rxjs";
+import {CommuteService} from "../../../services/commute/commute.service";
+import {TicketService} from "../../../services/ticket/ticket.service";
+import {TicketResponse} from "../../../model/responses/TicketResponse";
+import {Router} from "@angular/router";
+import {log} from "@angular-devkit/build-angular/src/builders/ssr-dev-server";
+
+@Component({
+  selector: 'app-start-commute',
+  standalone: true,
+  imports: [
+    MatButton,
+    MatFormField,
+    MatLabel,
+    MatOption,
+    MatSelect
+  ],
+  templateUrl: './start-commute.component.html',
+  styleUrl: './start-commute.component.css'
+})
+export class StartCommuteComponent implements OnInit {
+  tickets: TicketResponse[] = []
+  stations: Station[] = []
+  routeInstances: RouteInstanceResponse[] = []
+
+  station: number | undefined;
+  instance: number | undefined;
+  ticket: number | undefined;
+
+  private _stationSelected$ = new Subject<number>();
+  private _instanceSelected$ = new Subject<number>();
+  private _ticketSelected$ = new Subject<number>();
+  private _startCommute$ = new Subject<void>();
+
+  constructor(private routeInstanceService: RouteInstanceService,
+              private stationService: StationService,
+              private commuteService: CommuteService,
+              private ticketService: TicketService,
+              private _router: Router,
+  ) {
+  }
+
+  ngOnInit(): void {
+    this.ticketService.getTickets().subscribe({
+      next: response => {
+        this.tickets = response
+        console.log(this.tickets)
+      }
+    })
+
+    this.stationService.getAllStations().subscribe({
+      next: response => {
+        this.stations = response;
+        console.log(this.stations)
+      }
+    })
+
+    this._stationSelected$.pipe(
+      switchMap(station => this.routeInstanceService.getForStation(station))
+    ).subscribe({
+      next: response => {
+        this.routeInstances = response;
+        console.log(response);
+      }
+    })
+    // todo: finish logic
+    this._startCommute$.pipe(
+      switchMap(() => {
+          console.log('in switch map');
+          return this.commuteService.startCommute({
+            stationId: this.station!!,
+            routeInstanceId: this.instance!!,
+            ticketId: this.ticket!!
+          });
+        }
+      )
+    ).subscribe({
+      next: response => {
+        console.log(response)
+      },
+      error: err => console.log(err)
+    })
+  }
+
+
+  onStationPick(event: MatSelectChange) {
+    this.station = event.value
+    if (this.station) this._stationSelected$.next(this.station)
+  }
+
+  onInstancePick(event: MatSelectChange) {
+    this.instance = event.value
+    if (this.instance) this._instanceSelected$.next(this.instance)
+  }
+
+  startCommute() {
+    console.log('starting commute');
+    console.log('ticket', this.ticket);
+    console.log('instance', this.instance);
+    console.log('station', this.station);
+    if (this.station && this.ticket && this.instance)
+      this.commuteService.startCommute({
+        stationId: this.station!!,
+        routeInstanceId: this.instance!!,
+        ticketId: this.ticket!!
+      }).pipe(
+        tap(res => console.log(res))
+      ).subscribe(res => {
+        console.log(res)
+        this._router.navigate(['/commutes', res.id])
+      })
+  }
+
+  onTicketSelect(event: MatSelectChange) {
+    this.ticket = event.value
+    if (this.ticket) this._ticketSelected$.next(this.ticket)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+::ng-deep .mdc-notched-outline__notch {
+  border-right: none !important;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,78 @@
+<div class="flex flex-col justify-center items-center">
+  <div class="w-full flex flex-col justify-center items-center p-10">
+    <h1 class="text-3xl p-5">Create new fine</h1>
+    <div class="w-1/3">
+      <form (ngSubmit)="onSubmit($event)" class="flex flex-wrap gap-x-5" [formGroup]="fineForm">
+        <mat-form-field>
+          <mat-label>Iznos</mat-label>
+          <input formControlName="iznos" matInput placeholder="1000" value="" type="number">
+        </mat-form-field>
+
+        <mat-checkbox class="w-1/3" formControlName="plateno">Plateno</mat-checkbox>
+
+        <mat-form-field>
+          <mat-label>Dokument</mat-label>
+          <input formControlName="dokument" matInput placeholder="DC-1234" value="" type="text">
+        </mat-form-field>
+
+        <mat-form-field (click)="onClick()" [appearance]="'outline'">
+          <mat-label>Select patnik (if is registered)</mat-label>
+          <mat-select formControlName="patnikId">
+            @for (passenger of passengers; track passenger.email) {
+              <mat-option [value]="passenger.id">{{ passenger.name }} -> {{ passenger.email }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+
+        <mat-form-field>
+          <mat-label>Telefon</mat-label>
+          <input formControlName="telefon" matInput placeholder="07x xxx xxx" value="" type="text">
+        </mat-form-field>
+
+        <mat-form-field>
+          <mat-label>Adresa</mat-label>
+          <input formControlName="adresa" matInput placeholder="ul. Jane Sandanski" value="" type="text">
+        </mat-form-field>
+
+        <mat-form-field>
+          <mat-label>Ime</mat-label>
+          <input formControlName="ime" matInput placeholder="Zoran Stojkovski" value="" type="text">
+        </mat-form-field>
+
+        <button class="w-3/4" type="submit" mat-flat-button>Create new fine</button>
+      </form>
+    </div>
+  </div>
+
+  <div class="relative overflow-x-auto">
+    <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
+      <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
+      <tr>
+        <th scope="col" class="px-6 py-3">#</th>
+        <th scope="col" class="px-6 py-3">Conductor</th>
+        <th scope="col" class="px-6 py-3">Passenger</th>
+        <th scope="col" class="px-6 py-3">Date Created</th>
+        <th scope="col" class="px-6 py-3">Payed</th>
+        <th scope="col" class="px-6 py-3">Date Payed</th>
+
+      </tr>
+      </thead>
+      <tbody>
+
+        @for (fine of fines; track fine.id) {
+          <tr>
+            <td class="px-6 py-4">
+              {{ fine.id }}
+            </td>
+            <td class="px-6 py-4">{{ fine.kondukter.name }}</td>
+            <td class="px-6 py-4">{{ fine.ime }}{{ fine.patnik?.name }}</td>
+            <td class="px-6 py-4">{{ fine.dateCreated }}</td>
+            <td class="px-6 py-4">{{ fine.plateno }}</td>
+            <td class="px-6 py-4">{{ fine.datePayed || 'not payed' }}</td>
+          </tr>
+        }
+      </tbody>
+    </table>
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/control/control.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,83 @@
+import {Component, OnInit} from '@angular/core';
+import {ActivatedRoute, Router} from "@angular/router";
+import {ControlsService} from "../../../services/controls/controls.service";
+import {FineResponse} from "../../../model/responses/FineResponse";
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
+import {MatOption} from "@angular/material/core";
+import {MatSelect} from "@angular/material/select";
+import {UserService} from "../../../services/user/user.service";
+import {UserResponse} from "../../../model/responses/UserResponse";
+import {MatButton} from "@angular/material/button";
+import {MatCheckbox} from "@angular/material/checkbox";
+import {FineRequest} from "../../../model/requests/FineRequest";
+import {FineService} from "../../../services/fine/fine.service";
+import {Subject, switchMap} from "rxjs";
+
+@Component({
+  selector: 'app-control',
+  standalone: true,
+  imports: [
+    FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, MatOption, MatSelect, MatButton, MatCheckbox
+  ],
+  templateUrl: './control.component.html',
+  styleUrl: './control.component.css'
+})
+export class ControlComponent implements OnInit {
+  controlId: number = +this.route.snapshot.paramMap.get('id')!!;
+  fines: FineResponse[] = []
+  passengers: UserResponse[] = []
+
+  fineForm: FormGroup = new FormGroup({
+    dokument: new FormControl(null, [Validators.required]),
+    plateno: new FormControl(null, [Validators.required]),
+    iznos: new FormControl(null, [Validators.required]),
+    patnikId: new FormControl(null, []),
+    telefon: new FormControl(null, []),
+    ime: new FormControl(null, []),
+    adresa: new FormControl(null, []),
+    kontrolaId: new FormControl(this.controlId, []),
+  })
+  private refreshFines$ = new Subject<void>();
+
+  constructor(private route: ActivatedRoute, private router: Router,
+              private controlsService: ControlsService,
+              private userService: UserService,
+              private fineService: FineService) {
+  }
+
+  ngOnInit(): void {
+    this.controlId = +this.route.snapshot.paramMap.get('id')!!
+    this.refreshFines$.pipe(
+      switchMap(() => this.controlsService.getControlInfo(this.controlId))
+    ).subscribe({
+      next: response => {
+        this.fines = response
+      }
+    })
+    this.refreshFines$.next()
+  }
+
+
+  onClick() {
+    this.userService.getAllPassengers().subscribe(
+      res => {
+        this.passengers = res;
+      }
+    )
+  }
+
+  protected readonly onsubmit = onsubmit;
+
+  onSubmit($event: any) {
+    console.log($event)
+    console.log(this.fineForm.value)
+    this.fineService.createFine(this.fineForm.value as FineRequest).subscribe({
+      next: res => {
+        console.log(res)
+        this.refreshFines$.next()
+      }
+    })
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+::ng-deep .mdc-notched-outline__notch {
+  border-right: none !important;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,51 @@
+<div class="w-full h-full flex flex-col justify-center items-center">
+
+  <div>
+    <div>
+      <mat-form-field (click)="onClick()" [appearance]="'outline'">
+        <mat-label>Select instance</mat-label>
+        <mat-select (selectionChange)="onInstancePick($event)">
+          @for (instance of instances; track instance.id) {
+            <mat-option [value]="instance.id">{{ instance.line.ime }} -> {{instance.direction.pravec}}</mat-option>
+          }
+        </mat-select>
+      </mat-form-field>
+    </div>
+
+      <button mat-flat-button (click)="onStart()">
+        Start new
+      </button>
+
+
+  </div>
+
+
+  <div class="relative overflow-x-auto">
+    <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
+      <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
+      <tr>
+        <th scope="col" class="px-6 py-3">Link</th>
+        <th scope="col" class="px-6 py-3">Conductor</th>
+        <th scope="col" class="px-6 py-3">Route Instance</th>
+        <th scope="col" class="px-6 py-3">Date Created</th>
+
+      </tr>
+      </thead>
+      <tbody>
+
+        @for (control of controls; track control.id) {
+          <tr>
+            <td class="px-6 py-4" [routerLink]="[control.id]">
+              <a class="text-blue-700 cursor-pointer">Go to control</a>
+            </td>
+            <td class="px-6 py-4">{{control.kondukter.name}}</td>
+            <td class="px-6 py-4">{{control.instancaNaLinija.line.ime}} - {{control.instancaNaLinija.direction.pravec}} - {{control.instancaNaLinija.driver.name}}</td>
+            <td class="px-6 py-4">{{control.dateCreated}}</td>
+          </tr>
+        }
+      </tbody>
+    </table>
+  </div>
+
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/controls/controls.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,61 @@
+import {Component, OnInit} from '@angular/core';
+import {ControlsService} from "../../../services/controls/controls.service";
+import {ControlsResponse} from "../../../model/responses/ControlsResponse";
+import {Router, RouterLink} from "@angular/router";
+import {MatButton} from "@angular/material/button";
+import {MatFormField, MatLabel} from "@angular/material/form-field";
+import {MatOption} from "@angular/material/core";
+import {MatSelect, MatSelectChange} from "@angular/material/select";
+import {RouteInstanceService} from "../../../services/route-instance/route-instance.service";
+import {RouteInstanceResponse} from "../../../model/responses/RouteInstanceResponse";
+
+@Component({
+  selector: 'app-controls',
+  standalone: true,
+  imports: [
+    RouterLink,
+    MatButton,
+    MatFormField,
+    MatLabel,
+    MatOption,
+    MatSelect
+  ],
+  templateUrl: './controls.component.html',
+  styleUrl: './controls.component.css'
+})
+export class ControlsComponent implements OnInit {
+  controls: ControlsResponse[] = []
+  instances: RouteInstanceResponse[] = []
+
+  instanceId: number | undefined;
+
+  constructor(private _controlsService: ControlsService,
+              private _routeInstanceService: RouteInstanceService,
+              private router: Router) {
+  }
+
+  ngOnInit() {
+    this._controlsService.getControls().subscribe(controls => {
+      this.controls = controls
+    })
+
+
+  }
+
+  onClick() {
+    this._routeInstanceService.getAll().subscribe(instances => this.instances = instances)
+  }
+
+  onInstancePick(event: MatSelectChange) {
+    this.instanceId = event.value
+  }
+
+  onStart() {
+    if (this.instanceId) {
+      this._controlsService.start(this.instanceId).subscribe(response => {
+        console.log(response);
+        this.router.navigate(['/controls', response.id])
+      })
+    }
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,1 @@
+<p>start-ccontrol works!</p>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/controls/start-ccontrol/start-ccontrol.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-start-ccontrol',
+  standalone: true,
+  imports: [],
+  templateUrl: './start-ccontrol.component.html',
+  styleUrl: './start-ccontrol.component.css'
+})
+export class StartCcontrolComponent {
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,1 @@
+<p>footer works!</p>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FooterComponent } from './footer.component';
+
+describe('FooterComponent', () => {
+  let component: FooterComponent;
+  let fixture: ComponentFixture<FooterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [FooterComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(FooterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/footer/footer.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-footer',
+  standalone: true,
+  imports: [],
+  templateUrl: './footer.component.html',
+  styleUrl: './footer.component.css'
+})
+export class FooterComponent {
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+<div>
+  @if (additionalInfo) {
+    <div class="flex items-center justify-between">
+      <label [for]="id" class="block text-sm font-medium leading-6 text-gray-900">{{label}}</label>
+      <div class="text-sm">
+        <a href="#" class="font-semibold text-indigo-600 hover:text-indigo-500">{{additionalInfo}}</a>
+      </div>
+
+    </div>
+  } @else {
+    <label [for]="id" class="block text-sm font-medium leading-6 text-gray-900">{{label}}</label>
+  }
+
+  <div class="mt-2">
+    <input #input (input)="handleInput(input.value)" [id]="id" [name]="name" [type]="type" [placeholder]="placeholder" [autocomplete]="autocomplete"  [required]="required" [class]="customClass">
+  </div>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { InputFieldComponent } from './input-field.component';
+
+describe('InputFieldComponent', () => {
+  let component: InputFieldComponent;
+  let fixture: ComponentFixture<InputFieldComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [InputFieldComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(InputFieldComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/input-field/input-field.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,25 @@
+import {Component, EventEmitter, Input, Output} from '@angular/core';
+
+@Component({
+  selector: 'app-input-field',
+  standalone: true,
+  imports: [],
+  templateUrl: './input-field.component.html',
+  styleUrl: './input-field.component.css'
+})
+export class InputFieldComponent {
+  @Input() name: string | undefined;
+  @Input() type: string | undefined;
+  @Input() placeholder: string | undefined;
+  @Input() id: string | undefined;
+  @Input() customClass: string | undefined;
+  @Input() required: boolean | undefined;
+  @Input() autocomplete: string | undefined;
+  @Input() label: string | undefined;
+  @Input() additionalInfo: string | undefined;
+  @Output() onInputChange: EventEmitter<string | undefined> = new EventEmitter();
+
+  handleInput(value: string) {
+    this.onInputChange.emit(value)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,51 @@
+<!--
+  This example requires some changes to your config:
+
+  ```
+  // tailwind.config.js
+  module.exports = {
+    // ...
+    plugins: [
+      // ...
+      require('@tailwindcss/forms'),
+    ],
+  }
+  ```
+-->
+<!--
+  This example requires updating your template:
+
+  ```
+  <html class="h-full bg-white">
+  <body class="h-full">
+  ```
+-->
+<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
+  <div class="sm:mx-auto sm:w-full sm:max-w-sm">
+    <img class="mx-auto h-10 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="Your Company">
+    <h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Sign in to your account</h2>
+  </div>
+
+  <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
+    <form [formGroup]="form" class="space-y-6" (ngSubmit)="onSubmit($event)">
+      <mat-form-field appearance="outline">
+        <label>Email</label>
+        <input matInput formControlName="email" placeholder="john.doe@example.com">
+      </mat-form-field>
+
+      <mat-form-field appearance="outline">
+        <label>Password</label>
+        <input  matInput [type]="'password'" formControlName="password">
+      </mat-form-field>
+
+      <div>
+        <input [disabled]="form.invalid || form.pristine" value="Sign in" type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
+      </div>
+    </form>
+
+    <p class="mt-10 text-center text-sm text-gray-500">
+      Not a member?
+      <a [routerLink]="['/register']" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Register now!</a>
+    </p>
+  </div>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/login/login.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,56 @@
+import { Component } from '@angular/core';
+import {
+  FormControl,
+  FormGroupDirective,
+  NgForm,
+  Validators,
+  FormsModule,
+  ReactiveFormsModule, FormGroup,
+} from '@angular/forms';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {ErrorStateMatcher} from "@angular/material/core";
+import {Router, RouterLink} from "@angular/router";
+import {InputFieldComponent} from "../input-field/input-field.component";
+import {AuthService} from "../../services/auth/auth.service";
+import {AuthRequest} from "../../model/requests/AuthRequest";
+import {tap} from "rxjs";
+@Component({
+  standalone: true,
+  imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, RouterLink, InputFieldComponent],
+  templateUrl: './login.component.html',
+})
+export class LoginComponent {
+
+  form: FormGroup = new FormGroup({
+    email: new FormControl('', [Validators.required, Validators.email]),
+    password: new FormControl('', [Validators.required]),
+  })
+
+  constructor(
+    private router: Router,
+    private service: AuthService
+  ) {
+  }
+
+  onSubmit($event: Event) {
+    console.log(this.form.value as AuthRequest)
+      this.service.login(this.form.value as AuthRequest)
+        .pipe(
+          tap(result => {
+            console.log(result)
+            sessionStorage.setItem('jwt', result.token);
+            this.service.refreshAuth$.next(true);
+          })
+        )
+        .subscribe({
+        next: result => {
+          this.router.navigate(['/'])
+        },
+        error: error => {
+          sessionStorage.removeItem('jwt');
+        }
+      })
+  }
+}
+
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,24 @@
+<div class="w-full flex justify-center items-center h-[100px] bg-gray-300">
+  <div class="w-4/5 flex justify-between">
+    <div class="flex gap-4">
+      <a [routerLink]="['tickets']">Tickets</a>
+      <a [routerLink]="['route-instances', 'start']">Start Route</a>
+      <a [routerLink]="['commutes', 'start']">Commute</a>
+      <a [routerLink]="['controls']">Controls</a>
+      <a [routerLink]="['admin']">Admin Panel</a>
+    </div>
+    <div>
+      @if (user) {
+        <button mat-button [matMenuTriggerFor]="menu">{{user.email}}</button>
+        <mat-menu #menu="matMenu">
+          <button (click)="signOut()" mat-menu-item>Sign out</button>
+          <button mat-menu-item>Item 2</button>
+        </mat-menu>
+      } @else {
+        <a [routerLink]="['login']">
+          <button mat-flat-button>Log in</button>
+        </a>
+      }
+    </div>
+  </div>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/navigation/navigation.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,66 @@
+import {Component, OnInit} from '@angular/core';
+import {AuthService} from "../../services/auth/auth.service";
+import {Router, RouterLink} from "@angular/router";
+import {switchMap} from "rxjs";
+import {UserResponse} from "../../model/responses/UserResponse";
+import {UserService} from "../../services/user/user.service";
+import {MatMenuModule} from '@angular/material/menu';
+import {MatButtonModule} from '@angular/material/button';
+
+@Component({
+  selector: 'app-navigation',
+  standalone: true,
+  imports: [
+    RouterLink, MatButtonModule, MatMenuModule
+  ],
+  templateUrl: './navigation.component.html',
+})
+export class NavigationComponent implements OnInit {
+
+  constructor(
+    private _authService: AuthService,
+    private _router: Router,
+    private _userService: UserService,
+  ) {
+  }
+
+  user: UserResponse | undefined
+
+  ngOnInit(): void {
+    this._authService.refreshAuth$.pipe(
+      switchMap(auth => this._userService.getUser())
+    ).subscribe({
+      next: user => {
+        console.log(user)
+        this.user = user
+      },
+      error: err => {
+        this.user = undefined
+      }
+    })
+
+    this._userService.getUser().subscribe({
+      next: user => {
+        this.user = user
+      }
+    })
+  }
+
+  isMenuOpen = false;
+  isIconMenuOpen = false;
+
+  changeMenuState() {
+    console.log('changeMenuState');
+    this.isMenuOpen = !this.isMenuOpen;
+  }
+
+  changeIconMenuState() {
+    console.log('changeIconMenuState');
+    this.isIconMenuOpen = !this.isIconMenuOpen;
+  }
+
+  signOut() {
+    sessionStorage.clear()
+    this._authService.refreshAuth$.next(false)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,37 @@
+
+<div class="w-full h-full flex justify-center items-center">
+  <form [formGroup]="form" class="flex flex-col w-1/2" (ngSubmit)="onSubmit()">
+
+  <mat-form-field appearance="outline">
+    <label>Full Name</label>
+    <input matInput formControlName="name" placeholder="John Doe">
+  </mat-form-field>
+
+  <mat-form-field appearance="outline">
+    <label>Email</label>
+    <input matInput formControlName="email" placeholder="john.doe@example.com">
+  </mat-form-field>
+
+  <mat-form-field appearance="outline">
+    <label>Password</label>
+    <input matInput type="password" formControlName="password">
+  </mat-form-field>
+
+  <mat-form-field appearance="outline">
+    <label>Confirm Password</label>
+    <input matInput type="password" formControlName="confirmPassword">
+  </mat-form-field>
+
+  <mat-form-field appearance="outline">
+    <label>Address</label>
+    <input matInput formControlName="address" placeholder="str. Dame Gruev 12">
+  </mat-form-field>
+
+  <mat-form-field appearance="outline">
+    <label>Phone</label>
+    <input matInput formControlName="phoneNumber" placeholder="+3897xxxxxxx">
+  </mat-form-field>
+
+    <button mat-flat-button>Register</button>
+</form>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/register/register.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,82 @@
+import { Component } from '@angular/core';
+import {MatFormField} from "@angular/material/form-field";
+import {MatInput} from "@angular/material/input";
+import {MatButtonModule} from "@angular/material/button";
+import {
+  AbstractControl,
+  Form,
+  FormControl,
+  FormGroup,
+  ReactiveFormsModule,
+  ValidationErrors,
+  ValidatorFn,
+  Validators
+} from "@angular/forms";
+import {AuthService} from "../../services/auth/auth.service";
+import {RegisterRequest} from "../../model/requests/RegisterRequest";
+import {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-register',
+  standalone: true,
+  imports: [
+    MatFormField,
+    MatInput,
+    ReactiveFormsModule,
+    MatButtonModule,
+  ],
+  templateUrl: './register.component.html',
+  styleUrl: './register.component.css'
+})
+export class RegisterComponent {
+
+  form: FormGroup = new FormGroup({
+    email: new FormControl('', [Validators.required, Validators.email]),
+    password: new FormControl('', [Validators.required]),
+    phoneNumber: new FormControl('', [Validators.required]),
+    name  : new FormControl('', [Validators.required]),
+    address: new FormControl('', [Validators.required]),
+    confirmPassword: new FormControl('', [Validators.required])
+  },
+    {
+      validators: this.matchValidator('password', 'confirmPassword')
+    })
+
+  constructor(private authService: AuthService, private router: Router) {
+  }
+
+  matchValidator(controlName: string, matchingControlName: string): ValidatorFn {
+    return (abstractControl: AbstractControl) => {
+      const control = abstractControl.get(controlName);
+      const matchingControl = abstractControl.get(matchingControlName);
+
+      if (matchingControl!.errors && !matchingControl!.errors?.['confirmedValidator']) {
+        return null;
+      }
+
+      if (control!.value !== matchingControl!.value) {
+        const error = { confirmedValidator: 'Passwords do not match.' };
+        matchingControl!.setErrors(error);
+        return error;
+      } else {
+        matchingControl!.setErrors(null);
+        return null;
+      }
+    }
+
+
+  }
+
+  onSubmit() {
+    this.authService.register(this.form.value as RegisterRequest).subscribe({
+      next: response => {
+        console.log(response)
+        sessionStorage.setItem('jwt', response.token);
+        this.authService.refreshAuth$.next(true);
+        this.router.navigate(['/'])
+      }
+      }
+    )
+  }
+}
+
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+<div class="flex justify-center items-center w-full h-full">
+
+  {{this.routeInstance?.id}}
+  {{routeInstance?.driver?.email}}
+  <div>
+    {{routeInstance?.end}}
+  </div>
+  <div>
+    <button [disabled]="routeInstance?.end" mat-flat-button (click)="endInstance()">
+      End instance
+    </button>
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/route-instance/route-instance.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,41 @@
+import {Component, OnInit} from '@angular/core';
+import {ActivatedRoute} from "@angular/router";
+import {RouteInstanceService} from "../../../services/route-instance/route-instance.service";
+import {RouteInstanceResponse} from "../../../model/responses/RouteInstanceResponse";
+import {MatButton} from "@angular/material/button";
+
+@Component({
+  selector: 'app-route-instance',
+  standalone: true,
+  imports: [
+    MatButton
+  ],
+  templateUrl: './route-instance.component.html',
+})
+export class RouteInstanceComponent implements OnInit {
+  routeInstance: RouteInstanceResponse | undefined
+
+  constructor(private route: ActivatedRoute,
+              private routeInstanceService: RouteInstanceService,) {
+  }
+
+  ngOnInit(): void {
+    const routeInstanceId: number = +this.route.snapshot.paramMap.get('id')!
+    this.routeInstanceService.getById(routeInstanceId).subscribe({
+      next: response => {
+        this.routeInstance = response
+      }
+    })
+
+  }
+
+  endInstance() {
+    if (this.routeInstance) {
+      this.routeInstanceService.stop(this.routeInstance.id).subscribe({
+        next: response => {
+          this.routeInstance = response
+        }
+      })
+    }
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+::ng-deep .mdc-notched-outline__notch {
+  border-right: none !important;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,52 @@
+<div class="w-full h-full flex justify-center items-center">
+
+  <div class="flex flex-col">
+
+    @if (isDriverFree) {
+      <form class="flex flex-col">
+
+        <mat-form-field [appearance]="'outline'">
+          <mat-label>Select bus</mat-label>
+          <mat-select (selectionChange)="onBusPick($event)">
+            @for (bus of buses; track bus.id) {
+              <mat-option [value]="bus.id">{{ bus.registracija }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+
+
+        @if (bus) {
+          <mat-form-field [appearance]="'outline'">
+            <mat-label>Select line</mat-label>
+            <mat-select (selectionChange)="onLinePick($event)">
+              @for (line of lines; track line.id) {
+                <mat-option [value]="line.id">{{ line.ime }}</mat-option>
+              }
+            </mat-select>
+          </mat-form-field>
+        }
+
+        @if (line) {
+          <mat-form-field [appearance]="'outline'">
+            <mat-label>Select direction</mat-label>
+            <mat-select (selectionChange)="onDirectionPick($event)">
+              @for (direction of directions; track direction.id) {
+                <mat-option [value]="direction.id">{{ direction.pravec }}</mat-option>
+              }
+            </mat-select>
+          </mat-form-field>
+        }
+
+        <button (click)="onSubmit()" type="button" mat-flat-button>
+          Start
+        </button>
+      </form>
+    } @else {
+      <div>
+        Currently logged in driver is busy!
+      </div>
+
+    }
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/route-instances/start-route-instnace/start-route-instance.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,111 @@
+import {Component, OnInit} from '@angular/core';
+import {LineService} from "../../../services/line/line.service";
+import {BusService} from "../../../services/bus/bus.service";
+import {DirectionService} from "../../../services/direction/direction.service";
+import {Bus} from "../../../model/Bus";
+import {MatButton} from "@angular/material/button";
+import {MatFormField, MatLabel} from "@angular/material/form-field";
+import {MatOption} from "@angular/material/core";
+import {MatSelect, MatSelectChange} from "@angular/material/select";
+import {filter, Subject, switchMap, tap} from "rxjs";
+import {Line} from "../../../model/Line";
+import {Direction} from "../../../model/Direction";
+import {RouteInstanceService} from "../../../services/route-instance/route-instance.service";
+import {Router} from "@angular/router";
+import {AuthService} from "../../../services/auth/auth.service";
+import {log} from "@angular-devkit/build-angular/src/builders/ssr-dev-server";
+
+@Component({
+  selector: 'app-start-route-instnace',
+  standalone: true,
+  imports: [
+    MatButton,
+    MatFormField,
+    MatLabel,
+    MatOption,
+    MatSelect
+  ],
+  templateUrl: './start-route-instance.component.html',
+  styleUrl: './start-route-instance.component.css'
+})
+export class StartRouteInstanceComponent implements OnInit {
+  buses: Bus[] = []
+  lines: Line[] = []
+  directions: Direction[] = []
+  isDriverFree = false
+
+  bus: Bus | undefined
+  line: Line | undefined
+  direction: Direction | undefined
+
+  private _busSelected$ = new Subject<Bus>();
+  private _lineSelected$ = new Subject<Line>();
+
+  constructor(
+    private _lineService: LineService,
+    private _busService: BusService,
+    private _directionService: DirectionService,
+    private _routeInstanceService: RouteInstanceService,
+    private _router: Router,
+    private _authService: AuthService
+  ) {
+  }
+
+  ngOnInit(): void {
+
+    this._authService.isDriverFree().pipe(
+      tap(x => console.log(x)),
+      tap(isDriverFree => this.isDriverFree = isDriverFree),
+      filter(isDriverFree => isDriverFree === true),
+      switchMap(_ => this._busService.getAllFree())
+    ).subscribe({
+      next: response => {
+        console.log('free buses', response)
+        this.buses = response
+      }
+    })
+
+    this._busSelected$.pipe(
+      switchMap(bus => this._lineService.getAll())
+    ).subscribe({
+      next: response => {
+        this.lines = response
+      }
+    })
+    this._lineSelected$.pipe(
+      switchMap(line => this._lineService.getDirections(line))
+    ).subscribe({
+      next: response => {
+        this.directions = response.map(x => x.pravec)
+        console.log(response)
+      }
+    })
+  }
+
+  onBusPick($event: MatSelectChange) {
+    this.bus = this.buses.find(bus => bus.id === $event.value)
+    if (this.bus) this._busSelected$.next(this.bus)
+  }
+
+  onLinePick($event: MatSelectChange) {
+    this.line = this.lines.find(line => line.id === $event.value)
+    if (this.line) this._lineSelected$.next(this.line)
+  }
+
+  onDirectionPick($event: MatSelectChange) {
+    this.direction = this.directions.find(direction => direction.id === $event.value)
+  }
+
+  onSubmit() {
+    if (this.bus && this.line && this.direction)
+      this._routeInstanceService.start({
+        lineId: this.line.id,
+        busId: this.bus.id,
+        directionId: this.direction.id,
+      }).subscribe({
+        next: response => {
+          this._router.navigate(['/route-instances', response.id])
+        }
+      })
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+<div>
+  <mat-card appearance="outlined">
+    <mat-card-header>
+      <mat-card-title> {{ticket?.tip?.ime}}</mat-card-title>
+      <mat-card-subtitle>Duration: {{ticket?.tip?.trajnost}}</mat-card-subtitle>
+      <mat-card-subtitle>Date of buying: {{ticket?.datumKupuvanje}}</mat-card-subtitle>
+      <mat-card-subtitle>Date of activation: {{ticket?.datumAktivacija}}</mat-card-subtitle>
+    </mat-card-header>
+    <mat-card-actions>
+      <div class="w-full flex justify-between">
+        <button mat-button>Learn More</button>
+        <button mat-flat-button [disabled]="this.ticket?.datumAktivacija" (click)="activateTicket()">Activate</button>
+
+      </div>
+    </mat-card-actions>
+  </mat-card>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/ticket/ticket.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,37 @@
+import {Component, Input} from '@angular/core';
+import { TicketResponse } from '../../model/responses/TicketResponse';
+import {MatButtonModule} from '@angular/material/button';
+import {MatCardModule} from '@angular/material/card';
+import {TicketService} from "../../services/ticket/ticket.service";
+import {Router} from "@angular/router";
+import {MatSnackBar} from '@angular/material/snack-bar';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+
+
+@Component({
+  selector: 'app-ticket',
+  standalone: true,
+  imports: [MatCardModule, MatButtonModule],
+  templateUrl: './ticket.component.html',
+})
+export class TicketComponent {
+  @Input() ticket: TicketResponse | undefined;
+
+  constructor(private service: TicketService, private router: Router, private _snackBar: MatSnackBar) {
+  }
+
+  activateTicket() {
+    if(this.ticket) {
+      this.service.activateTicket(this.ticket.id).subscribe({
+        next: () => {
+          this.openSnackBar("Ticket successfully activated!", "Okay");
+        }
+      })
+    }
+  }
+
+  openSnackBar(message: string, action: string) {
+    this._snackBar.open(message, action);
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+::ng-deep .mdc-notched-outline__notch {
+  border-right: none !important;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+<div class="flex justify-center items-center">
+  <div class="flex flex-col">
+
+    <form class="flex flex-col">
+      <mat-form-field [appearance]="'outline'">
+        <mat-label>Select</mat-label>
+        <mat-select (selectionChange)="onPick($event)">
+          @for (type of types; track type.id) {
+            <mat-option [value]="type.id">{{type.ime}} - {{type.cena}}</mat-option>
+          }
+        </mat-select>
+      </mat-form-field>
+
+      <button (click)="onSubmit()" type="button" mat-flat-button>
+        Buy
+      </button>
+    </form>
+  </div>
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-buy/tickets-buy.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,50 @@
+import {Component, OnInit} from '@angular/core';
+import {MatSelectChange, MatSelectModule} from '@angular/material/select';
+import {MatInputModule} from '@angular/material/input';
+import {MatFormFieldModule} from '@angular/material/form-field';
+import {TicketTypeService} from "../../services/ticket-type/ticket-type.service";
+import {Tipbilet} from "../../model/Tipbilet";
+import {MatButtonModule} from '@angular/material/button';
+import {TicketService} from "../../services/ticket/ticket.service";
+
+@Component({
+  selector: 'app-tickets-buy',
+  standalone: true,
+  imports: [MatFormFieldModule, MatInputModule, MatSelectModule, MatButtonModule],
+  templateUrl: './tickets-buy.component.html',
+  styleUrl: './tickets-buy.component.css'
+})
+export class TicketsBuyComponent implements OnInit {
+  types: Tipbilet[] = []
+  selectedType: number | undefined;
+
+  constructor(private ticketTypesService: TicketTypeService, private ticketService: TicketService) {
+  }
+
+  ngOnInit(): void {
+    this.ticketTypesService.getTypes().subscribe({
+      next: response => {
+        console.log(response)
+        this.types = response
+      }
+    })
+  }
+
+  protected readonly onsubmit = onsubmit;
+
+  onSubmit() {
+    if (this.selectedType)
+      this.ticketService.buyTicket({
+        type: this.selectedType,
+      }).subscribe({
+        next: response => {
+          console.log(response)
+        }
+      })
+  }
+
+  onPick($event: MatSelectChange) {
+    console.log($event)
+    this.selectedType = $event.value
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+<div class="flex justify-center items-center flex-col">
+  <div>Tickets</div>
+  <div>
+    <button mat-flat-button>
+      <a [routerLink]="['buy']">Buy Ticket</a>
+    </button>
+  </div>
+
+  <div>
+    @for (ticket of tickets; track ticket.id) {
+      <app-ticket [ticket]="ticket"></app-ticket>
+    }
+  </div>
+
+</div>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/components/tickets-page/tickets-page.component.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,34 @@
+import {Component, OnInit} from '@angular/core';
+import {TicketService} from "../../services/ticket/ticket.service";
+import {TicketResponse} from "../../model/responses/TicketResponse";
+import {TicketComponent} from "../ticket/ticket.component";
+import {RouterLink} from "@angular/router";
+import {MatButton, MatButtonModule} from "@angular/material/button";
+
+@Component({
+  selector: 'app-tickets-page',
+  standalone: true,
+  imports: [
+    TicketComponent,
+    RouterLink,
+    MatButtonModule
+  ],
+  templateUrl: './tickets-page.component.html',
+})
+export class TicketsPageComponent implements OnInit{
+
+  tickets: TicketResponse[] = []
+
+    constructor(private service: TicketService) {
+    }
+
+    ngOnInit(): void {
+        this.service.getTickets().subscribe({
+          next: response => {
+            console.log(response);
+            this.tickets = response
+          }
+        })
+    }
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+import { TestBed } from '@angular/core/testing';
+import { CanActivateFn } from '@angular/router';
+
+import { authCanmatchGuard } from './auth-canmatch.guard';
+
+describe('authCanmatchGuard', () => {
+  const executeGuard: CanActivateFn = (...guardParameters) => 
+      TestBed.runInInjectionContext(() => authCanmatchGuard(...guardParameters));
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+  });
+
+  it('should be created', () => {
+    expect(executeGuard).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth-canmatch.guard.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+import {CanActivateFn, Router} from '@angular/router';
+import {inject} from "@angular/core";
+import {AuthService} from "../services/auth/auth.service";
+
+export const authCanmatchGuard: CanActivateFn = (route, state) => {
+  let service = inject(AuthService);
+  let router = inject(Router)
+  if (service.isAuthenticated()) {
+    return true;
+  }
+  else {
+    router.navigate(['/login'])
+    return false;
+  }
+};
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+import { TestBed } from '@angular/core/testing';
+import { CanActivateFn } from '@angular/router';
+
+import { authGuard } from './auth.guard';
+
+describe('authGuard', () => {
+  const executeGuard: CanActivateFn = (...guardParameters) => 
+      TestBed.runInInjectionContext(() => authGuard(...guardParameters));
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+  });
+
+  it('should be created', () => {
+    expect(executeGuard).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/guards/auth.guard.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+import {CanActivateFn, Router} from '@angular/router';
+import {AuthService} from "../services/auth/auth.service";
+import {inject} from "@angular/core";
+
+export const authGuard: CanActivateFn = (route, state) => {
+  let service = inject(AuthService);
+  let router = inject(Router)
+  if (service.isAuthenticated()) {
+    return true;
+  }
+  else {
+    router.navigate(['/login'])
+    return false;
+  }
+};
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/interceptors/auth.interceptor.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/interceptors/auth.interceptor.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/interceptors/auth.interceptor.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+import {HttpInterceptorFn} from '@angular/common/http';
+
+export const authInterceptor: HttpInterceptorFn = (req, next) => {
+  const jwt = sessionStorage.getItem('jwt');
+  if (jwt && jwt.length > 0) {
+    const newReq = req.clone({
+      setHeaders: {
+        Authorization: `Bearer ${sessionStorage.getItem('jwt')}`,
+      },
+    });
+    return next(newReq);
+  }
+  return next(req);
+};
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Bus.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Bus.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Bus.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+export interface Bus {
+  id: number,
+  registracija: string,
+  seriskiBroj: string,
+  brojSedishta: number
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Direction.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Direction.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Direction.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+export interface Direction {
+  id: number,
+  pravec: string,
+  opis: string
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/FinesPerLine.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/FinesPerLine.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/FinesPerLine.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+import {Line} from "./Line";
+
+export interface FinesPerLine {
+  id: number,
+  line: Line,
+  count: number,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Line.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Line.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Line.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,4 @@
+export interface Line {
+  id: number,
+  ime: string
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineDirection.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineDirection.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineDirection.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+import {Line} from "./Line";
+import {Direction} from "./Direction";
+
+export interface LineDirection {
+  linija: Line;
+  pravec: Direction;
+  id: number;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineStation.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineStation.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/LineStation.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,11 @@
+import {Line} from "./Line";
+import {Station} from "./Station";
+import {Direction} from "./Direction";
+
+export interface LineStation {
+  id: number,
+  redenBroj: number,
+  linija: Line,
+  postojka: Station,
+  pravec: Direction,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/PieChartValues.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/PieChartValues.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/PieChartValues.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,4 @@
+export interface PieChartValues {
+  value: number;
+  name: string;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Station.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Station.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Station.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+export interface Station {
+  id: number,
+  ime: string,
+  lat: number,
+  lon: number,
+  opis: string,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Tipbilet.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Tipbilet.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/Tipbilet.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+export interface Tipbilet{
+  id: number,
+  trajnost: number,
+  cena: number,
+  ime: string
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/AuthRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/AuthRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/AuthRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,4 @@
+export interface AuthRequest {
+  email: string,
+  password: string,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/FineRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/FineRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/FineRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,10 @@
+export interface FineRequest {
+   iznos: number,
+   plateno: boolean,
+   dokument: string,
+   kontrolaId: number,
+   telefon: string | undefined,
+   ime: string | undefined,
+   adresa: string | undefined,
+   patnikId: number | undefined,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/RegisterRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/RegisterRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/RegisterRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+export interface RegisterRequest {
+  email: string;
+  password: string;
+  confirmPassword: string;
+  name: string;
+  address: string;
+  phoneNumber: string;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartCommuteRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartCommuteRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartCommuteRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+export interface StartCommuteRequest {
+  ticketId: number;
+  routeInstanceId: number;
+  stationId: number;
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartRouteInstanceRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartRouteInstanceRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/StartRouteInstanceRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+export interface StartRouteInstanceRequest {
+  lineId: number,
+  busId: number,
+  directionId: number,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/TicketBuyRequest.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/TicketBuyRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/requests/TicketBuyRequest.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+export interface TicketBuyRequest {
+  type: number
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AdminUsersResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AdminUsersResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AdminUsersResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+export interface AdminUsersResponse {
+  email: string
+  name: string
+  address: string
+  phoneNumber: string
+  id: number
+  roles: string[]
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AuthResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AuthResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/AuthResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,3 @@
+export interface AuthResponse {
+  token: string
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/CommuteResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/CommuteResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/CommuteResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,13 @@
+import {TicketResponse} from "./TicketResponse";
+import {UserResponse} from "./UserResponse";
+import {LineStation} from "../LineStation";
+
+export interface CommuteResponse {
+commuter: UserResponse,
+   ticket: TicketResponse,
+   stationStart: LineStation,
+   status: String,
+   startDate: Date,
+   endDate: Date | null,
+   id: number,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/ControlsResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/ControlsResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/ControlsResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+import {UserResponse} from "./UserResponse";
+import {RouteInstanceResponse} from "./RouteInstanceResponse";
+
+export interface ControlsResponse {
+  id: number,
+  dateCreated: Date,
+  kondukter: UserResponse,
+  instancaNaLinija: RouteInstanceResponse,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/FineResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/FineResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/FineResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+import {UserResponse} from "./UserResponse";
+import {ControlsResponse} from "./ControlsResponse";
+
+export interface FineResponse {
+    id: number,
+    iznos: number,
+    plateno: boolean,
+     dateCreated: Date,
+    datePayed: Date | undefined,
+    dokument: string,
+     kondukter: UserResponse,
+     kontrola: ControlsResponse,
+     patnik: UserResponse | undefined,
+    telefon: string | undefined,
+    ime: string | undefined,
+    adresa: string | undefined,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/RouteInstanceResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/RouteInstanceResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/RouteInstanceResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+import {Bus} from "../Bus";
+import {Direction} from "../Direction";
+import {Line} from "../Line";
+import {UserResponse} from "./UserResponse";
+
+export interface RouteInstanceResponse {
+  bus: Bus,
+  direction: Direction,
+  line: Line,
+  driver: UserResponse,
+  start: Date,
+  end: Date | undefined,
+  id: number
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/TicketResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/TicketResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/TicketResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+import {Tipbilet} from "../Tipbilet";
+
+export interface TicketResponse {
+  id: number,
+  datumKupuvanje: Date,
+  datumAktivacija: Date | undefined,
+  status: string,
+  tip: Tipbilet,
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/UserResponse.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/UserResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/model/responses/UserResponse.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+export interface UserResponse {
+  email: string
+  name: string
+  address: string
+  phoneNumber: string
+  id: number
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AdminService } from './admin.service';
+
+describe('AdminService', () => {
+  let service: AdminService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AdminService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/admin/admin.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,37 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {AdminUsersResponse} from "../../model/responses/AdminUsersResponse";
+import {FinesPerLine} from "../../model/FinesPerLine";
+import {CommutesByHour} from "../../components/charts/line-chart.component";
+import {IncomeData} from "../../components/charts/stacked-bar-chart.component";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AdminService {
+  private url = '/api/admin'
+  constructor(private http: HttpClient) { }
+
+  getAllUsers(): Observable<AdminUsersResponse[]> {
+    return this.http.get<AdminUsersResponse[]>(`${this.url}/all-users`)
+  }
+
+  updateRolesToUser(id: number, roles: string[]): Observable<AdminUsersResponse[]> {
+    return this.http.post<AdminUsersResponse[]>(`${this.url}/update-roles/${id}`, JSON.stringify(roles), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+
+  getFinesPerLine() {
+    return this.http.get<FinesPerLine[]>(`${this.url}/fines-by-line`);
+  }
+
+  getCommutesByHour() {
+    return this.http.get<CommutesByHour[]>(`${this.url}/commutes-by-hour`);
+  }
+
+  getTotalIncome() {
+    return this.http.get<IncomeData[]>(`${this.url}/total-income`);
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AuthService } from './auth.service';
+
+describe('AuthService', () => {
+  let service: AuthService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AuthService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/auth/auth.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,45 @@
+import { Injectable } from '@angular/core';
+import {Observable, Subject} from "rxjs";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {AuthResponse} from "../../model/responses/AuthResponse";
+import {AuthRequest} from "../../model/requests/AuthRequest";
+import {RegisterRequest} from "../../model/requests/RegisterRequest";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AuthService {
+  refreshAuth$ = new Subject<boolean>();
+  private url = '/api/auth';
+
+  constructor(private http: HttpClient) { }
+
+  login(authRequest: AuthRequest): Observable<AuthResponse> {
+    return this.http.post<AuthResponse>(
+      `${this.url}`,
+      JSON.stringify(authRequest),
+      {
+        headers: new HttpHeaders({ 'Content-Type': 'application/json' })
+      }
+    )
+  }
+
+  register(registerRequest: RegisterRequest): Observable<AuthResponse> {
+    return this.http.post<AuthResponse>(
+      `${this.url}/register`,
+      JSON.stringify(registerRequest),
+      {
+        headers: new HttpHeaders({ 'Content-Type': 'application/json' })
+      }
+    )
+  }
+
+  isAuthenticated(): Observable<boolean> {
+    return this.http.get<boolean>(`${this.url}`);
+  }
+
+  isDriverFree(): Observable<boolean> {
+    return this.http.get<boolean>(`${this.url}/is-driver-free`);
+  }
+
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { BusService } from './bus.service';
+
+describe('BusService', () => {
+  let service: BusService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(BusService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/bus/bus.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {HttpClient} from "@angular/common/http";
+import {Bus} from "../../model/Bus";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class BusService {
+  private _url = '/api/buses'
+  constructor(private _http: HttpClient) { }
+
+  getAll(): Observable<Bus[]> {
+    return this._http.get<Bus[]>(`${this._url}`)
+  }
+
+  getAllFree() {
+    return this._http.get<Bus[]>(`${this._url}/free`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CommuteService } from './commute.service';
+
+describe('CommuteService', () => {
+  let service: CommuteService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(CommuteService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/commute/commute.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,24 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {StartCommuteRequest} from "../../model/requests/StartCommuteRequest";
+import {Observable, tap} from "rxjs";
+import {CommuteResponse} from "../../model/responses/CommuteResponse";
+import {RouteInstanceResponse} from "../../model/responses/RouteInstanceResponse";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class CommuteService {
+
+  private url = '/api/commutes'
+
+  constructor(private http: HttpClient) { }
+
+  startCommute(request: StartCommuteRequest): Observable<CommuteResponse> {
+    return this.http.put<CommuteResponse>(`${this.url}/start`, JSON.stringify(request), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    }).pipe(
+      tap(res => console.log(res))
+    )
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ControlsService } from './controls.service';
+
+describe('ControlsService', () => {
+  let service: ControlsService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(ControlsService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/controls/controls.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,29 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {ControlsResponse} from "../../model/responses/ControlsResponse";
+import {FineResponse} from "../../model/responses/FineResponse";
+import {FineRequest} from "../../model/requests/FineRequest";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ControlsService {
+  private url = '/api/controls'
+
+  constructor(private http: HttpClient) { }
+
+  getControls(): Observable<ControlsResponse[]> {
+    return this.http.get<ControlsResponse[]>(`${this.url}`)
+  }
+
+  start(routeInstanceId: number): Observable<ControlsResponse> {
+    return this.http.put<ControlsResponse>(`${this.url}/start`, JSON.stringify(routeInstanceId), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+
+  getControlInfo(controlId: number): Observable<FineResponse[]> {
+    return this.http.get<FineResponse[]>(`${this.url}/${controlId}/fines`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DirectionService } from './direction.service';
+
+describe('DirectionService', () => {
+  let service: DirectionService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DirectionService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/direction/direction.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class DirectionService {
+
+  constructor() { }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DriverService } from './driver.service';
+
+describe('DriverService', () => {
+  let service: DriverService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DriverService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/driver/driver.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class DriverService {
+  private url = '/api/drivers'
+  constructor() { }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { FineService } from './fine.service';
+
+describe('FineService', () => {
+  let service: FineService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(FineService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/fine/fine.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {FineResponse} from "../../model/responses/FineResponse";
+import {FineRequest} from "../../model/requests/FineRequest";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class FineService {
+  private url = '/api/fines'
+
+  constructor(private http: HttpClient) { }
+
+  createFine(request: FineRequest): Observable<FineResponse> {
+    return this.http.put<FineResponse>(`${this.url}`, JSON.stringify(request), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { LineService } from './line.service';
+
+describe('LineService', () => {
+  let service: LineService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(LineService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/line/line.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,22 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {HttpClient} from "@angular/common/http";
+import {Line} from "../../model/Line";
+import {Direction} from "../../model/Direction";
+import {LineDirection} from "../../model/LineDirection";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class LineService {
+  private url = '/api/lines'
+  constructor(private _http: HttpClient) { }
+
+  getAll(): Observable<Line[]> {
+    return this._http.get<Line[]>(`${this.url}`)
+  }
+
+  getDirections(line: Line): Observable<LineDirection[]> {
+    return this._http.get<LineDirection[]>(`${this.url}/${line.id}/directions`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { RouteInstanceService } from './route-instance.service';
+
+describe('RouteInstanceService', () => {
+  let service: RouteInstanceService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(RouteInstanceService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/route-instance/route-instance.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,41 @@
+import {Injectable} from '@angular/core';
+import {Observable} from "rxjs";
+import {StartRouteInstanceRequest} from "../../model/requests/StartRouteInstanceRequest";
+import {RouteInstanceResponse} from "../../model/responses/RouteInstanceResponse";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {StartCommuteRequest} from "../../model/requests/StartCommuteRequest";
+import {CommuteResponse} from "../../model/responses/CommuteResponse";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class RouteInstanceService {
+  private url = '/api/route-instances'
+
+  constructor(private http: HttpClient) {
+  }
+
+  start(request: StartRouteInstanceRequest): Observable<RouteInstanceResponse> {
+    return this.http.post<RouteInstanceResponse>(`${this.url}/start`, JSON.stringify(request), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+
+  getById(id: number): Observable<RouteInstanceResponse> {
+    return this.http.get<RouteInstanceResponse>(`${this.url}/${id}`)
+  }
+
+  stop(id: number): Observable<RouteInstanceResponse> {
+    return this.http.patch<RouteInstanceResponse>(`${this.url}/stop`, JSON.stringify(id), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+
+  getForStation(id: number): Observable<RouteInstanceResponse[]> {
+    return this.http.get<RouteInstanceResponse[]>(`${this.url}/station/${id}`)
+  }
+
+  getAll(): Observable<RouteInstanceResponse[]> {
+    return this.http.get<RouteInstanceResponse[]>(`${this.url}`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { StationService } from './station.service';
+
+describe('StationService', () => {
+  let service: StationService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(StationService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/station/station.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {Station} from "../../model/Station";
+import {HttpClient} from "@angular/common/http";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class StationService {
+  private url = '/api/stations'
+  constructor(private http: HttpClient) { }
+
+  getAllStations(): Observable<Station[]> {
+    return this.http.get<Station[]>(this.url);
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { TicketTypeService } from './ticket-type.service';
+
+describe('TicketTypeService', () => {
+  let service: TicketTypeService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TicketTypeService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket-type/ticket-type.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {Tipbilet} from "../../model/Tipbilet";
+import {HttpClient} from "@angular/common/http";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TicketTypeService {
+
+  private _url = '/api/ticket-types';
+
+  constructor(private http: HttpClient) { }
+
+  getTypes(): Observable<Tipbilet[]> {
+    return this.http.get<Tipbilet[]>(`${this._url}`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { TicketService } from './ticket.service';
+
+describe('TicketService', () => {
+  let service: TicketService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TicketService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/ticket/ticket.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,31 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {TicketBuyRequest} from "../../model/requests/TicketBuyRequest";
+import {TicketResponse} from "../../model/responses/TicketResponse";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class TicketService {
+
+  private _url = '/api/tickets'
+
+  constructor(private http: HttpClient) { }
+
+  getTickets(): Observable<TicketResponse[]> {
+    return this.http.get<TicketResponse[]>(`${this._url}`)
+  }
+
+  activateTicket(id: number): Observable<TicketResponse> {
+    return this.http.patch<TicketResponse>(`${this._url}/activate/${id}`, JSON.stringify({}), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+
+  buyTicket(request: TicketBuyRequest): Observable<TicketResponse> {
+    return this.http.post<TicketResponse>(`${this._url}/buy`, JSON.stringify(request), {
+      headers: new HttpHeaders({'Content-Type': 'application/json'})
+    })
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.spec.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.spec.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { UserService } from './user.service';
+
+describe('UserService', () => {
+  let service: UserService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(UserService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/app/services/user/user.service.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {UserResponse} from "../../model/responses/UserResponse";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class UserService {
+  private _url= '/api/users'
+
+  constructor(private _http: HttpClient) { }
+
+  getUser(): Observable<UserResponse | undefined> {
+    return this._http.get<UserResponse>(`${this._url}`)
+  }
+
+  getAllPassengers(): Observable<UserResponse[]> {
+    return this._http.get<UserResponse[]>(`${this._url}/passengers`)
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/index.html
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/index.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/index.html	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>BusNGoFrontend</title>
+  <base href="/">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+</head>
+<body>
+  <app-root></app-root>
+</body>
+</html>
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/main.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/main.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/main.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+import { bootstrapApplication } from '@angular/platform-browser';
+import { appConfig } from './app/app.config';
+import { AppComponent } from './app/app.component';
+
+bootstrapApplication(AppComponent, appConfig)
+  .catch((err) => console.error(err));
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/proxy.conf.json
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/proxy.conf.json	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/proxy.conf.json	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+{
+  "/api": {
+    "target": "http://localhost:8080",
+    "secure": false
+  }
+}
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/styles.css
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/styles.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/styles.css	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+/* You can add global styles to this file, and also import other style files */
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+html, body { height: 100%; }
+body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/typings.d.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/typings.d.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/typings.d.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,2 @@
+// declare module 'stompjs';
+// declare module 'sockjs-client';
Index: bus-n-go-pavel-216049/bus-n-go-frontend/src/window-global-fix.ts
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-frontend/src/window-global-fix.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-frontend/src/window-global-fix.ts	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,4 @@
+// (window as any).global = window;
+// (window as any).process = {
+//   env: { DEBUG: undefined },
+// };
