Index: src/main/java/com/db/finki/www/build_board/controller/HomePageController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/HomePageController.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/controller/HomePageController.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -8,5 +8,4 @@
 
 @Controller
-@RequestMapping("/")
 public class HomePageController {
     private final NamedThreadService namedThreadService;
@@ -16,8 +15,12 @@
     }
 
-    @GetMapping
+    @GetMapping("/")
     public String homePage(Model model) {
         model.addAttribute("threads", namedThreadService.findAll());
         return "home";
     }
+    @GetMapping("/home")
+    public String home(Model model) {
+        return "home";
+    }
 }
Index: src/main/java/com/db/finki/www/build_board/controller/SearchController.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/controller/SearchController.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
+++ src/main/java/com/db/finki/www/build_board/controller/SearchController.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -0,0 +1,34 @@
+package com.db.finki.www.build_board.controller;
+
+import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+import com.db.finki.www.build_board.service.search.SearchService;
+import com.db.finki.www.build_board.service.threads.itfs.TopicService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Controller
+public class SearchController {
+    private final TopicService topicService;
+    private final SearchService searchService;
+
+    public SearchController(TopicService topicService, SearchService searchService) {
+        this.topicService = topicService;
+        this.searchService = searchService;
+    }
+
+    @PostMapping("/search")
+    public String search(@RequestParam String query, @RequestParam(required = false) List<String> filters, @RequestParam String type , Model model, RedirectAttributes redirectAttributes) {
+        if(filters == null || filters.isEmpty()) {
+            filters = new ArrayList<>();
+            filters.add("all");
+        }
+        model.addAttribute("threads", searchService.search(query,filters,type));
+        return "home";
+    }
+}
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Tag.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -6,7 +6,5 @@
 import jakarta.persistence.Table;
 import lombok.Data;
-import lombok.Getter;
 import lombok.NoArgsConstructor;
-import lombok.Setter;
 
 import java.util.ArrayList;
Index: src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/entity/threads/Topic.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -6,5 +6,4 @@
 import lombok.*;
 
-import java.util.Map;
 import java.util.List;
 
@@ -12,6 +11,8 @@
 @EqualsAndHashCode(callSuper = false)
 @Entity
