Files
2026-09-16 23:20:08 +07:00

264 lines
10 KiB
PHP

<?php require_once 'includes/header.php'; ?>
<!-- FullCalendar Library -->
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/locales/th.js'></script>
<div class="page-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h4 class="fw-bold mb-1">ปฏิทินการขอใช้ห้องประชุม</h4>
<p class="text-muted mb-0">แสดงข้อมูลการจองทั้งหมด</p>
</div>
<div class="d-flex align-items-center gap-3 bg-white px-3 py-2 rounded-pill shadow-sm flex-wrap">
<span class="fs-6 fw-bold me-2">สัญลักษณ์:</span>
<div class="d-flex align-items-center gap-1">
<span style="display:inline-block; width:12px; height:12px; background-color:#0d6efd; border-radius:50%;"></span>
<span class="small text-muted">จองผ่านระบบนี้</span>
</div>
<div class="d-flex align-items-center gap-1">
<span style="display:inline-block; width:12px; height:12px; background-color:#fd7e14; border-radius:50%;"></span>
<span class="small text-muted">จองผ่านช่องทางอื่น</span>
</div>
<div class="d-flex align-items-center gap-1">
<span style="display:inline-block; width:12px; height:12px; background-color:#dc3545; border-radius:50%;"></span>
<span class="small text-muted">วันหยุดราชการ</span>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card border-0 shadow-sm" style="border-radius: 16px;">
<div class="card-body p-4">
<div id="calendar"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal Event Detail -->
<div class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content" style="border-radius: 16px; border: none; box-shadow: var(--shadow-lg);">
<div class="modal-header border-0 pb-0 pt-4 px-4">
<h5 class="modal-title fw-bold" id="eventModalLabel">รายละเอียดการประชุม</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<p><strong>หัวข้อ:</strong> <span id="eventTopic"></span></p>
<p><strong>ผู้สร้าง:</strong> <span id="eventCreator"></span></p>
<p><strong>ที่มา:</strong> <span id="eventSource"></span></p>
<p><strong>วันและเวลา:</strong> <span id="eventTime"></span></p>
<p id="eventDetailsContainer" style="display:none;"><strong>รายละเอียด:</strong> <span id="eventDetails" class="text-muted"></span></p>
<div id="eventLinkContainer" class="mt-3">
<a href="#" id="eventMeetLink" target="_blank" class="btn btn-primary w-100 rounded-pill"><i class="bi bi-camera-video"></i> เข้าร่วมประชุม</a>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
firstDay: 0,
contentHeight: 'auto',
locale: 'th',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
buttonText: {
today: 'วันนี้',
month: 'เดือน',
week: 'สัปดาห์',
day: 'วัน',
list: 'รายการ'
},
themeSystem: 'bootstrap5',
events: 'api/get_events.php',
eventDisplay: 'block',
eventClick: function(info) {
info.jsEvent.preventDefault(); // don't let the browser navigate
var eventObj = info.event;
var props = eventObj.extendedProps;
document.getElementById('eventTopic').innerText = eventObj.title;
document.getElementById('eventCreator').innerText = props.creator || '-';
let sourceText = '';
if (props.source === 'internal') {
sourceText = '<span class="badge bg-primary">จองผ่านระบบนี้</span>';
} else if (props.source === 'holiday') {
sourceText = '<span class="badge bg-danger">วันหยุดราชการ</span>';
} else {
sourceText = '<span class="badge bg-warning text-dark">จองผ่านช่องทางอื่น</span>';
}
document.getElementById('eventSource').innerHTML = sourceText;
// Format time manually
let start = eventObj.start;
let end = eventObj.end;
let timeStr = "";
if (start) {
let sD = start.toLocaleDateString('th-TH');
let sT = start.toLocaleTimeString('th-TH', {hour: '2-digit', minute:'2-digit'});
timeStr += sD + " " + sT;
}
if (end) {
let eD = end.toLocaleDateString('th-TH');
let eT = end.toLocaleTimeString('th-TH', {hour: '2-digit', minute:'2-digit'});
if (start && start.toLocaleDateString('th-TH') === eD) {
timeStr += " - " + eT;
} else {
timeStr += " ถึง " + eD + " " + eT;
}
}
document.getElementById('eventTime').innerText = timeStr;
// Display Details if available
var detailsContainer = document.getElementById('eventDetailsContainer');
if (props.details) {
document.getElementById('eventDetails').innerText = props.details;
detailsContainer.style.display = 'block';
} else {
detailsContainer.style.display = 'none';
}
var linkContainer = document.getElementById('eventLinkContainer');
if (props.meet_link) {
document.getElementById('eventMeetLink').href = props.meet_link;
linkContainer.style.display = 'block';
} else {
linkContainer.style.display = 'none';
}
var eventModal = new bootstrap.Modal(document.getElementById('eventModal'));
eventModal.show();
}
});
calendar.render();
});
</script>
<style>
/* FullCalendar Premium Customizations */
.fc {
font-family: 'Inter', 'Prompt', sans-serif;
}
.fc .fc-toolbar-title {
font-size: 1.4rem;
font-weight: 800;
color: var(--text-main);
letter-spacing: -0.5px;
}
.fc .fc-button-group > .fc-button {
margin-right: 2px;
}
.fc .fc-button-primary {
background-color: var(--bg-surface) !important;
border: 1px solid var(--border-color) !important;
color: var(--text-main) !important;
box-shadow: var(--shadow-sm);
border-radius: 8px !important;
text-transform: capitalize;
font-weight: 500;
transition: all 0.2s ease;
padding: 0.4rem 1rem;
}
.fc .fc-button-primary:hover {
background-color: var(--bg-body) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
}
.fc .fc-button-primary:not(:disabled):active,
.fc .fc-button-primary:not(:disabled).fc-button-active {
background-color: var(--primary-light) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
box-shadow: none !important;
}
.fc .fc-button-primary:focus {
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25) !important;
}
.fc-theme-bootstrap5 .fc-scrollgrid {
border-color: var(--border-color);
border-radius: 12px;
overflow: hidden;
}
.fc-theme-bootstrap5 .fc-scrollgrid td, .fc-theme-bootstrap5 .fc-scrollgrid th {
border-color: var(--border-color);
}
.fc .fc-col-header-cell {
background-color: #f8fafc;
padding: 12px 0;
border-bottom: 2px solid var(--border-color);
}
.fc .fc-col-header-cell-cushion {
color: #64748b;
font-weight: 600;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.5px;
text-decoration: none;
}
.fc .fc-daygrid-day-number {
color: var(--text-main);
font-weight: 600;
padding: 8px;
text-decoration: none;
}
.fc .fc-day-today {
background-color: rgba(13, 110, 253, 0.04) !important;
}
.fc .fc-day-today .fc-daygrid-day-number {
background-color: var(--primary);
color: white;
border-radius: 50%;
width: 28px;
height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
margin: 4px;
padding: 0;
box-shadow: 0 2px 4px rgba(13, 110, 253, 0.3);
}
.fc .fc-day-sat, .fc .fc-day-sun {
background-color: #f8f9fa; /* Light gray for weekends to stand out slightly */
}
.fc-event {
cursor: pointer;
border: none !important;
padding: 4px 8px;
border-radius: 6px;
font-size: 0.75rem;
font-weight: 500;
margin: 2px 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.fc-event:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
opacity: 0.95;
}
.fc-daygrid-event-dot {
display: none;
}
.fc-daygrid-block-event .fc-event-time,
.fc-daygrid-block-event .fc-event-title {
font-weight: 500;
}
</style>
<?php require_once 'includes/footer.php'; ?>