@nualang/nualang-ui-components 0.1.1170 → 0.1.1172

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/Chat/Chat.js CHANGED
@@ -94,7 +94,8 @@ function Chat({
94
94
  currentMessage,
95
95
  roleplayImage,
96
96
  siteLanguage,
97
- answerCounts
97
+ answerCounts,
98
+ noAnswerCounts
98
99
  }) {
99
100
  const {
100
101
  classes
@@ -155,7 +156,8 @@ function Chat({
155
156
  currentMessage: currentMessage,
156
157
  roleplayImage: roleplayImage,
157
158
  siteLanguage: siteLanguage,
158
- answerCounts: answerCounts
159
+ answerCounts: answerCounts,
160
+ noAnswerCounts: noAnswerCounts
159
161
  }), !hideBottomBar && !viewAttemptMode && /*#__PURE__*/_react.default.createElement(_BottomBar.default, {
160
162
  t: t,
161
163
  inputName: inputName,
@@ -58,6 +58,7 @@ function Messages({
58
58
  roleplayImage,
59
59
  siteLanguage,
60
60
  answerCounts,
61
+ noAnswerCounts,
61
62
  moveScriptItem,
62
63
  ...otherProps
63
64
  }) {
@@ -163,6 +164,7 @@ function Messages({
163
164
  handleContinue: handleContinue,
164
165
  isCurrentMessage: isCurrentMessage,
165
166
  answerCounts: answerCounts,
167
+ noAnswerCounts: noAnswerCounts,
166
168
  messages: messages,
167
169
  moveScriptItem: moveScriptItem,
168
170
  provided: provided
@@ -188,7 +190,8 @@ function Messages({
188
190
  siteLanguage: siteLanguage,
189
191
  moveScriptItem: moveScriptItem,
190
192
  provided: provided
191
- }, m, otherProps)))) : /*#__PURE__*/_react.default.createElement("div", null, m?.question && !isLivePlayer ? /*#__PURE__*/_react.default.createElement(_Question.default, _extends({
193
+ }, m, otherProps)))) : /*#__PURE__*/_react.default.createElement("div", null, m?.question && !isLivePlayer && /*#__PURE__*/_react.default.createElement(_Question.default, _extends({
194
+ t: t,
192
195
  languageTag: languageTag,
193
196
  key: `messx_${i}`,
194
197
  messageIndex: i,
@@ -205,8 +208,10 @@ function Messages({
205
208
  handleContinue: handleContinue,
206
209
  isCurrentMessage: isCurrentMessage,
207
210
  answerCounts: answerCounts,
211
+ noAnswerCounts: noAnswerCounts,
208
212
  messages: messages
209
- }, m, otherProps)) : /*#__PURE__*/_react.default.createElement(_Message.default, _extends({
213
+ }, m, otherProps)), !m?.question && /*#__PURE__*/_react.default.createElement(_Message.default, _extends({
214
+ t: t,
210
215
  languageTag: languageTag,
211
216
  key: `messy_${i}`,
212
217
  disableTranslation: disableTranslation,
@@ -9,6 +9,7 @@ var _mui = require("tss-react/mui");
9
9
  var _RadioButtonUnchecked = _interopRequireDefault(require("@mui/icons-material/RadioButtonUnchecked"));
10
10
  var _Check = _interopRequireDefault(require("@mui/icons-material/Check"));
11
11
  var _Cancel = _interopRequireDefault(require("@mui/icons-material/Cancel"));
12
+ var _RemoveCircleOutlined = _interopRequireDefault(require("@mui/icons-material/RemoveCircleOutlined"));
12
13
  var _Delete = _interopRequireDefault(require("@mui/icons-material/Delete"));
13
14
  var _Create = _interopRequireDefault(require("@mui/icons-material/Create"));
14
15
  var _Circle = _interopRequireDefault(require("@mui/icons-material/Circle"));
@@ -56,6 +57,9 @@ const useStyles = (0, _mui.makeStyles)()(theme => ({
56
57
  },
57
58
  incorrect: {
58
59
  color: theme.palette.error.main
60
+ },
61
+ noAnswer: {
62
+ color: "#757575"
59
63
  }
60
64
  }));
61
65
  function Answers({
@@ -75,6 +79,7 @@ function Answers({
75
79
  isAnswered,
76
80
  handleContinue,
77
81
  answerCounts,
82
+ noAnswerCounts,
78
83
  messages,
79
84
  messageIndex
80
85
  }) {
@@ -114,6 +119,14 @@ function Answers({
114
119
  setIsLoading(false);
115
120
  }
116
121
  }, [answerCounts, showResults]);
122
+ (0, _react.useEffect)(() => {
123
+ if (showResults && noAnswerCounts > 0) {
124
+ const totalAnswerVotes = Object.values(answerCounts).reduce((sum, count) => sum + count, 0);
125
+ const totalVotesIncludingNoAnswer = totalAnswerVotes + (noAnswerCounts || 0);
126
+ setTotalVotes(totalVotesIncludingNoAnswer);
127
+ setIsLoading(false);
128
+ }
129
+ }, [answerCounts, noAnswerCounts, showResults]);
117
130
  if (isLoading && showResults) {
118
131
  return null;
119
132
  }
@@ -156,9 +169,42 @@ function Answers({
156
169
  }) : /*#__PURE__*/_react.default.createElement(_Cancel.default, {
157
170
  className: classes.incorrect
158
171
  }),
159
- checked: true
172
+ checked: true,
173
+ disableRipple: true
160
174
  })
161
175
  });
176
+ }), noAnswerCounts > 0 && /*#__PURE__*/_react.default.createElement(_material.FormControlLabel, {
177
+ label: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, t("no_answer"), /*#__PURE__*/_react.default.createElement(_material.Box, {
178
+ sx: {
179
+ mt: 0.5,
180
+ mb: 0.5
181
+ }
182
+ }, /*#__PURE__*/_react.default.createElement(_material.LinearProgress, {
183
+ variant: "determinate",
184
+ value: totalVotes > 0 ? noAnswerCounts / totalVotes * 100 : 0,
185
+ sx: {
186
+ height: 6,
187
+ width: 240
188
+ }
189
+ }), /*#__PURE__*/_react.default.createElement(_material.Typography, {
190
+ variant: "caption",
191
+ sx: {
192
+ mt: 0.5,
193
+ mb: 0.5
194
+ }
195
+ }, t(noAnswerCounts + ` vote${noAnswerCounts === 1 ? "" : "s"}`)))),
196
+ value: t("no_answer"),
197
+ control: /*#__PURE__*/_react.default.createElement(_material.Radio, {
198
+ color: "default",
199
+ icon: /*#__PURE__*/_react.default.createElement(_RemoveCircleOutlined.default, {
200
+ className: classes.noAnswer
201
+ }),
202
+ checkedIcon: /*#__PURE__*/_react.default.createElement(_RemoveCircleOutlined.default, {
203
+ className: classes.noAnswer
204
+ }),
205
+ checked: true,
206
+ disableRipple: true
207
+ })
162
208
  })) : /*#__PURE__*/_react.default.createElement(_material.RadioGroup, {
163
209
  className: classes.list
164
210
  }, answers.map((value, i) => {
@@ -178,7 +224,8 @@ function Answers({
178
224
  }) : /*#__PURE__*/_react.default.createElement(_Cancel.default, {
179
225
  className: classes.incorrect
180
226
  }),
181
- checked: true
227
+ checked: true,
228
+ disableRipple: true
182
229
  })
183
230
  });
184
231
  })) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isAnswered && selected ? /*#__PURE__*/_react.default.createElement(_material.Box, {
@@ -272,6 +319,7 @@ function Question({
272
319
  isAnswered,
273
320
  handleContinue,
274
321
  answerCounts,
322
+ noAnswerCounts,
275
323
  messages,
276
324
  provided
277
325
  }) {
@@ -378,6 +426,7 @@ function Question({
378
426
  answerAttempts: answerAttempts,
379
427
  showResults: true,
380
428
  answerCounts: answerCounts,
429
+ noAnswerCounts: noAnswerCounts,
381
430
  messages: messages,
382
431
  messageIndex: messageIndex
383
432
  }))), moveScriptItem && /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
@@ -11,6 +11,9 @@ var _styles = require("@mui/material/styles");
11
11
  var _mui = require("tss-react/mui");
12
12
  var _useMediaQuery = _interopRequireDefault(require("@mui/material/useMediaQuery"));
13
13
  var _Star = _interopRequireDefault(require("@mui/icons-material/Star"));
14
+ var _Search = _interopRequireDefault(require("@mui/icons-material/Search"));
15
+ var _InputBase = _interopRequireDefault(require("@mui/material/InputBase"));
16
+ var _InputAdornment = _interopRequireDefault(require("@mui/material/InputAdornment"));
14
17
  var _Header = _interopRequireDefault(require("../../Navigation/Header"));
15
18
  var _ResponsiveDrawer = _interopRequireDefault(require("../../Navigation/ResponsiveDrawer"));
16
19
  var _BottomBar = _interopRequireDefault(require("../../Navigation/BottomBar/BottomBar"));
@@ -22,6 +25,8 @@ var _Snackbar = _interopRequireDefault(require("../../Misc/Snackbar"));
22
25
  var _School = _interopRequireDefault(require("@mui/icons-material/School"));
23
26
  var _BubbleChart = _interopRequireDefault(require("@mui/icons-material/BubbleChart"));
24
27
  var _Add = _interopRequireDefault(require("@mui/icons-material/Add"));
28
+ var _ArrowBack = _interopRequireDefault(require("@mui/icons-material/ArrowBack"));
29
+ var _Close = _interopRequireDefault(require("@mui/icons-material/Close"));
25
30
  var _UpgradeSubscription = _interopRequireDefault(require("../../Dialogs/UpgradeSubscription/UpgradeSubscription"));
26
31
  var _nav = _interopRequireDefault(require("../../Navigation/_nav"));
27
32
  var _material = require("@mui/material");
@@ -55,6 +60,91 @@ const useStyles = (0, _mui.makeStyles)()((theme, {
55
60
  marginTop: `env(safe-area-inset-top)`
56
61
  }
57
62
  }));
