@edx/frontend-app-subscription-learner-dashboard 1.56.0 → 1.57.0

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.
Files changed (63) hide show
  1. package/dist/containers/CourseCard/components/CourseCardActions/BeginCourseButton.js +1 -1
  2. package/dist/containers/CourseCard/components/CourseCardActions/BeginCourseButton.js.map +1 -1
  3. package/dist/containers/CourseCard/components/CourseCardActions/ResumeButton.js +1 -1
  4. package/dist/containers/CourseCard/components/CourseCardActions/ResumeButton.js.map +1 -1
  5. package/dist/containers/CourseCard/components/CourseCardActions/ViewCourseButton.js +1 -1
  6. package/dist/containers/CourseCard/components/CourseCardActions/ViewCourseButton.js.map +1 -1
  7. package/dist/containers/CourseCard/components/CourseCardBanners/CourseUpgradeButton.js +8 -1
  8. package/dist/containers/CourseCard/components/CourseCardBanners/CourseUpgradeButton.js.map +1 -1
  9. package/dist/containers/CourseCard/components/CourseCardBanners/FindCourseBanner.d.ts +3 -1
  10. package/dist/containers/CourseCard/components/CourseCardBanners/FindCourseBanner.js +6 -2
  11. package/dist/containers/CourseCard/components/CourseCardBanners/FindCourseBanner.js.map +1 -1
  12. package/dist/containers/CourseCard/components/CourseCardBanners/ViewCertificateBanner.js +5 -3
  13. package/dist/containers/CourseCard/components/CourseCardBanners/ViewCertificateBanner.js.map +1 -1
  14. package/dist/containers/CourseCard/components/CourseCardBanners/ViewCourseDetailBanner.d.ts +3 -1
  15. package/dist/containers/CourseCard/components/CourseCardBanners/ViewCourseDetailBanner.js +6 -2
  16. package/dist/containers/CourseCard/components/CourseCardBanners/ViewCourseDetailBanner.js.map +1 -1
  17. package/dist/containers/CourseCard/components/CourseCardBanners/ViewGradesBanner.js +4 -2
  18. package/dist/containers/CourseCard/components/CourseCardBanners/ViewGradesBanner.js.map +1 -1
  19. package/dist/containers/CourseCard/components/CourseCardBanners/index.js +1 -1
  20. package/dist/containers/CourseCard/components/CourseCardBanners/index.js.map +1 -1
  21. package/dist/containers/CoursesPanel/CourseList/index.js +10 -1
  22. package/dist/containers/CoursesPanel/CourseList/index.js.map +1 -1
  23. package/dist/containers/CoursesPanel/NoCoursesView/index.js +4 -1
  24. package/dist/containers/CoursesPanel/NoCoursesView/index.js.map +1 -1
  25. package/dist/containers/ProductCard/index.js +5 -1
  26. package/dist/containers/ProductCard/index.js.map +1 -1
  27. package/dist/containers/ProgramDashboard/ProgramsList/ProgramListCard.js +5 -1
  28. package/dist/containers/ProgramDashboard/ProgramsList/ProgramListCard.js.map +1 -1
  29. package/dist/containers/ProgramDashboard/ProgramsList/index.js +9 -1
  30. package/dist/containers/ProgramDashboard/ProgramsList/index.js.map +1 -1
  31. package/dist/containers/ProgramsPanel/NoProgramsView/index.js +4 -1
  32. package/dist/containers/ProgramsPanel/NoProgramsView/index.js.map +1 -1
  33. package/dist/containers/SubscriptionBanner/components/SubscriptionBanner.js +19 -3
  34. package/dist/containers/SubscriptionBanner/components/SubscriptionBanner.js.map +1 -1
  35. package/dist/containers/SubscriptionInformation/components/SubscriptionInformation.js +18 -5
  36. package/dist/containers/SubscriptionInformation/components/SubscriptionInformation.js.map +1 -1
  37. package/dist/hooks/useCourseTrackingEvent.d.ts +1 -1
  38. package/dist/hooks/useCourseTrackingEvent.js.map +1 -1
  39. package/dist/hooks/useProgramTrackingEvents.d.ts +2 -0
  40. package/dist/hooks/useProgramTrackingEvents.js +9 -0
  41. package/dist/hooks/useProgramTrackingEvents.js.map +1 -0
  42. package/dist/tracking/constants.js +15 -7
  43. package/dist/tracking/constants.js.map +1 -1
  44. package/dist/tracking/index.d.ts +2 -0
  45. package/dist/tracking/index.js +2 -0
  46. package/dist/tracking/index.js.map +1 -1
  47. package/dist/tracking/trackers/course.d.ts +6 -2
  48. package/dist/tracking/trackers/course.js +7 -2
  49. package/dist/tracking/trackers/course.js.map +1 -1
  50. package/dist/tracking/trackers/program.d.ts +7 -0
  51. package/dist/tracking/trackers/program.js +27 -0
  52. package/dist/tracking/trackers/program.js.map +1 -0
  53. package/dist/tracking/trackers/subscription.d.ts +10 -0
  54. package/dist/tracking/trackers/subscription.js +12 -0
  55. package/dist/tracking/trackers/subscription.js.map +1 -0
  56. package/dist/widgets/ProgressiveProfilingQuiz/SearchPageBanners/BannerEntry.js +34 -2
  57. package/dist/widgets/ProgressiveProfilingQuiz/SearchPageBanners/BannerEntry.js.map +1 -1
  58. package/dist/widgets/ProgressiveProfilingQuiz/SearchPageBanners/messages.js +1 -1
  59. package/dist/widgets/ProgressiveProfilingQuiz/SearchPageBanners/messages.js.map +1 -1
  60. package/dist/widgets/ProgressiveProfilingQuiz/data/constants.d.ts +1 -1
  61. package/dist/widgets/ProgressiveProfilingQuiz/data/constants.js +1 -1
  62. package/dist/widgets/ProgressiveProfilingQuiz/data/constants.js.map +1 -1
  63. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ export declare const eventNames: {
2
+ paginationPageSelected: string;
3
+ cardTileSelected: string;
4
+ subscriptionBannerViewed: string;
5
+ subscriptionBannerDismissed: string;
6
+ subscriptionBannerActionClicked: string;
7
+ manageSubscriptionClicked: string;
8
+ renewSubscriptionClicked: string;
9
+ };
10
+ export declare const trackSubscriptionEvent: (eventName: string, properties?: Record<string, unknown>) => void;
@@ -0,0 +1,12 @@
1
+ import { createEventTracker } from '../../data/services/segment/utils';
2
+ export const eventNames = {
3
+ paginationPageSelected: 'edx.subscription.learner.pagination.page.selected',
4
+ cardTileSelected: 'edx.subscription.learner.card.tile.selected',
5
+ subscriptionBannerViewed: 'edx.subscription.learner.subscription.banner.viewed',
6
+ subscriptionBannerDismissed: 'edx.subscription.learner.subscription.banner.dismissed',
7
+ subscriptionBannerActionClicked: 'edx.subscription.learner.subscription.banner.action.clicked',
8
+ manageSubscriptionClicked: 'edx.subscription.learner.manage.subscription.clicked',
9
+ renewSubscriptionClicked: 'edx.subscription.learner.renew.subscription.clicked',
10
+ };
11
+ export const trackSubscriptionEvent = (eventName, properties = {}) => (createEventTracker(eventName, properties)());
12
+ //# sourceMappingURL=subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../src/tracking/trackers/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAEtE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,sBAAsB,EAAE,mDAAmD;IAC3E,gBAAgB,EAAE,6CAA6C;IAC/D,wBAAwB,EAAE,qDAAqD;IAC/E,2BAA2B,EAAE,wDAAwD;IACrF,+BAA+B,EAAE,6DAA6D;IAC9F,yBAAyB,EAAE,sDAAsD;IACjF,wBAAwB,EAAE,qDAAqD;CAChF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAiB,EAAE,aAAsC,EAAE,EAAE,EAAE,CAAC,CACrG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAC5C,CAAC","sourcesContent":["import { createEventTracker } from '@src/data/services/segment/utils';\n\nexport const eventNames = {\n paginationPageSelected: 'edx.subscription.learner.pagination.page.selected',\n cardTileSelected: 'edx.subscription.learner.card.tile.selected',\n subscriptionBannerViewed: 'edx.subscription.learner.subscription.banner.viewed',\n subscriptionBannerDismissed: 'edx.subscription.learner.subscription.banner.dismissed',\n subscriptionBannerActionClicked: 'edx.subscription.learner.subscription.banner.action.clicked',\n manageSubscriptionClicked: 'edx.subscription.learner.manage.subscription.clicked',\n renewSubscriptionClicked: 'edx.subscription.learner.renew.subscription.clicked',\n};\n\nexport const trackSubscriptionEvent = (eventName: string, properties: Record<string, unknown> = {}) => (\n createEventTracker(eventName, properties)()\n);\n"]}
@@ -1,10 +1,20 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useRef, useEffect } from 'react';
2
3
  import { useProgressiveProfilingQuiz } from '../ProgressiveProfilingQuizProvider';
