@nualang/nualang-ui-components 0.1.1360 → 0.1.1362

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.
@@ -1,6 +1,23 @@
1
1
  import { useState, useEffect, useRef, Fragment } from "react";
2
2
  import { makeStyles } from "tss-react/mui";
3
- import n2words from "n2words";
3
+ import { toCardinal as n2wordsEn } from "n2words/en-US";
4
+ import { toCardinal as n2wordsEs } from "n2words/es-ES";
5
+ import { toCardinal as n2wordsDe } from "n2words/de-DE";
6
+ import { toCardinal as n2wordsFr } from "n2words/fr-FR";
7
+ import { toCardinal as n2wordsIt } from "n2words/it-IT";
8
+ import { toCardinal as n2wordsPt } from "n2words/pt-PT";
9
+ import { toCardinal as n2wordsZh } from "n2words/zh-Hans-CN";
10
+ import { toCardinal as n2wordsJa } from "n2words/ja-JP";
11
+ const n2wordsConverters = {
12
+ en: n2wordsEn,
13
+ es: n2wordsEs,
14
+ de: n2wordsDe,
15
+ fr: n2wordsFr,
16
+ it: n2wordsIt,
17
+ pt: n2wordsPt,
18
+ zh: n2wordsZh,
19
+ ja: n2wordsJa
20
+ };
4
21
  import DialogContentText from "@mui/material/DialogContentText";
5
22
  import Grid from "@mui/material/Grid";
6
23
  import { Box } from "@mui/material";
@@ -147,12 +164,12 @@ function CreatePhrase({
147
164
  german: "de",
148
165
  english: "en",
149
166
  french: "fr",
150
- portuguese: "pt"
167
+ portuguese: "pt",
168
+ chinese: "zh",
169
+ japanese: "ja"
151
170
  };
152
171
  const languageCode = languageMapping[learnLang];
153
- const numberToText = n2words(alternativeVersion, {
154
- lang: languageCode
155
- });
172
+ const numberToText = n2wordsConverters[languageCode]?.(alternativeVersion) ?? alternativeVersion;
156
173
  stringMatch = localeCompare(removeAllSymbols(numberToText), removeAllSymbols(finalTranscript));
157
174
  if (stringMatch === 0) {
158
175
  return true;
@@ -170,9 +187,7 @@ function CreatePhrase({
170
187
  portuguese: "pt"
171
188
  };
172
189
  const languageCode = languageMapping[learnLang];
173
- const numberToText = n2words(word, {
174
- lang: languageCode
175
- });
190
+ const numberToText = n2wordsConverters[languageCode]?.(word) ?? word;
176
191
  newStringArray[index] = numberToText;
177
192
  }
178
193
  });
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import useMediaQuery from "@mui/material/useMediaQuery";
4
4
  import { useTheme } from "@mui/material/styles";
5
5
  import { makeStyles } from "tss-react/mui";
@@ -807,28 +807,26 @@ function Bot({
807
807
  handleClose: handleCloseHelp,
808
808
  children: /*#__PURE__*/_jsx(Tutorial, {})
809
809
  }), /*#__PURE__*/_jsx(Joyride, {
810
- callback: handleJoyrideCallback,
810
+ onEvent: handleJoyrideCallback,
811
811
  continuous: true,
812
812
  run: run,
813
813
  scrollToFirstStep: true,
814
- showProgress: true,
815
- showSkipButton: true,
816
814
  steps: steps,
817
- styles: {
818
- options: {
819
- zIndex: 10000,
820
- arrowColor: theme.palette.background.paper,
821
- backgroundColor: theme.palette.background.paper,
822
- primaryColor: theme.palette.primary.main,
823
- textColor: theme.palette.text.primary
824
- }
825
- },
826
815
  locale: {
827
816
  back: t("back"),
828
817
  close: t("close"),
829
818
  last: t("last"),
830
819
  next: t("next"),
831
820
  skip: t("skip")
821
+ },
822
+ options: {
823
+ showProgress: true,
824
+ zIndex: 10000,
825
+ arrowColor: theme.palette.background.paper,
826
+ backgroundColor: theme.palette.background.paper,
827
+ primaryColor: theme.palette.primary.main,
828
+ textColor: theme.palette.text.primary,
829
+ buttons: ['back', 'close', 'primary', 'skip']
832
830
  }
833
831
  })]
834
832
  });
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { useTheme } from "@mui/material/styles";
4
4
  import { makeStyles } from "tss-react/mui";
5
5
  import { Slide, Button, IconButton, Dialog, AppBar, Toolbar, Tabs, Tab, Box, Typography, Avatar, Tooltip, useMediaQuery, SpeedDial, SpeedDialAction, SpeedDialIcon } from "@mui/material";
@@ -919,28 +919,26 @@ function Roleplay({
919
919
  initialTopicGoal: initialTopicGoal,
920
920
  autoSelect: true
921
921
  }), /*#__PURE__*/_jsx(Joyride, {
922
- callback: handleJoyrideCallback,
922
+ onEvent: handleJoyrideCallback,
923
923
  continuous: true,
924
924
  run: run,
925
925
  scrollToFirstStep: true,
926
- showProgress: true,
927
- showSkipButton: true,
928
926
  steps: steps,
929
- styles: {
930
- options: {
931
- zIndex: 10000,
932
- arrowColor: theme.palette.background.paper,
933
- backgroundColor: theme.palette.background.paper,
934
- primaryColor: theme.palette.primary.main,
935
- textColor: theme.palette.text.primary
936
- }
937
- },
938
927
  locale: {
939
928
  back: t("back"),
940
929
  close: t("close"),
941
930
  last: t("last"),
942
931
  next: t("next"),
943
932
  skip: t("skip")
933
+ },
934
+ options: {
935
+ showProgress: true,
936
+ zIndex: 10000,
937
+ arrowColor: theme.palette.background.paper,
938
+ backgroundColor: theme.palette.background.paper,
939
+ primaryColor: theme.palette.primary.main,
940
+ textColor: theme.palette.text.primary,
941
+ buttons: ['back', 'close', 'primary', 'skip']
944
942
  }
945
943
  })]
