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:
@@ -81,6 +81,7 @@ Integrates natively with Odoo's hr.attendance module for full payroll compatibil
|
|||||||
'assets': {
|
'assets': {
|
||||||
'web.assets_frontend': [
|
'web.assets_frontend': [
|
||||||
'fusion_clock/static/src/css/portal_clock.css',
|
'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_portal.js',
|
||||||
'fusion_clock/static/src/js/fusion_clock_kiosk.js',
|
'fusion_clock/static/src/js/fusion_clock_kiosk.js',
|
||||||
],
|
],
|
||||||
|
|||||||
242
fusion_clock/static/src/scss/nfc_kiosk.scss
Normal file
242
fusion_clock/static/src/scss/nfc_kiosk.scss
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user