3
- import { useIntl } from '@openedx/frontend-base';
4
+ import { getAuthenticatedUser, useIntl } from '@openedx/frontend-base';
4
5
  import { Banner } from './Banner';
5
6
  import messages from './messages';
6
7
  import { PROGRESSIVE_PROFILING_USER_STATUS } from '../data/constants';
7
8
  import { trackProgressiveProfilingSearchPageBannerClick } from '../../../tracking/trackers/progressiveProfiling';
9
+ // Prefix is namespaced per-user so a different user (or a cleared/incognito profile) on the
10
+ // same browser is treated as never having seen the auto-opened modal before.
11
+ const AUTO_OPEN_KEY_PREFIX = 'progressiveProfiling.autoOpened.';
12
+ const getAutoOpenKey = () => {
13
+ const user = getAuthenticatedUser();
14
+ if (!(user === null || user === void 0 ? void 0 : user.userId))
15
+ return null;
16
+ return `${AUTO_OPEN_KEY_PREFIX}${user.userId}`;
17
+ };
8
18
  /**
9
19
  * Single slot entry point.
10
20
  * Reads progressive profiling state from context and selects one CTA.
@@ -13,9 +23,31 @@ export const BannerEntry = () => {
13
23
  var _a, _b, _c, _d, _e;
14
24
  const { openModal, answers, progressiveProfileStatus, } = useProgressiveProfilingQuiz();
15
25
  const { formatMessage } = useIntl();
26
+ const hasAttemptedAutoOpen = useRef(false);
27
+ const { status, remainingQuestions } = progressiveProfileStatus || {};
28
+ /*
29
+ Auto-trigger the survey modal the very first time this user (on this browser/device) lands
30
+ on the Search page with a not-started progressive profile. Once opened - regardless of
31
+ whether the user completes, abandons, or closes it - it's flagged as "seen" for that user so
32
+ it never auto-opens again, even if the backend status hasn't caught up yet (e.g. abandoned
33
+ partway through, before any answers were saved).
34
+ */
35
+ useEffect(() => {
36
+ if (hasAttemptedAutoOpen.current)
37
+ return;
38
+ if (!status || status !== PROGRESSIVE_PROFILING_USER_STATUS.NOT_STARTED)
39
+ return;
40
+ const autoOpenKey = getAutoOpenKey();
41
+ if (!autoOpenKey)
42
+ return; // No authenticated user available yet; try again next render.
43
+ if (localStorage.getItem(autoOpenKey))
44
+ return;
45
+ hasAttemptedAutoOpen.current = true;
46
+ localStorage.setItem(autoOpenKey, 'true');
47
+ openModal();
48
+ }, [status, openModal]);
16
49
  if (!progressiveProfileStatus)
