diff --git a/src/home/index.php b/src/home/index.php
index 3eabce4f15da4e17c1506c07b617f5e6808f6397..b8b0d2681cd933950b2726dbd588be54c81496a3 100644
--- a/src/home/index.php
+++ b/src/home/index.php
@@ -24,18 +24,18 @@ $selectedCity = $_GET["city"] ?? null;
 $selectedPriceRange = $_GET["price-range"] ?? null;
 $selectedSorting = $_GET["sorting"] ?? null;
 
-$gymsFiltered = GymService::getInstance()->getFiltered(
-    [
-        'page' => $currentPage,
-        'cityId' => $selectedCity,
-        'sorting' => $selectedSorting,
-        'priceRange' => $selectedPriceRange,
-        'sortingOption' => $sortingOption,
-        'priceRangeOption' => $priceRangeOption,
-        'gymCountInPage' => $itemInPage,
-        'searching' => $searching
-    ]
-);
+// $gymsFiltered = GymService::getInstance()->getFiltered(
+//     [
+//         'page' => $currentPage,
+//         'cityId' => $selectedCity,
+//         'sorting' => $selectedSorting,
+//         'priceRange' => $selectedPriceRange,
+//         'sortingOption' => $sortingOption,
+//         'priceRangeOption' => $priceRangeOption,
+//         'gymCountInPage' => $itemInPage,
+//         'searching' => $searching
+//     ]
+// );
 
 ?>
 
