Widok Kalendarza płatności

This commit is contained in:
2026-02-19 01:07:23 +01:00
parent da4d77a808
commit 144aa81358
5 changed files with 593 additions and 28 deletions

View File

@@ -0,0 +1,162 @@
<?php
$enablePrototypeComments = true;
include '../../header-invoice.php';
?>
<link rel="stylesheet" href="../../assets/vendor/libs/fullcalendar/fullcalendar.css" />
<div class="container-fluid flex-grow-1 container-p-y">
<h4 class="py-3 mb-4">
<span class="text-muted fw-light">Faktury i sprzedaż /</span> Kalendarz płatności
</h4>
<div class="card app-calendar-wrapper">
<div class="row g-0">
<!-- Calendar Sidebar -->
<div class="col app-calendar-sidebar" id="app-calendar-sidebar" style="display:none;">
<!-- Hide sidebar/filter for now, we use tabs -->
</div>
<!-- /Calendar Sidebar -->
<!-- Calendar & Tabs -->
<div class="col app-calendar-content">
<div class="card shadow-none border-0">
<div class="card-header border-bottom d-flex justify-content-between align-items-center">
<h5 class="mb-0">Kalendarz płatności</h5>
<ul class="nav nav-pills" role="tablist">
<li class="nav-item">
<button type="button" class="nav-link active" role="tab" data-bs-toggle="tab"
data-filter="all">Wszystkie</button>
</li>
<li class="nav-item">
<button type="button" class="nav-link" role="tab" data-bs-toggle="tab"
data-filter="paid">Zapłacone</button>
</li>
<li class="nav-item">
<button type="button" class="nav-link" role="tab" data-bs-toggle="tab"
data-filter="unpaid">Do zapłaty</button>
</li>
</ul>
</div>
<div class="card-body pb-0">
<div id="calendar"></div>
</div>
</div>
</div>
<!-- /Calendar & Tabs -->
</div>
</div>
</div>
<?php include '../../footer.php'; ?>
<script src="../../assets/vendor/libs/fullcalendar/fullcalendar.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const calendarEl = document.getElementById('calendar');
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth(); // 0-indexed
// Mock Data
// Paid: Green, use payment date
// Unpaid: Red/Orange, use due date
const allEvents = [
// PAID (Past)
{
id: 1,
title: 'FV/2026/01/001 - Comarch',
start: new Date(y, m, 5),
allDay: true,
extendedProps: { status: 'paid', amount: '1230.00 PLN' },
className: 'bg-label-success'
},
{
id: 2,
title: 'FV/2026/01/015 - Google Cloud',
start: new Date(y, m, 10),
allDay: true,
extendedProps: { status: 'paid', amount: '50.00 USD' },
className: 'bg-label-success'
},
// UNPAID (Future / Current)
{
id: 3,
title: 'FV/2026/02/105 - Tauron',
start: new Date(y, m, 24), // Due date
allDay: true,
extendedProps: { status: 'unpaid', amount: '553.50 PLN' },
className: 'bg-label-danger'
},
{
id: 4,
title: 'FV/2026/02/110 - Orange',
start: new Date(y, m, 28), // Due date
allDay: true,
extendedProps: { status: 'unpaid', amount: '120.00 PLN' },
className: 'bg-label-warning'
},
{
id: 5,
title: 'FV/2026/02/115 - Biurorach',
start: new Date(y, m + 1, 5), // Next month
allDay: true,
extendedProps: { status: 'unpaid', amount: '1500.00 PLN' },
className: 'bg-label-warning'
}
];
let calendar = new Calendar(calendarEl, {
plugins: [dayGridPlugin, interactionPlugin, listPlugin, timegridPlugin],
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,listMonth'
},
events: allEvents,
locale: 'pl',
firstDay: 1, // Start week on Monday
eventDidMount: function (info) {
// Add tooltip using Bootstrap
if (info.event.extendedProps.amount) {
new bootstrap.Tooltip(info.el, {
title: info.event.title + ' (' + info.event.extendedProps.amount + ')',
placement: 'top',
trigger: 'hover',
container: 'body'
});
}
}
});
calendar.render();
// Tabs Filtering
const tabBtns = document.querySelectorAll('[data-bs-toggle="tab"]');
tabBtns.forEach(btn => {
btn.addEventListener('shown.bs.tab', function (e) {
const filter = e.target.getAttribute('data-filter');
console.log("Filtering by:", filter);
// Remove all events first
calendar.removeAllEvents();
// Filter and add back
let filteredEvents = [];
if (filter === 'all') {
filteredEvents = allEvents;
} else {
filteredEvents = allEvents.filter(ev => ev.extendedProps.status === filter);
}
filteredEvents.forEach(ev => calendar.addEvent(ev));
});
});
});
</script>