PageSourceSearch

https://amaga-antioquia.gov.co/SiteAssets/v4/assets/components/home-noticias/js/interface.js

js amaga-antioquia.gov.co collected 2026-10-02 13:21:10 UTC 9,942 bytes, 287 lines download raw bytes

1import { API } from "./API.js";
2
3//DOM Elements
4const FILTER_LIST = document.querySelector("#select-category");
5const NEWS_COUNTER = document.querySelector("#news-count");
6const INPUT_SEARCH = document.querySelector("#input-search-news");
7const DATE_PICKER = document.querySelector("#datePicker");
8
9//DELETE AND SEARCH
10const FILTER_BUTTONS = document.querySelectorAll("#category-buttons > li");
11const DATE_BUTTONS = document.querySelectorAll("#date-buttons > li");
12
13const ITEMS_LIST = document.querySelector("#items-list");
14
15//HANDLERS DOM ELEMENTS
16const LOADER = document.querySelector("#loader");
17
18let _FILTER = "";
19let _DATE_FILTER = [];
20let _SEARCH = "";
21
22const itemComponent = (info) => {
23  const li = document.createElement("li");
24
25  li.innerHTML = `
26  <a href="${info.link}" class="no-underline flex flex-col h-full border-solid border border-gray-200 rounded-xl overflow-hidden group">
27    <figure class="h-[300px] relative">
28      <figcaption class="flex gap-3 absolute z-[20] bg-color1 p-2 bottom-3 left-3 rounded-lg">
29        <p class="!m-0 !p-0 !font-semibold text-white !uppercase">${
30          info.category ? info.category : "Sin Categoría"
31        }</p>
32      </figcaption>
33      <img src="${info.image}" alt="${info.title}" class="w-full object-cover relative h-[300px]">
34    </figure>
35    <section class="flex items-center justify-center gap-2 p-2 bg-color1 text-white">
36      <i class="fa-regular fa-calendar-days"></i>
37      <p class="!uppercase !m-0 !p-0">${info.date}</p>
38    </section>
39    <section class="flex flex-col h-full justify-between gap-4 p-3">
40      <h3 class="line-clamp-3 text-[25px] group-hover:text-color1 !font-bold text-color8 transition-colors duration-300 !m-0 !p-0">
41      ${info.title}
42      </h3>
43      <p class="text-black font-light leading-6 line-clamp-2">
44      ${info.comments}
45      </p>
46      <p class="underline text-black font-semibold group-hover:text-color1 transition-colors duration-300">
47        Conocer más
48      </p>
49    </section>
50  </a>
51  `;
52
53  return li;
54};
55
56const drawPagination = async (count, currentPage) => {
57  const pagination = document.getElementById("countPagination");
58  pagination.innerHTML = ""; // Clear existing pagination buttons
59
60  const totalPages = Math.ceil(count / 8); // Usar PAGE_SIZE = 8
61  const maxVisiblePages = 4;
62  let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
63  let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
64
65  if (endPage - startPage < maxVisiblePages - 1) {
66    startPage = Math.max(1, endPage - maxVisiblePages + 1);
67  }
68
69  if (startPage > 1) {
70    const prevButton = document.createElement("button");
71    prevButton.setAttribute("type", "button");
72    prevButton.setAttribute(
73      "class",
74      "bg-black !m-0 !p-0 border-none cursor-pointer w-[40px] h-[40px]  rounded-full flex items-center justify-center transition-color duration-500 hover:opacity-80"
75    );
76    prevButton.innerHTML = `<i class="fa-solid fa-chevron-left text-white text-[18px]"></i>`;
77    prevButton.addEventListener("click", () => {
78      ITEMS_LIST.innerHTML = "";
79      LOADER.classList.remove("hidden");
80      drawPagination(count, currentPage - 1);
81      API.goToPage(currentPage - 1, _FILTER, _DATE_FILTER, _SEARCH).then(
82        ({ results }) => {
83          drawItems(results, currentPage - 1);
84        }
85      );
86    });
87    pagination.appendChild(prevButton);
88  }
89
90  for (let i = startPage; i <= endPage; i++) {
91    const page = document.createElement("button");
92    page.setAttribute("type", "button");
93    page.setAttribute(
94      "class",
95      "page-button text-[16px] !m-0 !p-0 border-none cursor-pointer w-[40px] h-[40px] rounded-full flex items-center justify-center transition-color duration-500 font-bold hover:opacity-80"
96    );
97    page.textContent = i;
98    if (i === currentPage) {
99      page.classList.add("bg-color1");
100    } else {
101      page.classList.add("bg-color7");
102    }
103    page.addEventListener("click", async () => {
104      ITEMS_LIST.innerHTML = "";
105      LOADER.classList.remove("hidden");
106      API.goToPage(i, _FILTER, _DATE_FILTER, _SEARCH).then(({ results }) => {
107        drawItems(results, i);
108      });
109      drawPagination(count, i); // Update pagination to reflect the active page
110    });
111    pagination.appendChild(page);
112  }
113
114  if (endPage < totalPages) {
115    const nextButton = document.createElement("button");
116    nextButton.setAttribute("type", "button");
117    nextButton.setAttribute(
118      "class",
119      "bg-black !m-0 !p-0 border-none cursor-pointer w-[40px] h-[40px]  rounded-full flex items-center justify-center transition-color duration-500 hover:opacity-80"
120    );
121    nextButton.innerHTML = `<i class="fa-solid fa-chevron-right text-white text-[18px]"></i>`;
122    nextButton.addEventListener("click", () => {
123      ITEMS_LIST.innerHTML = "";
124      LOADER.classList.remove("hidden");
125      drawPagination(count, currentPage + 1);
126      API.goToPage(currentPage + 1, _FILTER, _DATE_FILTER, _SEARCH).then(
127        ({ results }) => {
128          drawItems(results, currentPage + 1);
129        }
130      );
131    });
132    pagination.appendChild(nextButton);
133  }
134
135  // Update active page button
136  const btnPages = document.querySelectorAll("#countPagination > .page-button");
137  btnPages.forEach((btn) => {
138    btn.classList.remove("bg-color7");
139
140    btn.classList.add("bg-color1");
141    if (parseInt(btn.textContent) === currentPage) {
142      btn.classList.remove("bg-color1");
143
144      btn.classList.add("bg-color7");
145    }
146  });
147};
148
149const drawItems = async (items, currentPage) => {
150  LOADER.classList.add("hidden");
151  ITEMS_LIST.innerHTML = ""; // Clear existing cards
152
153  items.forEach((item) => {
154    const itemHTML = itemComponent(item);
155    ITEMS_LIST.appendChild(itemHTML);
156  });
157
158  // Update active page button
159  const btnPages = document.querySelectorAll("#countPagination > .page-button");
160  btnPages.forEach((btn) => {
161    btn.classList.remove("bg-color7");
162
163    btn.classList.add("bg-color1");
164    if (parseInt(btn.textContent) === currentPage) {
165      btn.classList.remove("bg-color1");
166
167      btn.classList.add("bg-color7");
168    }
169  });
170};
171
172const mainInterfaceFunctions = () => {
173  // Inicializar Flatpickr y guardar la instancia
174  const flatpickrInstance = flatpickr("#datePicker", { mode: "range",
175    dateFormat: "Y-m-d",});
176
177  INPUT_SEARCH.addEventListener("input", async (e) => {
178    _SEARCH = e.target.value;
179    updateDOM();
180  });
181
182  FILTER_LIST.addEventListener("change", async (e) => {
183    FILTER_BUTTONS[0].classList.remove("opacity-80");
184    FILTER_BUTTONS[0].addEventListener("click", async () => {
185      _FILTER = e.target.value;
186      FILTER_BUTTONS[0].classList.add("hidden");
187      FILTER_BUTTONS[1].classList.remove("hidden");
188      updateDOM();
189    });
190    if (!FILTER_BUTTONS[1].classList.contains("hidden")) {
191      _FILTER = e.target.value;
192      updateDOM();
193    }
194    FILTER_BUTTONS[1].addEventListener("click", async () => {
195      _FILTER = "";
196      FILTER_LIST.value = "";
197      FILTER_BUTTONS[1].classList.add("hidden");
198      FILTER_BUTTONS[0].classList.remove("hidden");
199      FILTER_BUTTONS[0].classList.add("opacity-80");
200      updateDOM();
201    });
202  });
203
204  DATE_PICKER.addEventListener("change", async (e) => {
205    DATE_BUTTONS[0].classList.remove("opacity-80");
206
207    DATE_BUTTONS[0].addEventListener("click", async () => {
208      const dateRange = e.target.value.split(" to ");
209      const startDate = dateRange[0];
210      const endDate = dateRange[1];
211
212      _DATE_FILTER = [startDate, endDate];
213      DATE_BUTTONS[0].classList.add("hidden");
214      DATE_BUTTONS[1].classList.remove("hidden");
215      updateDOM();
216      DATE_PICKER.setAttribute("disabled", "true"); // Deshabilitar el selector de fecha
217    });
218    DATE_BUTTONS[1].addEventListener("click", async () => {
219      _DATE_FILTER = [];
220      flatpickrInstance.clear(); // Limpiar el valor del selector de fecha
221      DATE_PICKER.value = "";
222      DATE_BUTTONS[1].classList.add("hidden");
223      DATE_BUTTONS[0].classList.remove("hidden");
224      DATE_BUTTONS[0].classList.add("opacity-80");
225      DATE_PICKER.removeAttribute("disabled"); // Habilitar el selector de fecha
226      updateDOM();
227    });
228  });
229};
230
231const updateDOM = async () => {
232  LOADER.classList.remove("hidden");
233  const { results } = await API.goToPage(
234    1,
235    _FILTER,
236    _DATE_FILTER,
237    _SEARCH
238  );
239  const allItemsCount = await API.getAllItemsCount(
240    _FILTER,
241    _DATE_FILTER,
242    _SEARCH
243  );
244  animateCount(NEWS_COUNTER, 0, allItemsCount, 1000);
245
246  if (results.length === 0) {
247    ITEMS_LIST.innerHTML = "";
248    drawPagination(allItemsCount, 1);
249    ITEMS_LIST.appendChild(noFoundComponent());
250    LOADER.classList.add("hidden");
251    return;
252  }
253  drawItems(results, 1);
254  drawPagination(allItemsCount, 1);
255  LOADER.classList.add("hidden");
256};
257
258const noFoundComponent = () => {
259  const li = document.createElement("li");
260  li.className = "col-span-1 lg:col-span-4 w-full h-full";
261  li.innerHTML = `
262 <section
263      class="lg:min-h-[1500px] h-full w-full flex flex-col gap-4 items-center justify-center"
264      id="not-found"
265    >
266      <img src="/SiteAssets/v1/assets/components/home-noticias/not-found.svg" alt="not found" class="w-[200px] h-[200px]" />
267        <p class="text-[20px] font-semibold text-center">No se encontraron elementos</p>
268    </section>`;
269  return li;
270};
271
272function animateCount(element, start = 0, end = 0, duration = 1000) {
273  anime({
274    targets: element,
275    innerHTML: [start, end],
276    easing: "linear",
277    round: 1, // Redondear a números enteros
278    duration: duration,
279  });
280}
281
282export const UI = {
283  drawPagination,
284  drawItems,
285  animateCount,
286  mainInterfaceFunctions,
287};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.