This commit is contained in:
xadyz1 2026-07-22 13:32:59 +01:00
parent 2d4af97f67
commit 38fd41324d
8 changed files with 176 additions and 34 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 425 KiB

View file

@ -2,8 +2,17 @@
body {
display: flex;
overflow: hidden;
font-family: 'Michroma', sans-serif;
}
h1, h2, h3, h4, h5, h6, .logo {
font-family: 'Goldman', sans-serif;
}
/* Responsiveness Utility Classes */
@media (max-width: 767px) { .show-on-desktop { display: none !important; } }
@media (min-width: 768px) { .show-on-mobile { display: none !important; } }
.sidebar {
width: var(--sidebar-width);
height: 100vh;
@ -305,6 +314,17 @@ body {
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
position: sticky;
top: 0;
z-index: 50;
background: rgba(17, 17, 19, 0.8);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
padding: 16px 32px;
margin-left: -32px;
margin-right: -32px;
margin-top: -24px;
border-bottom: 1px solid var(--border);
}
.page-header h1 {
@ -321,7 +341,7 @@ body {
/* Buttons */
.btn {
padding: 8px 16px;
border-radius: var(--radius);
border-radius: var(--radius-xl);
font-weight: 500;
font-size: 13px;
transition: all var(--transition);
@ -329,6 +349,9 @@ body {
align-items: center;
gap: 6px;
}
.btn:active {
transform: scale(0.98);
}
.btn-primary {
background: var(--accent);

View file

@ -1,27 +1,45 @@
:root {
--bg-primary: #111827;
--bg-secondary: #1f2937;
--bg-card: #1e293b;
--bg-card-hover: #283548;
--bg-input: #0f172a;
--accent: #3b82f6;
--accent-hover: #2563eb;
--accent-dim: #1d4ed8;
--text-primary: #f1f5f9;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--success: #22c55e;
--success-dim: #15803d;
/* Cores de Destaque */
--accent: #ff6b00;
--accent-hover: #e65c00;
--accent-dim: rgba(255, 107, 0, 0.15);
--accent-glow: rgba(255, 107, 0, 0.35);
/* Sistema de Feedback */
--success: #34d399;
--danger: #ef4444;
--danger-dim: #991b1b;
--warning: #f59e0b;
--warning-dim: #92400e;
--border: #334155;
--border-light: #475569;
--radius: 8px;
--radius-lg: 12px;
--shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
--warning: #fbbf24;
/* Borda arredondada / Glassmorphism */
--radius-sm: 8px;
--radius-md: 14px;
--radius-lg: 20px;
--radius-xl: 28px;
--transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
--sidebar-width: 220px;
--transition: 0.2s ease;
}
[data-theme="dark"], :root {
--bg-base: #09090b;
--bg-surface: #111113;
--bg-card: #1a1a1e;
--bg-card-hover: #242429;
--bg-input: #0d0d10;
--text-primary: #ffffff;
--text-secondary: #a1a1aa;
--text-muted: #6b7280;
--border: #27272a;
--border-highlight: #3f3f46;
--shadow: rgba(0, 0, 0, 0.5);
/* Mapping old variables to new ones for compatibility */
--bg-primary: var(--bg-base);
--bg-secondary: var(--bg-surface);
--radius: var(--radius-sm);
--success-dim: rgba(52, 211, 153, 0.2);
--danger-dim: rgba(239, 68, 68, 0.2);
--warning-dim: rgba(251, 191, 36, 0.2);
--border-light: var(--border-highlight);
--shadow-sm: rgba(0, 0, 0, 0.3);
}

View file

@ -1,16 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<html data-theme="dark" lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#111827">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#ff6b00">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/assets/icon-192.png">
<link rel="apple-touch-icon" href="/assets/icon-192.png">
<title>ScreenTinker</title>
<title>GoldenSignage</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Goldman:wght@400;700&family=Michroma&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/variables.css">
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/main.css">
@ -30,7 +35,7 @@
<line x1="8" y1="21" x2="16" y2="21"/>
<line x1="12" y1="17" x2="12" y2="21"/>
</svg>
<span id="brandName">ScreenTinker</span>
<span id="brandName">GoldenSignage</span>
</div>
<!-- #38: apply cached white-label before first paint (no ScreenTinker flash) -->
<script src="/js/brand-prime.js"></script>

View file

@ -543,7 +543,7 @@ window.addEventListener('hashchange', () => { if (isAuthenticated()) refreshCurr
// Register PWA service worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-admin.js').catch(() => {});
navigator.serviceWorker.register('/sw.js').catch(() => {});
}
// Mobile sidebar: open/close via hamburger, backdrop, nav tap, Escape
@ -640,3 +640,45 @@ document.addEventListener('click', (e) => {
const modal = document.getElementById(id);
if (modal) modal.style.display = 'none';
});
// Custom Pull-to-Refresh logic for mobile PWA standalone
let pwaTouchStartY = 0;
let pwaIsPulling = false;
document.addEventListener('touchstart', (e) => {
// Only start pull-to-refresh if we are at the very top of the page
const scrollElement = document.querySelector('.content') || document.documentElement;
if (scrollElement.scrollTop === 0) {
pwaTouchStartY = e.changedTouches[0].screenY;
pwaIsPulling = true;
} else {
pwaIsPulling = false;
}
}, { passive: true });
document.addEventListener('touchend', (e) => {
if (!pwaIsPulling) return;
const pwaTouchEndY = e.changedTouches[0].screenY;
if (pwaTouchEndY - pwaTouchStartY > 150) {
if ('caches' in window) {
caches.keys().then((names) => {
Promise.all(names.map(name => caches.delete(name)))
.then(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then((registrations) => {
for (let registration of registrations) {
registration.unregister();
}
window.location.reload(true);
});
} else {
window.location.reload(true);
}
});
});
} else {
window.location.reload(true);
}
}
}, { passive: true });

View file

@ -1,11 +1,11 @@
{
"name": "ScreenTinker",
"short_name": "ScreenTinker",
"name": "GoldenSignage",
"short_name": "GoldenSignage",
"description": "Digital Signage Management",
"start_url": "/",
"display": "standalone",
"background_color": "#111827",
"theme_color": "#3B82F6",
"background_color": "#09090b",
"theme_color": "#ff6b00",
"orientation": "any",
"icons": [
{

54
frontend/sw.js Normal file
View file

@ -0,0 +1,54 @@
const CACHE_NAME = 'goldensignage-v1';
const ASSETS_TO_CACHE = [
'/',
'/index.html',
'/manifest.json',
'/css/reset.css',
'/css/variables.css',
'/css/main.css',
'/js/app.js',
'/assets/icon-192.png',
'/assets/icon-512.png',
'https://fonts.googleapis.com/css2?family=Goldman:wght@400;700&family=Michroma&display=swap'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ASSETS_TO_CACHE);
})
);
self.skipWaiting();
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
);
self.clients.claim();
});
self.addEventListener('fetch', (event) => {
// Cache-First Strategy
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}
return fetch(event.request).then((networkResponse) => {
// Cache dynamic assets if needed, but for now just return network response
return networkResponse;
}).catch(() => {
// Handle offline fallback if needed
});
})
);
});