17
50
  return null;
18
- const { status, remainingQuestions } = progressiveProfileStatus || {};
19
51
  const learningGoal = (_c = (_b = (_a = answers === null || answers === void 0 ? void 0 : answers['learning-goal']) === null || _a === void 0 ? void 0 : _a.selectedValues) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.replaceAll('-', ' ');
20
52
  const interests = (_e = (_d = answers === null || answers === void 0 ? void 0 : answers['interests-declared']) === null || _d === void 0 ? void 0 : _d.selectedValues) !== null && _e !== void 0 ? _e : [];
21
53
  const formattedInterests = interests.length > 1
@@ -1 +1 @@
1
- {"version":3,"file":"BannerEntry.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/SearchPageBanners/BannerEntry.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,iCAAiC,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,8CAA8C,EAAE,MAAM,6CAA6C,CAAC;AAE7G;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAO,GAAG,EAAE;;IAClC,MAAM,EACJ,SAAS,EACT,OAAO,EACP,wBAAwB,GACzB,GAAG,2BAA2B,EAAE,CAAC;IAClC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,IAAI,CAAC,wBAAwB;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,wBAAwB,IAAI,EAAE,CAAC;IAEtE,MAAM,YAAY,GAAG,MAAA,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,eAAe,CAAC,0CAAE,cAAc,0CAAG,CAAC,CAAC,0CAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3F,MAAM,SAAS,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,oBAAoB,CAAC,0CAAE,cAAc,mCAAI,EAAE,CAAC;IACxE,MAAM,kBAAkB,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;QAC7C,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;QAChE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAEjB,+DAA+D;IAC/D,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,SAAS,EAAE,CAAC;QACZ,8CAA8C,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC;IAEF,IAAI,KAAK,GAAc,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC/D,IAAI,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAE9D,IAAI,MAAM,KAAK,iCAAiC,CAAC,QAAQ,EAAE,CAAC;QAC1D,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,2BAAS,MAAM,GAAU,EAAE,CAAC,CAAC;QAC1I,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,MAAM,KAAK,iCAAiC,CAAC,UAAU,EAAE,CAAC;QAC5D,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACxE,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,KAAC,MAAM,IAAC,aAAa,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,GAAI,CAAC;AAC5F,CAAC,CAAC","sourcesContent":["import { FC, ReactNode } from 'react';\nimport { useProgressiveProfilingQuiz } from '../ProgressiveProfilingQuizProvider';\nimport { useIntl } from '@openedx/frontend-base';\n\nimport { Banner } from './Banner';\nimport messages from './messages';\nimport { PROGRESSIVE_PROFILING_USER_STATUS } from '../data/constants';\nimport { trackProgressiveProfilingSearchPageBannerClick } from '@src/tracking/trackers/progressiveProfiling';\n\n/**\n * Single slot entry point.\n * Reads progressive profiling state from context and selects one CTA.\n */\nexport const BannerEntry: FC = () => {\n const {\n openModal,\n answers,\n progressiveProfileStatus,\n } = useProgressiveProfilingQuiz();\n const { formatMessage } = useIntl();\n\n if (!progressiveProfileStatus) return null;\n\n const { status, remainingQuestions } = progressiveProfileStatus || {};\n\n const learningGoal = answers?.['learning-goal']?.selectedValues?.[0]?.replaceAll('-', ' ');\n const interests = answers?.['interests-declared']?.selectedValues ?? [];\n const formattedInterests = interests.length > 1\n ? `${interests.slice(0, -1).join(', ')} and ${interests.at(-1)}`\n : interests[0];\n\n // Handle button click for the banner and track the click event\n const handleButtonClick = () => {\n openModal();\n trackProgressiveProfilingSearchPageBannerClick({ eventStatus: status });\n };\n\n let title: ReactNode = formatMessage(messages.notStartedTitle);\n let buttonText = formatMessage(messages.notStartedButtonText);\n\n if (status === PROGRESSIVE_PROFILING_USER_STATUS.COMPLETE) {\n title = formatMessage(messages.completeTitle, { learningGoal, interests: formattedInterests, bold: chunks => <strong>{chunks}</strong> });\n buttonText = formatMessage(messages.completeButtonText);\n }\n\n if (status === PROGRESSIVE_PROFILING_USER_STATUS.INCOMPLETE) {\n title = formatMessage(messages.incompleteTitle, { remainingQuestions });\n buttonText = formatMessage(messages.incompleteButtonText);\n }\n\n return <Banner onButtonClick={handleButtonClick} title={title} buttonText={buttonText} />;\n};\n"]}
1
+ {"version":3,"file":"BannerEntry.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/SearchPageBanners/BannerEntry.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FC, ReactNode, useRef, useEffect } from 'react';\nimport { useProgressiveProfilingQuiz } from '../ProgressiveProfilingQuizProvider';\nimport { getAuthenticatedUser, useIntl } from '@openedx/frontend-base';\n\nimport { Banner } from './Banner';\nimport messages from './messages';\nimport { PROGRESSIVE_PROFILING_USER_STATUS } from '../data/constants';\nimport { trackProgressiveProfilingSearchPageBannerClick } from '@src/tracking/trackers/progressiveProfiling';\n\n// Prefix is namespaced per-user so a different user (or a cleared/incognito profile) on the\n// same browser is treated as never having seen the auto-opened modal before.\nconst AUTO_OPEN_KEY_PREFIX = 'progressiveProfiling.autoOpened.';\n\nconst getAutoOpenKey = (): string | null => {\n const user = getAuthenticatedUser();\n if (!user?.userId) return null;\n return `${AUTO_OPEN_KEY_PREFIX}${user.userId}`;\n};\n\n/**\n * Single slot entry point.\n * Reads progressive profiling state from context and selects one CTA.\n */\nexport const BannerEntry: FC = () => {\n const {\n openModal,\n answers,\n progressiveProfileStatus,\n } = useProgressiveProfilingQuiz();\n const { formatMessage } = useIntl();\n const hasAttemptedAutoOpen = useRef(false);\n const { status, remainingQuestions } = progressiveProfileStatus || {};\n\n /*\n Auto-trigger the survey modal the very first time this user (on this browser/device) lands\n on the Search page with a not-started progressive profile. Once opened - regardless of\n whether the user completes, abandons, or closes it - it's flagged as \"seen\" for that user so\n it never auto-opens again, even if the backend status hasn't caught up yet (e.g. abandoned\n partway through, before any answers were saved).\n */\n useEffect(() => {\n if (hasAttemptedAutoOpen.current) return;\n if (!status || status !== PROGRESSIVE_PROFILING_USER_STATUS.NOT_STARTED) return;\n\n const autoOpenKey = getAutoOpenKey();\n if (!autoOpenKey) return; // No authenticated user available yet; try again next render.\n\n if (localStorage.getItem(autoOpenKey)) return;\n\n hasAttemptedAutoOpen.current = true;\n localStorage.setItem(autoOpenKey, 'true');\n openModal();\n }, [status, openModal]);\n\n if (!progressiveProfileStatus) return null;\n\n const learningGoal = answers?.['learning-goal']?.selectedValues?.[0]?.replaceAll('-', ' ');\n const interests = answers?.['interests-declared']?.selectedValues ?? [];\n const formattedInterests = interests.length > 1\n ? `${interests.slice(0, -1).join(', ')} and ${interests.at(-1)}`\n : interests[0];\n\n // Handle button click for the banner and track the click event\n const handleButtonClick = () => {\n openModal();\n trackProgressiveProfilingSearchPageBannerClick({ eventStatus: status });\n };\n\n let title: ReactNode = formatMessage(messages.notStartedTitle);\n let buttonText = formatMessage(messages.notStartedButtonText);\n\n if (status === PROGRESSIVE_PROFILING_USER_STATUS.COMPLETE) {\n title = formatMessage(messages.completeTitle, { learningGoal, interests: formattedInterests, bold: chunks => <strong>{chunks}</strong> });\n buttonText = formatMessage(messages.completeButtonText);\n }\n\n if (status === PROGRESSIVE_PROFILING_USER_STATUS.INCOMPLETE) {\n title = formatMessage(messages.incompleteTitle, { remainingQuestions });\n buttonText = formatMessage(messages.incompleteButtonText);\n }\n\n return <Banner onButtonClick={handleButtonClick} title={title} buttonText={buttonText} />;\n};\n"]}
@@ -27,7 +27,7 @@ const messages = defineMessages({
27
27
  },
28
28
  completeButtonText: {
29
29
  id: 'progressiveProfiling.searchPage.banner.complete.buttonText',
30
- defaultMessage: 'Share my goals',
30
+ defaultMessage: 'Update my goals',
31
31
  description: 'Button text to be shown on banner when the progressive profiling quiz is complete',
32
32
  },
33
33
  });
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/SearchPageBanners/messages.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,yDAAyD;QAC7D,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,sFAAsF;KACpG;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,8DAA8D;QAClE,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,4FAA4F;KAC1G;IACD,eAAe,EAAE;QACf,EAAE,EAAE,yDAAyD;QAC7D,cAAc,EAAE,iJAAiJ;QACjK,WAAW,EAAE,+EAA+E;KAC7F;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,8DAA8D;QAClE,cAAc,EAAE,yBAAyB;QACzC,WAAW,EAAE,qFAAqF;KACnG;IACD,aAAa,EAAE;QACb,EAAE,EAAE,uDAAuD;QAC3D,cAAc,EAAE,4FAA4F;QAC5G,WAAW,EAAE,6EAA6E;KAC3F;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,4DAA4D;QAChE,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,mFAAmF;KACjG;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n notStartedTitle: {\n id: 'progressiveProfiling.searchPage.banner.notStarted.title',\n defaultMessage: 'What do you want to learn?',\n description: 'Title to be shown on banner when the progressive profiling quiz has not been started',\n },\n notStartedButtonText: {\n id: 'progressiveProfiling.searchPage.banner.notStarted.buttonText',\n defaultMessage: 'Share my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz has not been started',\n },\n incompleteTitle: {\n id: 'progressiveProfiling.searchPage.banner.incomplete.title',\n defaultMessage: 'Answer {remainingQuestions, plural, =0 {# more question} one {# more question} other {# more questions}} and get better course recommendations.',\n description: 'Title to be shown on banner when the progressive profiling quiz is incomplete',\n },\n incompleteButtonText: {\n id: 'progressiveProfiling.searchPage.banner.incomplete.buttonText',\n defaultMessage: 'Finish sharing my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz is incomplete',\n },\n completeTitle: {\n id: 'progressiveProfiling.searchPage.banner.complete.title',\n defaultMessage: 'Your learning on edX to <bold>{learningGoal}</bold> and you\\'re interested in {interests}.',\n description: 'Title to be shown on banner when the progressive profiling quiz is complete',\n },\n completeButtonText: {\n id: 'progressiveProfiling.searchPage.banner.complete.buttonText',\n defaultMessage: 'Share my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz is complete',\n },\n});\n\nexport default messages;\n"]}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/SearchPageBanners/messages.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,yDAAyD;QAC7D,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,sFAAsF;KACpG;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,8DAA8D;QAClE,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,4FAA4F;KAC1G;IACD,eAAe,EAAE;QACf,EAAE,EAAE,yDAAyD;QAC7D,cAAc,EAAE,iJAAiJ;QACjK,WAAW,EAAE,+EAA+E;KAC7F;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,8DAA8D;QAClE,cAAc,EAAE,yBAAyB;QACzC,WAAW,EAAE,qFAAqF;KACnG;IACD,aAAa,EAAE;QACb,EAAE,EAAE,uDAAuD;QAC3D,cAAc,EAAE,4FAA4F;QAC5G,WAAW,EAAE,6EAA6E;KAC3F;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,4DAA4D;QAChE,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,mFAAmF;KACjG;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n notStartedTitle: {\n id: 'progressiveProfiling.searchPage.banner.notStarted.title',\n defaultMessage: 'What do you want to learn?',\n description: 'Title to be shown on banner when the progressive profiling quiz has not been started',\n },\n notStartedButtonText: {\n id: 'progressiveProfiling.searchPage.banner.notStarted.buttonText',\n defaultMessage: 'Share my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz has not been started',\n },\n incompleteTitle: {\n id: 'progressiveProfiling.searchPage.banner.incomplete.title',\n defaultMessage: 'Answer {remainingQuestions, plural, =0 {# more question} one {# more question} other {# more questions}} and get better course recommendations.',\n description: 'Title to be shown on banner when the progressive profiling quiz is incomplete',\n },\n incompleteButtonText: {\n id: 'progressiveProfiling.searchPage.banner.incomplete.buttonText',\n defaultMessage: 'Finish sharing my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz is incomplete',\n },\n completeTitle: {\n id: 'progressiveProfiling.searchPage.banner.complete.title',\n defaultMessage: 'Your learning on edX to <bold>{learningGoal}</bold> and you\\'re interested in {interests}.',\n description: 'Title to be shown on banner when the progressive profiling quiz is complete',\n },\n completeButtonText: {\n id: 'progressiveProfiling.searchPage.banner.complete.buttonText',\n defaultMessage: 'Update my goals',\n description: 'Button text to be shown on banner when the progressive profiling quiz is complete',\n },\n});\n\nexport default messages;\n"]}
@@ -8,6 +8,6 @@ export type ProgressiveProfilingQuizStepKey = typeof PROGRESSIVE_PROFILING_QUIZ_
8
8
  export declare const PROGRESSIVE_PROFILING_USER_STATUS: {
9
9
  readonly INCOMPLETE: "incomplete";
10
10
  readonly COMPLETE: "complete";
11
- readonly NOT_STARTED: "not-started";
11
+ readonly NOT_STARTED: "not_started";
12
12
  };
13
13
  export declare const getProgressiveProfilingStepName: (stepIndex: number) => ProgressiveProfilingQuizStepKey | undefined;
@@ -7,7 +7,7 @@ export const PROGRESSIVE_PROFILING_QUIZ_STEPS = {
7
7
  export const PROGRESSIVE_PROFILING_USER_STATUS = {
8
8
  INCOMPLETE: 'incomplete',
9
9
  COMPLETE: 'complete',
10
- NOT_STARTED: 'not-started',
10
+ NOT_STARTED: 'not_started',
11
11
  };
12
12
  export const getProgressiveProfilingStepName = (stepIndex) => (Object.values(PROGRESSIVE_PROFILING_QUIZ_STEPS)[stepIndex]);
13
13
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/data/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,aAAa,EAAE,eAAe;IAC9B,mBAAmB,EAAE,qBAAqB;IAC1C,kBAAkB,EAAE,oBAAoB;IACxC,WAAW,EAAE,aAAa;CAClB,CAAC;AAKX,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;CAClB,CAAC;AAEX,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,SAAiB,EAA+C,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC","sourcesContent":["export const PROGRESSIVE_PROFILING_QUIZ_STEPS = {\n LEARNING_GOAL: 'learning-goal',\n LEARNING_MOTIVATION: 'learning-motivation',\n INTERESTS_DECLARED: 'interests-declared',\n WORK_STATUS: 'work-status',\n} as const;\n\nexport type ProgressiveProfilingQuizStepKey =\n typeof PROGRESSIVE_PROFILING_QUIZ_STEPS[keyof typeof PROGRESSIVE_PROFILING_QUIZ_STEPS];\n\nexport const PROGRESSIVE_PROFILING_USER_STATUS = {\n INCOMPLETE: 'incomplete',\n COMPLETE: 'complete',\n NOT_STARTED: 'not-started',\n} as const;\n\nexport const getProgressiveProfilingStepName = (stepIndex: number): ProgressiveProfilingQuizStepKey | undefined => (Object.values(PROGRESSIVE_PROFILING_QUIZ_STEPS)[stepIndex]);\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/data/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,aAAa,EAAE,eAAe;IAC9B,mBAAmB,EAAE,qBAAqB;IAC1C,kBAAkB,EAAE,oBAAoB;IACxC,WAAW,EAAE,aAAa;CAClB,CAAC;AAKX,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;CAClB,CAAC;AAEX,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,SAAiB,EAA+C,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC","sourcesContent":["export const PROGRESSIVE_PROFILING_QUIZ_STEPS = {\n LEARNING_GOAL: 'learning-goal',\n LEARNING_MOTIVATION: 'learning-motivation',\n INTERESTS_DECLARED: 'interests-declared',\n WORK_STATUS: 'work-status',\n} as const;\n\nexport type ProgressiveProfilingQuizStepKey =\n typeof PROGRESSIVE_PROFILING_QUIZ_STEPS[keyof typeof PROGRESSIVE_PROFILING_QUIZ_STEPS];\n\nexport const PROGRESSIVE_PROFILING_USER_STATUS = {\n INCOMPLETE: 'incomplete',\n COMPLETE: 'complete',\n NOT_STARTED: 'not_started',\n} as const;\n\nexport const getProgressiveProfilingStepName = (stepIndex: number): ProgressiveProfilingQuizStepKey | undefined => (Object.values(PROGRESSIVE_PROFILING_QUIZ_STEPS)[stepIndex]);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edx/frontend-app-subscription-learner-dashboard",
3
- "version": "1.56.0",
3
+ "version": "1.57.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",