feat: improve calendar layout
This commit is contained in:
parent
0421d840e3
commit
b5cf8f4346
@ -5,5 +5,6 @@ NEXTCLOUD_URL=
|
|||||||
NEXTCLOUD_USER=
|
NEXTCLOUD_USER=
|
||||||
NEXTCLOUD_APP_PASSWORD=
|
NEXTCLOUD_APP_PASSWORD=
|
||||||
NEXTCLOUD_CALENDAR_URL=
|
NEXTCLOUD_CALENDAR_URL=
|
||||||
|
NEXTCLOUD_CALENDAR_EMBED_URL=
|
||||||
publicVapidKey="YOUR_PUBLIC_VAPID_KEY"
|
publicVapidKey="YOUR_PUBLIC_VAPID_KEY"
|
||||||
privateVapidKey="YOUR_PRIVATE_VAPID_KEY"
|
privateVapidKey="YOUR_PRIVATE_VAPID_KEY"
|
||||||
@ -492,6 +492,10 @@ export function attachAdminDashboardListeners() {
|
|||||||
document.getElementById('calendar-clear-btn')?.addEventListener('click', handleCalendarSettingsClear);
|
document.getElementById('calendar-clear-btn')?.addEventListener('click', handleCalendarSettingsClear);
|
||||||
document.getElementById('calendar-embed-url')?.addEventListener('input', (e) => updateCalendarPreview(e.target.value.trim()));
|
document.getElementById('calendar-embed-url')?.addEventListener('input', (e) => updateCalendarPreview(e.target.value.trim()));
|
||||||
setupTabbedInterface();
|
setupTabbedInterface();
|
||||||
|
const adminContent = document.getElementById('admin-tabs-content');
|
||||||
|
if (adminContent) {
|
||||||
|
adminContent.classList.toggle('calendar-full-bleed', lastAdminTab === 'calendar');
|
||||||
|
}
|
||||||
if (lastAdminTab === 'calendar') renderCalendarView();
|
if (lastAdminTab === 'calendar') renderCalendarView();
|
||||||
if (lastAdminTab === 'settings') loadCalendarSettings();
|
if (lastAdminTab === 'settings') loadCalendarSettings();
|
||||||
}
|
}
|
||||||
@ -549,6 +553,7 @@ function setupTabbedInterface() {
|
|||||||
panel.classList.add('hidden');
|
panel.classList.add('hidden');
|
||||||
});
|
});
|
||||||
document.getElementById(`tab-content-${tabTarget}`).classList.remove('hidden');
|
document.getElementById(`tab-content-${tabTarget}`).classList.remove('hidden');
|
||||||
|
contentContainer.classList.toggle('calendar-full-bleed', tabTarget === 'calendar');
|
||||||
if (tabTarget === 'calendar') {
|
if (tabTarget === 'calendar') {
|
||||||
renderCalendarView();
|
renderCalendarView();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,7 +168,7 @@ export async function renderEmployeeDashboard() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tab-content-employee-calendar" class="space-y-4 hidden">
|
<div id="tab-content-employee-calendar" class="space-y-4 hidden">
|
||||||
<div class="bg-white rounded-xl shadow-md p-6">
|
<div class="bg-white rounded-xl shadow-md p-4">
|
||||||
<div class="flex flex-wrap justify-between items-center gap-2 mb-4">
|
<div class="flex flex-wrap justify-between items-center gap-2 mb-4">
|
||||||
<h3 class="text-xl font-bold text-gray-700">Calendar</h3>
|
<h3 class="text-xl font-bold text-gray-700">Calendar</h3>
|
||||||
<a id="employee-calendar-link" class="text-sm text-blue-600 hover:underline hidden" target="_blank" rel="noopener">Open in new tab</a>
|
<a id="employee-calendar-link" class="text-sm text-blue-600 hover:underline hidden" target="_blank" rel="noopener">Open in new tab</a>
|
||||||
@ -211,18 +211,18 @@ export async function renderAdminDashboard() {
|
|||||||
const employeesOnly = allUsers.filter(u => u.role === 'employee');
|
const employeesOnly = allUsers.filter(u => u.role === 'employee');
|
||||||
|
|
||||||
mainViews.admin.innerHTML = `
|
mainViews.admin.innerHTML = `
|
||||||
<div class="max-w-6xl mx-auto space-y-4">
|
<div class="max-w-6xl mx-auto w-full px-2 sm:px-0 space-y-4">
|
||||||
<div class="bg-white rounded-xl shadow-md p-4">
|
<div class="bg-white rounded-xl shadow-md p-4">
|
||||||
<h2 class="text-2xl font-bold">Admin Dashboard</h2>
|
<h2 class="text-2xl font-bold">Admin Dashboard</h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="admin-tabs-nav" class="flex border-b border-gray-200 bg-white rounded-t-lg px-4">
|
<div id="admin-tabs-nav" class="flex border-b border-gray-200 bg-white rounded-t-lg px-4 overflow-x-auto whitespace-nowrap -mx-2">
|
||||||
<button data-tab="overview" class="tab-btn active-tab py-3 px-4">Overview</button>
|
<button data-tab="overview" class="tab-btn active-tab py-3 px-4 flex-shrink-0">Overview</button>
|
||||||
<button data-tab="logs" class="tab-btn py-3 px-4">Time Logs</button>
|
<button data-tab="logs" class="tab-btn py-3 px-4 flex-shrink-0">Time Logs</button>
|
||||||
<button data-tab="users" class="tab-btn py-3 px-4">User Management</button>
|
<button data-tab="users" class="tab-btn py-3 px-4 flex-shrink-0">User Management</button>
|
||||||
<button data-tab="calendar" class="tab-btn py-3 px-4">Calendar</button>
|
<button data-tab="calendar" class="tab-btn py-3 px-4 flex-shrink-0">Calendar</button>
|
||||||
<button data-tab="settings" class="tab-btn py-3 px-4">Settings</button>
|
<button data-tab="settings" class="tab-btn py-3 px-4 flex-shrink-0">Settings</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="admin-tabs-content" class="bg-white rounded-b-lg shadow-md p-6">
|
<div id="admin-tabs-content" class="admin-tabs-content bg-white rounded-b-lg shadow-md p-6">
|
||||||
<div id="tab-content-overview" class="space-y-8">
|
<div id="tab-content-overview" class="space-y-8">
|
||||||
<div><h3 class="text-xl font-bold text-gray-700 mb-2">Currently Punched In</h3><ul class="border rounded-lg divide-y">${punchedInEntries.map(e => `<li class="flex flex-col items-start space-y-2 p-3 sm:flex-row sm:items-center sm:justify-between sm:space-y-0"><span class="font-medium text-gray-800">${e.username}</span><div class="flex items-center space-x-4"><span class="text-sm text-gray-500">Since: ${utils.formatDateTime(e.punch_in_time)}</span><button class="force-clock-out-btn px-3 py-1 text-xs bg-red-500 text-white rounded whitespace-nowrap" data-userid="${e.user_id}" data-username="${e.username}">Force Clock Out</button></div></li>`).join('') || '<li class="p-4 text-center text-gray-500">None</li>'}</ul></div>
|
<div><h3 class="text-xl font-bold text-gray-700 mb-2">Currently Punched In</h3><ul class="border rounded-lg divide-y">${punchedInEntries.map(e => `<li class="flex flex-col items-start space-y-2 p-3 sm:flex-row sm:items-center sm:justify-between sm:space-y-0"><span class="font-medium text-gray-800">${e.username}</span><div class="flex items-center space-x-4"><span class="text-sm text-gray-500">Since: ${utils.formatDateTime(e.punch_in_time)}</span><button class="force-clock-out-btn px-3 py-1 text-xs bg-red-500 text-white rounded whitespace-nowrap" data-userid="${e.user_id}" data-username="${e.username}">Force Clock Out</button></div></li>`).join('') || '<li class="p-4 text-center text-gray-500">None</li>'}</ul></div>
|
||||||
<div>
|
<div>
|
||||||
@ -330,7 +330,9 @@ export async function renderCalendarView() {
|
|||||||
|
|
||||||
if (res.success && res.data.url) {
|
if (res.success && res.data.url) {
|
||||||
calendarContainer.innerHTML = `
|
calendarContainer.innerHTML = `
|
||||||
<iframe src="${res.data.url}" style="width: 100%; height: 80vh; border: none;"></iframe>
|
<div class="-mx-6 -my-6">
|
||||||
|
<iframe src="${res.data.url}" style="width: 100%; height: 80vh; border: none;"></iframe>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
} else {
|
} else {
|
||||||
calendarContainer.innerHTML = `
|
calendarContainer.innerHTML = `
|
||||||
|
|||||||
@ -46,6 +46,10 @@ body {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-tabs-content.calendar-full-bleed {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sticky Message Box Styles */
|
/* Sticky Message Box Styles */
|
||||||
#message-box {
|
#message-box {
|
||||||
position: fixed; /* 'Fixes' the element relative to the browser window */
|
position: fixed; /* 'Fixes' the element relative to the browser window */
|
||||||
|
|||||||
17
server.js
17
server.js
@ -1,8 +1,5 @@
|
|||||||
//server.js
|
//server.js
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
console.log('--- DIAGNOSTIC TEST ---');
|
|
||||||
console.log('publicVapidKey loaded as:', process.env.publicVapidKey);
|
|
||||||
console.log('--- END DIAGNOSTIC TEST ---');
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const sqlite3 = require('sqlite3');
|
const sqlite3 = require('sqlite3');
|
||||||
const { open } = require('sqlite');
|
const { open } = require('sqlite');
|
||||||
@ -41,11 +38,15 @@ async function startServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webpush.setVapidDetails(
|
if (publicVapidKey && privateVapidKey) {
|
||||||
'mailto:utility@beachpartyballoons.com', // A contact email
|
webpush.setVapidDetails(
|
||||||
publicVapidKey,
|
'mailto:utility@beachpartyballoons.com',
|
||||||
privateVapidKey
|
publicVapidKey,
|
||||||
);
|
privateVapidKey
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn('Web push disabled: missing PUBLIC_VAPID_KEY or PRIVATE_VAPID_KEY.');
|
||||||
|
}
|
||||||
|
|
||||||
async function initializeDatabase() {
|
async function initializeDatabase() {
|
||||||
console.log("Initializing database schema...");
|
console.log("Initializing database schema...");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user