Projette les cibles en temps réel et corrige le fuseau horaire
Calcule les heures travaillées et cibles d'entrée/sortie même quand une demi-journée est en cours (pas encore de pointage de sortie), au lieu d'attendre la fin de journée. Ajoute un endpoint /refresh pour rafraîchir l'affichage sans repointer. Désambiguïse les libellés de semaine sur plusieurs années et force TZ=Europe/Paris dans le conteneur. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -750,6 +750,7 @@
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
.wkly-wrap {
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
@ -774,6 +775,71 @@
|
||||
/* Zoomable canvas hint */
|
||||
canvas.zoomable { cursor: zoom-in; }
|
||||
|
||||
/* ── Alerte départ ── */
|
||||
#alerte-depart {
|
||||
position: fixed;
|
||||
bottom: 1.5rem;
|
||||
right: 1.5rem;
|
||||
z-index: 9999;
|
||||
background: var(--neg);
|
||||
color: #fff;
|
||||
border-left: 4px solid #ff6b5b;
|
||||
box-shadow: 0 6px 28px rgba(0,0,0,.3);
|
||||
min-width: 240px;
|
||||
animation: alerte-slide .35s cubic-bezier(.2,.8,.3,1) both;
|
||||
}
|
||||
.alerte-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .75rem;
|
||||
padding: .85rem 1rem;
|
||||
}
|
||||
.alerte-icon { font-size: 1.5rem; flex-shrink: 0; animation: alerte-pulse 1s ease-in-out 3; }
|
||||
.alerte-body { flex: 1; }
|
||||
.alerte-label {
|
||||
font-family: var(--mono);
|
||||
font-size: 9px;
|
||||
letter-spacing: .12em;
|
||||
text-transform: uppercase;
|
||||
opacity: .7;
|
||||
margin-bottom: .2rem;
|
||||
}
|
||||
.alerte-time {
|
||||
font-family: var(--mono);
|
||||
font-size: 1.75rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: -.03em;
|
||||
line-height: 1;
|
||||
}
|
||||
.alerte-close {
|
||||
background: none;
|
||||
border: 1px solid rgba(255,255,255,.3);
|
||||
color: #fff;
|
||||
width: 24px; height: 24px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-start;
|
||||
transition: background .15s;
|
||||
}
|
||||
.alerte-close:hover { background: rgba(255,255,255,.15); }
|
||||
.alerte-supp {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
opacity: .8;
|
||||
margin-top: .25rem;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
@keyframes alerte-slide {
|
||||
from { opacity: 0; transform: translateX(120%); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
@keyframes alerte-pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.25); }
|
||||
}
|
||||
|
||||
/* ── Chart zoom modal ── */
|
||||
.chart-modal {
|
||||
position: fixed;
|
||||
@ -831,10 +897,31 @@
|
||||
.chart-modal-close:hover { border-color: var(--text); color: var(--text); }
|
||||
.chart-modal-close:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.chart-modal-body {
|
||||
position: relative;
|
||||
padding: 1.25rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
#chart-modal-canvas { display: block; }
|
||||
|
||||
.chart-tooltip {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
background: var(--surface);
|
||||
border: 1.5px solid var(--rule);
|
||||
box-shadow: 0 2px 8px rgba(28,23,18,.12);
|
||||
padding: .35rem .55rem;
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
color: var(--text);
|
||||
white-space: nowrap;
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -100%);
|
||||
transition: opacity .1s;
|
||||
z-index: 5;
|
||||
}
|
||||
.chart-tooltip.visible { opacity: 1; }
|
||||
.chart-tooltip .ct-val { font-weight: 500; }
|
||||
.chart-tooltip .ct-label { color: var(--muted); margin-left: .35em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user