Updated page layout for fullscreen
This commit is contained in:
@@ -4,7 +4,9 @@
|
|||||||
* static/css/attendance_fullscreen.css
|
* static/css/attendance_fullscreen.css
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Fullscreen Toggle Button */
|
/* ===========================
|
||||||
|
FULLSCREEN TOGGLE BUTTON
|
||||||
|
=========================== */
|
||||||
.fullscreen-toggle-btn {
|
.fullscreen-toggle-btn {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
@@ -35,21 +37,29 @@
|
|||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fullscreen Mode Styles */
|
/* ===========================
|
||||||
|
FULLSCREEN MODE BASE
|
||||||
|
=========================== */
|
||||||
.fullscreen-mode {
|
.fullscreen-mode {
|
||||||
position: fixed;
|
position: fixed !important;
|
||||||
top: 0;
|
top: 0 !important;
|
||||||
left: 0;
|
left: 0 !important;
|
||||||
width: 100vw;
|
width: 100vw !important;
|
||||||
height: 100vh;
|
height: 100vh !important;
|
||||||
background: #f8fafc;
|
max-width: 100vw !important;
|
||||||
z-index: 9998;
|
margin: 0 !important;
|
||||||
overflow: auto;
|
background: #f8fafc !important;
|
||||||
padding: 20px;
|
z-index: 9998 !important;
|
||||||
box-sizing: border-box;
|
overflow: auto !important;
|
||||||
|
padding: 20px !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide sidebar and other UI elements in fullscreen */
|
/* ===========================
|
||||||
|
HIDE UI ELEMENTS IN FULLSCREEN
|
||||||
|
=========================== */
|
||||||
|
|
||||||
|
/* Hide sidebar and overlays */
|
||||||
.fullscreen-mode ~ #sidebar,
|
.fullscreen-mode ~ #sidebar,
|
||||||
.fullscreen-mode ~ .sidebar-overlay,
|
.fullscreen-mode ~ .sidebar-overlay,
|
||||||
body.fullscreen-active #sidebar,
|
body.fullscreen-active #sidebar,
|
||||||
@@ -57,237 +67,533 @@ body.fullscreen-active .sidebar-overlay {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust main wrapper in fullscreen */
|
/* Adjust main wrapper */
|
||||||
body.fullscreen-active .main-wrapper {
|
body.fullscreen-active .main-wrapper {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compact header in fullscreen mode */
|
/* Hide header completely */
|
||||||
.fullscreen-mode .attendance-header {
|
.fullscreen-mode .attendance-header,
|
||||||
padding: 1rem 1.5rem;
|
.fullscreen-mode > .attendance-header {
|
||||||
margin-bottom: 1rem;
|
display: none !important;
|
||||||
background: white;
|
visibility: hidden !important;
|
||||||
border-radius: 8px;
|
height: 0 !important;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
overflow: hidden !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .attendance-header h1 {
|
/* Hide ALL stats sections with various possible class names */
|
||||||
font-size: 1.5rem;
|
.fullscreen-mode .stats-section,
|
||||||
margin-bottom: 0.25rem;
|
.fullscreen-mode > .stats-section,
|
||||||
|
.fullscreen-mode .stats-overview,
|
||||||
|
.fullscreen-mode > .stats-overview,
|
||||||
|
.fullscreen-mode .statistics-section,
|
||||||
|
.fullscreen-mode > .statistics-section,
|
||||||
|
.fullscreen-mode [class*="stat"][class*="section"],
|
||||||
|
.fullscreen-mode div[class*="stat-"] {
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden !important;
|
||||||
|
height: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .attendance-header p {
|
/* Exception: Keep stat cards inside table section visible */
|
||||||
font-size: 0.875rem;
|
.fullscreen-mode .attendance-table-section .stat-card,
|
||||||
margin: 0;
|
.fullscreen-mode .table-section .stat-card {
|
||||||
|
display: flex !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compact stats in fullscreen */
|
/* ===========================
|
||||||
.fullscreen-mode .stats-section {
|
COMPACT FILTERS IN FULLSCREEN
|
||||||
margin-bottom: 1rem;
|
=========================== */
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stat-card {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stat-icon {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stat-content h3 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stat-content p {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stat-trend {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compact filters in fullscreen */
|
|
||||||
.fullscreen-mode .filters-section {
|
.fullscreen-mode .filters-section {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .filters-card {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filters-header {
|
.fullscreen-mode .filters-header {
|
||||||
padding: 1rem 1.5rem;
|
padding: 0.75rem 1.5rem !important;
|
||||||
|
background: #f8fafc !important;
|
||||||
|
border-bottom: 1px solid #e2e8f0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filters-header h3 {
|
.fullscreen-mode .filters-header h3 {
|
||||||
font-size: 1.125rem;
|
font-size: 1rem !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
margin: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filters-form {
|
.fullscreen-mode .filters-form {
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-row {
|
.fullscreen-mode .filter-row {
|
||||||
gap: 0.75rem;
|
display: grid !important;
|
||||||
|
grid-template-columns: repeat(5, 1fr) !important;
|
||||||
|
gap: 0.75rem !important;
|
||||||
|
align-items: end !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .filter-group {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
gap: 0.25rem !important;
|
||||||
|
min-width: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-group label {
|
.fullscreen-mode .filter-group label {
|
||||||
font-size: 0.8125rem;
|
font-size: 0.75rem !important;
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
color: #374151 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-group input,
|
.fullscreen-mode .filter-group input,
|
||||||
.fullscreen-mode .filter-group select {
|
.fullscreen-mode .filter-group select {
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem !important;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem !important;
|
||||||
|
height: 38px !important;
|
||||||
|
border: 2px solid #e2e8f0 !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
width: 100% !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
background: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Optimized table for fullscreen */
|
.fullscreen-mode .filter-group input:focus,
|
||||||
|
.fullscreen-mode .filter-group select:focus {
|
||||||
|
border-color: #2563eb !important;
|
||||||
|
outline: none !important;
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .filter-actions {
|
||||||
|
grid-column: 1 / -1 !important;
|
||||||
|
display: flex !important;
|
||||||
|
gap: 0.75rem !important;
|
||||||
|
justify-content: flex-start !important;
|
||||||
|
margin-top: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .filter-actions .btn {
|
||||||
|
padding: 0.5rem 1rem !important;
|
||||||
|
font-size: 0.875rem !important;
|
||||||
|
height: 38px !important;
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
TABLE SECTION IN FULLSCREEN
|
||||||
|
=========================== */
|
||||||
.fullscreen-mode .attendance-table-section {
|
.fullscreen-mode .attendance-table-section {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
background: white !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
|
||||||
|
overflow: hidden !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .table-header {
|
.fullscreen-mode .table-header {
|
||||||
padding: 1rem 1.5rem;
|
padding: 0.75rem 1.5rem !important;
|
||||||
|
background: #f8fafc !important;
|
||||||
|
border-bottom: 1px solid #e2e8f0 !important;
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
align-items: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .table-header h3 {
|
.fullscreen-mode .table-header h3 {
|
||||||
font-size: 1.125rem;
|
font-size: 1rem !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .table-controls {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .table-container {
|
||||||
|
max-height: calc(100vh - 280px) !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
overflow-x: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .attendance-table {
|
.fullscreen-mode .attendance-table {
|
||||||
font-size: 0.875rem;
|
font-size: 0.8125rem !important;
|
||||||
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .attendance-table th,
|
.fullscreen-mode .attendance-table th,
|
||||||
.fullscreen-mode .attendance-table td {
|
.fullscreen-mode .attendance-table td {
|
||||||
padding: 0.75rem 0.5rem;
|
padding: 0.625rem 0.5rem !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .employee-id {
|
.fullscreen-mode .attendance-table th {
|
||||||
font-size: 0.875rem;
|
position: sticky !important;
|
||||||
|
top: 0 !important;
|
||||||
|
background: #f8fafc !important;
|
||||||
|
z-index: 10 !important;
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 0.025em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
TABLE COLUMN OPTIMIZATION
|
||||||
|
=========================== */
|
||||||
|
|
||||||
|
/* Prevent text overlap - allow wrapping for long content */
|
||||||
|
.fullscreen-mode .attendance-table td {
|
||||||
|
white-space: normal !important;
|
||||||
|
word-wrap: break-word !important;
|
||||||
|
word-break: break-word !important;
|
||||||
|
max-width: 200px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep headers on single line */
|
||||||
|
.fullscreen-mode .attendance-table th {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific column width optimizations */
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(1),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(1) {
|
||||||
|
/* # column */
|
||||||
|
width: 40px !important;
|
||||||
|
min-width: 40px !important;
|
||||||
|
max-width: 40px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(2),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(2) {
|
||||||
|
/* Employee ID */
|
||||||
|
width: 80px !important;
|
||||||
|
min-width: 80px !important;
|
||||||
|
max-width: 80px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(3),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(3) {
|
||||||
|
/* Employee Name */
|
||||||
|
width: 120px !important;
|
||||||
|
min-width: 120px !important;
|
||||||
|
max-width: 120px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(4),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(4) {
|
||||||
|
/* Location */
|
||||||
|
width: 150px !important;
|
||||||
|
min-width: 150px !important;
|
||||||
|
max-width: 150px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(5),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(5) {
|
||||||
|
/* Event */
|
||||||
|
width: 80px !important;
|
||||||
|
min-width: 80px !important;
|
||||||
|
max-width: 80px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(6),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(6) {
|
||||||
|
/* Date */
|
||||||
|
width: 100px !important;
|
||||||
|
min-width: 100px !important;
|
||||||
|
max-width: 100px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(7),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(7) {
|
||||||
|
/* Time */
|
||||||
|
width: 80px !important;
|
||||||
|
min-width: 80px !important;
|
||||||
|
max-width: 80px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(8),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(8) {
|
||||||
|
/* QR Address */
|
||||||
|
width: 180px !important;
|
||||||
|
min-width: 180px !important;
|
||||||
|
max-width: 180px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(9),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(9) {
|
||||||
|
/* Check-in Address */
|
||||||
|
width: 180px !important;
|
||||||
|
min-width: 180px !important;
|
||||||
|
max-width: 180px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(10),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(10) {
|
||||||
|
/* Location Accuracy */
|
||||||
|
width: 100px !important;
|
||||||
|
min-width: 100px !important;
|
||||||
|
max-width: 100px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(11),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(11) {
|
||||||
|
/* Device */
|
||||||
|
width: 100px !important;
|
||||||
|
min-width: 100px !important;
|
||||||
|
max-width: 100px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(12),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(12) {
|
||||||
|
/* Actions */
|
||||||
|
width: 80px !important;
|
||||||
|
min-width: 80px !important;
|
||||||
|
max-width: 80px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Address columns - allow text to wrap within container */
|
||||||
|
.fullscreen-mode .address-column,
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(8),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(9) {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
line-height: 1.3 !important;
|
||||||
|
padding: 0.5rem 0.375rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Location accuracy badge styling */
|
||||||
|
.fullscreen-mode .location-accuracy-badge,
|
||||||
|
.fullscreen-mode .accuracy-badge {
|
||||||
|
display: inline-block !important;
|
||||||
|
padding: 0.25rem 0.5rem !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
font-size: 0.7rem !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device info */
|
||||||
|
.fullscreen-mode .device-info {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Employee info styling */
|
||||||
|
.fullscreen-mode .employee-id,
|
||||||
|
.fullscreen-mode .employee-name {
|
||||||
|
font-size: 0.8125rem !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Location and event info */
|
||||||
|
.fullscreen-mode .location-info,
|
||||||
|
.fullscreen-mode .event-info {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 0.25rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .location-info i,
|
||||||
|
.fullscreen-mode .event-info i {
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
font-size: 0.7rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Address info containers */
|
||||||
|
.fullscreen-mode .address-info {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
gap: 0.25rem !important;
|
||||||
|
word-break: break-word !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .address-info i {
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
margin-top: 0.125rem !important;
|
||||||
|
font-size: 0.7rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Time display */
|
||||||
.fullscreen-mode .time-info {
|
.fullscreen-mode .time-info {
|
||||||
font-size: 0.8125rem;
|
font-size: 0.75rem !important;
|
||||||
padding: 0.25rem 0.5rem;
|
padding: 0.25rem 0.5rem !important;
|
||||||
|
background: #f1f5f9 !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action buttons */
|
||||||
|
.fullscreen-mode .record-actions {
|
||||||
|
display: flex !important;
|
||||||
|
gap: 0.25rem !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
align-items: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .action-btn {
|
.fullscreen-mode .action-btn {
|
||||||
width: 30px;
|
width: 28px !important;
|
||||||
height: 30px;
|
height: 28px !important;
|
||||||
font-size: 0.75rem;
|
font-size: 0.7rem !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
display: inline-flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iPad Landscape Optimization */
|
/* Table layout */
|
||||||
|
.fullscreen-mode .attendance-table {
|
||||||
|
table-layout: fixed !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure table container allows horizontal scroll if needed */
|
||||||
|
.fullscreen-mode .table-container {
|
||||||
|
overflow-x: auto !important;
|
||||||
|
-webkit-overflow-scrolling: touch !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
RESPONSIVE BREAKPOINTS
|
||||||
|
=========================== */
|
||||||
|
|
||||||
|
/* iPad Landscape */
|
||||||
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {
|
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {
|
||||||
.fullscreen-mode {
|
.fullscreen-mode {
|
||||||
padding: 15px;
|
padding: 12px !important;
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stats-grid {
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-row {
|
.fullscreen-mode .filter-row {
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr) !important;
|
||||||
|
gap: 0.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-actions {
|
.fullscreen-mode .filter-actions {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .attendance-table {
|
.fullscreen-mode .attendance-table {
|
||||||
font-size: 0.8125rem;
|
font-size: 0.7rem !important;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iPad Portrait Optimization */
|
|
||||||
@media (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
|
|
||||||
.fullscreen-mode {
|
|
||||||
padding: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .stats-grid {
|
.fullscreen-mode .attendance-table th,
|
||||||
grid-template-columns: repeat(2, 1fr);
|
.fullscreen-mode .attendance-table td {
|
||||||
gap: 1rem;
|
padding: 0.5rem 0.375rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-row {
|
/* Adjust column widths for iPad landscape */
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .attendance-table {
|
|
||||||
font-size: 0.8125rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide less important columns on iPad portrait */
|
|
||||||
.fullscreen-mode .attendance-table th:nth-child(8),
|
.fullscreen-mode .attendance-table th:nth-child(8),
|
||||||
.fullscreen-mode .attendance-table td:nth-child(8),
|
.fullscreen-mode .attendance-table td:nth-child(8),
|
||||||
.fullscreen-mode .attendance-table th:nth-child(9),
|
.fullscreen-mode .attendance-table th:nth-child(9),
|
||||||
.fullscreen-mode .attendance-table td:nth-child(9) {
|
.fullscreen-mode .attendance-table td:nth-child(9) {
|
||||||
display: none;
|
width: 150px !important;
|
||||||
|
min-width: 150px !important;
|
||||||
|
max-width: 150px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small tablets and large phones */
|
/* iPad Portrait */
|
||||||
@media (max-width: 767px) {
|
@media (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
|
||||||
.fullscreen-toggle-btn {
|
|
||||||
width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
top: 15px;
|
|
||||||
right: 15px;
|
|
||||||
font-size: 1.125rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode {
|
.fullscreen-mode {
|
||||||
padding: 10px;
|
padding: 12px !important;
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .attendance-header {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode .stats-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 0.75rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-row {
|
.fullscreen-mode .filter-row {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: repeat(2, 1fr) !important;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-actions {
|
.fullscreen-mode .filter-actions {
|
||||||
grid-column: 1;
|
grid-column: 1 / -1 !important;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode .filter-actions .btn {
|
.fullscreen-mode .attendance-table {
|
||||||
width: 100%;
|
font-size: 0.7rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide less important columns on iPad portrait */
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(11),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(11) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust remaining column widths */
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(8),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(8),
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(9),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(9) {
|
||||||
|
width: 140px !important;
|
||||||
|
min-width: 140px !important;
|
||||||
|
max-width: 140px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.fullscreen-toggle-btn {
|
||||||
|
width: 45px !important;
|
||||||
|
height: 45px !important;
|
||||||
|
top: 15px !important;
|
||||||
|
right: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen-mode .filter-row {
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show only essential columns on mobile */
|
/* Show only essential columns on mobile */
|
||||||
.fullscreen-mode .attendance-table th:nth-child(4),
|
|
||||||
.fullscreen-mode .attendance-table td:nth-child(4),
|
|
||||||
.fullscreen-mode .attendance-table th:nth-child(5),
|
|
||||||
.fullscreen-mode .attendance-table td:nth-child(5),
|
|
||||||
.fullscreen-mode .attendance-table th:nth-child(8),
|
.fullscreen-mode .attendance-table th:nth-child(8),
|
||||||
.fullscreen-mode .attendance-table td:nth-child(8),
|
.fullscreen-mode .attendance-table td:nth-child(8),
|
||||||
.fullscreen-mode .attendance-table th:nth-child(9),
|
.fullscreen-mode .attendance-table th:nth-child(9),
|
||||||
.fullscreen-mode .attendance-table td:nth-child(9),
|
.fullscreen-mode .attendance-table td:nth-child(9),
|
||||||
|
.fullscreen-mode .attendance-table th:nth-child(10),
|
||||||
|
.fullscreen-mode .attendance-table td:nth-child(10),
|
||||||
.fullscreen-mode .attendance-table th:nth-child(11),
|
.fullscreen-mode .attendance-table th:nth-child(11),
|
||||||
.fullscreen-mode .attendance-table td:nth-child(11) {
|
.fullscreen-mode .attendance-table td:nth-child(11) {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth transitions */
|
/* ===========================
|
||||||
.fullscreen-transition {
|
SCROLLBAR STYLING
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
=========================== */
|
||||||
}
|
|
||||||
|
|
||||||
/* Scrollbar styling for fullscreen mode */
|
|
||||||
.fullscreen-mode::-webkit-scrollbar {
|
.fullscreen-mode::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
@@ -306,87 +612,31 @@ body.fullscreen-active .main-wrapper {
|
|||||||
background: #94a3b8;
|
background: #94a3b8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus states for accessibility */
|
/* ===========================
|
||||||
.fullscreen-toggle-btn:focus {
|
OVERSCROLL PREVENTION
|
||||||
outline: 3px solid rgba(37, 99, 235, 0.5);
|
=========================== */
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Animation for entering/exiting fullscreen */
|
|
||||||
@keyframes fadeInFullscreen {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.98);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode {
|
.fullscreen-mode {
|
||||||
animation: fadeInFullscreen 0.3s ease-out;
|
overscroll-behavior: none !important;
|
||||||
|
-webkit-overflow-scrolling: touch !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print styles - hide fullscreen button when printing */
|
body.fullscreen-active {
|
||||||
|
overscroll-behavior: none !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===========================
|
||||||
|
PRINT STYLES
|
||||||
|
=========================== */
|
||||||
@media print {
|
@media print {
|
||||||
.fullscreen-toggle-btn {
|
.fullscreen-toggle-btn {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-mode {
|
.fullscreen-mode {
|
||||||
position: static;
|
position: static !important;
|
||||||
width: 100%;
|
width: 100% !important;
|
||||||
height: auto;
|
height: auto !important;
|
||||||
padding: 0;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* High contrast mode support */
|
|
||||||
@media (prefers-contrast: high) {
|
|
||||||
.fullscreen-toggle-btn {
|
|
||||||
border: 2px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fullscreen-mode {
|
|
||||||
border: 2px solid #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reduced motion support */
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
|
||||||
.fullscreen-toggle-btn,
|
|
||||||
.fullscreen-mode,
|
|
||||||
.fullscreen-transition {
|
|
||||||
animation: none !important;
|
|
||||||
transition: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prevent pull-to-refresh and overscroll on touch devices in fullscreen */
|
|
||||||
.fullscreen-mode {
|
|
||||||
overscroll-behavior: none;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.fullscreen-active {
|
|
||||||
overscroll-behavior: none;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure content is scrollable within fullscreen container */
|
|
||||||
.fullscreen-mode {
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prevent iOS Safari bounce effect */
|
|
||||||
.fullscreen-mode,
|
|
||||||
.fullscreen-mode * {
|
|
||||||
-webkit-transform: translateZ(0);
|
|
||||||
transform: translateZ(0);
|
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,10 @@
|
|||||||
// Fullscreen state management
|
// Fullscreen state management
|
||||||
let isFullscreen = false;
|
let isFullscreen = false;
|
||||||
|
|
||||||
|
// Touch event handlers
|
||||||
|
let touchStartY = 0;
|
||||||
|
let touchStartX = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle fullscreen mode for attendance report
|
* Toggle fullscreen mode for attendance report
|
||||||
*/
|
*/
|
||||||
@@ -32,6 +36,75 @@ function toggleFullscreen() {
|
|||||||
logFullscreenAction(isFullscreen ? 'enter' : 'exit');
|
logFullscreenAction(isFullscreen ? 'enter' : 'exit');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent swipe gestures from interfering with fullscreen on touch devices
|
||||||
|
*/
|
||||||
|
function preventSwipeGestures(container, enable) {
|
||||||
|
if (enable) {
|
||||||
|
// Prevent pull-to-refresh and other touch gestures
|
||||||
|
container.addEventListener('touchstart', handleTouchStart, { passive: false });
|
||||||
|
container.addEventListener('touchmove', handleTouchMove, { passive: false });
|
||||||
|
container.addEventListener('touchend', handleTouchEnd, { passive: false });
|
||||||
|
|
||||||
|
// Prevent overscroll
|
||||||
|
document.body.style.overscrollBehavior = 'none';
|
||||||
|
container.style.overscrollBehavior = 'none';
|
||||||
|
|
||||||
|
console.log('Swipe gestures prevented for fullscreen mode');
|
||||||
|
} else {
|
||||||
|
// Re-enable normal touch behavior
|
||||||
|
container.removeEventListener('touchstart', handleTouchStart);
|
||||||
|
container.removeEventListener('touchmove', handleTouchMove);
|
||||||
|
container.removeEventListener('touchend', handleTouchEnd);
|
||||||
|
|
||||||
|
// Restore overscroll
|
||||||
|
document.body.style.overscrollBehavior = '';
|
||||||
|
container.style.overscrollBehavior = '';
|
||||||
|
|
||||||
|
console.log('Swipe gestures re-enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTouchStart(e) {
|
||||||
|
touchStartY = e.touches[0].clientY;
|
||||||
|
touchStartX = e.touches[0].clientX;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTouchMove(e) {
|
||||||
|
if (!isFullscreen) return;
|
||||||
|
|
||||||
|
const touchY = e.touches[0].clientY;
|
||||||
|
const touchX = e.touches[0].clientX;
|
||||||
|
const deltaY = touchY - touchStartY;
|
||||||
|
const deltaX = touchX - touchStartX;
|
||||||
|
|
||||||
|
const container = document.getElementById('attendanceReportContainer');
|
||||||
|
const scrollTop = container.scrollTop;
|
||||||
|
const scrollHeight = container.scrollHeight;
|
||||||
|
const clientHeight = container.clientHeight;
|
||||||
|
const isAtTop = scrollTop === 0;
|
||||||
|
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
|
||||||
|
|
||||||
|
// Prevent pull-down-to-refresh when at top
|
||||||
|
if (isAtTop && deltaY > 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent overscroll at bottom
|
||||||
|
if (isAtBottom && deltaY < 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow normal scrolling within the container
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTouchEnd(e) {
|
||||||
|
touchStartY = 0;
|
||||||
|
touchStartX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enter fullscreen mode
|
* Enter fullscreen mode
|
||||||
*/
|
*/
|
||||||
@@ -129,80 +202,6 @@ function exitFullscreen(container, icon, body) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent swipe gestures from interfering with fullscreen on touch devices
|
|
||||||
*/
|
|
||||||
function preventSwipeGestures(container, enable) {
|
|
||||||
if (enable) {
|
|
||||||
// Prevent pull-to-refresh and other touch gestures
|
|
||||||
container.addEventListener('touchstart', handleTouchStart, { passive: false });
|
|
||||||
container.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
||||||
container.addEventListener('touchend', handleTouchEnd, { passive: false });
|
|
||||||
|
|
||||||
// Prevent overscroll
|
|
||||||
document.body.style.overscrollBehavior = 'none';
|
|
||||||
container.style.overscrollBehavior = 'none';
|
|
||||||
|
|
||||||
console.log('Swipe gestures prevented for fullscreen mode');
|
|
||||||
} else {
|
|
||||||
// Re-enable normal touch behavior
|
|
||||||
container.removeEventListener('touchstart', handleTouchStart);
|
|
||||||
container.removeEventListener('touchmove', handleTouchMove);
|
|
||||||
container.removeEventListener('touchend', handleTouchEnd);
|
|
||||||
|
|
||||||
// Restore overscroll
|
|
||||||
document.body.style.overscrollBehavior = '';
|
|
||||||
container.style.overscrollBehavior = '';
|
|
||||||
|
|
||||||
console.log('Swipe gestures re-enabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Touch event handlers
|
|
||||||
let touchStartY = 0;
|
|
||||||
let touchStartX = 0;
|
|
||||||
|
|
||||||
function handleTouchStart(e) {
|
|
||||||
touchStartY = e.touches[0].clientY;
|
|
||||||
touchStartX = e.touches[0].clientX;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTouchMove(e) {
|
|
||||||
if (!isFullscreen) return;
|
|
||||||
|
|
||||||
const touchY = e.touches[0].clientY;
|
|
||||||
const touchX = e.touches[0].clientX;
|
|
||||||
const deltaY = touchY - touchStartY;
|
|
||||||
const deltaX = touchX - touchStartX;
|
|
||||||
|
|
||||||
const container = document.getElementById('attendanceReportContainer');
|
|
||||||
const scrollTop = container.scrollTop;
|
|
||||||
const scrollHeight = container.scrollHeight;
|
|
||||||
const clientHeight = container.clientHeight;
|
|
||||||
const isAtTop = scrollTop === 0;
|
|
||||||
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
|
|
||||||
|
|
||||||
// Prevent pull-down-to-refresh when at top
|
|
||||||
if (isAtTop && deltaY > 0) {
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent overscroll at bottom
|
|
||||||
if (isAtBottom && deltaY < 0) {
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow normal scrolling within the container
|
|
||||||
// Don't prevent default for vertical scrolling when not at boundaries
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleTouchEnd(e) {
|
|
||||||
touchStartY = 0;
|
|
||||||
touchStartX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore table layout
|
// Restore table layout
|
||||||
adjustTableForFullscreen(false);
|
adjustTableForFullscreen(false);
|
||||||
|
|
||||||
@@ -237,11 +236,19 @@ function adjustTableForFullscreen(isFullscreen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save fullscreen preference to localStorage
|
* Save fullscreen preference to localStorage and URL
|
||||||
*/
|
*/
|
||||||
function saveFullscreenPreference(isFullscreen) {
|
function saveFullscreenPreference(isFullscreen) {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem('attendance_fullscreen_preference', isFullscreen ? 'true' : 'false');
|
localStorage.setItem('attendance_fullscreen_preference', isFullscreen ? 'true' : 'false');
|
||||||
|
|
||||||
|
// Also update the hidden form field if it exists
|
||||||
|
const fullscreenInput = document.getElementById('fullscreenState');
|
||||||
|
if (fullscreenInput) {
|
||||||
|
fullscreenInput.value = isFullscreen ? '1' : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Fullscreen preference saved:', isFullscreen);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Could not save fullscreen preference:', e);
|
console.warn('Could not save fullscreen preference:', e);
|
||||||
}
|
}
|
||||||
@@ -338,7 +345,7 @@ function handleKeyboardShortcuts(event) {
|
|||||||
*/
|
*/
|
||||||
function detectAndOptimizeForIPad() {
|
function detectAndOptimizeForIPad() {
|
||||||
const isIPad = /iPad/.test(navigator.userAgent) ||
|
const isIPad = /iPad/.test(navigator.userAgent) ||
|
||||||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 0);
|
||||||
|
|
||||||
if (isIPad) {
|
if (isIPad) {
|
||||||
console.log('iPad detected - optimizing UI');
|
console.log('iPad detected - optimizing UI');
|
||||||
@@ -352,6 +359,48 @@ function detectAndOptimizeForIPad() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore fullscreen state from URL (CSS-only, no native fullscreen)
|
||||||
|
*/
|
||||||
|
function restoreFullscreenFromURL() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const fullscreenParam = urlParams.get('fullscreen');
|
||||||
|
|
||||||
|
if (fullscreenParam === '1' && !isFullscreen) {
|
||||||
|
console.log('Restoring fullscreen mode from URL parameter (CSS-only)');
|
||||||
|
|
||||||
|
// Use CSS-only fullscreen (no native fullscreen API call)
|
||||||
|
const container = document.getElementById('attendanceReportContainer');
|
||||||
|
const icon = document.getElementById('fullscreenIcon');
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
|
if (container && icon) {
|
||||||
|
// Manually set fullscreen state without calling native API
|
||||||
|
isFullscreen = true;
|
||||||
|
container.classList.add('fullscreen-mode');
|
||||||
|
body.classList.add('fullscreen-active');
|
||||||
|
|
||||||
|
// Update icon
|
||||||
|
icon.classList.remove('fa-expand');
|
||||||
|
icon.classList.add('fa-compress');
|
||||||
|
|
||||||
|
// Update button
|
||||||
|
const button = document.getElementById('fullscreenToggle');
|
||||||
|
if (button) {
|
||||||
|
button.setAttribute('title', 'Exit Fullscreen');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply touch gesture prevention
|
||||||
|
preventSwipeGestures(container, true);
|
||||||
|
|
||||||
|
// Save preference
|
||||||
|
saveFullscreenPreference(true);
|
||||||
|
|
||||||
|
console.log('Fullscreen restored successfully (CSS-only mode)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize fullscreen functionality
|
* Initialize fullscreen functionality
|
||||||
*/
|
*/
|
||||||
@@ -361,7 +410,7 @@ function initializeFullscreen() {
|
|||||||
// Detect iPad
|
// Detect iPad
|
||||||
detectAndOptimizeForIPad();
|
detectAndOptimizeForIPad();
|
||||||
|
|
||||||
// Add event listeners for native fullscreen changes
|
// Add event listeners for native fullscreen changes (desktop only)
|
||||||
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
||||||
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
|
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
|
||||||
document.addEventListener('mozfullscreenchange', handleFullscreenChange);
|
document.addEventListener('mozfullscreenchange', handleFullscreenChange);
|
||||||
@@ -370,12 +419,16 @@ function initializeFullscreen() {
|
|||||||
// Add keyboard shortcuts
|
// Add keyboard shortcuts
|
||||||
document.addEventListener('keydown', handleKeyboardShortcuts);
|
document.addEventListener('keydown', handleKeyboardShortcuts);
|
||||||
|
|
||||||
// Load saved preference
|
// Intercept filter form submission to preserve fullscreen state
|
||||||
const savedPreference = loadFullscreenPreference();
|
const filterForm = document.getElementById('filterForm');
|
||||||
if (savedPreference) {
|
if (filterForm) {
|
||||||
console.log('Restoring fullscreen preference');
|
filterForm.addEventListener('submit', function(e) {
|
||||||
// Optional: Auto-enter fullscreen if user had it enabled last time
|
const fullscreenInput = document.getElementById('fullscreenState');
|
||||||
// toggleFullscreen();
|
if (fullscreenInput) {
|
||||||
|
fullscreenInput.value = isFullscreen ? '1' : '';
|
||||||
|
console.log('Filter form submitted with fullscreen state:', isFullscreen);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle orientation changes
|
// Handle orientation changes
|
||||||
@@ -397,6 +450,12 @@ function initializeFullscreen() {
|
|||||||
}, 250);
|
}, 250);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Restore fullscreen state from URL if present
|
||||||
|
// Use setTimeout to ensure DOM is fully loaded
|
||||||
|
setTimeout(function() {
|
||||||
|
restoreFullscreenFromURL();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
console.log('Fullscreen functionality initialized');
|
console.log('Fullscreen functionality initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filters-form">
|
<div class="filters-form">
|
||||||
<form method="GET" action="{{ url_for('attendance_report') }}">
|
<form method="GET" action="{{ url_for('attendance_report') }}">
|
||||||
|
<!-- Hidden field to preserve fullscreen state -->
|
||||||
|
<input type="hidden" id="fullscreenState" name="fullscreen" value="">
|
||||||
<div class="filter-row">
|
<div class="filter-row">
|
||||||
<!-- Date Range Filters -->
|
<!-- Date Range Filters -->
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
@@ -410,11 +412,33 @@ const hasEditPermission = ['admin'].includes(userRole);
|
|||||||
const hasLocationAccuracy = {{ 'true' if has_location_accuracy_feature else 'false' }};
|
const hasLocationAccuracy = {{ 'true' if has_location_accuracy_feature else 'false' }};
|
||||||
|
|
||||||
function clearFilters() {
|
function clearFilters() {
|
||||||
window.location.href = "{{ url_for('attendance_report') }}";
|
// Get current fullscreen state
|
||||||
|
const fullscreenState = window.isAttendanceFullscreen && window.isAttendanceFullscreen() ? '1' : '';
|
||||||
|
|
||||||
|
// Redirect to clean URL with only fullscreen parameter if active
|
||||||
|
if (fullscreenState === '1') {
|
||||||
|
window.location.href = '{{ url_for('attendance_report') }}?fullscreen=1';
|
||||||
|
} else {
|
||||||
|
window.location.href = '{{ url_for('attendance_report') }}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshReport() {
|
function refreshReport() {
|
||||||
window.location.reload();
|
// Get current fullscreen state
|
||||||
|
const fullscreenState = window.isAttendanceFullscreen && window.isAttendanceFullscreen() ? '1' : '';
|
||||||
|
|
||||||
|
// Build URL with current filters and fullscreen state
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
// Add or update fullscreen parameter
|
||||||
|
if (fullscreenState === '1') {
|
||||||
|
params.set('fullscreen', '1');
|
||||||
|
} else {
|
||||||
|
params.delete('fullscreen');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload with preserved state
|
||||||
|
window.location.href = window.location.pathname + '?' + params.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLocationMap(recordId) {
|
function showLocationMap(recordId) {
|
||||||
@@ -651,6 +675,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
initializeFullscreen();
|
initializeFullscreen();
|
||||||
console.log('Fullscreen functionality initialized for attendance report');
|
console.log('Fullscreen functionality initialized for attendance report');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we should restore fullscreen from URL parameter
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const shouldBeFullscreen = urlParams.get('fullscreen') === '1';
|
||||||
|
|
||||||
|
if (shouldBeFullscreen) {
|
||||||
|
console.log('URL indicates fullscreen should be active');
|
||||||
|
// The initializeFullscreen function will handle restoration
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user