Merge pull request #28544 from overleaf/ac-some-web-esm-migration-4

[web] Convert some Features files to ES modules (part 4)

GitOrigin-RevId: cf11a7584e39c4d4de08e2f924240e488a4066c4
This commit is contained in:
Antoine Clausse
2025-09-23 11:20:07 +02:00
committed by Copybot
parent c0c065e477
commit 46715191e3
44 changed files with 2806 additions and 2642 deletions

View File

@@ -0,0 +1,62 @@
import UserUpdater from '../User/UserUpdater.js'
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 }