Index: src/main/java/com/db/finki/www/build_board/controller/thread_controllers/ProjectController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/thread_controllers/ProjectController.java	(revision 31a10a2c5c223b9dad338541ec34e59e1d1f69b5)
+++ src/main/java/com/db/finki/www/build_board/controller/thread_controllers/ProjectController.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -59,4 +59,14 @@
     }
 
+    @GetMapping("/{pr_title}/members")
+    public String getProjectMembersPage(
+            Model model,
+            @PathVariable(name = "pr_title") Project project
+    )
+    {
+        model.addAttribute("project", project);
+        return "project_pages/members";
+    }
+
     @PreAuthorize("project.getUser().username.equals(username)")
     @PostMapping("/{title}/modify")
@@ -103,4 +113,5 @@
         return "redirect:/" ;
     }
+
 }
 ///projects/topics/add
Index: src/main/java/com/db/finki/www/build_board/controller/thread_controllers/requests/ProjectRequestController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/thread_controllers/requests/ProjectRequestController.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ src/main/java/com/db/finki/www/build_board/controller/thread_controllers/requests/ProjectRequestController.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,21 @@
+package com.db.finki.www.build_board.controller.thread_controllers.requests;
+
+import com.db.finki.www.build_board.entity.threads.Project;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+@RequestMapping("/project/{pr_title}/requests")
+public class ProjectRequestController {
+    @GetMapping("/")
+    public String getRequestPage(
+            Model model,
+            @PathVariable(name = "pr_title") Project project
+    ) {
+        model.addAttribute("requests", project.getRequests());
+        return "project_pages/requests/show-requests";
+    }
+}
Index: src/main/java/com/db/finki/www/build_board/entity/requests/ProjectRequests.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/requests/ProjectRequests.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ src/main/java/com/db/finki/www/build_board/entity/requests/ProjectRequests.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,29 @@
+package com.db.finki.www.build_board.entity.requests;
+
+import com.db.finki.www.build_board.entity.threads.Project;
+import com.db.finki.www.build_board.entity.user_types.BBUser;
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@Entity
+@Table(name = "project_request")
+public class ProjectRequests {
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "project_req_gen")
+    @SequenceGenerator(name = "project_req_gen", sequenceName = "project_request_id_seq", initialValue = 1, allocationSize = 1)
+    private Integer id;
+    private String description;
+
+    @ManyToOne
+    @JoinColumn(name = "project_id")
+    Project project;
+
+    @ManyToOne
+    @JoinColumn(name = "user_id")
+    BBUser creator;
+}
Index: src/main/java/com/db/finki/www/build_board/entity/requests/Report.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/requests/Report.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ src/main/java/com/db/finki/www/build_board/entity/requests/Report.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,4 @@
+package com.db.finki.www.build_board.entity.requests;
+
+public class Report {
+}
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Project.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Project.java	(revision 31a10a2c5c223b9dad338541ec34e59e1d1f69b5)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Project.java	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -1,15 +1,20 @@
 package com.db.finki.www.build_board.entity.threads;
 
+import com.db.finki.www.build_board.entity.requests.ProjectRequests;
 import com.db.finki.www.build_board.entity.user_types.BBUser;
 import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+import com.db.finki.www.build_board.entity.user_types.Developer;
 import jakarta.persistence.*;
 import lombok.*;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 //TODO: project request
 //TODO: crud na kanali
-@Data
+@Getter
+@Setter
 @NoArgsConstructor
 @EqualsAndHashCode(callSuper = false)
@@ -33,4 +38,15 @@
     private List<Topic> topics = new ArrayList<>();
 
+    @ManyToMany
+    @JoinTable(
+            name ="developer_associated_with_project",
+            joinColumns = @JoinColumn(name = "project_id"),
+            inverseJoinColumns = @JoinColumn(name = "developer_id")
+    )
+    private Set<Developer> developers = new HashSet<>();
+
+    @OneToMany(mappedBy = "project")
+    private Set<ProjectRequests> requests = new HashSet<>();
+
     @Override
     public String getTypeName() {
Index: src/main/resources/db/migration/V1__init_ddl.sql
===================================================================
--- src/main/resources/db/migration/V1__init_ddl.sql	(revision 31a10a2c5c223b9dad338541ec34e59e1d1f69b5)
+++ src/main/resources/db/migration/V1__init_ddl.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -93,5 +93,5 @@
 CREATE TABLE project_thread
 (
-    title    VARCHAR(256) NOT NULL,
+    title    VARCHAR(256) UNIQUE NOT NULL,
     repo_url TEXT,
     id       INT PRIMARY KEY REFERENCES thread (id) on delete cascade
Index: src/main/resources/templates/project_pages/members.html
===================================================================
--- src/main/resources/templates/project_pages/members.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ src/main/resources/templates/project_pages/members.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Members</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+    <style>
+        body {
+            background-color: #f8f9fa; /* Light background for the whole page */
+        }
+
+        .card {
+            background-color: #ffffff; /* White background for the cards */
+            border: 1px solid #dde2e6; /* Light grey border */
+            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
+            transition: transform 0.3s ease, box-shadow 0.3s ease;
+            height: 350px; /* Fixed height for larger cards */
+        }
+
+        .card:hover {
+            transform: translateY(-5px); /* Slight lift on hover */
+            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); /* Stronger shadow on hover */
+        }
+
+        .card-header {
+            background-color: #007bff; /* Blue header color */
+            color: #ffffff; /* White text */
+            font-weight: bold;
+        }
+
+        .card-body {
+            background-color: #f1f3f5; /* Light grey background */
+            color: #495057; /* Dark text */
+            height: 200px; /* Larger height for the card body */
+            overflow-y: auto; /* Allow scrolling if content exceeds height */
+        }
+
+        .card-footer {
+            background-color: #f8f9fa;
+            color: #495057;
+        }
+
+        .card-title {
+            color: #000000; /* Dark text color for card title */
+        }
+
+        .card-text {
+            color: #6c757d; /* Grey text for descriptions */
+        }
+
+        .btn-link {
+            color: #007bff; /* Blue accent for buttons */
+        }
+
+        .container-header {
+            margin-top: 50px;
+            text-align: center;
+        }
+    </style>
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+
+<header class="container container-header mb-5">
+    <h1 class="text-primary" th:text="|${project.getTitle()} members|">Projects Tittles</h1>
+</header>
+<main class="d-flex justify-content-center align-content-center ">
+    <div class="list-group w-75">
+        <!--    <div class="list-group-item" th:with="creator=${project.getUser()}">-->
+        <!--      <img th:src="${creator.getAvatarUrl()}">-->
+        <!--      <h5 class="mb-1 d-flex">-->
+        <!--        <a th:href="@{/{username}/profile (username=${creator.getName()})}"-->
+        <!--           th:text="${creator.getName()}" class="text-decoration-none"></a>-->
+        <!--      </h5>-->
+        <!--      <h5>Creator</h5>-->
+        <!--    </div>-->
+        <div class="list-group-item d-flex gap-2 justify-content-between align-items-center ps-4 pe-4"
+             th:each="member : ${project.getDevelopers()}">
+            <div class="d-flex flex-row align-items-center gap-3">
+                <img class="rounded-circle border border-1 border-info"
+                     style="width: 5em; height: 5em" th:src="${member.getAvatarUrl()}">
+                <h5 class="mb-1 d-flex">
+                    <a th:href="@{/{username}/profile (username=${member.getUsername()})}"
+                       th:text="${member.getUsername()}"
+                        class="text-decoration-none"
+                    ></a>
+                </h5>
+            </div>
+            <h5 class="fw-lighter fst-italic">Developer</h5>
+        </div>
+    </div>
+    </div>
+</main>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: c/main/resources/templates/project_pages/project.html
===================================================================
--- src/main/resources/templates/project_pages/project.html	(revision 31a10a2c5c223b9dad338541ec34e59e1d1f69b5)
+++ 	(revision )
@@ -1,137 +1,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Projects</title>
-  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
-  <style>
-    body {
-      background-color: #f8f9fa; /* Light background for the whole page */
-    }
-    .card {
-      background-color: #ffffff; /* White background for the cards */
-      border: 1px solid #dde2e6; /* Light grey border */
-      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
-      transition: transform 0.3s ease, box-shadow 0.3s ease;
-      height: 350px; /* Fixed height for larger cards */
-    }
-    .card:hover {
-      transform: translateY(-5px); /* Slight lift on hover */
-      box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); /* Stronger shadow on hover */
-    }
-    .card-header {
-      background-color: #007bff; /* Blue header color */
-      color: #ffffff; /* White text */
-      font-weight: bold;
-    }
-    .card-body {
-      background-color: #f1f3f5; /* Light grey background */
-      color: #495057; /* Dark text */
-      height: 200px; /* Larger height for the card body */
-      overflow-y: auto; /* Allow scrolling if content exceeds height */
-    }
-    .card-footer {
-      background-color: #f8f9fa;
-      color: #495057;
-    }
-    .card-title {
-      color: #000000; /* Dark text color for card title */
-    }
-    .card-text {
-      color: #6c757d; /* Grey text for descriptions */
-    }
-    .btn-link {
-      color: #007bff; /* Blue accent for buttons */
-    }
-    .container-header {
-      margin-top: 50px;
-      text-align: center;
-    }
-  </style>
-</head>
-<body>
-<div th:replace="/home_pages/home :: navigation"></div>
-
-<header class="container container-header">
-  <h1 class="text-primary">Projects</h1>
-  <h2 class="text-muted">View All Projects</h2>
-</header>
-
-<div class="container pt-5">
-  <!-- Card 1 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 1</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 1.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject1" aria-expanded="false" aria-controls="collapseProject1">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject1">
-        <div class="card card-body">
-          <p>More detailed information about Project 1...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 2 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 2</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 2.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject2" aria-expanded="false" aria-controls="collapseProject2">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject2">
-        <div class="card card-body">
-          <p>More detailed information about Project 2...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 3 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 3</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 3.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject3" aria-expanded="false" aria-controls="collapseProject3">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject3">
-        <div class="card card-body">
-          <p>More detailed information about Project 3...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Card 4 -->
-  <div class="card mb-4">
-    <div class="card-header">
-      <h2 class="card-title">Project 4</h2>
-    </div>
-    <div class="card-body">
-      <p class="card-text">Short description of Project 4.</p>
-      <button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseProject4" aria-expanded="false" aria-controls="collapseProject4">
-        Learn More
-      </button>
-      <div class="collapse mt-3" id="collapseProject4">
-        <div class="card card-body">
-          <p>More detailed information about Project 4...</p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-</div>
-
-<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
-</body>
-</html>
Index: src/main/resources/templates/project_pages/requests/show-requests.html
===================================================================
--- src/main/resources/templates/project_pages/requests/show-requests.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ src/main/resources/templates/project_pages/requests/show-requests.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Requests</title>
+</head>
+<body>
+<header>
+    <div th:replace="/home_pages/home :: navigation"></div>
+</header>
+<main>
+
+</main>
+</body>
+</html>
Index: src/main/resources/templates/project_pages/show-project.html
===================================================================
--- src/main/resources/templates/project_pages/show-project.html	(revision 31a10a2c5c223b9dad338541ec34e59e1d1f69b5)
+++ src/main/resources/templates/project_pages/show-project.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -1,4 +1,4 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
 <head>
     <meta charset="UTF-8">