946
944
  });
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect, useRef, memo } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { Slide, Dialog, IconButton, Typography, Box, Tooltip, Button } from "@mui/material";
4
4
  import LightbulbIcon from "@mui/icons-material/Lightbulb";
5
5
  import { makeStyles } from "tss-react/mui";
@@ -684,28 +684,26 @@ function Bot({
684
684
  goBackToAssignment: goBackToAssignment
685
685
  })]
686
686
  }), /*#__PURE__*/_jsx(Joyride, {
687
- callback: handleJoyrideCallback,
687
+ onEvent: handleJoyrideCallback,
688
688
  continuous: true,
689
689
  run: run,
690
690
  scrollToFirstStep: true,
691
- showProgress: true,
692
- showSkipButton: true,
693
691
  steps: steps,
694
- styles: {
695
- options: {
696
- zIndex: 10000,
697
- arrowColor: theme.palette.background.paper,
698
- backgroundColor: theme.palette.background.paper,
699
- primaryColor: theme.palette.primary.main,
700
- textColor: theme.palette.text.primary
701
- }
702
- },
703
692
  locale: {
704
693
  back: t("back"),
705
694
  close: t("close"),
706
695
  last: t("last"),
707
696
  next: t("next"),
708
697
  skip: t("skip")
698
+ },
699
+ options: {
700
+ showProgress: true,
701
+ zIndex: 10000,
702
+ arrowColor: theme.palette.background.paper,
703
+ backgroundColor: theme.palette.background.paper,
704
+ primaryColor: theme.palette.primary.main,
705
+ textColor: theme.palette.text.primary,
706
+ buttons: ['back', 'close', 'primary', 'skip']
709
707
  }
710
708
  })]
711
709
  });
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect, forwardRef, useRef } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { Grid, Slide, IconButton, Button, Dialog, AppBar, Toolbar, Tooltip, Typography, Box } from "@mui/material";
4
4
  import LightbulbIcon from "@mui/icons-material/Lightbulb";
5
5
  import { makeStyles } from "tss-react/mui";
@@ -983,30 +983,27 @@ function Listener({
983
983
  inTopic: courseId && sectionId && topicId,
984
984
  goBackToAssignment: goBackToAssignment
985
985
  }), /*#__PURE__*/_jsx(Joyride, {
986
- callback: handleJoyrideCallback,
986
+ onEvent: handleJoyrideCallback,
987
987
  continuous: true,
988
988
  run: run,
989
989
  scrollToFirstStep: true,
990
- showProgress: true,
991
- showSkipButton: true,
992
990
  steps: steps,
993
- scrollOffset: 100,
994
- disableScrollParentFix: true,
995
- styles: {
996
- options: {
997
- zIndex: 10000,
998
- arrowColor: theme.palette.background.paper,
999
- backgroundColor: theme.palette.background.paper,
1000
- primaryColor: theme.palette.primary.main,
1001
- textColor: theme.palette.text.primary
1002
- }
1003
- },
1004
991
  locale: {
1005
992
  back: t("back"),
1006
993
  close: t("close"),
1007
994
  last: t("last"),
1008
995
  next: t("next"),
1009
996
  skip: t("skip")
997
+ },
998
+ options: {
999
+ showProgress: true,
1000
+ scrollOffset: 100,
1001
+ zIndex: 10000,
1002
+ arrowColor: theme.palette.background.paper,
1003
+ backgroundColor: theme.palette.background.paper,
1004
+ primaryColor: theme.palette.primary.main,
1005
+ textColor: theme.palette.text.primary,
1006
+ buttons: ['back', 'close', 'primary', 'skip']
1010
1007
  }
1011
1008
  })]
1012
1009
  });
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState, useRef } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { Grid, Slide, IconButton, Button, Dialog, AppBar, Toolbar, Tooltip, Typography, Box } from "@mui/material";
4
4
  import LightbulbIcon from "@mui/icons-material/Lightbulb";
5
5
  import { makeStyles } from "tss-react/mui";
@@ -760,30 +760,27 @@ function Meaning({
760
760
  inTopic: courseId && sectionId && topicId,
761
761
  goBackToAssignment: goBackToAssignment
762
762
  }), /*#__PURE__*/_jsx(Joyride, {
763
- callback: handleJoyrideCallback,
763
+ onEvent: handleJoyrideCallback,
764
764
  continuous: true,
765
765
  run: run,
766
766
  scrollToFirstStep: true,
767
- showProgress: true,
768
- showSkipButton: true,
769
767
  steps: steps,
770
- scrollOffset: 100,
771
- disableScrollParentFix: true,
772
- styles: {
773
- options: {
774
- zIndex: 10000,
775
- arrowColor: theme.palette.background.paper,
776
- backgroundColor: theme.palette.background.paper,
777
- primaryColor: theme.palette.primary.main,
778
- textColor: theme.palette.text.primary
779
- }
780
- },
781
768
  locale: {
782
769
  back: t("back"),
783
770
  close: t("close"),
784
771
  last: t("last"),
785
772
  next: t("next"),
786
773
  skip: t("skip")
774
+ },
775
+ options: {
776
+ showProgress: true,
777
+ scrollOffset: 100,
778
+ zIndex: 10000,
779
+ arrowColor: theme.palette.background.paper,
780
+ backgroundColor: theme.palette.background.paper,
781
+ primaryColor: theme.palette.primary.main,
782
+ textColor: theme.palette.text.primary,
783
+ buttons: ['back', 'close', 'primary', 'skip']
787
784
  }
788
785
  })]
789
786
  });
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect, useRef } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { makeStyles } from "tss-react/mui";
4
4
  import { useTheme } from "@mui/material/styles";
