Widok Kalendarza płatności
This commit is contained in:
162
prototype/invoice/app-purchase-calendar.php
Normal file
162
prototype/invoice/app-purchase-calendar.php
Normal 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>
|
||||
Reference in New Issue
Block a user