Index: Sources/frontend/src/app/ActiveUserInterface.ts
===================================================================
--- Sources/frontend/src/app/ActiveUserInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/ActiveUserInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,4 @@
+export interface ActiveUserInterface {
+  username: string;
+  userType: string;
+}
Index: Sources/frontend/src/app/AdminInterface.ts
===================================================================
--- Sources/frontend/src/app/AdminInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/AdminInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+export interface AdminInterface{
+  id: 1,
+  name: string,
+  lastName: string,
+  username: string,
+  email: string,
+  password: string
+}
Index: Sources/frontend/src/app/AnswerInterface.ts
===================================================================
--- Sources/frontend/src/app/AnswerInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/AnswerInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,13 @@
+import {QuestionInterface} from "./QuestionInterface";
+import {ProfessorInterface} from "./ProfessorInterface";
+import {StudentInterface} from "./StudentInterface";
+
+export interface AnswerInterface{
+  id:number,
+  content?: string,
+  valid?: string,
+  dateAnswered?: string,
+  question?: QuestionInterface,
+  professor?: ProfessorInterface,
+  student?: StudentInterface
+}
Index: Sources/frontend/src/app/IntervalInterface.ts
===================================================================
--- Sources/frontend/src/app/IntervalInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/IntervalInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,13 @@
+export interface IntervalInterface {
+  days:number,
+  hours:number,
+  microSeconds:number,
+  minutes:number,
+  months:number,
+  null:boolean,
+  seconds:number,
+  type:string,
+  value:string,
+  wholeSeconds:number,
+  years:number
+}
Index: Sources/frontend/src/app/ProfessorCourseInterface.ts
===================================================================
--- Sources/frontend/src/app/ProfessorCourseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/ProfessorCourseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+import {CourseInterface} from "./courseInterface";
+import {ProfessorInterface} from "./ProfessorInterface";
+
+export interface ProfessorCourseInterface{
+  id?: number,
+  professor: ProfessorInterface,
+  course: CourseInterface,
+}
Index: Sources/frontend/src/app/ProfessorInterface.ts
===================================================================
--- Sources/frontend/src/app/ProfessorInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/ProfessorInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+export interface ProfessorInterface{
+  id: number,
+  name: string,
+  lastName: string,
+  username: string,
+  email: string,
+  password: string,
+}
Index: Sources/frontend/src/app/Query1Interface.ts
===================================================================
--- Sources/frontend/src/app/Query1Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/Query1Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,9 @@
+export interface Query1Interface{
+  maximum: number,
+  pra_id: number,
+  pra_naslov: string,
+  pra_sodrzina: string,
+  pra_datum: string,
+  ku_id: number,
+  s_id: number
+}
Index: Sources/frontend/src/app/Query2Interface.ts
===================================================================
--- Sources/frontend/src/app/Query2Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/Query2Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,9 @@
+export interface Query2Interface{
+  pra_id: number,
+  pra_naslov: string,
+  pra_sodrzina: string,
+  pra_datum: string,
+  ku_id: number,
+  s_id: number,
+  sum: number
+}
Index: Sources/frontend/src/app/Query3Interface.ts
===================================================================
--- Sources/frontend/src/app/Query3Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/Query3Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,4 @@
+export interface Query3Interface{
+  korisnicko_ime: string,
+  vk: number
+}
Index: Sources/frontend/src/app/Query4Interface.ts
===================================================================
--- Sources/frontend/src/app/Query4Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/Query4Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,7 @@
+export interface Query4Interface{
+  pr_id: number,
+  pr_ime: string,
+  ku_ime: string,
+  br_isti_kategorii: number,
+  br_prasanja: number
+}
Index: Sources/frontend/src/app/Query5Interface.ts
===================================================================
--- Sources/frontend/src/app/Query5Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/Query5Interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,7 @@
+import {IntervalInterface} from "./IntervalInterface";
+
+export interface Query5Interface {
+  p_ime: number,
+  p_prezime: string,
+  najbrzo_vreme: IntervalInterface
+}
Index: Sources/frontend/src/app/QuestionInterface.ts
===================================================================
--- Sources/frontend/src/app/QuestionInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/QuestionInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,11 @@
+import {StudentInterface} from "./StudentInterface";
+import {CourseInterface} from "./courseInterface";
+
+export interface QuestionInterface{
+  id:number,
+  title:string,
+  content:string
+  dateAsked:string,
+  student:StudentInterface,
+  course: CourseInterface
+}
Index: Sources/frontend/src/app/StudentCourseInterface.ts
===================================================================
--- Sources/frontend/src/app/StudentCourseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/StudentCourseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+import {StudentInterface} from "./StudentInterface";
+import {CourseInterface} from "./courseInterface";
+
+export interface StudentCourseInterface {
+  id:number,
+  student: StudentInterface,
+  course: CourseInterface
+}
Index: Sources/frontend/src/app/StudentInterface.ts
===================================================================
--- Sources/frontend/src/app/StudentInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/StudentInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,9 @@
+export interface StudentInterface{
+  id: number,
+  name: string,
+  lastName: string,
+  username: string,
+  email: string,
+  password: string,
+  index: string
+}
Index: Sources/frontend/src/app/add-answer.service.spec.ts
===================================================================
--- Sources/frontend/src/app/add-answer.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AddAnswerService } from './add-answer.service';
+
+describe('AddAnswerService', () => {
+  let service: AddAnswerService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AddAnswerService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-answer.service.ts
===================================================================
--- Sources/frontend/src/app/add-answer.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,26 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {Router} from "@angular/router";
+import {QuestionInterface} from "./QuestionInterface";
+import {AnswerInterface} from "./AnswerInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AddAnswerService {
+
+  url = "http://localhost:8080/api/answers/add"
+  constructor(private http: HttpClient, private router: Router) {
+  }
+
+  add(content: string, username: string, questionId: number) {
+    const params = new HttpParams()
+      .append("content",content)
+      .append("username",username)
+      .append("questionId",questionId)
+    this.http.get<AnswerInterface>(this.url, {params:params})
+      .subscribe(resp => {
+        this.router.navigate(['/question-details/'+questionId]);
+      })
+  }
+}
Index: Sources/frontend/src/app/add-answer/add-answer.component.css
===================================================================
--- Sources/frontend/src/app/add-answer/add-answer.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer/add-answer.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,68 @@
+.parent-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 400px;
+  margin-right: 400px;
+  margin-top: 100px;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  width: 100px;
+  margin: 5px;
+  cursor: pointer;
+  float: right;
+  border-radius: 5px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+  min-width: 150px;
+}
+
+.add-answer {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+label {
+  width: 100%;
+  font-weight: bold;
+  font-size: 20px;
+  padding-top: 10px;
+  color: rgba(27, 39, 107, 0.8);
+}
+
+textarea {
+  width: 100%;
+  height: 180px;
+  margin: none;
+  background-color: rgba(237, 238, 245, 0.8);
+  border-color: rgba(159, 168, 216, 0.5);
+  font-size: 16px;
+  border-radius: 5px;
+}
+
+.btn-div {
+  margin-top: 20px;
+  float: right;
+}
+
+input {
+  border-radius: 5px;
+  background-color: rgba(237, 238, 245, 0.8);
+}
+
+h3 {
+  color: rgba(27, 39, 107, 0.8);
+}
+
+.container{
+  padding: 20px;
+  background-color: #ffffff;
+  border-radius: 10px;
+}
Index: Sources/frontend/src/app/add-answer/add-answer.component.html
===================================================================
--- Sources/frontend/src/app/add-answer/add-answer.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer/add-answer.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+<div class="parent-container">
+  <div class="container">
+    <form class="example-form">
+      <div class="add-answer">
+        <h3>Содржина</h3>
+        <textarea name="content" [(ngModel)]="content" placeholder="Внесете го вашиот одговор овде..."></textarea>
+        <div class="btn-div">
+          <button (click)="submit()"
+                  [disabled]="content==null" type="button">Одговори на прашањето
+          </button>
+        </div>
+      </div>
+    </form>
+  </div>
+
+</div>
Index: Sources/frontend/src/app/add-answer/add-answer.component.spec.ts
===================================================================
--- Sources/frontend/src/app/add-answer/add-answer.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer/add-answer.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddAnswerComponent } from './add-answer.component';
+
+describe('AddAnswerComponent', () => {
+  let component: AddAnswerComponent;
+  let fixture: ComponentFixture<AddAnswerComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ AddAnswerComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(AddAnswerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-answer/add-answer.component.ts
===================================================================
--- Sources/frontend/src/app/add-answer/add-answer.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-answer/add-answer.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,36 @@
+import {Component} from '@angular/core';
+
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {ActivatedRoute, Router} from "@angular/router";
+import {AddAnswerService} from "../add-answer.service";
+
+@Component({
+  selector: 'app-add-answer',
+  templateUrl: './add-answer.component.html',
+  styleUrls: ['./add-answer.component.css']
+})
+export class AddAnswerComponent {
+  content: string | undefined;
+  questionId: number | undefined;
+  activeUser: ActiveUserInterface | undefined;
+
+  constructor(private addAnswerService: AddAnswerService,
+              private loginService: LoginService,
+              private route: ActivatedRoute,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.questionId = Number(this.route.snapshot.paramMap.get('id'));
+    this.activeUser = this.loginService.activeUser;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+  }
+
+  submit() {
+    this.addAnswerService.add(this.content!!, this.activeUser!!.username, this.questionId!!)
+  }
+
+}
Index: Sources/frontend/src/app/add-material/add-material.component.css
===================================================================
--- Sources/frontend/src/app/add-material/add-material.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-material/add-material.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,31 @@
+.container {
+  margin-left: 200px;
+  margin-right: 200px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-top: 100px;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  margin: 5px;
+  border-radius: 5px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+h3{
+  color: rgba(27, 39, 107, 0.8);
+}
+
+a{
+  cursor: pointer;
+}
+
+span{
+  color: #3A98B9;
+}
Index: Sources/frontend/src/app/add-material/add-material.component.html
===================================================================
--- Sources/frontend/src/app/add-material/add-material.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-material/add-material.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,39 @@
+<div class="container">
+  <div >
+    <div>
+      <h3>Прикачи датотека</h3>
+    </div><br>
+    <div>
+      <div *ngIf="fileStatus.status==='progress'">
+        <div>
+          <div [style.width.%]="fileStatus.percent" class="progress-bar progress-bar-animated bg-info" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">
+            {{ fileStatus.requestType }} {{ fileStatus.percent }}
+          </div>
+        </div>
+      </div> <hr>
+
+      <form enctype="multipart/form-data">
+        <fieldset>
+          <div>
+            <div>
+              <input type="file" (change)="onUploadFiles($event)" name="files" multiple class="form-control" />
+            </div>
+          </div>
+        </fieldset>
+      </form>
+
+      <br>
+
+      <div *ngIf="filenames.length > 0">
+        <h3>Прикачени материјали</h3>
+        <div *ngFor="let filename of filenames">
+          <a (click)="onDownloadFile(filename)">
+            {{ filename }}
+            <a><span>Превземи</span></a>
+          </a><br>
+        </div>
+      </div>
+    </div>
+  </div>
+  <button routerLink="/materials/{{courseId}}">Назад кон материјали</button>
+</div>
Index: Sources/frontend/src/app/add-material/add-material.component.spec.ts
===================================================================
--- Sources/frontend/src/app/add-material/add-material.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-material/add-material.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddMaterialComponent } from './add-material.component';
+
+describe('AddMaterialComponent', () => {
+  let component: AddMaterialComponent;
+  let fixture: ComponentFixture<AddMaterialComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ AddMaterialComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(AddMaterialComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-material/add-material.component.ts
===================================================================
--- Sources/frontend/src/app/add-material/add-material.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-material/add-material.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,101 @@
+import {Component, OnInit} from '@angular/core';
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {MaterialsService} from "../materials.service";
+import {HttpErrorResponse, HttpEvent, HttpEventType} from "@angular/common/http";
+import {saveAs} from 'file-saver';
+import {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-add-material',
+  templateUrl: './add-material.component.html',
+  styleUrls: ['./add-material.component.css']
+})
+export class AddMaterialComponent implements OnInit {
+  activeUser: ActiveUserInterface | undefined;
+  filenames: string[] = [];
+  fileStatus = {status: '', requestType: '', percent: 0};
+  courseId: number;
+
+  constructor(private loginService: LoginService,
+              private materialService: MaterialsService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.activeUser = this.loginService.activeUser;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+    this.courseId = this.loginService.currentCourse;
+  }
+
+  // define a function to upload files
+  onUploadFiles(e): void {
+    let files = e.target.files;
+    console.log("files", files)
+    const formData = new FormData();
+    for (const file of files) {
+      formData.append('files', file, file.name);
+    }
+    this.materialService.upload(formData, this.activeUser.username, this.loginService.currentCourse).subscribe(
+      event => {
+        console.log(event);
+        this.reportProgress(event);
+      },
+      (error: HttpErrorResponse) => {
+        console.log(error);
+      }
+    );
+  }
+
+  // define a function to download files
+  onDownloadFile(filename: string): void {
+    this.materialService.download(filename).subscribe(
+      event => {
+        console.log(event);
+        this.reportProgress(event);
+      },
+      (error: HttpErrorResponse) => {
+        console.log(error);
+      }
+    );
+  }
+
+  private reportProgress(httpEvent: HttpEvent<string[] | Blob>): void {
+    switch (httpEvent.type) {
+      case HttpEventType.UploadProgress:
+        this.updateStatus(httpEvent.loaded, httpEvent.total!, 'Uploading... ');
+        break;
+      case HttpEventType.DownloadProgress:
+        this.updateStatus(httpEvent.loaded, httpEvent.total!, 'Downloading... ');
+        break;
+      case HttpEventType.ResponseHeader:
+        console.log('Header returned', httpEvent);
+        break;
+      case HttpEventType.Response:
+        if (httpEvent.body instanceof Array) {
+          this.fileStatus.status = 'done';
+          for (const filename of httpEvent.body) {
+            this.filenames.unshift(filename);
+          }
+        } else {
+          saveAs(new Blob([httpEvent.body!],
+              {type: `${httpEvent.headers.get('Content-Type')};charset=utf-8`}),
+            httpEvent.headers.get('File-Name'));
+        }
+        this.fileStatus.status = 'done';
+        break;
+      default:
+        console.log(httpEvent);
+        break;
+
+    }
+  }
+
+  private updateStatus(loaded: number, total: number, requestType: string): void {
+    this.fileStatus.status = 'progress';
+    this.fileStatus.requestType = requestType;
+    this.fileStatus.percent = Math.round(100 * loaded / total);
+  }
+}
Index: Sources/frontend/src/app/add-question.service.spec.ts
===================================================================
--- Sources/frontend/src/app/add-question.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AddQuestionService } from './add-question.service';
+
+describe('AddQuestionService', () => {
+  let service: AddQuestionService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AddQuestionService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-question.service.ts
===================================================================
--- Sources/frontend/src/app/add-question.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,36 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {Router} from "@angular/router";
+import {QuestionInterface} from "./QuestionInterface";
+import {QuestionTaggedWithCategoryInterface} from "./question-tagged-with-category-interface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AddQuestionService {
+
+  url = "http://localhost:8080/api/questions/add"
+  taggingUrl = "http://localhost:8080/api/tagged-questions/add/"
+  constructor(private http: HttpClient, private router: Router) {
+  }
+
+  add(title:string,content:string,studentUserame:string,courseId:number,categories:number[]){
+    const params = new HttpParams()
+      .append("title",title)
+      .append("content",content)
+      .append("studentUserame",studentUserame)
+      .append("courseId",courseId)
+    this.http.get<QuestionInterface>(this.url, {params:params})
+      .subscribe(resp => {
+        const taggingParams= new HttpParams()
+          .append("questionId",resp.id)
+        for(let category of categories){
+          this.http.get<QuestionTaggedWithCategoryInterface>(this.taggingUrl+category,{params:taggingParams})
+            .subscribe(resp => {
+              console.log(resp)
+            })
+        }
+        this.router.navigate(['/details/'+courseId]);
+      })
+  }
+}
Index: Sources/frontend/src/app/add-question/add-question.component.css
===================================================================
--- Sources/frontend/src/app/add-question/add-question.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question/add-question.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,75 @@
+.parent-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 400px;
+  margin-right: 400px;
+  margin-top: 100px;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  width: 100px;
+  margin: 5px;
+  cursor: pointer;
+  float: right;
+  border-radius: 5px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.add-question {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+label {
+  width: 100%;
+  font-weight: bold;
+  font-size: 20px;
+  padding-top: 10px;
+  color: rgba(27, 39, 107, 0.8);
+}
+
+input {
+  width: 100%;
+  height: 30px;
+  margin: none;
+  background-color: rgba(237, 238, 245, 0.8);
+  font-size: 16px;
+  border-radius: 5px;
+}
+
+textarea {
+  width: 100%;
+  height: 180px;
+  margin: none;
+  background-color: rgba(237, 238, 245, 0.8);
+  border-color: rgba(159, 168, 216, 0.5);
+  font-size: 16px;
+  border-radius: 7px;
+}
+
+.btn-div {
+  float: right;
+}
+ng-multiselect-dropdown{
+  width: 97%;
+}
+:host ::ng-deep .multiselect-dropdown .dropdown-btn {
+    width: 97%;
+    background-color: rgba(237, 238, 245, 0.8);
+    font-size: 16px;
+    border-radius: 5px;
+}
+
+.container{
+  padding: 20px;
+  background-color: #ffffff;
+  border-radius: 10px;
+}
Index: Sources/frontend/src/app/add-question/add-question.component.html
===================================================================
--- Sources/frontend/src/app/add-question/add-question.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question/add-question.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,27 @@
+<div class="parent-container">
+  <div class="container">
+    <form class="example-form">
+      <div class="add-question">
+        <label>Наслов</label>
+        <input name="title"
+               [(ngModel)]="title">
+        <label>Содржина</label>
+        <textarea name="content" [(ngModel)]="content"></textarea>
+        <label>Категории</label>
+        <ng-multiselect-dropdown
+          [placeholder]=""
+          [settings]="dropdownSettings"
+          [data]="categories"
+          [(ngModel)]="selectedItems"
+          name="categories">
+        </ng-multiselect-dropdown>
+        <div class="btn-div">
+          <button (click)="submit()"
+                  [disabled]="title==null && content==null" type="button">Прашај
+          </button>
+        </div>
+      </div>
+    </form>
+  </div>
+
+</div>
Index: Sources/frontend/src/app/add-question/add-question.component.spec.ts
===================================================================
--- Sources/frontend/src/app/add-question/add-question.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question/add-question.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddQuestionComponent } from './add-question.component';
+
+describe('AddQuestionComponent', () => {
+  let component: AddQuestionComponent;
+  let fixture: ComponentFixture<AddQuestionComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ AddQuestionComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(AddQuestionComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-question/add-question.component.ts
===================================================================
--- Sources/frontend/src/app/add-question/add-question.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-question/add-question.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,57 @@
+import {Component} from '@angular/core';
+import {QuestionInterface} from "../QuestionInterface";
+import {CourseInterface} from "../courseInterface";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {ActivatedRoute, Router} from "@angular/router";
+import {AddQuestionService} from "../add-question.service";
+import {CategoryInterface} from "../categoryInterface";
+import {CategoryService} from "../category.service";
+
+
+@Component({
+  selector: 'app-add-question',
+  templateUrl: './add-question.component.html',
+  styleUrls: ['./add-question.component.css']
+})
+export class AddQuestionComponent {
+  title: string | undefined;
+  content: string | undefined;
+  courseId: number | undefined;
+  question: QuestionInterface | undefined;
+  course: CourseInterface | undefined;
+  activeUser: ActiveUserInterface | undefined;
+  categories : CategoryInterface[] =[]
+  dropdownList = [];
+  selectedItems = [];
+  dropdownSettings = {};
+
+  constructor(private addQuestionService: AddQuestionService,
+              private categoryService: CategoryService,
+              private loginService: LoginService,
+              private route: ActivatedRoute,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.courseId = Number(this.route.snapshot.paramMap.get('id'));
+    this.activeUser = this.loginService.activeUser;
+    this.categoryService.getAllCategories().subscribe(response => this.categories=response);
+    this.dropdownSettings = {
+      singleSelection: false,
+      idField: 'id',
+      textField: 'name',
+      selectAllText: 'Select All',
+      unSelectAllText: 'UnSelect All',
+      itemsShowLimit: 6,
+      allowSearchFilter: false
+    };
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+  }
+
+  submit() {
+    this.addQuestionService.add(this.title!!, this.content!!, this.activeUser!!.username, this.courseId!!,this.selectedItems!!.map(cat => cat.id))
+  }
+}
Index: Sources/frontend/src/app/add-student-courses.service.spec.ts
===================================================================
--- Sources/frontend/src/app/add-student-courses.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-student-courses.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AddStudentCoursesService } from './add-student-courses.service';
+
+describe('AddStudentCoursesService', () => {
+  let service: AddStudentCoursesService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AddStudentCoursesService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/add-student-courses.service.ts
===================================================================
--- Sources/frontend/src/app/add-student-courses.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/add-student-courses.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,26 @@
+import { Injectable } from '@angular/core';
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {StudentCourseInterface} from "./StudentCourseInterface";
+import {ProfessorCourseInterface} from "./ProfessorCourseInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AddStudentCoursesService {
+
+  url = "http://localhost:8080/api/student-courses/add"
+  urlProf = "http://localhost:8080/api/professor-courses/add"
+
+  constructor(private http: HttpClient) { }
+
+  addCourseToStudent(username: string, selectedCourse: number) :Observable<StudentCourseInterface> {
+    const params = new HttpParams().append('username', username).append("selectedCourse",selectedCourse);
+    return this.http.get<StudentCourseInterface>(this.url, {params: params})
+  }
+
+  addCourseToProfessor(username: string, selectedCourse: number) :  Observable<ProfessorCourseInterface> {
+    const params = new HttpParams().append('username', username).append("selectedCourse",selectedCourse);
+    return this.http.get<ProfessorCourseInterface>(this.urlProf, {params: params})
+  }
+}
Index: Sources/frontend/src/app/admin-panel.service.spec.ts
===================================================================
--- Sources/frontend/src/app/admin-panel.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AdminPanelService } from './admin-panel.service';
+
+describe('AdminPanelService', () => {
+  let service: AdminPanelService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(AdminPanelService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/admin-panel.service.ts
===================================================================
--- Sources/frontend/src/app/admin-panel.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,35 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {forkJoin, Observable} from "rxjs";
+import {Query1Interface} from "./Query1Interface";
+
+import {Query2Interface} from "./Query2Interface";
+import {Query3Interface} from "./Query3Interface";
+import {Query4Interface} from "./Query4Interface";
+import {Query5Interface} from "./Query5Interface";
+
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AdminPanelService {
+  url = "http://localhost:8080/api/admin/admin-panel"
+
+  constructor(private http: HttpClient) {
+  }
+  getFirstQuery():Observable<Query1Interface[]> {
+    return this.http.get<Query1Interface[]>(this.url+'/1')
+  }
+  getSecondQuery():Observable<Query2Interface[]>{
+    return this.http.get<Query2Interface[]>(this.url+'/2')
+  }
+  getThirdQuery():Observable<Query3Interface[]>{
+    return this.http.get<Query3Interface[]>(this.url+'/3')
+  }
+  getFourthQuery():Observable<Query4Interface[]>{
+    return this.http.get<Query4Interface[]>(this.url+'/4')
+  }
+  getFifthQuery():Observable<Query5Interface[]>{
+    return this.http.get<Query5Interface[]>(this.url+'/5')
+  }
+}
Index: Sources/frontend/src/app/admin-panel/admin-panel.component.css
===================================================================
--- Sources/frontend/src/app/admin-panel/admin-panel.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel/admin-panel.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,42 @@
+table {
+  width: 80%;
+  border-collapse: collapse;
+  margin: auto;
+}
+
+th, td {
+  border: 1px solid white;
+  padding: 8px;
+  text-align: left;
+  background-color: rgba(228, 236, 237, 0.8);
+}
+
+th {
+  background-color: #3A98B9;
+}
+
+.table-container {
+  margin-bottom: 20px;
+  padding-bottom: 10px;
+}
+
+.table-title {
+  text-align: center;
+  margin-bottom: 10px;
+}
+
+.container {
+  margin-left: 200px;
+  margin-right: 200px;
+  color: rgba(27, 39, 107, 0.8);
+  background-color: white;
+  padding: 10px 25px 10px 25px;
+  border-radius: 10px;
+}
+
+table th{
+  color: #FFF1DC;
+}
+table td{
+  color: rgba(27, 39, 107, 0.8);
+}
Index: Sources/frontend/src/app/admin-panel/admin-panel.component.html
===================================================================
--- Sources/frontend/src/app/admin-panel/admin-panel.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel/admin-panel.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,114 @@
+<div class="container">
+  <h1>Административна табла</h1>
+  <br>
+
+  <div class="table-container">
+    <h3 class="table-title">Извештај за првите 3 валидни прашања кои имаат барем два одговори од професор, од тие три се
+      бира прашањето кое има најмногу одговори во последните 4 месеци</h3>
+    <table>
+      <thead>
+      <tr>
+        <th>Наслов</th>
+        <th>Содржина</th>
+        <th>Датум</th>
+        <th>Број на одговори</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let row of query1">
+        <td>{{row?.pra_naslov}}</td>
+        <td>{{row?.pra_sodrzina}}</td>
+        <td>{{row?.pra_datum}}</td>
+        <td>{{row?.maximum}}</td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+  <hr>
+  <div class="table-container">
+    <h3 class="table-title">Извештај за првите три прашања со најмногу одговори од студенти и професори посебно, потоа
+      од тие прашања ја пресметуваме вкупната сума на реакции на одговорите(заедно од професори и студенти) и ги
+      филтритаме само оние кои имаат просечен или надпросечен број на реакции</h3>
+    <table>
+      <thead>
+      <tr>
+        <th>Наслов</th>
+        <th>Содржина</th>
+        <th>Датум</th>
+        <th>Број на реакции</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let row of query2">
+        <td>{{row?.pra_naslov}}</td>
+        <td>{{row?.pra_sodrzina}}</td>
+        <td>{{row?.pra_datum}}</td>
+        <td>{{row?.sum}}</td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+  <hr>
+  <div class="table-container">
+    <h3 class="table-title">Извештај за пронаоѓање на најдобрите 5 професори т.е. професорите кои имаат одговори со
+      најдобри рејтингзи, имаат поставено најмногу материјали и предаваат најмногу курсеви.</h3>
+    <table>
+      <thead>
+      <tr>
+
+        <th>Корисничко име</th>
+        <th>Вкупен број на активности</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let row of query3">
+        <td>{{row?.korisnicko_ime}}</td>
+        <td>{{row?.vk}}</td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+  <hr>
+  <div class="table-container">
+    <h3 class="table-title">Извештај за секој предмет најпопуларните 3 курсеви во последните 3 месеци кои имаат барем по
+      2 исти категории за материјали и прашања</h3>
+    <table>
+      <thead>
+      <tr>
+        <th>Име на предмет</th>
+        <th>Име на курс</th>
+        <th>Број на исти категории</th>
+        <th>Број на исти категории</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let row of query4">
+        <td>{{row?.pr_ime}}</td>
+        <td>{{row?.ku_ime}}</td>
+        <td>{{row?.br_isti_kategorii}}</td>
+        <td>{{row?.br_prasanja}}</td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+  <hr>
+  <div class="table-container">
+    <h3 class="table-title">Извештај за пронаоѓање на професорот кој најбрзо одговорил на поставено прашање</h3>
+    <table>
+      <thead>
+      <tr>
+        <th>Име на професор</th>
+        <th>Презиме на професор</th>
+        <th>Најбрзо време на одговор</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let row of query5">
+        <td>{{row?.p_ime}}</td>
+        <td>{{row?.p_prezime}}</td>
+        <td>{{formatInterval(row.najbrzo_vreme.value)}}</td>
+      </tr>
+      </tbody>
+    </table>
+  </div>
+</div>
Index: Sources/frontend/src/app/admin-panel/admin-panel.component.spec.ts
===================================================================
--- Sources/frontend/src/app/admin-panel/admin-panel.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel/admin-panel.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AdminPanelComponent } from './admin-panel.component';
+
+describe('AdminPanelComponent', () => {
+  let component: AdminPanelComponent;
+  let fixture: ComponentFixture<AdminPanelComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ AdminPanelComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(AdminPanelComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/admin-panel/admin-panel.component.ts
===================================================================
--- Sources/frontend/src/app/admin-panel/admin-panel.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/admin-panel/admin-panel.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,70 @@
+import {Component, OnInit} from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {forkJoin} from "rxjs";
+import {Query1Interface} from "../Query1Interface";
+import {AdminPanelService} from "../admin-panel.service";
+import {Query2Interface} from "../Query2Interface";
+import {Query3Interface} from "../Query3Interface";
+import {Query4Interface} from "../Query4Interface";
+import {Query5Interface} from "../Query5Interface";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {Router} from "@angular/router";
+import {LoginService} from "../login.service";
+
+@Component({
+  selector: 'app-admin-panel',
+  templateUrl: './admin-panel.component.html',
+  styleUrls: ['./admin-panel.component.css']
+})
+export class AdminPanelComponent implements OnInit {
+  query1: Query1Interface[] | undefined;
+  query2: Query2Interface[] | undefined;
+  query3: Query3Interface[] | undefined;
+  query4: Query4Interface[] | undefined;
+  query5: Query5Interface[] | undefined;
+  activeUser: ActiveUserInterface | undefined;
+
+  constructor(private http: HttpClient, private service: AdminPanelService, private loginService: LoginService, private router: Router) { }
+
+  ngOnInit():void {
+    this.activeUser = this.loginService.activeUser!!;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+    forkJoin([
+      this.service.getFirstQuery(),
+      this.service.getSecondQuery(),
+      this.service.getThirdQuery(),
+      this.service.getFourthQuery(),
+      this.service.getFifthQuery(),
+    ]).subscribe(results => {
+      this.query1 = results[0];
+      this.query2 = results[1];
+      this.query3 = results[2];
+      this.query4 = results[3];
+      this.query5 = results[4];
+    });
+  }
+  formatInterval(interval: string) {
+    const match = interval.match(/(\d+) years (\d+) mons (\d+) days (\d+) hours (\d+) mins (\d+\.\d+) secs/);
+    if (!match) {
+      return interval;
+    }
+    const [, years, months, days, hours, minutes, seconds] = match;
+    const units = [
+      { value: years, unit: 'years' },
+      { value: months, unit: 'months' },
+      { value: days, unit: 'days' },
+      { value: hours, unit: 'hours' },
+      { value: minutes, unit: 'minutes' },
+      { value: seconds, unit: 'seconds' },
+    ];
+    const result: string[] = [];
+    units.forEach(({ value, unit }) => {
+      if (value !== '0') {
+        result.push(`${value} ${unit}`);
+      }
+    });
+    return result.join(', ');
+  }
+}
Index: Sources/frontend/src/app/all-courses/all-courses.component.css
===================================================================
--- Sources/frontend/src/app/all-courses/all-courses.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/all-courses/all-courses.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,33 @@
+.card{
+  display: inline-block;
+  background-color: #3A98B9;
+  width: 100px;
+  height: 100px;
+  margin: 10px;
+  padding: 5px;
+}
+.container{
+  display: flex;
+}
+.parent-container{
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+button{
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  width: 100px;
+  margin: 5px;
+  float: right;
+  cursor: pointer;
+}
+
+.list{
+  display: flex;
+}
Index: Sources/frontend/src/app/all-courses/all-courses.component.html
===================================================================
--- Sources/frontend/src/app/all-courses/all-courses.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/all-courses/all-courses.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,18 @@
+<div class="parent-container">
+  <h1>Сите курсеви</h1>
+  <form class="example-form">
+    <div class="list">
+      <div *ngFor="let c of courses">
+        <input type="checkbox" name="{{c.name}}"
+               (change)="onChange({event : $event, id : {id : c.id}})"
+               [checked]="checked({id : {id : c.id}})">
+        <label>
+          <p class="card">
+            Курс: {{c.name}}
+          </p>
+        </label>
+      </div>
+    </div>
+    <button (click)="submit()" type="button"><b>Submit</b></button>
+  </form>
+</div>
Index: Sources/frontend/src/app/all-courses/all-courses.component.spec.ts
===================================================================
--- Sources/frontend/src/app/all-courses/all-courses.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/all-courses/all-courses.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AllCoursesComponent } from './all-courses.component';
+
+describe('AllCoursesComponent', () => {
+  let component: AllCoursesComponent;
+  let fixture: ComponentFixture<AllCoursesComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ AllCoursesComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(AllCoursesComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/all-courses/all-courses.component.ts
===================================================================
--- Sources/frontend/src/app/all-courses/all-courses.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/all-courses/all-courses.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,74 @@
+import {Component, Input, OnInit} from '@angular/core';
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {CourseInterface} from "../courseInterface";
+import {CourseService} from "../course.service";
+import {AddStudentCoursesService} from "../add-student-courses.service";
+import {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-all-courses',
+  templateUrl: './all-courses.component.html',
+  styleUrls: ['./all-courses.component.css']
+})
+export class AllCoursesComponent implements OnInit {
+
+  courses: CourseInterface[] = [];
+
+  selectedCourses = [];
+  activeUser: ActiveUserInterface | undefined;
+  @Input() subjectId: number | undefined;
+
+  constructor(private service: CourseService,
+              private addService: AddStudentCoursesService,
+              private loginService: LoginService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.service.getAllCourses().subscribe(courses => this.courses = courses)
+    this.activeUser = this.loginService.activeUser!!;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+  }
+
+  loadCourses(subjectId: number) {
+    this.service.findCoursesBySubjectId(subjectId).subscribe(courses => this.courses = courses);
+  }
+
+  checked({id}: { id: any }) {
+    // @ts-ignore
+    if (this.selectedCourses.indexOf(id) != -1) {
+      return true;
+    }
+    return false;
+  }
+
+  onChange({event, id}: { event: any, id: any }) {
+    if (event.target.checked) {
+      // @ts-ignore
+      this.selectedCourses.push(id.id);
+    } else {
+      // @ts-ignore
+      this.selectedCourses.splice(this.selectedCourses.indexOf(id.id), 1)
+    }
+  }
+
+  submit() {
+    this.activeUser = this.loginService.activeUser!!;
+    this.selectedCourses = this.selectedCourses.sort()
+    if (this.loginService.activeUser!!.userType == 'STUDENT') {
+      for (let course of this.selectedCourses) {
+        this.addService.addCourseToStudent(this.activeUser.username, +course)
+          .subscribe(() => this.router.navigate(['/courses']));
+      }
+    }
+    if (this.loginService.activeUser!!.userType == 'PROFESSOR') {
+      for (let course of this.selectedCourses) {
+        this.addService.addCourseToProfessor(this.activeUser.username, +course)
+          .subscribe(() => this.router.navigate(['/courses']));
+      }
+    }
+  }
+}
Index: Sources/frontend/src/app/app-routing.module.ts
===================================================================
--- Sources/frontend/src/app/app-routing.module.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/app-routing.module.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,35 @@
+import { NgModule } from '@angular/core';
+import { RouterModule, Routes } from '@angular/router';
+import {LoginComponent} from "./login/login.component";
+import {StudentCourseComponent} from "./student-course/student-course.component";
+import {QuestionComponent} from "./question/question.component";
+import {QuestionDetailsComponent} from "./question-details/question-details.component";
+import {SubjectComponent} from "./subject/subject.component";
+import {AddQuestionComponent} from "./add-question/add-question.component";
+import {AddAnswerComponent} from "./add-answer/add-answer.component";
+import {AdminPanelComponent} from "./admin-panel/admin-panel.component";
+import {MaterialsComponent} from "./materials/materials.component";
+import {AddMaterialComponent} from "./add-material/add-material.component";
+
+
+const routes: Routes = [
+  { path: '', redirectTo: '/login', pathMatch: 'full' },
+  { path: 'login', component: LoginComponent },
+  { path: 'courses', component: StudentCourseComponent },
+  { path: 'allCourses', component: SubjectComponent },
+  { path: 'admin-panel', component: AdminPanelComponent},
+  { path: 'add-question/:id', component: AddQuestionComponent},
+  { path: 'add-answer/:id', component:AddAnswerComponent},
+  { path: 'details/:id', component: QuestionComponent },
+  { path: 'question-details/:id', component: QuestionDetailsComponent},
+  { path: 'materials/:id', component: MaterialsComponent},
+  { path: 'add-materials', component: AddMaterialComponent}
+];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule]
+})
+export class AppRoutingModule {
+
+}
Index: Sources/frontend/src/app/app.component.html
===================================================================
--- Sources/frontend/src/app/app.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/app.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,1 @@
+<router-outlet></router-outlet>
Index: Sources/frontend/src/app/app.component.spec.ts
===================================================================
--- Sources/frontend/src/app/app.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/app.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,35 @@
+import { TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [
+        RouterTestingModule
+      ],
+      declarations: [
+        AppComponent
+      ],
+    }).compileComponents();
+  });
+
+  it('should create the app', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app).toBeTruthy();
+  });
+
+  it(`should have as title 'finkiForumsFrontEnd'`, () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app.title).toEqual('finkiForumsFrontEnd');
+  });
+
+  it('should render title', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    fixture.detectChanges();
+    const compiled = fixture.nativeElement as HTMLElement;
+    expect(compiled.querySelector('.content span')?.textContent).toContain('finkiForumsFrontEnd app is running!');
+  });
+});
Index: Sources/frontend/src/app/app.component.ts
===================================================================
--- Sources/frontend/src/app/app.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/app.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.css']
+})
+export class AppComponent {
+  title = 'finkiForumsFrontEnd';
+}
Index: Sources/frontend/src/app/app.module.ts
===================================================================
--- Sources/frontend/src/app/app.module.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/app.module.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,50 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+
+import { AppRoutingModule } from './app-routing.module';
+import { AppComponent } from './app.component';
+import { StudentCourseComponent } from './student-course/student-course.component';
+import {HttpClientModule} from "@angular/common/http";
+import { SubjectComponent } from './subject/subject.component';
+import { QuestionComponent } from './question/question.component';
+import { LoginComponent } from './login/login.component';
+import { FormsModule } from '@angular/forms';
+import {RouterModule} from "@angular/router";
+import { QuestionDetailsComponent } from './question-details/question-details.component';
+import { AllCoursesComponent } from './all-courses/all-courses.component';
+import { AddQuestionComponent } from './add-question/add-question.component';
+import { AddAnswerComponent } from './add-answer/add-answer.component';
+import { CategoryComponent } from './category/category.component';
+import { AdminPanelComponent } from './admin-panel/admin-panel.component';
+import { MaterialsComponent } from './materials/materials.component';
+import { AddMaterialComponent } from './add-material/add-material.component';
+import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown';
+
+@NgModule({
+  declarations: [
+    AppComponent,
+    StudentCourseComponent,
+    SubjectComponent,
+    QuestionComponent,
+    LoginComponent,
+    QuestionDetailsComponent,
+    AllCoursesComponent,
+    AddQuestionComponent,
+    AddAnswerComponent,
+    CategoryComponent,
+    AdminPanelComponent,
+    MaterialsComponent,
+    AddMaterialComponent
+  ],
+  imports: [
+    BrowserModule,
+    AppRoutingModule,
+    HttpClientModule,
+    FormsModule,
+    RouterModule,
+    NgMultiSelectDropDownModule.forRoot()
+  ],
+  providers: [],
+  bootstrap: [AppComponent]
+})
+export class AppModule { }
Index: Sources/frontend/src/app/category.service.spec.ts
===================================================================
--- Sources/frontend/src/app/category.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/category.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CategoryService } from './category.service';
+
+describe('CategoryService', () => {
+  let service: CategoryService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(CategoryService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/category.service.ts
===================================================================
--- Sources/frontend/src/app/category.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/category.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,19 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {CategoryInterface} from "./categoryInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class CategoryService {
+
+  url = "http://localhost:8080/api/categories"
+
+  constructor(private http: HttpClient) {
+  }
+
+  getAllCategories(): Observable<CategoryInterface[]> {
+    return this.http.get<CategoryInterface[]>(`${this.url}/all`)
+  }
+}
Index: Sources/frontend/src/app/category/category.component.html
===================================================================
--- Sources/frontend/src/app/category/category.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/category/category.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,10 @@
+<div class="parent-container">
+  <h1>Категории</h1>
+    <div class="list">
+      <div *ngFor="let c of categories">
+          <p class="card">
+            {{c.name}}
+          </p>
+      </div>
+    </div>
+</div>
Index: Sources/frontend/src/app/category/category.component.spec.ts
===================================================================
--- Sources/frontend/src/app/category/category.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/category/category.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CategoryComponent } from './category.component';
+
+describe('CategoryComponent', () => {
+  let component: CategoryComponent;
+  let fixture: ComponentFixture<CategoryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ CategoryComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(CategoryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/category/category.component.ts
===================================================================
--- Sources/frontend/src/app/category/category.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/category/category.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,21 @@
+import {Component, OnInit} from '@angular/core';
+import {CategoryService} from "../category.service";
+import {CategoryInterface} from "../categoryInterface";
+
+@Component({
+  selector: 'app-category',
+  templateUrl: './category.component.html',
+  styleUrls: ['./category.component.css']
+})
+export class CategoryComponent implements OnInit{
+
+  categories : CategoryInterface[] =[]
+
+  constructor(private categoryService: CategoryService) {
+  }
+
+  ngOnInit(): void {
+    this.categoryService.getAllCategories().subscribe(response => this.categories = response)
+  }
+
+}
Index: Sources/frontend/src/app/categoryInterface.ts
===================================================================
--- Sources/frontend/src/app/categoryInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/categoryInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,5 @@
+export interface CategoryInterface {
+  id: number,
+  name: string,
+  description: string
+}
Index: Sources/frontend/src/app/course.service.spec.ts
===================================================================
--- Sources/frontend/src/app/course.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/course.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CourseService } from './course.service';
+
+describe('CourseService', () => {
+  let service: CourseService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(CourseService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/course.service.ts
===================================================================
--- Sources/frontend/src/app/course.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/course.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,25 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {CourseInterface} from "./courseInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class CourseService {
+
+  url = "http://localhost:8080/api/courses"
+
+  constructor(private http: HttpClient) {
+  }
+
+  getAllCourses(): Observable<CourseInterface[]> {
+    return this.http.get<CourseInterface[]>(`${this.url}/all`)
+  }
+  findCoursesBySubjectId(id : number) : Observable<CourseInterface[]> {
+  return this.http.get<CourseInterface[]>(`${this.url}/by-subject/${id}`)
+}
+  findCourseById(id :number) : Observable<CourseInterface>{
+      return this.http.get<CourseInterface>(`${this.url}/course/${id}`);
+  }
+}
Index: Sources/frontend/src/app/courseInterface.ts
===================================================================
--- Sources/frontend/src/app/courseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/courseInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+import {SubjectInterface} from "./subjectInterface";
+
+export interface CourseInterface{
+  id: number,
+  name: string,
+  description: string,
+  subject: SubjectInterface
+}
Index: Sources/frontend/src/app/login.service.spec.ts
===================================================================
--- Sources/frontend/src/app/login.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { LoginService } from './login.service';
+
+describe('LoginService', () => {
+  let service: LoginService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(LoginService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/login.service.ts
===================================================================
--- Sources/frontend/src/app/login.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,39 @@
+import {Injectable} from '@angular/core';
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {ActiveUserInterface} from "./ActiveUserInterface";
+import {Router} from "@angular/router";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class LoginService {
+
+  url = "http://localhost:8080/api/login"
+  activeUser: ActiveUserInterface | undefined;
+  currentCourse: number | undefined;
+
+  constructor(private http: HttpClient, private router: Router) {
+  }
+
+  loginUser(username: string, password: string) {
+    const params = new HttpParams()
+      .append('username', username)
+      .append('password', password);
+    console.log("params", params)
+    this.http.get<ActiveUserInterface>(this.url, {params:params})
+      .subscribe(resp => {
+        console.log("Response login", resp);
+        this.activeUser = resp;
+        console.log("active user", this.activeUser)
+        if (this.activeUser.userType==="ADMIN")
+          this.router.navigate(['/admin-panel'])
+        else
+          this.router.navigate(['/courses']);
+      })
+  }
+
+  setCurrentCourse(id: number) : void{
+    this.currentCourse = id;
+    console.log("Current course is ", id);
+  }
+}
Index: Sources/frontend/src/app/login/login.component.css
===================================================================
--- Sources/frontend/src/app/login/login.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login/login.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,72 @@
+.header {
+  display: flex;
+  justify-content: space-between;
+}
+
+.parent-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  width: 15%;
+  margin: 5px;
+  cursor: pointer;
+  border-radius: 5px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.login-form {
+  display: flex;
+  flex-direction: column;
+}
+
+input {
+  width: 50%;
+  height: 40px;
+  margin: none;
+  border-color: rgba(159, 168, 216, 0.5);
+  border-radius: 5px;
+}
+
+.register-form {
+  display: flex;
+  flex-direction: column;
+}
+
+.radio {
+  width: auto !important;
+  height: 30px;
+  margin: none;
+}
+
+.action-button {
+  width: 50%
+}
+
+label {
+  font-size: large;
+  color: rgba(27, 39, 107, 0.8);
+}
+
+.form-check {
+  display: flex;
+}
+
+.radio-button-group {
+  display: flex;
+  align-items: center;
+}
+#logo{
+  width: 300px;
+  height: 300px;
+}
Index: Sources/frontend/src/app/login/login.component.html
===================================================================
--- Sources/frontend/src/app/login/login.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login/login.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,84 @@
+<div class="parent-container">
+  <div class="header">
+    <div class="headings">
+      <h1>
+        Добредојдовте на <i>FinkiForums</i>
+        <br>
+        Централизирано место за прашања околу ФИНКИ
+      </h1>
+    </div>
+    <img id="logo" src="https://i.ibb.co/zn95ydK/NEW-LOGO.jpg">
+  </div>
+
+  <button class="action-button" (click)="showLogin()">Најави се</button>
+
+  <h1>
+    Сеуште немате профил?
+    <br>
+    Регистрирајте се и научете повеќе
+  </h1>
+
+  <button class="action-button" (click)="showRegister()">Регистрирај се</button>
+
+  <div class="container" *ngIf="login">
+    <form class="example-form">
+      <div class="login-form">
+        <label>Корисничко име</label>
+        <input placeholder="Enter your username" name="username"
+               [(ngModel)]="username">
+        <label>Лозинка</label>
+        <input placeholder="Enter your password"
+               value=""
+               name="password"
+               type="password"
+               [(ngModel)]="password">
+        <button (click)="submitLogin()"
+                [disabled]="username==null && password==null" type="button">Submit
+        </button>
+      </div>
+    </form>
+  </div>
+  <div class="container" *ngIf="register">
+    <form class="example-form">
+      <div class="register-form">
+        <label>Име</label>
+        <input placeholder="Enter your name" name="name"
+               [(ngModel)]="name">
+        <label>Презиме</label>
+        <input placeholder="Enter your last name" name="lastName"
+               [(ngModel)]="lastName">
+        <label>Електронска пошта</label>
+        <input placeholder="Enter your email" name="email"
+               [(ngModel)]="email">
+        <label>Корисничко име</label>
+        <input placeholder="Enter your username" name="username"
+               [(ngModel)]="username">
+        <label>Лозинка</label>
+        <input placeholder="Enter your password"
+               value=""
+               name="password"
+               type="password"
+               [(ngModel)]="password">
+        <div class="form-check">
+          <div class="radio-button-group">
+            <input class="radio" type="radio" name="userType" [(ngModel)]="userType" value="PROFESSOR">
+            <label class="radio-label">Професор</label>
+          </div>
+          <div class="radio-button-group">
+            <input class="radio" type="radio" name="userType" [(ngModel)]="userType" value="STUDENT">
+            <label class="radio-label">Студент</label>
+          </div>
+        </div>
+        <label *ngIf="userType=='STUDENT'">Индекс</label>
+        <input *ngIf="userType=='STUDENT'"
+               placeholder="Enter your index"
+               name="index"
+               [(ngModel)]="index">
+        <button (click)="submitRegister()"
+                [disabled]="name==null || lastName==null || email==null || username==null || password==null || userType==null"
+                type="button">Регистрирај се
+        </button>
+      </div>
+    </form>
+  </div>
+</div>
Index: Sources/frontend/src/app/login/login.component.spec.ts
===================================================================
--- Sources/frontend/src/app/login/login.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login/login.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+  let component: LoginComponent;
+  let fixture: ComponentFixture<LoginComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ LoginComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(LoginComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/login/login.component.ts
===================================================================
--- Sources/frontend/src/app/login/login.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/login/login.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,45 @@
+import { Component } from '@angular/core';
+import {LoginService} from "../login.service";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {Router} from "@angular/router";
+import {RegisterService} from "../register.service";
+
+@Component({
+  selector: 'app-login',
+  templateUrl: './login.component.html',
+  styleUrls: ['./login.component.css']
+})
+export class LoginComponent {
+  name:string|undefined;
+  lastName:string|undefined;
+  email:string|undefined;
+  username:string|undefined;
+  password:string|undefined;
+  userType:string|undefined;
+  index:string|undefined;
+  activeUser: ActiveUserInterface | undefined;
+  login: boolean | undefined;
+  register: boolean | undefined;
+
+  constructor(private service: LoginService, private registerService: RegisterService, private router: Router) {
+  }
+
+  submitLogin(){
+      console.log("username and pass", this.username, this.password)
+      this.service.loginUser(this.username!!, this.password!!)
+  }
+  submitRegister(){
+    console.log(this.name, this.lastName,this.email,this.username,this.password,this.userType,this.index)
+    this.registerService.registerUser(this.name!!, this.lastName!!,this.email!!,this.username!!,this.password!!,this.userType!!,this.index!!)
+  }
+  showLogin(){
+    this.login = this.login == null ? true : !this.login;
+    this.register = false;
+  }
+
+  showRegister(){
+    this.register = this.register == null ? true : !this.register;
+    this.login = false;
+  }
+
+}
Index: Sources/frontend/src/app/materials.service.spec.ts
===================================================================
--- Sources/frontend/src/app/materials.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MaterialsService } from './materials.service';
+
+describe('MaterialsService', () => {
+  let service: MaterialsService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MaterialsService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/materials.service.ts
===================================================================
--- Sources/frontend/src/app/materials.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,32 @@
+import {Injectable} from '@angular/core';
+import {HttpClient, HttpEvent} from "@angular/common/http";
+import {Observable} from "rxjs";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class MaterialsService {
+  private path = 'http://localhost:8080/api/materials'
+
+  constructor(private http: HttpClient) {
+  }
+
+  upload(formData: FormData, username: string, courseId: number): Observable<HttpEvent<string[]>> {
+    return this.http.post<string[]>(`${this.path}/upload/${courseId}`, formData, {
+      reportProgress: true,
+      observe: 'events'
+    });
+  }
+
+  download(filename: string): Observable<HttpEvent<Blob>> {
+    return this.http.get(`${this.path}/download/${filename}`, {
+      reportProgress: true,
+      observe: 'events',
+      responseType: 'blob'
+    });
+  }
+
+  findAllMaterialsForCourse(id : number){
+    return this.http.get(`${this.path}/all/${id}`)
+  }
+}
Index: Sources/frontend/src/app/materials/materials.component.css
===================================================================
--- Sources/frontend/src/app/materials/materials.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials/materials.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,45 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  margin: 5px;
+  border-radius: 5px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+li {
+  padding: 10px;
+}
+
+p {
+  display: inline;
+  margin-right: 20px;
+}
+
+svg {
+  color: rgba(27, 39, 107, 0.8);
+}
+
+ol{
+  color: #3A98B9;
+  font-size: large;
+  background-color: #ffffff;
+  border-radius: 15px;
+}
+
Index: Sources/frontend/src/app/materials/materials.component.html
===================================================================
--- Sources/frontend/src/app/materials/materials.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials/materials.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,20 @@
+<div class="container">
+  <div class="header">
+    <h1>Материјали</h1>
+    <button *ngIf="this.activeUser?.userType=='PROFESSOR'" routerLink="/add-materials">+Материјал</button>
+  </div>
+  <ol>
+    <li *ngFor="let filename of files">
+      <p>{{ filename }}</p>
+      <a (click)="onDownloadFile(filename)">
+        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download"
+             viewBox="0 0 16 16">
+          <path
+            d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
+          <path
+            d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
+        </svg>
+      </a>
+    </li>
+  </ol>
+</div>
Index: Sources/frontend/src/app/materials/materials.component.spec.ts
===================================================================
--- Sources/frontend/src/app/materials/materials.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials/materials.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MaterialsComponent } from './materials.component';
+
+describe('MaterialsComponent', () => {
+  let component: MaterialsComponent;
+  let fixture: ComponentFixture<MaterialsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ MaterialsComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(MaterialsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/materials/materials.component.ts
===================================================================
--- Sources/frontend/src/app/materials/materials.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/materials/materials.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,84 @@
+import {Component, OnInit} from '@angular/core';
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {MaterialsService} from "../materials.service";
+import {HttpErrorResponse, HttpEvent, HttpEventType} from "@angular/common/http";
+import {saveAs} from "file-saver";
+import {ActivatedRoute} from "@angular/router";
+
+@Component({
+  selector: 'app-materials',
+  templateUrl: './materials.component.html',
+  styleUrls: ['./materials.component.css']
+})
+export class MaterialsComponent implements OnInit{
+
+  activeUser: ActiveUserInterface | undefined;
+  courseId : number | undefined;
+  files: string[] | any = []
+  fileStatus = {status: '', requestType: '', percent: 0};
+
+  constructor(private loginService: LoginService,
+              private materialService: MaterialsService,
+              private _router: ActivatedRoute) {
+  }
+  ngOnInit() {
+    this.activeUser = this.loginService.activeUser;
+    this.courseId = +this._router.snapshot.paramMap.get("id");
+    this.materialService.findAllMaterialsForCourse(this.courseId)
+      .subscribe(response => {
+        console.log("files", this.files)
+        this.files = response
+      })
+  }
+
+  onDownloadFile(filename: string): void {
+    this.materialService.download(filename).subscribe(
+      event => {
+        console.log(event);
+        this.resportProgress(event);
+      },
+      (error: HttpErrorResponse) => {
+        console.log(error);
+      }
+    );
+  }
+
+  private resportProgress(httpEvent: HttpEvent<string[] | Blob>): void {
+    switch (httpEvent.type) {
+      case HttpEventType.UploadProgress:
+        this.updateStatus(httpEvent.loaded, httpEvent.total!, 'Uploading... ');
+        break;
+      case HttpEventType.DownloadProgress:
+        this.updateStatus(httpEvent.loaded, httpEvent.total!, 'Downloading... ');
+        break;
+      case HttpEventType.ResponseHeader:
+        console.log('Header returned', httpEvent);
+        break;
+      case HttpEventType.Response:
+        if (httpEvent.body instanceof Array) {
+          this.fileStatus.status = 'done';
+          for (const filename of httpEvent.body) {
+            this.files.unshift(filename);
+          }
+        } else {
+          saveAs(new Blob([httpEvent.body!],
+              { type: `${httpEvent.headers.get('Content-Type')};charset=utf-8`}),
+            httpEvent.headers.get('File-Name'));
+        }
+        this.fileStatus.status = 'done';
+        break;
+      default:
+        console.log(httpEvent);
+        break;
+
+    }
+  }
+
+  private updateStatus(loaded: number, total: number, requestType: string): void {
+    this.fileStatus.status = 'progress';
+    this.fileStatus.requestType = requestType;
+    this.fileStatus.percent = Math.round(100 * loaded / total);
+  }
+
+}
Index: Sources/frontend/src/app/question-details/question-details.component.css
===================================================================
--- Sources/frontend/src/app/question-details/question-details.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question-details/question-details.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,73 @@
+.title {
+  color: #3A98B9;
+}
+
+button {
+  border: none;
+  padding: 5px;
+  height: 50px;
+  border-radius: 5px;
+  background-color: #3A98B9;
+  cursor: pointer;
+  font-weight: normal;
+  font-size: large;
+  color: #FFF1DC;
+}
+
+small {
+  color: gray;
+}
+
+.container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+}
+
+.arrows {
+  display: flex;
+  flex-direction: column;
+  margin-bottom: 0;
+  padding-bottom: 0;
+  margin-right: 5px;
+  color: #3A98B9;
+}
+
+.answer-card {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.answer-card p {
+  background-color: #3A98B9;
+  padding: 10px;
+  width: 100%;
+  border-radius: 10px;
+  padding-top: 25px;
+  padding-bottom: 25px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.header {
+  margin-top: 10px;
+}
+
+.content {
+  background-color: #ffffff;
+  padding: 10px;
+  border-radius: 10px;
+}
+
+b {
+  color: rgba(51, 64, 136, 0.8);
+}
Index: Sources/frontend/src/app/question-details/question-details.component.html
===================================================================
--- Sources/frontend/src/app/question-details/question-details.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question-details/question-details.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,29 @@
+<div class="container">
+  <div class="header">
+    <h1>Детали за прашањето</h1>
+    <button routerLink="/add-answer/{{question?.id}}">Одговори на прашањето</button>
+  </div>
+  <hr>
+  <hr>
+  <h2 class="title">{{question?.title}}</h2>
+  <p class="content">{{question?.content}}</p>
+  <small>Поставено на:&nbsp;{{question?.dateAsked?.slice(0, 10)}}
+    од:&nbsp;&nbsp;{{question?.student?.name}} {{question?.student?.lastName}}</small>
+  <hr>
+  <div class="answer-card" *ngFor="let ans of answers">
+    <div class="arrows">
+      <svg (click)="likeAnswer(ans!!.id)" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
+           class="bi bi-arrow-up" viewBox="0 0 16 16">
+        <path fill-rule="evenodd"
+              d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z"/>
+      </svg>
+      <b>{{answersLikes.get(ans!!.id)}}</b>
+      <svg (click)="unlikeAnswer(ans!!.id)" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
+           fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
+        <path fill-rule="evenodd"
+              d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/>
+      </svg>
+    </div>
+    <p>{{ans?.content}}</p>
+  </div>
+</div>
Index: Sources/frontend/src/app/question-details/question-details.component.spec.ts
===================================================================
--- Sources/frontend/src/app/question-details/question-details.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question-details/question-details.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { QuestionDetailsComponent } from './question-details.component';
+
+describe('QuestionDetailsComponent', () => {
+  let component: QuestionDetailsComponent;
+  let fixture: ComponentFixture<QuestionDetailsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ QuestionDetailsComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(QuestionDetailsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/question-details/question-details.component.ts
===================================================================
--- Sources/frontend/src/app/question-details/question-details.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question-details/question-details.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,72 @@
+import {Component, OnInit} from '@angular/core';
+import {QuestionService} from "../question.service";
+import {QuestionInterface} from "../QuestionInterface";
+import {ActivatedRoute, Router} from "@angular/router";
+import {AnswerInterface} from "../AnswerInterface";
+import {LoginService} from "../login.service";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+
+@Component({
+  selector: 'app-question-details',
+  templateUrl: './question-details.component.html',
+  styleUrls: ['./question-details.component.css']
+})
+export class QuestionDetailsComponent implements OnInit {
+  question: QuestionInterface | undefined
+  answers: AnswerInterface[] = []
+  answersLikes = new Map<number, number>()
+  activeUser: ActiveUserInterface | undefined;
+
+  constructor(private questionService: QuestionService,
+              private route: ActivatedRoute,
+              private loginService: LoginService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    const id = Number(this.route.snapshot.paramMap.get('id'));
+    this.findQuestionById(id);
+    this.activeUser = this.loginService.activeUser;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+  }
+
+  findQuestionById(id: number) {
+    this.questionService.findQuestionById(id)
+      .subscribe(resp => {
+        this.question = resp;
+        this.questionService.findAnswersForQuestionWithId(id)
+          .subscribe(resp => {
+            this.answers = resp;
+            this.findLikesForAnswers()
+          })
+      });
+  }
+
+  findLikesForAnswers() {
+    this.answers.forEach(answer =>
+      this.questionService.findLikesForAnswer(answer.id)
+        .subscribe(number => this.answersLikes.set(answer.id, +number))
+    )
+  }
+
+  likeAnswer(id: number) {
+    // @ts-ignore
+    this.questionService.likeAnswer(id, this.activeUser!!.username, this.activeUser!!.userType)
+      .subscribe(number => {
+        this.answersLikes.delete(id);
+        this.answersLikes.set(id, +number);
+      })
+  }
+
+  unlikeAnswer(id: number) {
+    // @ts-ignore
+    this.questionService.unlikeAnswer(id, this.activeUser!!.username, this.activeUser!!.userType)
+      .subscribe(number => {
+        this.answersLikes.delete(id);
+        this.answersLikes.set(id, +number);
+      })
+  }
+
+}
Index: Sources/frontend/src/app/question-tagged-with-category-interface.ts
===================================================================
--- Sources/frontend/src/app/question-tagged-with-category-interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question-tagged-with-category-interface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,8 @@
+import {QuestionInterface} from "./QuestionInterface";
+import {CategoryInterface} from "./categoryInterface";
+
+export interface QuestionTaggedWithCategoryInterface {
+  id:number,
+  question:QuestionInterface,
+  category:CategoryInterface
+}
Index: Sources/frontend/src/app/question.service.spec.ts
===================================================================
--- Sources/frontend/src/app/question.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { QuestionService } from './question.service';
+
+describe('QuestionService', () => {
+  let service: QuestionService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(QuestionService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/question.service.ts
===================================================================
--- Sources/frontend/src/app/question.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,60 @@
+import {Injectable} from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {QuestionInterface} from "./QuestionInterface";
+import {AnswerInterface} from "./AnswerInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class QuestionService {
+
+  url = "http://localhost:8080/api/questions"
+  answersUrl = "http://localhost:8080/api/answers"
+  studentReactsUrl = "http://localhost:8080/api/student-reacts"
+  professorReactsUrl = "http://localhost:8080/api/professor-reacts"
+
+  constructor(private http: HttpClient) {
+  }
+
+  getAllQuestions(): Observable<QuestionInterface[]> {
+    return this.http.get<QuestionInterface[]>(this.url)
+  }
+
+  getAllQuestionsForCourse(id: number): Observable<QuestionInterface[]> {
+    return this.http.get<QuestionInterface[]>(`${this.url}/${id}`)
+  }
+
+  findQuestionById(id: number): Observable<QuestionInterface> {
+    return this.http.get<QuestionInterface>(`${this.url}/question/${id}`)
+  }
+
+  findAnswersForQuestionWithId(id: number): Observable<AnswerInterface[]> {
+    return this.http.get<AnswerInterface[]>(`${this.answersUrl}/question/${id}`)
+  }
+
+  findLikesForAnswer(id: number) {
+    return this.http.get(`${this.url}/likes/${id}`);
+  }
+
+
+  // @ts-ignore
+  likeAnswer(id: number, username: string, role: string){
+    if (role == 'PROFESSOR') {
+      return this.http.post(`${this.professorReactsUrl}/like/${id}`, username)
+    } else if (role == 'STUDENT') {
+      return this.http.post(`${this.studentReactsUrl}/like/${id}`, username)
+    }
+  }
+
+
+  // @ts-ignore
+  unlikeAnswer(id: number, username: string, role: string) {
+    if (role == 'PROFESSOR') {
+      return this.http.post(`${this.professorReactsUrl}/unlike/${id}`, username)
+    } else if (role == 'STUDENT') {
+      return this.http.post(`${this.studentReactsUrl}/unlike/${id}`, username)
+    }
+  }
+
+}
Index: Sources/frontend/src/app/question/question.component.css
===================================================================
--- Sources/frontend/src/app/question/question.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question/question.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,43 @@
+.card {
+  background-color: #3A98B9;
+  margin: 10px;
+  padding: 10px;
+  border-radius: 10px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+.header {
+  display: flex;
+  justify-content: space-between;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px 10px 5px 10px;
+  height: 50px;
+  margin: 5px;
+  border-radius: 7px;
+  cursor: pointer;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.buttons {
+  display: flex;
+}
+
+.card:hover {
+  box-shadow: 0 0 2px 2px #E1DDDD;
+}
Index: Sources/frontend/src/app/question/question.component.html
===================================================================
--- Sources/frontend/src/app/question/question.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question/question.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,17 @@
+<div class="container">
+  <h1>{{course?.name}}</h1>
+  <div class="header">
+    <h2>Прашања</h2>
+    <div class="buttons">
+      <button *ngIf="this.activeUser?.userType=='STUDENT'" routerLink="/add-question/{{course?.id}}">+ Прашање</button>
+      <button routerLink="/materials/{{course?.id}}">Материјали</button>
+    </div>
+  </div>
+
+  <div class="card" *ngFor="let q of questions" routerLink="/question-details/{{q?.id}}">
+    <h3>{{q?.title}}</h3>
+    <p>{{q?.content}}</p>
+  </div>
+
+</div>
+
Index: Sources/frontend/src/app/question/question.component.spec.ts
===================================================================
--- Sources/frontend/src/app/question/question.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question/question.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { QuestionComponent } from './question.component';
+
+describe('QuestionComponent', () => {
+  let component: QuestionComponent;
+  let fixture: ComponentFixture<QuestionComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ QuestionComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(QuestionComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/question/question.component.ts
===================================================================
--- Sources/frontend/src/app/question/question.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/question/question.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,47 @@
+import {Component} from '@angular/core';
+import {QuestionInterface} from "../QuestionInterface";
+import {QuestionService} from "../question.service";
+import {ActivatedRoute, Router} from "@angular/router";
+import {CourseService} from "../course.service";
+import {CourseInterface} from "../courseInterface";
+import {LoginService} from "../login.service";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+
+@Component({
+  selector: 'app-question',
+  templateUrl: './question.component.html',
+  styleUrls: ['./question.component.css']
+})
+export class QuestionComponent {
+  questions: QuestionInterface[] = []
+  course: CourseInterface | undefined;
+  activeUser: ActiveUserInterface | undefined;
+
+  constructor(private service: QuestionService,
+              private route: ActivatedRoute,
+              private courseService: CourseService,
+              private loginService: LoginService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    const id = Number(this.route.snapshot.paramMap.get('id'));
+    this.activeUser = this.loginService.activeUser;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+    this.findCourseById(id);
+    this.getAllQuestionsForCourse(id);
+  }
+
+  findCourseById(id: number) {
+    this.courseService.findCourseById(id).subscribe(resp => {
+      this.course = resp
+    })
+  }
+
+  getAllQuestionsForCourse(id: number) {
+    this.service.getAllQuestionsForCourse(id).subscribe(questions => this.questions = questions);
+  }
+
+}
Index: Sources/frontend/src/app/register.service.spec.ts
===================================================================
--- Sources/frontend/src/app/register.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/register.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { RegisterService } from './register.service';
+
+describe('RegisterService', () => {
+  let service: RegisterService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(RegisterService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/register.service.ts
===================================================================
--- Sources/frontend/src/app/register.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/register.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,34 @@
+import { Injectable } from '@angular/core';
+import {ActiveUserInterface} from "./ActiveUserInterface";
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {Router} from "@angular/router";
+import {LoginService} from "./login.service";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class RegisterService {
+
+  url = "http://localhost:8080/api/register"
+  activeUser: ActiveUserInterface | undefined;
+  constructor(private http:HttpClient,
+              private router: Router,
+              private loginService: LoginService) {
+  }
+  registerUser(name:string, lastName:string, email:string, username:string, password:string, userType:string, index:string){
+    const params = new HttpParams()
+      .append("name",name)
+      .append("lastName",lastName)
+      .append("email",email)
+      .append("username",username)
+      .append("password",password)
+      .append("userType",userType)
+      .append("index",index);
+    this.http.get<ActiveUserInterface>(this.url,{params:params})
+      .subscribe(resp =>{
+        this.activeUser = resp;
+        this.loginService.activeUser = this.activeUser;
+        this.router.navigate(['/allCourses']);
+      })
+  }
+}
Index: Sources/frontend/src/app/student-course.service.spec.ts
===================================================================
--- Sources/frontend/src/app/student-course.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { StudentCourseService } from './student-course.service';
+
+describe('StudentCourseService', () => {
+  let service: StudentCourseService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(StudentCourseService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/student-course.service.ts
===================================================================
--- Sources/frontend/src/app/student-course.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import {Observable} from "rxjs";
+import {StudentCourseInterface} from "./StudentCourseInterface";
+import {HttpClient, HttpParams} from "@angular/common/http";
+import {ProfessorCourseInterface} from "./ProfessorCourseInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class StudentCourseService {
+
+  url = "http://localhost:8080/api/student-courses"
+  urlProf = "http://localhost:8080/api/professor-courses"
+  constructor(private http: HttpClient) { }
+
+  getAllStudentCourses(): Observable<StudentCourseInterface[]> {
+    return this.http.get<StudentCourseInterface[]>(`${this.url}/all`)
+  }
+
+  getAllCoursesForActiveUserStudent(username:string) :  Observable<StudentCourseInterface[]> {
+    const params = new HttpParams().append('username', username);
+    return this.http.get<StudentCourseInterface[]>(this.url, {params: params})
+  }
+
+  getAllCoursesForActiveUserProfessor(username:string) :  Observable<ProfessorCourseInterface[]> {
+    const params = new HttpParams().append('username', username);
+    return this.http.get<ProfessorCourseInterface[]>(this.urlProf, {params: params})
+  }
+
+}
Index: Sources/frontend/src/app/student-course/student-course.component.css
===================================================================
--- Sources/frontend/src/app/student-course/student-course.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course/student-course.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,36 @@
+.card {
+  display: flex;
+  background-color: #3A98B9;
+  width: 200px;
+  height: 200px;
+  margin: 10px;
+  padding: 5px;
+  align-items: center;
+  justify-content: center;
+  border-radius: 10px;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.container {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.parent-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+a {
+  text-decoration: none;
+  color: #FFF1DC;
+}
+
+.card:hover {
+  box-shadow: 0 0 2px 2px #E1DDDD;
+}
Index: Sources/frontend/src/app/student-course/student-course.component.html
===================================================================
--- Sources/frontend/src/app/student-course/student-course.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course/student-course.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,20 @@
+<div class="parent-container">
+  <h1>Мои курсеви</h1>
+  <div class="container" *ngIf="this.activeUser?.userType=='STUDENT'">
+    <a class="card" *ngFor="let s of studentCourses"
+       routerLink="/details/{{s?.course?.id}}">
+      Курс: {{s?.course?.name}}
+    </a>
+  </div>
+  <div class="container" *ngIf="this.activeUser?.userType=='PROFESSOR'">
+    <div class="card" *ngFor="let s of professorCourses">
+      <a
+         (click)="saveCourseAsCurrent(s?.course?.id)"
+         routerLink="/details/{{s?.course?.id}}">
+        Курс:
+        <br>
+        {{s?.course?.name}}
+      </a>
+    </div>
+  </div>
+</div>
Index: Sources/frontend/src/app/student-course/student-course.component.spec.ts
===================================================================
--- Sources/frontend/src/app/student-course/student-course.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course/student-course.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StudentCourseComponent } from './student-course.component';
+
+describe('StudentCourseComponent', () => {
+  let component: StudentCourseComponent;
+  let fixture: ComponentFixture<StudentCourseComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ StudentCourseComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(StudentCourseComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/student-course/student-course.component.ts
===================================================================
--- Sources/frontend/src/app/student-course/student-course.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/student-course/student-course.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,45 @@
+import {Component, OnInit} from '@angular/core';
+import {StudentCourseService} from "../student-course.service";
+import {StudentCourseInterface} from "../StudentCourseInterface";
+import {LoginService} from "../login.service";
+import {ProfessorCourseInterface} from "../ProfessorCourseInterface";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-student-course',
+  templateUrl: './student-course.component.html',
+  styleUrls: ['./student-course.component.css']
+})
+export class StudentCourseComponent implements OnInit {
+
+  studentCourses: StudentCourseInterface[] = []
+  professorCourses: ProfessorCourseInterface[] = []
+  activeUser: ActiveUserInterface | undefined;
+
+  constructor(private service: StudentCourseService,
+              private loginService: LoginService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.activeUser = this.loginService.activeUser!!;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+    // console.log("username", this.activeUser.username)
+    if (this.loginService.activeUser!!.userType == 'STUDENT')
+      this.service.getAllCoursesForActiveUserStudent(this.activeUser.username)
+        .subscribe(studentCourses => this.studentCourses = studentCourses);
+    if (this.activeUser.userType == 'PROFESSOR')
+      this.service.getAllCoursesForActiveUserProfessor(this.activeUser.username)
+        .subscribe(professorCourses => this.professorCourses = professorCourses);
+  }
+
+  saveCourseAsCurrent(id: number): void {
+    console.log("course id", id)
+    this.loginService.setCurrentCourse(id);
+  }
+
+
+}
Index: Sources/frontend/src/app/subject.service.spec.ts
===================================================================
--- Sources/frontend/src/app/subject.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject.service.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { SubjectService } from './subject.service';
+
+describe('SubjectService', () => {
+  let service: SubjectService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(SubjectService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/subject.service.ts
===================================================================
--- Sources/frontend/src/app/subject.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject.service.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {Observable} from "rxjs";
+import {StudentCourseInterface} from "./StudentCourseInterface";
+import {SubjectInterface} from "./subjectInterface";
+
+@Injectable({
+  providedIn: 'root'
+})
+export class SubjectService {
+
+  url = "http://localhost:8080/api/subjects/all"
+  constructor(private http: HttpClient) { }
+
+  getAllSubjects(): Observable<SubjectInterface[]> {
+    return this.http.get<SubjectInterface[]>(this.url)
+  }
+}
Index: Sources/frontend/src/app/subject/subject.component.css
===================================================================
--- Sources/frontend/src/app/subject/subject.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject/subject.component.css	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,41 @@
+.card {
+  display: inline-block;
+  background-color: #3A98B9;
+  width: 100px;
+  height: 100px;
+  margin: 10px;
+  padding: 5px;
+  color: #FFF1DC;;
+  font-weight: normal;
+  font-size: large;
+}
+
+.container {
+  display: flex;
+}
+
+.parent-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 200px;
+  margin-right: 200px;
+}
+
+button {
+  background-color: #3A98B9;
+  border: none;
+  padding: 5px;
+  height: 50px;
+  width: 100px;
+  margin: 5px;
+  float: right;
+  cursor: pointer;
+  color: #FFF1DC;
+  font-weight: normal;
+  font-size: large;
+}
+
+.list {
+  display: flex;
+}
Index: Sources/frontend/src/app/subject/subject.component.html
===================================================================
--- Sources/frontend/src/app/subject/subject.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject/subject.component.html	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,14 @@
+<div class="parent-container" *ngIf="this.activeUser!!.userType == 'PROFESSOR'">
+  <h1>Сите Предмети</h1>
+  <form class="example-form" class="list">
+    <div *ngFor="let s of subjects">
+      <input type="radio" name="radio-btns" (change)="onChange({event : $event, id : {id : s.id}})">
+      <label>
+        <p class="card">
+          {{s?.name}}
+        </p>
+      </label>
+    </div>
+  </form>
+</div>
+<app-all-courses [subjectId]="subjectId"></app-all-courses>
Index: Sources/frontend/src/app/subject/subject.component.spec.ts
===================================================================
--- Sources/frontend/src/app/subject/subject.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject/subject.component.spec.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SubjectComponent } from './subject.component';
+
+describe('SubjectComponent', () => {
+  let component: SubjectComponent;
+  let fixture: ComponentFixture<SubjectComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ SubjectComponent ]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(SubjectComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: Sources/frontend/src/app/subject/subject.component.ts
===================================================================
--- Sources/frontend/src/app/subject/subject.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subject/subject.component.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,46 @@
+import {Component, ViewChild} from '@angular/core';
+import {SubjectInterface} from "../subjectInterface";
+import {SubjectService} from "../subject.service";
+import {ActiveUserInterface} from "../ActiveUserInterface";
+import {LoginService} from "../login.service";
+import {AllCoursesComponent} from "../all-courses/all-courses.component";
+import {Router} from "@angular/router";
+
+@Component({
+  selector: 'app-subject',
+  templateUrl: './subject.component.html',
+  styleUrls: ['./subject.component.css']
+})
+export class SubjectComponent {
+
+  subjects: SubjectInterface[] = [];
+  subjectId: number | undefined;
+  activeUser: ActiveUserInterface | undefined;
+  @ViewChild(AllCoursesComponent) child!: AllCoursesComponent;
+
+  constructor(private service: SubjectService,
+              private loginService: LoginService,
+              private router: Router) {
+  }
+
+  ngOnInit(): void {
+    this.activeUser = this.loginService.activeUser!!;
+    if (!this.activeUser) {
+      this.router.navigate(['/'])
+    }
+    this.service.getAllSubjects()
+      .subscribe(subjects => this.subjects = subjects);
+  }
+
+  onChange({event, id}: { event: any, id: any }) {
+    if (event.target.checked) {
+      // @ts-ignore
+      this.subjectId = id
+      this.child.loadCourses(id.id);
+    } else {
+      // @ts-ignore
+      this.subjectId = null;
+    }
+  }
+
+}
Index: Sources/frontend/src/app/subjectInterface.ts
===================================================================
--- Sources/frontend/src/app/subjectInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
+++ Sources/frontend/src/app/subjectInterface.ts	(revision 84234294abb1e8ce0876e888a7bec532eaeb6a14)
@@ -0,0 +1,7 @@
+import {AdminInterface} from "./AdminInterface";
+
+export interface SubjectInterface{
+  id: number,
+  name: string,
+  admin: AdminInterface
+}