@@ -51,8 +51,20 @@ $gymsFiltered = GymService::getInstance()->getFiltered(
 
 <body>
     <div class="app">
+        <script>
+            const gym_name = <?php echo json_encode($_GET["gym_name"] ?? null) ?>;
+            const page = <?php echo json_encode($currentPage) ?>;
+            const selectedCity = <?php echo json_encode($selectedCity) ?>;
+            const selectedSorting = <?php echo json_encode($selectedSorting) ?>;
+            const selectedPriceRange = <?php echo json_encode($selectedPriceRange) ?>;
+            const sortingOption = <?php echo json_encode($sortingOption) ?>;
+            const priceRangeOption = <?php echo json_encode($priceRangeOption) ?>;
+            const itemInPage = <?php echo json_encode($itemInPage) ?>;
+            const searching = <?php echo json_encode($searching) ?>;
+            console.log(gym_name);
+        </script>
         <?php
-        echo Navbar();
+            echo Navbar();
         ?>
         <div class="space"></div>
         <div class="first-line-button">
@@ -63,32 +75,24 @@ $gymsFiltered = GymService::getInstance()->getFiltered(
             <?php
                 echo FilterForm($selectedCity, $selectedPriceRange, $selectedSorting);
             ?>
-            <div class="form-search">
-                <input id="input-search" class="input-search" type="text" name="name" onChange={handleChange}
-                    placeholder="Search a gym" />
-                <button class="button-search" id="button-search" onclick="callSearchGym()">
+            <form class="form-search">
+                <input id="input-search" class="input-search" type="text" name="gym_name" placeholder="Search Gym">
+                <button class="button-search" id="button-search">
                     <img src="/public/icon/vector_search.svg" alt="Search Icon">
                 </button>
-            </div>
+            </form>
         </div>
         
-        <div class="gym-card-container">
-            <?php
-            if (sizeof($gymsFiltered['gyms']) == 0) {
-                ?>
-                <?= "No Gym Found" ?>
-                <?php
-            }
-            foreach ($gymsFiltered['gyms'] as $gym) {
-                echo GymCard($gym);
-            }
-            ?>
+        <div class="gym-card-container" id="gym-card-container">
+            <div class="space"></div>
+                Loading...
         </div>
+        <div class="pagination-container" id="pagination-container">
 
-        <div class="pagination-container">
-            <?php echo generatePagination($gymsFiltered['itemCount'], $itemInPage, $currentPage, $maxPages); ?>
         </div>
     </div>
+    <script src="/public/javascript/gym/gym_card.js"></script>
+    <script src="/public/javascript/pagination.js"></script>
     <script src="/public/javascript/gym/filter.js"></script>
     <script src="/public/javascript/gym/search.js"></script>
 </body>
diff --git a/src/public/javascript/gym/filter.js b/src/public/javascript/gym/filter.js
index ad99c8989226b5cd941df2f2dacd0756ac1618d0..5486e4cf5f4678a8b09624eddf08ae6c3378d149 100644
--- a/src/public/javascript/gym/filter.js
+++ b/src/public/javascript/gym/filter.js
@@ -2,14 +2,64 @@ const filter = document.getElementById("filter-gym");
 const filterButton = document.getElementById("button-filter");
 const searchFilter = document.getElementById("button-search-filter");
 const cancelFilter = document.getElementById("button-cancel-filter");
-const searchButton = document.getElementById("button-search");
-const inputSearch = document.getElementById("input-search");
-const inputPriceMin = document.getElementById("filter-min-price");
-const inputPriceMax = document.getElementById("filter-max-price");
-const toggleAlphAsc = document.getElementById("filter-alph-asc");
-const toggleAlphDesc = document.getElementById("filter-alph-desc");
-const togglePriceAsc = document.getElementById("filter-price-asc");
-const togglePriceDesc = document.getElementById("filter-price-desc");
+const queryParams = new URLSearchParams(window.location.search);
+
+function getFilteredGyms(){
+  const params = {
+    page: page,
+    cityId: selectedCity,
+    sorting: selectedSorting,
+    priceRange: selectedPriceRange,
+    sortingOption: sortingOption,
+    priceRangeOption: priceRangeOption,
+    gymCountInPage: itemInPage,
+    searching: searching
+  };
+  const jsonParams = JSON.stringify(params);
+
+  const xhr = new XMLHttpRequest();
+  xhr.onreadystatechange = function() {
+    if(this.readyState === 4) {
+      if(this.status === 200) {
+            FilteredGyms(JSON.parse(this.responseText), page, itemInPage);
+          } else {
+              const json = JSON.parse(this.responseText);
+              alert(json["error"]);
+          }
+      }
+  };
+  
+  xhr.open("PUT", `/api/gym/filter`, true);
+  xhr.send(jsonParams);
+}
+// check if the params has a gym_name
+if ((queryParams.has("gym_name")==false) || queryParams.get("gym_name") == "") {
+  // if (queryParams.get("gym_name") == "") {
+  //   queryParams.delete("gym_name");
+  //   window.location.search = queryParams.toString();
+  // }
+  getFilteredGyms();
+}
+
+function FilteredGyms(data, page, itemInPage) {
+  let gyms = data["gyms"];
+  let data_length = data["itemCount"];
+  let gym_card_container = document.getElementById("gym-card-container");
+  let paginationContainer = document.getElementById("pagination-container");
+  gym_card_container.innerHTML = "";
+  if (gyms.length == 0) {
+    gym_card_container.innerHTML = "No gyms found";
+  }
+  for (let i = 0; i < gyms.length; i++) {
+    gym_card_container.innerHTML += GymCard(gyms[i]);
+  }
+  // alert(page)
+  let pg = generatePagination(data_length, itemInPage, page);
+  paginationContainer.innerHTML = pg;
+}
+
+
+
 filter.style.display = "none";
 filter.addEventListener("click", function (event) {
   // stop propagation but if clicks outside of the filter, it will close the filter
@@ -30,10 +80,3 @@ searchFilter.addEventListener("click", function () {
 cancelFilter.addEventListener("click", function () {
   filter.style.display = "none";
 });
-// change price min and max input from document
-// inputPriceMin.addEventListener("change", function () {
-//   filteredGymData.price_min = inputPriceMin.value;
-// });
-// inputPriceMax.addEventListener("change", function () {
-//   filteredGymData.price_max = inputPriceMax.value;
-// });
diff --git a/src/public/javascript/gym/gym_card.js b/src/public/javascript/gym/gym_card.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb43578b575a959b4bf01d16715fa97ca00df991
--- /dev/null
+++ b/src/public/javascript/gym/gym_card.js
@@ -0,0 +1,44 @@
+function truncateText(text, length)
+{
+    if (text.length <= length) {
+        return text;
+    } else {
+        text = text.substring(0, length-3);
+        text = text + "...";
+        return text;
+    }
+}
+
+function formatPrice(price)
+{
+    if (price == 0) {
+        return "Free";
+    }
+    price = price.toLocaleString('id-ID');
+    return 'Rp' + price;
+}
+
+function GymCard(gym){
+    let truncated_name = truncateText(gym.name, 16);
+    let formatted_price = formatPrice(gym.monthly_price);
+    let gym_card = `
+    <a class="gym-card" id="gym-card-${gym.gym_id}" href="./gym?gym_id=${gym.gym_id}">
+    <div class="content-gym-card">
+        <img class="gym-card-picture" src="../public/image/gym/${gym.picture_id}.png" alt="Gym Image-${gym.picture_id}">
+        <div class="gym-card-text">
+            <div class="gym-card-name">${truncated_name}</div>
+            <div class="gym-card-text-bottom">
+                <div class="gym-card-text-bottom-left">
+                    ${gym.average_rating}
+                    <img src="../public/icon/star.svg" alt="Star Icon">
+                </div>
+                <div class="gym-card-text-bottom-right">
+                    ${formatted_price}
+                </div>
+            </div>
+        </div>
+    </div>
+    </a>
+    `;
+    return gym_card;
+}
\ No newline at end of file
diff --git a/src/public/javascript/gym/search.js b/src/public/javascript/gym/search.js
index 14b32f38c3be74e57a19516658c266c46a1f6036..c0047ceb62bc48d1fb8cd79fbdd324281f1676af 100644
--- a/src/public/javascript/gym/search.js
+++ b/src/public/javascript/gym/search.js
@@ -1,9 +1,16 @@
-function callSearchGym() {
+if (gym_name != null && gym_name != "") {
+    callSearchGym(gym_name);
+}
+
+function callSearchGym(gym_name) {
+    // alert(JSON.stringify(gyms));
+    // searchGym(gyms, document.getElementById("input-search").value);
     const xhr = new XMLHttpRequest();
     xhr.onreadystatechange = function() {
         if(this.readyState === 4) {
             if(this.status === 200) {
-                searchGym(JSON.parse(this.responseText), document.getElementById("input-search").value);
+                // searchGym(JSON.parse(this.responseText), document.getElementById("input-search").value);
+                searchGym(JSON.parse(this.responseText), gym_name);
             } else {
                 const json = JSON.parse(this.responseText);
                 alert(json["error"]);
@@ -15,31 +22,25 @@ function callSearchGym() {
    xhr.send(); 
 }
 
-
 function searchGym(allGyms, searchString) {
-    const searchedGyms = [];
-    for(let i = 0; i < allGyms.length; i++) {
-        if(allGyms[i]["name"].toUpperCase().includes(searchString.toUpperCase())) {
-            searchedGyms.push(allGyms[i]);
-        }
-    }
+    const paginationContainer = document.getElementById("pagination-container");
+    const searchedGyms = allGyms.filter((gym) => {
+        return gym["name"].toUpperCase().includes(searchString.toUpperCase());
+    });
+    data_length = searchedGyms.length;
+    let gymCardContainer = document.getElementById("gym-card-container");
+    gymCardContainer.innerHTML = "";
+    if(searchedGyms.length == 0) {
+        gymCardContainer.innerHTML = "No gyms found";
+    } else {
+         // Slice the array to display 
+         let startIndex = (page - 1) * itemInPage;
+         let slicedGyms = searchedGyms.slice(startIndex, startIndex + itemInPage);
 
-    const xhr = new XMLHttpRequest();
-
-    xhr.onreadystatechange = function() {
-        if(this.readyState === 4) {
-            if(this.status === 200) {
-        
-                window.location.reload(true);
-            } else {
-                const json = JSON.parse(this.responseText);
-                alert(json["error"]);
-            }
+        for(let i = 0; i < slicedGyms.length; i++) {
+            gymCardContainer.innerHTML += GymCard(slicedGyms[i]);
         }
-    };
-
-    xhr.open("POST", `/home/`, true);
-    xhr.setRequestHeader('Content-Type', 'application/json');
-
-    xhr.send(JSON.stringify(searchedGyms));
-}
\ No newline at end of file
+        let pg = generatePagination(data_length, itemInPage, page);
+        paginationContainer.innerHTML = pg;
+    }
+}
diff --git a/src/public/javascript/pagination.js b/src/public/javascript/pagination.js
new file mode 100644
index 0000000000000000000000000000000000000000..5364ec565f5d8d4ea118d0cd17240b35cd032bb8
--- /dev/null
+++ b/src/public/javascript/pagination.js
@@ -0,0 +1,45 @@
+function generatePagination(totalItems, itemsPerPage, currentPage, maxPages = 6) {
+    const totalPages = Math.ceil(totalItems / itemsPerPage);
+    let pagination = '<div class="pagination">';
+    const queryParams = new URLSearchParams(window.location.search);
+    queryParams.delete('page');
+    
+    const queryString = queryParams.toString() ? `&${queryParams.toString()}` : '';
+
+    // Previous page 
+    if (currentPage > 1) {
+        pagination += `<a href="?page=${currentPage - 1}${queryString}">&laquo;</a>`;
+    }
+
+    // Individual pages
+    if (totalPages > maxPages) {
+        let start = Math.max(1, currentPage - Math.floor(maxPages / 2));
+        let end = Math.min(totalPages, start + maxPages - 1);
+        start = Math.max(1, end - maxPages + 1);
+
+        if (start > 1) {
+            pagination += '<span>...</span>';
+        }
+
+        for (let i = start; i <= end; i++) {
+            pagination += `<a href="?page=${i}${queryString}" ${i == currentPage ? 'class="active"' : ''}>${i}</a>`;
+        }
+
+        if (end < totalPages) {
+            pagination += '<span>...</span>';
+        }
+    } else {
+        for (let i = 1; i <= totalPages; i++) {
+            pagination += `<a href="?page=${i}${queryString}" ${i === currentPage ? 'class="active"' : ''}>${i}</a>`;
+        }
+    }
+
+    // Next page 
+    if (currentPage < totalPages) {
+        pagination += `<a href="?page=${currentPage + 1}${queryString}">&raquo;</a>`;
+    }
+
+    pagination += '</div>';
+
+    return pagination;
+}