templates/includes/blocks/jobs.html.twig line 1

  1. {% set propertyName = propertyName|default('blocks') %}
  2. <style>
  3.     .custom-job-listing {
  4.         position: relative;
  5.         width: 100%;
  6.         padding-bottom: 1rem;
  7.     }
  8.     .job-list.job-list {
  9.         list-style-type: none;
  10.         padding: 0;
  11.         margin-left: 0;
  12.     }
  13.     .job-list__item {
  14.         margin-bottom: 5px;
  15.         border-bottom: 1px solid #ddd;
  16.         padding-bottom: 2px;
  17.         font-size: 0.9em;
  18.         display: flex;
  19.         & h5, h6 {
  20.             color: var(--color-primary);
  21.             text-decoration: none;
  22.             font-weight: 700;
  23.             font-family: Roboto, sans-serif;
  24.             font-style: normal;
  25.         }
  26.         & h5 {
  27.             font-size: 29px;
  28.         }
  29.         & h6 {
  30.             font-size: 18px;
  31.         }
  32.     }
  33.     @media (max-width: 640px) {
  34.         .job-list__item {
  35.             flex-direction: column;
  36.         }
  37.     }
  38.     .job-list__item__left {
  39.         display: flex;
  40.         flex-direction: column;
  41.         flex-grow: 1;
  42.     }
  43.     .job-list__item__right {
  44.         display: flex;
  45.         flex-direction: column;
  46.     }
  47.     .job-list__link {
  48.     }
  49.     .job-list__link:hover {
  50.     }
  51.     .job-list__title {
  52.         font-size: 1.1em;
  53.     }
  54.     .pagination {
  55.         display: flex;
  56.         justify-content: center;
  57.         margin-top: 20px;
  58.     }
  59.     .pagination__button {
  60.         padding: 5px 10px;
  61.         margin: 0 5px;
  62.         background-color: #007bff;
  63.         color: white;
  64.         border: none;
  65.         border-radius: 4px;
  66.         cursor: pointer;
  67.     }
  68.     .pagination__button:disabled {
  69.         background-color: #ccc;
  70.         cursor: default;
  71.     }
  72.     .pagination__page-number {
  73.         font-size: larger;
  74.     }
  75.     .loading-overlay {
  76.         display: none; /* Standardmäßig versteckt */
  77.         position: absolute; /* Positionierung über dem gesamten Inhalt */
  78.         top: 0;
  79.         left: 0;
  80.         width: 100%;
  81.         height: 100%;
  82.         background: rgba(255, 255, 255, 0.5); /* Leicht transparenter Hintergrund */
  83.         backdrop-filter: blur(5px); /* Unscharfer Hintergrund-Effekt */
  84.         justify-content: center;
  85.         align-items: center;
  86.         z-index: 1000; /* Stellt sicher, dass es über anderen Elementen liegt */
  87.     }
  88.     .loading-indicator {
  89.         font-size: 1.5em;
  90.     }
  91.     .job-counter{
  92.         font-size: small;
  93.     }
  94. </style>
  95. <div class="grid-container">
  96.     <div class="grid-x grid-margin-x">
  97.         <div class="custom-job-listing">
  98.             <div class="loading-overlay">
  99.                 <div class="loading-indicator">Jobs werden geladen...</div>
  100.             </div>
  101.             <ul class="job-list">
  102.             </ul>
  103.             <div class="job-counter"></div>
  104.             <div class="error-message" style="display: none"></div>
  105.             <div class="pagination">
  106.                 <button class="pagination__button pagination__button--prev">Zurück</button>
  107.                 <span class="pagination__page-number">1</span>
  108.                 <button class="pagination__button pagination__button--next">Weiter</button>
  109.             </div>
  110.         </div>
  111.     </div>
  112. </div>
  113. <script>
  114.     document.addEventListener("DOMContentLoaded", function () {
  115.         const jobManager = new JobManager();
  116.         jobManager.init();
  117.     });
  118.     class JobManager {
  119.         constructor() {
  120.             this.currentPage = 1;
  121.             this.pageSize = 10;
  122.             this.searchText = "";
  123.             this.searchZipCode = "";
  124.             this.searchZipCodeRadius = 50;
  125.             this.totalPages = 0;
  126.             this.artemisUrl = "https://ndh.artemis.aveo-solutions.net/GetAktuelleStellenanzeigen";
  127.         }
  128.         init() {
  129.             this.fetchJobs();
  130.             this.setupEventListeners();
  131.         }
  132.         fetchJobs() {
  133.             this.showLoadingIndicator(true);
  134.             const url = `${this.artemisUrl}?perPage=${this.pageSize}&page=${this.currentPage}&suchText=${this.searchText}&suchOrt=${this.searchZipCode}&radius=${this.searchZipCodeRadius}`;
  135.             fetch(url)
  136.                 .then((response) => this.handleResponse(response))
  137.                 .then((data) => this.processJobData(data))
  138.                 .catch((error) => this.handleError(error))
  139.                 .finally(() => this.showLoadingIndicator(false));
  140.         }
  141.         handleResponse(response) {
  142.             if (!response.ok) {
  143.                 throw new Error(`HTTP error! status: ${response.status}`);
  144.             }
  145.             return response.json();
  146.         }
  147.         processJobData(data) {
  148.             this.updateJobCount(data.totalResults);
  149.             this.displayJobs(data.results);
  150.             this.updatePagination(data.totalResults);
  151.         }
  152.         updateJobCount(totalJobs) {
  153.             this.totalJobs = totalJobs;
  154.             this.updateJobRangeDisplay();
  155.         }
  156.         displayJobs(jobs) {
  157.             const jobsList = document.querySelector(".job-list");
  158.             jobsList.innerHTML = jobs.map((job) => this.jobTemplate(job)).join("");
  159.         }
  160.         jobTemplate(job) {
  161.             console.log(job);
  162.             return `
  163.             <li class="job-list__item">
  164.                 <div class="job-list__item__left">
  165.                     <h6>${job.arbeitsort}</h6>
  166.                     <a class="job-list__link" href="${job.bewerbenUrl}" target="_blank">
  167.                         <h5>${job.name}</h5>
  168.                     </a>
  169.                 </div>
  170.                 <div class="job-list__item__right">
  171.                     <a class="button-wrapper pt-0" href="${job.bewerbenUrl}" target="_blank" rel="external">
  172.                         <span class="btn btn-primary">
  173.                             Details
  174.                         </span>
  175.                     </a>
  176.                 </div>
  177.             </li>
  178.           `;
  179.         }
  180.         updatePagination(totalJobs) {
  181.             this.totalPages = Math.ceil(totalJobs / this.pageSize);
  182.             this.updatePaginationControls();
  183.         }
  184.         setupEventListeners() {
  185.             document
  186.                 .querySelector(".pagination__button--prev")
  187.                 .addEventListener("click", () => this.changePage(-1));
  188.             document
  189.                 .querySelector(".pagination__button--next")
  190.                 .addEventListener("click", () => this.changePage(1));
  191.         }
  192.         changePage(delta) {
  193.             const newPage = this.currentPage + delta;
  194.             if (newPage > 0 && newPage <= this.totalPages) {
  195.                 this.currentPage = newPage;
  196.                 this.fetchJobs();
  197.                 this.updatePaginationDisplay();
  198.                 this.updateJobRangeDisplay();
  199.             }
  200.         }
  201.         updatePaginationDisplay() {
  202.             document.querySelector(".pagination__page-number").textContent =
  203.                 this.currentPage;
  204.             this.updatePaginationControls();
  205.         }
  206.         updatePaginationControls() {
  207.             document.querySelector(".pagination__button--prev").disabled =
  208.                 this.currentPage <= 1;
  209.             document.querySelector(".pagination__button--next").disabled =
  210.                 this.currentPage >= this.totalPages;
  211.             document.querySelector(".pagination").style.display =
  212.                 this.totalPages <= 1 ? "none" : "";
  213.         }
  214.         updateJobRangeDisplay() {
  215.             const startJobNumber = (this.currentPage - 1) * this.pageSize + 1;
  216.             const endJobNumber = Math.min(
  217.                 this.currentPage * this.pageSize,
  218.                 this.totalJobs
  219.             );
  220.             const jobCountElement = document.querySelector(".job-counter");
  221.             jobCountElement.textContent = `Jobs ${startJobNumber} bis ${endJobNumber} von ${this.totalJobs}`;
  222.         }
  223.         showLoadingIndicator(show) {
  224.             const overlay = document.querySelector(".loading-overlay");
  225.             overlay.style.display = show ? "flex" : "none";
  226.         }
  227.         handleError(error) {
  228.             const errorContainer = document.querySelector(".error-message");
  229.             errorContainer.textContent = `Error: ${error.message}`;
  230.             errorContainer.style.display = "block";
  231.         }
  232.     }
  233. </script>