5
5
  import { Grid, Slide, IconButton, Button, Toolbar, AppBar, Dialog, Typography, Box, Tooltip } from "@mui/material";
@@ -938,29 +938,27 @@ function Pronouncer({
938
938
  inTopic: courseId && sectionId && topicId,
939
939
  goBackToAssignment: goBackToAssignment
940
940
  }), /*#__PURE__*/_jsx(Joyride, {
941
- callback: handleJoyrideCallback,
941
+ onEvent: handleJoyrideCallback,
942
942
  continuous: true,
943
943
  run: run,
944
944
  scrollToFirstStep: true,
945
- showProgress: true,
946
- showSkipButton: true,
947
945
  steps: steps,
948
- scrollOffset: 100,
949
- styles: {
950
- options: {
951
- zIndex: 10000,
952
- arrowColor: theme.palette.background.paper,
953
- backgroundColor: theme.palette.background.paper,
954
- primaryColor: theme.palette.primary.main,
955
- textColor: theme.palette.text.primary
956
- }
957
- },
958
946
  locale: {
959
947
  back: t("back"),
960
948
  close: t("close"),
961
949
  last: t("last"),
962
950
  next: t("next"),
963
951
  skip: t("skip")
952
+ },
953
+ options: {
954
+ showProgress: true,
955
+ scrollOffset: 100,
956
+ zIndex: 10000,
957
+ arrowColor: theme.palette.background.paper,
958
+ backgroundColor: theme.palette.background.paper,
959
+ primaryColor: theme.palette.primary.main,
960
+ textColor: theme.palette.text.primary,
961
+ buttons: ['back', 'close', 'primary', 'skip']
964
962
  }
965
963
  })]
966
964
  });
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState, memo } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { useTheme, alpha } from "@mui/material/styles";
4
4
  import { withStyles } from "tss-react/mui";
5
5
  import { makeStyles } from "tss-react/mui";
@@ -913,29 +913,27 @@ function Roleplay({
913
913
  goBack: handleCloseExercise,
914
914
  inTopic: courseId && sectionId && topicId
915
915
  }), /*#__PURE__*/_jsx(Joyride, {
916
- callback: handleJoyrideCallback,
916
+ onEvent: handleJoyrideCallback,
917
917
  continuous: true,
918
918
  run: run,
919
919
  scrollToFirstStep: true,
920
- showProgress: true,
921
- showSkipButton: true,
922
920
  steps: steps,
923
- scrollOffset: 300,
924
- styles: {
925
- options: {
926
- zIndex: 10000,
927
- arrowColor: theme.palette.background.paper,
928
- backgroundColor: theme.palette.background.paper,
929
- primaryColor: theme.palette.primary.main,
930
- textColor: theme.palette.text.primary
931
- }
932
- },
933
921
  locale: {
934
922
  back: t("back"),
935
923
  close: t("close"),
936
924
  last: t("last"),
937
925
  next: t("next"),
938
926
  skip: t("skip")
927
+ },
928
+ options: {
929
+ showProgress: true,
930
+ scrollOffset: 300,
931
+ zIndex: 10000,
932
+ arrowColor: theme.palette.background.paper,
933
+ backgroundColor: theme.palette.background.paper,
934
+ primaryColor: theme.palette.primary.main,
935
+ textColor: theme.palette.text.primary,
936
+ buttons: ['back', 'close', 'primary', 'skip']
939
937
  }
940
938
  })]
941
939
  });
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState, memo } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { useLocation, useNavigate, useParams } from "react-router";
4
4
  import { useTheme } from "@mui/material/styles";
5
5
  import { Slide, IconButton, Dialog, Box, Divider, Tooltip } from "@mui/material";
@@ -368,29 +368,27 @@ function Roleplay({
368
368
  })
369
369
  })]
370
370
  }), /*#__PURE__*/_jsx(Joyride, {
371
- callback: handleJoyrideCallback,
371
+ onEvent: handleJoyrideCallback,
372
372
  continuous: true,
373
373
  run: run,
374
374
  scrollToFirstStep: true,
375
- showProgress: true,
376
- showSkipButton: true,
377
375
  steps: steps,
378
- scrollOffset: 300,
379
- styles: {
380
- options: {
381
- zIndex: 10000,
382
- arrowColor: theme.palette.background.paper,
383
- backgroundColor: theme.palette.background.paper,
384
- primaryColor: theme.palette.primary.main,
385
- textColor: theme.palette.text.primary
386
- }
387
- },
388
376
  locale: {
389
377
  back: t("back"),
390
378
  close: t("close"),
391
379
  last: t("last"),
392
380
  next: t("next"),
393
381
  skip: t("skip")
382
+ },
383
+ options: {
384
+ showProgress: true,
385
+ scrollOffset: 300,
386
+ zIndex: 10000,
387
+ arrowColor: theme.palette.background.paper,
388
+ backgroundColor: theme.palette.background.paper,
389
+ primaryColor: theme.palette.primary.main,
390
+ textColor: theme.palette.text.primary,
391
+ buttons: ['back', 'close', 'primary', 'skip']
394
392
  }
395
393
  })]
396
394
  });
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState, forwardRef, useRef } from "react";
2
- import Joyride, { STATUS } from "react-joyride";
2
+ import { Joyride, STATUS } from "react-joyride";
3
3
  import { Grid, Slide, IconButton, Button, Dialog, AppBar, Toolbar, Tooltip, Typography, Box } from "@mui/material";
4
4
  import LightbulbIcon from "@mui/icons-material/Lightbulb";
5
5
  import { red } from "@mui/material/colors";