+@NoArgsConstructor
 @Table(name = "topic_thread")
 public class Topic extends BBThread implements NamedThread {
+
     private String title;
 
Index: src/main/java/com/db/finki/www/build_board/repository/threads/TopicRepository.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/repository/threads/TopicRepository.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/repository/threads/TopicRepository.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -3,10 +3,12 @@
 import com.db.finki.www.build_board.entity.threads.Topic;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.stereotype.Repository;
 
+
 @Repository
-public interface TopicRepository extends JpaRepository<Topic,Long> {
+public interface TopicRepository extends JpaRepository<Topic,Long>, JpaSpecificationExecutor<Topic> {
     Topic findByTitle(String title);
     void deleteByTitle(String title);
-    Topic findById(long id);
+    Topic findById(long id);;
 }
Index: src/main/java/com/db/finki/www/build_board/service/search/FilterMap.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/search/FilterMap.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
+++ src/main/java/com/db/finki/www/build_board/service/search/FilterMap.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -0,0 +1,38 @@
+package com.db.finki.www.build_board.service.search;
+
+import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+import org.springframework.context.annotation.Scope;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+@Component
+@Scope("prototype")
+public class FilterMap<T extends NamedThread> {
+    private final Map<String, Function<String, Specification<T>>> filterMap;
+    public FilterMap() {
+        filterMap = new HashMap<>();
+        filterMap.put("all", s -> Specification.where(null));
+        filterMap.put("title", (param) -> {
+            if (param == null) {
+                return (root, query, cb) -> null;
+            } else {
+                return (root, query, cb) -> cb.like(cb.lower(root.get("title")), "%" + param.toLowerCase() + "%");
+            }
+        });
+        filterMap.put("content",(param) -> {
+            if (param == null) {
+                return (root, query, cb) -> null;
+            } else {
+                return (root, query, cb) -> cb.like(cb.lower(root.get("content")), "%" + param.toLowerCase() + "%");
+            }
+        });
+
+    }
+    public Function<String, Specification<T>> getFilter(String filter) {
+        return filterMap.get(filter);
+    }
+}
Index: src/main/java/com/db/finki/www/build_board/service/search/SearchService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/search/SearchService.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
+++ src/main/java/com/db/finki/www/build_board/service/search/SearchService.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -0,0 +1,12 @@
+package com.db.finki.www.build_board.service.search;
+
+//spored title, content, type
+
+import com.db.finki.www.build_board.entity.threads.Topic;
+import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+
+import java.util.List;
+
+public interface SearchService {
+    List<NamedThread> search(String query, List<String> filters, String type);
+}
Index: src/main/java/com/db/finki/www/build_board/service/search/SearchServiceImpl.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/search/SearchServiceImpl.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
+++ src/main/java/com/db/finki/www/build_board/service/search/SearchServiceImpl.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -0,0 +1,71 @@
+package com.db.finki.www.build_board.service.search;
+
+import com.db.finki.www.build_board.entity.threads.Project;
+import com.db.finki.www.build_board.entity.threads.Topic;
+import com.db.finki.www.build_board.entity.threads.interfaces.NamedThread;
+import com.db.finki.www.build_board.repository.threads.ProjectRepository;
+import com.db.finki.www.build_board.repository.threads.TopicRepository;
+import com.db.finki.www.build_board.service.threads.impl.NamedThreadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+public class SearchServiceImpl implements SearchService {
+    private final TopicRepository topicRepository;
+    private final FilterMap<Topic> topicFilterMap;
+    private final FilterMap<Project> projectFilterMap;
+    private final ProjectRepository projectRepository;
+    private final NamedThreadService namedThreadService;
+
+    @Autowired
+    public SearchServiceImpl(TopicRepository topicRepository, FilterMap<Topic> topicFilterMap, FilterMap<Project> projectFilterMap, ProjectRepository projectRepository, NamedThreadService namedThreadService) {
+        this.topicRepository = topicRepository;
+        this.topicFilterMap = topicFilterMap;
+        this.projectFilterMap = projectFilterMap;
+        this.projectRepository = projectRepository;
+        this.namedThreadService = namedThreadService;
+    }
+
+
+    //todo strictmode so and spec
+
+    private List<Topic> searchTopics(String query, List<String> filters) {
+        Specification<Topic> spec = Specification.where(null);
+        for (String filter : filters) {
+            System.out.println("FILTER: " + filter);
+            spec = spec.or(topicFilterMap.getFilter(filter).apply(query));
+        }
+        return topicRepository.findAll(spec);
+    }
+
+    private List<Project> searchProjects(String query, List<String> filters) {
+        Specification<Project> spec = Specification.where(null);
+        for (String filter : filters) {
+            spec = spec.or(projectFilterMap.getFilter(filter).apply(query));
+        }
+        return projectRepository.findAll(spec);
+    }
+
+    public List<NamedThread> search(String query, List<String> filters,String type) {
+        List<NamedThread> result = new ArrayList<>();
+
+        if(Objects.equals(type, "project")){
+            System.out.println("PROJECT");
+            result.addAll(searchProjects(query, filters));
+        } else if(Objects.equals(type, "topic")){
+            result.addAll(searchTopics(query, filters));
+            System.out.println("TOPIC");
+        } else {
+            result.addAll(searchTopics(query, filters));
+            result.addAll(searchProjects(query, filters));
+            System.out.println("ALL");
+        }
+
+        return result;
+    }
+}
Index: src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/service/threads/impl/TagServiceImpl.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -8,5 +8,4 @@
 
 import java.util.List;
-import java.util.stream.Collectors;
 
 @Service
Index: src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java
===================================================================
--- src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/java/com/db/finki/www/build_board/service/threads/itfs/TopicService.java	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -13,5 +13,4 @@
     Topic getById(Long id);
     void addTagToTopic(Topic topic, String tagName);
-
     Topic save(long id, String title, String description);
     Topic deleteTagFromTopic(long id, String tagName);
Index: src/main/resources/db/migration/U1__remove_ddl.sql
===================================================================
--- src/main/resources/db/migration/U1__remove_ddl.sql	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/resources/db/migration/U1__remove_ddl.sql	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -36,3 +36,2 @@
 drop function if exists clean_routines CASCADE;
 DROP TRIGGER IF EXISTS validate_same_parent ON discussion_thread CASCADE;
-
Index: src/main/resources/db/migration/V2__add_test_data.sql
===================================================================
--- src/main/resources/db/migration/V2__add_test_data.sql	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/resources/db/migration/V2__add_test_data.sql	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -15,4 +15,19 @@
     ('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);
 
@@ -20,5 +35,9 @@
 VALUES
     (1, 'Topic 1' , NULL),
-    (2, 'Topic 2', NULL);
+    (2, 'Topic 2', NULL),
+    (8, 'Topic 7' , NULL),
+    (9, 'Topic 8', NULL),
+    (16, 'Topic 9' , NULL),
+    (17, 'Topic 10', NULL);
 
 insert into topic_guidelines(topic_id,description)
@@ -36,5 +55,7 @@
 INSERT INTO project_thread (id, title, repo_url)
 VALUES
-    (5, 'Project 1 Thread', 'http://github.com/project1');
+    (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)
Index: src/main/resources/templates/home.html
===================================================================
--- src/main/resources/templates/home.html	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/resources/templates/home.html	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -41,4 +41,6 @@
         <a href="/login" class="btn btn-primary btn-sm ms-auto" th:if="${session.user == null}">Log in</a>
     </div>
+    <a href="/login">Log in</a>
+
 </nav>
 
@@ -46,12 +48,48 @@
 <div class="container">
     <div class="row justify-content-end">
-        <div class="col-md-5 pt-5">
-            <div class="search-container">
-                <input type="text" class="form-control search-input" placeholder="Search...">
-                <i class="fas fa-search search-icon"></i>
-            </div>
+        <div class="col-md-8 pt-5">
+            <form action="/search" method="post" class="row g-3 align-items-center">
+                <!-- Search Input and Button -->
+                <div class="col-auto flex-grow-1">
+                    <div class="input-group">
+                        <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">
+                    </div>
+                </div>
+                <div class="col-auto">
+                    <button type="submit" class="btn btn-primary">
+                        Search
+                    </button>
+                </div>
+
+                <!-- Filters -->
+                <div class="col-12 d-flex align-items-center">
+                    <span class="me-2">Filters:</span>
+                    <div class="form-check me-3">
+                        <input class="form-check-input" type="checkbox" id="filterTitle" name="filters" value="title">
+                        <label class="form-check-label" for="filterTitle">Title</label>
+                    </div>
+                    <div class="form-check me-3">
+                        <input class="form-check-input" type="checkbox" id="filterContent" name="filters" value="content">
+                        <label class="form-check-label" for="filterContent">Content</label>
+                    </div>
+                    <div class="form-group me-3">
+                        <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">
Index: src/main/resources/templates/project_pages/show-project.html
===================================================================
--- src/main/resources/templates/project_pages/show-project.html	(revision aa4ac2337ee8a98e7293037f88d783d291e60dfb)
+++ src/main/resources/templates/project_pages/show-project.html	(revision e1c13920259173a131b3c2380ac66def5b5c73a7)
@@ -27,6 +27,14 @@
             </div>
         </div>
-        <div class="card-body">
-            <p th:text="${project.getContent()}">Description of the project goes here.</p>
+        <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>
@@ -55,5 +63,6 @@
         </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;">
+            <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>
@@ -73,13 +82,17 @@
             </div>
             <div class="modal-body">
-                <form th:action="@{/project/{title}/add-tag(title=${project.getTitle()})}" method="post" id="addTagForm">
+                <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:value="${tag.getName()}" th:text="${tag.getName()}">Example 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" />
+                        <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>
