Preview future presence overrides in coordinator and fit the party board in 1080px

This commit is contained in:
2026-09-20 11:36:01 -04:00
parent 66a8dd2751
commit a4e612da86
4 changed files with 68 additions and 32 deletions
+9 -4
View File
@@ -50,6 +50,7 @@ from .dao_rules import QuestDefinitionsDao
from .dao_presence import PresenceOverridesDao, PresenceSchedulesDao
from .db import NestQuestDatabase
from .presence import (
MAX_PREVIEW_SCAN_DAYS,
PresenceEngine,
PresenceOverride,
PresenceSchedule,
@@ -167,10 +168,14 @@ class NestQuestCoordinator(DataUpdateCoordinator):
schedules[child.id] = PresenceSchedule.decode(
child.id, schedule.anchor_date, schedule.pattern
)
todays = await PresenceOverridesDao(
window_end = today + datetime.timedelta(
days=MAX_PREVIEW_SCAN_DAYS
)
window_end_iso = window_end.isoformat()
ranged = await PresenceOverridesDao(
self.database
).list_by_child_and_range(child.id, today_iso, today_iso)
if todays:
).list_by_child_and_range(child.id, today_iso, window_end_iso)
if ranged:
# The engine validates MODEL objects, not DAO records;
# each record converts losslessly (the schema guarantees
# end >= start and a real is_present).
@@ -182,7 +187,7 @@ class NestQuestCoordinator(DataUpdateCoordinator):
record.is_present,
record.note,
)
for record in todays
for record in ranged
]
engine = PresenceEngine(schedules, overrides)
@@ -603,8 +603,8 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
padding: 64px 110px 150px;
height: 100vh;
padding: 48px 110px 150px;
overflow: hidden;
background: var(--nq-p-parchment);
box-shadow: var(--nq-p-vignette);
@@ -676,7 +676,7 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
}
.kicker {
margin: 24px 0 0;
margin: 14px 0 0;
font-family: var(--nq-p-font-heading);
font-size: 22px;
font-weight: 600;
@@ -689,7 +689,7 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
.plates {
width: 100%;
margin-top: 72px;
margin-top: 42px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 56px;
@@ -701,9 +701,9 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
flex-direction: column;
align-items: center;
justify-content: center;
gap: 26px;
height: 600px;
padding: 44px 28px 40px;
gap: 20px;
height: 560px;
padding: 36px 28px 32px;
border: 2px solid var(--nq-p-panel-border);
border-radius: var(--nq-p-radius-panel);
background: var(--nq-p-card-panel);
@@ -737,8 +737,8 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
.crest {
position: relative;
flex: none;
width: 188px;
height: 214px;
width: 168px;
height: 192px;
padding: 4px;
clip-path: ${$(lt)};
background: rgba(255, 255, 255, 0.22);
@@ -750,7 +750,7 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 78px;
padding-bottom: 70px;
clip-path: ${$(lt)};
background: var(--nq-p-crest);
}
@@ -784,7 +784,7 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
display: inline-flex;
align-items: center;
gap: 10px;
padding: 10px 24px;
padding: 8px 20px;
border-radius: var(--nq-p-radius-pill);
background: rgba(22, 120, 60, 0.35);
font-family: var(--nq-p-font-heading);
@@ -813,7 +813,7 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
.progress-line {
font-family: var(--nq-p-font-heading);
font-size: 26px;
font-size: 24px;
font-weight: 700;
line-height: 1.2;
color: var(--nq-p-ink-secondary);
@@ -836,9 +836,9 @@ const lt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Kt = "polygon(50%
}
.hint {
margin: 40px 0 0;
margin: 26px 0 0;
font-family: var(--nq-p-font-body);
font-size: 27px;
font-size: 24px;
font-weight: 600;
line-height: 1.4;
text-align: center;