Let a day removed from a period stay removed

Taking one day out of a period the planner placed did nothing that
lasted: the period still asked for a full week, so the next sync put the
day straight back. The option was disabled rather than lying about it.

A removed day is now recorded as its own thing — no leave for this
parent, this child, this date — and the planner honours it on every
later sync. It is kept apart from the working-day overrides, which
answer a different question about the calendar rather than about the
plan.

The day belongs to the parent whose band was clicked, so removing one
parent's day leaves their partner's alone; where both parents were to be
off on one funding arrangement, the partner is simply funded on their
own instead. A removed day shortens what the period is asking for rather
than counting as a day the plan failed to find, so the advice about
closing a shortfall does not start arguing for a day nobody wants.

Nothing is removed without a way back: the toast undoes it, and the day
itself is marked in the calendar and offers to restore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ei7gCZzdd751uZtPzb1Pep
This commit is contained in:
2026-09-19 16:05:17 +02:00
parent 6d92b87bf3
commit 8cfb9c82c6
39 changed files with 2362 additions and 31 deletions
+57
View File
@@ -517,6 +517,30 @@ function toDayOverride(raw: RawDayOverride): import('@/types').DayOverride {
}
}
interface RawPlannedDayExclusion {
id: string
workspace_id: string
child_id: string
parent_personal_data_uuid: string
date: string
created_at: string | null
updated_at: string | null
}
function toPlannedDayExclusion(
raw: RawPlannedDayExclusion,
): import('@/types').PlannedDayExclusion {
return {
id: raw.id,
workspaceId: raw.workspace_id,
childId: raw.child_id,
parentPersonalDataUuid: raw.parent_personal_data_uuid,
date: raw.date,
createdAt: raw.created_at,
updatedAt: raw.updated_at,
}
}
let _accessToken: string | null = null
export function setAccessToken(token: string | null): void {
@@ -1169,6 +1193,39 @@ export async function deleteDayOverride(id: string): Promise<void> {
return apiFetch(`/day-overrides/${id}`, { method: 'DELETE' })
}
// ---------------------------------------------------------------------------
// Planned-day exclusions — the days the user removed by hand and the planner
// must therefore leave empty on every subsequent sync.
// ---------------------------------------------------------------------------
export async function createPlannedDayExclusion(
req: import('@/types').PlannedDayExclusionCreateRequest,
): Promise<import('@/types').PlannedDayExclusion> {
const raw = (await apiFetch('/planned-day-exclusions', {
method: 'POST',
body: JSON.stringify({
workspace_id: req.workspaceId,
child_id: req.childId,
parent_personal_data_uuid: req.parentPersonalDataUuid,
date: req.date,
}),
})) as RawPlannedDayExclusion
return toPlannedDayExclusion(raw)
}
export async function listPlannedDayExclusionsByWorkspace(
workspaceId: string,
): Promise<import('@/types').PlannedDayExclusion[]> {
const raw = (await apiFetch(
`/planned-day-exclusions/workspace/${workspaceId}`,
)) as RawPlannedDayExclusion[]
return raw.map(toPlannedDayExclusion)
}
export async function deletePlannedDayExclusion(id: string): Promise<void> {
return apiFetch(`/planned-day-exclusions/${id}`, { method: 'DELETE' })
}
// ---------------------------------------------------------------------------
// Calendar (röda dagar / klämdagar) — GET /api/calendar/days, backs §3.4
// (Kalender shading), §3.6 (click-to-override) and §3.8 (Settings red-days