Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/components/LanguageSelectionGrid.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { API_ENDPOINTS, URL_PARAMS } from "../constants/urls"
import { useChatStorage, useSiteStorage } from "hooks/useStorage"
import { clearFromStorage } from "../services/storage_service"
import { getFlowLanguagesApi } from "../api/endpoints/flow"
import { languageList, languageValueMap } from "../pages/ShikshalokamVoiceChat/enum"
import { sessionFlowName } from "../constants/session"
import { useChatStorage, useSiteStorage } from "hooks/useStorage"
import { useEffect } from "react"
import { useNavigate } from "react-router-dom"
import { useQuery } from "@tanstack/react-query"
Expand All @@ -27,6 +27,7 @@ const LanguageSelectionGrid = ({ usecaseType }) => {
data: flowLanguages,
isError: isFlowLanguagesError,
error: flowLanguagesError,
isLoading: isFlowLanguagesLoading,
} = useQuery({
queryKey: [API_ENDPOINTS.FLOW_LANGUAGES, urlFlow],
queryFn: () => getFlowLanguagesApi(urlFlow),
Expand Down Expand Up @@ -74,13 +75,27 @@ const LanguageSelectionGrid = ({ usecaseType }) => {
</div>
<p className="sm:text-xl text-md font-semibold text-center">{t("languageQuestion")}</p>
<div className="mt-4 mb-10 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-2 gap-3 sm:gap-4 md:gap-6 md:justify-items-center lg:px-[80px] md:px-[20px] sm:px-[20px] px-[10px]">
{flowLanguages &&
{
isFlowLanguagesLoading && (
<>
<div className="shadow-md rounded-[10px] bg-[#F1F5F9] animate-pulse w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center">
</div>
<div className="shadow-md rounded-[10px] bg-[#F1F5F9] animate-pulse w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center">
</div>
<div className="shadow-md rounded-[10px] bg-[#F1F5F9] animate-pulse w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center">
</div>
<div className="shadow-md rounded-[10px] bg-[#F1F5F9] animate-pulse w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center">
</div>
</>
)
}
{!isFlowLanguagesLoading && flowLanguages &&
flowLanguages.languages.map(lang => (
<div key={lang} className="div14-lang w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center" onClick={() => handleLanguageClick(lang)}>
<button className="w-full">{languageValueMap[lang]}</button>
</div>
))}
{!flowLanguages &&
{!isFlowLanguagesLoading && !flowLanguages &&
languageList
Comment on lines +92 to 99

@coderabbitai coderabbitai Bot Apr 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fallback condition misses empty-language responses.

Line 98 only checks !flowLanguages. If API returns { languages: [] }, neither list renders and users get an empty grid. Also, flowLanguages truthy with missing languages can break mapping at Line 93.

✅ Suggested fix
-        {!isFlowLanguagesLoading && flowLanguages &&
-          flowLanguages.languages.map(lang => (
+        {!isFlowLanguagesLoading && (flowLanguages?.languages?.length ?? 0) > 0 &&
+          flowLanguages.languages.map(lang => (
             <div key={lang} className="div14-lang w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center" onClick={() => handleLanguageClick(lang)}>
               <button className="w-full">{languageValueMap[lang]}</button>
             </div>
           ))}
-        {!isFlowLanguagesLoading && !flowLanguages &&
+        {!isFlowLanguagesLoading && (flowLanguages?.languages?.length ?? 0) === 0 &&
           languageList
             .filter(lang => !lang.excludeFor.includes(urlFlow || usecaseType))
             .map(lang => (
📝 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
{!isFlowLanguagesLoading && flowLanguages &&
flowLanguages.languages.map(lang => (
<div key={lang} className="div14-lang w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center" onClick={() => handleLanguageClick(lang)}>
<button className="w-full">{languageValueMap[lang]}</button>
</div>
))}
{!flowLanguages &&
{!isFlowLanguagesLoading && !flowLanguages &&
languageList
{!isFlowLanguagesLoading && (flowLanguages?.languages?.length ?? 0) > 0 &&
flowLanguages.languages.map(lang => (
<div key={lang} className="div14-lang w-full text-center vertical-center m-0 h-[100px] flex items-center justify-center" onClick={() => handleLanguageClick(lang)}>
<button className="w-full">{languageValueMap[lang]}</button>
</div>
))}
{!isFlowLanguagesLoading && (flowLanguages?.languages?.length ?? 0) === 0 &&
languageList
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/LanguageSelectionGrid.jsx` around lines 92 - 99, The current
render checks only !isFlowLanguagesLoading and flowLanguages, which fails when
flowLanguages is {languages: []} or missing languages; update the conditional
rendering to first guard that flowLanguages.languages is a non-empty array
(e.g., use flowLanguages?.languages?.length > 0) before mapping in the JSX where
flowLanguages.languages.map(...) is used (refer to flowLanguages,
flowLanguages.languages, isFlowLanguagesLoading, languageList,
handleLanguageClick, languageValueMap), and add a fallback branch that renders
languageList when flowLanguages is falsy or when flowLanguages.languages is
empty to avoid runtime errors and an empty grid.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Languages will never be empty

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@VishnuKrishnathu, understood! If the API contract guarantees that the languages array is always non-empty, then the empty-grid concern doesn't apply. I'll note this for future reviews.

(The optional chaining on flowLanguages?.languages is still a low-cost defensive guard against unexpected API shape changes, but I leave that to your discretion.)

(^ο½₯ω・^)


🧠 Learnings used
Learnt from: VishnuKrishnathu
Repo: ELEVATE-Project/mohini-app-frontend PR: 244
File: src/components/LanguageSelectionGrid.jsx:47-68
Timestamp: 2026-02-16T06:38:02.503Z
Learning: In LanguageSelectionGrid.jsx (src/components/LanguageSelectionGrid.jsx), the `setPreviousUrl` and `setStorageFlow` calls are intentionally only set for specific route_mapping flows (ParentPerceptionSurvey, ListeningActivity) before navigation. For the COMMON_CHAT navigation path, these should NOT be set, as users should not be able to navigate back to /home or the current page. This is expected behavior.

.filter(lang => !lang.excludeFor.includes(urlFlow || usecaseType))
.map(lang => (
Expand Down
1 change: 1 addition & 0 deletions src/constants/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export const sessionFlowName = {
FreeFlow: "free_flow",
ShikshaSamvad: "shiksha-samvad",
DelhiShikshaSamvad: "delhi-shiksha-samvad",
StudyTeacherInterview: "study_teacher_interview",
}
7 changes: 4 additions & 3 deletions src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ const DynamicVoiceChat = ({ type = "" }) => {
title: t("PPsCompletionMessage"),
showCancelButton: false,
confirmButtonText: t("PPsCompletionCTA"),
showConfirmButton: ![sessionFlowName.ShikshaSamvad, sessionFlowName.DelhiShikshaSamvad].includes(storageFlow),
showConfirmButton: ![sessionFlowName.ShikshaSamvad, sessionFlowName.DelhiShikshaSamvad, sessionFlowName.StudyTeacherInterview].includes(storageFlow),
showCloseButton: false,
allowEscapeKey: false,
allowOutsideClick: false,
Expand Down Expand Up @@ -2177,7 +2177,7 @@ const DynamicVoiceChat = ({ type = "" }) => {
<div className={isMobile ? "div30_a" : "div30"}>
<MainHeader
isMobileFirst={isMobile}
displayNewSessionButton={!([sessionFlowName.ShikshaSamvad, sessionFlowName.DelhiShikshaSamvad].includes(storageFlow))}
displayNewSessionButton={!([sessionFlowName.ShikshaSamvad, sessionFlowName.DelhiShikshaSamvad, sessionFlowName.StudyTeacherInterview].includes(storageFlow))}
showTheDots={false}
content={
<button
Expand Down Expand Up @@ -2289,7 +2289,8 @@ const DynamicVoiceChat = ({ type = "" }) => {
[sessionFlowName.ListeningActivity]: "la_",
[sessionFlowName.ParentPerceptionSurvey]: "pppi_",
[sessionFlowName.ShikshaSamvad]: "shiksha_samvad_",
[sessionFlowName.DelhiShikshaSamvad]: "shiksha_samvad_"
[sessionFlowName.DelhiShikshaSamvad]: "shiksha_samvad_",
[sessionFlowName.StudyTeacherInterview]: "shiksha_samvad_",
}

const prefix = prefixMap[storageFlow] || ""
Expand Down