Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

style: Update AIChatWidget UI#20

Closed
TharinduMahesh wants to merge 2 commits into
mainfrom
chatbot
Closed

style: Update AIChatWidget UI#20
TharinduMahesh wants to merge 2 commits into
mainfrom
chatbot

Conversation

@TharinduMahesh

@TharinduMahesh TharinduMahesh commented Nov 10, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Improved chat UI with theme-based styling, decorative sparkles, and enhanced message bubbles.
    • Chat now displays tool usage indicators prepended to AI responses.
    • Login prompt and conditional input placeholder when not authenticated.
  • Bug Fixes / Reliability

    • Better handling and messaging for API errors and non-OK responses.
  • Chores

    • Updated internal code comments for improved clarity.
  • Dependencies

    • Added new icon library for UI visuals.

@vercel

vercel Bot commented Nov 10, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
techtorque Error Error Nov 11, 2025 10:10am

@coderabbitai

coderabbitai Bot commented Nov 10, 2025

Copy link
Copy Markdown

Walkthrough

Replaces external auth hook with a local/mock auth flow, adds in-file theming constants, changes API endpoint to localhost with token-in-header/payload, improves error handling and response processing (supports optional tool_executed), updates UI rendering/styling and adds login prompt and visual indicators.

Changes

Cohort / File(s) Summary
Chat widget logic & UI
src/app/components/chatbot/AIChatWidget.tsx
Replaced external auth hook with a mock/local token flow; wired token retrieval into request headers and payload; changed API URL to http://localhost:3000/api/ai/chat; improved error handling for non-OK responses; support for tool_executed in responses (prepends indicator to AI replies); moved to in-file theming constants and theme-based classes; added login prompt/placeholder when unauthenticated; reworked message rendering and minor renames/reordering.
Dependency addition
package.json
Added dependency lucide-react@^0.553.0.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant UI as AIChatWidget
    participant Auth as localAuthHook
    participant API as localhost:/api/ai/chat
    Note over UI,Auth: New local token flow

    User->>UI: enters message & submits
    UI->>UI: append immediate user message to history
    UI->>Auth: request token (mock/local)
    Auth-->>UI: return token (or null)
    UI->>API: POST payload + token in header/payload
    API-->>UI: 200 OK with { reply, tool_executed? }
    alt tool_executed present
        UI->>UI: prepend tool indicator to AI reply
    end
    UI->>User: render updated message list (styled via theme classes)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to token handling and where token is placed (headers vs payload) in AIChatWidget.tsx.
  • Verify error handling paths and user-visible messages for non-OK API responses.
  • Review UI changes for authentication state (login prompt/placeholder) and tool_executed display logic.

Possibly related PRs

  • Main #9 — Overlapping edits to src/app/components/chatbot/AIChatWidget.tsx affecting token retrieval, error handling, and message-send logic; likely related and may conflict.

Poem

🐰 Hopping in with tiny socks,
I tweaked the tokens, changed the box,
Sparkles glow where answers land,
A local hook holds out its hand,
The chat now hums — a joyful hop!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'style: Update AIChatWidget UI' is overly broad and does not accurately reflect the substantial functional changes. The PR includes authentication logic, API integration, error handling, and tool execution support—not just style updates. Revise the title to reflect the main functional changes, such as: 'feat: Add authentication and tool execution support to AIChatWidget' or 'refactor: Integrate mock auth flow and API token handling in AIChatWidget'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chatbot

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 and usage tips.

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
src/app/components/chatbot/AIChatWidget.tsx (1)

79-79: Fix ESLint error: replace any type annotation.

Line 79 has an ESLint error from the no-explicit-any rule. The error parameter should be typed more specifically. Use Error or unknown instead.

-        } catch (error: any) {
+        } catch (error: unknown) {

If using unknown, you'll need to add type guards when accessing error properties:

-        } catch (error: any) {
+        } catch (error: unknown) {
             console.error("Chat Error:", error);
             const errorMessage: Message = { 
-                text: error.message.includes('401') 
+                text: error instanceof Error && error.message.includes('401')
                     ? "Your session has expired. Please log in again."
                     : "Sorry, I'm having trouble with the services. Try again later.", 
                 sender: 'system' 
             };

Alternatively, use Error if you're confident the caught error is always an Error instance:

-        } catch (error: any) {
+        } catch (error: Error) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b3680e and 7badaef.

