musora-content-services 2.32.0 → 2.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.coderabbit.yaml +5 -0
- package/CHANGELOG.md +15 -0
- package/docs/ContentOrganization.html +2 -2
- package/docs/Gamification.html +2 -2
- package/docs/UserManagementSystem.html +2 -2
- package/docs/api_types.js.html +2 -2
- package/docs/config.js.html +2 -2
- package/docs/content-org_content-org.js.html +2 -2
- package/docs/content-org_guided-courses.ts.html +118 -0
- package/docs/content-org_playlists-types.js.html +2 -2
- package/docs/content-org_playlists.js.html +2 -2
- package/docs/content.js.html +2 -2
- package/docs/gamification_awards.js.html +1 -1
- package/docs/gamification_awards.ts.html +158 -0
- package/docs/gamification_gamification.js.html +2 -2
- package/docs/gamification_types.js.html +1 -1
- package/docs/global.html +2 -222
- package/docs/index.html +2 -2
- package/docs/module-Accounts.html +1471 -0
- package/docs/module-Awards.html +234 -14
- package/docs/module-Config.html +2 -2
- package/docs/module-Content-Services-V2.html +2 -2
- package/docs/module-GuidedCourses.html +108 -0
- package/docs/module-Interests.html +2 -2
- package/docs/module-Permissions.html +2 -2
- package/docs/module-Playlists.html +2 -2
- package/docs/module-Railcontent-Services.html +2 -2
- package/docs/module-Sanity-Services.html +2 -2
- package/docs/module-Sessions.html +2 -2
- package/docs/module-UserActivity.html +3 -3
- package/docs/module-UserChat.html +2 -2
- package/docs/module-UserManagement.html +2 -2
- package/docs/module-UserNotifications.html +2 -2
- package/docs/module-UserProfile.html +2 -2
- package/docs/railcontent.js.html +2 -2
- package/docs/sanity.js.html +2 -2
- package/docs/userActivity.js.html +7 -7
- package/docs/user_account.ts.html +190 -0
- package/docs/user_chat.js.html +2 -2
- package/docs/user_interests.js.html +2 -2
- package/docs/user_management.js.html +3 -2
- package/docs/user_notifications.js.html +2 -2
- package/docs/user_permissions.js.html +2 -2
- package/docs/user_profile.js.html +2 -2
- package/docs/user_sessions.js.html +2 -2
- package/docs/user_types.js.html +2 -2
- package/docs/user_user-management-system.js.html +2 -2
- package/jsdoc.json +11 -1
- package/package.json +5 -1
- package/src/index.d.ts +8 -2
- package/src/index.js +8 -2
- package/src/services/api/types.ts +22 -0
- package/src/services/gamification/awards.ts +86 -0
- package/src/services/user/account.ts +52 -0
- package/src/services/user/management.js +1 -0
- package/src/services/userActivity.js +5 -5
- package/src/services/gamification/awards.js +0 -93
- package/src/services/gamification/types.js +0 -8
package/jsdoc.json
CHANGED
|
@@ -12,9 +12,19 @@
|
|
|
12
12
|
"src/services/railcontent.js",
|
|
13
13
|
"src/index.js"
|
|
14
14
|
],
|
|
15
|
-
"includePattern": ".js$",
|
|
15
|
+
"includePattern": "(.js|.ts$)",
|
|
16
16
|
"excludePattern": "(node_modules/|docs)"
|
|
17
17
|
},
|
|
18
|
+
"plugins": [
|
|
19
|
+
"node_modules/jsdoc-babel"
|
|
20
|
+
],
|
|
21
|
+
"babel": {
|
|
22
|
+
"extensions": ["ts"],
|
|
23
|
+
"ignore": ["**/*.(test|spec).ts"],
|
|
24
|
+
"babelrc": false,
|
|
25
|
+
"presets": [["@babel/preset-env", { "targets": { "node": true } }], "@babel/preset-typescript"],
|
|
26
|
+
"plugins": ["@babel/plugin-transform-class-properties", "@babel/plugin-transform-object-rest-spread"]
|
|
27
|
+
},
|
|
18
28
|
"opts": {
|
|
19
29
|
"destination": "./docs",
|
|
20
30
|
"recurse": true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "musora-content-services",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.33.1",
|
|
4
4
|
"description": "A package for Musoras content services ",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,9 +21,13 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/railroadmedia/musora-content-services#readme",
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@babel/plugin-transform-class-properties": "^7.27.1",
|
|
25
|
+
"@babel/plugin-transform-object-rest-spread": "^7.28.0",
|
|
26
|
+
"@babel/preset-typescript": "^7.27.1",
|
|
24
27
|
"dotenv": "^16.4.5",
|
|
25
28
|
"jest": "^29.7.0",
|
|
26
29
|
"jsdoc": "^4.0.3",
|
|
30
|
+
"jsdoc-babel": "^0.5.0",
|
|
27
31
|
"prettier": "3.4.2",
|
|
28
32
|
"standard-version": "^9.5.0",
|
|
29
33
|
"ts-jest": "^29.2.4"
|
package/src/index.d.ts
CHANGED
|
@@ -95,8 +95,9 @@ import {
|
|
|
95
95
|
} from './services/forum.js';
|
|
96
96
|
|
|
97
97
|
import {
|
|
98
|
-
fetchAwardsForUser
|
|
99
|
-
|
|
98
|
+
fetchAwardsForUser,
|
|
99
|
+
fetchCertificate
|
|
100
|
+
} from './services/gamification/awards.ts';
|
|
100
101
|
|
|
101
102
|
import {
|
|
102
103
|
applyCloudflareWrapper,
|
|
@@ -219,6 +220,8 @@ import {
|
|
|
219
220
|
} from './services/sanity.js';
|
|
220
221
|
|
|
221
222
|
import {
|
|
223
|
+
confirmEmailChange,
|
|
224
|
+
requestEmailChange,
|
|
222
225
|
resetPassword,
|
|
223
226
|
sendAccountSetupEmail,
|
|
224
227
|
sendPasswordResetEmail,
|
|
@@ -319,6 +322,7 @@ declare module 'musora-content-services' {
|
|
|
319
322
|
buildImageSRC,
|
|
320
323
|
calculateLongestStreaks,
|
|
321
324
|
closeComment,
|
|
325
|
+
confirmEmailChange,
|
|
322
326
|
contentStatusCompleted,
|
|
323
327
|
contentStatusReset,
|
|
324
328
|
convertToTimeZone,
|
|
@@ -348,6 +352,7 @@ declare module 'musora-content-services' {
|
|
|
348
352
|
fetchByRailContentIds,
|
|
349
353
|
fetchByReference,
|
|
350
354
|
fetchCarouselCardData,
|
|
355
|
+
fetchCertificate,
|
|
351
356
|
fetchChatAndLiveEnvent,
|
|
352
357
|
fetchChatSettings,
|
|
353
358
|
fetchCoachLessons,
|
|
@@ -507,6 +512,7 @@ declare module 'musora-content-services' {
|
|
|
507
512
|
replyToComment,
|
|
508
513
|
reportComment,
|
|
509
514
|
reportPlaylist,
|
|
515
|
+
requestEmailChange,
|
|
510
516
|
reset,
|
|
511
517
|
resetPassword,
|
|
512
518
|
restoreComment,
|
package/src/index.js
CHANGED
|
@@ -95,8 +95,9 @@ import {
|
|
|
95
95
|
} from './services/forum.js';
|
|
96
96
|
|
|
97
97
|
import {
|
|
98
|
-
fetchAwardsForUser
|
|
99
|
-
|
|
98
|
+
fetchAwardsForUser,
|
|
99
|
+
fetchCertificate
|
|
100
|
+
} from './services/gamification/awards.ts';
|
|
100
101
|
|
|
101
102
|
import {
|
|
102
103
|
applyCloudflareWrapper,
|
|
@@ -219,6 +220,8 @@ import {
|
|
|
219
220
|
} from './services/sanity.js';
|
|
220
221
|
|
|
221
222
|
import {
|
|
223
|
+
confirmEmailChange,
|
|
224
|
+
requestEmailChange,
|
|
222
225
|
resetPassword,
|
|
223
226
|
sendAccountSetupEmail,
|
|
224
227
|
sendPasswordResetEmail,
|
|
@@ -318,6 +321,7 @@ export {
|
|
|
318
321
|
buildImageSRC,
|
|
319
322
|
calculateLongestStreaks,
|
|
320
323
|
closeComment,
|
|
324
|
+
confirmEmailChange,
|
|
321
325
|
contentStatusCompleted,
|
|
322
326
|
contentStatusReset,
|
|
323
327
|
convertToTimeZone,
|
|
@@ -347,6 +351,7 @@ export {
|
|
|
347
351
|
fetchByRailContentIds,
|
|
348
352
|
fetchByReference,
|
|
349
353
|
fetchCarouselCardData,
|
|
354
|
+
fetchCertificate,
|
|
350
355
|
fetchChatAndLiveEnvent,
|
|
351
356
|
fetchChatSettings,
|
|
352
357
|
fetchCoachLessons,
|
|
@@ -506,6 +511,7 @@ export {
|
|
|
506
511
|
replyToComment,
|
|
507
512
|
reportComment,
|
|
508
513
|
reportPlaylist,
|
|
514
|
+
requestEmailChange,
|
|
509
515
|
reset,
|
|
510
516
|
resetPassword,
|
|
511
517
|
restoreComment,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface PaginatedMeta {
|
|
2
|
+
current_page: number
|
|
3
|
+
from: number
|
|
4
|
+
to: number
|
|
5
|
+
per_page: number
|
|
6
|
+
last_page: number
|
|
7
|
+
total: number
|
|
8
|
+
path: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface PaginatedLinks {
|
|
12
|
+
first: string
|
|
13
|
+
last: string
|
|
14
|
+
next: string
|
|
15
|
+
prev: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PaginatedResponse<T> {
|
|
19
|
+
meta: PaginatedMeta
|
|
20
|
+
links: PaginatedLinks
|
|
21
|
+
data: Array<T>
|
|
22
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Awards
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { HttpClient } from '../../infrastructure/http/HttpClient'
|
|
6
|
+
import { PaginatedResponse } from '../api/types'
|
|
7
|
+
import { globalConfig } from '../config'
|
|
8
|
+
|
|
9
|
+
const baseUrl = `/api/gamification`
|
|
10
|
+
|
|
11
|
+
export interface Award {
|
|
12
|
+
id: number
|
|
13
|
+
user_id: number
|
|
14
|
+
completed_at: string // ISO-8601 timestamp
|
|
15
|
+
completion_data: Object
|
|
16
|
+
award_id: number
|
|
17
|
+
type: string
|
|
18
|
+
title: string
|
|
19
|
+
badge: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Certificate {
|
|
23
|
+
id: number
|
|
24
|
+
user_name: string
|
|
25
|
+
user_id: number
|
|
26
|
+
completed_at: string // ISO-8601 timestamp
|
|
27
|
+
message: string
|
|
28
|
+
award_id: number
|
|
29
|
+
type: string
|
|
30
|
+
title: string
|
|
31
|
+
musora_logo: string
|
|
32
|
+
musora_logo_64: string
|
|
33
|
+
brand_logo: string
|
|
34
|
+
brand_logo_64: string
|
|
35
|
+
ribbon_image: string
|
|
36
|
+
ribbon_image_64: string
|
|
37
|
+
award_image: string
|
|
38
|
+
award_image_64: string
|
|
39
|
+
|
|
40
|
+
instructor_signature?: string
|
|
41
|
+
instructor_signature_64?: string
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get awards for a specific user.
|
|
45
|
+
*
|
|
46
|
+
* NOTE: needs error handling for the response from http client
|
|
47
|
+
* (Alexandre: I'm doing it in a different branch/PR: https://github.com/railroadmedia/musora-content-services/pull/349)
|
|
48
|
+
* NOTE: This function still expects brand because FE passes the argument. It is ignored for now
|
|
49
|
+
*
|
|
50
|
+
* @param {number} userId - The user ID. If not provided, the authenticated user is used instead.
|
|
51
|
+
* @param {string} _brand - The brand to fetch the awards for.
|
|
52
|
+
* @param {number|null} [page=1] - Page attribute for pagination
|
|
53
|
+
* @param {number|null} [limit=5] - Limit how many items to return
|
|
54
|
+
* @returns {Promise<PaginatedResponse<Award>>} - The awards for the user.
|
|
55
|
+
*/
|
|
56
|
+
export async function fetchAwardsForUser(
|
|
57
|
+
userId: number,
|
|
58
|
+
_brand: string,
|
|
59
|
+
page: number = 1,
|
|
60
|
+
limit: number = 5
|
|
61
|
+
): Promise<PaginatedResponse<Award>> {
|
|
62
|
+
const httpClient = new HttpClient(globalConfig.baseUrl, globalConfig.sessionConfig.token)
|
|
63
|
+
const response = await httpClient.get<PaginatedResponse<Award>>(
|
|
64
|
+
`${baseUrl}/v1/users/${userId}/awards?limit=${limit}&page=${page}`
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return response
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get certificate data for a completed user award
|
|
72
|
+
*
|
|
73
|
+
* NOTE: needs error handling for the response from http client
|
|
74
|
+
* (Alexandre: I'm doing it in a different branch/PR: https://github.com/railroadmedia/musora-content-services/pull/349)
|
|
75
|
+
* NOTE: This function still expects brand because FE passes the argument. It is ignored for now
|
|
76
|
+
*
|
|
77
|
+
* @param {number} userAwardId - The user award progress id
|
|
78
|
+
* @returns {Promise<Certificate>} - The certificate data for the completed user award.
|
|
79
|
+
*/
|
|
80
|
+
export async function fetchCertificate(userAwardId: number): Promise<Certificate> {
|
|
81
|
+
const httpClient = new HttpClient(globalConfig.baseUrl, globalConfig.sessionConfig.token)
|
|
82
|
+
const response = await httpClient.get<Certificate>(
|
|
83
|
+
`${baseUrl}/v1/users/certificate/${userAwardId}`
|
|
84
|
+
)
|
|
85
|
+
return response
|
|
86
|
+
}
|
|
@@ -12,6 +12,10 @@ export interface PasswordResetProps {
|
|
|
12
12
|
token: string
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} email - The email address to check the account status for.
|
|
17
|
+
* @returns {Promise<{requires_setup: boolean}|HttpError>} - A promise that resolves to an object indicating whether account setup is required, or an HttpError if the request fails.
|
|
18
|
+
*/
|
|
15
19
|
export async function status(email: string): Promise<{ requires_setup: boolean } | HttpError> {
|
|
16
20
|
const httpClient = new HttpClient(globalConfig.baseUrl)
|
|
17
21
|
const response = await httpClient.get<{ requires_setup: boolean }>(
|
|
@@ -20,6 +24,10 @@ export async function status(email: string): Promise<{ requires_setup: boolean }
|
|
|
20
24
|
return response
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} email - The email address to send the account setup email to.
|
|
29
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the email is sent or an HttpError if the request fails.
|
|
30
|
+
*/
|
|
23
31
|
export async function sendAccountSetupEmail(email: string): Promise<void | HttpError> {
|
|
24
32
|
const httpClient = new HttpClient(globalConfig.baseUrl)
|
|
25
33
|
return httpClient.post<void>(
|
|
@@ -28,6 +36,14 @@ export async function sendAccountSetupEmail(email: string): Promise<void | HttpE
|
|
|
28
36
|
)
|
|
29
37
|
}
|
|
30
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @param {Object} params - The parameters for setting up the account.
|
|
41
|
+
* @property {string} email - The email address for the account.
|
|
42
|
+
* @property {string} password - The new password for the account.
|
|
43
|
+
* @property {string} passwordConfirmation - The confirmation of the new password.
|
|
44
|
+
* @property {string} token - The token sent to the user's email for verification.
|
|
45
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the account setup is complete or an HttpError if the request fails.
|
|
46
|
+
*/
|
|
31
47
|
export async function setupAccount({
|
|
32
48
|
email,
|
|
33
49
|
password,
|
|
@@ -43,6 +59,10 @@ export async function setupAccount({
|
|
|
43
59
|
})
|
|
44
60
|
}
|
|
45
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @param {string} email - The email address to send the password reset email to.
|
|
64
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the email change request is made.
|
|
65
|
+
*/
|
|
46
66
|
export async function sendPasswordResetEmail(email: string): Promise<void | HttpError> {
|
|
47
67
|
const httpClient = new HttpClient(globalConfig.baseUrl)
|
|
48
68
|
return httpClient.post(`/api/user-management-system/v1/accounts/password/reset-email`, {
|
|
@@ -50,6 +70,14 @@ export async function sendPasswordResetEmail(email: string): Promise<void | Http
|
|
|
50
70
|
})
|
|
51
71
|
}
|
|
52
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @param {Object} params - The parameters for resetting the password.
|
|
75
|
+
* @property {string} email - The email address for the account.
|
|
76
|
+
* @property {string} password - The new password for the account.
|
|
77
|
+
* @property {string} passwordConfirmation - The confirmation of the new password.
|
|
78
|
+
* @property {string} token - The token sent to the user's email for verification.
|
|
79
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the password reset is complete or an HttpError if the request fails.
|
|
80
|
+
*/
|
|
53
81
|
export async function resetPassword({
|
|
54
82
|
email,
|
|
55
83
|
password,
|
|
@@ -64,3 +92,27 @@ export async function resetPassword({
|
|
|
64
92
|
token,
|
|
65
93
|
})
|
|
66
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @param {string} email - The new email address to set for the user.
|
|
98
|
+
* @param {string} password - The current password of the user for verification.
|
|
99
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the email change request is made.
|
|
100
|
+
*/
|
|
101
|
+
export async function requestEmailChange(
|
|
102
|
+
email: string,
|
|
103
|
+
password: string
|
|
104
|
+
): Promise<void | HttpError> {
|
|
105
|
+
const apiUrl = `/api/user-management-system/v1/accounts/${globalConfig.sessionConfig.userId}/email-change`
|
|
106
|
+
const httpClient = new HttpClient(globalConfig.baseUrl, globalConfig.sessionConfig.token)
|
|
107
|
+
return httpClient.post(apiUrl, { email, password })
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string} token - The token sent to the user's email for verification.
|
|
112
|
+
* @returns {Promise<void|HttpError>} - A promise that resolves when the email change is confirmed.
|
|
113
|
+
*/
|
|
114
|
+
export async function confirmEmailChange(token: string): Promise<void | HttpError> {
|
|
115
|
+
const apiUrl = `/api/user-management-system/v1/accounts/email-change/confirm`
|
|
116
|
+
const httpClient = new HttpClient(globalConfig.baseUrl, globalConfig.sessionConfig.token)
|
|
117
|
+
return httpClient.post(apiUrl, { token })
|
|
118
|
+
}
|
|
@@ -995,6 +995,7 @@ function generateContentsMap(contents, playlistsContents) {
|
|
|
995
995
|
const existingShows = new Set()
|
|
996
996
|
const contentsMap = new Map()
|
|
997
997
|
const childToParentMap = {}
|
|
998
|
+
if (!contents) return contentsMap
|
|
998
999
|
contents.forEach((content) => {
|
|
999
1000
|
if (Array.isArray(content.parent_content_data) && content.parent_content_data.length > 0) {
|
|
1000
1001
|
childToParentMap[content.id] =
|
|
@@ -1073,20 +1074,20 @@ export async function getProgressRows({ brand = null, limit = 8 } = {}) {
|
|
|
1073
1074
|
nonPlaylistContentIds.push(userPinnedItem.id)
|
|
1074
1075
|
}
|
|
1075
1076
|
const [playlistsContents, contents] = await Promise.all([
|
|
1076
|
-
addContextToContent(fetchByRailContentIds, playlistEngagedOnContents, 'progress-tracker', {
|
|
1077
|
+
playlistEngagedOnContents ? addContextToContent(fetchByRailContentIds, playlistEngagedOnContents, 'progress-tracker', {
|
|
1077
1078
|
addNextLesson: true,
|
|
1078
1079
|
addNavigateTo: true,
|
|
1079
1080
|
addProgressStatus: true,
|
|
1080
1081
|
addProgressPercentage: true,
|
|
1081
1082
|
addProgressTimestamp: true,
|
|
1082
|
-
}),
|
|
1083
|
-
addContextToContent(fetchByRailContentIds, nonPlaylistContentIds, 'progress-tracker', brand, {
|
|
1083
|
+
}) : Promise.resolve([]),
|
|
1084
|
+
nonPlaylistContentIds ? addContextToContent(fetchByRailContentIds, nonPlaylistContentIds, 'progress-tracker', brand, {
|
|
1084
1085
|
addNextLesson: true,
|
|
1085
1086
|
addNavigateTo: true,
|
|
1086
1087
|
addProgressStatus: true,
|
|
1087
1088
|
addProgressPercentage: true,
|
|
1088
1089
|
addProgressTimestamp: true,
|
|
1089
|
-
}),
|
|
1090
|
+
}) : Promise.resolve([]),
|
|
1090
1091
|
])
|
|
1091
1092
|
const contentsMap = generateContentsMap(contents, playlistsContents)
|
|
1092
1093
|
let combined = await extractPinnedItemsAndSortAllItems(
|
|
@@ -1103,7 +1104,6 @@ export async function getProgressRows({ brand = null, limit = 8 } = {}) {
|
|
|
1103
1104
|
item.type === 'playlist' ? processPlaylistItem(item) : processContentItem(item)
|
|
1104
1105
|
)
|
|
1105
1106
|
)
|
|
1106
|
-
console.log('HomePageProgressRows results: remove before merge', results)
|
|
1107
1107
|
return {
|
|
1108
1108
|
type: TabResponseType.PROGRESS_ROWS,
|
|
1109
1109
|
displayBrowseAll: combined.length > limit,
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module Awards
|
|
3
|
-
*/
|
|
4
|
-
import '../api/types.js'
|
|
5
|
-
import './types.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Get awards for a specific user.
|
|
9
|
-
*
|
|
10
|
-
* @param {number|null} userId - The user ID. If not provided, the authenticated user is used instead.
|
|
11
|
-
* @param {string|null} brand - Brand
|
|
12
|
-
* @param {number|null} page - Page attribute for pagination
|
|
13
|
-
* @param {number|null} limit - Limit how many items to return
|
|
14
|
-
* @returns {Promise<PaginatedResponse<Award>>} - The awards for the user.
|
|
15
|
-
*/
|
|
16
|
-
export async function fetchAwardsForUser(userId, brand, page = 1, limit = 20) {
|
|
17
|
-
// TODO: connect to the API to get the user awards
|
|
18
|
-
return {
|
|
19
|
-
data: [
|
|
20
|
-
{
|
|
21
|
-
id: 1,
|
|
22
|
-
title: '30-Day Drummer',
|
|
23
|
-
challenge_title: '30-Day Drummer',
|
|
24
|
-
award:
|
|
25
|
-
'https://cdn.sanity.io/files/4032r8py/staging/5c7449ea40f09a096451a48e4a58e4452244e38d.png',
|
|
26
|
-
badge:
|
|
27
|
-
'https://cdn.sanity.io/files/4032r8py/staging/5c7449ea40f09a096451a48e4a58e4452244e38d.png',
|
|
28
|
-
date_completed: '2021-01-01',
|
|
29
|
-
award_text:
|
|
30
|
-
'You received this award for completing 30-Day Drummer with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
31
|
-
description:
|
|
32
|
-
'You received this award for completing 30-Day Drummer with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: 2,
|
|
36
|
-
title: '30-Day Bass',
|
|
37
|
-
challenge_title: '30-Day Bass',
|
|
38
|
-
award:
|
|
39
|
-
'https://cdn.sanity.io/files/4032r8py/production/b7efb6a2f0bd57e87dd13f85b1c3b0c876272b7c.png',
|
|
40
|
-
badge:
|
|
41
|
-
'https://cdn.sanity.io/files/4032r8py/production/b7efb6a2f0bd57e87dd13f85b1c3b0c876272b7c.png',
|
|
42
|
-
date_completed: '2022-02-02',
|
|
43
|
-
award_text:
|
|
44
|
-
'You received this award for completing 30-Day Bass with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
45
|
-
description:
|
|
46
|
-
'You received this award for completing 30-Day Bass with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
id: 3,
|
|
50
|
-
title: 'New Piano Players Start Here',
|
|
51
|
-
challenge_title: 'New Piano Players Start Here',
|
|
52
|
-
award:
|
|
53
|
-
'https://cdn.sanity.io/files/4032r8py/staging/94e663015da362b41695f5d6f3a8ca3f8317e1b5.png',
|
|
54
|
-
badge:
|
|
55
|
-
'https://cdn.sanity.io/files/4032r8py/staging/94e663015da362b41695f5d6f3a8ca3f8317e1b5.png',
|
|
56
|
-
date_completed: '2023-03-03',
|
|
57
|
-
award_text:
|
|
58
|
-
'You received this award for completing New Piano Players Start Here with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
59
|
-
description:
|
|
60
|
-
'You received this award for completing New Piano Players Start Here with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: 4,
|
|
64
|
-
title: 'Ear Training For Singers',
|
|
65
|
-
challenge_title: 'Ear Training For Singers',
|
|
66
|
-
award:
|
|
67
|
-
'https://cdn.sanity.io/files/4032r8py/staging/24fc36e8351d7994bfe8fb5c63c577cf5ed16dc9.png',
|
|
68
|
-
badge:
|
|
69
|
-
'https://cdn.sanity.io/files/4032r8py/staging/24fc36e8351d7994bfe8fb5c63c577cf5ed16dc9.png',
|
|
70
|
-
date_completed: '2024-04-04',
|
|
71
|
-
award_text:
|
|
72
|
-
'You received this award for completing Ear Training For Singers with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
73
|
-
description:
|
|
74
|
-
'You received this award for completing Ear Training For Singers with a perfect streak. You practiced a total of 123 minutes over the past 30 days.',
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
meta: {
|
|
78
|
-
current_page: 1,
|
|
79
|
-
from: 1,
|
|
80
|
-
to: 15,
|
|
81
|
-
per_page: 15,
|
|
82
|
-
last_page: 1,
|
|
83
|
-
total: 4,
|
|
84
|
-
path: 'to be implemented when BE is ready',
|
|
85
|
-
},
|
|
86
|
-
links: {
|
|
87
|
-
first: 'to be implemented when BE is ready',
|
|
88
|
-
last: 'to be implemented when BE is ready',
|
|
89
|
-
next: 'to be implemented when BE is ready',
|
|
90
|
-
prev: 'to be implemented when BE is ready',
|
|
91
|
-
},
|
|
92
|
-
}
|
|
93
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {Object} Award
|
|
3
|
-
* @property {number} id - Unique identifier for the award.
|
|
4
|
-
* @property {string} title - The title of the award.
|
|
5
|
-
* @property {string} badge - URL of the award badge image.
|
|
6
|
-
* @property {string} description - Description of the award.
|
|
7
|
-
* @property {Date} date_completed - Date when the award was completed.
|
|
8
|
-
*/
|