@@ -990,30 +990,27 @@ function Translator({
990
990
  inTopic: courseId && sectionId && topicId,
991
991
  goBackToAssignment: goBackToAssignment
992
992
  }), /*#__PURE__*/_jsx(Joyride, {
993
- callback: handleJoyrideCallback,
993
+ onEvent: handleJoyrideCallback,
994
994
  continuous: true,
995
995
  run: run,
996
996
  scrollToFirstStep: true,
997
- showProgress: true,
998
- showSkipButton: true,
999
997
  steps: steps,
1000
- scrollOffset: 100,
1001
- disableScrollParentFix: true,
1002
- styles: {
1003
- options: {
1004
- zIndex: 10000,
1005
- arrowColor: theme.palette.background.paper,
1006
- backgroundColor: theme.palette.background.paper,
1007
- primaryColor: theme.palette.primary.main,
1008
- textColor: theme.palette.text.primary
1009
- }
1010
- },
1011
998
  locale: {
1012
999
  back: t("back"),
1013
1000
  close: t("close"),
1014
1001
  last: t("last"),
1015
1002
  next: t("next"),
1016
1003
  skip: t("skip")
1004
+ },
1005
+ options: {
1006
+ showProgress: true,
1007
+ scrollOffset: 100,
1008
+ zIndex: 10000,
1009
+ arrowColor: theme.palette.background.paper,
1010
+ backgroundColor: theme.palette.background.paper,
1011
+ primaryColor: theme.palette.primary.main,
1012
+ textColor: theme.palette.text.primary,
1013
+ buttons: ['back', 'close', 'primary', 'skip']
1017
1014
  }
1018
1015
  })]
1019
1016
  });
@@ -8,7 +8,7 @@ import Close from "@mui/icons-material/Close";
8
8
  import PersonAddIcon from "@mui/icons-material/PersonAdd";
9
9
  import People from "@mui/icons-material/People";
10
10
  import SettingsIcon from "@mui/icons-material/Settings";
11
- import Joyride, { STATUS } from "react-joyride";
11
+ import { Joyride, STATUS } from "react-joyride";
12
12
  import ExerciseProgressBar from "../../Misc/ExerciseProgressBar/ExerciseProgressBar";
13
13
  import VoiceSpeedSelector from "../../Misc/VoiceSpeed/VoiceSpeed";
14
14
  import Leaderboard from "../../Lists/Leaderboard/Leaderboard";
