Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All 1.3 tn prod hotfix #230

Merged
merged 495 commits into from
Dec 16, 2024
Merged

All 1.3 tn prod hotfix #230

merged 495 commits into from
Dec 16, 2024

Conversation

gouravmore
Copy link
Member

@gouravmore gouravmore commented Dec 16, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration file for code reviews and automated processes.
    • Added new workflows for deployment automation across various branches.
    • Created a new component for handling bad words filtering.
    • Added a new login page component with user authentication functionality.
    • Introduced a custom hook for audio detection.
    • Enhanced the Practice component with new state variables and improved logic.
    • Added a new PracticeRedirectPage component for navigation.
  • Bug Fixes

    • Improved error handling and state management in various components.
  • Documentation

    • Updated .gitignore and added new configuration files for ESLint and Prettier.
  • Style

    • Added new styles for the login page and modified existing CSS classes for better visual representation.
  • Tests

    • Enhanced testing capabilities with the introduction of new state management and error handling logic in components.
  • Chores

    • Updated dependencies and scripts in package.json for improved development experience.

gouravmore and others added 30 commits June 19, 2024 19:18
Issue #219845: deployment automation for all
Issue #219845 fix: all automation for test-rig instances
Issue #219845 fix: branch update for test-rig prod
Issueid #221626 fix: Implement AuthGuard for Route Protection in React
IssueId #223082 feat: Create Log Out Button in Test-Rig [React]
IssueId #223082 feat: Create Log Out Button in Test-Rig [React]
Task #224175 fix: Sonar Cloud Fixes for all-learner-ai-app
Task #224175 fix: sonar issue fixed
gouravmore and others added 23 commits November 21, 2024 22:34
Issueid #231004 feat:play youtube help video in mylearning iframe
#0000 updated origin variable in yml file
Copy link

coderabbitai bot commented Dec 16, 2024

Caution

Review failed

The pull request is closed.

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/components/Assesment/Assesment.jsx

Oops! Something went wrong! :(

ESLint: 7.32.0

ESLint couldn't find the config "react-app" to extend from. Please check that the name of the config is correct.

The config "react-app" was referenced from the config file in "/package.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

Walkthrough

This pull request introduces a comprehensive set of configuration and code changes across multiple files in a React-based learning application. The changes focus on enhancing code review processes, deployment workflows, development tools, and application functionality. Key modifications include adding a new configuration file for code reviews, introducing multiple GitHub Actions workflows for different deployment environments, updating environment variables, and refining various components' interactions and state management.

Changes

File/Group Change Summary
.coderabbit.yaml New configuration file for code review settings, specifying language, review workflow, and path filters
.env Updated environment variables for Learner AI application host and orchestration services
.github/workflows/ Added multiple deployment workflow files for different branches and environments (sandbox, dev, prod, staging)
.gitignore Added entries for environment files, build artifacts, and framework-specific outputs
.husky/ Introduced pre-commit hook and updated .gitignore
package.json Added new dependencies, scripts for linting and formatting, and configuration for Husky and lint-staged
src/routes/index.js Updated routing configuration with new routes and authentication requirements
src/components/ Multiple component updates for improved state management, error handling, and user interactions
src/utils/ Added new utility functions for audio detection, bad word filtering, and URL constants
src/views/ Introduced new views like LoginPage and PracticeRedirectPage

Possibly related PRs

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a92e59 and 840ea1b.

⛔ Files ignored due to path filters (1)
  • src/assets/images/gameLost.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • .gitignore (1 hunks)
  • src/components/Assesment/Assesment.jsx (16 hunks)
  • src/components/DiscoverEnd/DiscoverEnd.jsx (4 hunks)
  • src/components/Layouts.jsx/MainLayout.jsx (8 hunks)
  • src/components/Mechanism/WordsOrImage.jsx (9 hunks)
  • src/views/Practice/Practice.jsx (24 hunks)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 71

🔭 Outside diff range comments (5)
src/components/DiscoverEnd/DiscoverEnd.jsx (1)

Line range hint 37-50: Add error handling for audio playback and API calls.

The current implementation lacks error handling for both audio playback and API calls, which could lead to unhandled runtime errors in production.

Consider applying these improvements:

 (async () => {
-      let audio = new Audio(LevelCompleteAudio);
-      audio.play();
+      try {
+        let audio = new Audio(LevelCompleteAudio);
+        await audio.play();
+      } catch (error) {
+        console.error("Failed to play audio:", error);
+      }
+
+      try {
       const virtualId = getLocalData("virtualId");
       const lang = getLocalData("lang");
       const getMilestoneDetails = await axios.get(
         `${process.env.REACT_APP_LEARNER_AI_APP_HOST}/${config.URLS.GET_MILESTONE}/${virtualId}?language=${lang}`
       );
       const { data } = getMilestoneDetails;
-      setLevel(data.data.milestone_level);
-      setLocalData("userLevel", data.data.milestone_level?.replace("m", ""));
+      if (data?.data?.milestone_level) {
+        setLevel(data.data.milestone_level);
+        setLocalData("userLevel", data.data.milestone_level.replace(/^m/i, ""));
+      }
+      } catch (error) {
+        console.error("Failed to fetch milestone details:", error);
+        // Consider showing a user-friendly error message
+      }
     })();
src/store/sagas/handlers/user.handler.js (1)

Line range hint 1-64: Security: Remove sensitive data logging and refactor token storage

Production code contains multiple security concerns:

  1. Sensitive data logging (tokens, OTP)
  2. Storing sensitive tokens in localStorage (vulnerable to XSS)

Recommendations:

  1. Remove all console.log statements
  2. Consider using HttpOnly cookies for token storage
  3. Add token encryption before storage if cookies aren't feasible
src/components/Practice/Mechanics4.jsx (1)

Line range hint 134-141: Avoid creating new Audio instances on each interaction.

Creating new Audio instances for each interaction can lead to performance issues and memory leaks.

+ const [correctAudio] = useState(() => new Audio(correctSound));
+ const [wrongAudio] = useState(() => new Audio(wrongSound));

- let audio = new Audio(
-   [...selectedWords, word]?.join(" ") === parentWords
-     ? correctSound
-     : wrongSound
- );
- audio.play();
+ if ([...selectedWords, word]?.join(" ") === parentWords) {
+   correctAudio.play();
+ } else {
+   wrongAudio.play();
+ }
src/utils/RecordVoiceVisualizer.jsx (2)

Line range hint 1-47: Eliminate code duplication in bar definitions

The individual bar definitions (bar1 through bar5) contain identical code with only different variable names. This violates the DRY principle and makes maintenance harder.

Consider replacing the repeated bar definitions with a single reusable function:

-const bar1 = (...)
-const bar2 = (...)
-const bar3 = (...)
-const bar4 = (...)
-const bar5 = (...)
+const createBar = (index) => (
+  <span
+    className={`playing__bar playing__bar${index}`}
+    style={{
+      height: `${Math.floor(Math.random() * 100)}%`,
+      animationDelay: `${Math.floor(Math.random() * 5)}s`,
+    }}
+  ></span>
+);

Line range hint 57-69: Optimize performance by memoizing random values

The renderBar function generates new random values on every render, which could cause unnecessary re-renders and visual flickering.

Consider using useMemo to stabilize the random values:

+const useMemoizedBars = (count, barIndex) => {
+  return React.useMemo(
+    () =>
+      Array.from({ length: count }, () => ({
+        height: Math.floor(Math.random() * 100),
+        delay: Math.random() * 5,
+      })),
+    [count]
+  );
+};

 const renderBar = (key, value) => {
-  const renderArr = [];
-  for (let i = 0; i <= Number(value.times); i++) {
-    renderArr.push(/*...*/);
-  }
-  return renderArr;
+  const bars = useMemoizedBars(value.times + 1, value.bar);
+  return bars.map((bar, index) => (
+    <span
+      key={`${key}-${index}`}
+      className={`playing__bar playing__bar${value.bar}`}
+      style={{
+        height: `${bar.height}%`,
+        animationDelay: `${bar.delay}s`,
+      }}
+    ></span>
+  ));
 };
🧹 Nitpick comments (30)
src/components/AssesmentEnd/AssesmentEnd.jsx (1)

19-20: Consider using path aliases and type checking for imports

For better maintainability and type safety:

  1. Replace relative paths with path aliases
  2. Add TypeScript interfaces or PropTypes for the config object
src/components/Practice/Mechanics5.jsx (1)

452-465: Specify more precise PropTypes instead of using 'PropTypes.any'

Some props are declared as PropTypes.any, which reduces the effectiveness of type checking. Specifying more precise PropTypes will improve code quality and help catch potential errors.

Consider updating the PropTypes with appropriate types:

-      type: PropTypes.any,
+      type: PropTypes.string,

-      words: PropTypes.any,
+      words: PropTypes.arrayOf(PropTypes.string),

-      level: PropTypes.any,
+      level: PropTypes.number,

-      contentId: PropTypes.any,
+      contentId: PropTypes.string.isRequired,

-      livesData: PropTypes.any,
+      livesData: PropTypes.object,

-      gameOverData: PropTypes.any,
+      gameOverData: PropTypes.object,
src/components/Practice/Mechanics6.jsx (3)

295-295: Remove unnecessary Fragment wrapper

The Fragment (<>...</>) is unnecessary since it wraps only a single child element.

Apply this diff to simplify the code:

-                    <>{isPlaying ? <StopAudioButton /> : <PlayAudioButton />}</>
+                    {isPlaying ? <StopAudioButton /> : <PlayAudioButton />}
🧰 Tools
🪛 Biome (1.9.4)

[error] 295-295: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)


