Skip to content

implemented the quick reply chips for the conversation for better user experience. - #21

Open
farhanp1502 wants to merge 9 commits into
ELEVATE-Project:release-1.3.0from
farhanp1502:release-1.3.0
Open

implemented the quick reply chips for the conversation for better user experience.#21
farhanp1502 wants to merge 9 commits into
ELEVATE-Project:release-1.3.0from
farhanp1502:release-1.3.0

Conversation

@farhanp1502

@farhanp1502 farhanp1502 commented Aug 7, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features

    • Added reusable pill-shaped chips with color variants, sizes, icons, disabled states, and keyboard support.
    • Added quick-reply chips to voice chat with duplicate-selection prevention and customized message text.
    • Added profile viewing and editing for personal, organization, and location details.
    • Added profile save confirmation, error handling, and logout access from the chat sidebar.
    • Preserved additional chat-history content and enabled quick replies in historical messages.
  • Localization

    • Added profile-related labels and messages in English, Hindi, Kannada, Odia, Tamil, and Telugu.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2c7eaee2-5eff-46ff-9b99-003c08a43ba6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds profile editing, localized profile fields, a reusable Chip component, and quick-reply support to voice chat. It also returns profile data from session validation and adds the profile update API endpoint.

Changes

Voice chat profile and quick replies