@@ -612,28 +612,26 @@ export default function Game({
612
612
  exercise: exercise,
613
613
  roleplay: selectedRoleplay
614
614
  }), /*#__PURE__*/_jsx(Joyride, {
615
- callback: handleJoyrideCallback,
615
+ onEvent: handleJoyrideCallback,
616
616
  continuous: true,
617
617
  run: run,
618
618
  scrollToFirstStep: true,
619
- showProgress: true,
620
- showSkipButton: true,
621
619
  steps: steps,
622
- styles: {
623
- options: {
624
- zIndex: 10000,
625
- arrowColor: theme.palette.background.paper,
626
- backgroundColor: theme.palette.background.paper,
627
- primaryColor: theme.palette.primary.main,
628
- textColor: theme.palette.text.primary
629
- }
630
- },
631
620
  locale: {
632
621
  back: t("back"),
633
622
  close: t("close"),
634
623
  last: t("last"),
635
624
  next: t("next"),
636
625
  skip: t("skip")
626
+ },
627
+ options: {
628
+ showProgress: true,
629
+ zIndex: 10000,
630
+ arrowColor: theme.palette.background.paper,
631
+ backgroundColor: theme.palette.background.paper,
632
+ primaryColor: theme.palette.primary.main,
633
+ textColor: theme.palette.text.primary,
634
+ buttons: ['back', 'close', 'primary', 'skip']
637
635
  }
638
636
  }), /*#__PURE__*/_jsx(FinalScoreDrawer, {
639
637
  t: t,
@@ -114,6 +114,11 @@ function LiveMeaning({
114
114
  speak(definitionText, voice, false, "#currentDefinition", voiceLanguageCode, false, voicePitch, () => setIsFinishedInitialSpeaking(true));
115
115
  }
116
116
  }, [currentQuestion?.phrase, isCreator]);
117
+ useEffect(() => {
118
+ if (isCreator && isTimeUp && currentQuestion?.phrase) {
119
+ speak(currentQuestion.phrase, voice, false, null, voiceLanguageCode, false, voicePitch);
120
+ }
121
+ }, [isTimeUp]);
117
122
  const voiceMap = getVoiceImages(voices || []);
118
123
  const getVoiceImage = () => {
119
124
  try {
@@ -9,12 +9,14 @@ import PlayCircleOutline from "@mui/icons-material/PlayCircleOutline";
9
9
  import People from "@mui/icons-material/People";
10
10
  import StudentWaitingMessage from "../../Misc/StudentWaitingMessage/StudentWaitingMessage";
11
11
  import AutoStoriesIcon from "@mui/icons-material/AutoStories";
12
+ import ExtensionIcon from '@mui/icons-material/Extension';
12
13
  import MedalSelector from "../../Misc/MedalSelector/MedalSelector";
13
14
  import OndemandVideo from "@mui/icons-material/OndemandVideo";
14
15
  import VideoViewer from "../../Dialogs/VideoViewer/VideoViewer";
15
16
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
16
17
  export default function WaitingRoom({
17
18
  topicImage,
19
+ phraseListImage,
18
20
  t,
19
21
  topicName,
20
22
  topicDescription,
@@ -70,6 +72,13 @@ export default function WaitingRoom({
70
72
  style: {
71
73
  borderRadius: "5%"
72
74
  }
75
+ }) : phraseListImage ? /*#__PURE__*/_jsx("img", {
76
+ src: phraseListImage,
77
+ width: 250,
78
+ alt: topicName || t("topic_image"),
79
+ style: {
80
+ borderRadius: "5%"
81
+ }
73
82
  }) : topicImage ? /*#__PURE__*/_jsx("img", {
74
83
  src: topicImage,
75
84
  width: 250,
@@ -144,6 +153,11 @@ export default function WaitingRoom({
144
153
  children: /*#__PURE__*/_jsx(AutoStoriesIcon, {
145
154
  fontSize: "large"
146
155
  })
156
+ }), exercise.toLowerCase() === "meaning" && /*#__PURE__*/_jsx(ListItemIcon, {
157
+ children: /*#__PURE__*/_jsx(ExtensionIcon, {
158
+ fontSize: "large",
159
+ "aria-hidden": "true"
160
+ })
147
161
  }), /*#__PURE__*/_jsx(ListItemText, {
148
162
  primary: t(exerciseName),
149
163
  secondary: isLgScreen ? t(exerciseDescription) : /*#__PURE__*/_jsx(_Fragment, {
@@ -2,7 +2,24 @@ import { useEffect, useRef, useState } from "react";
2
2
  import { Button, Drawer, Box, Checkbox, FormGroup, FormControlLabel, Typography, Tooltip } from "@mui/material";
3
3
  import { orange } from "@mui/material/colors";
4
4
  import { styled } from "@mui/system";
5
- import n2words from "n2words";
5
+ import { toCardinal as n2wordsEn } from "n2words/en-US";
6
+ import { toCardinal as n2wordsEs } from "n2words/es-ES";
7
+ import { toCardinal as n2wordsDe } from "n2words/de-DE";
8
+ import { toCardinal as n2wordsFr } from "n2words/fr-FR";
9
+ import { toCardinal as n2wordsIt } from "n2words/it-IT";
10
+ import { toCardinal as n2wordsPt } from "n2words/pt-PT";
11
+ import { toCardinal as n2wordsZh } from "n2words/zh-Hans-CN";
12
+ import { toCardinal as n2wordsJa } from "n2words/ja-JP";
13
+ const n2wordsConverters = {
14
+ en: n2wordsEn,
15
+ es: n2wordsEs,
16
+ de: n2wordsDe,
17
+ fr: n2wordsFr,
18
+ it: n2wordsIt,
19
+ pt: n2wordsPt,
20
+ zh: n2wordsZh,
21
+ ja: n2wordsJa
22
+ };
6
23
  import VeryhappyIcon from "../../img/sentiment_very_satisfied_24px.svg";
7
24
  import DissatisfiedIcon from "../../img/sentiment_dissatisfied_24px.svg";
8
25
  import HappyIcon from "../../img/sentiment_satisfied_24px.svg";
@@ -113,14 +130,14 @@ function TranscriptBox({
113
130
  german: "de",
114
131
  english: "en",
115
132
  french: "fr",
116
- portuguese: "pt"
133
+ portuguese: "pt",
134
+ chinese: "zh",
135
+ japanese: "ja"
117
136
  };
118
137
  const languageCode = languageMapping[learnLang?.toLowerCase()];
119
138
  if (transcriptText) {
120
139
  if (/^\d+$/.test(transcriptText)) {
121
- const numberToText = n2words(transcriptText, {
122
- lang: languageCode
123
- });
140
+ const numberToText = n2wordsConverters[languageCode]?.(transcriptText) ?? transcriptText;
124
141
  return numberToText;
125
142
  } else {
126
143
  return transcriptText;
@@ -173,6 +173,10 @@ const CustomChipInput = props => {
173
173
  const [inputValue, setInputValue] = useState("");
174
174
  const [focusedChip, setFocusedChip] = useState(null);
175
175
  const [inputBlurTimeout, setInputBlurTimeout] = useState(null);
176
+ const chipsRef = useRef(chips);
177
+ useEffect(() => {
178
+ chipsRef.current = chips;
179
+ }, [chips]);
176
180
  useEffect(() => {
177
181
  clearTimeout(inputBlurTimeout);
178
182
  }, [inputBlurTimeout]);
@@ -180,14 +184,13 @@ const CustomChipInput = props => {
180
184
  if (onBlur) onBlur(event);
181
185
  setFocusedChip(null);
182
186
  const value = event.target.value;
183
- let addChipOptions;
184
187
  if (blurBehavior === "add" || blurBehavior === "add-or-clear") {
185
188
  if (delayBeforeAdd) {
186
189
  const numChipsBefore = chips.length;
187
190
  setInputBlurTimeout(setTimeout(() => {
188
- if (chips.length === numChipsBefore) handleAddChip(value, addChipOptions);else setInputValue("");
191
+ if (chipsRef.current.length === numChipsBefore) handleAddChip(value, chipsRef.current);else setInputValue("");
189
192
  }, 150));
190
- } else handleAddChip(value, addChipOptions);
193
+ } else handleAddChip(value);
191
194
  } else if (blurBehavior === "clear") setInputValue("");
192
195
  };
193
196
  const handleKeyDown = event => {
@@ -225,13 +228,13 @@ const CustomChipInput = props => {
225
228
  break;
226
229
  }
227
230
  };
228
- const handleAddChip = chip => {
231
+ const handleAddChip = (chip, currentChips = chips) => {
229
232
  if (chip.trim().length > 0) {
230
- if (!allowDuplicates && chips.includes(chip)) {
233
+ if (!allowDuplicates && currentChips.includes(chip)) {
231
234
  return;
232
235
  }
233
236
  const splitChips = chip.split(delimiter);
234
- const updatedChips = [...chips, ...splitChips];
237
+ const updatedChips = [...currentChips, ...splitChips];
235
238
  setChips(updatedChips);
236
239
  setInputValue("");
237
240
  if (onAdd) onAdd(chip);
@@ -16,7 +16,7 @@ import { useTheme } from "@mui/material/styles";
16
16
  import { makeStyles } from "tss-react/mui";
17
17
  import Typography from "@mui/material/Typography";
18
18
  import NewText from "../../img/NewText.svg";
19
- import Joyride, { STATUS } from "react-joyride";
19
+ import { Joyride, STATUS } from "react-joyride";
20
20
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
21
  function TabPanel(props) {
22
22
  const {
@@ -326,52 +326,48 @@ function ResponsiveTabs({
326
326
  })
327
327
  }, fab.id))
328
328
  }), run && /*#__PURE__*/_jsx(Joyride, {
329
- callback: handleJoyrideCallback,
329
+ onEvent: handleJoyrideCallback,
330
330
  continuous: true,
331
331
  run: run,
332
332
  scrollToFirstStep: true,
333
- showProgress: true,
334
- showSkipButton: true,
335
333
  steps: steps,
336
- styles: {
337
- options: {
338
- zIndex: 10000,
339
- arrowColor: theme.palette.background.paper,
340
- backgroundColor: theme.palette.background.paper,
341
- primaryColor: theme.palette.primary.main,
342
- textColor: theme.palette.text.primary
343
- }
344
- },
345
334
  locale: {
346
335
  back: t("back"),
347
336
  close: t("close"),
348
337
  last: t("last"),
349
338
  next: t("next"),
350
339
  skip: t("skip")
340
+ },
341
+ options: {
342
+ showProgress: true,
343
+ zIndex: 10000,
344
+ arrowColor: theme.palette.background.paper,
345
+ backgroundColor: theme.palette.background.paper,
346
+ primaryColor: theme.palette.primary.main,
347
+ textColor: theme.palette.text.primary,
348
+ buttons: ['back', 'close', 'primary', 'skip']
351
349
  }
352
350
  }), creatorRun && /*#__PURE__*/_jsx(Joyride, {
353
- callback: handleCreatorJoyrideCallback,
351
+ onEvent: handleCreatorJoyrideCallback,
354
352
  continuous: true,
355
353
  run: creatorRun,
356
354
  scrollToFirstStep: true,
357
- showProgress: true,
358
- showSkipButton: true,
359
355
  steps: creatorSteps,
360
- styles: {
361
- options: {
362
- zIndex: 10000,
363
- arrowColor: theme.palette.background.paper,
364
- backgroundColor: theme.palette.background.paper,
365
- primaryColor: theme.palette.primary.main,
366
- textColor: theme.palette.text.primary
367
- }
368
- },
369
356
  locale: {
370
357
  back: t("back"),
371
358
  close: t("close"),
372
359
  last: t("last"),
373
360
  next: t("next"),
374
361
  skip: t("skip")
362
+ },
363
+ options: {
364
+ showProgress: true,
365
+ zIndex: 10000,
366
+ arrowColor: theme.palette.background.paper,
367
+ backgroundColor: theme.palette.background.paper,
368
+ primaryColor: theme.palette.primary.main,
369
+ textColor: theme.palette.text.primary,
370
+ buttons: ['back', 'close', 'primary', 'skip']
375
371
  }
376
372
  })]
377
373
  });
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect, useRef, useMemo } from "react";
2
2
  import { Link as RouterLink, useNavigate, useLocation } from "react-router";
3
- import Joyride, { STATUS } from "react-joyride";
3
+ import { Joyride, STATUS } from "react-joyride";
4
4
  import { Typography, Button, Box, Menu, MenuItem, IconButton, Tooltip } from "@mui/material";
5
5
  import { useTheme } from "@mui/material/styles";
6
6
  import { makeStyles } from "tss-react/mui";
@@ -1578,22 +1578,20 @@ function Classroom({
1578
1578
  handleClose: () => setDisplayDynamicAiDialog(false),
1579
1579
  t: t
1580
1580
  }), run && /*#__PURE__*/_jsx(Joyride, {
1581
- callback: handleJoyrideCallback,
1581
+ onEvent: handleJoyrideCallback,
1582
+ options: {
1583
+ buttons: ['skip', 'primary', 'back', 'close'],
1584
+ showProgress: true,
1585
+ zIndex: 10000,
1586
+ arrowColor: theme.palette.background.paper,
1587
+ backgroundColor: theme.palette.background.paper,
1588
+ primaryColor: theme.palette.primary.main,
1589
+ textColor: theme.palette.text.primary
1590
+ },
1582
1591
  continuous: true,
1583
1592
  run: run,
1584
1593
  scrollToFirstStep: true,
1585
- showProgress: true,
1586
- showSkipButton: true,
1587
1594
  steps: steps,
1588
- styles: {
1589
- options: {
1590
- zIndex: 10000,
1591
- arrowColor: theme.palette.background.paper,
1592
- backgroundColor: theme.palette.background.paper,
1593
- primaryColor: theme.palette.primary.main,
1594
- textColor: theme.palette.text.primary
1595
- }
1596
- },
1597
1595
  locale: {
1598
1596
  back: t("back"),
1599
1597
  close: t("close"),
@@ -1,7 +1,24 @@
1
1
  import { useState, useEffect } from "react";
2
2
  import { useNavigate } from "react-router";
3
3
  import distance from "jaro-winkler";
4
- import n2words from "n2words";
4
+ import { toCardinal as n2wordsEn } from "n2words/en-US";
5
+ import { toCardinal as n2wordsEs } from "n2words/es-ES";
6
+ import { toCardinal as n2wordsDe } from "n2words/de-DE";
7
+ import { toCardinal as n2wordsFr } from "n2words/fr-FR";
8
+ import { toCardinal as n2wordsIt } from "n2words/it-IT";
9
+ import { toCardinal as n2wordsPt } from "n2words/pt-PT";
10
+ import { toCardinal as n2wordsZh } from "n2words/zh-Hans-CN";
11
+ import { toCardinal as n2wordsJa } from "n2words/ja-JP";
12
+ const n2wordsConverters = {
13
+ en: n2wordsEn,
14
+ es: n2wordsEs,
15
+ de: n2wordsDe,
16
+ fr: n2wordsFr,
17
+ it: n2wordsIt,
18
+ pt: n2wordsPt,
19
+ zh: n2wordsZh,
20
+ ja: n2wordsJa
21
+ };
5
22
  import { shuffle, removeAllSymbols, removeAllSymbolsFillInBlanks, formatMarkdownNewlines, localeCompare, localeCompareCase, removeExtraWhiteSpaces } from "../utils/index";
6
23
  import { botErrorMessage } from "../utils/constants";
7
24
  import BotNualaImage from "../img/bot_nuala.svg";
@@ -1062,9 +1079,7 @@ export default function useExerciseState({
1062
1079
  portuguese: "pt"
1063
1080
  };
1064
1081
  const languageCode = languageMapping[learnLang];
1065
- const numberToText = n2words(finalTranscript, {
1066
- lang: languageCode
1067
- });
1082
+ const numberToText = n2wordsConverters[languageCode]?.(finalTranscript) ?? finalTranscript;
1068
1083
  stringMatch = localeCompare(removeAllSymbols(numberToText), removeAllSymbols(answer.phrase));
1069
1084
  if (stringMatch === 0) {
1070
1085
  return true;
@@ -1082,9 +1097,7 @@ export default function useExerciseState({
1082
1097
  portuguese: "pt"
1083
1098
  };
1084
1099
  const languageCode = languageMapping[learnLang];
1085
- const numberToText = n2words(word, {
1086
- lang: languageCode
1087
- });
1100
+ const numberToText = n2wordsConverters[languageCode]?.(word) ?? word;
1088
1101
  newStringArray[index] = numberToText;
1089
1102
  }
1090
1103
  });
@@ -1207,12 +1220,12 @@ export default function useExerciseState({
1207
1220
  german: "de",
1208
1221
  english: "en",
1209
1222
  french: "fr",
1210
- portuguese: "pt"
1223
+ portuguese: "pt",
1224
+ chinese: "zh",
1225
+ japanese: "ja"
1211
1226
  };
1212
1227
  const languageCode = languageMapping[learnLang];
1213
- const numberToText = n2words(listeningText, {
1214
- lang: languageCode
1215
- });
1228
+ const numberToText = n2wordsConverters[languageCode]?.(listeningText) ?? listeningText;
1216
1229
  phraseMatch = localeCompareCase(removeAllSymbols(numberToText), removeAllSymbols(currentPhrase.phrase));
1217
1230
  if (phraseMatch === 0) {
1218
1231
  return true;
@@ -1230,9 +1243,7 @@ export default function useExerciseState({
1230
1243
  portuguese: "pt"
1231
1244
  };
1232
1245
  const languageCode = languageMapping[learnLang];
1233
- const numberToText = n2words(word, {
1234
- lang: languageCode
1235
- });
1246
+ const numberToText = n2wordsConverters[languageCode]?.(word) ?? word;
1236
1247
  newStringArray[index] = numberToText;
1237
1248
  }
1238
1249
  });
@@ -1266,12 +1277,12 @@ export default function useExerciseState({
1266
1277
  german: "de",
1267
1278
  english: "en",
1268
1279
  french: "fr",
1269
- portuguese: "pt"
1280
+ portuguese: "pt",
1281
+ chinese: "zh",
1282
+ japanese: "ja"
1270
1283
  };
1271
1284
  const languageCode = languageMapping[learnLang];
1272
- const numberToText = n2words(listeningText, {
1273
- lang: languageCode
1274
- });
1285
+ const numberToText = n2wordsConverters[languageCode]?.(listeningText) ?? listeningText;
1275
1286
  phraseMatch = localeCompare(removeAllSymbols(numberToText), removeAllSymbols(currentPhrase.phrase));
1276
1287
  if (phraseMatch === 0) {
1277
1288
  return true;
@@ -1289,9 +1300,7 @@ export default function useExerciseState({
1289
1300
  portuguese: "pt"
1290
1301
  };
1291
1302
  const languageCode = languageMapping[learnLang];
1292
- const numberToText = n2words(word, {
1293
- lang: languageCode
1294
- });
1303
+ const numberToText = n2wordsConverters[languageCode]?.(word) ?? word;
1295
1304
  newStringArray[index] = numberToText;
1296
1305
  }
1297
1306
  });
@@ -1859,9 +1868,7 @@ export default function useExerciseState({
1859
1868
  portuguese: "pt"
1860
1869
  };
1861
1870
  const languageCode = languageMapping[learnLang];
1862
- const numberToText = n2words(finalTranscript, {
1863
- lang: languageCode
1864
- });
1871
+ const numberToText = n2wordsConverters[languageCode]?.(finalTranscript) ?? finalTranscript;
1865
1872
  stringMatch = localeCompare(removeAllSymbols(numberToText), removeAllSymbols(answer));
1866
1873
  if (stringMatch === 0) {
1867
1874
  return true;
@@ -1879,9 +1886,7 @@ export default function useExerciseState({
1879
1886
  portuguese: "pt"
1880
1887
  };
1881
1888
  const languageCode = languageMapping[learnLang];
1882
- const numberToText = n2words(word, {
1883
- lang: languageCode
1884
- });
1889
+ const numberToText = n2wordsConverters[languageCode]?.(word) ?? word;
1885
1890
  newStringArray[index] = numberToText;
1886
1891
  }
1887
1892
  stringMatch = localeCompare(removeAllSymbols(newStringArray.join(" ")), removeAllSymbols(currentPhrase.phrase));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nualang/nualang-ui-components",
3
- "version": "0.1.1360",
3
+ "version": "0.1.1362",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -18,12 +18,11 @@
18
18
  "@dnd-kit/utilities": "3.2.2",
19
19
  "@emotion/react": "^11.13",
20
20
  "@emotion/styled": "^11.13",
21
- "@hookform/resolvers": "^3.6.0",
21
+ "@hookform/resolvers": "^5.2.2",
22
22
  "@json2csv/plainjs": "^7.0.1",
23
23
  "@nualang/avatars": "2.0.3",
24
24
  "@nualang/rivescript": "^2.2.2-alpha1",
25
- "ajv-keywords": "^3.5.2",
26
- "axios": "^1.13.1",
25
+ "axios": "^1.14.0",
27
26
  "base64-arraybuffer": "^1.0.2",
28
27
  "chart.js": "^4.5.1",
29
28
  "chartjs-plugin-datalabels": "^2.2.0",
@@ -46,7 +45,7 @@
46
45
  "kuromoji": "^0.1.2",
47
46
  "luxon": "^3.6.1",
48
47
  "moment": "^2.29.4",
49
- "n2words": "^1.23.1",
48
+ "n2words": "^4.0.0",
50
49
  "patch-package": "^8.0.0",
51
50
  "pino": "^10.2.1",
52
51
  "pinyin-pro": "^3.28.0",
@@ -60,16 +59,16 @@
60
59
  "react-dnd": "^16.0.1",
61
60
  "react-dnd-multi-backend": "^9.0.0",
62
61
  "react-dnd-test-backend": "^16.0.1",
63
- "react-dropzone": "^14.2.3",
62
+ "react-dropzone": "^15.0.0",
64
63
  "react-easy-crop": "^5.0.0",
65
64
  "react-feather": "^2.0",
66
65
  "react-flip-toolkit": "^7.1.0",
67
66
  "react-hook-form": "^7.71.1",
68
- "react-i18next": "^16.5.3",
67
+ "react-i18next": "^17.0.2",
69
68
  "react-infinite-scroll-component": "^6.1.0",
70
69
  "react-infinite-scroller": "^1.2.6",
71
- "react-intersection-observer": "10.0.2",
72
- "react-joyride": "^2.8.2",
70
+ "react-intersection-observer": "^10.0.3",
71
+ "react-joyride": "^3.0.2",
73
72
  "react-markdown": "^10.1.0",
74
73
  "react-modal-promise": "^1.0.2",
75
74
  "react-papaparse": "^4.1.0",
@@ -77,7 +76,7 @@
77
76
  "react-qrcode-logo": "^4.0.0",
78
77
  "react-refresh": "^0.18.0",
79
78
  "react-simplemde-editor": "5.2.0",
80
- "react-spreadsheet-grid": "^1.4.3",
79
+ "react-spreadsheet-grid": "^2.3.1",
81
80
  "react-swipeable-views": "^0.14.0",
82
81
  "rehype-raw": "^7.0.0",
83
82
  "socket.io-client": "^4.7.1",
@@ -95,21 +94,22 @@
95
94
  "@babel/preset-env": "^7.28.6",
96
95
  "@babel/preset-react": "^7.28.5",
97
96
  "@eslint/compat": "^2.0.2",
97
+ "@eslint/js": "^10.0.1",
98
98
  "@mui/icons-material": "^7.0.2",
99
99
  "@mui/lab": "^7.0.1-beta.21",
100
100
  "@mui/material": "^7.0.2",
101
101
  "@mui/system": "^7.0.2",
102
- "@mui/x-date-pickers": "^7.28.3",
103
- "@nualang/eslint-config-nualang": "0.2.0-alpha-4",
104
- "@nualang/nualang-api-and-queries": "^1.1.32",
102
+ "@mui/x-date-pickers": "^8.27.2",
103
+ "@nualang/eslint-config-nualang": "0.2.0-alpha-5",
104
+ "@nualang/nualang-api-and-queries": "^1.1.33",
105
105
  "@react-theming/storybook-addon": "^1.1.10",
106
106
  "@storybook/addon-docs": "^10.0.2",
107
107
  "@storybook/addon-links": "^10.0.2",
108
108
  "@storybook/builder-vite": "^10.0.2",
109
109
  "@storybook/react-vite": "^10.0.2",
110
- "@tanstack/react-query": "^5.90.21",
111
- "@tanstack/react-query-devtools": "^5.91.3",
112
- "@tanstack/react-query-persist-client": "^5.90.22",
110
+ "@tanstack/react-query": "^5.95.2",
111
+ "@tanstack/react-query-devtools": "^5.95.2",
112
+ "@tanstack/react-query-persist-client": "^5.95.2",
113
113
  "@testing-library/dom": "^10.4.0",
114
114
  "@testing-library/react": "^16.3.2",
115
115
  "@vitejs/plugin-react": "^5.1.0",
@@ -117,21 +117,21 @@
117
117
  "babel-plugin-macros": "^3.1.0",
118
118
  "chalk": "^5.4.1",
119
119
  "clsx": "^2.0.0",
120
- "cross-env": "^7.0.3",
121
- "eslint": "^9.38.0",
120
+ "cross-env": "^10.1.0",
121
+ "eslint": "^10.1.0",
122
122
  "eslint-plugin-jsx-a11y": "^6.8.0",
123
- "eslint-plugin-react-hooks": "^5.1.0",
124
- "eslint-plugin-storybook": "9.1.3",
125
- "glob": "^11.0.2",
123
+ "eslint-plugin-react-hooks": "^7.0.1",
124
+ "eslint-plugin-storybook": "10.3.3",
125
+ "glob": "^13.0.6",
126
126
  "globals": "^17.0.0",
127
- "i18next": "^25.8.0",
127
+ "i18next": "^26.0.2",
128
128
  "intersection-observer": "^0.12.0",
129
- "jsdom": "^27.1.0",
129
+ "jsdom": "^29.0.1",
130
130
  "msw": "^2.11.6",
131
131
  "msw-storybook-addon": "^2.0.6",
132
132
  "prettier": "^3.8.0",
133
- "react": "19.2.3",
134
- "react-dom": "19.2.3",
133
+ "react": "^19.2.4",
134
+ "react-dom": "^19.2.4",
135
135
  "react-pdf": "^10.2.0",
136
136
  "react-router": "^7.12.0",
137
137
  "rimraf": "^6.1.0",