122 lines
3.9 KiB
JavaScript
122 lines
3.9 KiB
JavaScript
// Utility functions
|
|
export function escapeHtml(text) {
|
|
if (text === null || text === undefined) {
|
|
return '';
|
|
}
|
|
const div = document.createElement('div');
|
|
div.textContent = String(text);
|
|
return div.innerHTML;
|
|
}
|
|
|
|
export function parseGeoLocation(value) {
|
|
if (!value) return null;
|
|
|
|
// Try semicolon separator first
|
|
let parts = value.split(';');
|
|
if (parts.length !== 2) {
|
|
// Try comma separator
|
|
parts = value.split(',');
|
|
}
|
|
|
|
if (parts.length === 2) {
|
|
const lat = parseFloat(parts[0].trim());
|
|
const lng = parseFloat(parts[1].trim());
|
|
|
|
if (!isNaN(lat) && !isNaN(lng)) {
|
|
return { lat, lng };
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function showStatus(message, type = 'info') {
|
|
const container = document.getElementById('status-container');
|
|
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.className = `status-message ${type}`;
|
|
messageDiv.textContent = message;
|
|
|
|
container.appendChild(messageDiv);
|
|
|
|
// Auto-remove after 5 seconds
|
|
setTimeout(() => {
|
|
messageDiv.remove();
|
|
}, 5000);
|
|
}
|
|
|
|
export function hideLoading() {
|
|
const loading = document.getElementById('loading');
|
|
if (loading) {
|
|
loading.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
export function updateLocationCount(count) {
|
|
const countElement = document.getElementById('location-count');
|
|
const mobileCountElement = document.getElementById('mobile-location-count');
|
|
|
|
const countText = `${count} location${count !== 1 ? 's' : ''}`;
|
|
|
|
if (countElement) {
|
|
countElement.textContent = countText;
|
|
}
|
|
if (mobileCountElement) {
|
|
mobileCountElement.textContent = countText;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets a CSS custom property `--app-height` to the window's inner height.
|
|
* This helps create a reliable "full height" value across all browsers,
|
|
* especially on mobile where `100vh` can be inconsistent.
|
|
*/
|
|
export function setAppHeight() {
|
|
const doc = document.documentElement;
|
|
doc.style.setProperty('--app-height', `${window.innerHeight}px`);
|
|
}
|
|
|
|
/**
|
|
* Sets viewport dimensions and handles safe area insets for better mobile support
|
|
* Also detects if we're on a scrollable page and adjusts accordingly
|
|
*/
|
|
export function setViewportDimensions() {
|
|
const doc = document.documentElement;
|
|
|
|
// Set height
|
|
doc.style.setProperty('--app-height', `${window.innerHeight}px`);
|
|
|
|
// Set width (useful for avoiding overflow issues)
|
|
doc.style.setProperty('--app-width', `${window.innerWidth}px`);
|
|
|
|
// Handle safe area insets for devices with notches or home indicators
|
|
if (CSS.supports('padding: env(safe-area-inset-top)')) {
|
|
doc.style.setProperty('--safe-area-top', 'env(safe-area-inset-top)');
|
|
doc.style.setProperty('--safe-area-bottom', 'env(safe-area-inset-bottom)');
|
|
doc.style.setProperty('--safe-area-left', 'env(safe-area-inset-left)');
|
|
doc.style.setProperty('--safe-area-right', 'env(safe-area-inset-right)');
|
|
} else {
|
|
doc.style.setProperty('--safe-area-top', '0px');
|
|
doc.style.setProperty('--safe-area-bottom', '0px');
|
|
doc.style.setProperty('--safe-area-left', '0px');
|
|
doc.style.setProperty('--safe-area-right', '0px');
|
|
}
|
|
|
|
// For pages that need scrolling (like shifts, user), don't restrict height
|
|
const isScrollablePage = window.location.pathname.includes('shifts') ||
|
|
window.location.pathname.includes('user') ||
|
|
window.location.pathname.includes('admin');
|
|
|
|
if (isScrollablePage) {
|
|
// Allow the body and app to grow beyond viewport height
|
|
document.body.style.height = 'auto';
|
|
document.body.style.minHeight = `${window.innerHeight}px`;
|
|
|
|
const app = document.getElementById('app');
|
|
if (app) {
|
|
app.style.height = 'auto';
|
|
app.style.minHeight = `${window.innerHeight}px`;
|
|
}
|
|
}
|
|
}
|