Implement ST-402 activity evaluation fields

This commit is contained in:
Janpeter Visser 2026-04-19 09:51:20 +02:00
parent c3cd1de647
commit 57ade6a772
10 changed files with 344 additions and 6 deletions

View file

@ -9,10 +9,12 @@ import {
} from "@/lib/planning/options";
import {
createActivityForTodayForCurrentUser,
updateActivityEvaluationForTodayForCurrentUser,
updateActivityStatusForTodayForCurrentUser,
} from "@/lib/planning/service";
import type {
CreateActivitySubmission,
UpdateActivityEvaluationSubmission,
UpdateActivityStatusSubmission,
} from "@/lib/planning/types";
import {
@ -20,6 +22,8 @@ import {
FormDataValidationError,
getEnumValue,
getIntegerValue,
getOptionalString,
getOptionalUuidValue,
getRequiredString,
getUuidValue,
} from "@/lib/forms/parse";
@ -69,6 +73,24 @@ function buildUpdateActivityStatusSubmission(
};
}
function buildUpdateActivityEvaluationSubmission(
formData: FormData,
): UpdateActivityEvaluationSubmission {
const notes = getOptionalString(formData, "notes");
return {
activityId: getUuidValue(formData, "activityId", "invalid-activity-evaluation"),
skipReasonId: getOptionalUuidValue(
formData,
"skipReasonId",
"invalid-activity-evaluation",
),
notes: notes
? assertMaxLength(notes, 500, "invalid-activity-evaluation")
: null,
};
}
export async function createActivityAction(
_previousState: null,
formData: FormData,
@ -114,3 +136,33 @@ export async function updateActivityStatusAction(
redirect(buildPathWithQuery("/planning", { status: "activity-status-saved" }));
return null;
}
export async function saveActivityEvaluationAction(
_previousState: null,
formData: FormData,
): Promise<null> {
try {
await updateActivityEvaluationForTodayForCurrentUser(
buildUpdateActivityEvaluationSubmission(formData),
);
} catch (error) {
if (error instanceof FormDataValidationError) {
redirect(buildPathWithQuery("/planning", { error: error.code }));
}
if (
error instanceof Error &&
(error.message === "Ongeldige of niet-beschikbare activiteit." ||
error.message === "Skip-reden is verplicht voor een overgeslagen activiteit." ||
error.message === "Toelichting is verplicht voor een aangepaste activiteit." ||
error.message === "Ongeldige skip-reden.")
) {
redirect(buildPathWithQuery("/planning", { error: "invalid-activity-evaluation" }));
}
redirect(buildPathWithQuery("/planning", { error: "activity-evaluation-failed" }));
}
redirect(buildPathWithQuery("/planning", { status: "activity-evaluation-saved" }));
return null;
}

View file

@ -144,6 +144,7 @@ export default async function PlanningPage({ searchParams }: PlanningPageProps)
<TodayActivitiesList
activities={planningPageData.activities}
categories={planningPageData.categories}
skipReasons={planningPageData.skipReasons}
/>
</div>
</AppShell>