Files
magico.prototype/prototype/invoice/app-purchase-calendar.php

191 lines
6.5 KiB
PHP

<?php
$enablePrototypeComments = true;
include '../../header-invoice.php';
?>
<link rel="stylesheet" href="../../assets/vendor/libs/fullcalendar/fullcalendar.css" />
<style>
/* Custom darker event colors for white text contrast */
.fc-event-dark-success {
background-color: #1b5e20 !important;
border-color: #1b5e20 !important;
color: #ffffff !important;
}
.fc-event-dark-danger {
background-color: #b71c1c !important;
border-color: #b71c1c !important;
color: #ffffff !important;
}
.fc-event-dark-warning {
background-color: #e65100 !important;
border-color: #e65100 !important;
color: #ffffff !important;
}
</style>
<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="d-flex mb-3 gap-2 align-items-center flex-nowrap overflow-auto pb-2">
<button type="button" class="btn btn-label-primary text-nowrap tab-filter-btn" data-filter="all">
Wszystkie
</button>
<button type="button" class="btn btn-label-secondary text-nowrap tab-filter-btn" data-filter="paid">
Zapłacone
</button>
<button type="button" class="btn btn-label-secondary text-nowrap tab-filter-btn" data-filter="unpaid">
Do zapłaty
</button>
</div>
<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-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: 'fc-event-dark-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: 'fc-event-dark-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: 'fc-event-dark-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: 'fc-event-dark-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: 'fc-event-dark-warning'
}
];
let calendar = new Calendar(calendarEl, {
plugins: [dayGridPlugin, interactionPlugin, listPlugin, timegridPlugin],
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,listMonth'
},
buttonText: {
today: 'Dzisiaj',
month: 'Miesiąc',
week: 'Tydzień',
day: 'Dzień',
list: 'Lista'
},
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('.tab-filter-btn');
tabBtns.forEach(btn => {
btn.addEventListener('click', function (e) {
// Remove active class from all
tabBtns.forEach(b => {
b.classList.remove('btn-label-primary');
b.classList.add('btn-label-secondary');
});
// Add active class to clicked
this.classList.remove('btn-label-secondary');
this.classList.add('btn-label-primary');
const filter = this.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>