@@ -15,15 +15,33 @@
         <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
             <h3 th:text="${project.getTitle()}">Project Title</h3>
-            <div th:if="${isManager}" class="d-flex flex-row gap-2">
-                <button
-                        class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">Add Tag
-                </button>
+            <div class="d-flex flex-row gap-2">
+                <th:object th:if="${isManager}">
+                    <button
+                            class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">Add Tag
+                    </button>
+                    <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/topic/add(pr_title=${project.getTitle()})}">Add Topic</a>
+                    </button>
+                    <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/modify(pr_title=${project.getTitle()})}">Modify project</a>
+                    </button>
+                    <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/requets(pr_title=${project.getTitle()})}">View project requests</a>
+                    </button>
+                </th:object>
                 <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
                     <a class="text-decoration-none text-reset"
-                       th:href="@{/project/{pr_title}/topic/add(pr_title=${project.getTitle()})}">Add Topic</a>
+                       th:href="@{/project/{pr_title}/members(pr_title=${project.getTitle()})}">Show members</a>
                 </button>
-                <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                <button th:if="${session.user != null && !project.getUser().equals(session.user)
+                 && !project.getDevelopers().contains(session.user)}"
+                        class="btn btn-success btn-sm"
+                        data-bs-toggle="modal"
+                        data-bs-target="#addTagModal">
                     <a class="text-decoration-none text-reset"
-                       th:href="@{/project/{pr_title}/modify(pr_title=${project.getTitle()})}">Modify project</a>
+                       th:href="@{/project/{pr_title}/requests/add(pr_title=${project.getTitle()})}">Send request</a>
                 </button>
             </div>
