{"id":5136,"date":"2026-02-04T12:54:25","date_gmt":"2026-02-04T12:54:25","guid":{"rendered":"https:\/\/csaude.org.mz\/?page_id=5136"},"modified":"2026-09-09T09:02:58","modified_gmt":"2026-09-09T07:02:58","slug":"concursos","status":"publish","type":"page","link":"https:\/\/csaude.org.mz\/pt\/concursos\/","title":{"rendered":"Concursos"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"5136\" class=\"elementor elementor-5136\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f9952d8 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"f9952d8\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2568378 e-con-full e-flex wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"2568378\" data-element_type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8542808 elementor-widget elementor-widget-html\" data-id=\"8542808\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"lista-concursos-publicos\">\r\n  <style>\r\n    #lista-concursos-publicos {\r\n      font-family: Arial, sans-serif;\r\n      color: #1f2937;\r\n      max-width: 1100px;\r\n      margin: 0 auto;\r\n      padding: 20px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-header {\r\n      margin-bottom: 24px;\r\n      text-align: center;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-header h2 {\r\n      font-size: 32px;\r\n      margin-bottom: 10px;\r\n      color: #0f172a;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-header p {\r\n      font-size: 16px;\r\n      color: #475569;\r\n      max-width: 780px;\r\n      margin: 0 auto;\r\n      line-height: 1.6;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-filters {\r\n      display: grid;\r\n      grid-template-columns: minmax(0, 1fr) 260px;\r\n      gap: 14px;\r\n      margin: 30px 0 20px;\r\n      align-items: stretch;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-search-wrap,\r\n    #lista-concursos-publicos .cp-select-wrap {\r\n      position: relative;\r\n    }\r\n\r\n    #lista-concursos-publicos input,\r\n    #lista-concursos-publicos select {\r\n      width: 100%;\r\n      min-width: 0;\r\n      height: 52px;\r\n      padding: 14px 16px;\r\n      border: 1px solid #cbd5e1;\r\n      border-radius: 12px;\r\n      font-size: 15px;\r\n      box-sizing: border-box;\r\n      background: #fff;\r\n      color: #0f172a;\r\n      outline: none;\r\n      transition: border-color 0.2s ease, box-shadow 0.2s ease;\r\n    }\r\n\r\n    #lista-concursos-publicos input:focus,\r\n    #lista-concursos-publicos select:focus {\r\n      border-color: #0f766e;\r\n      box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.12);\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-section {\r\n      margin-top: 34px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-section-header {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 12px;\r\n      flex-wrap: wrap;\r\n      margin-bottom: 16px;\r\n      padding-bottom: 10px;\r\n      border-bottom: 2px solid #e2e8f0;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-section-title {\r\n      margin: 0;\r\n      font-size: 24px;\r\n      color: #0f172a;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-section-count {\r\n      font-size: 14px;\r\n      font-weight: 700;\r\n      color: #475569;\r\n      background: #f8fafc;\r\n      border: 1px solid #e2e8f0;\r\n      border-radius: 999px;\r\n      padding: 8px 12px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-list {\r\n      display: grid;\r\n      gap: 18px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-card {\r\n      background: #ffffff;\r\n      border: 1px solid #e2e8f0;\r\n      border-radius: 14px;\r\n      padding: 22px;\r\n      box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06);\r\n      transition: transform 0.2s ease, box-shadow 0.2s ease;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-card:hover {\r\n      transform: translateY(-2px);\r\n      box-shadow: 0 10px 24px rgba(15, 23, 42, 0.1);\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-top {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: flex-start;\r\n      gap: 15px;\r\n      flex-wrap: wrap;\r\n      margin-bottom: 14px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-title {\r\n      font-size: 22px;\r\n      font-weight: bold;\r\n      color: #0f172a;\r\n      margin: 0 0 10px 0;\r\n      line-height: 1.35;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-badge {\r\n      display: inline-block;\r\n      background: #ecfeff;\r\n      color: #0f766e;\r\n      padding: 6px 12px;\r\n      border-radius: 999px;\r\n      font-size: 13px;\r\n      font-weight: bold;\r\n      margin-right: 8px;\r\n      margin-bottom: 8px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-status {\r\n      display: inline-block;\r\n      padding: 6px 12px;\r\n      border-radius: 999px;\r\n      font-size: 13px;\r\n      font-weight: bold;\r\n      margin-bottom: 8px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-status-open {\r\n      background: #dcfce7;\r\n      color: #166534;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-status-closed {\r\n      background: #fee2e2;\r\n      color: #991b1b;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-status-awarded {\r\n      background: #dbeafe;\r\n      color: #1e3a8a;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-meta {\r\n      display: grid;\r\n      grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\r\n      gap: 10px;\r\n      margin: 14px 0;\r\n      font-size: 14px;\r\n      color: #334155;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-meta div {\r\n      background: #f8fafc;\r\n      border-radius: 8px;\r\n      padding: 10px 12px;\r\n      line-height: 1.5;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-description {\r\n      font-size: 15px;\r\n      line-height: 1.6;\r\n      color: #475569;\r\n      margin: 16px 0 20px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-footer {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 12px;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-deadline {\r\n      font-size: 14px;\r\n      font-weight: bold;\r\n      color: #b91c1c;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-btn {\r\n      display: inline-block;\r\n      padding: 12px 18px;\r\n      background: #0f766e;\r\n      color: #fff;\r\n      text-decoration: none;\r\n      border-radius: 10px;\r\n      font-weight: bold;\r\n      font-size: 14px;\r\n      transition: background 0.2s ease;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-btn:hover {\r\n      background: #115e59;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-no-results {\r\n      text-align: center;\r\n      padding: 30px 15px;\r\n      background: #f8fafc;\r\n      border: 1px dashed #cbd5e1;\r\n      border-radius: 12px;\r\n      color: #64748b;\r\n      font-size: 15px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-empty-section {\r\n      padding: 18px 16px;\r\n      background: #fafafa;\r\n      border: 1px dashed #d1d5db;\r\n      border-radius: 12px;\r\n      color: #6b7280;\r\n      font-size: 14px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-pagination {\r\n      display: flex;\r\n      justify-content: center;\r\n      align-items: center;\r\n      gap: 8px;\r\n      flex-wrap: wrap;\r\n      margin-top: 22px;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-page-btn {\r\n      border: 1px solid #cbd5e1;\r\n      background: #fff;\r\n      color: #0f172a;\r\n      padding: 10px 14px;\r\n      border-radius: 10px;\r\n      cursor: pointer;\r\n      font-size: 14px;\r\n      font-weight: 600;\r\n      transition: all 0.2s ease;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-page-btn:hover {\r\n      background: #f1f5f9;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-page-btn.active {\r\n      background: #0f766e;\r\n      color: #fff;\r\n      border-color: #0f766e;\r\n    }\r\n\r\n    #lista-concursos-publicos .cp-page-btn:disabled {\r\n      opacity: 0.5;\r\n      cursor: not-allowed;\r\n    }\r\n    \r\n    #lista-concursos-publicos .cp-top-content {\r\n  flex: 1;\r\n  min-width: 0;\r\n}\r\n\r\n#lista-concursos-publicos .cp-top-actions {\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 8px;\r\n  flex-shrink: 0;\r\n}\r\n\r\n#lista-concursos-publicos .cp-language-btn {\r\n  display: inline-flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 6px;\r\n  min-height: 38px;\r\n  padding: 8px 13px;\r\n  border: 1px solid #0f766e;\r\n  border-radius: 9px;\r\n  background: #ffffff;\r\n  color: #0f766e;\r\n  font-size: 13px;\r\n  font-weight: 700;\r\n  cursor: pointer;\r\n  transition:\r\n    background 0.2s ease,\r\n    color 0.2s ease,\r\n    border-color 0.2s ease;\r\n}\r\n\r\n#lista-concursos-publicos .cp-language-btn:hover {\r\n  background: #0f766e;\r\n  color: #ffffff;\r\n}\r\n\r\n#lista-concursos-publicos .cp-language-btn:focus {\r\n  outline: none;\r\n  box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.15);\r\n}\r\n\r\n    @media (max-width: 768px) {\r\n        #lista-concursos-publicos .cp-top-actions {\r\n  width: 100%;\r\n  justify-content: flex-start;\r\n}\r\n      #lista-concursos-publicos .cp-filters {\r\n        grid-template-columns: 1fr;\r\n      }\r\n\r\n      #lista-concursos-publicos .cp-header h2 {\r\n        font-size: 26px;\r\n      }\r\n\r\n      #lista-concursos-publicos .cp-title {\r\n        font-size: 20px;\r\n      }\r\n\r\n      #lista-concursos-publicos .cp-meta {\r\n        grid-template-columns: 1fr;\r\n      }\r\n    }\r\n  <\/style>\r\n\r\n  <div class=\"cp-header\">\r\n    <h2>Concursos P\u00fablicos<\/h2>\r\n    <p>\r\n      Consulte abaixo os concursos p\u00fablicos e oportunidades de procurement actualmente dispon\u00edveis.\r\n      Utilize a pesquisa ou filtre por categoria para localizar rapidamente o concurso pretendido.\r\n    <\/p>\r\n  <\/div>\r\n\r\n  <div class=\"cp-filters\">\r\n    <div class=\"cp-search-wrap\">\r\n      <input type=\"text\" id=\"cpSearch\" placeholder=\"Pesquisar por t\u00edtulo, refer\u00eancia, local ou categoria...\" \/>\r\n    <\/div>\r\n    <div class=\"cp-select-wrap\">\r\n      <select id=\"cpCategoryFilter\">\r\n        <option value=\"all\">Todas as categorias<\/option>\r\n      <\/select>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"cpResults\"><\/div>\r\n<\/div>\r\n\r\n<script>\r\n  (function () {\r\n    let concursos = [];\r\n    \/\/ Endpoint no pr\u00f3prio website. O browser deixa de comunicar directamente com o OPS.\r\n    const CP_API_URL = \"\/wp-json\/csaude\/v1\/concursos\";\r\n\r\n    const cpSearch = document.getElementById(\"cpSearch\");\r\n    const cpCategoryFilter = document.getElementById(\"cpCategoryFilter\");\r\n    const cpResults = document.getElementById(\"cpResults\");\r\n\r\n    const itemsPerPage = 10;\r\n    \r\n    const languageState = {};\r\n\r\nconst interfaceTexts = {\r\n  pt: {\r\n    reference: \"Refer\u00eancia\",\r\n    publishedDate: \"Data de publica\u00e7\u00e3o\",\r\n    clarificationDeadline: \"Prazo para esclarecimentos\",\r\n    submissionDeadline: \"Prazo de submiss\u00e3o\",\r\n    location: \"Local\",\r\n    status: \"Estado\",\r\n\r\n    open: \"Aberto\",\r\n    closed: \"Fechado\",\r\n    awarded: \"Adjudicado\",\r\n    cancelled: \"Cancelado\",\r\n\r\n    submissionUntil: \"Submiss\u00e3o at\u00e9\",\r\n    tenderClosed: \"Concurso Fechado\",\r\n    tenderAwarded: \"Concurso Adjudicado\",\r\n    tenderCancelled: \"Concurso Cancelado\",\r\n\r\n    documentsButton: \"Ver edital \/ Documentos\",\r\n    changeLanguage: \"English\"\r\n  },\r\n\r\n  en: {\r\n    reference: \"Reference\",\r\n    publishedDate: \"Publication date\",\r\n    clarificationDeadline: \"Clarification deadline\",\r\n    submissionDeadline: \"Submission deadline\",\r\n    location: \"Location\",\r\n    status: \"Status\",\r\n\r\n    open: \"Open\",\r\n    closed: \"Closed\",\r\n    awarded: \"Awarded\",\r\n    cancelled: \"Cancelled\",\r\n\r\n    submissionUntil: \"Submission deadline\",\r\n    tenderClosed: \"Tender Closed\",\r\n    tenderAwarded: \"Tender Awarded\",\r\n    tenderCancelled: \"Tender Cancelled\",\r\n\r\n    documentsButton: \"View tender \/ Documents\",\r\n    changeLanguage: \"Portugu\u00eas\"\r\n  }\r\n};\r\nfunction getItemId(item) {\r\n  return item.id || item.reference;\r\n}\r\n\r\nfunction hasMultipleLanguages(item) {\r\n  return (\r\n    item.languages &&\r\n    Object.keys(item.languages).length > 1\r\n  );\r\n}\r\n\r\nfunction getCurrentLanguage(item) {\r\n  if (!item.languages) {\r\n    return \"pt\";\r\n  }\r\n\r\n  const itemId = getItemId(item);\r\n\r\n  if (languageState[itemId] && item.languages[languageState[itemId]]) {\r\n    return languageState[itemId];\r\n  }\r\n\r\n  if (item.languages.pt) {\r\n    return \"pt\";\r\n  }\r\n\r\n  return Object.keys(item.languages)[0];\r\n}\r\n\r\nfunction getItemContent(item) {\r\n  if (!item.languages) {\r\n    return {\r\n      title: item.title || \"\",\r\n      category: item.category || \"\",\r\n      description: item.description || \"\"\r\n    };\r\n  }\r\n\r\n  const language = getCurrentLanguage(item);\r\n  const selectedContent = item.languages[language];\r\n\r\n  return {\r\n    title: selectedContent.title || \"\",\r\n    category: selectedContent.category || item.category || \"\",\r\n    description: selectedContent.description || \"\"\r\n  };\r\n}\r\n\r\nfunction getAllLanguageContent(item) {\r\n  if (!item.languages) {\r\n    return [\r\n      item.title || \"\",\r\n      item.category || \"\",\r\n      item.description || \"\"\r\n    ].join(\" \");\r\n  }\r\n\r\n  return Object.values(item.languages)\r\n    .map(language => {\r\n      return [\r\n        language.title || \"\",\r\n        language.category || \"\",\r\n        language.description || \"\"\r\n      ].join(\" \");\r\n    })\r\n    .join(\" \");\r\n}\r\n\r\n    function parseDate(dateStr) {\r\n      if (!dateStr || typeof dateStr !== \"string\") return null;\r\n      const parts = dateStr.split(\"\/\");\r\n      if (parts.length !== 3) return null;\r\n      const [day, month, year] = parts;\r\n      const parsed = new Date(Number(year), Number(month) - 1, Number(day));\r\n      return Number.isNaN(parsed.getTime()) ? null : parsed;\r\n    }\r\n\r\n    function isExpired(dateStr) {\r\n      const targetDate = parseDate(dateStr);\r\n      if (!targetDate) return false;\r\n      const today = new Date();\r\n      today.setHours(0, 0, 0, 0);\r\n      targetDate.setHours(0, 0, 0, 0);\r\n      return today > targetDate;\r\n    }\r\n\r\n    function getStatus(item, language = \"pt\") {\r\n      const texts = interfaceTexts[language] || interfaceTexts.pt;\r\n\r\n      if (item.status === \"cancelled\") {\r\n        return { key: \"cancelled\", label: texts.cancelled, class: \"cp-status-closed\" };\r\n      }\r\n      if (item.status === \"awarded\") {\r\n        return { key: \"awarded\", label: texts.awarded, class: \"cp-status-awarded\" };\r\n      }\r\n      if (item.status === \"closed\" || isExpired(item.submissionDeadline)) {\r\n        return { key: \"closed\", label: texts.closed, class: \"cp-status-closed\" };\r\n      }\r\n      return { key: \"open\", label: texts.open, class: \"cp-status-open\" };\r\n    }\r\n\r\n    function populateCategories() {\r\n      const categories = [...new Set(concursos.map(item => item.category))].sort();\r\n      categories.forEach(category => {\r\n        const option = document.createElement(\"option\");\r\n        option.value = category;\r\n        option.textContent = category;\r\n        cpCategoryFilter.appendChild(option);\r\n      });\r\n    }\r\n\r\n    function getFilteredConcursos() {\r\n  const searchTerm = cpSearch.value.toLowerCase().trim();\r\n  const selectedCategory = cpCategoryFilter.value;\r\n\r\n  return concursos\r\n    .filter(item => {\r\n      const searchableContent = [\r\n        getAllLanguageContent(item),\r\n        item.reference || \"\",\r\n        item.category || \"\",\r\n        item.location || \"\"\r\n      ]\r\n        .join(\" \")\r\n        .toLowerCase();\r\n\r\n      const matchesSearch =\r\n        searchTerm === \"\" ||\r\n        searchableContent.includes(searchTerm);\r\n\r\n      const matchesCategory =\r\n        selectedCategory === \"all\" ||\r\n        item.category === selectedCategory;\r\n\r\n      return matchesSearch && matchesCategory;\r\n    })\r\n    .sort((a, b) => {\r\n      const dateA = parseDate(a.publishedDate);\r\n      const dateB = parseDate(b.publishedDate);\r\n      return (dateB ? dateB.getTime() : 0) - (dateA ? dateA.getTime() : 0);\r\n    });\r\n}\r\n\r\n    function renderCard(item) {\r\n  const language = getCurrentLanguage(item);\r\n  const content = getItemContent(item);\r\n  const texts = interfaceTexts[language] || interfaceTexts.pt;\r\n  const status = getStatus(item, language);\r\n  const itemId = getItemId(item);\r\n\r\n  const languageButton = hasMultipleLanguages(item)\r\n    ? `\r\n      <div class=\"cp-top-actions\">\r\n        <button\r\n          type=\"button\"\r\n          class=\"cp-language-btn\"\r\n          data-item-id=\"${itemId}\"\r\n          aria-label=\"${texts.changeLanguage}\"\r\n          title=\"${texts.changeLanguage}\"\r\n        >\r\n          \ud83c\udf10 ${texts.changeLanguage}\r\n        <\/button>\r\n      <\/div>\r\n    `\r\n    : \"\";\r\n\r\n  let deadlineText = \"\";\r\n\r\n  if (status.key === \"open\") {\r\n    deadlineText = `${texts.submissionUntil}: ${item.submissionDeadline}`;\r\n  } else if (status.key === \"closed\") {\r\n    deadlineText = texts.tenderClosed;\r\n  } else if (status.key === \"cancelled\") {\r\n    deadlineText = texts.tenderCancelled;\r\n  } else {\r\n    deadlineText = texts.tenderAwarded;\r\n  }\r\n\r\n  return `\r\n    <div class=\"cp-card\">\r\n      <div class=\"cp-top\">\r\n        <div class=\"cp-top-content\">\r\n          <h3 class=\"cp-title\">${content.title}<\/h3>\r\n\r\n          <span class=\"cp-badge\">\r\n            ${content.category}\r\n          <\/span>\r\n\r\n          <span class=\"cp-status ${status.class}\">\r\n            ${status.label}\r\n          <\/span>\r\n        <\/div>\r\n\r\n        ${languageButton}\r\n      <\/div>\r\n\r\n      <div class=\"cp-meta\">\r\n        <div>\r\n          <strong>${texts.reference}:<\/strong>\r\n          ${item.reference}\r\n        <\/div>\r\n\r\n        <div>\r\n          <strong>${texts.publishedDate}:<\/strong>\r\n          ${item.publishedDate}\r\n        <\/div>\r\n\r\n        <div>\r\n          <strong>${texts.clarificationDeadline}:<\/strong>\r\n          ${item.clarificationDeadline || \"-\"}\r\n        <\/div>\r\n\r\n        <div>\r\n          <strong>${texts.submissionDeadline}:<\/strong>\r\n          ${item.submissionDeadline}\r\n        <\/div>\r\n\r\n        <div>\r\n          <strong>${texts.location}:<\/strong>\r\n          ${item.location}\r\n        <\/div>\r\n\r\n        <div>\r\n          <strong>${texts.status}:<\/strong>\r\n          ${status.label}\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"cp-description\">\r\n        ${content.description}\r\n      <\/div>\r\n\r\n      <div class=\"cp-footer\">\r\n        <div class=\"cp-deadline\">\r\n          ${deadlineText}\r\n        <\/div>\r\n\r\n        <a\r\n          class=\"cp-btn\"\r\n          href=\"${item.link}\"\r\n          target=\"_blank\"\r\n          rel=\"noopener noreferrer\"\r\n        >\r\n          ${texts.documentsButton}\r\n        <\/a>\r\n      <\/div>\r\n    <\/div>\r\n  `;\r\n}\r\n\r\n    function renderPagination(sectionId, totalItems, currentPage) {\r\n      const totalPages = Math.ceil(totalItems \/ itemsPerPage);\r\n\r\n      if (totalPages <= 1) {\r\n        return \"\";\r\n      }\r\n\r\n      let html = `<div class=\"cp-pagination\" data-section=\"${sectionId}\">`;\r\n\r\n      html += `\r\n        <button class=\"cp-page-btn\" data-section=\"${sectionId}\" data-page=\"prev\" ${currentPage === 1 ? \"disabled\" : \"\"}>\r\n          Anterior\r\n        <\/button>\r\n      `;\r\n\r\n      for (let i = 1; i <= totalPages; i++) {\r\n        html += `\r\n          <button class=\"cp-page-btn ${i === currentPage ? \"active\" : \"\"}\" data-section=\"${sectionId}\" data-page=\"${i}\">\r\n            ${i}\r\n          <\/button>\r\n        `;\r\n      }\r\n\r\n      html += `\r\n        <button class=\"cp-page-btn\" data-section=\"${sectionId}\" data-page=\"next\" ${currentPage === totalPages ? \"disabled\" : \"\"}>\r\n          Seguinte\r\n        <\/button>\r\n      `;\r\n\r\n      html += `<\/div>`;\r\n      return html;\r\n    }\r\n\r\n    const pageState = {\r\n      open: 1,\r\n      closed: 1,\r\n      awarded: 1,\r\n      cancelled: 1\r\n    };\r\n\r\n    function renderSection(title, sectionKey, items) {\r\n      const currentPage = pageState[sectionKey] || 1;\r\n      const totalPages = Math.max(1, Math.ceil(items.length \/ itemsPerPage));\r\n      const safePage = currentPage > totalPages ? 1 : currentPage;\r\n      pageState[sectionKey] = safePage;\r\n\r\n      const startIndex = (safePage - 1) * itemsPerPage;\r\n      const paginatedItems = items.slice(startIndex, startIndex + itemsPerPage);\r\n\r\n      return `\r\n        <div class=\"cp-section\">\r\n          <div class=\"cp-section-header\">\r\n            <h3 class=\"cp-section-title\">${title}<\/h3>\r\n            <span class=\"cp-section-count\">${items.length} item(ns)<\/span>\r\n          <\/div>\r\n\r\n          ${\r\n            items.length === 0\r\n              ? `<div class=\"cp-empty-section\">Nenhum concurso nesta categoria.<\/div>`\r\n              : `\r\n                <div class=\"cp-list\">\r\n                  ${paginatedItems.map(renderCard).join(\"\")}\r\n                <\/div>\r\n                ${renderPagination(sectionKey, items.length, safePage)}\r\n              `\r\n          }\r\n        <\/div>\r\n      `;\r\n    }\r\n\r\n    function renderConcursos() {\r\n      const filtered = getFilteredConcursos();\r\n\r\n      if (filtered.length === 0) {\r\n        cpResults.innerHTML = `\r\n          <div class=\"cp-no-results\">\r\n            Nenhum concurso encontrado com os crit\u00e9rios seleccionados.\r\n          <\/div>\r\n        `;\r\n        return;\r\n      }\r\n\r\n      const openItems = filtered.filter(item => getStatus(item).key === \"open\");\r\n      const closedItems = filtered.filter(item => getStatus(item).key === \"closed\");\r\n      const awardedItems = filtered.filter(item => getStatus(item).key === \"awarded\");\r\n      const cancelledItems = filtered.filter(item => getStatus(item).key === \"cancelled\");\r\n\r\n      cpResults.innerHTML = `\r\n        ${renderSection(\"Concursos Abertos\", \"open\", openItems)}\r\n        ${renderSection(\"Concursos Encerrados\", \"closed\", closedItems)}\r\n        ${renderSection(\"Concursos Cancelados\", \"cancelled\", cancelledItems)}\r\n        ${renderSection(\"Concursos Adjudicados\", \"awarded\", awardedItems)}\r\n      `;\r\n\r\n      bindPaginationEvents();\r\nbindLanguageEvents();\r\n    }\r\n    \r\n    function bindLanguageEvents() {\r\n  const languageButtons =\r\n    cpResults.querySelectorAll(\".cp-language-btn\");\r\n\r\n  languageButtons.forEach(button => {\r\n    button.addEventListener(\"click\", function () {\r\n      const itemId = this.getAttribute(\"data-item-id\");\r\n\r\n      const item = concursos.find(concurso => {\r\n        return String(getItemId(concurso)) === String(itemId);\r\n      });\r\n\r\n      if (!item || !item.languages) {\r\n        return;\r\n      }\r\n\r\n      const currentLanguage = getCurrentLanguage(item);\r\n      const availableLanguages = Object.keys(item.languages);\r\n\r\n      const currentIndex =\r\n        availableLanguages.indexOf(currentLanguage);\r\n\r\n      const nextIndex =\r\n        currentIndex >= availableLanguages.length - 1\r\n          ? 0\r\n          : currentIndex + 1;\r\n\r\n      languageState[itemId] =\r\n        availableLanguages[nextIndex];\r\n\r\n      renderConcursos();\r\n    });\r\n  });\r\n}\r\n\r\n    function bindPaginationEvents() {\r\n      const buttons = cpResults.querySelectorAll(\".cp-page-btn\");\r\n\r\n      buttons.forEach(button => {\r\n        button.addEventListener(\"click\", function () {\r\n          const section = this.getAttribute(\"data-section\");\r\n          const page = this.getAttribute(\"data-page\");\r\n\r\n          const items = getFilteredConcursos().filter(item => getStatus(item).key === section);\r\n          const totalPages = Math.max(1, Math.ceil(items.length \/ itemsPerPage));\r\n\r\n          if (page === \"prev\" && pageState[section] > 1) {\r\n            pageState[section]--;\r\n          } else if (page === \"next\" && pageState[section] < totalPages) {\r\n            pageState[section]++;\r\n          } else if (!isNaN(page)) {\r\n            pageState[section] = Number(page);\r\n          }\r\n\r\n          renderConcursos();\r\n        });\r\n      });\r\n    }\r\n\r\n    function resetPaginationAndRender() {\r\n      pageState.open = 1;\r\n      pageState.closed = 1;\r\n      pageState.awarded = 1;\r\n      pageState.cancelled = 1;\r\n      renderConcursos();\r\n    }\r\n\r\n    async function loadConcursos() {\r\n      cpResults.innerHTML = `<div class=\"cp-no-results\">A carregar concursos...<\/div>`;\r\n      try {\r\n        const response = await fetch(CP_API_URL, { method: \"GET\", credentials: \"same-origin\", cache: \"no-store\" });\r\n        if (!response.ok) throw new Error(`HTTP ${response.status}`);\r\n        const payload = await response.json();\r\n        concursos = Array.isArray(payload.items) ? payload.items : [];\r\n        populateCategories();\r\n        renderConcursos();\r\n      } catch (error) {\r\n        console.error(\"Erro ao carregar concursos do OPS:\", error);\r\n        cpResults.innerHTML = `<div class=\"cp-no-results\">N\u00e3o foi poss\u00edvel carregar os concursos neste momento. Tente novamente mais tarde.<\/div>`;\r\n      }\r\n    }\r\n\r\n    cpSearch.addEventListener(\"input\", resetPaginationAndRender);\r\n    cpCategoryFilter.addEventListener(\"change\", resetPaginationAndRender);\r\n    loadConcursos();\r\n  })();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Concursos P\u00fablicos Consulte abaixo os concursos p\u00fablicos e oportunidades de procurement actualmente dispon\u00edveis. Utilize a pesquisa ou filtre por categoria para localizar rapidamente o concurso pretendido. Todas as categorias<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-5136","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Concursos - C-Sa\u00fade<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/csaude.org.mz\/pt\/concursos\/\" \/>\n<meta property=\"og:locale\" content=\"pt_PT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Concursos - C-Sa\u00fade\" \/>\n<meta property=\"og:description\" content=\"Concursos P\u00fablicos Consulte abaixo os concursos p\u00fablicos e oportunidades de procurement actualmente dispon\u00edveis. Utilize a pesquisa ou filtre por categoria para localizar rapidamente o concurso pretendido. Todas as categorias\" \/>\n<meta property=\"og:url\" content=\"https:\/\/csaude.org.mz\/pt\/concursos\/\" \/>\n<meta property=\"og:site_name\" content=\"C-Sa\u00fade\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-09T07:02:58+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tempo estimado de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/csaude.org.mz\/concursos\/\",\"url\":\"https:\/\/csaude.org.mz\/concursos\/\",\"name\":\"Concursos - C-Sa\u00fade\",\"isPartOf\":{\"@id\":\"https:\/\/csaude.org.mz\/#website\"},\"datePublished\":\"2026-02-04T12:54:25+00:00\",\"dateModified\":\"2026-09-09T07:02:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/csaude.org.mz\/concursos\/#breadcrumb\"},\"inLanguage\":\"pt-PT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/csaude.org.mz\/concursos\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/csaude.org.mz\/concursos\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/csaude.org.mz\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Concursos\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/csaude.org.mz\/#website\",\"url\":\"https:\/\/csaude.org.mz\/\",\"name\":\"C-Sa\u00fade\",\"description\":\"Centro pela Sa\u00fade Global\",\"publisher\":{\"@id\":\"https:\/\/csaude.org.mz\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/csaude.org.mz\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-PT\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/csaude.org.mz\/#organization\",\"name\":\"C-Sa\u00fade\",\"url\":\"https:\/\/csaude.org.mz\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-PT\",\"@id\":\"https:\/\/csaude.org.mz\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/csaude.org.mz\/wp-content\/uploads\/2024\/05\/c-saude_final-01.jpg\",\"contentUrl\":\"https:\/\/csaude.org.mz\/wp-content\/uploads\/2024\/05\/c-saude_final-01.jpg\",\"width\":857,\"height\":339,\"caption\":\"C-Sa\u00fade\"},\"image\":{\"@id\":\"https:\/\/csaude.org.mz\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/centro-pela-sade-global-c-sade\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Concursos - C-Sa\u00fade","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/csaude.org.mz\/pt\/concursos\/","og_locale":"pt_PT","og_type":"article","og_title":"Concursos - C-Sa\u00fade","og_description":"Concursos P\u00fablicos Consulte abaixo os concursos p\u00fablicos e oportunidades de procurement actualmente dispon\u00edveis. Utilize a pesquisa ou filtre por categoria para localizar rapidamente o concurso pretendido. Todas as categorias","og_url":"https:\/\/csaude.org.mz\/pt\/concursos\/","og_site_name":"C-Sa\u00fade","article_modified_time":"2026-09-09T07:02:58+00:00","twitter_card":"summary_large_image","twitter_misc":{"Tempo estimado de leitura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/csaude.org.mz\/concursos\/","url":"https:\/\/csaude.org.mz\/concursos\/","name":"Concursos - C-Sa\u00fade","isPartOf":{"@id":"https:\/\/csaude.org.mz\/#website"},"datePublished":"2026-02-04T12:54:25+00:00","dateModified":"2026-09-09T07:02:58+00:00","breadcrumb":{"@id":"https:\/\/csaude.org.mz\/concursos\/#breadcrumb"},"inLanguage":"pt-PT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/csaude.org.mz\/concursos\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/csaude.org.mz\/concursos\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/csaude.org.mz\/"},{"@type":"ListItem","position":2,"name":"Concursos"}]},{"@type":"WebSite","@id":"https:\/\/csaude.org.mz\/#website","url":"https:\/\/csaude.org.mz\/","name":"C-Sa\u00fade","description":"Centro pela Sa\u00fade Global","publisher":{"@id":"https:\/\/csaude.org.mz\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/csaude.org.mz\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-PT"},{"@type":"Organization","@id":"https:\/\/csaude.org.mz\/#organization","name":"C-Sa\u00fade","url":"https:\/\/csaude.org.mz\/","logo":{"@type":"ImageObject","inLanguage":"pt-PT","@id":"https:\/\/csaude.org.mz\/#\/schema\/logo\/image\/","url":"https:\/\/csaude.org.mz\/wp-content\/uploads\/2024\/05\/c-saude_final-01.jpg","contentUrl":"https:\/\/csaude.org.mz\/wp-content\/uploads\/2024\/05\/c-saude_final-01.jpg","width":857,"height":339,"caption":"C-Sa\u00fade"},"image":{"@id":"https:\/\/csaude.org.mz\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/centro-pela-sade-global-c-sade"]}]}},"_links":{"self":[{"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/pages\/5136","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/comments?post=5136"}],"version-history":[{"count":0,"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/pages\/5136\/revisions"}],"wp:attachment":[{"href":"https:\/\/csaude.org.mz\/pt\/wp-json\/wp\/v2\/media?parent=5136"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}