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': {
|
||||
'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',
|
||||
],
|
||||
|
||||
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