63
+ const Search = (0, _styles.styled)("div")(({
64
+ theme
65
+ }) => ({
66
+ position: "relative",
67
+ borderRadius: theme.shape.borderRadius,
68
+ backgroundColor: (0, _styles.alpha)(theme.palette.common.white, 0.15),
69
+ "&:hover": {
70
+ backgroundColor: (0, _styles.alpha)(theme.palette.common.white, 0.25)
71
+ },
72
+ marginLeft: theme.spacing(1),
73
+ marginRight: theme.spacing(1),
74
+ width: "100%",
75
+ [theme.breakpoints.up("md")]: {
76
+ width: "auto"
77
+ }
78
+ }));
79
+ const SearchIconWrapper = (0, _styles.styled)("div")(({
80
+ theme
81
+ }) => ({
82
+ padding: theme.spacing(0, 2),
83
+ height: "100%",
84
+ position: "absolute",
85
+ pointerEvents: "none",
86
+ display: "flex",
87
+ alignItems: "center",
88
+ justifyContent: "center"
89
+ }));
90
+ const StyledInputBase = (0, _styles.styled)(_InputBase.default)(({
91
+ theme
92
+ }) => ({
93
+ color: "inherit",
94
+ width: "100%",
95
+ "& .MuiInputBase-input": {
96
+ padding: theme.spacing(1, 1, 1, 0),
97
+ paddingLeft: `calc(1em + ${theme.spacing(4)})`,
98
+ transition: theme.transitions.create("width"),
99
+ [theme.breakpoints.up("lg")]: {
100
+ width: "30ch",
101
+ "&:focus": {
102
+ width: "35ch"
103
+ }
104
+ }
105
+ }
106
+ }));
107
+ function AppSearch({
108
+ t,
109
+ navigate,
110
+ searchText,
111
+ setSearchText
112
+ }) {
113
+ const handleSearchContent = () => {
114
+ const extraData = {
115
+ searchText
116
+ };
117
+ const queryString = new URLSearchParams(extraData).toString();
118
+ navigate(`/search?${queryString}`);
119
+ };
120
+ return /*#__PURE__*/_react.default.createElement(Search, null, /*#__PURE__*/_react.default.createElement(SearchIconWrapper, null, /*#__PURE__*/_react.default.createElement(_Search.default, null)), /*#__PURE__*/_react.default.createElement(StyledInputBase, {
121
+ autoFocus: true,
122
+ placeholder: t("app_search_placeholder"),
123
+ value: searchText,
124
+ onChange: ev => setSearchText(ev.target.value),
125
+ inputProps: {
126
+ "aria-label": t("app_search_placeholder"),
127
+ onKeyPress: event => {
128
+ if (event.key === "Enter") {
129
+ handleSearchContent(searchText);
130
+ }
131
+ }
132
+ },
133
+ endAdornment: /*#__PURE__*/_react.default.createElement(_InputAdornment.default, {
134
+ position: "end",
135
+ sx: {
136
+ color: "inherit",
137
+ mr: 1,
138
+ visibility: searchText ? "visible" : "hidden"
139
+ }
140
+ }, /*#__PURE__*/_react.default.createElement(_material.IconButton, {
141
+ color: "inherit",
142
+ size: "small",
143
+ "aria-label": t("clear"),
144
+ onClick: () => setSearchText("")
145
+ }, /*#__PURE__*/_react.default.createElement(_Close.default, null)))
146
+ }));
147
+ }
58
148
  function App({
59
149
  children,
60
150
  Link = _reactRouterDom.Link,
@@ -87,9 +177,11 @@ function App({
87
177
  const theme = (0, _styles.useTheme)();
88
178
  const isLgScreen = (0, _useMediaQuery.default)(theme.breakpoints.up("md"));
89
179
  const [hideSkipNavigation, setHideSkipNavigation] = (0, _react.useState)(true);
180
+ const [searchText, setSearchText] = (0, _react.useState)("");
90
181
  const [isAppContainerLoading, setIsAppContainerLoading] = (0, _react.useState)(true);
91
182
  const [anchorEl, setAnchorEl] = (0, _react.useState)(null);
92
183
  const [isUpgradeSubscriptionOpen, setIsUpgradeSubscriptionOpen] = (0, _react.useState)(false);
184
+ const [isMobileSearchExpanded, setIsMobileSearchExpanded] = (0, _react.useState)(false);
93
185
  const handleOpenUpgradeSubscriptionModal = () => {
94
186
  setIsUpgradeSubscriptionOpen(true);
95
187
  };
@@ -151,6 +243,9 @@ function App({
151
243
  height: "auto",
152
244
  overflow: "visible"
153
245
  };
246
+ const isSearchActive = searchText || isMobileSearchExpanded;
247
+ const isTeacher = user && user["custom:role"] === "teach";
248
+ const isNewSearchVisible = localStorage.getItem(`new-search-enabled`) === "true";
154
249
  return /*#__PURE__*/_react.default.createElement("div", {
155
250
  className: classes.root
156
251
  }, /*#__PURE__*/_react.default.createElement(_Header.default, {
@@ -159,8 +254,36 @@ function App({
159
254
  isCollapsed: isCollapsed && isLgScreen,
160
255
  drawerWidth: drawerWidth,
161
256
  drawerCollapsedWidth: drawerCollapsedWidth,
162
- includeAdminBadge: includeAdminBadge
163
- }, /*#__PURE__*/_react.default.createElement(_DefaultColourButton.default, {
257
+ includeAdminBadge: includeAdminBadge,
258
+ isLogoHidden: !isLgScreen && isSearchActive ? true : false
259
+ }, !isLgScreen && isSearchActive ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.IconButton, {
260
+ color: "inherit",
261
+ "aria-label": t("back"),
262
+ onClick: () => {
263
+ setIsMobileSearchExpanded(false);
264
+ setSearchText("");
265
+ },
266
+ edge: "start"
267
+ }, /*#__PURE__*/_react.default.createElement(_ArrowBack.default, null)), /*#__PURE__*/_react.default.createElement(AppSearch, {
268
+ t: t,
269
+ navigate: navigate,
270
+ searchText: searchText,
271
+ setSearchText: setSearchText
272
+ })) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isLgScreen ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isTeacher && isNewSearchVisible && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(AppSearch, {
273
+ t: t,
274
+ navigate: navigate,
275
+ searchText: searchText,
276
+ setSearchText: setSearchText
277
+ }), /*#__PURE__*/_react.default.createElement(_material.Box, {
278
+ flexGrow: 1
279
+ }))) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isTeacher && isNewSearchVisible && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.Tooltip, {
280
+ title: t("search"),
281
+ enterDelay: 300
282
+ }, /*#__PURE__*/_react.default.createElement(_material.IconButton, {
283
+ color: "inherit",
284
+ "aria-label": t("search"),
285
+ onClick: () => setIsMobileSearchExpanded(true)
286
+ }, /*#__PURE__*/_react.default.createElement(_Search.default, null))))), /*#__PURE__*/_react.default.createElement(_DefaultColourButton.default, {
164
287
  href: "#maincontent",
165
288
  color: "inherit",
166
289
  variant: "contained",
@@ -187,7 +310,7 @@ function App({
187
310
  fontSize: isLgScreen ? null : 12,
188
311
  mr: 1
189
312
  }
190
- }, t("upgrade_plan")), user && user["custom:role"] === "teach" && (isLgScreen ? /*#__PURE__*/_react.default.createElement(_material.Button, {
313
+ }, t("upgrade_plan")), isTeacher && (isLgScreen ? /*#__PURE__*/_react.default.createElement(_material.Button, {
191
314
  variant: "contained",
192
315
  onClick: handleClickCreate,
193
316
  "data-cy": "appbar-create-button",
@@ -252,7 +375,7 @@ function App({
252
375
  },
253
376
  margin: theme.spacing(1, 1.5)
254
377
  })
255
- }, t("sign_up")))), isLgScreen ? /*#__PURE__*/_react.default.createElement(_ResponsiveDrawer.default, _extends({
378
+ }, t("sign_up"))))), isLgScreen ? /*#__PURE__*/_react.default.createElement(_ResponsiveDrawer.default, _extends({
256
379
  navToSettings: navToSettings,
257
380
  Link: Link,
258
381
  navigation: navigation,
@@ -86,6 +86,7 @@ const props = exports.props = {
86
86
  currentLanguage: "en",
87
87
  navToSettings: "",
88
88
  handleChangeLanguage: () => {},
89
+ navigate: () => {},
89
90
  toggleTheme: () => {},
90
91
  handleSignOut: () => {},
91
92
  isSnackbarOpen: false,
@@ -95,13 +96,16 @@ const props = exports.props = {
95
96
  user: {
96
97
  preferred_username: "Sandra Adams",
97
98
  email: "sandra_a88@gmail.com",
98
- picture: "https://randomuser.me/api/portraits/women/31.jpg"
99
+ picture: "https://randomuser.me/api/portraits/women/31.jpg",
100
+ "custom:role": "teach"
99
101
  },
100
102
  subscription: {
101
- isUpgradePossible: true
103
+ isUpgradePossible: false
102
104
  },
103
105
  isCollapsed: false,
104
- setIsCollapsed: () => {}
106
+ setIsCollapsed: () => {},
107
+ logoSrc: "https://app.dev.nualang.com/assets/nualang-logo-white-MYV2DVUT.svg",
108
+ authenticated: true
105
109
  };
106
110
  const story = {
107
111
  title: "Containers/App",
@@ -34,6 +34,7 @@ function GenerateRoleplayDialog({
34
34
  hideRoleplayLengthOptions = true,
35
35
  makeChatGptApiRequest,
36
36
  learnLang,
37
+ forLang,
37
38
  getAllVoices,
38
39
  i18nLanguage,
39
40
  initialValues = {
@@ -58,6 +59,7 @@ function GenerateRoleplayDialog({
58
59
  pdfDetails,
59
60
  makeCandooAIQuery,
60
61
  pdfVectorStoreCreationStatus,
62
+ siteLanguage,
61
63
  phrases,
62
64
  topicId,
63
65
  initialTopicGoal
@@ -72,6 +74,8 @@ function GenerateRoleplayDialog({
72
74
  const [values, setValues] = (0, _react.useState)(initialValues);
73
75
  const [errorMessage, setErrorMessage] = (0, _react.useState)(null);
74
76
  const [generateQuestions, setGenerateQuestions] = (0, _react.useState)(false);
77
+ const [questionLang, setQuestionLang] = (0, _react.useState)(learnLang);
78
+ const finalForLang = forLang ? forLang.charAt(0).toUpperCase() + forLang.slice(1) : siteLanguage;
75
79
  (0, _react.useEffect)(() => {
76
80
  if (initialTopicGoal && initialTopicGoal.trim() !== "") {
77
81
  setTopicGoal(initialTopicGoal);
@@ -186,7 +190,7 @@ function GenerateRoleplayDialog({
186
190
 
187
191
  // Add explicit JSON formatting instructions with roleplay length
188
192
  const promptWithoutQuestions = usePdfContext ? `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines). Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Please ensure the entire output is formatted as a single, well-formed JSON array.` : `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines). Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Please ensure the entire output is formatted as a single, well-formed JSON array.`;
189
- const promptWithQuestions = usePdfContext ? `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines), followed by ${values?.questionsAmount} comprehension questions related to the conversation. Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Each comprehension question should also be represented as an object within the same array, with the keys 'question' and 'answers'. The 'answers' key should be an array of 3 objects, each containing 'text', 'correct' (true or false), and 'type' ('correct' or 'incorrect'). Please ensure the entire output is formatted as a single, well-formed JSON array.` : `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines), followed by ${values?.questionsAmount} comprehension questions related to the conversation. Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Each comprehension question should also be represented as an object within the same array, with the keys 'question' and 'answers'. The 'answers' key should be an array of 3 objects, each containing 'text', 'correct' (true or false), and 'type' ('correct' or 'incorrect'). Please ensure the entire output is formatted as a single, well-formed JSON array.`;
193
+ const promptWithQuestions = usePdfContext ? `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines), followed by ${values?.questionsAmount} comprehension questions related to the conversation, the question should be generated in ${questionLang}. Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Each comprehension question should also be represented as an object within the same array, with the keys 'question' and 'answers'. The 'answers' key should be an array of 3 objects, each containing 'text', 'correct' (true or false), and 'type' ('correct' or 'incorrect'), the answers should be generated in ${questionLang}. Please ensure the entire output is formatted as a single, well-formed JSON array.` : `${finalPrompt} The conversation should be returned as a single JSON array. The array must contain exactly ${values.roleplayLengthNumber} exchanges (lines), followed by ${values?.questionsAmount} comprehension questions related to the conversation, the question should be generated in ${questionLang}. Each piece of dialogue should be represented as an object with the keys 'actor' and 'text'. The 'actor' key should be set to 1 if the dialogue is spoken by the first actor, and 2 if it is spoken by the second actor. The 'text' key should be set to the dialogue text spoken by that actor. Each comprehension question should also be represented as an object within the same array, with the keys 'question' and 'answers'. The 'answers' key should be an array of 3 objects, each containing 'text', 'correct' (true or false), and 'type' ('correct' or 'incorrect'), the answers should be generated in ${questionLang}. Please ensure the entire output is formatted as a single, well-formed JSON array.`;
190
194
  const activePrompt = generateQuestions ? promptWithQuestions : promptWithoutQuestions;
191
195
  console.log("Final Prompt Sent to API:", activePrompt);
192
196
 
@@ -464,7 +468,22 @@ function GenerateRoleplayDialog({
464
468
  sx: {
465
469
  marginRight: 0
466
470
  }
467
- })))), generateQuestions && /*#__PURE__*/_react.default.createElement(_material.Grid, {
471
+ })))), generateQuestions && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, finalForLang !== learnLang.charAt(0).toUpperCase() + learnLang.slice(1) && /*#__PURE__*/_react.default.createElement(_material.Grid, {
472
+ item: true,
473
+ xs: 12,
474
+ mb: 2
475
+ }, /*#__PURE__*/_react.default.createElement(_material.TextField, {
476
+ select: true,
477
+ fullWidth: true,
478
+ label: t("question_language"),
479
+ value: questionLang,
480
+ onChange: e => setQuestionLang(e.target.value),
481
+ variant: "outlined"
482
+ }, /*#__PURE__*/_react.default.createElement(_material.MenuItem, {
483
+ value: learnLang
484
+ }, t(learnLang)), /*#__PURE__*/_react.default.createElement(_material.MenuItem, {
485
+ value: finalForLang
486
+ }, t(finalForLang)))), /*#__PURE__*/_react.default.createElement(_material.Grid, {
468
487
  item: true,
469
488
  xs: 12
470
489
  }, /*#__PURE__*/_react.default.createElement(_material.Typography, {
@@ -483,7 +502,7 @@ function GenerateRoleplayDialog({
483
502
  marks: true,
484
503
  min: 1,
485
504
  max: Math.floor(values?.roleplayLengthNumber / 2)
486
- })), topicId && /*#__PURE__*/_react.default.createElement(_material.FormGroup, null, /*#__PURE__*/_react.default.createElement(_material.Grid, {
505
+ }))), topicId && /*#__PURE__*/_react.default.createElement(_material.FormGroup, null, /*#__PURE__*/_react.default.createElement(_material.Grid, {
487
506
  item: true,
488
507
  xs: 12,
489
508
  marginBottom: 1
@@ -28,7 +28,8 @@ const props = exports.props = {
28
28
  });
29
29
  return promise;
30
30
  },
31
- learnLang,
31
+ learnLang: "spanish",
32
+ forLang: "english",
32
33
  getAllVoices: () => {
33
34
  let voicesArray = [];
34
35
  if (_config.default) {
@@ -144,7 +144,6 @@ function LiveGameTutorial({
144
144
  default:
145
145
  images = [];
146
146
  }
147
- console.log("exerciseName is:", exerciseName);
148
147
  return /*#__PURE__*/_react.default.createElement(_ResponsiveDialog.default, {
149
148
  open: open,
150
149
  handleClose: handleClose,
@@ -1187,6 +1187,7 @@ function Editor({
1187
1187
  display: "flex",
1188
1188
  alignItems: "center"
1189
1189
  }, /*#__PURE__*/_react.default.createElement(_material.Button, {
1190
+ size: "small",
1190
1191
  sx: {
1191
1192
  marginRight: 1
1192
1193
  },
@@ -847,7 +847,9 @@ function Roleplay({
847
847
  makeCandooAIQuery: makeCandooAIQuery,
848
848
  getAllVoices: getAllVoices,
849
849
  learnLang: learnLang,
850
+ forLang: forLang,
850
851
  i18nLanguage: i18nLanguage,
852
+ siteLanguage: siteLanguage,
851
853
  initialValues: {
852
854
  roleplayTopic: roleplay.roleplayName,
853
855
  roleplayDifficulty: roleplay.difficulty,
@@ -216,6 +216,16 @@ function Pronouncer({
216
216
  handleContinue(false, currentPhrase);
217
217
  }
218
218
  }, [open, recognizing, finalTranscript]);
219
+ (0, _react.useEffect)(() => {
220
+ let timer;
221
+ if (recognizing && interimTranscript === "" && finalTranscript === "") {
222
+ // Set a timer to stop listening if no audio is detected after 10 seconds
223
+ timer = setTimeout(() => {
224
+ stopListening();
225
+ }, 10000);
226
+ }
227
+ return () => clearTimeout(timer);
228
+ }, [recognizing, interimTranscript, finalTranscript]);
219
229
  const initialVoiceSpeed = topicInfo && topicInfo.voiceSpeed ? topicInfo.voiceSpeed : "";
220
230
  const exerciseState = (0, _useExerciseState.default)({
221
231
  open,
@@ -426,6 +426,16 @@ function RoleplayGame({
426
426
  // Stop Recording required to get final confidence score and trigger event if needed
427
427
  toggleListen(learnLang, speechContexts, model, true);
428
428
  };
429
+ (0, _react.useEffect)(() => {
430
+ let timer;
431
+ if (recognizing && interimTranscript === "" && finalTranscript === "") {
432
+ // Set a timer to stop listening if no audio is detected after 10 seconds
433
+ timer = setTimeout(() => {
434
+ stopListening();
435
+ }, 10000);
436
+ }
437
+ return () => clearTimeout(timer);
438
+ }, [recognizing, interimTranscript, finalTranscript]);
429
439
  const getRandomNuala = () => {
430
440
  let finished = false;
431
441
  while (!finished) {
@@ -424,6 +424,16 @@ function RoleplayGame({
424
424
  // Stop Recording required to get final confidence score and trigger event if needed
425
425
  toggleListen(learnLang, speechContexts, model, true);
426
426
  };
427
+ (0, _react.useEffect)(() => {
428
+ let timer;
429
+ if (recognizing && interimTranscript === "" && finalTranscript === "") {
430
+ // Set a timer to stop listening if no audio is detected after 10 seconds
431
+ timer = setTimeout(() => {
432
+ stopListening();
433
+ }, 10000);
434
+ }
435
+ return () => clearTimeout(timer);
436
+ }, [recognizing, interimTranscript, finalTranscript]);
427
437
  const getRandomNuala = () => {
428
438
  let finished = false;
429
439
  while (!finished) {
@@ -438,7 +438,7 @@ function BotInformation({
438
438
  maxLength: 1000,
439
439
  characters: langChar,
440
440
  learnLang: learnLang
441
- }))), update && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.Typography, null, /*#__PURE__*/_react.default.createElement(_material.Box, {
441
+ }))), /*#__PURE__*/_react.default.createElement(_material.Typography, null, /*#__PURE__*/_react.default.createElement(_material.Box, {
442
442
  pt: 2
443
443
  }, t("student_instructions"))), /*#__PURE__*/_react.default.createElement(_material.Grid, {
444
444
  container: true,
@@ -454,7 +454,7 @@ function BotInformation({
454
454
  placeholder: t("student_instructions_placeholder"),
455
455
  imageUploadFunction: handleBotInstructionsImageUpload,
456
456
  handleChange: handleChange
457
- })))), /*#__PURE__*/_react.default.createElement(_material.Typography, null, /*#__PURE__*/_react.default.createElement(_material.Box, null, t("creator_instructions"))), /*#__PURE__*/_react.default.createElement(_material.Grid, {
457
+ })))), update && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.Typography, null, /*#__PURE__*/_react.default.createElement(_material.Box, null, t("creator_instructions"))), /*#__PURE__*/_react.default.createElement(_material.Grid, {
458
458
  container: true,
459
459
  spacing: 1
460
460
  }, /*#__PURE__*/_react.default.createElement(_material.Grid, {
@@ -12,17 +12,17 @@ const samples = exports.samples = ["Personas famosas", "Comprando ingredientes",
12
12
  const sampleAutofillValues = exports.sampleAutofillValues = {
13
13
  "Personas famosas": {
14
14
  topic: "Personas famosas",
15
- prompt: `One's profession is often an important part of identity. Cany ou match these famous Spanish speakers with their identity? Converse with your partner, connecting the person's name and identity with es, as in the model. Look up the people you don't know, or consult a classmate to fill in the gaps in your knowledge.`,
15
+ prompt: `One's profession is often an important part of identity. Can you match these famous Spanish speakers with their identity? Converse with your partner, connecting the person's name and identity with es, as in the model. Look up the people you don't know, or consult a classmate to fill in the gaps in your knowledge.`,
16
16
  url: "",
17
17
  backgroundImages: [],
18
- meetingImages: [_input.default, _mode.default]
18
+ meetingImages: []
19
19
  },
20
20
  "Comprando ingredientes": {
21
21
  topic: "Comprando ingredientes",
22
22
  prompt: `Vas al Mercado de la Merced para comprar los ingredientes para tu escamocha. Actúa la situación con un/a compañero/a de clase. Una personal compra, y la otra vende. Luego, cambien los papeles (switch roles) y repitan la situación.`,
23
23
  url: "",
24
24
  backgroundImages: [],
25
- meetingImages: [_mode2.default]
25
+ meetingImages: []
26
26
  },
27
27
  "¿Qué prefieres?": {
28
28
  topic: "¿Qué prefieres?",
@@ -33,21 +33,21 @@ const sampleAutofillValues = exports.sampleAutofillValues = {
33
33
  3. ¿Qué comida internacional prefieres: comida mexicana, tilandesa o italiana?
34
34
  4. ¿Qué prefieres beber: jugo de naranja, jugo de manzana o solo agua?
35
35
  5. ¿Puedes comer gluten, productos lacteos (dairy) y nueces (nuts), o tienes alergias?`,
36
- url: "www.facebook.com",
36
+ url: "",
37
37
  backgroundImages: [],
38
38
  meetingImages: []
39
39
  },
40
40
  "¿Qué quieres?": {
41
41
  topic: "¿Qué quieres?",
42
- prompt: `Work with a compañero/a to create questions and answers based on the following paris of words.`,
43
- url: "www.facebook.com",
42
+ prompt: `Work with a compañero/a to create questions and answers based on the following pairs of words.`,
43
+ url: "",
44
44
  backgroundImages: [],
45
45
  meetingImages: []
46
46
  },
47
47
  Compara: {
48
48
  topic: "Compara",
49
49
  prompt: `Con un/a compañero/a, prepara una diagrama de Venn comparando el desfile en el video con una celebración en tu comunidad.`,
50
- url: "https://drive.google.com/file/d/1hJwDJK3OVrZ_kvsfMMyXleKgOkCVOpEt/view",
50
+ url: "",
51
51
  backgroundImages: [],
52
52
  meetingImages: []
53
53
  }
@@ -145,6 +145,7 @@ function Game({
145
145
  handleTranslate,
146
146
  userImage,
147
147
  answerCounts,
148
+ noAnswerCounts,
148
149
  ...otherProps
149
150
  }) {
150
151
  const {
@@ -466,7 +467,8 @@ function Game({
466
467
  nextScriptLine: nextScriptLine,
467
468
  handleTranslate: handleTranslate,
468
469
  isFinalScoreDrawerOpen: isFinalScoreDrawerOpen,
469
- answerCounts: answerCounts
470
+ answerCounts: answerCounts,
471
+ noAnswerCounts: noAnswerCounts
470
472
  }, otherProps));
471
473
  }
472
474
  })(), gameView === GameViewTypes.Leaderboard && /*#__PURE__*/_react.default.createElement(_material.Box, {
@@ -73,7 +73,8 @@ function LiveStory({
73
73
  setIsStudentAnswerDrawerOpen,
74
74
  roleplayAnswer,
75
75
  setRoleplayAnswer,
76
- answerCounts
76
+ answerCounts,
77
+ noAnswerCounts
77
78
  }) {
78
79
  const {
79
80
  classes
@@ -222,7 +223,8 @@ function LiveStory({
222
223
  handleContinue: handleContinue,
223
224
  currentMessage: currentMessage,
224
225
  roleplayImage: roleplay.picture,
225
- answerCounts: answerCounts
226
+ answerCounts: answerCounts,
227
+ noAnswerCounts: noAnswerCounts
226
228
  })), /*#__PURE__*/_react.default.createElement(_AnswerResult.default, _extends({
227
229
  t: t,
228
230
  open: isCorrectResultOpen
@@ -45,7 +45,8 @@ function Header({
45
45
  drawerWidth = 256,
46
46
  drawerCollapsedWidth,
47
47
  isCollapsed,
48
- includeAdminBadge = false
48
+ includeAdminBadge = false,
49
+ isLogoHidden = false
49
50
  }) {
50
51
  const theme = (0, _styles.useTheme)();
51
52
  return /*#__PURE__*/_react.default.createElement(_HideOnScroll.default, null, /*#__PURE__*/_react.default.createElement(AppBar, {
@@ -53,7 +54,7 @@ function Header({
53
54
  drawerWidth: drawerWidth,
54
55
  drawerCollapsedWidth: drawerCollapsedWidth,
55
56
  isCollapsed: isCollapsed
56
- }, /*#__PURE__*/_react.default.createElement(_Toolbar.default, null, logoSrc ? /*#__PURE__*/_react.default.createElement(Logo, {
57
+ }, /*#__PURE__*/_react.default.createElement(_Toolbar.default, null, !isLogoHidden && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, logoSrc ? /*#__PURE__*/_react.default.createElement(Logo, {
57
58
  src: logoSrc,
58
59
  alt: title
59
60
  }) : /*#__PURE__*/_react.default.createElement(_Typography.default, {
@@ -75,7 +76,7 @@ function Header({
75
76
  }
76
77
  }, "Admin")), /*#__PURE__*/_react.default.createElement(_Box.default, {
77
78
  flexGrow: 1
78
- }), children)));
79
+ })), children)));
79
80
  }
80
81
  Header.propTypes = {
81
82
  drawerWidth: _propTypes.default.number.isRequired,
@@ -59,7 +59,8 @@ function SearchFilters({
59
59
  forLang,
60
60
  sort,
61
61
  difficulty,
62
- difficultyOptions
62
+ difficultyOptions,
63
+ showCreateCourseButton
63
64
  }) {
64
65
  const [searchText, setSearchText] = (0, _react.useState)("");
65
66
  const debouncedSearch = (0, _useDebounce.default)(searchText, 500);
@@ -200,7 +201,19 @@ function SearchFilters({
200
201
  duration: theme.transitions.duration.leavingScreen
201
202
  })
202
203
  })
203
- }))))));
204
+ }))), showCreateCourseButton && /*#__PURE__*/_react.default.createElement(_material.Grid, {
205
+ item: true,
206
+ xs: 12,
207
+ sm: 12,
208
+ md: 2.5
209
+ }, /*#__PURE__*/_react.default.createElement(_material.Button, {
210
+ onClick: handleCreateCourse,
211
+ variant: "contained",
212
+ color: "primary",
213
+ endIcon: /*#__PURE__*/_react.default.createElement(_Add.default, null),
214
+ fullWidth: true,
215
+ role: "link"
216
+ }, t("create_course"))))));
204
217
  }
205
218
  function SearchCourses({
206
219
  t = text => text,
@@ -242,7 +255,8 @@ function SearchCourses({
242
255
  setSearch,
243
256
  handleDuplicateCourse,
244
257
  difficulty,
245
- difficultyOptions
258
+ difficultyOptions,
259
+ showCreateCourseButton
246
260
  }) {
247
261
  const {
248
262
  classes
@@ -276,7 +290,8 @@ function SearchCourses({
276
290
  sort: sort,
277
291
  forLang: forLang,
278
292
  difficulty: difficulty,
279
- difficultyOptions: difficultyOptions
293
+ difficultyOptions: difficultyOptions,
294
+ showCreateCourseButton: showCreateCourseButton
280
295
  }), isLoading || courses !== undefined && courses.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
281
296
  className: classes.root
282
297
  }, /*#__PURE__*/_react.default.createElement(_Courses.default, {
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = Search;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _material = require("@mui/material");
9
+ var _mui = require("tss-react/mui");
10
+ var _Courses = _interopRequireDefault(require("../../Lists/Courses"));
11
+ var _Courses2 = _interopRequireDefault(require("../../Misc/NotFound/Courses"));
12
+ var _LanguageSelector = _interopRequireDefault(require("../../Forms/LanguageSelector/LanguageSelector"));
13
+ var _HideOnScroll = _interopRequireDefault(require("../../Misc/HideOnScroll"));
14
+ var _SortBySelector = _interopRequireDefault(require("../../Forms/SortBySelector/SortBySelector"));
15
+ var _useDebounce = _interopRequireDefault(require("../../utils/hooks/useDebounce"));
16
+ var _reactRouterDom = require("react-router-dom");
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
19
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
+ const useStyles = (0, _mui.makeStyles)()((theme, {
21
+ disablePadding
22
+ }) => ({
23
+ root: {
24
+ height: "100%",
25
+ padding: disablePadding ? 0 : theme.spacing(1, 2),
26
+ [theme.breakpoints.up("sm")]: {
27
+ padding: disablePadding ? 0 : theme.spacing(2, 3)
28
+ }
29
+ },
30
+ box: {
31
+ padding: theme.spacing(1, 2),
32
+ [theme.breakpoints.up("sm")]: {
33
+ padding: theme.spacing(2, 3)
34
+ }
35
+ },
36
+ autocomplete: {
37
+ flexGrow: 1,
38
+ marginRight: theme.spacing(1)
39
+ },
40
+ actions: {
41
+ marginBottom: theme.spacing(1)
42
+ },
43
+ divider: {
44
+ marginBottom: theme.spacing(1)
45
+ }
46
+ }));
47
+ function SearchFilters({
48
+ t,
49
+ classes,
50
+ languageOptions,
51
+ forLanguageOptions,
52
+ handleFilterChange,
53
+ sortByOptions,
54
+ learnLang,
55
+ search,
56
+ setSearch,
57
+ handleCreateCourse,
58
+ forLang,
59
+ sort,
60
+ difficulty,
61
+ difficultyOptions
62
+ }) {
63
+ const location = (0, _reactRouterDom.useLocation)();
64
+ const queryParams = new URLSearchParams(location.search);
65
+ const text = queryParams.get("searchText") || "";
66
+ const [searchText] = (0, _react.useState)(text);
67
+ const debouncedSearch = (0, _useDebounce.default)(searchText, 500);
68
+ (0, _react.useEffect)(() => {
69
+ if (setSearch && searchText !== search) {
70
+ setSearch(searchText);
71
+ if (window.scrollY > 100) {
72
+ window.scrollTo(0, 0);
73
+ }
74
+ }
75
+ }, [debouncedSearch]);
76
+ return /*#__PURE__*/_react.default.createElement(_HideOnScroll.default, {
77
+ threshold: 300
78
+ }, /*#__PURE__*/_react.default.createElement(_material.Box, {
79
+ display: "flex",
80
+ mb: 2,
81
+ className: classes.box,
82
+ sx: theme => ({
83
+ position: "sticky",
84
+ top: 0,
85
+ zIndex: 1200,
86
+ backgroundColor: theme.palette.background.default,
87
+ borderBottom: `1px solid ${theme.palette.divider}`,
88
+ marginTop: theme.spacing(0.5)
89
+ })
90
+ }, /*#__PURE__*/_react.default.createElement(_material.Grid, {
91
+ container: true,
92
+ direction: "row",
93
+ alignItems: "center",
94
+ spacing: 1,
95
+ className: classes.actions
96
+ }, /*#__PURE__*/_react.default.createElement(_material.Grid, {
97
+ item: true,
98
+ xs: 12,
99
+ md: 2
100
+ }, /*#__PURE__*/_react.default.createElement(_LanguageSelector.default, {
101
+ id: "learnLang",
102
+ name: "learnLang",
103
+ label: t("learn"),
104
+ margin: "dense",
105
+ variant: "outlined",
106
+ fullWidth: true,
107
+ t: t,
108
+ languages: languageOptions,
109
+ value: learnLang,
110
+ onChange: handleFilterChange
111
+ })), /*#__PURE__*/_react.default.createElement(_material.Grid, {
112
+ item: true,
113
+ xs: 12,
114
+ md: 2
115
+ }, /*#__PURE__*/_react.default.createElement(_LanguageSelector.default, {
116
+ id: "forLang",
117
+ name: "forLang",
118
+ label: t("speakers_of"),
119
+ margin: "dense",
120
+ variant: "outlined",
121
+ fullWidth: true,
122
+ t: t,
123
+ languages: forLanguageOptions,
124
+ value: forLang,
125
+ onChange: handleFilterChange
126
+ })), /*#__PURE__*/_react.default.createElement(_material.Grid, {
127
+ item: true,
128
+ xs: 12,
129
+ md: 2
130
+ }, /*#__PURE__*/_react.default.createElement(_material.TextField, {
131
+ select: true,
132
+ id: "difficulty",
133
+ name: "difficulty",
134
+ "data-cy": "difficulty",
135
+ label: t("difficulty"),
136
+ value: difficulty,
137
+ onChange: handleFilterChange,
138
+ margin: "dense",
139
+ variant: "outlined",
140
+ fullWidth: true
141
+ }, difficultyOptions)), /*#__PURE__*/_react.default.createElement(_material.Grid, {
142
+ item: true,
143
+ xs: 12,
144
+ md: 2
145
+ }, /*#__PURE__*/_react.default.createElement(_SortBySelector.default, {
146
+ id: "sortBy",
147
+ name: "sort",
148
+ label: t("sort"),
149
+ margin: "dense",
150
+ variant: "outlined",
151
+ fullWidth: true,
152
+ t: t,
153
+ value: sort,
154
+ onChange: handleFilterChange,
155
+ sortByOptions: sortByOptions,
156
+ disabled: (!learnLang || learnLang === "all") && (!forLang || forLang === "all")
157
+ })))));
158
+ }
159
+ function Search({
160
+ t = text => text,
161
+ courses = [],
162
+ selectedCourses = [],
163
+ isLoading,
164
+ placeholderImageUrl,
165
+ handleSelectAllCoursesClick,
166
+ handleClickCourse,
167
+ selectable,
168
+ learnLang,
169
+ forLang,
170
+ handleViewCourseTopic,
171
+ handleFilterChange,
172
+ languages,
173
+ forLanguages,
174
+ handleStartCourse,
175
+ handleLeaveCourse,
176
+ handleViewCourse,
177
+ handleViewUserProfile,
178
+ handleCreateCourse,
179
+ membersProps,
180
+ getMemberDetails,
181
+ reviewPlaceholderImageUrl,
182
+ memberPlaceholderImageUrl,
183
+ disablePadding,
184
+ getUserReviews,
185
+ getMemberInfo,
186
+ getCourseSections,
187
+ getCourseReviews,
188
+ getCourseMember,
189
+ getCourseMembers,
190
+ memberId,
191
+ username,
192
+ sort,
193
+ isLearnLangDisabled,
194
+ scrollTarget,
195
+ search,
196
+ setSearch,
197
+ handleDuplicateCourse,
198
+ difficulty,
199
+ difficultyOptions
200
+ }) {
201
+ const {
202
+ classes
203
+ } = useStyles({
204
+ disablePadding
205
+ });
206
+ const languageOptions = {
207
+ all: {},
208
+ ...languages
209
+ };
210
+ const forLanguageOptions = {
211
+ all: {},
212
+ ...forLanguages
213
+ };
214
+ const sortByOptions = {
215
+ newest: "newest",
216
+ oldest: "oldest",
217
+ popular: "popular"
218
+ };
219
+ return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(SearchFilters, {
220
+ t: t,
221
+ classes: classes,
222
+ languageOptions: languageOptions,
223
+ forLanguageOptions: forLanguageOptions,
224
+ handleFilterChange: handleFilterChange,
225
+ sortByOptions: sortByOptions,
226
+ learnLang: learnLang,
227
+ search: search,
228
+ setSearch: setSearch,
229
+ handleCreateCourse: handleCreateCourse,
230
+ sort: sort,
231
+ forLang: forLang,
232
+ difficulty: difficulty,
233
+ difficultyOptions: difficultyOptions
234
+ }), isLoading || courses !== undefined && courses.length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
235
+ className: classes.root
236
+ }, /*#__PURE__*/_react.default.createElement(_Courses.default, {
237
+ t: t,
238
+ courses: courses !== undefined && Array.isArray(courses) && courses.length ? courses : null,
239
+ handleStartCourse: handleStartCourse,
240
+ handleLeaveCourse: handleLeaveCourse,
241
+ handleViewCourse: handleViewCourse,
242
+ handleViewUserProfile: handleViewUserProfile,
243
+ membersProps: membersProps,
244
+ handleViewCourseTopic: handleViewCourseTopic,
245
+ selectable: selectable,
246
+ selectedCourses: selectedCourses,
247
+ handleSelectAllCoursesClick: handleSelectAllCoursesClick,
248
+ handleClickCourse: handleClickCourse,
249
+ getMemberDetails: getMemberDetails,
250
+ getMemberInfo: getMemberInfo,
251
+ reviewPlaceholderImageUrl: reviewPlaceholderImageUrl,
252
+ getUserReviews: getUserReviews,
253
+ memberPlaceholderImageUrl: memberPlaceholderImageUrl,
254
+ getCourseSections: getCourseSections,
255
+ getCourseReviews: getCourseReviews,
256
+ getCourseMember: getCourseMember,
257
+ getCourseMembers: getCourseMembers,
258
+ memberId: memberId,
259
+ username: username,
260
+ handleDuplicateCourse: handleDuplicateCourse
261
+ })) : /*#__PURE__*/_react.default.createElement("div", {
262
+ className: classes.root
263
+ }, /*#__PURE__*/_react.default.createElement(_Courses2.default, {
264
+ t: t,
265
+ placeholderImageUrl: placeholderImageUrl,
266
+ handleCreateCourse: handleCreateCourse,
267
+ title: t("courses_not_found_title"),
268
+ description: t("courses_not_found_desc")
269
+ })));
270
+ }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.props = exports.default = exports.StateExample = exports.Selectable = exports.NotFound = exports.Loading = exports.Loaded = exports.DialogExample = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _material = require("@mui/material");
9
+ var _Close = _interopRequireDefault(require("@mui/icons-material/Close"));
10
+ var _Search = _interopRequireDefault(require("./Search"));
11
+ var _ResponsiveTabs = _interopRequireDefault(require("../../Navigation/ResponsiveTabs"));
12
+ var _Courses = require("../../Lists/Courses/Courses.stories");
13
+ var _Course = require("../../Cards/Course/Course.stories");
14
+ var _Members = require("../../Lists/Members/Members.stories");
15
+ var _config = _interopRequireDefault(require("../../config"));
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
18
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
19
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
20
+ const Template = args => /*#__PURE__*/_react.default.createElement(_Search.default, args);
21
+ const props = exports.props = {
22
+ courses: [],
23
+ isLoading: false,
24
+ hasMoreCourses: false,
25
+ loadMoreCourses: () => console.log("loading more"),
26
+ getMemberDetails: _Members.getMemberDetails,
27
+ languages: _config.default.languages,
28
+ handleFilterChange: event => console.log("filter change", event),
29
+ getCourseSections: _Course.props.getCourseSections,
30
+ getCourseReviews: _Course.props.getCourseReviews,
31
+ getCourseMembers: _Course.props.getCourseMembers
32
+ };
33
+ const handleClickCourse = (courseId, value) => {
34
+ console.log(courseId, value);
35
+ };
36
+ function SearchExample(props) {
37
+ const [state, setState] = (0, _react.useState)({
38
+ courses: [],
39
+ hasMoreCourses: true,
40
+ isLoading: false
41
+ });
42
+ const fetchCourses = () => {
43
+ setState({
44
+ ...state,
45
+ isLoading: true
46
+ });
47
+ console.log("Loading more items");
48
+ setTimeout(() => {
49
+ setState({
50
+ hasMoreCourses: state.courses.length < 10,
51
+ isLoading: false,
52
+ courses: [...state.courses].concat([..._Courses.courses, ..._Courses.courses])
53
+ });
54
+ }, 2500);
55
+ };
56
+ (0, _react.useEffect)(() => {
57
+ fetchCourses();
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }, []);
60
+ const loadMore = async () => {
61
+ console.log("Reached the end of screen");
62
+ if (state.hasMoreCourses && !state.isLoading) {
63
+ fetchCourses();
64
+ } else {
65
+ console.log("No more items");
66
+ }
67
+ };
68
+ return /*#__PURE__*/_react.default.createElement(_Search.default, _extends({}, props, state, {
69
+ loadMoreCourses: loadMore
70
+ }));
71
+ }
72
+ function SearchDialogExample() {
73
+ // please keep it undefined here to not make useScrollTrigger throw an error on first render
74
+ const [scrollTarget, setScrollTarget] = (0, _react.useState)(undefined);
75
+ return /*#__PURE__*/_react.default.createElement(_material.Dialog, {
76
+ PaperProps: {
77
+ id: "courses-dialog"
78
+ },
79
+ open: true,
80
+ fullScreen: true
81
+ }, /*#__PURE__*/_react.default.createElement(_material.AppBar, {
82
+ sx: {
83
+ position: "relative",
84
+ paddingRight: 0
85
+ }
86
+ }, /*#__PURE__*/_react.default.createElement(_material.Toolbar, null, /*#__PURE__*/_react.default.createElement(_material.IconButton, {
87
+ edge: "start",
88
+ color: "inherit",
89
+ "aria-label": "Close",
90
+ size: "large"
91
+ }, /*#__PURE__*/_react.default.createElement(_Close.default, null)), /*#__PURE__*/_react.default.createElement(_material.Typography, {
92
+ variant: "h6",
93
+ color: "inherit",
94
+ flexGrow: 1
95
+ }, "Add Courses"))), /*#__PURE__*/_react.default.createElement(_material.DialogContent, {
96
+ sx: {
97
+ padding: 0
98
+ },
99
+ ref: node => {
100
+ if (node) {
101
+ setScrollTarget(node);
102
+ }
103
+ }
104
+ }, /*#__PURE__*/_react.default.createElement(_ResponsiveTabs.default, {
105
+ tabs: [{
106
+ label: "My Courses"
107
+ }, {
108
+ label: "Find Course"
109
+ }],
110
+ centered: true
111
+ }, /*#__PURE__*/_react.default.createElement(_material.Box, {
112
+ py: 2
113
+ }, /*#__PURE__*/_react.default.createElement(SearchExample, {
114
+ scrollTarget: scrollTarget
115
+ })), /*#__PURE__*/_react.default.createElement(_material.Box, {
116
+ py: 2
117
+ }, /*#__PURE__*/_react.default.createElement(SearchExample, {
118
+ scrollTarget: scrollTarget
119
+ })))), /*#__PURE__*/_react.default.createElement(_material.DialogActions, null, /*#__PURE__*/_react.default.createElement(_material.Button, {
120
+ color: "primary"
121
+ }, "Cancel"), /*#__PURE__*/_react.default.createElement(_material.Button, {
122
+ color: "primary",
123
+ variant: "contained",
124
+ autoFocus: true
125
+ }, "Add Courses")));
126
+ }
127
+ const story = {
128
+ title: "Screens/Search",
129
+ excludeStories: ["props"],
130
+ component: _Search.default
131
+ };
132
+ var _default = exports.default = story;
133
+ const NotFound = exports.NotFound = Template.bind({});
134
+ NotFound.args = {
135
+ ...props
136
+ };
137
+ NotFound.storyName = "not found";
138
+ const Loading = exports.Loading = Template.bind({});
139
+ Loading.args = {
140
+ ...props,
141
+ isLoading: true,
142
+ hasMoreCourses: true
143
+ };
144
+ Loading.storyName = "loading";
145
+ const Loaded = exports.Loaded = Template.bind({});
146
+ Loaded.args = {
147
+ ...props,
148
+ courses: [..._Courses.courses, ..._Courses.courses],
149
+ hasMoreCourses: true
150
+ };
151
+ Loaded.storyName = "loaded";
152
+ const Selectable = exports.Selectable = Template.bind({});
153
+ Selectable.args = {
154
+ ...props,
155
+ courses: _Courses.courses,
156
+ selectable: true,
157
+ handleClickCourse: handleClickCourse
158
+ };
159
+ Selectable.storyName = "selectable";
160
+ const StateExampleTemplate = args => /*#__PURE__*/_react.default.createElement(SearchExample, args);
161
+ const StateExample = exports.StateExample = StateExampleTemplate.bind({});
162
+ StateExample.storyName = "state example";
163
+ const DialogExampleTemplate = args => /*#__PURE__*/_react.default.createElement(SearchDialogExample, args);
164
+ const DialogExample = exports.DialogExample = DialogExampleTemplate.bind({});
165
+ DialogExample.storyName = "dialog example";
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "Search",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "main": "./Search.js"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nualang/nualang-ui-components",
3
- "version": "0.1.1170",
3
+ "version": "0.1.1172",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist",