feat(fusion_clock): NFC kiosk SCSS (always-dark, high-contrast)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-14 01:14:14 -04:00
parent 03fd3d7c1c
commit 0351dcd497
2 changed files with 243 additions and 0 deletions

View File

@@ -81,6 +81,7 @@ Integrates natively with Odoo's hr.attendance module for full payroll compatibil
'assets': {
'web.assets_frontend': [
'fusion_clock/static/src/css/portal_clock.css',
'fusion_clock/static/src/scss/nfc_kiosk.scss',
'fusion_clock/static/src/js/fusion_clock_portal.js',
'fusion_clock/static/src/js/fusion_clock_kiosk.js',
],

View File

@@ -0,0 +1,242 @@
// NFC Clock Kiosk — always-dark, high-contrast.
// Per CLAUDE.md: shop-floor kiosks need explicit hex (no var(--bs-*) which drift)
// and we deliberately do NOT branch on $o-webclient-color-scheme — this is a
// frontend bundle (not backend), and the kiosk is intentionally always dark
// regardless of the user's color scheme preference.
$nfc-bg: #0b0d10;
$nfc-panel: #15191f;
$nfc-text: #ffffff;
$nfc-text-muted: #9ba3ad;
$nfc-success: #18a957;
$nfc-error: #d9374e;
$nfc-accent: #3b82f6;
$nfc-border: #2a3038;
html, body {
background: $nfc-bg !important;
color: $nfc-text;
margin: 0;
padding: 0;
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.o_main_navbar, header, footer { display: none !important; }
.nfc-kiosk {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
box-sizing: border-box;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.nfc-kiosk__company {
position: absolute;
top: 1.5rem;
left: 50%;
transform: translateX(-50%);
font-size: 1.25rem;
color: $nfc-text-muted;
}
.nfc-kiosk__time {
position: absolute;
top: 1.5rem;
right: 2rem;
font-size: 2rem;
font-weight: 600;
color: $nfc-text;
font-variant-numeric: tabular-nums;
}
.nfc-kiosk__date {
position: absolute;
top: 4.5rem;
right: 2rem;
font-size: 1rem;
color: $nfc-text-muted;
}
.nfc-kiosk__location {
position: absolute;
bottom: 1.5rem;
left: 2rem;
font-size: 0.95rem;
color: $nfc-text-muted;
}
.nfc-kiosk__settings {
position: absolute;
bottom: 1rem;
right: 1rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background: transparent;
color: $nfc-text-muted;
border: 1px solid $nfc-border;
cursor: pointer;
font-size: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
&:hover { color: $nfc-text; }
}
.nfc-kiosk__idle {
text-align: center;
}
.nfc-kiosk__icon {
font-size: 8rem;
color: $nfc-accent;
animation: nfc-pulse 2s ease-in-out infinite;
}
@keyframes nfc-pulse {
0%, 100% { opacity: 0.85; transform: scale(1); }
50% { opacity: 1.0; transform: scale(1.06); }
}
.nfc-kiosk__prompt {
font-size: 2rem;
font-weight: 500;
margin-top: 2rem;
}
.nfc-kiosk__processing {
text-align: center;
font-size: 1.5rem;
color: $nfc-text-muted;
}
.nfc-kiosk__result {
width: min(80vw, 700px);
padding: 2.5rem 3rem;
border-radius: 1rem;
display: flex;
align-items: center;
gap: 2rem;
&--success { background: $nfc-success; }
&--error { background: $nfc-error; }
}
.nfc-kiosk__avatar {
width: 7rem;
height: 7rem;
border-radius: 50%;
background-size: cover;
background-position: center;
background-color: rgba(255,255,255,0.2);
flex-shrink: 0;
}
.nfc-kiosk__result-text {
flex: 1;
.name { font-size: 2rem; font-weight: 700; }
.action { font-size: 1.5rem; margin-top: 0.5rem; }
.hours { font-size: 1.1rem; opacity: 0.9; margin-top: 0.25rem; }
}
.nfc-kiosk__setup {
text-align: center;
max-width: 600px;
h2 { font-size: 2rem; margin-bottom: 1rem; }
p { color: $nfc-text-muted; margin-bottom: 2rem; }
button {
font-size: 1.5rem;
padding: 1rem 3rem;
background: $nfc-accent;
color: white;
border: none;
border-radius: 0.5rem;
cursor: pointer;
}
}
.nfc-kiosk__enroll-overlay {
position: fixed; inset: 0;
background: rgba(0,0,0,0.85);
z-index: 1000;
display: flex; align-items: center; justify-content: center;
padding: 2rem;
}
.nfc-kiosk__enroll-panel {
background: $nfc-panel;
border: 1px solid $nfc-border;
border-radius: 1rem;
padding: 2.5rem;
width: min(80vw, 700px);
h2 { font-size: 1.5rem; margin: 0 0 1.5rem; }
.numpad {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem;
margin: 1rem 0;
button {
font-size: 2rem; padding: 1.5rem 0;
background: $nfc-bg; color: $nfc-text;
border: 1px solid $nfc-border; border-radius: 0.5rem;
cursor: pointer;
}
}
.pin-display {
font-size: 2.5rem; letter-spacing: 0.5rem;
text-align: center; margin: 1rem 0;
font-variant-numeric: tabular-nums;
}
.employee-search {
width: 100%;
padding: 0.75rem 1rem;
font-size: 1.25rem;
background: $nfc-bg; color: $nfc-text;
border: 1px solid $nfc-border;
border-radius: 0.5rem;
margin-bottom: 1rem;
}
.employee-list {
max-height: 40vh;
overflow-y: auto;
.employee-row {
padding: 0.75rem 1rem;
border-bottom: 1px solid $nfc-border;
cursor: pointer;
font-size: 1.1rem;
&:hover { background: $nfc-bg; }
}
}
.actions {
display: flex; gap: 1rem; justify-content: flex-end;
margin-top: 1.5rem;
button {
font-size: 1rem; padding: 0.75rem 1.5rem;
border-radius: 0.5rem; cursor: pointer; border: none;
}
.cancel { background: $nfc-border; color: $nfc-text; }
.confirm { background: $nfc-accent; color: white; }
}
}