Award shortlist UX improvements + configurable invite link expiry
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m30s

Award shortlist:
- Expandable reasoning text (click to toggle, hover hint)
- Bulk select/deselect all checkbox in header
- Top N projects highlighted with amber background
- New bulkToggleShortlisted backend mutation

Invite link expiry:
- New "Invitation Link Expiry (hours)" field in Security Settings
- Reads from systemSettings `invite_link_expiry_hours` (default 72h / 3 days)
- Email template dynamically shows "X hours" or "X days" based on setting
- All 3 invite paths (bulk create, single invite, bulk resend) use setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 22:05:58 +01:00
parent 8a7da0fd93
commit d02b0b91b9
6 changed files with 156 additions and 24 deletions

View File

@@ -972,6 +972,28 @@ export const specialAwardRouter = router({
return { shortlisted: updated.shortlisted }
}),
/**
* Bulk toggle shortlisted status for multiple projects
*/
bulkToggleShortlisted: adminProcedure
.input(z.object({
awardId: z.string(),
projectIds: z.array(z.string()),
shortlisted: z.boolean(),
}))
.mutation(async ({ ctx, input }) => {
const result = await ctx.prisma.awardEligibility.updateMany({
where: {
awardId: input.awardId,
projectId: { in: input.projectIds },
eligible: true,
},
data: { shortlisted: input.shortlisted },
})
return { updated: result.count, shortlisted: input.shortlisted }
}),
/**
* Confirm shortlist — for SEPARATE_POOL awards, creates ProjectRoundState entries
*/