Paint each board row in its own notification type's colour
This commit is contained in:
@@ -45,13 +45,17 @@
|
||||
|
||||
<!-- Carousel - one card at a time, rotating -->
|
||||
<section v-else-if="group.displaystyle === 'carousel'" class="recognition-section">
|
||||
<div class="section-title recognition">{{ group.typename }}</div>
|
||||
<div
|
||||
class="section-title recognition"
|
||||
:style="{ backgroundColor: getTypeColor(group.typecolor), color: textOn(group.typecolor) }"
|
||||
>{{ group.typename }}</div>
|
||||
<div class="recognition-carousel">
|
||||
<div
|
||||
v-for="(rec, idx) in group.items"
|
||||
:key="`${rec.notificationid}-${rec.employeesso}`"
|
||||
class="recognition-card"
|
||||
:class="{ active: idx === carouselIndex(group) }"
|
||||
:style="{ '--accent': getTypeColor(rec.typecolor) }"
|
||||
>
|
||||
<!-- A type that names no employee is a message, not a person:
|
||||
no photo frame, no empty name line. -->
|
||||
@@ -82,7 +86,10 @@
|
||||
|
||||
<!-- Grid - a row of tiles, cycling a page at a time -->
|
||||
<section v-else class="recert-section">
|
||||
<div class="section-title recert-title">
|
||||
<div
|
||||
class="section-title recert-title"
|
||||
:style="{ backgroundColor: getTypeColor(group.typecolor), color: textOn(group.typecolor) }"
|
||||
>
|
||||
<span>{{ group.typename }} ({{ group.items.length }})</span>
|
||||
<span v-if="gridRangeLabel(group)" class="recert-range">{{ gridRangeLabel(group) }}</span>
|
||||
</div>
|
||||
@@ -99,6 +106,7 @@
|
||||
:key="`grid-${rec.notificationid}-${rec.employeesso}`"
|
||||
class="recert-tile"
|
||||
:class="{ 'message-tile': !hasEmployee(rec) }"
|
||||
:style="{ '--accent': getTypeColor(rec.typecolor) }"
|
||||
>
|
||||
<template v-if="hasEmployee(rec)">
|
||||
<img
|
||||
@@ -265,6 +273,10 @@ const styledGroups = computed(() => {
|
||||
key,
|
||||
typename: heading,
|
||||
displaystyle: n.displaystyle,
|
||||
// Heading colour comes from the first type in the row. A shared
|
||||
// category is one heading, so it can only carry one colour; the
|
||||
// individual cards below still wear their own type's colour.
|
||||
typecolor: n.typecolor,
|
||||
items: []
|
||||
})
|
||||
}
|
||||
@@ -453,6 +465,19 @@ function getTypeColor(typecolor) {
|
||||
return aliases[typecolor] || typecolor || '#14abef'
|
||||
}
|
||||
|
||||
// Text colour for a heading painted an arbitrary type colour. Gold needs dark
|
||||
// text, navy needs white, and a site picks its own hexes - so this is computed
|
||||
// rather than a per-colour rule.
|
||||
function textOn(backgroundcolor) {
|
||||
const hex = getTypeColor(backgroundcolor).replace('#', '')
|
||||
if (hex.length < 6) return '#fff'
|
||||
const r = parseInt(hex.slice(0, 2), 16)
|
||||
const g = parseInt(hex.slice(2, 4), 16)
|
||||
const b = parseInt(hex.slice(4, 6), 16)
|
||||
// Rec. 709 luma, the usual quick contrast test.
|
||||
return (0.2126 * r + 0.7152 * g + 0.0722 * b) > 150 ? '#231b00' : '#fff'
|
||||
}
|
||||
|
||||
function getSectionClass(notifications) {
|
||||
// Use danger color if any active incidents
|
||||
const hasIncident = notifications.some(n => n.typecolor === 'danger' && !n.resolved)
|
||||
@@ -602,6 +627,7 @@ function handlePhotoError(e) {
|
||||
}
|
||||
|
||||
.section-title.recognition {
|
||||
/* Fallback only - the real colour is the type's, set inline. */
|
||||
background: #ffc107;
|
||||
color: #3a2e00;
|
||||
}
|
||||
@@ -612,6 +638,7 @@ function handlePhotoError(e) {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.section-title.recert-title {
|
||||
/* Fallback only - the real colour is the type's, set inline. */
|
||||
background: #0d6efd;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
@@ -638,8 +665,8 @@ function handlePhotoError(e) {
|
||||
gap: 14px;
|
||||
}
|
||||
.recert-tile {
|
||||
background: linear-gradient(135deg, #1e3a5f 0%, #0d2137 100%);
|
||||
border: 2px solid #0d6efd;
|
||||
background: linear-gradient(135deg, #16233b 0%, #0d2137 100%);
|
||||
border: 2px solid var(--accent, #0d6efd);
|
||||
border-radius: 10px;
|
||||
padding: 14px 10px;
|
||||
display: flex;
|
||||
@@ -653,7 +680,7 @@ function handlePhotoError(e) {
|
||||
height: 90px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 3px solid #0d6efd;
|
||||
border: 3px solid var(--accent, #0d6efd);
|
||||
background: #1a1a2e;
|
||||
}
|
||||
.recert-photo.ge-logo-fallback {
|
||||
@@ -713,8 +740,8 @@ function handlePhotoError(e) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(135deg, #4a3a0a 0%, #2a2200 100%);
|
||||
border: 3px solid #ffc107;
|
||||
background: linear-gradient(135deg, #2b2718 0%, #1d1a10 100%);
|
||||
border: 3px solid var(--accent, #ffc107);
|
||||
border-radius: 12px;
|
||||
padding: 20px 25px;
|
||||
display: flex;
|
||||
@@ -736,7 +763,7 @@ function handlePhotoError(e) {
|
||||
height: 140px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 4px solid #ffc107;
|
||||
border: 4px solid var(--accent, #ffc107);
|
||||
background: #1a1a2e;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user