📒 Files selected for processing (1)
  • src/app/components/chatbot/AIChatWidget.tsx (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Build and Test Frontend_Web
src/app/components/chatbot/AIChatWidget.tsx

[error] 79-79: ESLint: Unexpected any. Specify a different type. @typescript-eslint/no-explicit-any (no-explicit-any)

Comment thread src/app/components/chatbot/AIChatWidget.tsx Outdated
Comment thread src/app/components/chatbot/AIChatWidget.tsx Outdated

@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: 4

🧹 Nitpick comments (1)
src/app/components/chatbot/AIChatWidget.tsx (1)

4-15: Consider a proper theme system for better maintainability.

The theme object groups CSS classes, which is an improvement over scattered hardcoded styles. However, for better theme management, consider using CSS variables, Tailwind's built-in dark mode utilities directly, or a theme provider like next-themes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7badaef and f801830.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json (1 hunks)
  • src/app/components/chatbot/AIChatWidget.tsx (3 hunks)
🧰 Additional context used
🪛 GitHub Actions: Build and Test Frontend_Web
src/app/components/chatbot/AIChatWidget.tsx

[error] 110-110: ESLint: Unexpected any. Specify a different type. @typescript-eslint/no-explicit-any

🪛 GitHub Check: Install, Lint and Build
src/app/components/chatbot/AIChatWidget.tsx

[failure] 110-110:
Unexpected any. Specify a different type

🔇 Additional comments (5)
package.json (1)

14-14: LGTM!

The lucide-react dependency is properly integrated and used for UI icons (Sparkles, Bolt) in the AIChatWidget component.

src/app/components/chatbot/AIChatWidget.tsx (4)

1-2: LGTM!

Icon imports are correctly integrated with the lucide-react dependency and used appropriately in the UI.


17-27: LGTM!

The tool_executed field is properly typed as optional and correctly integrated with the response handling logic.


91-104: LGTM!

The enhanced error handling with HTTP status fallback and the tool execution indicator provide better user feedback and debugging visibility.


130-200: LGTM!

The UI updates improve visual consistency with theme-based styling, add helpful visual indicators (icons), and provide clear user feedback when authentication is required.


const API_ENDPOINT = '/api/v1/ai/chat'; // This will be routed by your API Gateway
// NOTE: Using localhost:8091 to test against the locally running FastAPI service
const API_ENDPOINT = 'http://localhost:8091/api/v1/ai/chat';

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 | 🔴 Critical

Replace hardcoded localhost URL with environment variable.

The API endpoint is hardcoded to localhost:8091, which will fail in production, staging, and any non-local environment.

Use an environment variable for the base URL:

-const API_ENDPOINT = 'http://localhost:8091/api/v1/ai/chat';
+const API_ENDPOINT = `${process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8091'}/api/v1/ai/chat`;

Then configure .env.local (local), .env.production, etc.:

NEXT_PUBLIC_API_BASE_URL=https://api.yourdomain.com
📝 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
const API_ENDPOINT = 'http://localhost:8091/api/v1/ai/chat';
const API_ENDPOINT = `${process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8091'}/api/v1/ai/chat`;
🤖 Prompt for AI Agents
In src/app/components/chatbot/AIChatWidget.tsx around line 36, replace the
hardcoded API endpoint 'http://localhost:8091/api/v1/ai/chat' with a URL built
from an environment variable: read process.env.NEXT_PUBLIC_API_BASE_URL (falling
back to a sensible default only for local dev if needed), append
'/api/v1/ai/chat' while normalizing slashes to avoid double slashes, and
export/use that constant; update docs/.env files to include
NEXT_PUBLIC_API_BASE_URL for each environment.

Comment on lines +38 to +43
// --- MOCK AUTH HOOK ---
// Provides a mock token; replace this with your actual useAuth hook
const useAuth = (): AuthHook => ({
token: "mock-jwt-token-for-user-12345",
isLoggedIn: true
});

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 | 🔴 Critical

Remove mock authentication before production deployment.

The mock useAuth hook returns a hardcoded token and always reports the user as logged in. This bypasses real authentication and poses a security risk.

Replace with your actual authentication hook:

-// --- MOCK AUTH HOOK ---
-// Provides a mock token; replace this with your actual useAuth hook
-const useAuth = (): AuthHook => ({
-    token: "mock-jwt-token-for-user-12345", 
-    isLoggedIn: true
-});
+// Import your real auth hook
+import { useAuth } from '@/hooks/useAuth'; // or your actual auth hook location

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

🤖 Prompt for AI Agents
In src/app/components/chatbot/AIChatWidget.tsx around lines 38 to 43, remove the
mock useAuth hook that returns a hardcoded token and replace it with your real
authentication hook (e.g., import and call your existing useAuth/useUser hook);
ensure the component reads the token from the real hook, handles the
unauthenticated state (null/undefined token or isLoggedIn false) gracefully
(show login prompt or disable features), and do not leave any hardcoded tokens
in source code or logs.

Comment on lines 76 to +86
const payload = {
query: message,
session_id: sessionId,
token: userToken, // Passed in body for Agent_Bot context retrieval
token: userToken, // Sent in body for Agent_Bot context
};

const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${userToken}`, // Passed in header for Gateway validation
'Authorization': `Bearer ${userToken}`, // Sent in header for Gateway validation

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

Token is transmitted twice—clarify the intent or remove redundancy.

The token is sent in both the request body (line 79) and the Authorization header (line 86). This duplication may cause confusion about which location is authoritative.

If the Gateway validates via header and Agent_Bot needs it in the body, document this clearly:

 const payload = {
     query: message,
     session_id: sessionId, 
-    token: userToken, // Sent in body for Agent_Bot context
+    token: userToken, // REQUIRED: Agent_Bot service needs token in body for internal routing
 };

 const response = await fetch(API_ENDPOINT, {
     method: 'POST',
     headers: { 
         'Content-Type': 'application/json',
-        'Authorization': `Bearer ${userToken}`, // Sent in header for Gateway validation
+        'Authorization': `Bearer ${userToken}`, // REQUIRED: API Gateway validates token in header
     },
     body: JSON.stringify(payload),
 });

Otherwise, if only one is needed, remove the redundant transmission.

🤖 Prompt for AI Agents
In src/app/components/chatbot/AIChatWidget.tsx around lines 76 to 86, the user
token is being sent twice (in payload.session_id/token and again in the
Authorization header) causing ambiguity; either remove the token field from the
JSON payload and rely solely on the Authorization header for Gateway validation,
or if the downstream Agent_Bot requires the token in the body, keep both but add
a clear comment explaining that header is for Gateway auth and body.token is for
Agent_Bot, and update any related types/tests to reflect the chosen approach.

setSessionId(data.session_id); // CRITICAL: Save the session ID for the next turn
setSessionId(data.session_id); // CRITICAL: Save the session ID

} catch (error: any) {

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

Replace any type with specific error type.

Using any defeats TypeScript's type safety and is flagged by the linter.

Apply this diff:

-} catch (error: any) {
+} catch (error: unknown) {
     console.error("Chat Error:", error);
     const errorMessage: Message = { 
-        text: "Sorry, I'm having trouble connecting to the services. Please try again later.", 
+        text: error instanceof Error ? error.message : "Sorry, I'm having trouble connecting to the services. Please try again later.", 
         sender: 'system' 
     };

Or if you prefer to keep the generic message:

-} catch (error: any) {
+} catch (error: unknown) {
     console.error("Chat Error:", error);

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

🧰 Tools
🪛 GitHub Actions: Build and Test Frontend_Web

[error] 110-110: ESLint: Unexpected any. Specify a different type. @typescript-eslint/no-explicit-any

🪛 GitHub Check: Install, Lint and Build

[failure] 110-110:
Unexpected any. Specify a different type

🤖 Prompt for AI Agents
In src/app/components/chatbot/AIChatWidget.tsx around line 110, the catch clause
currently uses the `any` type which bypasses TypeScript safety; change the catch
parameter to `unknown` (or `error: unknown`) and then narrow it before use
(e.g., use `if (error instanceof Error) { const msg = error.message } else {
const msg = String(error) }`) or explicitly type-guard/extract the message so
you never assume `any`; update subsequent error handling/logging to use the
safely extracted message.

@RandithaK RandithaK closed this Nov 11, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants