Files
overleaf-cep/services/web/app/src/Features/Tutorial/TutorialHandler.mjs
Andrew Rumble 4f02a85aa4 Update paths
GitOrigin-RevId: 399c594dd1bbf739d91874df6be3b70e57fe01e3
2025-11-06 09:05:57 +00:00

63 lines
1.6 KiB
JavaScript

import UserUpdater from '../User/UserUpdater.mjs'
const POSTPONE_DURATION_MS = 24 * 60 * 60 * 1000 // 1 day
/**
* Change the tutorial state
*
* @param {string} userId
* @param {string} tutorialKey
* @param {'completed' | 'postponed'} state
* @param {Date} [postponedUntil] - The date until which the tutorial is postponed
*/
async function setTutorialState(
userId,
tutorialKey,
state,
postponedUntil = null
) {
const updateData = {
state,
updatedAt: new Date(),
}
if (state === 'postponed' && postponedUntil) {
updateData.postponedUntil = postponedUntil
}
await UserUpdater.promises.updateUser(userId, {
$set: {
[`completedTutorials.${tutorialKey}`]: updateData,
},
})
}
/**
* Returns a list of inactive tutorials for a given user
*
* The user must be loaded with the completedTutorials property.
*/
function getInactiveTutorials(user, tutorialKey) {
const inactiveTutorials = []
for (const [key, record] of Object.entries(user.completedTutorials ?? {})) {
if (record instanceof Date) {
// Legacy format: single date means the tutorial was completed
inactiveTutorials.push(key)
} else if (record.state === 'postponed') {
const defaultPostponedUntil = new Date(
record.updatedAt.getTime() + POSTPONE_DURATION_MS
)
const postponedUntil = record.postponedUntil ?? defaultPostponedUntil
if (new Date() < postponedUntil) {
inactiveTutorials.push(key)
}
} else {
inactiveTutorials.push(key)
}
}
return inactiveTutorials
}
export default { setTutorialState, getInactiveTutorials }