Index: docs/todo.txt
===================================================================
--- docs/todo.txt	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ docs/todo.txt	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -31,5 +31,5 @@
 
 ---------------
+- timestamp da sa prikazvit za discussion threads, koga sa postaveni
 
 
-
Index: src/main/java/com/db/finki/www/build_board/controller/channels/ChannelController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/channels/ChannelController.java	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/java/com/db/finki/www/build_board/controller/channels/ChannelController.java	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -24,5 +24,5 @@
 
     @GetMapping()
-    public String getChannels(@PathVariable("title") Project project,Model model) {
+    public String getChannels(@PathVariable("title") Project project, Model model) {
         List<Channel> channels = channelService.getAllChannelsForProject(project);
         model.addAttribute("channels", channels);
@@ -30,6 +30,10 @@
     }
 
+    @PreAuthorize("#project.getDevelopers().contains(#user)")
     @GetMapping("/{channelName}")
-    public String getChannel(@PathVariable String channelName, @PathVariable("title") Project project, Model model, RedirectAttributes redirectAttributes) {
+    public String getChannel(@PathVariable String channelName, @PathVariable("title") @P("project") Project project,
+                             Model model,
+                             RedirectAttributes redirectAttributes,
+                             @SessionAttribute @P("user") BBUser user) {
         Channel c = (Channel) redirectAttributes.getAttribute("channel");
         if (c == null) {
@@ -42,4 +46,5 @@
         return "channels/view-channel";
     }
+
     @PreAuthorize("@channelService.getByNameAndProject(#channelName,#project).getDeveloper().equals(#user)")
     @PostMapping("/{channelName}/delete")
@@ -47,5 +52,5 @@
                                 @SessionAttribute @P("user") BBUser user, RedirectAttributes redirectAttributes) {
         channelService.deleteChannel(channelName, project);
-        return "redirect:/project/"+project.getTitle()+"/channels";
+        return "redirect:/project/" + project.getTitle();
     }
 
@@ -53,7 +58,12 @@
     @PostMapping("/add")
     public String add(@PathVariable("title") @P("project") Project project, String channelName, String description, @SessionAttribute @P("user") BBUser user, RedirectAttributes redirectAttributes) {
-        Channel channel = channelService.create(project, channelName, description, user);
-        redirectAttributes.addFlashAttribute("channel", channel);
-        return "redirect:/project/" + project.getTitle() + "/channels/" + channel.getName();
+        try {
+            Channel channel = channelService.create(project, channelName, description, user);
+            redirectAttributes.addFlashAttribute("channel", channel);
+        } catch (Exception e) {
+            redirectAttributes.addFlashAttribute("error", e.getMessage());
+        }
+
+        return "redirect:/project/" + project.getTitle();
     }
 
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 ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/java/com/db/finki/www/build_board/controller/thread_controllers/ProjectController.java	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -12,4 +12,5 @@
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
 @Controller
@@ -18,15 +19,20 @@
 
     private final ProjectService projectService;
-    private final TagService topicService;
+    private final TagService tagService;
 
     public ProjectController(ProjectService projectService, TagServiceImpl topicService) {
         this.projectService = projectService;
-        this.topicService = topicService;
+        this.tagService = topicService;
     }
 
     @GetMapping("/{title}")
-    public String getProjectPage(@PathVariable(name = "title") Project project, Model model) {
+    public String getProjectPage(@PathVariable(name = "title") Project project, Model model, RedirectAttributes redirectAttributes) {
         model.addAttribute("project", project);
-        model.addAttribute("tags", topicService.findAll());
+        model.addAttribute("tags", tagService.findAll());
+        String error = (String) redirectAttributes.getAttribute("error");
+        if(error != null){
+            model.addAttribute("error", error);
+        }
+        
         Hibernate.initialize(project.getTags());
 
@@ -37,5 +43,5 @@
     public String getCreateProjectPage(Model model) {
         model.addAttribute("project", new Project());
-        model.addAttribute("isCreatingProject", topicService.findAll());
+        model.addAttribute("isCreatingProject", tagService.findAll());
         return "project_pages/project-create";
     }
Index: src/main/java/com/db/finki/www/build_board/service/channel/ChannelService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/channel/ChannelService.java	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/java/com/db/finki/www/build_board/service/channel/ChannelService.java	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -17,4 +17,10 @@
     private final DeveloperRepository developerRepository;
 
+    private final String INVALID_INPUT_REGEX = "(^/|/$|[\\#?])";
+
+    private boolean isInvalidInput(String input) {
+        return input.matches(INVALID_INPUT_REGEX);
+    }
+
     public ChannelService(ChannelRepository channelRepository, DeveloperRepository developerRepository) {
         this.channelRepository = channelRepository;
@@ -27,4 +33,12 @@
 
     public Channel create(Project project, String channelName, String description, BBUser user){
+        if(channelRepository.findByProjectTitleAndName(project.getTitle(), channelName) != null) {
+            throw new IllegalArgumentException("Channel with title '" + channelName + "' already exists");
+        }
+
+        if(isInvalidInput(channelName)) {
+            throw new IllegalArgumentException("Channel name contains invalid characters");
+        }
+
         Developer developer = developerRepository.findById(user.getId());
         Channel channel = new Channel(channelName,project,description,developer);
Index: src/main/resources/db/migration/V2__add_test_data.sql
===================================================================
--- src/main/resources/db/migration/V2__add_test_data.sql	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/resources/db/migration/V2__add_test_data.sql	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -106,5 +106,5 @@
 INSERT INTO channel (name, description, project_id, developer_id)
 VALUES
-    ('General', 'General discussion channel', 5, 1),
+    ('General', 'General discussion channel', 5, 3),
     ('Updates', 'Project updates channel', 5, 3);
 
Index: src/main/resources/templates/home_pages/project_description.html
===================================================================
--- src/main/resources/templates/home_pages/project_description.html	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/resources/templates/home_pages/project_description.html	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -19,13 +19,4 @@
     </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>
@@ -49,4 +40,13 @@
             </p>
         </div>
+        <h3>BuildBoard</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>Contact</h3>
         <ul>
Index: src/main/resources/templates/project_pages/show-project.html
===================================================================
--- src/main/resources/templates/project_pages/show-project.html	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/resources/templates/project_pages/show-project.html	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -94,19 +94,24 @@
                 </div>
 
-                <div th:if="${!project.getChannels().isEmpty()}" class="w-75 d-flex flex-column align-items-center">
+                <div th:if="${project.getDevelopers().contains(session.user)}" 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="channel : ${project.getChannels()}">
-                            <div class="d-flex">
-                                <h5 class="mb-1">
-                                    <a th:href="@{/channel/{name} (name=${channel.getName()})}"
-                                       th:text="${channel.getName()}" 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>-->
+                            <form method="post" th:action="@{/project/{projectName}/channels/{channelName}/delete (projectName=${project.getTitle()},channelName=${channel.getName()})}">
+                                <div class="d-flex justify-content-between">
+                                    <h5 class="mb-1">
+                                        <a th:href="@{/project/{projectName}/channels/{name} (name=${channel.getName()},projectName=${project.getTitle()})}"
+                                           th:text="${channel.getName()}" class="text-decoration-none"></a>
+                                    </h5>
+                                    <div th:if="${channel.getDeveloper().getId() == session.user.getId() || project.getUser() == session.user}">
+                                        <button class="btn btn-sm btn-outline-danger">Delete</button>
+                                    </div>
+                                </div>
+                            </form>
                         </div>
-                        <button class="btn btn-success mt-3"> Add Channel </button>
+                        <button class="btn btn-success btn-sm w-25 mt-2 mx-auto" data-bs-toggle="modal"
+                                data-bs-target="#addChannelModal">
+                            Add Channel
+                        </button>
                     </div>
                 </div>
@@ -147,4 +152,8 @@
 </main>
 
+<section id="errors" class="container bg bg-danger border border-dark w-50" th:if="${error != null}">
+    <p class="fw-bold fs-6" th:text="'Error: ' + ${error}"></p>
+</section>
+
 <!-- Add Tag Modal -->
 <div class="modal fade" id="addTagModal" tabindex="-1" aria-labelledby="addTagModalLabel" aria-hidden="true">
@@ -180,4 +189,28 @@
 </div>
 
+<div class="modal fade" id="addChannelModal" tabindex="-1" aria-labelledby="addChannelModalLabel" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="addChannelModalLabel">Create a channel</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}/channels/add(title=${project.getTitle()})}" method="post"
+                      id="addChannelForm">
+
+                    <div class="mb-3 d-flex flex-column justify-content-center">
+                        <input class="form-control" type="text" id="channelName" name="channelName"
+                               placeholder="Enter channel name"/>
+                        <textarea class="form-control mt-2" id="channelDescription" name="channelDescription" cols="30"
+                                  rows="10" placeholder="What is this channel about.."></textarea>
+                    </div>
+                    <button type="submit" class="btn btn-primary w-100">Create Channel</button>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
 <script>
     document.addEventListener("DOMContentLoaded", function () {
Index: src/main/resources/templates/show-topic.html
===================================================================
--- src/main/resources/templates/show-topic.html	(revision ec80eec5715d33c1b8d17f8214c9fb485b3ebc5c)
+++ src/main/resources/templates/show-topic.html	(revision 72b7d6cd23a8d13574be1a0c05e232c5c7c83efc)
@@ -20,6 +20,4 @@
 <body>
 <div th:replace="/home_pages/home :: navigation"></div>
-
-<a href="#32/user1">Test</a>
 
 <main class="container mt-5">
@@ -131,4 +129,5 @@
                      style="width: 3rem; height: 3rem; object-fit: cover; vertical-align: middle;">
                 <span th:text="${reply.getUser().getUsername()}">Reply Author</span>
+<!--                <span th:text="${reply.}">Reply Time</span>-->
                 <span class="ms-auto text-muted d-flex align-items-center">
                     <i class="bi bi-arrow-return-right me-2"></i>
@@ -159,5 +158,4 @@
             </div>
         </div>
-
 
         <!-- Reply content -->
