Add study account engagement features; v1.2.4
- Pause reminders: remindersPausedUntil field + scheduler skip + account UI with 7/14/30-day presets - Email digest mode: reminderFrequency field (immediate/weekly) + weekly digest email + scheduler + account UI toggle - Admin user list improvements: streak, reengagement, frequency, pause, per-study lesson progress - Admin manual re-engagement: POST endpoint + tier selector button in admin panel - Study bookmarks: bookmarkedSectionIds in progress file + POST/DELETE endpoints + toggle button in lesson UI - Study completion certificate email: auto-sent on first certificate issuance - Content fields for certificate and weekly digest email templates in admin Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
5bc8245ed2
commit
038ef2b039
12 files changed
+540
-38
No files matched your search
@@ -1415,6 +1415,9 @@ export function sanitizeStudyUsers(value) {
|
||||
totpEnabledAt: typeof item?.totpEnabledAt === 'string' ? item.totpEnabledAt : null,
|
||||
totpRecoveryCodes: Array.isArray(item?.totpRecoveryCodes) ? item.totpRecoveryCodes.filter(h => typeof h === 'string') : [],
|
||||
totpSecretPending: typeof item?.totpSecretPending === 'string' ? item.totpSecretPending : undefined,
|
||||
remindersPausedUntil: typeof item?.remindersPausedUntil === 'string' ? item.remindersPausedUntil : null,
|
||||
reminderFrequency: item?.reminderFrequency === 'weekly' ? 'weekly' : 'immediate',
|
||||
weeklyDigestSentAt: typeof item?.weeklyDigestSentAt === 'string' ? item.weeklyDigestSentAt : null,
|
||||
})
|
||||
}
|
||||
return out.slice(0, MAX_STUDY_USERS)
|
||||
@@ -1459,8 +1462,12 @@ export function sanitizeStudyProgress(value) {
|
||||
])
|
||||
)
|
||||
: {}
|
||||
const bookmarkedSectionIds = Array.isArray(studyData?.bookmarkedSectionIds)
|
||||
? Array.from(new Set(studyData.bookmarkedSectionIds.filter(id => typeof id === 'string' && id.trim()).map(id => id.trim())))
|
||||
: []
|
||||
progress.byStudy[studySlug.trim().toLowerCase()] = {
|
||||
completedSectionIds: Array.from(new Set(completedSectionIds)),
|
||||
bookmarkedSectionIds,
|
||||
quizAnswers,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user