templates/base.html.twig line 1

Open in your IDE?
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="utf-8">
  5.     <title>MyHajs - Budżet domowy</title>
  6.     <meta content="width=device-width, initial-scale=1.0" name="viewport">
  7.     <meta content="" name="keywords">
  8.     <meta content="" name="description">
  9.     <!-- Favicon -->
  10.     <link href="img/favicon.ico" rel="icon">
  11.     <!-- Google Web Fonts -->
  12.     <link rel="preconnect" href="https://fonts.googleapis.com">
  13.     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  14.     <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&family=Roboto:wght@500;700&display=swap" rel="stylesheet">
  15.     <!-- Icon Font Stylesheet -->
  16.     <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.0/css/all.min.css" rel="stylesheet">
  17.     <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css" rel="stylesheet">
  18.     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  19.     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap4.min.css">
  20.     <!-- Libraries Stylesheet -->
  21.     <link href="/darkpan/lib/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet">
  22.     <link href="/darkpan/lib/tempusdominus/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet" />
  23.     <!-- Customized Bootstrap Stylesheet -->
  24.     <link href="/darkpan/css/bootstrap.min.css" rel="stylesheet">
  25.     <!-- Template Stylesheet -->
  26.     <link href="/darkpan/css/style.css" rel="stylesheet">
  27.     {% block stylesheets %}{% endblock %}
  28.     <style>
  29.         #sortTable {
  30.             border-collapse: collapse !important;
  31.             border-color: black !important;
  32.             vertical-align: middle;
  33.         }
  34.         /* Notification Styles */
  35.         .notification {
  36.             position: fixed;
  37.             top: 20px;
  38.             right: 20px;
  39.             padding: 15px 25px;
  40.             color: white;
  41.             border-radius: 4px;
  42.             box-shadow: 0 4px 8px rgba(0,0,0,0.2);
  43.             z-index: 9999;
  44.             opacity: 0;
  45.             transform: translateX(100%);
  46.             transition: all 0.3s ease-in-out;
  47.             max-width: 850px;  /* Maksymalna szerokość */
  48.             width: auto;       /* Szerokość automatyczna, dostosowuje się do zawartości */
  49.             min-width: 250px;  /* Minimalna szerokość */
  50.         }
  51.         .notification.show {
  52.             opacity: 1;
  53.             transform: translateX(0);
  54.         }
  55.         .notification.success {
  56.             background-color: #28a745;
  57.         }
  58.         .notification.info {
  59.             background-color: #17a2b8;
  60.         }
  61.         .notification.warning {
  62.             background-color: #ffc107;
  63.             color: #212529;
  64.         }
  65.         .notification.error {
  66.             background-color: #dc3545;
  67.         }
  68.     </style>
  69.     {% block head %}{% endblock %}
  70. </head>
  71. <body>
  72. <div class="container-fluid position-relative d-flex p-0">
  73.     <!-- Spinner Start -->
  74.     <div id="spinner" class="show bg-dark position-fixed translate-middle w-100 vh-100 top-50 start-50 d-flex align-items-center justify-content-center">
  75.         <div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status">
  76.             <span class="sr-only">Loading...</span>
  77.         </div>
  78.     </div>
  79.     <!-- Spinner End -->
  80.     <!-- Sidebar Start -->
  81.     {% include '_sidebar.html.twig' %}
  82.     <!-- Sidebar End -->
  83.     <!-- Content Start -->
  84.     <div class="content">
  85.         <!-- Navbar Start -->
  86.         {% include '_navbar.html.twig' %}
  87. {#        <div class="container">#}
  88. {#            #}{# Wyświetlanie komunikatów flash #}
  89. {#            <div class="row mt-3">#}
  90. {#                <div class="col-12">#}
  91. {#                    {% for type, messages in app.flashes %}#}
  92. {#                        {% for message in messages %}#}
  93. {#                            <div class="alert alert-{{ type }} alert-dismissible fade show" role="alert">#}
  94. {#                                showNotification('{{ message|e('js') }}', '{{ type }}');#}
  95. {#                            </div>#}
  96. {#                        {% endfor %}#}
  97. {#                    {% endfor %}#}
  98. {#                </div>#}
  99. {#            </div>#}
  100. {#        </div>#}
  101.             {% block body %}{% endblock %}
  102.         <!-- Footer Start -->
  103.         <div class="container-fluid pt-4 px-4">
  104.             <div class="bg-secondary rounded-top p-4">
  105.                 <div class="row">
  106.                     <div class="col-12 col-sm-6 text-center text-sm-start">
  107.                         &copy; <a href="#">MyHajs</a>, All Right Reserved.
  108.                     </div>
  109.                     <div class="col-12 col-sm-6 text-center text-sm-end">
  110.                         <!--/*** This template is free as long as you keep the footer author’s credit link/attribution link/backlink. If you'd like to use the template without the footer author’s credit link/attribution link/backlink, you can purchase the Credit Removal License from "https://htmlcodex.com/credit-removal". Thank you for your support. ***/-->
  111.                         Designed By <a href="#">Mariusz Ludwikowski</a>
  112.                         <br>Distributed By: <a href="#" target="_blank">ludmax.pl</a>
  113.                     </div>
  114.                 </div>
  115.             </div>
  116.         </div>
  117.         <!-- Footer End -->
  118.     </div>
  119.     <!-- Content End -->
  120.     <!-- Back to Top -->
  121.     <a href="#" class="btn btn-lg btn-primary btn-lg-square back-to-top"><i class="bi bi-arrow-up"></i></a>
  122. </div>
  123. {% block javascripts %}
  124.     <!-- Notification Container -->
  125.     <div id="notification-container" class="position-fixed top-0 end-0 p-3" style="z-index: 1100">
  126.         <!-- Notifications will be inserted here -->
  127.     </div>
  128.     
  129.     <script>
  130.         // Notification function
  131.         function showNotification(message, type = 'info', duration = 3000) {
  132.             const container = document.getElementById('notification-container');
  133.             const notification = document.createElement('div');
  134.             notification.className = `notification ${type}`;
  135.             
  136.             // Create close button
  137.             const closeButton = document.createElement('button');
  138.             closeButton.innerHTML = '&times;';
  139.             closeButton.className = 'notification-close';
  140.             closeButton.style.cssText = 'position: absolute; right: 10px; top: 5px; background: none; border: none; color: white; font-size: 20px; cursor: pointer; padding: 0 5px; line-height: 1;';
  141.             
  142.             // Create message container
  143.             const messageContainer = document.createElement('div');
  144.             messageContainer.textContent = message;
  145.             messageContainer.style.paddingRight = '25px';
  146.             
  147.             // Add elements to notification
  148.             notification.appendChild(messageContainer);
  149.             notification.appendChild(closeButton);
  150.             notification.style.position = 'relative';
  151.             
  152.             container.appendChild(notification);
  153.             
  154.             // Trigger reflow to apply initial styles
  155.             notification.offsetHeight;
  156.             
  157.             // Show notification
  158.             notification.classList.add('show');
  159.             
  160.             // Auto remove after duration
  161.             setTimeout(() => {
  162.                 notification.classList.remove('show');
  163.                 setTimeout(() => {
  164.                     container.removeChild(notification);
  165.                 }, 300);
  166.             }, duration);
  167.         }
  168.         
  169.         // Helper functions for different notification types
  170.         function info_noti(message = 'Informacja!', duration = 5000) { // 5 sekundy
  171.             showNotification(message, 'info', duration);
  172.         }
  173.         
  174.         function success_noti(message = 'Sukces!', duration = 5000) { // 5 sekundy
  175.             showNotification(message, 'success', duration);
  176.         }
  177.         
  178.         function warning_noti(message = 'Ostrzeżenie!', duration = 8000) { // 8 sekundy
  179.             showNotification(message, 'warning', duration);
  180.         }
  181.         
  182.         function error_noti(message = 'Wystąpił błąd!', duration = 10000) { // 10 sekundy
  183.             showNotification(message, 'error', duration);
  184.         }
  185.         
  186.         // Flash messages from Symfony
  187.         document.addEventListener('DOMContentLoaded', function() {
  188.             {% for type, messages in app.flashes %}
  189.                 {% for message in messages %}
  190.                     showNotification('{{ message|e('js') }}', '{{ type }}');
  191.                 {% endfor %}
  192.             {% endfor %}
  193.         });
  194.     </script>
  195.     <!-- JavaScript Libraries -->
  196.     <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  197.     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script>
  198.     <script src="/darkpan/lib/chart/chart.min.js"></script>
  199.     <script src="/darkpan/lib/easing/easing.min.js"></script>
  200.     <script src="/darkpan/lib/waypoints/waypoints.min.js"></script>
  201.     <script src="/darkpan/lib/owlcarousel/owl.carousel.min.js"></script>
  202.     <script src="/darkpan/lib/tempusdominus/js/moment.min.js"></script>
  203.     <script src="/darkpan/lib/tempusdominus/js/moment-timezone.min.js"></script>
  204.     <script src="/darkpan/lib/tempusdominus/js/tempusdominus-bootstrap-4.min.js"></script>
  205.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  206.     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  207.     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  208.     <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
  209.     <script src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap4.min.js"></script>
  210.     <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  211.     <script>
  212.         function confirmDelete(url, id) {
  213.             swal({
  214.                 title: "Czy na pewno chcesz skasować?",
  215.                 text: "Tej operacji nie można cofnąć!",
  216.                 icon: "warning",
  217.                 buttons: ["Anuluj", "Usuń"],
  218.                 dangerMode: true,
  219.             })
  220.                 .then((willDelete) => {
  221.                     if (willDelete) {
  222.                         document.getElementById('delete-form'+id).submit();
  223.                     }
  224.                 });
  225.         }
  226.         // Znajdź indeksy kolumn bez klasy 'sort'
  227.         var nonSortableColumns = [];
  228.         $('#sortTable thead th').each(function(index) {
  229.             if (!$(this).hasClass('sort')) {
  230.                 nonSortableColumns.push(index);
  231.             }
  232.         });
  233.         // Przygotuj columnDefs
  234.         var columnDefs = nonSortableColumns.map(function(columnIndex) {
  235.             return {
  236.                 "targets": columnIndex,
  237.                 "orderable": false
  238.             };
  239.         });
  240.         // Sprawdź czy tabela ma klasę 'search'
  241.         var hasSearch = $('#sortTable').hasClass('search');
  242.         $('#sortTable').DataTable({
  243.             "pageLength": 10, // Ustawia długość strony na 10
  244.             "lengthChange": false, // Ukrywa opcję zmiany długości strony
  245.             "language": {
  246.                 "paginate": {
  247.                     "first": "Pierwsza",
  248.                     "last": "Ostatnia",
  249.                     "next": "Następna",
  250.                     "previous": "Poprzednia"
  251.                 },
  252.                 "search": hasSearch ? "Szukaj:" : "",
  253.                 "zeroRecords": "Nie znaleziono pasujących rekordów",
  254.                 "info": "Strona _PAGE_ z _PAGES_",
  255.                 "infoEmpty": "Brak rekordów",
  256.                 "infoFiltered": "(przeszukano _MAX_ rekordów)"
  257.             },
  258.             "dom": hasSearch ? 'lfrtip' : 'lrtip',
  259.             "order": [],
  260.             "columnDefs": columnDefs,
  261.             // "columnDefs": [
  262.             //     { "orderable": false, "targets": [0, 1, 2, 3, 4] }
  263.             // ],
  264.             initComplete: function() {
  265.                 // Inicjalizacja columnDefs
  266.                 var columnDefs = [];
  267.                 // Dodanie pól wyszukiwania dla każdej kolumny
  268.                 this.api().columns().every(function() {
  269.                     var column = this;
  270.                     var header = $(column.header());
  271.                     // ustawia filtry dla kolumn z class='sort'
  272.                     if (header.hasClass('filtr')) {
  273.                         var input = $('<input type="text" class="form-control form-control-sm" placeholder="Filtruj...">')
  274.                             .appendTo($(column.footer()).empty())
  275.                             .on('keyup change', function() {
  276.                                 if (column.search() !== this.value) {
  277.                                     column.search(this.value).draw();
  278.                                 }
  279.                             });
  280.                     }
  281.                 });
  282.             }
  283.         });
  284.     </script>
  285.     <!-- Template Javascript -->
  286.     <script src="/darkpan/js/main.js"></script>
  287.     <script>
  288.         // Close button functionality
  289.         document.addEventListener('click', function(e) {
  290.             if (e.target.matches('.notification-close') || e.target.closest('.notification-close')) {
  291.                 const notification = e.target.closest('.notification');
  292.                 if (notification) {
  293.                     notification.classList.remove('show');
  294.                     setTimeout(() => {
  295.                         notification.remove();
  296.                     }, 300);
  297.                 }
  298.             }
  299.         });
  300.     </script>
  301. {% endblock %}
  302. </body>
  303. </html>