168-170: Use 'useState' consistently after importing it

Since useState is imported from React, you can use it directly instead of React.useState for consistency.

Apply this diff:

-      const [isReady, setIsReady] = React.useState(false);
+      const [isReady, setIsReady] = useState(false);

-      const [isPlaying, setIsPlaying] = React.useState(false);
+      const [isPlaying, setIsPlaying] = useState(false);

-      const [currentProgress, setCurrentProgress] = React.useState(0);
+      const [currentProgress, setCurrentProgress] = useState(0);

Also applies to: 184-184


177-179: Simplify audio playback logic in 'togglePlayPause'

In the togglePlayPause function, calling audioRef.current.pause() before starting playback is unnecessary and may cause unexpected behavior. Also, reloading the audio using load() might not be needed.

Consider simplifying the code as follows:

        } else {
-          audioRef.current.pause();
-          audioRef.current.load();
           audioRef.current.play();
           setIsPlaying(true);
        }
src/utils/constants.js (4)

21-21: Replace var with let for block scoping

Using let instead of var ensures proper block scoping and avoids potential hoisting issues. This improves code readability and maintainability.

Apply this diff to improve code clarity:

-for (var k in arr1) {
+for (let k in arr1) {

88-88: Move inline comment outside of the attribute value

Including comments inside attribute strings is invalid in JSX. The comment should be moved outside the transform attribute to prevent syntax errors.

Apply this diff to fix the issue:

-        transform="translate(10, 10) scale(2.5)" /* Make arrow bigger and keep it centered */
+        {/* Make arrow bigger and keep it centered */}
+        transform="translate(10, 10) scale(2.5)"

3015-3016: Use consistent variable naming within the Diamond component

The variable heartColor is used within the Diamond component, which may cause confusion. For clarity, consider renaming it to diamondColor.

Apply this diff to improve clarity:

-  const heartColor = colorMap[milestone] || "#28a745"; // default to green if milestone is not m1, m2, m3, or m4
+  const diamondColor = colorMap[milestone] || "#28a745"; // default to green if milestone is not specified

Also, update all occurrences of heartColor within the component:

-          style={{ fill: heartColor }}
+          style={{ fill: diamondColor }}

3175-4218: Consider refactoring levelGetContent to reduce duplication

The levelGetContent object contains a significant amount of duplicated data across languages and levels. This can make maintenance challenging and increase the risk of inconsistencies. Consider refactoring to eliminate duplication by defining common templates or using functions to generate the content dynamically.

src/routes/index.js (1)

5-5: Consider renaming 'routData' to 'routeData' for consistency

The variable routData may be a misspelling of routeData. Renaming it can improve readability and maintain consistent naming conventions.

Apply this diff to rename the variable:

-const routData = [
+const routeData = [

And update all references to routData in the file.

src/components/Practice/Mechanics3.jsx (1)

125-125: Fix typo in 'currrentProgress' variable name

The variable currrentProgress appears to have an extra 'r'. Correcting the typo improves code readability.

Apply this diff to fix the typo:

-const [currrentProgress, setCurrrentProgress] = React.useState(0);
+const [currentProgress, setCurrentProgress] = React.useState(0);

Ensure all references to this variable are updated accordingly.

src/utils/VoiceAnalyser.js (5)

118-122: Use UI components instead of alert for error notifications

Using alert disrupts the user experience. Consider replacing alert with a non-blocking UI component like Snackbar or Dialog to display error messages.


145-149: Use UI components instead of alert for error notifications

Similarly, replace alert with a UI component to provide better user feedback when audio fails to load.


97-127: Refactor duplicated audio playback logic

The playAudio and playRecordedAudio functions contain similar code for handling audio playback and error handling. Refactor them into a common helper function to reduce code duplication and improve maintainability.

Also applies to: 129-149


373-380: Use setOpenMessageDialog instead of alert for user notifications

Replace alert with props.setOpenMessageDialog to inform the user about inappropriate language detected, providing a better user experience.


139-139: Remove console logs in production code

Avoid leaving console.log statements in production code to prevent unnecessary logging. Use proper logging mechanisms or remove them entirely.

src/components/Assesment/Assesment.jsx (2)

219-335: Component MessageDialog lacks default props

For better maintainability, consider adding default prop values to MessageDialog to handle cases where props might be undefined.


528-540: Conditional rendering without redundancy

Simplify the conditional rendering of the logout button to avoid redundant code and potential confusion.

src/views/Practice/Practice.jsx (3)

61-64: Use consistent parameter names in gameOver function

The parameter isUserPass should be named consistently with other parts of the code, possibly userWon, to avoid confusion.


288-293: Avoid hardcoding practice step resets

Instead of resetting newPracticeStep to 0 when it reaches 10, consider making the practice steps dynamic to accommodate future changes.


Line range hint 644-748: Optimize the highlightWords function for readability

The highlightWords function contains complex logic that could be simplified or broken into smaller helper functions for better readability and maintainability.

src/views/PracticeRedirectPage/PracticeRedirectPage.jsx (1)

13-21: Simplify component and add loading state.

The empty Grid with styling is unnecessary. Consider showing a loading state during navigation.

  return (
-   <Grid
-     container
-     direction="column"
-     justifyContent="center"
-     alignItems="center"
-     className="no-page-found"
-   ></Grid>
+   <div className="redirect-loading">Redirecting to practice...</div>
  );
src/views/AppContent/AppContent.jsx (1)

25-27: Remove commented code

Remove the commented-out code as it indicates incomplete changes that could cause confusion.

-  // const navigate = useNavigate();
-  // const location = useLocation();
src/utils/useAudioDetection.jsx (1)

42-42: Consider making the silence threshold configurable

The hardcoded threshold of 0.04 might not work well across different microphones and environments.

+  const SILENCE_THRESHOLD = 0.04;
   const average = total / inputDataLength;
-  const currentIsSilent = average < 0.04; // Threshold for silence
+  const currentIsSilent = average < SILENCE_THRESHOLD;
src/index.css (1)

121-127: Use CSS custom properties for consistent styling

The hardcoded values should be moved to CSS variables for better maintainability and consistency.

+:root {
+  --header-font-size: 40px;
+  --header-letter-spacing: 2px;
+  --header-line-height: 110.6%;
+  --success-color: #1cc871;
+  --success-stroke: #00b359;
+}

.successHeader {
-  color: #1cc871;
+  color: var(--success-color);
   -webkit-text-stroke-width: 0.5;
-  -webkit-text-stroke-color: #00b359;
+  -webkit-text-stroke-color: var(--success-stroke);
   font-family: sans-serif;
-  font-size: 40px;
+  font-size: var(--header-font-size);
   font-style: normal;
   font-weight: 700;
-  line-height: 110.6%;
-  letter-spacing: 2px;
+  line-height: var(--header-line-height);
+  letter-spacing: var(--header-letter-spacing);
}
src/App.js (1)

78-83: Improve URL parameter handling

The virtualId fallback logic could be simplified and made more robust.

Consider using nullish coalescing:

-let virtualId;
-
-if (getParameter("virtualId", window.location.search)) {
-  virtualId = getParameter("virtualId", window.location.search);
-} else {
-  virtualId = localStorage.getItem("virtualId");
-}
+const virtualId = getParameter("virtualId", window.location.search) ?? localStorage.getItem("virtualId");
.github/workflows/all-prod-rig.yml (1)

1-102: Implement workflow reusability

All three workflow files share almost identical code, which violates DRY principle and makes maintenance harder. Consider:

  1. Creating a reusable workflow with common steps
  2. Using workflow call to invoke the common workflow
  3. Passing environment-specific variables as inputs

Example structure:

# .github/workflows/deploy.yml
name: Reusable Deploy Workflow
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
      s3-bucket:
        required: true
        type: string
    secrets:
      aws-access-key-id:
        required: true
      aws-secret-access-key:
        required: true
      aws-region:
        required: true
      distribution-id:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      # Common steps here

Then in each environment-specific workflow:

jobs:
  deploy:
    uses: ./.github/workflows/deploy.yml
    with:
      environment: all-prod-rig
      s3-bucket: sb-all-rig
    secrets: inherit
🧰 Tools
🪛 actionlint (1.7.4)

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

src/components/Mechanism/WordsOrImage.jsx (1)

56-70: Consider memoizing the updateStoredData function.

The updateStoredData function is recreated on every render. Since it's used in a useEffect dependency array, this could cause unnecessary re-renders.

-  const updateStoredData = (audio, isCorrect) => {
+  const updateStoredData = React.useCallback((audio, isCorrect) => {
     if (audio && words) {
       const newEntry = {
         selectedAnswer: words,
         audioUrl: audio,
         correctAnswer: isCorrect,
       };
       setStoredData((prevData) => [...prevData, newEntry]);
     }
-  };
+  }, [words]);
src/Badwords/badWords.json (1)

1-510: Consider enhancing the profanity filter implementation.

  1. The current implementation might miss common variations and leetspeak.
  2. Consider using a more maintainable format with metadata.
  3. The list should be versioned and regularly updated.

Consider:

  1. Adding a version field for tracking updates
  2. Including severity levels for different terms
  3. Adding metadata for maintenance
  4. Using a more structured format:
{
  "version": "1.0.0",
  "lastUpdated": "2024-12-01",
  "languages": {
    "en": {
      "terms": [
        {
          "word": "example",
          "severity": "high",
          "variations": ["3xample", "ex@mple"],
          "category": "profanity"
        }
      ]
    }
  }
}
src/utils/RecordVoiceVisualizer.jsx (1)

Line range hint 79-83: Use CSS transform for better performance

Using absolute positioning with transform can impact performance. Consider using CSS transform with translate3d for better GPU acceleration.

Update the style to use hardware acceleration:

 <div
   className="playing"
-  style={{ position: 'absolute', left: '-0.241px', bottom: '-44px', transform: 'rotate(3.142rad)' }}
+  style={{ 
+    position: 'absolute',
+    transform: 'translate3d(-0.241px, calc(100% + 44px), 0) rotate(3.142rad)',
+    transformOrigin: 'center',
+  }}
 >
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08a1251 and 3a92e59.

⛔ Files ignored due to path filters (55)
  • package-lock.json is excluded by !**/package-lock.json
  • src/assets/correct.svg is excluded by !**/*.svg
  • src/assets/help.png is excluded by !**/*.png
  • src/assets/images/assesment-bg.svg is excluded by !**/*.svg
  • src/assets/images/assesmentComplete.png is excluded by !**/*.png
  • src/assets/images/assessmentBackground.png is excluded by !**/*.png
  • src/assets/images/back-arrow.png is excluded by !**/*.png
  • src/assets/images/back-arrow.svg is excluded by !**/*.svg
  • src/assets/images/catLoading.gif is excluded by !**/*.gif
  • src/assets/images/clouds.svg is excluded by !**/*.svg
  • src/assets/images/coinStar.svg is excluded by !**/*.svg
  • src/assets/images/cryPanda.svg is excluded by !**/*.svg
  • src/assets/images/desktopLevel1.png is excluded by !**/*.png
  • src/assets/images/desktopLevel2.png is excluded by !**/*.png
  • src/assets/images/desktopLevel3.jpg is excluded by !**/*.jpg
  • src/assets/images/desktopLevel4.png is excluded by !**/*.png
  • src/assets/images/desktopLevel5.png is excluded by !**/*.png
  • src/assets/images/desktopLevel6.png is excluded by !**/*.png
  • src/assets/images/desktopLevel7.png is excluded by !**/*.png
  • src/assets/images/desktopLevel8.png is excluded by !**/*.png
  • src/assets/images/desktopLevel9.png is excluded by !**/*.png
  • src/assets/images/discover-end-left.svg is excluded by !**/*.svg
  • src/assets/images/discover-end-right.svg is excluded by !**/*.svg
  • src/assets/images/discover-end-top.svg is excluded by !**/*.svg
  • src/assets/images/discover-end.png is excluded by !**/*.png
  • src/assets/images/discover-end.svg is excluded by !**/*.svg
  • src/assets/images/elephant.svg is excluded by !**/*.svg
  • src/assets/images/gameLost.svg is excluded by !**/*.svg
  • src/assets/images/gameLost1.svg is excluded by !**/*.svg
  • src/assets/images/gameWon.svg is excluded by !**/*.svg
  • src/assets/images/home.png is excluded by !**/*.png
  • src/assets/images/homeBackground.png is excluded by !**/*.png
  • src/assets/images/hurray.svg is excluded by !**/*.svg
  • src/assets/images/ic-arrow.svg is excluded by !**/*.svg
  • src/assets/images/ic-listen.svg is excluded by !**/*.svg
  • src/assets/images/ic-speak.svg is excluded by !**/*.svg
  • src/assets/images/level.svg is excluded by !**/*.svg
  • src/assets/images/logout.svg is excluded by !**/*.svg
  • src/assets/images/panda.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg-stone.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg-stone2.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg-stone3.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg2.svg is excluded by !**/*.svg
  • src/assets/images/practice-bg3.svg is excluded by !**/*.svg
  • src/assets/images/profile_url.png is excluded by !**/*.png
  • src/assets/images/profile_url.svg is excluded by !**/*.svg
  • src/assets/images/scoreView.png is excluded by !**/*.png
  • src/assets/images/scoreView.svg is excluded by !**/*.svg
  • src/assets/images/seePictureAndTell.png is excluded by !**/*.png
  • src/assets/images/textureImage.png is excluded by !**/*.png
  • src/assets/images/timer.svg is excluded by !**/*.svg
  • src/assets/turtle.svg is excluded by !**/*.svg
  • src/assets/wrong.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (54)
  • .coderabbit.yaml (1 hunks)
  • .env (1 hunks)
  • .github/workflows/all-app-sandbox.yml (1 hunks)
  • .github/workflows/all-dev-rig.yml (1 hunks)
  • .github/workflows/all-dev-tn-new.yml (1 hunks)
  • .github/workflows/all-dev-tn.yml (1 hunks)
  • .github/workflows/all-prod-rig.yml (1 hunks)
  • .github/workflows/all-prod-tn.yml (1 hunks)
  • .github/workflows/all-staging-tn.yml (1 hunks)
  • .gitignore (1 hunks)
  • .husky/.gitignore (1 hunks)
  • .husky/pre-commit (1 hunks)
  • .prettierrc (1 hunks)
  • eslintrc.json (1 hunks)
  • package.json (5 hunks)
  • prettierignore.txt (1 hunks)
  • prettierrc.json (1 hunks)
  • src/App.js (1 hunks)
  • src/Badwords/badWords.json (1 hunks)
  • src/components/Assesment/Assesment.jsx (15 hunks)
  • src/components/AssesmentEnd/AssesmentEnd.jsx (8 hunks)
  • src/components/DiscoverEnd/DiscoverEnd.jsx (4 hunks)
  • src/components/DiscoverSentance/DiscoverSentance.jsx (6 hunks)
  • src/components/Layouts.jsx/MainLayout.jsx (8 hunks)
  • src/components/Mechanism/WordsOrImage.jsx (9 hunks)
  • src/components/Practice/Mechanics1.jsx (0 hunks)
  • src/components/Practice/Mechanics3.jsx (10 hunks)
  • src/components/Practice/Mechanics4.jsx (8 hunks)
  • src/components/Practice/Mechanics5.jsx (1 hunks)
  • src/components/Practice/Mechanics6.jsx (1 hunks)
  • src/config/awsS3.js (1 hunks)
  • src/index.css (1 hunks)
  • src/routes/index.js (1 hunks)
  • src/services/callTelemetryIntract.js (0 hunks)
  • src/services/telementryService.js (4 hunks)
  • src/services/telemetryService.js (0 hunks)
  • src/services/utilService.js (0 hunks)
  • src/store/sagas/handlers/user.handler.js (1 hunks)
  • src/utils/AudioCompare.js (1 hunks)
  • src/utils/Badwords.js (1 hunks)
  • src/utils/RecordVoiceVisualizer.jsx (7 hunks)
  • src/utils/VoiceAnalyser.js (14 hunks)
  • src/utils/constants.js (8 hunks)
  • src/utils/urlConstants.json (1 hunks)
  • src/utils/useAudioDetection.jsx (1 hunks)
  • src/views/AppContent/AppContent.jsx (1 hunks)
  • src/views/HomePage/HomePage.jsx (1 hunks)
  • src/views/LoginPage/LoginPage.css (1 hunks)
  • src/views/LoginPage/LoginPage.jsx (1 hunks)
  • src/views/LoginPage/index.jsx (1 hunks)
  • src/views/Practice/Practice.jsx (19 hunks)
  • src/views/PracticeRedirectPage/PracticeRedirectPage.jsx (1 hunks)
  • src/views/PracticeRedirectPage/index.js (1 hunks)
  • src/views/index.js (1 hunks)
💤 Files with no reviewable changes (4)
  • src/services/callTelemetryIntract.js
  • src/services/utilService.js
  • src/components/Practice/Mechanics1.jsx
  • src/services/telemetryService.js
✅ Files skipped from review due to trivial changes (12)
  • .husky/.gitignore
  • src/views/PracticeRedirectPage/index.js
  • src/views/LoginPage/index.jsx
  • prettierignore.txt
  • src/views/HomePage/HomePage.jsx
  • prettierrc.json
  • .prettierrc
  • eslintrc.json
  • src/views/LoginPage/LoginPage.css
  • src/views/index.js
  • .env
  • src/utils/urlConstants.json
🧰 Additional context used
📓 Path-based instructions (1)
src/index.css (1)

Pattern **/*.css: "Review the CSS code against the google css style guide and point out any mismatches. Ensure that:

  • The code adheres to best practices associated with CSS.
  • The code adheres to best practices recommended by lighthouse or similar tools for performance.
  • The code adheres to similar naming conventions for classes, ids."
🪛 Biome (1.9.4)
src/components/Practice/Mechanics4.jsx

[error] 214-251: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

src/components/Practice/Mechanics6.jsx

[error] 185-185: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 295-295: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

src/components/Practice/Mechanics3.jsx

[error] 427-480: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment

(lint/complexity/noUselessFragments)

src/components/Layouts.jsx/MainLayout.jsx

[error] 872-872: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 376-376: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)


[error] 383-383: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

src/views/Practice/Practice.jsx

[error] 242-242: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 242-242: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/utils/RecordVoiceVisualizer.jsx

[error] 75-75: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🪛 actionlint (1.7.4)
.github/workflows/all-staging-tn.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-dev-rig.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-dev-tn.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


23-23: the runner of "aws-actions/configure-aws-credentials@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-prod-rig.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-dev-tn-new.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


23-23: the runner of "aws-actions/configure-aws-credentials@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-app-sandbox.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/all-prod-tn.yml

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (16)
src/components/DiscoverEnd/DiscoverEnd.jsx (2)

16-16: LGTM! Good practice to centralize API endpoints.

Centralizing API endpoints in a configuration file improves maintainability and makes it easier to manage environment-specific URLs.


135-135: LGTM! Proper implementation of the navigation handler.

The click handler correctly uses the new handleProfileBack function for navigation.

src/components/AssesmentEnd/AssesmentEnd.jsx (1)

Line range hint 1-391: Verify backward compatibility for production hotfix

Since this is a production hotfix, please verify:

  1. Impact on existing user sessions
  2. Compatibility with API versions
  3. Browser compatibility for localStorage usage
✅ Verification successful

Production hotfix changes are safe to proceed

Based on the codebase analysis:

  1. SessionId implementation is consistent across components (Practice, Assessment, DiscoverSentence) using the same pattern of generation and storage
  2. API endpoints are properly versioned and consistently used across components
  3. LocalStorage usage follows a standard pattern with proper fallbacks

The changes in AssessmentEnd.jsx maintain backward compatibility:

  • Preserves existing sessionId if present
  • Follows the same pattern for generating new sessionId as other components
  • Uses consistent API endpoint structure
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for existing usage of sessionId across the codebase
echo "Checking sessionId usage..."
rg "sessionId" --type js --type jsx

# Check for API version compatibility
echo "Checking API endpoint usage..."
rg "REACT_APP_LEARNER_AI" --type js --type jsx

# Check for browser compatibility
echo "Checking localStorage usage..."
rg "localStorage" --type js --type jsx

Length of output: 412


Script:

#!/bin/bash
# Check for existing usage of sessionId across the codebase
echo "Checking sessionId usage..."
rg "sessionId"

# Check for API endpoint usage
echo "Checking API endpoint usage..."
rg "REACT_APP_LEARNER_AI"

# Check for localStorage usage
echo "Checking localStorage usage..."
rg "localStorage"

Length of output: 16536

src/utils/constants.js (1)

2999-3000: ⚠️ Potential issue

Add error handling for localStorage access and JSON parsing

Accessing localStorage and parsing JSON can throw errors if the key doesn't exist or the data is malformed. To prevent runtime exceptions, add error handling to gracefully handle these cases.

Apply this diff to fix the issue:

-  const milestone =
-    JSON.parse(localStorage.getItem("getMilestone")).data?.milestone_level ||
-    "m1";
+  let milestone = "m1";
+  try {
+    const milestoneData = JSON.parse(localStorage.getItem("getMilestone"));
+    if (milestoneData?.data?.milestone_level) {
+      milestone = milestoneData.data.milestone_level;
+    }
+  } catch (e) {
+    console.error('Error parsing milestone data from localStorage:', e);
+  }

Likely invalid or redundant comment.

src/components/Assesment/Assesment.jsx (1)

Line range hint 97-179: Ensure consistent use of Grid container properties

In the LanguageModal component, verify that the Grid container's properties are correctly applied for consistent layout across different screen sizes.

src/views/Practice/Practice.jsx (2)

152-174: Ensure points increment logic is correct

Review the logic for incrementing points to ensure that points are added appropriately, especially considering the different conditions for isShowCase.


749-767: Check cross-origin communication safety

When communicating with the parent window, ensure that window.parent.postMessage is secure by validating parentOrigin to prevent security vulnerabilities.

[security]

.husky/pre-commit (1)

1-4: LGTM! Verify lint-staged configuration.

The pre-commit hook setup looks correct. However, since this is a production hotfix, we should verify the lint-staged configuration to ensure it won't block critical hotfixes.

✅ Verification successful

Pre-commit hook configuration is safe for hotfixes

The lint-staged configuration only applies auto-fixes for code formatting and linting, with reasonable Prettier defaults. There are no strict rules that would block critical hotfixes:

  • ESLint is run with --fix flag, which only applies safe auto-fixes
  • Prettier configuration uses standard formatting options
  • No overly strict ignore patterns are present
  • The hooks only run on staged JavaScript/JSX files in the src directory
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if lint-staged config exists and its contents
if [ -f package.json ]; then
    echo "Checking lint-staged config in package.json:"
    jq '.["lint-staged"]' package.json
fi

Length of output: 245


Script:

#!/bin/bash
# Check ESLint configuration to understand the rules being enforced
if [ -f .eslintrc.json ]; then
    echo "ESLint config from .eslintrc.json:"
    cat .eslintrc.json
elif [ -f .eslintrc.js ]; then
    echo "ESLint config from .eslintrc.js:"
    cat .eslintrc.js
fi

# Check Prettier configuration
if [ -f .prettierrc ]; then
    echo "Prettier config from .prettierrc:"
    cat .prettierrc
elif [ -f .prettierrc.json ]; then
    echo "Prettier config from .prettierrc.json:"
    cat .prettierrc.json
fi

# Check if there are any ignore files that might exclude hotfix changes
echo "\nChecking for ignore files:"
if [ -f .eslintignore ]; then
    echo "ESLint ignore patterns:"
    cat .eslintignore
fi
if [ -f .prettierignore ]; then
    echo "Prettier ignore patterns:"
    cat .prettierignore
fi

Length of output: 402

.coderabbit.yaml (1)

11-12: Verify XML exclusion necessity

The exclusion of XML files from review (!**/.xml) needs justification:

  • XML files might contain critical configurations
  • Consider removing this exclusion or documenting the reason
✅ Verification successful

XML exclusion can be safely kept

The exclusion of XML files from review is acceptable as there are no XML files in the repository that would require code review. The search results show no XML files that could contain critical configurations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any XML files in the repository that might need review
fd -e xml

Length of output: 11


Script:

#!/bin/bash
# Let's try a different approach using ripgrep to find any XML-related patterns
# Search for XML file references in the codebase
rg -i "\.xml" -g "!.git"

# Also check for potential XML-related configurations or build files
fd -e pom
fd -e build
fd -e config

Length of output: 65603

package.json (2)

Line range hint 20-50: Verify security vulnerabilities in new dependencies

Several new dependencies have been added. Let's verify their security status.

✅ Verification successful

No security vulnerabilities found in the new dependencies

The security check results show:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for known vulnerabilities in new dependencies
for pkg in "[email protected]" "[email protected]" "[email protected]" "[email protected]"; do
  echo "Checking $pkg..."
  gh api graphql -f query='{
    securityVulnerabilities(first: 5, ecosystem: NPM, package: "'$(echo $pkg | cut -d@ -f1)'") {
      nodes {
        advisory {
          summary
          severity
          publishedAt
        }
        vulnerableVersionRange
        firstPatchedVersion {
          identifier
        }
      }
    }
  }'
done

Length of output: 2441


92-99: ⚠️ Potential issue

Remove duplicate React dependency

React is listed in both dependencies and devDependencies, which could lead to version conflicts.

   "devDependencies": {
     "@mui/styles": "^5.15.10",
     "eslint": "^7.32.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-plugin-prettier": "^3.4.0",
     "husky": "^9.0.11",
     "lint-staged": "^11.0.0",
     "prettier": "^2.3.2",
-    "react": "^18.2.0"
   },

Likely invalid or redundant comment.

.github/workflows/all-app-sandbox.yml (1)

83-83: 🛠️ Refactor suggestion

Reconsider disabling CI mode

Disabling CI mode (CI: false) prevents treating warnings as errors, which could lead to quality issues being overlooked.

Consider addressing the underlying warnings instead of disabling CI mode.

.github/workflows/all-staging-tn.yml (1)

1-102: Address identical issues as in sandbox workflow

This workflow has the same issues as identified in all-app-sandbox.yml:

  1. Outdated GitHub Actions versions
  2. Debug step exposing sensitive information
  3. CI mode disabled
  4. Direct AWS credentials configuration

Please apply the same fixes as suggested in the sandbox workflow review.

🧰 Tools
🪛 actionlint (1.7.4)

15-15: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

src/services/telementryService.js (3)

94-114: LGTM! Well-structured error handling in Log function

The new Log function includes proper error handling and conditional telemetry mode checking.


74-75: LGTM! Additional device specification in telemetry data

The addition of dspec provides valuable device information for analytics.


232-238: ⚠️ Potential issue

Add null checks for userDetails access

The function accesses userDetails properties without checking if userDetails is defined, which could lead to runtime errors.

Apply these null checks:

-                { id: localStorage.getItem("lang") || 'ta', type: 'language' },
-                { id: userDetails?.school_name, type: 'school_name' },
-                {
-                  id: userDetails?.class_studying_id,
-                  type: 'class_studying_id',
-                },
-                { id: userDetails?.udise_code, type: 'udise_code' },
+                { id: localStorage.getItem("lang") || 'ta', type: 'language' },
+                { id: userDetails ? userDetails.school_name : '', type: 'school_name' },
+                {
+                  id: userDetails ? userDetails.class_studying_id : '',
+                  type: 'class_studying_id',
+                },
+                { id: userDetails ? userDetails.udise_code : '', type: 'udise_code' },

Likely invalid or redundant comment.

Comment on lines +55 to +65
const handleProfileBack = () => {
try {
if (process.env.REACT_APP_IS_APP_IFRAME === 'true') {
navigate("/")
} else {
navigate("/discover-start")
}
} catch (error) {
console.error("Error posting message:", error);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve hook usage and error handling in navigation.

  1. The navigate hook is declared after its usage in the component, which violates React hooks rules.
  2. The error handling could be more specific to navigation-related errors.

Apply these improvements:

 const SpeakSentenceComponent = () => {
   const [shake, setShake] = useState(true);
   const [level, setLevel] = useState("");
+  const navigate = useNavigate();
 
   useEffect(() => {
     // ... existing useEffect code
   }, []);
 
   const handleProfileBack = () => {
     try {
       if (process.env.REACT_APP_IS_APP_IFRAME === 'true') {
         navigate("/")
       } else {
         navigate("/discover-start")
       }
     } catch (error) {
-      console.error("Error posting message:", error);
+      console.error("Navigation failed:", error);
+      // Consider showing a user-friendly error message
     }
   };
 
-  const navigate = useNavigate();

Committable suggestion skipped: line range outside the PR's diff.

@@ -86,7 +86,7 @@ const AssesmentEnd = () => {
letterSpacing: "2%",
}}
>
{newLevel == previousLevel ? "Amost There.!" : `Hurray.!`}
{newLevel === previousLevel ? "Amost There.!" : `Hurray.!`}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor conditional text rendering for better maintainability

Current implementation has several maintainability issues:

  1. Repeated level comparison logic
  2. Hardcoded strings without i18n support
  3. Duplicated inline styles

Suggested improvements:

+ const MESSAGES = {
+   success: {
+     title: (isLevelComplete) => isLevelComplete ? 'Hurray.!' : 'Almost There.!',
+     subtitle: (isLevelComplete, level) => isLevelComplete 
+       ? `Level ${level} completed successfully` 
+       : `Some more practice required to complete ${level}`,
+   }
+ };

+ const isLevelComplete = newLevel !== previousLevel;
+ const messageStyles = {
+   title: {
+     color: "#00B359",
+     fontWeight: 700,
+     fontSize: "22px",
+     fontFamily: "Quicksand",
+     lineHeight: "32.5px",
+     letterSpacing: "2%",
+   }
+ };

- <span style={{...}}>{newLevel === previousLevel ? "Amost There.!" : `Hurray.!`}</span>
+ <span style={messageStyles.title}>{MESSAGES.success.title(isLevelComplete)}</span>

Also applies to: 109-109, 131-131, 137-140, 152-152, 311-311, 324-324

@@ -37,14 +34,18 @@ const AssesmentEnd = () => {
const previous_level = getLocalData("previous_level");
setPreviousLevel(previous_level?.replace("m", ""));
const getMilestoneDetails = await axios.get(
`${BASE_API}lais/scores/getMilestone/user/${virtualId}?language=${lang}`
`${process.env.REACT_APP_LEARNER_AI_APP_HOST}/${config.URLS.GET_MILESTONE}/${virtualId}?language=${lang}`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve API call error handling and user experience

The API implementation has several critical issues:

  1. Missing error handling for failed API calls
  2. No loading states during API calls
  3. No retry mechanism for failed network requests
  4. Potential URL injection vulnerability in template literals

Suggested implementation:

+ const [isLoading, setIsLoading] = useState(true);
+ const [error, setError] = useState(null);

  useEffect(() => {
    (async () => {
+     setIsLoading(true);
+     setError(null);
      try {
        let audio = new Audio(LevelCompleteAudio);
        audio.play();
        const virtualId = getLocalData("virtualId");
        const lang = getLocalData("lang");
        
+       // Sanitize inputs
+       if (!virtualId || !lang) throw new Error('Missing required parameters');
        
        const getMilestoneDetails = await axios.get(
          `${process.env.REACT_APP_LEARNER_AI_APP_HOST}/${config.URLS.GET_MILESTONE}/${encodeURIComponent(virtualId)}?language=${encodeURIComponent(lang)}`
        );
        // ... rest of the code
+     } catch (error) {
+       console.error('Failed to load assessment data:', error);
+       setError(error);
+     } finally {
+       setIsLoading(false);
+     }
    })();
  }, []);

Also applies to: 48-48

Comment on lines +42 to +46
let sessionId = getLocalData("sessionId");
if (!sessionId){
sessionId = uniqueId();
localStorage.setItem("sessionId", sessionId)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for localStorage operations

The current implementation has several potential issues:

  1. No try-catch block for localStorage operations which could fail in incognito mode
  2. No session expiry mechanism
  3. Direct localStorage access without abstraction

Suggested implementation:

- let sessionId = getLocalData("sessionId");
- if (!sessionId){
-   sessionId = uniqueId();
-   localStorage.setItem("sessionId", sessionId)
- }
+ let sessionId;
+ try {
+   sessionId = getLocalData("sessionId");
+   if (!sessionId) {
+     sessionId = uniqueId();
+     setLocalData("sessionId", sessionId);
+   }
+ } catch (error) {
+   console.error('Failed to manage session:', error);
+   sessionId = uniqueId(); // Fallback to temporary session
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let sessionId = getLocalData("sessionId");
if (!sessionId){
sessionId = uniqueId();
localStorage.setItem("sessionId", sessionId)
}
let sessionId;
try {
sessionId = getLocalData("sessionId");
if (!sessionId) {
sessionId = uniqueId();
setLocalData("sessionId", sessionId);
}
} catch (error) {
console.error('Failed to manage session:', error);
sessionId = uniqueId(); // Fallback to temporary session
}

Comment on lines +84 to +86
useEffect(() => {
updateStoredData();
}, [handleNext]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure 'updateStoredData' is called with the required arguments

The updateStoredData function expects audios and isCorrect as arguments, but it's being called without arguments in the useEffect hook. This could lead to unexpected behavior or errors.

Consider passing the necessary arguments to updateStoredData or adjust the function to handle undefined arguments appropriately.

Comment on lines +76 to +78
useEffect(() => {
updateStoredData();
}, [handleNext]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix empty useEffect dependency.

The useEffect hook has handleNext in its dependency array but calls updateStoredData with no arguments. This could lead to unexpected behavior.

- useEffect(() => {
-   updateStoredData();
- }, [handleNext]);
+ useEffect(() => {
+   if (handleNext) {
+     // Add appropriate audio and isCorrect values based on your requirements
+     updateStoredData(null, false);
+   }
+ }, [handleNext, updateStoredData]);

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +298 to +340
WordsOrImage.propTypes = {
handleNext: PropTypes.func.isRequired,
// background: PropTypes.string,
header: PropTypes.string,
image: PropTypes.string,
setVoiceText: PropTypes.func.isRequired,
setRecordedAudio: PropTypes.func.isRequired,
setVoiceAnimate: PropTypes.func.isRequired,
enableNext: PropTypes.bool,
showTimer: PropTypes.bool,
points: PropTypes.number,
currentStep: PropTypes.number.isRequired,
percentage: PropTypes.string,
fluency: PropTypes.bool,
isDiscover: PropTypes.bool,
showProgress: PropTypes.bool,
callUpdateLearner: PropTypes.bool,
disableScreen: PropTypes.bool,
isShowCase: PropTypes.bool,
handleBack: PropTypes.func.isRequired,
setEnableNext: PropTypes.func.isRequired,
startShowCase: PropTypes.bool,
setStartShowCase: PropTypes.func,
setLivesData: PropTypes.func.isRequired,
loading: PropTypes.bool,
setOpenMessageDialog: PropTypes.func.isRequired,
isNextButtonCalled: PropTypes.bool,
setIsNextButtonCalled: PropTypes.func,
background: PropTypes.bool,
type: PropTypes.any,
words: PropTypes.any,
storyLine: PropTypes.number,
steps: PropTypes.number,
contentId: PropTypes.any,
contentType: PropTypes.string,
level: PropTypes.any,
progressData: PropTypes.object,
playTeacherAudio: PropTypes.func,
livesData: PropTypes.any,
gameOverData: PropTypes.any,
highlightWords: PropTypes.func,
matchedChar: PropTypes.any,
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve PropTypes definitions.

Several prop types are defined as any, which reduces type safety. Consider using more specific PropTypes.

- type: PropTypes.any,
- words: PropTypes.any,
- contentId: PropTypes.any,
- level: PropTypes.any,
- livesData: PropTypes.any,
- gameOverData: PropTypes.any,
- matchedChar: PropTypes.any,
+ type: PropTypes.oneOf(['image', 'phonics', 'word']).isRequired,
+ words: PropTypes.string,
+ contentId: PropTypes.string.isRequired,
+ level: PropTypes.number.isRequired,
+ livesData: PropTypes.shape({
+   // Add appropriate shape based on your data structure
+ }),
+ gameOverData: PropTypes.shape({
+   // Add appropriate shape based on your data structure
+ }),
+ matchedChar: PropTypes.string,

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +111 to +114
setShake(true);
setTimeout(() => {
setShake(false);
}, 3000);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize shake animation handling.

The current implementation sets a timeout that might not be cleared if the component unmounts, potentially causing memory leaks.

+ useEffect(() => {
+   if (shake) {
+     const timer = setTimeout(() => {
+       setShake(false);
+     }, 3000);
+     return () => clearTimeout(timer);
+   }
+ }, [shake]);

- setShake(true);
- setTimeout(() => {
-   setShake(false);
- }, 3000);
+ setShake(true);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setShake(true);
setTimeout(() => {
setShake(false);
}, 3000);
useEffect(() => {
if (shake) {
const timer = setTimeout(() => {
setShake(false);
}, 3000);
return () => clearTimeout(timer);
}
}, [shake]);
setShake(true);

Comment on lines 214 to 251
<span
onClick={() => handleWords(elem, true)}
className={
answer === "wrong"
? `audioSelectedWrongWord ${shake ? "shakeImage" : ""}`
: ""
}
style={{
borderRadius: "12px",
padding: "5px 10px 5px 10px",
border:
answer != "wrong"
? answer === "correct"
? "none" // No border if the answer is correct
: answer === "wrong"
? "2px solid #C30303" // Red border if the answer is wrong
: !words.length && selectedWords.length && type === "word"
? "2px solid #1897DE" // Blue border for some specific condition
: "2px solid rgba(51, 63, 97, 0.15)"
: "", // Default light border,
color:
type == "word"
? answer == "correct"
type === "word"
? answer === "correct"
? "#58CC02"
: answer == "wrong"
: answer === "wrong"
? "#C30303"
: "#1897DE"
: answer === "wrong"
? "#C30303"
: "#333F61",
fontWeight: type == "word" ? 600 : 700,
fontSize: "40px",
fontWeight: type === "word" ? 600 : 700,
fontSize: "clamp(1.5rem, 2.5vw, 2.5rem)",
fontFamily: "Quicksand",
cursor: "pointer",
marginLeft: type == "word" ? 0 : "20px",
marginLeft:
type === "word" ? 0 : answer != "correct" ? "20px" : 0,
}}
>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add missing key prop in iterable.

React requires a unique key prop for elements in an iterable to maintain component state and optimize rendering.

{selectedWords?.map((elem) => (
  <span
+   key={elem}
    onClick={() => handleWords(elem, true)}
    className={
      answer === "wrong"
        ? `audioSelectedWrongWord ${shake ? "shakeImage" : ""}`
        : ""
    }
    // ... rest of the props
  >
    {elem}
  </span>
))}

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (1.9.4)

[error] 214-251: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

Comment on lines +73 to 77
<div className="playing">
{Object.entries(renderType).map(([key, value]) => {
return <>{renderBar(key, value)}</>;
})}
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add missing key prop in map iteration

React requires a unique key prop when rendering elements in an iteration to efficiently update the DOM.

Add a key prop to the mapped elements:

 {Object.entries(renderType).map(([key, value]) => {
-  return <>{renderBar(key, value)}</>;
+  return <React.Fragment key={key}>{renderBar(key, value)}</React.Fragment>;
 })}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="playing">
{Object.entries(renderType).map(([key, value]) => {
return <>{renderBar(key, value)}</>;
})}
</div>
<div className="playing">
{Object.entries(renderType).map(([key, value]) => {
return <React.Fragment key={key}>{renderBar(key, value)}</React.Fragment>;
})}
</div>
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots
C Reliability Rating on New Code (required ≥ A)
D Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

const handleProfileBack = () => {
try {
if (process.env.REACT_APP_IS_APP_IFRAME === "true") {
window.parent.postMessage({ type: "restore-iframe-content" }, "*");

Check failure

Code scanning / SonarCloud

Origins should be verified during cross-origin communications High

Specify a target origin for this message. See more on SonarQube Cloud
// go_to_result(voiceText);
setVoiceText("");
}
//eslint-disable-next-line
}, [voiceText]);

const send = (score) => {
if (process.env.REACT_APP_IS_APP_IFRAME === "true") {
window.parent.postMessage(

Check failure

Code scanning / SonarCloud

Origins should be verified during cross-origin communications High

Specify a target origin for this message. See more on SonarQube Cloud
// go_to_result(voiceText);
setVoiceText("");
}
//eslint-disable-next-line
}, [voiceText]);

const send = (score) => {
if (process.env.REACT_APP_IS_APP_IFRAME === "true") {
window.parent.postMessage(

Check failure

Code scanning / SonarCloud

Origins should be verified during cross-origin communications High

Specify a target origin for this message. See more on SonarQube Cloud
"mechanic_1")
? 500
: stringLengths[0];
window.parent.postMessage({ type: "stringLengths", length }, "*");

Check failure

Code scanning / SonarCloud

Origins should be verified during cross-origin communications High

Specify a target origin for this message. See more on SonarQube Cloud
@gouravmore gouravmore merged commit 783b5e1 into main Dec 16, 2024
0 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants