@edx/frontend-app-subscription-learner-dashboard 1.49.0 → 1.50.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.
- package/dist/containers/Dashboard/DashboardContent.d.ts +14 -1
- package/dist/containers/Dashboard/DashboardContent.js +11 -1
- package/dist/containers/Dashboard/DashboardContent.js.map +1 -1
- package/dist/containers/Dashboard/index.js +3 -1
- package/dist/containers/Dashboard/index.js.map +1 -1
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements.d.ts +17 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements.js +29 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements.js.map +1 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/messages.d.ts +43 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/messages.js +45 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/messages.js.map +1 -0
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingQuizProvider.js +2 -2
- package/dist/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingQuizProvider.js.map +1 -1
- package/dist/widgets/ProgressiveProfilingQuiz/data/api/fetchAnswers.d.ts +11 -1
- package/dist/widgets/ProgressiveProfilingQuiz/data/api/fetchAnswers.js +10 -4
- package/dist/widgets/ProgressiveProfilingQuiz/data/api/fetchAnswers.js.map +1 -1
- package/dist/widgets/ProgressiveProfilingQuiz/data/queryHooks.d.ts +2 -2
- package/dist/widgets/ProgressiveProfilingQuiz/data/queryHooks.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
export declare const DashboardContent: {
|
|
3
|
+
({ progressiveProfileStatus }: {
|
|
4
|
+
progressiveProfileStatus: any;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
propTypes: {
|
|
7
|
+
progressiveProfileStatus: PropTypes.Requireable<PropTypes.InferProps<{
|
|
8
|
+
status: PropTypes.Requireable<string>;
|
|
9
|
+
answeredQuestions: PropTypes.Requireable<number>;
|
|
10
|
+
totalQuestions: PropTypes.Requireable<number>;
|
|
11
|
+
remainingQuestions: PropTypes.Requireable<number>;
|
|
12
|
+
}>>;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
2
3
|
import { Row, Col } from '@openedx/paragon';
|
|
3
4
|
import DashboardTabs from './DashboardTabs';
|
|
4
|
-
|
|
5
|
+
import ProgressiveProfilingElements from '../../widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements';
|
|
6
|
+
export const DashboardContent = ({ progressiveProfileStatus }) => (_jsxs(Row, { children: [_jsx(Col, { xs: 12, lg: 8, children: _jsx(DashboardTabs, {}) }), _jsx(Col, { xs: 12, lg: 4, className: "mt-4", "data-testid": "dashboard-sidebar", children: _jsx("div", { className: "p-4", children: _jsx(ProgressiveProfilingElements, { progressiveProfileStatus: progressiveProfileStatus, orientation: "vertical" }) }) })] }));
|
|
7
|
+
DashboardContent.propTypes = {
|
|
8
|
+
progressiveProfileStatus: PropTypes.shape({
|
|
9
|
+
status: PropTypes.oneOf(['not_started', 'incomplete', 'complete']),
|
|
10
|
+
answeredQuestions: PropTypes.number,
|
|
11
|
+
totalQuestions: PropTypes.number,
|
|
12
|
+
remainingQuestions: PropTypes.number,
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
5
15
|
//# sourceMappingURL=DashboardContent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardContent.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardContent.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/DashboardContent.tsx"],"names":[],"mappings":";AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,4BAA4B,MAAM,iGAAiG,CAAC;AAE3I,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,wBAAwB,EAAE,EAAE,EAAE,CAAC,CAChE,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YAChB,KAAC,aAAa,KAAG,GACb,EACN,KAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,MAAM,iBAAa,mBAAmB,YAClE,cAAK,SAAS,EAAC,KAAK,YAClB,KAAC,4BAA4B,IAAC,wBAAwB,EAAE,wBAAwB,EAAE,WAAW,EAAC,UAAU,GAAG,GACvG,GACF,IACF,CACP,CAAC;AAEF,gBAAgB,CAAC,SAAS,GAAG;IAC3B,wBAAwB,EAAE,SAAS,CAAC,KAAK,CAAC;QACxC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QAClE,iBAAiB,EAAE,SAAS,CAAC,MAAM;QACnC,cAAc,EAAE,SAAS,CAAC,MAAM;QAChC,kBAAkB,EAAE,SAAS,CAAC,MAAM;KACrC,CAAC;CACH,CAAC","sourcesContent":["import PropTypes from 'prop-types';\nimport { Row, Col } from '@openedx/paragon';\nimport DashboardTabs from './DashboardTabs';\nimport ProgressiveProfilingElements from '@src/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements';\n\nexport const DashboardContent = ({ progressiveProfileStatus }) => (\n <Row>\n <Col xs={12} lg={8}>\n <DashboardTabs />\n </Col>\n <Col xs={12} lg={4} className=\"mt-4\" data-testid=\"dashboard-sidebar\">\n <div className=\"p-4\">\n <ProgressiveProfilingElements progressiveProfileStatus={progressiveProfileStatus} orientation=\"vertical\" />\n </div>\n </Col>\n </Row>\n);\n\nDashboardContent.propTypes = {\n progressiveProfileStatus: PropTypes.shape({\n status: PropTypes.oneOf(['not_started', 'incomplete', 'complete']),\n answeredQuestions: PropTypes.number,\n totalQuestions: PropTypes.number,\n remainingQuestions: PropTypes.number,\n }),\n};\n"]}
|
|
@@ -14,8 +14,10 @@ import './index.scss';
|
|
|
14
14
|
import { SubscriptionBanner } from '../SubscriptionBanner';
|
|
15
15
|
import { useInitializeSubsDashboard } from '../../data/hooks';
|
|
16
16
|
import DashboardHeroSlot from '../../slots/DashboardHeroSlot';
|
|
17
|
+
import { useAnswers } from '../../widgets/ProgressiveProfilingQuiz/data/queryHooks';
|
|
17
18
|
export const Dashboard = () => {
|
|
18
19
|
const { data, isPending } = useInitializeSubsCourseDashboard();
|
|
20
|
+
const { data: ProgressiveProfileStatus } = useAnswers();
|
|
19
21
|
const { data: learnerData } = useInitializeSubsDashboard();
|
|
20
22
|
const { pageTitle } = hooks.useDashboardMessages();
|
|
21
23
|
const { selectSessionModal } = useSelectSessionModal();
|
|
@@ -23,7 +25,7 @@ export const Dashboard = () => {
|
|
|
23
25
|
const learnerSubscriptionData = (learnerData === null || learnerData === void 0 ? void 0 : learnerData.userSubscription) || {};
|
|
24
26
|
const userSubscriptionStartDate = (learnerSubscriptionData === null || learnerSubscriptionData === void 0 ? void 0 : learnerSubscriptionData.subscriptionStartDate) || '';
|
|
25
27
|
const hasCourses = useMemo(() => { var _a; return ((_a = data === null || data === void 0 ? void 0 : data.subscriptionCourses) === null || _a === void 0 ? void 0 : _a.length) > 0; }, [data]);
|
|
26
|
-
return (_jsx("div", { id: "learnerdashboardroot", children: _jsx("main", { children: _jsxs("div", { id: "dashboard-container", className: "d-flex flex-column p-2 pt-0", children: [_jsx("h1", { className: "sr-only", children: pageTitle }), !isPending && (_jsxs(_Fragment, { children: [_jsx(DashboardModalSlot, {}), (hasCourses && showSelectSessionModal) && _jsx(SelectSessionModal, {})] })), _jsx("div", { id: "dashboard-content", "data-testid": "dashboard-content", children: _jsxs(DashboardLayout, { children: [_jsx(DashboardHeader, { startDate: userSubscriptionStartDate }), _jsx(SubscriptionBanner, { learnerSubscriptionData: learnerSubscriptionData }), _jsx(DashboardHeroSlot, {}), _jsx(DashboardContent, {}), _jsx(PopularCoursePanel, {}), _jsx(PopularProgramsPanel, {})] }) })] }) }) }));
|
|
28
|
+
return (_jsx("div", { id: "learnerdashboardroot", children: _jsx("main", { children: _jsxs("div", { id: "dashboard-container", className: "d-flex flex-column p-2 pt-0", children: [_jsx("h1", { className: "sr-only", children: pageTitle }), !isPending && (_jsxs(_Fragment, { children: [_jsx(DashboardModalSlot, {}), (hasCourses && showSelectSessionModal) && _jsx(SelectSessionModal, {})] })), _jsx("div", { id: "dashboard-content", "data-testid": "dashboard-content", children: _jsxs(DashboardLayout, { children: [_jsx(DashboardHeader, { startDate: userSubscriptionStartDate }), _jsx(SubscriptionBanner, { learnerSubscriptionData: learnerSubscriptionData }), _jsx(DashboardHeroSlot, {}), _jsx(DashboardContent, { progressiveProfileStatus: ProgressiveProfileStatus === null || ProgressiveProfileStatus === void 0 ? void 0 : ProgressiveProfileStatus.progressiveProfileStatus }), _jsx(PopularCoursePanel, {}), _jsx(PopularProgramsPanel, {})] }) })] }) }) }));
|
|
27
29
|
};
|
|
28
30
|
export default Dashboard;
|
|
29
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/index.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,kBAAkB,MAAM,gCAAgC,CAAC;AAChE,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAE3D,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/containers/Dashboard/index.jsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,kBAAkB,MAAM,gCAAgC,CAAC;AAChE,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAE3D,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,uDAAuD,CAAC;AAGnF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,gCAAgC,EAAE,CAAC;IAC/D,MAAM,EAAE,IAAI,EAAE,wBAAwB,EAAE,GAAG,UAAU,EAAE,CAAC;IACxD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,0BAA0B,EAAE,CAAC;IAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACnD,MAAM,EAAE,kBAAkB,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACvD,MAAM,sBAAsB,GAAG,kBAAkB,CAAC,MAAM,KAAK,IAAI,CAAC;IAClE,MAAM,uBAAuB,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,KAAI,EAAE,CAAC;IACpE,MAAM,yBAAyB,GAAG,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,qBAAqB,KAAI,EAAE,CAAC;IACvF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,WAAC,OAAA,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,0CAAE,MAAM,IAAG,CAAC,CAAA,EAAA,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhF,OAAO,CACL,cAAK,EAAE,EAAC,sBAAsB,YAC5B,yBACE,eAAK,EAAE,EAAC,qBAAqB,EAAC,SAAS,EAAC,6BAA6B,aACnE,aAAI,SAAS,EAAC,SAAS,YAAE,SAAS,GAAM,EACvC,CAAC,SAAS,IAAI,CACb,8BACE,KAAC,kBAAkB,KAAG,EACrB,CAAC,UAAU,IAAI,sBAAsB,CAAC,IAAI,KAAC,kBAAkB,KAAG,IAChE,CACJ,EACD,cAAK,EAAE,EAAC,mBAAmB,iBAAa,mBAAmB,YACzD,MAAC,eAAe,eACd,KAAC,eAAe,IAAC,SAAS,EAAE,yBAAyB,GAAI,EACzD,KAAC,kBAAkB,IAAC,uBAAuB,EAAE,uBAAuB,GAAI,EACxE,KAAC,iBAAiB,KAAG,EACrB,KAAC,gBAAgB,IAAC,wBAAwB,EAAE,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,wBAAwB,GAAG,EACjG,KAAC,kBAAkB,KAAG,EACtB,KAAC,oBAAoB,KAAG,IACR,GACd,IACF,GACD,GACH,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useMemo } from 'react';\nimport { DashboardHeader } from './DashboardHeader';\n\nimport { useSelectSessionModal } from '@src/data/context';\nimport { useInitializeSubsCourseDashboard } from '@src/data/hooks';\nimport SelectSessionModal from '../../containers/SelectSessionModal';\nimport { DashboardContent } from './DashboardContent';\nimport DashboardModalSlot from '../../slots/DashboardModalSlot';\nimport PopularCoursePanel from '../PopularCoursePanel';\nimport PopularProgramsPanel from '../PopularProgramsPanel';\n\nimport DashboardLayout from './DashboardLayout';\n\nimport hooks from './hooks';\nimport './index.scss';\nimport { SubscriptionBanner } from '../SubscriptionBanner';\nimport { useInitializeSubsDashboard } from '@src/data/hooks';\nimport DashboardHeroSlot from '@src/slots/DashboardHeroSlot';\nimport { useAnswers } from '@src/widgets/ProgressiveProfilingQuiz/data/queryHooks';\n\n\nexport const Dashboard = () => {\n const { data, isPending } = useInitializeSubsCourseDashboard();\n const { data: ProgressiveProfileStatus } = useAnswers();\n const { data: learnerData } = useInitializeSubsDashboard();\n const { pageTitle } = hooks.useDashboardMessages();\n const { selectSessionModal } = useSelectSessionModal();\n const showSelectSessionModal = selectSessionModal.cardId !== null;\n const learnerSubscriptionData = learnerData?.userSubscription || {};\n const userSubscriptionStartDate = learnerSubscriptionData?.subscriptionStartDate || '';\n const hasCourses = useMemo(() => data?.subscriptionCourses?.length > 0, [data]);\n\n return (\n <div id=\"learnerdashboardroot\">\n <main>\n <div id=\"dashboard-container\" className=\"d-flex flex-column p-2 pt-0\">\n <h1 className=\"sr-only\">{pageTitle}</h1>\n {!isPending && (\n <>\n <DashboardModalSlot />\n {(hasCourses && showSelectSessionModal) && <SelectSessionModal />}\n </>\n )}\n <div id=\"dashboard-content\" data-testid=\"dashboard-content\">\n <DashboardLayout>\n <DashboardHeader startDate={userSubscriptionStartDate} />\n <SubscriptionBanner learnerSubscriptionData={learnerSubscriptionData} />\n <DashboardHeroSlot />\n <DashboardContent progressiveProfileStatus={ProgressiveProfileStatus?.progressiveProfileStatus}/>\n <PopularCoursePanel />\n <PopularProgramsPanel />\n </DashboardLayout>\n </div>\n </div>\n </main>\n </div>\n );\n};\n\nexport default Dashboard;\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
declare const ProgressiveProfilingElements: {
|
|
3
|
+
({ progressiveProfileStatus, orientation }: {
|
|
4
|
+
progressiveProfileStatus: any;
|
|
5
|
+
orientation: any;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
propTypes: {
|
|
8
|
+
progressiveProfileStatus: PropTypes.Requireable<PropTypes.InferProps<{
|
|
9
|
+
status: PropTypes.Requireable<string>;
|
|
10
|
+
answeredQuestions: PropTypes.Requireable<number>;
|
|
11
|
+
totalQuestions: PropTypes.Requireable<number>;
|
|
12
|
+
remainingQuestions: PropTypes.Requireable<number>;
|
|
13
|
+
}>>;
|
|
14
|
+
orientation: PropTypes.Requireable<string>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export default ProgressiveProfilingElements;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import messages from './messages';
|
|
4
|
+
import { Card } from '@openedx/paragon';
|
|
5
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
6
|
+
import ActionButton from '../../../containers/CourseCard/components/CourseCardActions/ActionButton';
|
|
7
|
+
import { useProgressiveProfilingQuiz } from '../ProgressiveProfilingQuizProvider';
|
|
8
|
+
const ProgressiveProfilingElements = ({ progressiveProfileStatus, orientation }) => {
|
|
9
|
+
const { openModal } = useProgressiveProfilingQuiz();
|
|
10
|
+
const { formatMessage } = useIntl();
|
|
11
|
+
const { status, remainingQuestions, } = progressiveProfileStatus || {};
|
|
12
|
+
if (!progressiveProfileStatus)
|
|
13
|
+
return null;
|
|
14
|
+
const descriptionValues = Object.assign(Object.assign({}, (status === 'incomplete' && { remaining_questions: remainingQuestions })), (status === 'complete' && {
|
|
15
|
+
strong: (chunks) => _jsx("strong", { children: chunks }),
|
|
16
|
+
}));
|
|
17
|
+
return (_jsx("div", { "data-testid": "ProgressiveProfileStatus", children: _jsx(Card, { orientation: orientation, children: _jsxs("div", { className: "d-flex flex-column w-100 p-4", children: [status !== 'complete' && (_jsx("h6", { children: formatMessage(messages[`${status}_title`]) })), _jsx("p", { className: "small text-gray-700", children: formatMessage(messages[`${status}_description`], descriptionValues) }), _jsx(ActionButton, { variant: "outline-brand", size: "sm", style: { maxWidth: '12.5rem' }, onClick: openModal, children: formatMessage(messages[`${status}_button`]) })] }) }) }));
|
|
18
|
+
};
|
|
19
|
+
ProgressiveProfilingElements.propTypes = {
|
|
20
|
+
progressiveProfileStatus: PropTypes.shape({
|
|
21
|
+
status: PropTypes.oneOf(['not_started', 'incomplete', 'complete']),
|
|
22
|
+
answeredQuestions: PropTypes.number,
|
|
23
|
+
totalQuestions: PropTypes.number,
|
|
24
|
+
remainingQuestions: PropTypes.number,
|
|
25
|
+
}),
|
|
26
|
+
orientation: PropTypes.string,
|
|
27
|
+
};
|
|
28
|
+
export default ProgressiveProfilingElements;
|
|
29
|
+
//# sourceMappingURL=ProgressiveProfilingElements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressiveProfilingElements.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/ProgressiveProfilingElements.tsx"],"names":[],"mappings":";AACA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,YAAY,MAAM,sEAAsE,CAAC;AAChG,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,4BAA4B,GAAG,CAAC,EAAE,wBAAwB,EAAE,WAAW,EAAE,EAAE,EAAE;IACjF,MAAM,EAAE,SAAS,EAAE,GAAG,2BAA2B,EAAE,CAAC;IACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,MAAM,EACJ,MAAM,EACN,kBAAkB,GACnB,GAAG,wBAAwB,IAAI,EAAE,CAAC;IAEnC,IAAI,CAAC,wBAAwB;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,iBAAiB,mCAClB,CAAC,MAAM,KAAK,YAAY,IAAI,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,CAAC,GACxE,CAAC,MAAM,KAAK,UAAU,IAAI;QAC3B,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,2BAAS,MAAM,GAAU;KAC9C,CAAC,CACH,CAAC;IAEF,OAAO,CACL,6BAAiB,0BAA0B,YACzC,KAAC,IAAI,IAAC,WAAW,EAAE,WAAW,YAC5B,eAAK,SAAS,EAAC,8BAA8B,aAC1C,MAAM,KAAK,UAAU,IAAI,CACxB,uBAAK,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,GAAM,CACtD,EACD,YAAG,SAAS,EAAC,qBAAqB,YAC/B,aAAa,CACZ,QAAQ,CAAC,GAAG,MAAM,cAAc,CAAC,EACjC,iBAAiB,CAClB,GACC,EACJ,KAAC,YAAY,IACX,OAAO,EAAC,eAAe,EACvB,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAC9B,OAAO,EAAE,SAAS,YAEjB,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC,GAC/B,IACX,GACD,GACH,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,4BAA4B,CAAC,SAAS,GAAG;IACvC,wBAAwB,EAAE,SAAS,CAAC,KAAK,CAAC;QACxC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QAClE,iBAAiB,EAAE,SAAS,CAAC,MAAM;QACnC,cAAc,EAAE,SAAS,CAAC,MAAM;QAChC,kBAAkB,EAAE,SAAS,CAAC,MAAM;KACrC,CAAC;IACF,WAAW,EAAE,SAAS,CAAC,MAAM;CAC9B,CAAC;AAEF,eAAe,4BAA4B,CAAC","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport messages from './messages';\nimport { Card } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport ActionButton from '@src/containers/CourseCard/components/CourseCardActions/ActionButton';\nimport { useProgressiveProfilingQuiz } from '../ProgressiveProfilingQuizProvider';\n\nconst ProgressiveProfilingElements = ({ progressiveProfileStatus, orientation }) => {\n const { openModal } = useProgressiveProfilingQuiz();\n const { formatMessage } = useIntl();\n\n const {\n status,\n remainingQuestions,\n } = progressiveProfileStatus || {};\n\n if (!progressiveProfileStatus) return null;\n\n const descriptionValues = {\n ...(status === 'incomplete' && { remaining_questions: remainingQuestions }),\n ...(status === 'complete' && {\n strong: (chunks) => <strong>{chunks}</strong>,\n }),\n };\n\n return (\n <div data-testid=\"ProgressiveProfileStatus\">\n <Card orientation={orientation}>\n <div className=\"d-flex flex-column w-100 p-4\">\n {status !== 'complete' && (\n <h6>{formatMessage(messages[`${status}_title`])}</h6>\n )}\n <p className=\"small text-gray-700\">\n {formatMessage(\n messages[`${status}_description`],\n descriptionValues,\n )}\n </p>\n <ActionButton\n variant=\"outline-brand\"\n size=\"sm\"\n style={{ maxWidth: '12.5rem' }}\n onClick={openModal}\n >\n {formatMessage(messages[`${status}_button`])}\n </ActionButton>\n </div>\n </Card>\n </div>\n );\n};\n\nProgressiveProfilingElements.propTypes = {\n progressiveProfileStatus: PropTypes.shape({\n status: PropTypes.oneOf(['not_started', 'incomplete', 'complete']),\n answeredQuestions: PropTypes.number,\n totalQuestions: PropTypes.number,\n remainingQuestions: PropTypes.number,\n }),\n orientation: PropTypes.string,\n};\n\nexport default ProgressiveProfilingElements;\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
not_started_title: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
incomplete_title: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
not_started_description: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
incomplete_description: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
complete_description: {
|
|
23
|
+
id: string;
|
|
24
|
+
defaultMessage: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
not_started_button: {
|
|
28
|
+
id: string;
|
|
29
|
+
defaultMessage: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
incomplete_button: {
|
|
33
|
+
id: string;
|
|
34
|
+
defaultMessage: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
complete_button: {
|
|
38
|
+
id: string;
|
|
39
|
+
defaultMessage: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export default messages;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
not_started_title: {
|
|
4
|
+
id: 'progressiveProfilingQuiz.not_started.title',
|
|
5
|
+
defaultMessage: 'What is motivating you to study and learn on edx?',
|
|
6
|
+
description: 'Title for the progressive profiling quiz when not started',
|
|
7
|
+
},
|
|
8
|
+
incomplete_title: {
|
|
9
|
+
id: 'progressiveProfilingQuiz.incomplete.title',
|
|
10
|
+
defaultMessage: 'What do you want to learn?',
|
|
11
|
+
description: 'Title for the progressive profiling quiz when incomplete',
|
|
12
|
+
},
|
|
13
|
+
not_started_description: {
|
|
14
|
+
id: 'progressiveProfilingQuiz.not_started.description',
|
|
15
|
+
defaultMessage: 'Tell us what more about you and get better course recommendations.',
|
|
16
|
+
description: 'Description for the progressive profiling quiz when not started',
|
|
17
|
+
},
|
|
18
|
+
incomplete_description: {
|
|
19
|
+
id: 'progressiveProfilingQuiz.incomplete.description',
|
|
20
|
+
defaultMessage: 'Answer {remaining_questions, plural, one {# more question} other {# more questions}} and get better course recommendations.',
|
|
21
|
+
description: 'Description for the progressive profiling quiz when incomplete',
|
|
22
|
+
},
|
|
23
|
+
complete_description: {
|
|
24
|
+
id: 'progressiveProfilingQuiz.complete.description',
|
|
25
|
+
defaultMessage: 'Your learning on edX to <strong>advance your career</strong> and you’re interested in Business & Management and Leadership.',
|
|
26
|
+
description: 'Description for the progressive profiling quiz when complete',
|
|
27
|
+
},
|
|
28
|
+
not_started_button: {
|
|
29
|
+
id: 'progressiveProfilingQuiz.not_started.button',
|
|
30
|
+
defaultMessage: 'Share my goals',
|
|
31
|
+
description: 'Button text for the progressive profiling quiz when not started',
|
|
32
|
+
},
|
|
33
|
+
incomplete_button: {
|
|
34
|
+
id: 'progressiveProfilingQuiz.incomplete.button',
|
|
35
|
+
defaultMessage: 'Finish sharing my goals',
|
|
36
|
+
description: 'Button text for the progressive profiling quiz when incomplete',
|
|
37
|
+
},
|
|
38
|
+
complete_button: {
|
|
39
|
+
id: 'progressiveProfilingQuiz.complete.button',
|
|
40
|
+
defaultMessage: 'Update my goals',
|
|
41
|
+
description: 'Button text for the progressive profiling quiz when complete',
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
export default messages;
|
|
45
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingElements/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,iBAAiB,EAAE;QACjB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,mDAAmD;QACnE,WAAW,EAAE,2DAA2D;KACzE;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,0DAA0D;KACxE;IACD,uBAAuB,EAAE;QACvB,EAAE,EAAE,kDAAkD;QACtD,cAAc,EAAE,oEAAoE;QACpF,WAAW,EAAE,iEAAiE;KAC/E;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,iDAAiD;QACrD,cAAc,EACN,6HAA6H;QACrI,WAAW,EAAE,gEAAgE;KAC9E;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,6HAA6H;QAC7I,WAAW,EAAE,8DAA8D;KAC5E;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,6CAA6C;QACjD,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,iEAAiE;KAC/E;IACD,iBAAiB,EAAE;QACjB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,yBAAyB;QACzC,WAAW,EAAE,gEAAgE;KAC9E;IACD,eAAe,EAAE;QACf,EAAE,EAAE,0CAA0C;QAC9C,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,8DAA8D;KAC5E;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n not_started_title: {\n id: 'progressiveProfilingQuiz.not_started.title',\n defaultMessage: 'What is motivating you to study and learn on edx?',\n description: 'Title for the progressive profiling quiz when not started',\n },\n incomplete_title: {\n id: 'progressiveProfilingQuiz.incomplete.title',\n defaultMessage: 'What do you want to learn?',\n description: 'Title for the progressive profiling quiz when incomplete',\n },\n not_started_description: {\n id: 'progressiveProfilingQuiz.not_started.description',\n defaultMessage: 'Tell us what more about you and get better course recommendations.',\n description: 'Description for the progressive profiling quiz when not started',\n },\n incomplete_description: {\n id: 'progressiveProfilingQuiz.incomplete.description',\n defaultMessage:\n 'Answer {remaining_questions, plural, one {# more question} other {# more questions}} and get better course recommendations.',\n description: 'Description for the progressive profiling quiz when incomplete',\n },\n complete_description: {\n id: 'progressiveProfilingQuiz.complete.description',\n defaultMessage: 'Your learning on edX to <strong>advance your career</strong> and you’re interested in Business & Management and Leadership.',\n description: 'Description for the progressive profiling quiz when complete',\n },\n not_started_button: {\n id: 'progressiveProfilingQuiz.not_started.button',\n defaultMessage: 'Share my goals',\n description: 'Button text for the progressive profiling quiz when not started',\n },\n incomplete_button: {\n id: 'progressiveProfilingQuiz.incomplete.button',\n defaultMessage: 'Finish sharing my goals',\n description: 'Button text for the progressive profiling quiz when incomplete',\n },\n complete_button: {\n id: 'progressiveProfilingQuiz.complete.button',\n defaultMessage: 'Update my goals',\n description: 'Button text for the progressive profiling quiz when complete',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -10,8 +10,8 @@ export const ProgressiveProfilingQuizProvider = ({ children }) => {
|
|
|
10
10
|
const { data: storedAnswers } = useAnswers();
|
|
11
11
|
const { mutate: saveAnswers } = useSaveAnswers();
|
|
12
12
|
useEffect(() => {
|
|
13
|
-
if (storedAnswers) {
|
|
14
|
-
setAnswers(prev => (Object.assign(Object.assign({}, storedAnswers), prev)));
|
|
13
|
+
if (storedAnswers === null || storedAnswers === void 0 ? void 0 : storedAnswers.answers) {
|
|
14
|
+
setAnswers(prev => (Object.assign(Object.assign({}, storedAnswers.answers), prev)));
|
|
15
15
|
}
|
|
16
16
|
}, [storedAnswers]);
|
|
17
17
|
const openModal = useCallback(() => setIsModalOpen(true), []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressiveProfilingQuizProvider.js","sourceRoot":"","sources":["../../../src/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingQuizProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EACZ,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAa,WAAW,GAChF,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAiB/D,MAAM,+BAA+B,GAAG,aAAa,CAA6C,IAAI,CAAC,CAAC;AAMxG,MAAM,CAAC,MAAM,gCAAgC,GAAoD,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IAChH,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAwD,EAAE,CAAC,CAAC;IAClG,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,UAAU,EAAE,CAAC;IAC7C,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"ProgressiveProfilingQuizProvider.js","sourceRoot":"","sources":["../../../src/widgets/ProgressiveProfilingQuiz/ProgressiveProfilingQuizProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n createContext, useContext, useEffect, useMemo, useState, ReactNode, useCallback,\n} from 'react';\n\nimport { StoredAnswerRecord } from './data/api/fetchAnswers';\nimport { useAnswers, useSaveAnswers } from './data/queryHooks';\nimport { QuizAnswerRecord } from './data/types';\n\ninterface ProgressiveProfilingQuizContextType {\n isModalOpen: boolean,\n openModal: () => void,\n closeModal: () => void,\n currentStep: number,\n setCurrentStep: (step: number) => void,\n goToNextStep: () => void,\n goToPreviousStep: () => void,\n answers: Record<string, QuizAnswerRecord | StoredAnswerRecord>,\n recordAnswer: (answer: QuizAnswerRecord) => void,\n isComplete: boolean,\n setIsComplete: (isComplete: boolean) => void,\n}\n\nconst ProgressiveProfilingQuizContext = createContext<ProgressiveProfilingQuizContextType | null>(null);\n\ninterface ProgressiveProfilingQuizProviderProps {\n children: ReactNode,\n}\n\nexport const ProgressiveProfilingQuizProvider: React.FC<ProgressiveProfilingQuizProviderProps> = ({ children }) => {\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [currentStep, setCurrentStep] = useState(0);\n const [answers, setAnswers] = useState<Record<string, QuizAnswerRecord | StoredAnswerRecord>>({});\n const [isComplete, setIsComplete] = useState(false);\n\n const { data: storedAnswers } = useAnswers();\n const { mutate: saveAnswers } = useSaveAnswers();\n\n useEffect(() => {\n if (storedAnswers?.answers) {\n setAnswers(prev => ({ ...storedAnswers.answers, ...prev }));\n }\n }, [storedAnswers]);\n\n const openModal = useCallback(() => setIsModalOpen(true), []);\n const closeModal = useCallback(() => {\n setIsModalOpen(false);\n if (Object.keys(answers).length > 0) {\n saveAnswers(answers);\n }\n }, [answers, saveAnswers]);\n\n const goToNextStep = useCallback(() => setCurrentStep(prev => prev + 1), []);\n const goToPreviousStep = useCallback(() => setCurrentStep(prev => Math.max(0, prev - 1)), []);\n\n const recordAnswer = useCallback((answer: QuizAnswerRecord) => {\n setAnswers(prev => ({ ...prev, [answer.questionId]: answer }));\n }, []);\n\n const contextValue = useMemo(() => ({\n isModalOpen,\n openModal,\n closeModal,\n currentStep,\n setCurrentStep,\n goToNextStep,\n goToPreviousStep,\n answers,\n recordAnswer,\n isComplete,\n setIsComplete,\n }), [\n isModalOpen, openModal, closeModal,\n currentStep, goToNextStep, goToPreviousStep,\n answers, recordAnswer,\n isComplete,\n ]);\n\n return (\n <ProgressiveProfilingQuizContext.Provider value={contextValue}>\n {children}\n </ProgressiveProfilingQuizContext.Provider>\n );\n};\n\nexport const useProgressiveProfilingQuiz = (): ProgressiveProfilingQuizContextType => {\n const context = useContext(ProgressiveProfilingQuizContext);\n if (!context) {\n throw new Error('useProgressiveProfilingQuiz must be used within a ProgressiveProfilingQuizProvider');\n }\n return context;\n};\n"]}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { QuizAnswerRecord } from '../types';
|
|
2
2
|
/** What's actually stored by saveAnswers: a QuizAnswerRecord minus the options it omits. */
|
|
3
3
|
export type StoredAnswerRecord = Omit<QuizAnswerRecord, 'options'>;
|
|
4
|
+
export interface ProgressiveProfileStatus {
|
|
5
|
+
status: string;
|
|
6
|
+
answeredQuestions: number;
|
|
7
|
+
totalQuestions: number;
|
|
8
|
+
remainingQuestions: number;
|
|
9
|
+
}
|
|
10
|
+
export interface FetchAnswersResult {
|
|
11
|
+
answers: Record<string, StoredAnswerRecord>;
|
|
12
|
+
progressiveProfileStatus?: ProgressiveProfileStatus;
|
|
13
|
+
}
|
|
4
14
|
/**
|
|
5
15
|
* Retrieves whatever quiz answers were previously persisted via saveAnswers. Returns an empty
|
|
6
16
|
* object if the user hasn't answered yet (no 'progressive_profile' extended profile field on
|
|
@@ -12,4 +22,4 @@ export type StoredAnswerRecord = Omit<QuizAnswerRecord, 'options'>;
|
|
|
12
22
|
* questionId field nested inside the record is a value, not a key, so it isn't mangled and can be
|
|
13
23
|
* used to key the result the same way session-recorded answers already are.
|
|
14
24
|
*/
|
|
15
|
-
export declare const fetchAnswers: () => Promise<
|
|
25
|
+
export declare const fetchAnswers: () => Promise<FetchAnswersResult>;
|
|
@@ -26,9 +26,15 @@ export const fetchAnswers = () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
26
26
|
const extendedProfile = (_a = data.extended_profile) !== null && _a !== void 0 ? _a : [];
|
|
27
27
|
const progressiveProfile = extendedProfile.find((field) => field.field_name === 'progressive_profile');
|
|
28
28
|
const storedAnswers = ((_b = progressiveProfile === null || progressiveProfile === void 0 ? void 0 : progressiveProfile.field_value) !== null && _b !== void 0 ? _b : {});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const progressiveProfileStatus = data.progressive_profile_status
|
|
30
|
+
? camelCaseObject(data.progressive_profile_status)
|
|
31
|
+
: undefined;
|
|
32
|
+
return {
|
|
33
|
+
answers: Object.fromEntries(Object.values(storedAnswers).map((record) => {
|
|
34
|
+
const camelCasedRecord = camelCaseObject(record);
|
|
35
|
+
return [camelCasedRecord.questionId, camelCasedRecord];
|
|
36
|
+
})),
|
|
37
|
+
progressiveProfileStatus,
|
|
38
|
+
};
|
|
33
39
|
});
|
|
34
40
|
//# sourceMappingURL=fetchAnswers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchAnswers.js","sourceRoot":"","sources":["../../../../../src/widgets/ProgressiveProfilingQuiz/data/api/fetchAnswers.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,0BAA0B,EAAE,oBAAoB,EAAE,aAAa,EAAE,eAAe,GACjF,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetchAnswers.js","sourceRoot":"","sources":["../../../../../src/widgets/ProgressiveProfilingQuiz/data/api/fetchAnswers.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,0BAA0B,EAAE,oBAAoB,EAAE,aAAa,EAAE,eAAe,GACjF,MAAM,wBAAwB,CAAC;AAwBhC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAsC,EAAE;;IAClE,MAAM,EAAE,QAAQ,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAE5C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,CAAC,UAAU,yBAAyB,QAAQ,EAAE,CACjE,CAAC;IAEF,MAAM,eAAe,GAA2B,MAAA,IAAI,CAAC,gBAAgB,mCAAI,EAAE,CAAC;IAC5E,MAAM,kBAAkB,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,qBAAqB,CAAC,CAAC;IACvG,MAAM,aAAa,GAAG,CAAC,MAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,WAAW,mCAAI,EAAE,CAA4B,CAAC;IACzF,MAAM,wBAAwB,GAAG,IAAI,CAAC,0BAA0B;QAC9D,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,0BAA0B,CAA6B;QAC9E,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,WAAW,CACzB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC1C,MAAM,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAAuB,CAAC;YACvE,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;QACzD,CAAC,CAAC,CACH;QACD,wBAAwB;KACzB,CAAC;AACJ,CAAC,CAAA,CAAC","sourcesContent":["import {\n getAuthenticatedHttpClient, getAuthenticatedUser, getSiteConfig, camelCaseObject,\n} from '@openedx/frontend-base';\n\nimport { QuizAnswerRecord } from '../types';\n\n/** What's actually stored by saveAnswers: a QuizAnswerRecord minus the options it omits. */\nexport type StoredAnswerRecord = Omit<QuizAnswerRecord, 'options'>;\n\ninterface ExtendedProfileField {\n field_name: string,\n field_value: unknown,\n}\n\nexport interface ProgressiveProfileStatus {\n status: string,\n answeredQuestions: number,\n totalQuestions: number,\n remainingQuestions: number,\n}\n\nexport interface FetchAnswersResult {\n answers: Record<string, StoredAnswerRecord>,\n progressiveProfileStatus?: ProgressiveProfileStatus,\n}\n\n/**\n * Retrieves whatever quiz answers were previously persisted via saveAnswers. Returns an empty\n * object if the user hasn't answered yet (no 'progressive_profile' extended profile field on\n * their account).\n *\n * Keyed by each record's own questionId field rather than the map's own (outer) key: saveAnswers\n * snake-cases the whole answers map - including its outer keys - before sending it, so a\n * kebab-case questionId like 'learning-goal' comes back from storage as 'learning_goal'. The\n * questionId field nested inside the record is a value, not a key, so it isn't mangled and can be\n * used to key the result the same way session-recorded answers already are.\n */\nexport const fetchAnswers = async (): Promise<FetchAnswersResult> => {\n const { username } = getAuthenticatedUser();\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getSiteConfig().lmsBaseUrl}/api/user/v1/accounts/${username}`,\n );\n\n const extendedProfile: ExtendedProfileField[] = data.extended_profile ?? [];\n const progressiveProfile = extendedProfile.find((field) => field.field_name === 'progressive_profile');\n const storedAnswers = (progressiveProfile?.field_value ?? {}) as Record<string, unknown>;\n const progressiveProfileStatus = data.progressive_profile_status\n ? camelCaseObject(data.progressive_profile_status) as ProgressiveProfileStatus\n : undefined;\n\n return {\n answers: Object.fromEntries(\n Object.values(storedAnswers).map((record) => {\n const camelCasedRecord = camelCaseObject(record) as StoredAnswerRecord;\n return [camelCasedRecord.questionId, camelCasedRecord];\n }),\n ),\n progressiveProfileStatus,\n };\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
-
import { StoredAnswerRecord } from './api/fetchAnswers';
|
|
2
|
+
import { FetchAnswersResult, StoredAnswerRecord } from './api/fetchAnswers';
|
|
3
3
|
import { QuizAnswerRecord, SkillWithCount } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Fetches every skill value in the Algolia product index, cached for reuse by any
|
|
@@ -9,7 +9,7 @@ export declare const useSkills: () => UseQueryResult<SkillWithCount[]>;
|
|
|
9
9
|
/**
|
|
10
10
|
* Retrieves whatever quiz answers were previously persisted via saveAnswers
|
|
11
11
|
*/
|
|
12
|
-
export declare const useAnswers: () => UseQueryResult<
|
|
12
|
+
export declare const useAnswers: () => UseQueryResult<FetchAnswersResult>;
|
|
13
13
|
/**
|
|
14
14
|
* Persists whatever quiz answers have been recorded so far, whether the user finished every
|
|
15
15
|
* step or abandoned partway through.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryHooks.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/data/queryHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"queryHooks.js","sourceRoot":"","sources":["../../../../src/widgets/ProgressiveProfilingQuiz/data/queryHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAA0C,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,oCAAoC,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAGtG;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAqC,EAAE;IAC9D,MAAM,CAAC,YAAY,CAAC,GAAG,gBAAgB,EAAE,CAAC;IAE1C,OAAO,QAAQ,CAAC;QACd,QAAQ,EAAE,iCAAiC,CAAC,MAAM,EAAE;QACpD,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,YAAa,CAAC;QACzC,OAAO,EAAE,CAAC,CAAC,YAAY;QACvB,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAC1B,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAuC,EAAE,CAAC,QAAQ,CAAC;IAC3E,QAAQ,EAAE,iCAAiC,CAAC,OAAO,EAAE;IACrD,OAAO,EAAE,YAAY;CACtB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC;IAC9C,WAAW,EAAE,oCAAoC,CAAC,WAAW,EAAE;IAC/D,UAAU,EAAE,CAAC,OAA8D,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC;IACpG,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACjB,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { useMutation, useQuery, UseQueryResult } from '@tanstack/react-query';\nimport { logError } from '@openedx/frontend-base';\n\nimport { useAlgoliaSearch } from '@src/utils/algoliaUtils';\n\nimport { fetchAnswers, FetchAnswersResult, StoredAnswerRecord } from './api/fetchAnswers';\nimport { fetchSkills } from './api/fetchSkills';\nimport { saveAnswers } from './api/saveAnswers';\nimport { progressiveProfilingQuizMutationKeys, progressiveProfilingQuizQueryKeys } from './queryKeys';\nimport { QuizAnswerRecord, SkillWithCount } from './types';\n\n/**\n * Fetches every skill value in the Algolia product index, cached for reuse by any\n * question whose options are the skills list (e.g. 'preferred-subject').\n */\nexport const useSkills = (): UseQueryResult<SkillWithCount[]> => {\n const [searchClient] = useAlgoliaSearch();\n\n return useQuery({\n queryKey: progressiveProfilingQuizQueryKeys.skills(),\n queryFn: () => fetchSkills(searchClient!),\n enabled: !!searchClient,\n staleTime: 10 * 60 * 1000,\n });\n};\n\n/**\n * Retrieves whatever quiz answers were previously persisted via saveAnswers\n */\nexport const useAnswers = (): UseQueryResult<FetchAnswersResult> => useQuery({\n queryKey: progressiveProfilingQuizQueryKeys.answers(),\n queryFn: fetchAnswers,\n});\n\n/**\n * Persists whatever quiz answers have been recorded so far, whether the user finished every\n * step or abandoned partway through.\n */\nexport const useSaveAnswers = () => useMutation({\n mutationKey: progressiveProfilingQuizMutationKeys.saveAnswers(),\n mutationFn: (answers: Record<string, QuizAnswerRecord | StoredAnswerRecord>) => saveAnswers(answers),\n onError: (error) => {\n logError(error);\n },\n});\n"]}
|