Index: target/classes/application.properties
===================================================================
--- target/classes/application.properties	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/application.properties	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,13 @@
+spring.application.name=build_board
+
+spring.datasource.username=${POSTGRES_USER}
+spring.datasource.password=${POSTGRES_PASSWORD}
+spring.datasource.url=jdbc:postgresql://localhost:5432/${POSTGRES_DB}
+
+spring.flyway.password=${POSTGRES_PASSWORD}
+spring.flyway.user=${POSTGRES_USER}
+spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.show-sql=true
+
+avatar.upload-dir=/uploads/user-avatars
+logging.level.org.springframework.security=DEBUG
Index: target/classes/db/migration/U1__remove_ddl.sql
===================================================================
--- target/classes/db/migration/U1__remove_ddl.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/db/migration/U1__remove_ddl.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,37 @@
+DROP TABLE IF EXISTS users CASCADE;
+DROP TABLE IF EXISTS moderator CASCADE;
+DROP TABLE IF EXISTS developer CASCADE;
+DROP TABLE IF EXISTS project_manager CASCADE;
+DROP TABLE IF EXISTS thread CASCADE;
+DROP TABLE IF EXISTS likes CASCADE;
+DROP TABLE IF EXISTS topic_threads_moderators CASCADE;
+DROP TABLE IF EXISTS tag CASCADE;
+DROP TABLE IF EXISTS tag_threads CASCADE;
+DROP TABLE IF EXISTS topic_thread CASCADE;
+DROP TABLE IF EXISTS topic_belongs_to_project CASCADE;
+DROP TABLE IF EXISTS blacklisted_user CASCADE;
+DROP TABLE IF EXISTS project_thread CASCADE;
+DROP TABLE IF EXISTS discussion_thread CASCADE;
+DROP TABLE IF EXISTS developer_associated_with_project CASCADE;
+DROP TABLE IF EXISTS permissions CASCADE;
+DROP TABLE IF EXISTS project_roles CASCADE;
+DROP TABLE IF EXISTS users_project_roles CASCADE;
+DROP TABLE IF EXISTS project_roles_permissions CASCADE;
+DROP TABLE IF EXISTS project_request CASCADE;
+DROP TABLE IF EXISTS report CASCADE;
+DROP TABLE IF EXISTS channel CASCADE;
+DROP TABLE IF EXISTS messages CASCADE;
+DROP TABLE IF EXISTS threads_moderators CASCADE;
+DROP TYPE IF EXISTS status;
+DROP VIEW IF EXISTS v_topic_thread CASCADE;
+DROP VIEW IF EXISTS v_project_thread CASCADE;
+DROP VIEW IF EXISTS v_discussion_thread CASCADE;
+DROP VIEW IF EXISTS v_developer CASCADE;
+DROP VIEW IF EXISTS v_project_owner CASCADE;
+DROP VIEW IF EXISTS v_moderator CASCADE;
+drop function if exists fn_insert_project_manager CASCADE;
+drop function if exists fn_insert_topics_creator_as_moderator CASCADE;
+drop function if exists fn_validate_topic_title CASCADE;
+drop function if exists clean_tables CASCADE;
+drop function if exists clean_routines CASCADE;
+DROP TRIGGER IF EXISTS validate_same_parent ON discussion_thread CASCADE;
Index: target/classes/db/migration/V1__init_ddl.sql
===================================================================
--- target/classes/db/migration/V1__init_ddl.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/db/migration/V1__init_ddl.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,451 @@
+--- Trigger before update/insert za check na iminjata topic/discussion -> OK
+--- Trigger za ko ke adnit dete na topic thread sho e vo proekt, da go dodajt kako belongs_to vo proektot
+--- Trigger za check dali reply na discussion thread pripagjat na ist topic thread kako na toj so mu pret reply
+--- IMENUVANJE: triggeri so provervat nesto prefix = check, funkcii za istite prefix = validate
+--- Nemame contraint sho velit deka sekoj topic thread trebat da e moderiran
+DROP TABLE IF EXISTS users CASCADE;
+DROP TABLE IF EXISTS moderator CASCADE;
+DROP TABLE IF EXISTS developer CASCADE;
+DROP TABLE IF EXISTS project_manager CASCADE;
+DROP TABLE IF EXISTS thread CASCADE;
+DROP TABLE IF EXISTS likes CASCADE;
+DROP TABLE IF EXISTS topic_threads_moderators CASCADE;
+DROP TABLE IF EXISTS tag CASCADE;
+DROP TABLE IF EXISTS tag_threads CASCADE;
+DROP TABLE IF EXISTS topic_thread CASCADE;
+DROP TABLE IF EXISTS topic_belongs_to_project CASCADE;
+DROP TABLE IF EXISTS blacklisted_user CASCADE;
+DROP TABLE IF EXISTS project_thread CASCADE;
+DROP TABLE IF EXISTS discussion_thread CASCADE;
+DROP TABLE IF EXISTS developer_associated_with_project CASCADE;
+DROP TABLE IF EXISTS permissions CASCADE;
+DROP TABLE IF EXISTS project_roles CASCADE;
+DROP TABLE IF EXISTS users_project_roles CASCADE;
+DROP TABLE IF EXISTS project_roles_permissions CASCADE;
+DROP TABLE IF EXISTS project_request CASCADE;
+DROP TABLE IF EXISTS report CASCADE;
+DROP TABLE IF EXISTS channel CASCADE;
+DROP TABLE IF EXISTS messages CASCADE;
+DROP TABLE IF EXISTS threads_moderators CASCADE;
+DROP TYPE IF EXISTS status;
+DROP VIEW IF EXISTS v_topic_thread CASCADE;
+DROP VIEW IF EXISTS v_project_thread CASCADE;
+DROP VIEW IF EXISTS v_discussion_thread CASCADE;
+DROP VIEW IF EXISTS v_developer CASCADE;
+DROP VIEW IF EXISTS v_project_owner CASCADE;
+DROP VIEW IF EXISTS v_moderator CASCADE;
+drop function if exists fn_insert_project_manager CASCADE;
+drop function if exists fn_insert_topics_creator_as_moderator CASCADE;
+drop function if exists fn_validate_topic_title CASCADE;
+drop function if exists clean_tables CASCADE;
+drop function if exists clean_routines CASCADE;
+DROP TRIGGER IF EXISTS validate_same_parent ON discussion_thread CASCADE;
+
+---- DDL
+CREATE TABLE users
+(
+    id            SERIAL PRIMARY KEY,
+    username      VARCHAR(32) UNIQUE NOT NULL,
+    email         varchar(60)        not null,
+    name          varchar(32)        not null,
+    is_activate   bool DEFAULT true,
+    password      VARCHAR(72),
+    description   VARCHAR(200),
+    registered_at TIMESTAMP DEFAULT NOW(),
+    sex           VARCHAR(1)
+);
+CREATE TABLE moderator
+(
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
+);
+CREATE TABLE developer
+(
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
+);
+CREATE TABLE project_manager
+(
+    id INT PRIMARY KEY REFERENCES users (id) on delete cascade
+);
+CREATE TABLE thread
+(
+    id      SERIAL PRIMARY KEY,
+    content TEXT,
+    user_id INT REFERENCES users (id) NOT NULL
+);
+CREATE TABLE topic_thread
+(
+    title     VARCHAR(256) NOT NULL,
+    parent_id INT REFERENCES thread (id) on delete cascade,
+    id        INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+);
+create table topic_guidelines
+(
+    id          serial,
+    topic_id    int references topic_thread (id) on delete cascade,
+    description text,
+    PRIMARY KEY (id, topic_id)
+);
+CREATE TABLE discussion_thread
+(
+    parent_id INT REFERENCES thread (id) on delete cascade NOT NULL,
+    id        INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+);
+CREATE TABLE project_thread
+(
+    title    VARCHAR(256) UNIQUE NOT NULL,
+    repo_url TEXT,
+    id       INT PRIMARY KEY REFERENCES thread (id) on delete cascade
+);
+CREATE TABLE likes
+(
+    user_id   INT REFERENCES users (id) on delete cascade ,
+    thread_id INT REFERENCES thread (id) on delete cascade,
+    PRIMARY KEY (user_id, thread_id)
+);
+CREATE TABLE topic_threads_moderators
+(
+    thread_id INT REFERENCES thread (id) ON DELETE CASCADE,
+    user_id   INT REFERENCES users (id) ON DELETE CASCADE,
+    PRIMARY KEY (thread_id, user_id)
+);
+CREATE TABLE tag
+(
+    name VARCHAR(64) PRIMARY KEY
+);
+CREATE TABLE tag_threads
+(
+    thread_id INT REFERENCES thread (id) ON DELETE CASCADE,
+    tag_name  VARCHAR(64) REFERENCES tag (name) ON DELETE CASCADE,
+    PRIMARY KEY (thread_id, tag_name)
+);
+
+CREATE TABLE topic_belongs_to_project
+(
+    topic_id   INT REFERENCES thread (id) ON DELETE CASCADE,
+    project_id INT REFERENCES thread (id) ON DELETE CASCADE,
+    PRIMARY KEY (topic_id, project_id)
+);
+CREATE TABLE blacklisted_user
+(
+    topic_id     INT REFERENCES thread (id) ON DELETE CASCADE,
+    user_id      INT REFERENCES users (id) ON DELETE CASCADE,
+    moderator_id INT REFERENCES users (id) ON DELETE CASCADE,
+    start_date   TIMESTAMP,
+    end_date     TIMESTAMP,
+    reason       TEXT,
+    PRIMARY KEY (user_id, moderator_id, topic_id, start_date)
+);
+
+CREATE TABLE developer_associated_with_project
+(
+    project_id   INT REFERENCES thread (id) on delete cascade,
+    developer_id INT REFERENCES users (id) on delete cascade,
+    started_at   TIMESTAMP DEFAULT NOW(),
+    ended_at     TIMESTAMP,
+    PRIMARY KEY (project_id, developer_id, started_at)
+);
+CREATE TABLE permissions
+(
+    name VARCHAR(32) PRIMARY KEY
+);
+CREATE TABLE project_roles
+(
+    name        VARCHAR(32),
+    project_id  INT REFERENCES thread (id) ON DELETE CASCADE,
+    description TEXT,
+    PRIMARY KEY (name, project_id)
+);
+CREATE TABLE users_project_roles
+(
+    user_id    INT REFERENCES users (id) on delete cascade,
+    project_id INT,
+    role_name  VARCHAR(32),
+    FOREIGN KEY (role_name, project_id)
+        REFERENCES project_roles (name, project_id) ON DELETE CASCADE,
+    PRIMARY KEY (user_id, project_id, role_name)
+);
+CREATE TABLE project_roles_permissions
+(
+    permission_name VARCHAR(32) REFERENCES permissions (name),
+    role_name       VARCHAR(32),
+    project_id      INT,
+    PRIMARY KEY (permission_name, role_name, project_id),
+    FOREIGN KEY (role_name, project_id)
+        REFERENCES project_roles (name, project_id) ON DELETE CASCADE
+);
+CREATE TYPE status AS ENUM ('ACCEPTED', 'DENIED', 'PENDING');
+CREATE TABLE project_request
+(
+    id          SERIAL PRIMARY KEY,
+    description VARCHAR(200),
+    status      status                     NOT NULL,
+    user_id     INT REFERENCES users (id)  ON DELETE CASCADE NOT NULL ,
+    project_id  INT REFERENCES thread (id) ON DELETE CASCADE NOT NULL
+);
+CREATE TABLE report
+(
+    id          SERIAL,
+    created_at  TIMESTAMP,
+    description VARCHAR(200) NOT NULL,
+    status      status,
+    thread_id   INT REFERENCES thread (id) on delete cascade,
+    for_user_id INT REFERENCES users (id) on delete cascade,
+    by_user_id  INT REFERENCES users (id) on delete cascade,
+    PRIMARY KEY (id, thread_id, for_user_id, by_user_id)
+);
+CREATE TABLE channel
+(
+    name         VARCHAR(64),
+    description  VARCHAR(200),
+    project_id   INT REFERENCES thread (id) ON DELETE CASCADE,
+    developer_id INT REFERENCES users (id),
+    PRIMARY KEY (name, project_id)
+);
+CREATE TABLE messages
+(
+    sent_at      TIMESTAMP,
+    content      VARCHAR(200) NOT NULL,
+    sent_by      INT REFERENCES users (id),
+    project_id   INT,
+    channel_name VARCHAR(64),
+    FOREIGN KEY (channel_name, project_id)
+        REFERENCES channel (name, project_id) ON DELETE CASCADE,
+    PRIMARY KEY (channel_name, project_id, sent_at, sent_by)
+);
+
+
+------------------------VIEWS-----------------------------
+CREATE OR REPLACE VIEW v_project_thread
+AS
+SELECT thread.id, content, user_id, title, repo_url
+FROM project_thread project
+         JOIN thread
+              ON project.id = thread.id;
+-- CREATE OR REPLACE VIEW v_discussion_thread
+-- AS
+-- SELECT thread.id, content, user_id, parent_id
+-- FROM discussion_thread discussion
+--          JOIN thread
+--               ON discussion.id = thread.id;
+CREATE OR REPLACE VIEW v_topic_thread
+AS
+SELECT thread.id, content, user_id, title, parent_id
+FROM topic_thread topic
+         JOIN thread
+              ON topic.id = thread.id;
+CREATE OR REPLACE VIEW v_moderator
+AS
+SELECT users.id, username, is_activate, password, description, registered_at, sex
+FROM moderator
+         JOIN users ON moderator.id = users.id;
+
+CREATE OR REPLACE VIEW v_developer
+AS
+SELECT users.id, username, is_activate, password, description, registered_at, sex
+FROM developer
+         JOIN users ON developer.id = users.id;
+CREATE OR REPLACE VIEW v_project_owner
+AS
+SELECT users.id, username, is_activate, password, description, registered_at, sex
+FROM project_manager
+         JOIN users ON project_manager.id = users.id;
+CREATE OR REPLACE VIEW v_moderator
+AS
+SELECT users.id, username, is_activate, password, description, registered_at, sex
+FROM moderator
+         JOIN users ON moderator.id = users.id;
+
+CREATE OR REPLACE VIEW v_developer
+AS
+SELECT users.id, username, is_activate, password, description, registered_at, sex
+FROM developer
+         JOIN users ON developer.id = users.id;
+
+create or replace view v_discussion_thread
+as
+with recursive
+    depth_table as
+        (select parent_id, id, 0 as depth
+         from discussion_thread
+         UNION ALL
+         select discuss.parent_id, dpth.id, dpth.depth + 1
+         from depth_table dpth
+                  join discussion_thread discuss
+                       on dpth.parent_id = discuss.id),
+    tmp as (select id, max(depth) as depth
+            from depth_table
+            group by id)
+select d.id as id, t.user_id as user_id, d.depth as depth, d1.parent_id as parent_id
+from tmp d
+         join depth_table d1
+              on d.id = d1.id and d1.depth = d.depth
+         join thread t
+              on t.id = d.id;
+-------------------------- FUNCTIONS ----------------------
+CREATE OR REPLACE FUNCTION fn_validate_topic_title()
+    RETURNS TRIGGER
+    LANGUAGE plpgsql
+AS
+$$
+BEGIN
+    IF new.title IN
+       (SELECT title
+        FROM topic_thread
+                 AS t
+        WHERE t.parent_id = new.parent_id
+           OR (t.parent_id IS NULL AND new.parent_id IS NULL))
+    THEN
+        RAISE EXCEPTION 'There already exists a topic with title % in parent topic with id %',new.title,new.parent_id;
+    END IF;
+    RETURN new;
+END;
+$$;
+create function check_if_user_exists_in(table_name text, field_name text, field_value text) returns boolean
+    language plpgsql
+as
+$$
+DECLARE
+    result BOOL;
+BEGIN
+    EXECUTE format('SELECT EXISTS (SELECT 1 FROM %I WHERE %I = %L)', table_name, field_name, field_value)
+        INTO result;
+    RETURN result;
+END
+$$;
+CREATE OR REPLACE FUNCTION fn_insert_topics_creator_as_moderator()
+    RETURNS TRIGGER
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    v_user_id INT;
+BEGIN
+    SELECT v_topic_thread.user_id
+    INTO v_user_id
+    FROM v_topic_thread
+    WHERE v_topic_thread.id = new.id;
+    IF not check_if_user_exists_in('moderator', 'id', v_user_id::text) THEN
+        INSERT INTO topic_threads_moderators(thread_id, user_id) VALUES (new.id, v_user_id);
+    END IF;
+    RETURN NEW;
+END
+$$;
+
+CREATE OR REPLACE FUNCTION fn_insert_project_manager()
+    RETURNS TRIGGER
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    usrId      INT;
+    new_project_id INT;
+BEGIN
+    SELECT user_id, id
+    into usrId,new_project_id
+    FROM v_project_thread p
+    WHERE NEW.id = p.id;
+    IF not check_if_user_exists_in('developer', 'id', usrId::text) THEN
+        INSERT INTO developer VALUES (usrId);
+        IF NOT EXISTS (
+            select 1
+            from developer_associated_with_project dp
+            where dp.project_id=new_project_id and dp.developer_id=usrId
+        )
+        THEN
+            INSERT INTO developer_associated_with_project(project_id, developer_id, started_at)
+            values (new_project_id, usrId, NOW());
+        END IF;
+    end if;
+    IF not check_if_user_exists_in('project_manager', 'id', usrId::text) THEN
+        INSERT INTO project_manager VALUES (usrId);
+    end if;
+    RETURN NEW;
+END
+$$;
+create or replace function fn_remove_unused_tags()
+    returns trigger
+    language plpgsql
+as
+$$
+BEGIN
+    IF not check_if_user_exists_in('tag_threads', 'tag_name', old.tag_name)
+    THEN
+        raise notice 'kakosi';
+        delete from tag t where t.name = old.tag_name;
+    end if;
+    return old;
+end;
+$$;
+create or replace function fn_remove_not_active_project_manager()
+    returns trigger
+    language plpgsql
+as
+$$
+DECLARE
+    creator_id int;
+begin
+    select user_id
+    into creator_id
+    from thread t
+    where t.id = old.id;
+
+    IF NOT EXISTS(select 1
+                  from thread t
+                  where t.id in (select id from project_thread)
+                    and t.user_id = creator_id) THEN
+        delete from project_manager where id = creator_id;
+    end if;
+    return new;
+end
+$$;
+
+create or replace function fn_remove_not_active_developer()
+    returns trigger
+    language plpgsql
+as
+$$
+begin
+    IF not check_if_user_exists_in('developer_associated_with_project','developer_id',old.developer_id::text)
+    THEN
+        delete from developer d
+        where d.id=old.developer_id;
+    end if;
+    return new;
+end
+$$;
+
+-------------------------- TRIGGERS ----------------------
+CREATE OR REPLACE TRIGGER tr_check_topic_name
+    BEFORE INSERT OR UPDATE
+    ON topic_thread
+    FOR EACH ROW
+EXECUTE FUNCTION fn_validate_topic_title();
+CREATE OR REPLACE TRIGGER tr_insert_topics_creator_as_moderator
+    AFTER INSERT
+    ON topic_thread
+    FOR EACH ROW
+EXECUTE FUNCTION fn_insert_topics_creator_as_moderator();
+CREATE OR REPLACE TRIGGER tr_insert_project_manager
+    AFTER INSERT
+    ON project_thread
+    FOR EACH ROW
+EXECUTE FUNCTION fn_insert_project_manager();
+
+create or replace trigger tr_remove_unused_tags
+    after delete
+    on tag_threads
+    for each row
+execute function fn_remove_unused_tags();
+
+create trigger tr_remove_not_project_managers
+    after delete
+    on project_thread
+    for each row
+execute function fn_remove_not_active_project_manager();
+
+create trigger tr_remove_not_active_developer
+    after delete
+    on developer_associated_with_project
+    for each row
+execute function fn_remove_not_active_developer();
+
Index: target/classes/db/migration/V2__add_test_data.sql
===================================================================
--- target/classes/db/migration/V2__add_test_data.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/db/migration/V2__add_test_data.sql	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,115 @@
+INSERT INTO users (username, is_activate, password, description, registered_at, sex,name,email)
+VALUES
+    ('user1', true, '$2a$12$0f.x7aBM2wFBZBXoLPj0BObVsk.J1kXFYo5nb4niAWkI4hk5tHvDy', 'First user', NOW(), 'M','viki', 'viki@gmail.com'),
+    ('user2', true, '$2a$12$VkR0a47LDVM6aUqFcEJGSu9jhZCz.05tCoyiRicFObt4f2x2gijKa', 'Second user', NOW(), 'F','stefan', 'stefan@gmail.com'),
+    ('user3', true, '$2a$12$eSLdHHJ1KFgv.dOupmloXeItjrt2o1IB6ER6Nq7WYj9Jfr2bEwK2a', 'Third user', NOW(), 'M','darko', 'darko@gmail.com'),
+    ('user4', true, '$2a$12$dF5SXcNhMulgU3Qre3nh1e.aatRiJZsnfoBSqReGnXe9rIbHYVWhe', 'Fourth user', NOW(), 'F','andrej', 'andrej@gmail.com'),
+    ('user5', true, '$2a$12$zHrloz8WG2zo5S6MTf1C0ez1raMlmDJdB8OOa2I1S2pVy9oI76YTa', 'Fifth user', NOW(), 'M','ramche', 'ramche@gmail.com');
+
+
+INSERT INTO thread (content, user_id)
+VALUES
+    ('Main content for topic thread 1', 1),
+    ('Main content for topic thread 2', 2),
+    ('Discussion content for topic 1', 1),
+    ('Discussion content for topic 2', 2),
+    ('Project-specific thread content', 3),
+    ('Reply to topic 1', 4),
+    ('Further discussion on topic 2', 5),
+    ('Main content for topic thread', 1),
+    ('Main content for topic thread', 2),
+    ('Discussion content for topic 1', 1),
+    ('Discussion content for topic 2', 2),
+    ('Project-specific thread content', 3),
+    ('Reply to topic 1', 4),
+    ('Further discussion on topic 2', 5),
+    ('Further discussion on topic 2', 5),
+    ('Main content for topic thread', 1),
+    ('Main content for topic thread', 2),
+    ('Discussion content for topic 1', 1),
+    ('Discussion content for topic 2', 2),
+    ('Project-specific thread content', 3),
+    ('Reply to topic 1', 4),
+    ('Further discussion on topic 2', 5);
+
+INSERT INTO topic_thread (id, title, parent_id)
+VALUES
+    (1, 'Topic 1' , 5),
+    (2, 'Topic 2', 5),
+    (8, 'Topic 7' , NULL),
+    (9, 'Topic 8', NULL),
+    (16, 'Topic 9' , NULL),
+    (17, 'Topic 10', NULL);
+
+insert into topic_guidelines(topic_id,description)
+values
+    (1,'Follow guidelines'),
+    ( 2,'Be respectful');
+
+INSERT INTO discussion_thread (id, parent_id)
+VALUES
+    (3, 1),
+    (4, 2),
+    (6, 3),
+    (7, 4);
+
+INSERT INTO project_thread (id, title, repo_url)
+VALUES
+    (5, 'Project 1 Thread', 'http://github.com/project1'),
+    (10, 'Project 2 Thread', 'http://github.com/project1'),
+    (15, 'Project 3 Thread', 'http://github.com/project1');
+
+INSERT INTO likes (user_id, thread_id)
+VALUES
+    (1, 3),
+    (2, 4),
+    (3, 5),
+    (4, 6),
+    (5, 7);
+
+INSERT INTO blacklisted_user (topic_id, user_id, moderator_id, start_date, end_date, reason)
+VALUES
+    (1, 2, 1, NOW(), NOW() + INTERVAL '7 days', 'Spamming'),
+    (2, 3, 4, NOW(), NOW() + INTERVAL '3 days', 'Offensive language');
+
+INSERT INTO permissions (name)
+VALUES
+    ('Create Thread'),
+    ('Delete Thread');
+
+INSERT INTO project_roles (name, project_id, description)
+VALUES
+    ('Admin', 5, 'Admin role for the project'),
+    ('Developer', 5, 'Developer role for the project');
+
+INSERT INTO users_project_roles (user_id, project_id, role_name)
+VALUES
+    (3, 5, 'Admin'),
+    (2, 5, 'Developer'),
+    (4, 5, 'Developer');
+
+INSERT INTO project_roles_permissions (permission_name, role_name, project_id)
+VALUES
+    ('Create Thread', 'Admin', 5),
+    ('Delete Thread', 'Admin', 5);
+
+INSERT INTO project_request (description, status, user_id, project_id)
+VALUES
+    ('Request to join Project 1', 'PENDING', 2, 5),
+    ('Request to join Project 1', 'ACCEPTED', 4, 5);
+
+INSERT INTO report (created_at, description, status, thread_id, for_user_id, by_user_id)
+VALUES
+    (NOW(), 'Inappropriate content', 'PENDING', 3, 2, 1),
+    (NOW(), 'Spam content', 'DENIED', 6, 4, 3);
+
+INSERT INTO channel (name, description, project_id, developer_id)
+VALUES
+    ('General', 'General discussion channel', 5, 2),
+    ('Updates', 'Project updates channel', 5, 3);
+
+INSERT INTO messages (sent_at, content, sent_by, project_id, channel_name)
+VALUES
+    (NOW(), 'Hello, team!', 2, 5, 'General'),
+    (NOW(), 'We need to push the deadline.', 3, 5, 'Updates');
+
Index: target/classes/templates/create-topic.html
===================================================================
--- target/classes/templates/create-topic.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/create-topic.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Add Topic</title>
+  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+<main th:with="prefix=${project_title==null ? '' : '/project'}" class="container mt-5">
+  <div class="card shadow-sm">
+    <div class="card-header bg-primary text-white">
+      <h4 class="mb-0">Add a New Topic</h4>
+    </div>
+    <div class="card-body">
+      <form th:action="@{{prfx}/topic/add(prfx=${prefix})}" method="post">
+        <div class="mb-3">
+          <label for="title" class="form-label">Title</label>
+          <input type="text" id="title" name="title" class="form-control" placeholder="Enter the topic title" required>
+        </div>
+        <div class="mb-3">
+          <label for="description" class="form-label">Description</label>
+          <textarea id="description" name="description" class="form-control" rows="3" placeholder="Write a short description" required></textarea>
+        </div>
+        <button type="submit" class="btn btn-primary w-100">Submit</button>
+        <input th:if="${!#strings.isEmpty(prefix)}" type="hidden" name="project_title" th:value="${project_title}"/>
+        <input type="hidden" name="username" th:value="${session.user.getUsername()}"/>
+      </form>
+    </div>
+  </div>
+</main>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/fragments/user_fields.html
===================================================================
--- target/classes/templates/fragments/user_fields.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/fragments/user_fields.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,35 @@
+<form method="post"
+      class="d-flex gap-2 flex-grow-1 flex-column gap-2 list-group-flush "
+      th:action="${url}"
+      th:fragment="user_fields(url)"
+>
+    <h5>Personal Details</h5>
+    <label class="fw-bold ">Username:
+        <input th:readonly="${!canEdit}"
+               name="username" type="text" th:value="${user.getUsername()}"
+               class="w-100 border border-secondary ps-2 rounded list-group-item">
+    </label>
+    <label class="fw-bold ">Name:
+        <input name="name" th:readonly="${!canEdit}"
+               type="text" th:value="${user.getName()}" class="border ps-2 border-secondary rounded w-100 list-group-item">
+    </label>
+    <label th:readonly="${!canEdit}"
+           class="fw-bold ">Email:
+        <input name="email" type="text" th:value="${user.getEmail()}" class="border ps-2 border-secondary rounded w-100 list-group-item">
+    </label>
+    <label>
+        <span class="fw-bold d-block">Description</span>
+        <textarea name="description" class="border border-secondary ps-2 rounded w-100" th:readonly="${!canEdit}"
+                  th:text="${user.getDescription()}"></textarea>
+    </label>
+    <label th:readonly="${!canEdit}"
+           class="fw-bold ">Password:
+        <input name="password"
+               placeholder="Leave empty if you don't want to change it"
+               type="password" class="w-100 ps-2 list-group-item border border-secondary rounded">
+    </label>
+    <input type="hidden" name="cur_user_username"
+           th:value="${session.user == null} ? '' : ${session.user.getUsername()}">
+    <button th:if="${canEdit}" class="btn btn-success btn-sm w-50 align-self-center">Save changes
+    </button>
+</form>
Index: target/classes/templates/home_pages/home.html
===================================================================
--- target/classes/templates/home_pages/home.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/home_pages/home.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html lang="en"
+      xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Home Page</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+
+    <style>
+        .search-container {
+            position:  relative;
+        }
+
+        .search-input {
+            height: 50px;
+            border-radius: 30px;
+            padding-left: 35px;
+            border: none;
+            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+        }
+
+        .search-icon {
+            position: absolute;
+            top: 50%;
+            left: 15px;
+            transform: translateY(-50%);
+            color: #888;
+        }
+
+        .content-max-width{
+            width: max-content;
+        }
+    </style>
+</head>
+<body>
+<nav th:fragment="navigation" class="navbar navbar-expand-lg navbar-light bg-light shadow-sm">
+    <div class="container">
+        <a class="navbar-brand" href="/">BuildBoard</a>
+        <button class="navbar-toggler w-25" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
+                aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
+            <span class="navbar-toggler-icon"></span>
+        </button>
+        <div class="collapse navbar-collapse" id="navbarNav">
+            <ul class="navbar-nav justify-content-center d-flex align-items-center w-100">
+                <!-- Use mx-auto for centering the nav items -->
+                <li class="nav-item">
+                    <a class="nav-link" href="/">Home</a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" href="/about" th:href="@{/about}">About</a>
+                </li>
+                <li th:if="${session.user != null}" class="nav-item">
+                    <a class="nav-link" th:href="@{'/' + ${session.user.getUsername()} + '/profile'}">Profile</a>
+                </li>
+            </ul>
+            <div class="navbar-nav justify-content-center d-flex align-items-center w-25-md w-100-xs gap-3 mt-3 gap-l-0">
+                <div class="d-flex flex-row gap-3">
+                    <div class="nav-item d-flex align-items-center" th:if="${session.user != null}">
+                        <img th:src="${session.user.getAvatarUrl()}" alt="Profile Picture" id="profileImage"
+                             class="rounded-circle border border-1 border-info"
+                             style="width: 50px; height: 50px; object-fit: cover; vertical-align: middle;">
+                    </div>
+                    <div class="nav-item d-flex align-items-center" th:if="${session.user != null}">
+                        <span class="nav-link mb-0" th:text="${session.user.getUsername()}">Username</span>
+                    </div>
+                </div>
+                <div class="nav-item d-flex align-items-center ms-xs-5 ms-0  mt-xs-5" th:if="${session.user != null}">
+                    <a href="/logout" class="content-max-width btn btn-outline-primary btn-sm text-nowrap ">Log out</a>
+                </div>
+                <!-- Display login button if user is not logged in -->
+                <div class="nav-item d-flex align-items-center mt-xs-5" th:if="${session.user == null}">
+                    <a href="/login" class="content-max-width btn btn-primary btn-sm ms-2 ms-xs-0">Log in</a>
+                </div>
+                <div class="nav-item d-flex align-items-center mt-xs-5" th:if="${session.user == null}">
+                    <a href="/register" class="content-max-width btn btn-primary btn-sm ms-2 ms-xs-0">Register</a>
+                </div>
+            </div>
+        </div>
+    </div>
+</nav>
+
+<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
+<div class="container mb-5">
+    <div class="row justify-content-center align-items-center pt-3">
+        <div class="col-md-8 pt-5">
+            <form action="/" method="get" class="row g-3 align-items-center">
+                <!-- Search Input and Button -->
+                <div class="col-auto flex-grow-1">
+                    <div class="input-group position-relative">
+        <span class="input-group-text bg-light border-0">
+            <i class="fas fa-search"></i>
+        </span>
+                        <input type="text" class="form-control" placeholder="Search..." name="query" id="search-input">
+                        <!-- Dropdown container -->
+                        <div>
+                            <div id="suggestions" class="dropdown-menu show position-absolute"
+                                 style="top: 100%; left: 0; z-index: 1000; display: none;">
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-auto">
+                    <button type="submit" class="btn btn-primary">
+                        Search
+                    </button>
+                </div>
+
+
+                <!-- Filters -->
+                <div class="col-12 d-flex gap-2 flex-column">
+                    <div class="col-12 d-flex">
+                        <span class="me-2">Filters:</span>
+                        <div class="form-check me-3 d-flex align-items-center">
+                            <input class="form-check-input me-2" type="checkbox" id="filterTitle" name="filters"
+                                   value="title">
+                            <label class="form-check-label" for="filterTitle">Title</label>
+                        </div>
+                        <div class="form-check me-3 d-flex align-items-center">
+                            <input class="form-check-input me-2" type="checkbox" id="filterContent" name="filters"
+                                   value="content">
+                            <label class="form-check-label" for="filterContent">Content</label>
+                        </div>
+                    </div>
+                    <div class="form-group me-3 d-flex flex-row">
+                        <label for="filterType" class="me-2">Type:</label>
+                        <select class="form-select form-select-sm w-auto" id="filterType" name="type">
+                            <option value="all">All</option>
+                            <option value="topic">Topic</option>
+                            <option value="project">Project</option>
+                        </select>
+                    </div>
+                </div>
+
+            </form>
+        </div>
+    </div>
+</div>
+
+
+<main class="container mt-4">
+    <div class="d-flex justify-content-between align-items-center mb-3">
+        <h1 class="h4">Threads</h1>
+        <div th:if="${session.user!=null}">
+            <a href="/topic/create" class="btn btn-success btn-sm">Create Topic</a>
+            <a href="project/create" class="btn btn-success btn-sm">Create Project</a>
+        </div>
+    </div>
+    <div class="list-group">
+        <div class="list-group-item" th:each="thread : ${threads}">
+            <div class="d-flex w-100 justify-content-between">
+                <h5 class="mb-1">
+                    <a th:href="@{/{type}/{name} (type=${thread.getTypeName()},name=${thread.getTitle()})}"
+                       th:text="${thread.getTitle()}" class="text-decoration-none"></a>
+                </h5>
+                <!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
+            </div>
+            <!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
+            <!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
+        </div>
+    </div>
+</main>
+
+<script th:inline="javascript">
+    let searchInput = document.getElementById("search-input");
+    let suggestionsContainer = document.getElementById("suggestions");
+    let tags = /*[[${tags}]]*/ []; // kolku e glupa sintaksava gospode boze
+    let tagNames = tags.map(tag => tag.name);
+    let suggestionHeader = document.getElementById("suggestion-header");
+
+    function renderSuggestions(suggestions) {
+        suggestionsContainer.innerHTML = "";
+        if (suggestions.length === 0) {
+            suggestionsContainer.style.display = "none";
+            return;
+        }
+        suggestionsContainer.style.display = "block";
+        suggestions.forEach(tagName => {
+            let suggestionItem = document.createElement("a");
+            suggestionItem.href = "#";
+            suggestionItem.classList.add("dropdown-item");
+            suggestionItem.textContent = tagName;
+            suggestionItem.addEventListener("click", (e) => {
+                e.preventDefault();
+                searchInput.value = tagName;
+                suggestionsContainer.style.display = "none";
+            });
+            suggestionsContainer.appendChild(suggestionItem);
+        });
+    }
+
+    searchInput.addEventListener("input", () => {
+        let value = searchInput.value.toLowerCase();
+        let filteredTags = tagNames.filter(tag => tag.toLowerCase().includes(value));
+        renderSuggestions(filteredTags);
+    });
+
+    document.addEventListener("click", (e) => {
+        if (!suggestionsContainer.contains(e.target) && e.target !== searchInput) {
+            suggestionsContainer.style.display = "none";
+        }
+    });
+</script>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/home_pages/login.html
===================================================================
--- target/classes/templates/home_pages/login.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/home_pages/login.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Login</title>
+    <!-- Bootstrap CSS -->
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body class="bg-light">
+
+<div class="container d-flex align-items-center justify-content-center vh-100">
+    <div class="card shadow-lg" style="width: 100%; max-width: 400px;">
+        <div class="card-body">
+            <h4 class="card-title text-center mb-4">Login</h4>
+            <form method="POST" action="/login">
+                <div class="mb-3">
+                    <label for="username" class="form-label">Username</label>
+                    <input type="text" class="form-control" id="username" name="username" placeholder="Enter your username" required>
+                </div>
+                <div class="mb-3">
+                    <label for="password" class="form-label">Password</label>
+                    <input type="password" class="form-control" id="password" name="password" placeholder="Enter your password" required>
+                </div>
+                <button type="submit" class="btn btn-primary w-100">Login</button>
+            </form>
+            <div class="mt-3 text-center">
+                <a href="/register" class="text-decoration-none">Don't have an account? Register</a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- Bootstrap JS and dependencies -->
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/home_pages/profile.html
===================================================================
--- target/classes/templates/home_pages/profile.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/home_pages/profile.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,88 @@
+<!--TODO: make updates avaialbe i change password da mozish-->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Profile</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body class="bg-light">
+<div th:replace="/home_pages/home :: navigation"></div>
+<div class="container mt-5 w-50-xs w-75-md " style="width: max-content">
+    <!-- User Profile Card -->
+    <div class="card">
+        <div class="card-header bg-primary text-white">
+            <h4 class="mb-0">User Profile</h4>
+        </div>
+
+        <div class="card-body me-5 ms-5 pe-5 ps-5 d-flex flex-row gap-5 ">
+
+            <!-- Profile Picture -->
+            <div class="col-md-4 flex-grow-2 text-center d-flex justify-content-center align-items-center flex-column"
+            >
+                <form method="post" th:action="@{/{username}/upload-avatar(username=${user.getUsername()})}"  enctype="multipart/form-data">
+                    <img th:src="${user.getAvatarUrl()}" alt="Profile Picture" id="profileImage-input"
+                         class="rounded-circle border border-1 border-info mb-3"
+                         style="width: 150px; height: 150px; object-fit: cover;">
+                    <input type="file" id="userImage" name="userImage" accept="image/*" class="form-control mb-2">
+                    <input type="hidden" th:value="${session.user == null ? '' : session.user.getUsername()}"
+                           name="cur_user_username">
+                    <button type="submit" class="btn btn-success btn-sm w-100">Upload Picture</button>
+                </form>
+            </div>
+            <!-- User Details -->
+            <div th:replace="fragments/user_fields :: user_fields(url=@{/{username}/profile/change(username=${user.getUsername()})})"></div>
+<!--            <form method="post"-->
+<!--                  class="d-flex gap-2 flex-grow-1 flex-column gap-2 list-group-flush "-->
+<!--                  th:action="@{/{username}/profile/change(username=${user.getUsername()})}"-->
+<!--            >-->
+<!--                <h5>Personal Details</h5>-->
+<!--                <label class="fw-bold ">Username:-->
+<!--                    <input th:readonly="${!canEdit}"-->
+<!--                           name="username" type="text" th:value="${user.getUsername()}"-->
+<!--                           class="w-100 border border-secondary ps-2 rounded list-group-item">-->
+<!--                </label>-->
+<!--                <label class="fw-bold ">Name:-->
+<!--                    <input name="name" th:readonly="${!canEdit}"-->
+<!--                           type="text" th:value="${user.getName()}" class="border ps-2 border-secondary rounded w-100 list-group-item">-->
+<!--                </label>-->
+<!--                <label th:readonly="${!canEdit}"-->
+<!--                       class="fw-bold ">Email:-->
+<!--                    <input name="email" type="text" th:value="${user.getEmail()}" class="border ps-2 border-secondary rounded w-100 list-group-item">-->
+<!--                </label>-->
+<!--                <label>-->
+<!--                    <span class="fw-bold d-block">Description</span>-->
+<!--                    <textarea name="description" class="border border-secondary ps-2 rounded w-100" th:readonly="${!canEdit}"-->
+<!--                              th:text="${user.getDescription()}"></textarea>-->
+<!--                </label>-->
+<!--                <label th:readonly="${!canEdit}"-->
+<!--                       class="fw-bold ">Password:-->
+<!--                    <input name="password"-->
+<!--                           placeholder="Leave empty if you don't want to change it"-->
+<!--                           type="text" class="w-100 ps-2 list-group-item border border-secondary rounded">-->
+<!--                </label>-->
+<!--                <input type="hidden" name="cur_user_username"-->
+<!--                       th:value="${session.user == null} ? '' : ${session.user.getUsername()}">-->
+<!--                <button th:if="${canEdit}" class="btn btn-success btn-sm w-50 align-self-center">Save changes-->
+<!--                </button>-->
+<!--            </form>-->
+
+            <script>
+                const img = document.querySelector("#profileImage-input");
+                console.log(img)
+                document.querySelector('input[type="file"]').addEventListener("change", ev => {
+                    const [file] = ev.target.files
+                    console.log(file)
+                    if (file) {
+                        console.log(URL.createObjectURL(file))
+                        img.setAttribute("src", URL.createObjectURL(file));
+                    }
+                })
+            </script>
+        </div>
+    </div>
+
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/home_pages/project_description.html
===================================================================
--- target/classes/templates/home_pages/project_description.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/home_pages/project_description.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,67 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport"
+          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+    <title>About BuildBoard</title>
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+<section class="m-5 d-flex flex-column gap-5 justify-content-center align-items-center">
+    <header class="d-flex flex-row gap-2 align-items-center">
+        <img class="rounded-circle border border-1 border-info align-items-center"
+             style="width: 6rem; height: 6rem; object-fit: cover; vertical-align: middle;"
+             alt="Logo for BuildBoard project" src="/project_imgs/buildboard-logo.jpg"/>
+        <h1 class="d-inline">BuildBoard</h1>
+    </header>
+    <main class="d-flex flex-column gap-3 me-5 ms-5 pe-5 ps-5 align-items-center mt-5">
+        <h3>Short description</h3>
+        <p class="text-break text-wrap text-center ps-5 pe-5">BuildBoard is intended to be a social platform focused on
+            software
+            developers. The idea is to facilitate open discussions about technologies, approaches to problems, and more,
+            making it accessible to every software developer. Additionally, the application offers an integrated project
+            management system where multiple software developers can collaborate and build their own applications. The
+            goal is to create a single platform where people can talk, learn, and discuss software development while
+            also having the opportunity to explore real projects and connect with the developers behind them, whether
+            for consultation or collaboration purposes.</p>
+        <h3>Purpose</h3>
+        <div>
+            <p class="ps-5 mb-0 pe-5 text-break text-wrap text-center">
+                In today's world, there is an endless number of resources and ways for someone to acquire knowledge. The
+                problem
+                does not lie in the abundance of available knowledge but in the guidance, specifically, how to achieve
+                the
+                desired outcome. Every solution to a problem has its own path to reach the goal. This project aims to
+                solve
+                the
+                issue of guidance by enabling software developers to guide and assist one another.
+            </p>
+            <p class="pe-5 ps-5 text-break text-wrap text-center">
+                Another issue being addressed is the problem of centralization. This issue is closely related to the
+                aforementioned one, as it is much easier to guide someone who wants to learn if all the necessary
+                resources
+                are
+                in one place. On our platform, this is reflected through various informative threads and discussion
+                threads.
+            </p>
+        </div>
+        <h3>Contact</h3>
+        <ul>
+            <li>
+                <span>Viktor Hristovski</span>
+                <a href="mailto:viktorhristovski629@gmail.com">viktorhristovski629@gmail.com</a>
+            </li>
+            <li>
+                <span>Stefan Toskovski</span>
+                <!--            TODO: klaj si go mailot tuka -->
+                <a href="mailto:stefantoska84@gmail.com">stefantoska84@gmail.com</a>
+            </li>
+        </ul>
+    </main>
+</section>
+</body>
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</html>
Index: target/classes/templates/home_pages/register.html
===================================================================
--- target/classes/templates/home_pages/register.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/home_pages/register.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Register new user</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+<div class="container  mt-5" style="width: max-content; min-width: 45vw">
+    <div class="card">
+        <div class="card-header bg-primary text-white">
+            <h4 class="mb-0">Create new user</h4>
+        </div>
+
+        <form method="post"
+              class="d-flex me-5 mt-3 ms-5 mb-3 gap-2 flex-grow-1 flex-column gap-2 list-group-flush "
+              action="/register"
+        >
+            <label class="fw-bold ">Username:
+                <input name="username" type="text" th:value="${user.getUsername()}"
+                       class="w-100 border border-secondary ps-2 rounded list-group-item">
+            </label>
+            <label class="fw-bold ">Name:
+                <input name="name" th:readonly="${!canEdit}"
+                       type="text" th:value="${user.getName()}"
+                       class="border ps-2 border-secondary rounded w-100 list-group-item">
+            </label>
+            <label
+                    class="fw-bold ">Email:
+                <input name="email" type="text" th:value="${user.getEmail()}"
+                       class="border ps-2 border-secondary rounded w-100 list-group-item">
+            </label>
+            <label>
+                <span class="fw-bold d-block">Description</span>
+                <textarea name="description" class="border border-secondary ps-2 rounded w-100"
+                          th:text="${user.getDescription()}"></textarea>
+            </label>
+            <label class="fw-bold ">Password:
+                <input name="password"
+                       placeholder="Leave empty if you don't want to change it"
+                       type="password" class="w-100 ps-2 list-group-item border border-secondary rounded">
+            </label>
+            <div>
+                <label>Choose your gender:</label>
+                <label>
+                    <input name="sex" type="radio" value="male">Male
+                </label>
+                <label>
+                    <input name="sex" type="radio" value="female">Female
+                </label>
+            </div>
+            <button th:if="${canEdit}" class="btn btn-success btn-sm w-50 align-self-center">Create user
+            </button>
+        </form>
+    </div>
+</div>
+</body>
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</html>
Index: target/classes/templates/project_pages/members.html
===================================================================
--- target/classes/templates/project_pages/members.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/project_pages/members.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Members</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+    <style>
+        body {
+            background-color: #f8f9fa; /* Light background for the whole page */
+        }
+
+        .card {
+            background-color: #ffffff; /* White background for the cards */
+            border: 1px solid #dde2e6; /* Light grey border */
+            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* Subtle shadow */
+            transition: transform 0.3s ease, box-shadow 0.3s ease;
+            height: 350px; /* Fixed height for larger cards */
+        }
+
+        .card:hover {
+            transform: translateY(-5px); /* Slight lift on hover */
+            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); /* Stronger shadow on hover */
+        }
+
+        .card-header {
+            background-color: #007bff; /* Blue header color */
+            color: #ffffff; /* White text */
+            font-weight: bold;
+        }
+
+        .card-body {
+            background-color: #f1f3f5; /* Light grey background */
+            color: #495057; /* Dark text */
+            height: 200px; /* Larger height for the card body */
+            overflow-y: auto; /* Allow scrolling if content exceeds height */
+        }
+
+        .card-footer {
+            background-color: #f8f9fa;
+            color: #495057;
+        }
+
+        .card-title {
+            color: #000000; /* Dark text color for card title */
+        }
+
+        .card-text {
+            color: #6c757d; /* Grey text for descriptions */
+        }
+
+        .btn-link {
+            color: #007bff; /* Blue accent for buttons */
+        }
+
+        .container-header {
+            margin-top: 50px;
+            text-align: center;
+        }
+    </style>
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+
+<header class="container container-header mb-5">
+    <h1 class="text-primary" th:text="|${project.getTitle()} members|">Projects Tittles</h1>
+</header>
+<main class="d-flex justify-content-center align-content-center ">
+    <div class="list-group w-75">
+        <!--    <div class="list-group-item" th:with="creator=${project.getUser()}">-->
+        <!--      <img th:src="${creator.getAvatarUrl()}">-->
+        <!--      <h5 class="mb-1 d-flex">-->
+        <!--        <a th:href="@{/{username}/profile (username=${creator.getName()})}"-->
+        <!--           th:text="${creator.getName()}" class="text-decoration-none"></a>-->
+        <!--      </h5>-->
+        <!--      <h5>Creator</h5>-->
+        <!--    </div>-->
+        <div class="list-group-item d-flex gap-2 justify-content-between align-items-center ps-4 pe-4"
+             th:each="member : ${project.getDevelopers()}">
+            <div class="d-flex flex-row align-items-center gap-3">
+                <img class="rounded-circle border border-1 border-info"
+                     style="width: 5em; height: 5em" th:src="${member.getAvatarUrl()}">
+                <h5 class="mb-1 d-flex">
+                    <a th:href="@{/{username}/profile (username=${member.getUsername()})}"
+                       th:text="${member.getUsername()}"
+                        class="text-decoration-none"
+                    ></a>
+                </h5>
+            </div>
+            <h5 class="fw-lighter fst-italic">Developer</h5>
+        </div>
+    </div>
+    </div>
+</main>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/project_pages/project-create.html
===================================================================
--- target/classes/templates/project_pages/project-create.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/project_pages/project-create.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title th:text="${isCreatingProject==null} ? 'Modify Project' : 'Add Project' ">Add project</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+
+<main class="container mt-5">
+    <div class="card shadow-sm">
+        <div class="card-header bg-primary text-white">
+            <h4
+                    th:text="${isCreatingProject==null} ? 'Modify project' : 'Create new project' "
+                    class="mb-0">Create new project</h4>
+        </div>
+        <div class="card-body">
+            <form th:action="${isCreatingProject==null} ? '/project/' + ${project.getTitle()} + '/modify' : '/project/add'" method="post">
+                <div class="mb-3">
+                    <label for="title" class="form-label">Title</label>
+                    <input type="text" id="title" name="title" th:value="${project.getTitle()}" class="form-control" placeholder="Enter projects title" required>
+                </div>
+                <div class="mb-3">
+                    <label for="repo_url" class="form-label">Repository url</label>
+                    <input type="text" id="repo_url" name="repo_url"
+                           th:value="${project.getRepoUrl()}"
+                           class="form-control" placeholder="Enter url to your repository">
+                </div>
+                <div class="mb-3">
+                    <label for="description" class="form-label">Description</label>
+                    <textarea id="description"
+                              th:text="${project.getDescription()}"
+                              placeholder="Write a short description"
+                              name="description" class="form-control" rows="3" ></textarea>
+                </div>
+                <button type="submit" class="btn btn-primary w-100">Submit</button>
+                <input th:if="${isCreatingProject==null}" type="hidden" name="username" th:value="${session.user.getUsername()}"/>
+            </form>
+        </div>
+    </div>
+</main>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/project_pages/requests/show-requests.html
===================================================================
--- target/classes/templates/project_pages/requests/show-requests.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/project_pages/requests/show-requests.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Requests</title>
+</head>
+<body>
+<header>
+    <div th:replace="/home_pages/home :: navigation"></div>
+</header>
+<main>
+
+</main>
+</body>
+</html>
Index: target/classes/templates/project_pages/show-project.html
===================================================================
--- target/classes/templates/project_pages/show-project.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/project_pages/show-project.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html lang="en" xmlns:th="http://www.thymeleaf.org">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title th:text="${project.getTitle()}"></title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+
+<main th:with="isManager=${session.user != null ?  session.user.getId()==project.getUser().getId() : false }"
+      class="container mt-5">
+    <div class="card shadow-sm mb-4">
+        <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
+            <h3 th:text="${project.getTitle()}">Project Title</h3>
+            <div class="d-flex flex-row gap-2">
+                <th:object th:if="${isManager}">
+                    <button
+                            class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">Add Tag
+                    </button>
+                    <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/topic/add(pr_title=${project.getTitle()})}">Add Topic</a>
+                    </button>
+                    <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/modify(pr_title=${project.getTitle()})}">Modify project</a>
+                    </button>
+                    <button class="btn btn-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                        <a class="text-decoration-none text-reset"
+                           th:href="@{/project/{pr_title}/requets(pr_title=${project.getTitle()})}">View project requests</a>
+                    </button>
+                </th:object>
+                <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">
+                    <a class="text-decoration-none text-reset"
+                       th:href="@{/project/{pr_title}/members(pr_title=${project.getTitle()})}">Show members</a>
+                </button>
+                <button th:if="${session.user != null && !project.getUser().equals(session.user)
+                 && !project.getDevelopers().contains(session.user)}"
+                        class="btn btn-success btn-sm"
+                        data-bs-toggle="modal"
+                        data-bs-target="#addTagModal">
+                    <a class="text-decoration-none text-reset"
+                       th:href="@{/project/{pr_title}/requests/add(pr_title=${project.getTitle()})}">Send request</a>
+                </button>
+            </div>
+        </div>
+        <div class="d-flex flex-column gap-3 justify-content-between card-body">
+            <div>
+                <h4>Description</h4>
+                <p th:text="${project.getContent()}">Description of the project goes here.</p>
+            </div>
+            <div th:with="hasRepoUrl=${!#strings.isEmpty(project.getRepoUrl())}">
+                <h4>Repository</h4>
+                <a th:if="${hasRepoUrl}" th:href="${project.repoUrl}" th:text="${project.getRepoUrl()}"></a>
+                <span th:if="!${hasRepoUrl}">There's no provided url for this project</span>
+            </div>
+            <div th:if="${!project.getTags().isEmpty()}">
+                <h6>Tags:</h6>
+                <ul class="list-inline">
+                    <li th:each="tag : ${project.getTags()}"
+                        class="list-inline-item badge bg-info text-dark d-inline-flex align-items-center">
+                        <span th:text="${tag.getName()}">Tag Name</span>
+                        <form th:if="${session.user!=null && session.user.equals(project.getUser())}"
+                              th:action="@{/project/delete-tag/{projectTitle}/{tagName} (projectTitle=${project.getTitle()}, tagName=${tag.getName()})}"
+                              method="post" style="margin-left: 5px;">
+                            <button type="submit" class="btn btn-sm btn-link text-danger p-0 ms-1"
+                                    style="line-height: 1;">
+                                &times;
+                            </button>
+                            <input th:if="${session.user!=null}" type="hidden" name="username"
+                                   th:value="${session.user.getUsername()}">
+                        </form>
+                    </li>
+                </ul>
+            </div>
+            <div class="d-flex flex-row justify-content-between">
+                <div th:if="${!project.getTopics().isEmpty()}" class="w-75 d-flex flex-column align-items-center">
+                    <h4>Topics:</h4>
+                    <div class="list-group w-75">
+                        <div class="list-group-item w-100" th:each="topic : ${project.getTopics()}">
+                            <div class="d-flex">
+                                <h5 class="mb-1">
+                                    <a th:href="@{/topic/{name} (name=${topic.getTitle()})}"
+                                       th:text="${topic.getTitle()}" class="text-decoration-none"></a>
+                                </h5>
+                                <!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
+                            </div>
+                            <!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
+                            <!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
+                        </div>
+                    </div>
+                </div>
+
+                <div th:if="${!project.getTopics().isEmpty()}" class="w-75 d-flex flex-column align-items-center">
+                    <h4>Channels:</h4>
+                    <div class="list-group w-75">
+                        <div class="list-group-item w-100" th:each="topic : ${project.getTopics()}">
+                            <div class="d-flex">
+                                <h5 class="mb-1">
+                                    <a th:href="@{/topic/{name} (name=${topic.getTitle()})}"
+                                       th:text="${topic.getTitle()}" class="text-decoration-none"></a>
+                                </h5>
+                                <!--                <small th:text="${thread.getFormattedDate()}">Date</small>-->
+                            </div>
+                            <!--            <p class="mb-1 text-muted" th:text="${thread.getDescription()}">Thread description here...</p>-->
+                            <!--            <small th:text="${thread.getAuthor()}">Posted by Author</small>-->
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+            <div class="d-flex justify-content-between align-items-center mt-3 pt-3">
+                <div class="d-flex flex-row">
+                    <form th:action="'/project/' + ${project.getTitle()} + '/discussion/like'" method="post">
+                        <input type="hidden" name="threadId" th:value="${project.getId()}">
+                        <button th:if="${session.user!=null}"
+                                type="submit" class="btn btn-outline-success btn-sm me-2 like-button">
+                            <!--                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">-->
+                            👍 Like (<span th:text="${project.getNumLikes()}">0</span>)
+                        </button>
+                    </form>
+                    <form th:action="'/project/' + ${project.getTitle()} + '/discussion/dislike'" method="post">
+                        <input type="hidden" name="threadId" th:value="${project.getId()}">
+                        <button th:if="${session.user!=null}"
+                                class="btn btn-outline-danger btn-sm dislike-button">
+                            <!--                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">-->
+                            👎 Dislike
+                        </button>
+                    </form>
+                </div>
+            </div>
+        </div>
+        <div th:if="${isManager}" class="card-footer d-flex justify-content-between">
+            <form th:action="@{/project/delete/{title} (title=${project.getTitle()})}" method="post"
+                  style="display:inline;">
+                <input type="hidden" name="id" th:value="${project.getId()}"/>
+                <button type="submit" class="btn btn-danger btn-sm">Delete Project</button>
+                <input th:if="${session.user!=null}" type="hidden" name="username"
+                       th:value="${session.user.getUsername()}">
+            </form>
+        </div>
+    </div>
+
+</main>
+
+<!-- Add Tag Modal -->
+<div class="modal fade" id="addTagModal" tabindex="-1" aria-labelledby="addTagModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="addTagModalLabel">Add a Tag</h5>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <form th:action="@{/project/{title}/add-tag(title=${project.getTitle()})}" method="post"
+                      id="addTagForm">
+                    <div class="mb-3">
+                        <label for="existingTags" class="form-label">Tag Name</label>
+                        <select id="existingTags" class="form-select mb-3" name="tagName">
+                            <option value="" selected disabled>Select an existing tag</option>
+                            <option th:each="tag : ${tags}" th:if="${!project.getTags().contains(tag)}"
+                                    th:value="${tag.getName()}" th:text="${tag.getName()}">
+                                Example Tag
+                            </option>
+                            <option value="custom">Enter a custom tag...</option>
+                        </select>
+                        <input type="text" id="customTag" class="form-control d-none"
+                               placeholder="Enter custom tag name"/>
+                        <input th:if="${session.user!=null}" type="hidden" name="username"
+                               th:value="${session.user.getUsername()}">
+                    </div>
+                    <button type="submit" class="btn btn-primary w-100">Add Tag</button>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    document.addEventListener("DOMContentLoaded", function () {
+        const existingTags = document.getElementById("existingTags");
+        const customTagInput = document.getElementById("customTag");
+
+        existingTags.addEventListener("change", function () {
+            if (this.value === "custom") {
+                customTagInput.classList.remove("d-none");
+                customTagInput.required = true;
+                customTagInput.name = "tagName";
+                existingTags.name = "";
+            } else {
+                customTagInput.classList.add("d-none");
+                customTagInput.required = false;
+                customTagInput.name = "";
+                existingTags.name = "tagName";
+                customTagInput.value = "";
+            }
+        });
+    });
+
+</script>
+
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
Index: target/classes/templates/show-topic.html
===================================================================
--- target/classes/templates/show-topic.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
+++ target/classes/templates/show-topic.html	(revision 11b8b1cf9ac55a7b9f5090981a1706c178bae03e)
@@ -0,0 +1,403 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title th:text="${topic.getTitle()}"></title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+
+    <style>
+        .edit-reply-btn {
+            font-size: 12px;
+            padding: 2px 8px;
+            height: auto;
+            line-height: 1.2;
+        }
+    </style>
+
+
+</head>
+<body>
+<div th:replace="/home_pages/home :: navigation"></div>
+
+<a href="#32/user1">Test</a>
+
+<main class="container mt-5">
+    <!-- Topic Title and Description -->
+    <div class="card shadow-sm mb-4">
+        <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
+            <h3 th:text="${topic.getTitle()}">Topic Title</h3>
+            <!-- Add Tag Button -->
+            <button th:if="${session.user!=null && session.user.equals(topic.getUser())}"
+                    class="btn btn-info btn-sm" data-bs-toggle="modal" data-bs-target="#addTagModal">Add Tag
+            </button>
+        </div>
+        <div class="card-body">
+            <p th:text="${topic.getContent()}">Description of the topic goes here.</p>
+            <!-- Tags Section -->
+            <div>
+                <h6>Tags:</h6>
+                <ul class="list-inline">
+                    <li th:each="tag : ${topic.getTags()}" class="list-inline-item">
+            <span class="badge bg-info text-dark d-inline-flex align-items-center">
+                <span th:text="${tag.getName()}">Tag Name</span>
+                <form th:if="${session.user!=null && session.user.equals(topic.getUser())}"
+                      th:action="@{/topic/delete-tag/{topicId}/{tagName} (topicId=${topic.getId()}, tagName=${tag.getName()})}"
+                      method="post" style="margin-left: 5px;">
+                    <button type="submit" class="btn btn-sm btn-link text-danger p-0 ms-1" style="line-height: 1;">
+                        &times;
+                    </button>
+                    <input th:if="${session.user!=null}" type="hidden" name="username"
+                           th:value="${session.user.username}"/>
+                </form>
+            </span>
+                    </li>
+                </ul>
+                <div class="d-flex justify-content-end">
+                    <button th:if="${session.user != null}"
+                            class="btn btn-info btn-sm m-2 reply-button"
+                            th:attr="data-reply-id=${topic.getId()}">Reply
+                    </button>
+                </div>
+                <div th:attr="data-reply-id=${topic.getId()}" class="card-body d-none reply-body">
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/reply/add'" method="post">
+                        <div class="mb-3">
+                            <label for="reply" class="form-label">Your Reply</label>
+                            <textarea name="content" class="form-control" rows="3" placeholder="Write your reply here"
+                                      required></textarea>
+                        </div>
+                        <div class="d-flex justify-content-between">
+                            <input type="hidden" th:value="${topic.getId()}" name="parentId">
+                            <button type="submit" class="btn btn-success w-10 ms-2">Post Reply</button>
+                            <div class="d-flex justify-content-end reply-cancel">
+                                <button class="btn btn-danger btn-sm reply-cancel w-10 me-2"
+                                        th:attr="data-reply-id=${topic.getId()}">Cancel
+                                </button>
+                            </div>
+                        </div>
+                        <input type="hidden" th:if="${session.user!=null}" name="username"
+                               th:value="${session.user.username}">
+                    </form>
+                </div>
+            </div>
+            <div class="d-flex justify-content-between align-items-center mt-3 pt-3">
+                <div class="d-flex flex-row">
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/discussion/like'" method="post">
+                        <input type="hidden" name="threadId" th:value="${topic.getId()}">
+                        <button th:if="${session.user!=null}"
+                                type="submit" class="btn btn-outline-success btn-sm me-2 like-button">
+                            <!--                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">-->
+                            👍 Like (<span th:text="${topic.getNumLikes()}">0</span>)
+                        </button>
+                    </form>
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/discussion/dislike'" method="post">
+                        <input type="hidden" name="threadId" th:value="${topic.getId()}">
+                        <button th:if="${session.user!=null}"
+                                class="btn btn-outline-danger btn-sm dislike-button">
+                            <!--                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">-->
+                            👎 Dislike
+                        </button>
+                    </form>
+                </div>
+            </div>
+
+
+        </div>
+        <!-- Edit and Delete Buttons for Topic -->
+        <div th:if="${session.user != null && session.user.getId() == topic.getUser().getId()}"
+             class="card-footer d-flex justify-content-between">
+            <div>
+                <button class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#editTopicModal">Edit
+                    Topic
+                </button>
+                <form th:action="@{/topic/delete/{id} (id=${topic.getId()})}" method="post" style="display:inline;">
+                    <input type="hidden" name="id" th:value="${topic.getId()}"/>
+                    <button type="submit" class="btn btn-danger btn-sm">Delete Topic</button>
+                    <input th:if="${session.user!=null}" type="hidden" name="username"
+                           th:value="${session.user.username}"/>
+                </form>
+            </div>
+        </div>
+    </div>
+    <!--    DO TUKA E TOPIC-->
+
+    <!-- Replies Section -->
+    <div th:each="reply : ${replies}" class="card shadow-sm mt-4 d-flex"
+         th:style="'margin-left: ' + (${reply.depth + 1} * 5) + '%'">
+        <div class="card-header bg-light d-flex justify-content-between align-items-center" th:id="${reply.getId() + '/' + reply.getUser().getUsername()}">
+            <div class="d-flex align-items-center w-100">
+                <img th:src="${reply.getAvatarUrl()}" alt="Profile Picture" id="profileImage"
+                     class="rounded-circle border border-1 border-info me-3"
+                     style="width: 50px; height: 50px; object-fit: cover; vertical-align: middle;">
+                <span th:text="${reply.getUser().getUsername()}">Reply Author</span>
+                <span class="ms-auto text-muted d-flex align-items-center">
+                    <i class="bi bi-arrow-return-right me-2"></i>
+                     <strong th:text="'Replying to:  ' + ${reply.getDiscussion().getParent().getUser().getUsername()}"></strong>
+                </span>
+
+            </div>
+            <div th:if="${session.user != null && session.user.getId() == reply.getUser().getId()}"
+                 class="ms-5 d-flex align-items-center justify-content-between">
+
+                <div>
+                    <button class="btn btn-warning btn-sm edit-reply-btn"
+                            th:attr="data-reply-id=${reply.getDiscussion().getId()}">Edit
+                    </button>
+
+                </div>
+
+                <div>
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/discussion/delete'" method="post">
+                        <input type="hidden" name="threadId" th:value="${reply.getDiscussion().getId()}" class="w-0">
+                        <button class="btn btn-danger btn-sm edit-reply-btn ms-2"
+                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">Delete
+                        </button>
+                        <input th:if="${session.user!=null}" type="hidden" name="username"
+                               th:value="${session.user.username}"/>
+                    </form>
+                </div>
+            </div>
+        </div>
+
+
+        <!-- Reply content -->
+        <div class="card-body">
+            <div th:attr="data-reply-id=${reply.getDiscussion().getId()}" class="reply-content">
+                <p th:text="${reply.getDiscussion().getContent()}">Reply content goes here.</p>
+            </div>
+            <div class="d-none edit-reply" th:attr="data-reply-id=${reply.getDiscussion().getId()}">
+                <form th:action="'/topic/' + ${topic.getTitle()} + '/reply/edit'" method="post">
+                    <input type="hidden" name="replyId" th:value="${reply.getDiscussion().getId()}">
+                    <textarea name="content" th:text="${reply.getDiscussion().getContent()}" class="form-control"
+                              rows="3" placeholder="Write your reply here"></textarea>
+
+                    <button type="submit" class="btn btn-sm btn-success mt-2">Save Changes</button>
+                    <button type="button" class="btn btn-sm btn-danger mt-2"
+                            th:onclick="'hideEditReplyBox(' + ${reply.getDiscussion().getId()} + ')'">Cancel
+                    </button>
+                    <input th:if="${session.user!=null}" type="hidden" name="username"
+                           th:value="${session.user.username}"/>
+                </form>
+
+            </div>
+
+            <!-- Buttons Row -->
+            <div class="d-flex justify-content-between align-items-center mt-3 pt-3">
+                <div class="d-flex flex-row">
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/discussion/like'" method="post">
+                        <input type="hidden" name="threadId" th:value="${reply.getId()}">
+                        <button th:if="${session.user!=null}"
+                                type="submit" class="btn btn-outline-success btn-sm me-2 like-button"
+                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">
+                            👍 Like (<span th:text="${reply.getDiscussion().getNumLikes()}">0</span>)
+                        </button>
+                    </form>
+                    <form th:action="'/topic/' + ${topic.getTitle()} + '/discussion/dislike'" method="post">
+                        <input type="hidden" name="threadId" th:value="${reply.getId()}">
+                        <button th:if="${session.user!=null}"
+                                class="btn btn-outline-danger btn-sm dislike-button"
+                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">
+                            👎 Dislike
+                        </button>
+                    </form>
+                </div>
+                <div>
+                    <button th:if="${session.user!=null}"
+                            class="btn btn-info btn-sm reply-button"
+                            th:attr="data-reply-id=${reply.getDiscussion().getId()}">Reply
+                    </button>
+                </div>
+            </div>
+        </div>
+
+
+        <!-- Add Reply Card Hidden -->
+        <div th:attr="data-reply-id=${reply.getDiscussion().getId()}" class="card-body d-none reply-body">
+            <form th:action="'/topic/' + ${topic.getTitle()} + '/reply/add'" method="post">
+                <div class="mb-3">
+                    <label for="reply" class="form-label">Your Reply</label>
+                    <textarea name="content" class="form-control" rows="3" placeholder="Write your reply here"
+                              required></textarea>
+                </div>
+                <div class="d-flex justify-content-between">
+                    <input type="hidden" th:value="${reply.getId()}" name="parentId">
+                    <button type="submit" class="btn btn-success w-10 ms-2">Post Reply</button>
+                    <div class="d-flex justify-content-end reply-cancel">
+                        <button class="btn btn-danger btn-sm reply-cancel w-10 me-2"
+                                th:attr="data-reply-id=${reply.getDiscussion().getId()}">Cancel
+                        </button>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </div>
+
+
+</main>
+
+<!-- Add Tag Modal -->
+<div class="modal fade" id="addTagModal" tabindex="-1" aria-labelledby="addTagModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5
+                        class="modal-title" id="addTagModalLabel">Add a Tag</h5>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <form th:action="@{/topic/add-tag/{id} (id=${topic.getId()})}" method="post" id="addTagForm">
+                    <div class="mb-3">
+                        <label for="tagName" class="form-label">Tag Name</label>
+                        <select id="existingTags" class="form-select mb-3" name="tagName">
+                            <option value="" selected disabled>Select an existing tag</option>
+                            <option th:each="tag : ${tags}" th:value="${tag.getName()}" th:text="${tag.getName()}">
+                                Example Tag
+                            </option>
+                            <option value="custom">Enter a custom tag...</option>
+                        </select>
+                        <input type="text" id="customTag" class="form-control d-none"
+                               placeholder="Enter custom tag name"/>
+                    </div>
+                    <button type="submit" class="btn btn-primary w-100">Add Tag</button>
+                    <input th:if="${session.user!=null}" type="hidden" name="username"
+                           th:value="${session.user.username}"/>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- Edit Topic Modal -->
+<div class="modal fade" id="editTopicModal" tabindex="-1" aria-labelledby="editTopicModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="editTopicModalLabel">Edit Topic</h5>
+                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+                <form th:action="@{/topic/edit/{id} (id=${topic.getId()})}" method="post">
+                    <div class="mb-3">
+                        <label for="topicTitle" class="form-label">Title</label>
+                        <input type="text" id="topicTitle" name="title" class="form-control"
+                               th:value="${topic.getTitle()}" required>
+                    </div>
+                    <div class="mb-3">
+                        <label for="topicContent" class="form-label">Content</label>
+                        <textarea id="topicContent" name="content" class="form-control" rows="5"
+                                  th:text="${topic.getContent()}" required></textarea>
+                    </div>
+                    <button type="submit" class="btn btn-primary w-100">Save Changes</button>
+                    <input th:if="${session.user!=null}" type="hidden" name="username"
+                           th:value="${session.user.username}"/>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!-- Edit Reply Modal -->
+
+
+<script>
+
+    window.addEventListener("beforeunload", function () {
+        sessionStorage.setItem("scrollPosition", window.scrollY);
+    });
+
+    window.onload = function () {
+        const savedScrollPosition = sessionStorage.getItem("scrollPosition");
+
+        if (savedScrollPosition) {
+            window.scrollTo(0, savedScrollPosition);
+            sessionStorage.removeItem("scrollPosition");
+        }
+    };
+
+
+    document.addEventListener("DOMContentLoaded", function () {
+        const existingTags = document.getElementById("existingTags");
+        const customTagInput = document.getElementById("customTag");
+        existingTags.addEventListener("change", function () {
+            if (this.value === "custom") {
+                customTagInput.classList.remove("d-none");
+                customTagInput.required = true;
+                customTagInput.name = "tagName";
+                existingTags.name = "";
+            } else {
+                customTagInput.classList.add("d-none");
+                customTagInput.required = false;
+                customTagInput.name = "";
+                existingTags.name = "tagName";
+                customTagInput.value = "";
+            }
+        });
+    });
+
+
+    //todo-func
+
+    //ova funckcija rabotat gore ja koristam vidi gore vo html
+    function hideEditReplyBox(id) {
+        console.log("HIDE EDIT REPLY")
+        const editBox = document.querySelector(`.edit-reply[data-reply-id="${id}"]`)
+        const contentBox = document.querySelector(`.reply-content[data-reply-id="${id}"]`)
+        editClasses(editBox, 'd-block', 'd-none')
+        editClasses(contentBox, 'd-none', 'd-block')
+        // editBox.classList.remove("d-block");
+        // editBox.classList.add("d-none");
+        // contentBox.classList.remove("d-none")
+        // contentBox.classList.add("d-block");
+    }
+
+
+    function displayAddReplyBox() {
+
+    }
+
+    function editClasses(element, rmCls, addCls) {
+        if (rmCls !== '') {
+            element.classList.remove(rmCls);
+        }
+        if (addCls !== '')
+            element.classList.add(addCls);
+    }
+
+
+    // podeli go ova so ifojte vo funkcii
+
+    document.querySelector("main").addEventListener("click", ev => {
+        const target = ev.target;
+        if (target.classList.contains("reply-button")) {
+            const id = target.dataset.replyId
+            const dialog = document.querySelector(`.reply-body[data-reply-id="${id}"]`)
+            editClasses(dialog, 'd-none', 'd-block')
+            editClasses(target, '', 'd-none')
+            // dialog.classList.remove("d-none")
+            // dialog.classList.add("d-block")
+            // target.classList.add('d-none');
+        } else if (target.classList.contains("reply-cancel")) {
+            const id = target.dataset.replyId
+            const dialog = document.querySelector(`.reply-body[data-reply-id="${id}"]`)
+            const replyBtn = document.querySelector(`.reply-button[data-reply-id="${id}"]`)
+            editClasses(dialog, 'd-block', 'd-none')
+            // dialog.classList.add("d-none")
+            // dialog.classList.remove("d-block")
+            editClasses(replyBtn, 'd-none', 'd-block')
+            // replyBtn.classList.remove('d-none');
+            // replyBtn.classList.add('d-block');
+        } else if (target.classList.contains("edit-reply-btn")) {
+            const id = target.dataset.replyId;
+            const editBox = document.querySelector(`.edit-reply[data-reply-id="${id}"]`)
+            const contentBox = document.querySelector(`.reply-content[data-reply-id="${id}"]`)
+            editClasses(editBox, 'd-none', 'd-block')
+            // editBox.classList.remove("d-none");
+            // editBox.classList.add("d-block");
+            contentBox.classList.add("d-none")
+        }
+    })
+</script>
+
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+</body>
+</html>
