<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyHajs - Budżet domowy</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="" name="keywords">
<meta content="" name="description">
<!-- Favicon -->
<link href="img/favicon.ico" rel="icon">
<!-- Google Web Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&family=Roboto:wght@500;700&display=swap" rel="stylesheet">
<!-- Icon Font Stylesheet -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.0/css/all.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap4.min.css">
<!-- Libraries Stylesheet -->
<link href="/darkpan/lib/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet">
<link href="/darkpan/lib/tempusdominus/css/tempusdominus-bootstrap-4.min.css" rel="stylesheet" />
<!-- Customized Bootstrap Stylesheet -->
<link href="/darkpan/css/bootstrap.min.css" rel="stylesheet">
<!-- Template Stylesheet -->
<link href="/darkpan/css/style.css" rel="stylesheet">
{% block stylesheets %}{% endblock %}
<style>
#sortTable {
border-collapse: collapse !important;
border-color: black !important;
vertical-align: middle;
}
/* Notification Styles */
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
color: white;
border-radius: 4px;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
z-index: 9999;
opacity: 0;
transform: translateX(100%);
transition: all 0.3s ease-in-out;
max-width: 850px; /* Maksymalna szerokość */
width: auto; /* Szerokość automatyczna, dostosowuje się do zawartości */
min-width: 250px; /* Minimalna szerokość */
}
.notification.show {
opacity: 1;
transform: translateX(0);
}
.notification.success {
background-color: #28a745;
}
.notification.info {
background-color: #17a2b8;
}
.notification.warning {
background-color: #ffc107;
color: #212529;
}
.notification.error {
background-color: #dc3545;
}
</style>
{% block head %}{% endblock %}
</head>
<body>
<div class="container-fluid position-relative d-flex p-0">
<!-- Spinner Start -->
<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">
<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<!-- Spinner End -->
<!-- Sidebar Start -->
{% include '_sidebar.html.twig' %}
<!-- Sidebar End -->
<!-- Content Start -->
<div class="content">
<!-- Navbar Start -->
{% include '_navbar.html.twig' %}
{# <div class="container">#}
{# #}{# Wyświetlanie komunikatów flash #}
{# <div class="row mt-3">#}
{# <div class="col-12">#}
{# {% for type, messages in app.flashes %}#}
{# {% for message in messages %}#}
{# <div class="alert alert-{{ type }} alert-dismissible fade show" role="alert">#}
{# showNotification('{{ message|e('js') }}', '{{ type }}');#}
{# </div>#}
{# {% endfor %}#}
{# {% endfor %}#}
{# </div>#}
{# </div>#}
{# </div>#}
{% block body %}{% endblock %}
<!-- Footer Start -->
<div class="container-fluid pt-4 px-4">
<div class="bg-secondary rounded-top p-4">
<div class="row">
<div class="col-12 col-sm-6 text-center text-sm-start">
© <a href="#">MyHajs</a>, All Right Reserved.
</div>
<div class="col-12 col-sm-6 text-center text-sm-end">
<!--/*** 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. ***/-->
Designed By <a href="#">Mariusz Ludwikowski</a>
<br>Distributed By: <a href="#" target="_blank">ludmax.pl</a>
</div>
</div>
</div>
</div>
<!-- Footer End -->
</div>
<!-- Content End -->
<!-- Back to Top -->
<a href="#" class="btn btn-lg btn-primary btn-lg-square back-to-top"><i class="bi bi-arrow-up"></i></a>
</div>
{% block javascripts %}
<!-- Notification Container -->
<div id="notification-container" class="position-fixed top-0 end-0 p-3" style="z-index: 1100">
<!-- Notifications will be inserted here -->
</div>
<script>
// Notification function
function showNotification(message, type = 'info', duration = 3000) {
const container = document.getElementById('notification-container');
const notification = document.createElement('div');
notification.className = `notification ${type}`;
// Create close button
const closeButton = document.createElement('button');
closeButton.innerHTML = '×';
closeButton.className = 'notification-close';
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;';
// Create message container
const messageContainer = document.createElement('div');
messageContainer.textContent = message;
messageContainer.style.paddingRight = '25px';
// Add elements to notification
notification.appendChild(messageContainer);
notification.appendChild(closeButton);
notification.style.position = 'relative';
container.appendChild(notification);
// Trigger reflow to apply initial styles
notification.offsetHeight;
// Show notification
notification.classList.add('show');
// Auto remove after duration
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => {
container.removeChild(notification);
}, 300);
}, duration);
}
// Helper functions for different notification types
function info_noti(message = 'Informacja!', duration = 5000) { // 5 sekundy
showNotification(message, 'info', duration);
}
function success_noti(message = 'Sukces!', duration = 5000) { // 5 sekundy
showNotification(message, 'success', duration);
}
function warning_noti(message = 'Ostrzeżenie!', duration = 8000) { // 8 sekundy
showNotification(message, 'warning', duration);
}
function error_noti(message = 'Wystąpił błąd!', duration = 10000) { // 10 sekundy
showNotification(message, 'error', duration);
}
// Flash messages from Symfony
document.addEventListener('DOMContentLoaded', function() {
{% for type, messages in app.flashes %}
{% for message in messages %}
showNotification('{{ message|e('js') }}', '{{ type }}');
{% endfor %}
{% endfor %}
});
</script>
<!-- JavaScript Libraries -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="/darkpan/lib/chart/chart.min.js"></script>
<script src="/darkpan/lib/easing/easing.min.js"></script>
<script src="/darkpan/lib/waypoints/waypoints.min.js"></script>
<script src="/darkpan/lib/owlcarousel/owl.carousel.min.js"></script>
<script src="/darkpan/lib/tempusdominus/js/moment.min.js"></script>
<script src="/darkpan/lib/tempusdominus/js/moment-timezone.min.js"></script>
<script src="/darkpan/lib/tempusdominus/js/tempusdominus-bootstrap-4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap4.min.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script>
function confirmDelete(url, id) {
swal({
title: "Czy na pewno chcesz skasować?",
text: "Tej operacji nie można cofnąć!",
icon: "warning",
buttons: ["Anuluj", "Usuń"],
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
document.getElementById('delete-form'+id).submit();
}
});
}
// Znajdź indeksy kolumn bez klasy 'sort'
var nonSortableColumns = [];
$('#sortTable thead th').each(function(index) {
if (!$(this).hasClass('sort')) {
nonSortableColumns.push(index);
}
});
// Przygotuj columnDefs
var columnDefs = nonSortableColumns.map(function(columnIndex) {
return {
"targets": columnIndex,
"orderable": false
};
});
// Sprawdź czy tabela ma klasę 'search'
var hasSearch = $('#sortTable').hasClass('search');
$('#sortTable').DataTable({
"pageLength": 10, // Ustawia długość strony na 10
"lengthChange": false, // Ukrywa opcję zmiany długości strony
"language": {
"paginate": {
"first": "Pierwsza",
"last": "Ostatnia",
"next": "Następna",
"previous": "Poprzednia"
},
"search": hasSearch ? "Szukaj:" : "",
"zeroRecords": "Nie znaleziono pasujących rekordów",
"info": "Strona _PAGE_ z _PAGES_",
"infoEmpty": "Brak rekordów",
"infoFiltered": "(przeszukano _MAX_ rekordów)"
},
"dom": hasSearch ? 'lfrtip' : 'lrtip',
"order": [],
"columnDefs": columnDefs,
// "columnDefs": [
// { "orderable": false, "targets": [0, 1, 2, 3, 4] }
// ],
initComplete: function() {
// Inicjalizacja columnDefs
var columnDefs = [];
// Dodanie pól wyszukiwania dla każdej kolumny
this.api().columns().every(function() {
var column = this;
var header = $(column.header());
// ustawia filtry dla kolumn z class='sort'
if (header.hasClass('filtr')) {
var input = $('<input type="text" class="form-control form-control-sm" placeholder="Filtruj...">')
.appendTo($(column.footer()).empty())
.on('keyup change', function() {
if (column.search() !== this.value) {
column.search(this.value).draw();
}
});
}
});
}
});
</script>
<!-- Template Javascript -->
<script src="/darkpan/js/main.js"></script>
<script>
// Close button functionality
document.addEventListener('click', function(e) {
if (e.target.matches('.notification-close') || e.target.closest('.notification-close')) {
const notification = e.target.closest('.notification');
if (notification) {
notification.classList.remove('show');
setTimeout(() => {
notification.remove();
}, 300);
}
}
});
</script>
{% endblock %}
</body>
</html>