Layer / File(s) Summary
Profile contract and modal
src/constants/profileForm.js, src/constants/urls.ts, src/api/endpoints/user.js, src/components/UserProfileModal/index.jsx
Defines profile fields and modal sizing. Adds a schema-driven profile modal and a PATCH API for profile updates.
Profile session and voice chat wiring
src/utils/session.js, src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js, src/pages/ShikshalokamVoiceChat/shikshaChatStyle.css
Returns profile data from session validation. Opens and saves the profile modal, updates profile state, shows notifications, and wires the sidebar user trigger.
Reusable Chip component
src/components/Chip/index.jsx
Adds configurable variants, sizes, icons, styles, click handling, keyboard activation, button semantics, and disabled accessibility state.
Chat metadata and chip submissions
src/constants/dynamic-chat.js, src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
Adds chat source and special-ID constants. Preserves bot extra_content. Supports override message text, consumed-message tracking, textarea preservation, and resolved chat titles.
Quick-reply rendering and localization
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js, public/locales/*/translation.json
Renders quick-reply chips from live or historical bot responses. Hides consumed chips and disables them during blocked states. Adds profile and recent-conversation translations for seven languages.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DynamicVoiceChat
  participant UserProfileModal
  participant updateUserProfileApi
  participant Chip
  participant handleSendMessage
  User->>DynamicVoiceChat: Open profile control
  DynamicVoiceChat->>UserProfileModal: Provide profile data and form schema
  User->>UserProfileModal: Save profile fields
  UserProfileModal->>DynamicVoiceChat: Return form values
  DynamicVoiceChat->>updateUserProfileApi: PATCH profile data
  updateUserProfileApi-->>DynamicVoiceChat: Return updated profile data
  User->>Chip: Select quick-reply label
  Chip->>handleSendMessage: Submit label as override text
  handleSendMessage->>DynamicVoiceChat: Record consumed bot message
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main user-facing change: adding quick reply chips to the conversation interface.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Vinod-V3

Vinod-V3 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 3347-3351: Update the quick-reply onClick handler near
handleSendMessage to acquire a synchronous per-message lock before awaiting the
send, keyed by lastBotMsg?.updated_at or the equivalent bot-message identifier.
Ignore subsequent clicks while that message is locked, and clear the lock when
handleSendMessage fails so retries remain possible; preserve the existing
successful setQuickReplySentForMsgId behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 94fe2c55-5a2d-4bf6-b686-b24a633186cd

📥 Commits

Reviewing files that changed from the base of the PR and between 3145fe1 and 2ae85fb.

📒 Files selected for processing (3)
  • src/components/Chip/index.jsx
  • src/constants/dynamic-chat.js
  • src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js

Comment thread src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js Outdated
Comment thread src/components/Chip/index.jsx Outdated
onKeyDown={
isClickable
? (e) => {
if (e.key === "Enter" || e.key === " ") {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why this condition is used?
e.key === " "

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.

this is when used is focused on the chip and try to press spacebar then it uses auto reply happens,
however i will remove the condition and only keep enter for now.

Comment thread src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
event.stopPropagation()
}
// overrideText is used by quick-reply chips to send directly without touching textMessage
const messageToSend = overrideText ?? textMessage

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

From where is the "textMessage" coming from?

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.

This is the textMessage from the input field, where the user types their message before it is sent as a prompt to the bot.

audioRef.current.currentTime = 0
}
if (!textMessage.trim()) return
if (!messageToSend.trim()) return false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

trim the value while storing the message to messageToSend key in line 888

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.

done

}
if (showHistorySidebar) {
const firstMsg = textMessage.trim()
const firstMsg = messageToSend.trim()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Make the respective changes post .trim() change in line 888

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.

done

size="sm"
disabled={hasStartedRecording || isFetchingData || (isSimpleBot === false && strandStep >= stateMachineLength)}
onClick={async () => {
const text = typeof chip === "string" ? chip : chip.label ?? chip.text ?? String(chip)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can u check this logic?
if chip is an object when it goes to String(chip)
Is it right?

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.

done

@farhanp1502

Copy link
Copy Markdown
Author

@coderabbitai please review my pr

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

@farhanp1502 I will review pull request #21.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@public/locales/te/translation.json`:
- Around line 115-124: Add the missing recents translation entry to the Telugu
locale alongside the related profile translation keys, using a concise Telugu
label for recent conversations and preserving the existing JSON structure.

In `@src/components/UserProfileModal/index.jsx`:
- Around line 95-104: The FormData invocation in the profile field rendering
must pass the schema-defined labels for state and district instead of relying
only on placeholders. Add labelName using the translated f.labelKey or
f.labelName fallback and pass labelClass as labelCls, matching the other
text-input FormData calls.

In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 244-248: Normalize profile data to a canonical non-empty name in
the session response handling at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L244-L248 and modal
fallback fetch at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2692-L2698, preferring
name with first_name as fallback. After a successful save, update the canonical
name field in src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2711-L2736.
In the profile rendering flow at
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js#L2916-L2945, use the
canonical name consistently and fall back to t("user") before indexing the
avatar initial.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b0229dee-ed03-472b-ac57-f4a43edf7ecd

📥 Commits

Reviewing files that changed from the base of the PR and between 2ae85fb and 64fd49f.

📒 Files selected for processing (14)
  • public/locales/en/translation.json
  • public/locales/hi/translation.json
  • public/locales/kn/translation.json
  • public/locales/or/translation.json
  • public/locales/ta/translation.json
  • public/locales/te/translation.json
  • src/api/endpoints/user.js
  • src/components/Chip/index.jsx
  • src/components/UserProfileModal/index.jsx
  • src/constants/profileForm.js
  • src/constants/urls.ts
  • src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
  • src/pages/ShikshalokamVoiceChat/shikshaChatStyle.css
  • src/utils/session.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Chip/index.jsx

Comment thread public/locales/te/translation.json Outdated
Comment on lines +95 to +104
<FormData
layOut={f.layOut || 1}
id={f.id}
inputType={f.inputType || "text"}
inputName={f.inputName}
inputValue={formValues[f.dataKey] || ""}
inputOnChange={e => handleChange(f.dataKey, e.target.value)}
placeholder={t(f.placeholderKey || f.placeholder, f.placeholder)}
inputClass={inputCls}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Pass labels to the split input controls.

PROFILE_FORM_SCHEMA defines labels for state and district. These FormData calls omit labelName and labelClass, unlike the other text inputs. Placeholders do not provide persistent labels.

Pass t(f.labelKey || f.labelName, f.labelName) and labelCls to FormData.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/UserProfileModal/index.jsx` around lines 95 - 104, The
FormData invocation in the profile field rendering must pass the schema-defined
labels for state and district instead of relying only on placeholders. Add
labelName using the translated f.labelKey or f.labelName fallback and pass
labelClass as labelCls, matching the other text-input FormData calls.

Comment thread src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
@Vinod-V3

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/components/UserProfileModal/index.jsx (1)

66-72: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve unsaved profile edits during parent re-renders.

dynamic-voice-chat.js creates a new userData object on every parent render. While the modal is open, unrelated voice-chat updates rerun the effect and reset the controlled formValues, which discards unsaved edits. Memoize userData or initialize the form only when its field values change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/UserProfileModal/index.jsx` around lines 66 - 72, Update the
initialization effect in UserProfileModal so parent re-renders with a newly
created but value-equivalent userData object do not overwrite unsaved formValues
while the modal is open. Memoize userData at the caller or gate the effect on
actual profile field-value changes, while preserving initialization when the
relevant user data changes or the modal is opened.
src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js (2)

2726-2734: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Propagate cleared profile values to local state.

The payload sends empty strings for missing fields, but local stores update only when values are truthy. If a user clears state, the server can save the empty value while userState retains the old value. The later PDF path reads userState and can use stale profile data. Update clearable fields unconditionally after a successful save.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js` around lines 2726 -
2734, Update the successful profile-save handling around setFirstName, setState,
and _userData so clearable payload fields are propagated unconditionally,
including empty strings. Ensure userState and the corresponding local profile
fields reflect cleared name, state, school_name, district, and role values,
preventing the PDF path from using stale data.

953-973: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Return a successful queue or send result from handleSendMessage. useChatWebhook queues messages while the socket is CONNECTING, but sendMessage returns false for that queued path and for unavailable sockets. handleSendMessage ignores this result and always returns true, so a quick reply can become hidden and locked when its message was not accepted. Return true for sent or queued messages, and use that result before setting quickReplySentForMsgId.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js` around lines 953 -
973, The handleSendMessage flow must honor the result from sendMessage: capture
whether the message was successfully sent or queued, return that result instead
of always returning true, and only update quickReplySentForMsgId after a
successful result. Preserve the existing text clearing and scroll behavior while
preventing quick replies from being dismissed when the socket rejects or cannot
queue the message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/UserProfileModal/index.jsx`:
- Around line 66-72: Update the initialization effect in UserProfileModal so
parent re-renders with a newly created but value-equivalent userData object do
not overwrite unsaved formValues while the modal is open. Memoize userData at
the caller or gate the effect on actual profile field-value changes, while
preserving initialization when the relevant user data changes or the modal is
opened.

In `@src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js`:
- Around line 2726-2734: Update the successful profile-save handling around
setFirstName, setState, and _userData so clearable payload fields are propagated
unconditionally, including empty strings. Ensure userState and the corresponding
local profile fields reflect cleared name, state, school_name, district, and
role values, preventing the PDF path from using stale data.
- Around line 953-973: The handleSendMessage flow must honor the result from
sendMessage: capture whether the message was successfully sent or queued, return
that result instead of always returning true, and only update
quickReplySentForMsgId after a successful result. Preserve the existing text
clearing and scroll behavior while preventing quick replies from being dismissed
when the socket rejects or cannot queue the message.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b4b5be0-2ec7-4c87-b7d6-8f77b95640e4

📥 Commits

Reviewing files that changed from the base of the PR and between 64fd49f and 76e0983.

📒 Files selected for processing (9)
  • public/locales/en/translation.json
  • public/locales/hi/translation.json
  • public/locales/kn/translation.json
  • public/locales/or/translation.json
  • public/locales/ta/translation.json
  • public/locales/te/translation.json
  • src/components/UserProfileModal/index.jsx
  • src/constants/profileForm.js
  • src/pages/ShikshalokamVoiceChat/dynamic-voice-chat.js
💤 Files with no reviewable changes (5)
  • public/locales/hi/translation.json
  • public/locales/kn/translation.json
  • public/locales/en/translation.json
  • public/locales/or/translation.json
  • public/locales/ta/translation.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/constants/profileForm.js
  • public/locales/te/translation.json


const fields = schema.fields || []

const wasOpenRef = useRef(false)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

give relevant key names

return
}

const justOpened = !wasOpenRef.current

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

give relevant key names

if (justOpened || dataChanged) {
const init = {}
fields.forEach(field => {
if (field.type === "split") {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

are we getting field type as "split"?


const handleOverlayClick = e => { if (e.target === overlayRef.current) onClose() }

const inputCls =

@Vinod-V3 Vinod-V3 Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

give full relevant and complete variable names

return (
<div key={field.id} className="mb-3 sm:mb-4">
<div className="label-div">
<b className={labelCls}>{t(field.labelName, field.labelName)}</b>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

whats the use of this?
Giving multiple field.labelName, are we passign any dynamic value?

const handleOpenProfileModal = async () => {
setShowProfileModal(true)
// Reuse profileApiData already fetched during validateToken/validateSession to avoid duplicate API calls
if (!profileApiData || Object.keys(profileApiData).length === 0) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why this condition check?

if (canonicalName) setFirstName(canonicalName)
}
} catch (error) {
console.error("Error fetching profile via validateSession:", error)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also if profile fetch fails toast message not required?

flex-shrink: 0;
}

.saathi-popup-user-trigger {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

dont give specific class names as saathi
Use generic/common names

onClose={() => setShowProfileModal(false)}
onLogout={() => { setShowProfileModal(false); handleLogout() }}
onSave={handleSaveProfile}
userData={{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This object is used in many place
Try creating a function so that it takes the input object and returns the expected output
USe that function in other places wherever this object structure is being used

name: payload.name,
}))

showNotification({

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The auto close changes is done?

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.

2 participants