add window guard

This commit is contained in:
2026-06-30 10:12:29 +07:00
parent e94a87cbd9
commit aaafa6ada9
13 changed files with 475 additions and 66 deletions

View File

@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<link rel="icon" type="image/jpeg" href="/src/assets/logo.jpeg"/>
<title>Simple Care — Rikkei Education</title>
</head>
<body>

View File

@@ -93,6 +93,20 @@ body {
margin-bottom: 1.5rem;
}
.brand-logo-img {
width: 42px;
height: 42px;
border-radius: var(--radius-sm);
object-fit: cover;
flex-shrink: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.login-brand-row .brand-logo-img {
width: 48px;
height: 48px;
}
.login-logo {
width: 48px;
height: 48px;
@@ -413,24 +427,61 @@ body {
justify-content: space-between;
align-items: baseline;
gap: 0.5rem;
margin-bottom: 0.65rem;
margin-bottom: 0.4rem;
flex-shrink: 0;
}
.card-title-sub {
font-size: 0.75rem;
font-size: 0.72rem;
color: var(--text-muted);
font-family: monospace;
}
.clock-display-summary {
margin-bottom: 0.75rem;
padding-bottom: 0.75rem;
display: flex;
flex-wrap: wrap;
gap: 0.45rem;
margin-bottom: 0.45rem;
padding-bottom: 0.45rem;
border-bottom: 1px dashed var(--border-color);
flex: 0 0 auto;
}
.clock-chip {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.2rem 0.5rem;
border-radius: 6px;
border: 1px solid var(--border-color);
background: var(--bg-subtle);
font-size: 0.72rem;
}
.clock-chip em {
font-style: normal;
color: var(--text-muted);
font-weight: 600;
}
.clock-chip strong {
font-family: 'Share Tech Mono', monospace;
font-size: 0.78rem;
font-weight: 700;
}
.clock-chip--online strong {
color: var(--online-color);
}
.clock-chip--offline strong {
color: var(--offline-color);
}
.shifts-wrap {
flex: 1;
min-height: 0;
overflow: auto;
max-height: min(32vh, 220px);
}
.shifts-table {
@@ -571,10 +622,11 @@ body {
.clocks-card {
display: flex;
flex-direction: column;
gap: 0.65rem;
gap: 0.4rem;
flex: 1;
min-height: 0;
overflow: hidden;
padding: 0.75rem 0.85rem;
}
.card-title {

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -1,5 +1,8 @@
import './style.css';
import './app.css';
import logoUrl from './assets/logo.jpeg';
const brandLogoHtml = `<img src="${logoUrl}" alt="Simple Care" class="brand-logo-img" />`;
// Trạng thái cục bộ
let loggedIn = false;
@@ -68,7 +71,7 @@ function renderLoginPrompt() {
<div class="login-prompt-container">
<div class="card">
<div class="login-brand-row">
<div class="login-logo">RE</div>
${brandLogoHtml}
<div class="login-brand-text">
<div class="login-brand-name">Simple Care</div>
<div class="login-brand-sub">Rikkei Education</div>
@@ -157,7 +160,7 @@ function renderDashboard() {
<div class="dashboard-wrapper">
<header class="header">
<div class="brand">
<div class="brand-logo">RE</div>
${brandLogoHtml}
<div class="brand-text">
<span class="brand-name">Simple Care</span>
<span class="brand-sub">Rikkei Education</span>
@@ -228,14 +231,14 @@ function renderDashboard() {
<div class="card-title-sub" id="session-date">${stats.sessionDate || ''}</div>
</div>
<div class="clock-display clock-display-summary">
<div class="clock-item">
<div class="clock-label">Tổng trực tuyến</div>
<div class="clock-value online" id="clock-online">00:00:00</div>
</div>
<div class="clock-item">
<div class="clock-label">Tổng ngoại tuyến</div>
<div class="clock-value offline" id="clock-offline">00:00:00</div>
</div>
<span class="clock-chip clock-chip--online">
<em>Trực tuyến</em>
<strong id="clock-online">00:00:00</strong>
</span>
<span class="clock-chip clock-chip--offline">
<em>Ngoại tuyến</em>
<strong id="clock-offline">00:00:00</strong>
</span>
</div>
<div class="shifts-wrap" id="shifts-wrap">
${renderShiftsTable(stats.shifts)}
@@ -265,7 +268,7 @@ function formatDuration(totalSeconds) {
}
function startStatsTicker() {
setInterval(async () => {
const pullStats = async () => {
if (!loggedIn) return;
try {
const freshStats = await window.go.main.App.GetStats();
@@ -330,7 +333,9 @@ function startStatsTicker() {
} catch (err) {
console.error('Error fetching stats:', err);
}
}, 1000);
};
pullStats();
setInterval(pullStats, 1000);
}
async function startWebcam() {