Skip to content

[Dashboard] siwa chat widget #7128

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

Merged
merged 7 commits into from
May 23, 2025
Merged

[Dashboard] siwa chat widget #7128

merged 7 commits into from
May 23, 2025

Conversation

Yash094
Copy link
Member

@Yash094 Yash094 commented May 22, 2025


PR-Codex overview

This PR primarily focuses on enhancing the chat components within the application by adding new features, improving user experience, and refactoring existing code for better readability and functionality.

Detailed summary

  • Added teamId and placeholder props to various components (Chats, ChatBar, etc.).
  • Introduced FeedbackButtons for user feedback on assistant messages.
  • Implemented CustomChatButton for initiating chat interactions.
  • Enhanced chat functionalities with improved state management.
  • Refactored ExamplePrompt and ExamplePromptButton functions for cleaner syntax.
  • Integrated auth token checks and redirection in layout components.
  • Updated SupportPage to utilize new prompt structures and chat button.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Introduced a new customizable chat button and modal interface labeled "Ask AI for support" with enhanced authentication and team context.
    • Added a feedback feature enabling users to submit positive or negative ratings on assistant messages within chat.
    • Launched a custom chat experience supporting authenticated sessions, message streaming, example prompts, and a sign-in prompt for unauthenticated users.
    • Added floating AI chat assistant buttons to team and project pages for quick access.
  • Improvements

    • Updated support page chat UI and prompt labeling for clarity and personalization.
    • Added dynamic placeholder text "Ask Nebula" to chat input fields across multiple components.
    • Implemented authentication checks redirecting unauthenticated users to login on team pages.

@Yash094 Yash094 requested review from a team as code owners May 22, 2025 18:43
Copy link

changeset-bot bot commented May 22, 2025

⚠️ No Changeset found

Latest commit: b32f10b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented May 22, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 23, 2025 4:19am
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) May 23, 2025 4:19am
login ⬜️ Skipped (Inspect) May 23, 2025 4:19am
thirdweb_playground ⬜️ Skipped (Inspect) May 23, 2025 4:19am
wallet-ui ⬜️ Skipped (Inspect) May 23, 2025 4:19am

Copy link
Contributor

graphite-app bot commented May 22, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

Copy link
Contributor

coderabbitai bot commented May 22, 2025

Walkthrough

The changes introduce a new custom chat button and chat content components, replacing the previous Nebula chat button in the support page. The support chat now uses a different label, passes authentication tokens, and updates API parameter handling. Additionally, a feedback feature for assistant messages is added to the chat component, allowing users to rate responses.

Changes

File(s) Change Summary
apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx Replaced NebulaChatButton with CustomChatButton, removed thirdweb client creation, fetched teams asynchronously to get teamId, changed button label to "Ask AI for support", removed prompt prefix and old example prompts, added exported siwaExamplePrompts, passed authToken, teamId, and clientId props to chat button, and removed nebulaParams.
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx Added new FeedbackButtons component for assistant messages to submit positive/negative feedback asynchronously to an API endpoint with session and team context; manages loading and thank-you states. Added teamId parameter propagation. Existing message feedback UI remains unchanged. Imported new icons, hooks, and button component.
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx Added new CustomChatButton React component managing modal open state, rendering a button and popup chat modal, passing props including authToken, teamId, and clientId. Uses a thirdweb client instance internally and conditionally renders CustomChatContent with example prompts mapped to objects.
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx Added new CustomChatContent React component with authentication gating: renders sign-in prompt if not logged in, otherwise manages chat state with message streaming, session ID, abort controller, and analytics. Sends user messages to a proxied API with auth headers and team/client IDs. Renders empty state with example prompts or chat messages and input bar. Includes internal components for logged-out state and empty state with example prompts.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx Replaced local example prompt strings with imported examplePrompts array for NebulaChatButton usage; simplified prompt mapping to direct array pass-through.
apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx Added a floating CustomChatButton at bottom-right of team layout page with props including logged-in status, all networks, floating state, label "Ask AI Assistant", team context, example prompts, and auth token.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx Added a floating CustomChatButton at bottom-right of project layout page with props including logged-in status, all networks, floating state, page type "support", label "Ask AI Assistant", example prompts siwaExamplePrompts, team ID, client ID from project publishable key, and auth token.
apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx Added authentication check in RootTeamLayout async function by importing and calling getAuthToken; redirects unauthenticated users to /login before existing logic.
apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx Extended ChatBar component props to include required placeholder string; replaced hardcoded placeholder with prop value in the input textarea.
apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx Added placeholder="Ask Nebula" prop to ChatBar component usage.
apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx Added static placeholder="Ask Nebula" prop to ChatBar component in storybook variant.
apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx Added placeholder="Ask Nebula" prop to ChatBar component; simplified ExamplePrompt component props type annotation from multiline to single-line inline.
apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx Added placeholder="Ask Nebula" prop to ChatBar component; simplified ExamplePromptButton props type annotation from multiline to single-line inline.
apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx Added explicit teamId={undefined} prop to Chats component invocation in storybook variant.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SupportPage
    participant CustomChatButton
    participant CustomChatContent
    participant API
    participant Auth

    User->>SupportPage: Visits support page
    SupportPage->>CustomChatButton: Renders chat button (with authToken)
    User->>CustomChatButton: Clicks chat button
    CustomChatButton->>CustomChatContent: Opens chat modal
    CustomChatContent->>Auth: Checks if user is authenticated
    alt Not Authenticated
        CustomChatContent->>User: Shows sign-in prompt
    else Authenticated
        CustomChatContent->>User: Shows chat UI
        User->>CustomChatContent: Submits message
        CustomChatContent->>API: Sends message with authToken and session info
        API-->>CustomChatContent: Streams assistant response
        CustomChatContent->>User: Displays assistant response
        User->>CustomChatContent: Provides feedback (good/bad)
        CustomChatContent->>API: Sends feedback with sessionId, message, rating
        API-->>CustomChatContent: Acknowledges feedback
        CustomChatContent->>User: Shows thank-you message
    end
Loading

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a50e8c and b32f10b.

📒 Files selected for processing (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label May 22, 2025
Copy link

codecov bot commented May 22, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.61%. Comparing base (526b6b5) to head (b32f10b).
Report is 7 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7128   +/-   ##
=======================================
  Coverage   55.61%   55.61%           
=======================================
  Files         902      902           
  Lines       58177    58177           
  Branches     4085     4085           
=======================================
  Hits        32356    32356           
  Misses      25716    25716           
  Partials      105      105           
Flag Coverage Δ
packages 55.61% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

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

🧹 Nitpick comments (10)
apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (2)

13-13: Prefer path-aliases over deeply-nested relative paths

The relative import travels 6 directory levels upward/downward.
That becomes fragile the moment one of the segment folders is renamed or moved and is also hard to read.

-import { CustomChatButton } from "../../../nebula-app/(app)/components/CustomChat/CustomChatButton";
+import { CustomChatButton } from "@/nebula-app/components/CustomChat/CustomChatButton";

Consider adding a paths alias (e.g. @/nebula-app) in tsconfig.json so every file can import this component with a single, stable alias.
This improves maintainability and reduces merge-conflict headaches.


154-156: Branding inconsistency – “Nebula AI” vs “Siwa AI”

The heading still says “Nebula AI”, while the new button and PR description refer to “Siwa AI”.

Keeping both names in the same view is confusing for users and weakens the re-branding attempt.

-Get instant answers with Nebula AI, our onchain support assistant.
+Get instant answers with Siwa AI, our on-chain support assistant.
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (1)

227-260: Duplicate rendering path for assistant messages

A dedicated branch for message.type === "assistant" is added here, but the generic branch starting at line 262 still includes assistant-specific handling (icon, feedback, etc.).
While the early return prevents double-rendering, the duplicate code increases maintenance cost and risks the two branches drifting apart.

Consider extracting shared pieces into a helper component or keeping a single rendering path with feature flags.

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (3)

4-5: Unused import

ArrowUpRightIcon is imported but never used – remove to keep the bundle lean.

-import { ArrowRightIcon, ArrowUpRightIcon } from "lucide-react";
+import { ArrowRightIcon } from "lucide-react";
🧰 Tools
🪛 Biome (1.9.4)

[error] 4-4: This import is unused.

Unused imports might be the result of an incomplete refactoring.
Safe fix: Remove the unused import.

(lint/correctness/noUnusedImports)


92-98: useCallback dependency list contains an unused item

contextFilters never appears inside the callback body but is listed as a dependency, causing unnecessary re-creations.

-  [
-    props.authToken,
-    contextFilters,
+  [
+    props.authToken,

Double-check if you really need contextFilters here; otherwise remove it to satisfy the linter and save renders.

🧰 Tools
🪛 Biome (1.9.4)

[error] 92-92: This hook specifies more dependencies than necessary: contextFilters

This dependency can be removed from the list.

(lint/correctness/useExhaustiveDependencies)


176-180: Unused caught error

error is caught but not referenced – prefix with _ or log it for debugging.

-} catch (error) {
+} catch (_error) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 177-177: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (4)

29-31: Remove or implement commented-out code

There's a commented section about adding an outside click handler. Either implement this functionality or remove the comment to keep the code clean.

If you decide to implement it, you could add:

useEffect(() => {
  function handleClickOutside(event: MouseEvent) {
    if (ref.current && !ref.current.contains(event.target as Node)) {
      closeModal();
    }
  }
  
  document.addEventListener("mousedown", handleClickOutside);
  return () => {
    document.removeEventListener("mousedown", handleClickOutside);
  };
}, [closeModal]);

62-62: Sort CSS classes for better readability

The CSS classes in this line should be sorted for consistency and better maintainability.

- <div className="font-semibold text-lg flex items-center gap-2">
+ <div className="flex items-center gap-2 text-lg font-semibold">
🧰 Tools
🪛 Biome (1.9.4)

[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


54-57: Consider extracting complex className strings

The className string is quite complex and might be difficult to maintain. Consider extracting it to a separate variable or using a more structured approach.

+ const modalClasses = "slide-in-from-bottom-20 zoom-in-95 fade-in-0 fixed bottom-0 left-0 z-50 flex h-[80vh] w-[100vw] animate-in flex-col overflow-hidden rounded-t-2xl border bg-background shadow-2xl duration-200 lg:right-6 lg:bottom-6 lg:left-auto lg:h-[80vh] lg:max-w-xl lg:rounded-xl";
  <div
    className={cn(
-     "slide-in-from-bottom-20 zoom-in-95 fade-in-0 fixed bottom-0 left-0 z-50 flex h-[80vh] w-[100vw] animate-in flex-col overflow-hidden rounded-t-2xl border bg-background shadow-2xl duration-200 lg:right-6 lg:bottom-6 lg:left-auto lg:h-[80vh] lg:max-w-xl lg:rounded-xl",
+     modalClasses,
      !isOpen && "hidden"
    )}

40-50: Consider accessibility improvements for the chat button

The button would benefit from additional accessibility attributes to improve user experience for screen reader users.

  <Button
    onClick={() => {
      setIsOpen(true);
      setHasBeenOpened(true);
    }}
    variant="default"
    className="gap-2 rounded-full shadow-lg"
+   aria-label="Open chat"
+   aria-expanded={isOpen}
  >
    <MessageCircleIcon className="size-4" />
    {props.label}
  </Button>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 526b6b5 and 1e918d0.

📒 Files selected for processing (4)
  • apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (4 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (3 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (1)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1)
  • CustomChatButton (11-93)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (1)
apps/dashboard/src/app/nebula-app/(app)/icons/NebulaIcon.tsx (1)
  • NebulaIcon (1-24)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (3)
apps/dashboard/src/app/nebula-app/(app)/data/examplePrompts.ts (1)
  • ExamplePrompt (1-5)
apps/dashboard/src/@/components/ui/button.tsx (1)
  • Button (67-67)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1)
  • CustomChatContent (22-51)
🪛 Biome (1.9.4)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx

[error] 487-487: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 491-491: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 493-493: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 501-501: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 461-461: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend feedback with an underscore.

(lint/correctness/noUnusedVariables)


[error] 479-479: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend e with an underscore.

(lint/correctness/noUnusedVariables)


[error] 492-497: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 500-505: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 301-301: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 4-4: This import is unused.

Unused imports might be the result of an incomplete refactoring.
Safe fix: Remove the unused import.

(lint/correctness/noUnusedImports)


[error] 92-92: This hook specifies more dependencies than necessary: contextFilters

This dependency can be removed from the list.

(lint/correctness/useExhaustiveDependencies)


[error] 177-177: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx

[error] 18-18: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 25-25: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend setIsDismissed with an underscore.

(lint/correctness/noUnusedVariables)

🪛 Gitleaks (8.26.0)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

158-158: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (1)

159-176: Optional: remove unused prop when value is always empty

supportPromptPrefix is now an empty string and passed through customApiParams.messagePrefix.
If the prefix is deliberately disabled everywhere, consider dropping the prop altogether to avoid sending redundant data over the wire.

No action required if you expect this to be repopulated soon.

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (2)

33-35: Potentially unreachable conditional rendering

This conditional check on isDismissed will never be true since setIsDismissed is never called, making this code block effectively unreachable.

Verify if this dismiss functionality is intentional. If so, implement a way to set the isDismissed state to true.


11-93: Overall implementation looks good with minor improvements needed

The component implements a chat button and popup modal with good separation of concerns. The props are passed correctly to the CustomChatContent component, and the UI states are managed appropriately. Fix the issues with the any type, unused state variable, and consider the accessibility improvements suggested.

🧰 Tools
🪛 Biome (1.9.4)

[error] 18-18: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 25-25: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend setIsDismissed with an underscore.

(lint/correctness/noUnusedVariables)

@vercel vercel bot temporarily deployed to Preview – wallet-ui May 22, 2025 18:47 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 22, 2025 18:47 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 22, 2025 18:47 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 22, 2025 18:47 Inactive
Copy link
Contributor

github-actions bot commented May 22, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 56.62 KB (0%) 1.2 s (0%) 430 ms (+99.59% 🔺) 1.6 s
thirdweb (cjs) 309.13 KB (0%) 6.2 s (0%) 2.1 s (+1.71% 🔺) 8.3 s
thirdweb (minimal + tree-shaking) 5.69 KB (0%) 114 ms (0%) 148 ms (+877.68% 🔺) 262 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 66 ms (+1089.79% 🔺) 76 ms
thirdweb/react (minimal + tree-shaking) 19.5 KB (0%) 390 ms (0%) 228 ms (+483.7% 🔺) 618 ms

@vercel vercel bot temporarily deployed to Preview – docs-v2 May 22, 2025 18:49 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 22, 2025 18:50 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 22, 2025 18:50 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 22, 2025 18:50 Inactive
Copy link
Contributor

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

♻️ Duplicate comments (5)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (1)

460-517: Fix minor issues in FeedbackButtons component

There are several minor issues that should be addressed:

  1. The feedback state is set but never read
  2. Buttons miss an explicit type="button" attribute - default "submit" can cause unintended form submissions
  3. The error variable e in the catch block is unused
  4. Class lists are unsorted (style-lint)

Apply this diff to fix the issues:

-const [feedback, setFeedback] = useState<"good" | "bad" | null>(null);
+// State to track user feedback
+const [loading, setLoading] = useState(false);
+const [thankYou, setThankYou] = useState(false);

 async function sendFeedback(rating: "good" | "bad") {
   setLoading(true);
   try {
     await fetch("https://siwa-api.thirdweb-dev.com/v1/feedback", {
       method: "POST",
       headers: { "Content-Type": "application/json" },
       body: JSON.stringify({
         conversationId: sessionId,
         message: messageText,
         rating,
       }),
     });
-    setFeedback(rating);
     setThankYou(true);
-  } catch (e) {
+  } catch (_error) {
     // handle error
   } finally {
     setLoading(false);
   }
 }

 if (thankYou) {
   return (
-    <div className="mt-2 text-xs text-muted-foreground">
+    <div className="text-muted-foreground text-xs mt-2">
       Thank you for your feedback!
     </div>
   );
 }

 return (
-  <div className="flex gap-2 mt-2">
+  <div className="flex gap-2 mt-2">
     <button
-      className="p-1 rounded-full border hover:bg-muted-foreground/10"
+      className="border hover:bg-muted-foreground/10 p-1 rounded-full"
+      type="button"
       onClick={() => sendFeedback("good")}
       disabled={loading}
       aria-label="Thumbs up"
     >
       <ThumbsUpIcon className="size-4 text-green-500" />
     </button>
     <button
-      className="p-1 rounded-full border hover:bg-muted-foreground/10"
+      className="border hover:bg-muted-foreground/10 p-1 rounded-full"
+      type="button"
       onClick={() => sendFeedback("bad")}
       disabled={loading}
       aria-label="Thumbs down"
     >
       <ThumbsDownIcon className="size-4 text-red-500" />
     </button>
   </div>
 );
🧰 Tools
🪛 Biome (1.9.4)

[error] 491-491: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 498-498: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 500-500: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 508-508: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 464-464: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend feedback with an underscore.

(lint/correctness/noUnusedVariables)


[error] 482-482: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend e with an underscore.

(lint/correctness/noUnusedVariables)


[error] 499-504: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 507-512: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (2)

144-147: Avoid any – give payload a type

Using any drops all type-safety right before a network request.

Introduce an interface:

+interface SiwaPayload {
+  message: string;
+  authToken: string;
+  conversationId: string;
+}

-const payload: any = {
+const payload: SiwaPayload = {
  message:
    messageToSend.content.find((x) => x.type === "text")?.text ?? "",
  authToken: props.authToken,
  conversationId: sessionId ?? "25000000005",
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


158-160: ⚠️ Potential issue

Hard-coded CORS-sh proxy key leaked to the client

The header

"x-cors-api-key": "temp_3f2b6d4409a86dc7f4b7c45840dbd8e9"

exposes what looks like an API key to every site visitor (this file is shipped to the browser).
Anyone can now abuse the proxy quota.

Move this key to a server-side environment variable (e.g. process.env.CORS_PROXY_KEY) and inject it only in API routes or get rid of the proxy entirely by enabling CORS on the upstream service.

🧰 Tools
🪛 Gitleaks (8.26.0)

159-159: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (2)

18-18: Avoid using the any type in TypeScript

The customApiParams prop is typed as any, which bypasses TypeScript's type checking and can lead to runtime errors. Based on how this prop is used in CustomChatContent, you should use a more specific type.

-  customApiParams: any;
+  customApiParams: {
+    messagePrefix: string;
+    chainIds: number[];
+    wallet: string | undefined;
+  } | undefined;
🧰 Tools
🪛 Biome (1.9.4)

[error] 18-18: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


23-35: Unused state variable setIsDismissed

The setIsDismissed state setter is defined but never used in the component, while the isDismissed state is checked for conditional rendering. This suggests incomplete implementation.

Either implement the dismiss functionality or remove the unused state if it's not needed:

- const [isDismissed, setIsDismissed] = useState(false);
+ // If dismiss functionality is planned but not yet implemented:
+ // TODO: Implement dismiss functionality
+ const [isDismissed] = useState(false);

If the dismiss functionality is planned for future implementation, consider adding a TODO comment or implementing it now.

🧰 Tools
🪛 Biome (1.9.4)

[error] 25-25: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend setIsDismissed with an underscore.

(lint/correctness/noUnusedVariables)

🧹 Nitpick comments (4)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (2)

92-204: Improve error handling and remove unnecessary dependency

The contextFilters dependency is specified in the useCallback but is not used within the callback function. Also, the error handling could be improved to provide more specific error messages.

const handleSendMessage = useCallback(
  async (userMessage: NebulaUserMessage) => {
    // function implementation...
  },
  [
    props.authToken,
-   contextFilters,
    sessionId,
    props.customApiParams?.messagePrefix,
    userHasSubmittedMessage,
    trackEvent,
    props.pageType,
  ],
);

Also, improve error handling:

} catch (error) {
  if (abortController.signal.aborted) {
    return;
  }
+ 
+ const errorMessage = error instanceof Error 
+   ? `Error: ${error.message}` 
+   : "Sorry, something went wrong.";
+ 
  setMessages((prev) => [
    ...prev.slice(0, -1),
    {
      type: "assistant",
      request_id: undefined,
-     text: "Sorry, something went wrong.",
+     text: errorMessage,
    },
  ]);
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 92-92: This hook specifies more dependencies than necessary: contextFilters

This dependency can be removed from the list.

(lint/correctness/useExhaustiveDependencies)


[error] 178-178: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

🪛 Gitleaks (8.26.0)

159-159: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


154-164: Consider implementing a retry mechanism for API calls

The current implementation doesn't handle temporary network failures or server issues. Adding a retry mechanism would improve reliability.

+async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3): Promise<Response> {
+  let retries = 0;
+  while (retries < maxRetries) {
+    try {
+      return await fetch(url, options);
+    } catch (error) {
+      retries++;
+      if (retries >= maxRetries) throw error;
+      // Exponential backoff
+      await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retries - 1)));
+    }
+  }
+  throw new Error("Max retries exceeded");
+}

// Replace the fetch call with:
-const response = await fetch(
+const response = await fetchWithRetry(
  "https://proxy.cors.sh/https://siwa-slack-bot-u8ne.chainsaw-dev.zeet.app/siwa",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-cors-api-key": "temp_3f2b6d4409a86dc7f4b7c45840dbd8e9", // replace with your cors.sh API key
    },
    body: JSON.stringify(payload),
    signal: abortController.signal,
  },
);
🧰 Tools
🪛 Gitleaks (8.26.0)

159-159: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (2)

62-65: Sort CSS classes for consistency

The CSS classes in this line should be sorted for consistency with project standards.

-<div className="font-semibold text-lg flex items-center gap-2">
+<div className="flex items-center gap-2 font-semibold text-lg">
🧰 Tools
🪛 Biome (1.9.4)

[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


37-93: Consider adding keyboard navigation support

The chat modal lacks keyboard navigation support (Escape to close, focus trapping). This would improve accessibility.

Consider adding:

  1. Event listener for Escape key to close modal
  2. Focus trap to keep keyboard focus within the modal
  3. Return focus to button when modal closes
+import { useEffect } from "react";
+import FocusTrap from "focus-trap-react"; // You may need to install this

// Inside the component:
+useEffect(() => {
+  const handleKeyDown = (e: KeyboardEvent) => {
+    if (e.key === "Escape" && isOpen) {
+      closeModal();
+    }
+  };
+  
+  window.addEventListener("keydown", handleKeyDown);
+  return () => window.removeEventListener("keydown", handleKeyDown);
+}, [isOpen, closeModal]);

// Wrap modal content with FocusTrap
+{isOpen && (
+  <FocusTrap focusTrapOptions={{ initialFocus: false }}>
     <div className={cn(...)} ref={ref}>
       {/* Modal content */}
     </div>
+  </FocusTrap>
+)}
🧰 Tools
🪛 Biome (1.9.4)

[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e918d0 and 4994fbe.

📒 Files selected for processing (4)
  • apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (4 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (3 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (1)
apps/dashboard/src/app/nebula-app/(app)/icons/NebulaIcon.tsx (1)
  • NebulaIcon (1-24)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (3)
apps/dashboard/src/app/nebula-app/(app)/data/examplePrompts.ts (1)
  • ExamplePrompt (1-5)
apps/dashboard/src/@/components/ui/button.tsx (1)
  • Button (67-67)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1)
  • CustomChatContent (22-51)
🪛 Biome (1.9.4)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 302-302: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 92-92: This hook specifies more dependencies than necessary: contextFilters

This dependency can be removed from the list.

(lint/correctness/useExhaustiveDependencies)


[error] 178-178: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx

[error] 491-491: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 498-498: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 500-500: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 508-508: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 464-464: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend feedback with an underscore.

(lint/correctness/noUnusedVariables)


[error] 482-482: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend e with an underscore.

(lint/correctness/noUnusedVariables)


[error] 499-504: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 507-512: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx

[error] 18-18: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 62-62: These CSS classes should be sorted.

Unsafe fix: Sort the classes.

(lint/nursery/useSortedClasses)


[error] 25-25: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend setIsDismissed with an underscore.

(lint/correctness/noUnusedVariables)

🪛 Gitleaks (8.26.0)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

159-159: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (1)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (1)

227-259: Positive: Added dedicated feedback UI for assistant messages

The new dedicated rendering for assistant messages with integrated feedback buttons creates a cleaner user experience and will help gather useful feedback.

Copy link
Contributor

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

♻️ Duplicate comments (2)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (2)

144-149: Fix the any type for payload object

Using any drops all type safety right before a network request. Define a proper interface for the payload object.

-const payload: any = {
+interface SiwaPayload {
+  message: string;
+  authToken: string;
+  conversationId: string;
+}
+
+const payload: SiwaPayload = {
  message:
    messageToSend.content.find((x) => x.type === "text")?.text ?? "",
  authToken: props.authToken,
  conversationId: "25000000005",
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


300-302: Fix any type in EmptyStateChatPageContent props

The sendMessage prop in EmptyStateChatPageContent is typed as any, which reduces type safety.

function EmptyStateChatPageContent(props: {
-  sendMessage: (message: any) => void;
+  sendMessage: (message: NebulaUserMessage) => void;
  examplePrompts: { title: string; message: string }[];
}) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 301-301: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

🧹 Nitpick comments (4)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (4)

14-14: Remove commented-out import with "REMOVE" comment

The code contains a commented-out import statement with an explicit "REMOVE" comment. It's best to clean up this code to prevent confusion and maintain a clean codebase.

-// import { createSession } from "../../api/session"; // REMOVE

148-148: Avoid hardcoding the default conversation ID

The conversation ID "25000000005" is hardcoded in the payload. Consider extracting this to a constant or configuration to improve maintainability.

+const DEFAULT_CONVERSATION_ID = "25000000005";
+
 const payload: any = {
   message:
     messageToSend.content.find((x) => x.type === "text")?.text ?? "",
   authToken: props.authToken,
-  conversationId: "25000000005",
+  conversationId: DEFAULT_CONVERSATION_ID,
 };

153-163: Consider extracting API URL to a configuration variable

The API endpoint URL is hardcoded in the fetch call. Extract it to a constant or environment variable for better maintainability and flexibility across environments.

+const SIWA_API_ENDPOINT = "https://siwa-api.thirdweb-dev.com/api/chat";
+
 const response = await fetch(
-  "https://siwa-api.thirdweb-dev.com/api/chat",
+  SIWA_API_ENDPOINT,
   {
     method: "POST",
     headers: {
       "Content-Type": "application/json",
     },
     body: JSON.stringify(payload),
     signal: abortController.signal,
   },
 );

177-178: Utilize the error variable in catch block

The error variable is caught but not used. Consider logging the error or using it to provide more specific error messages to users.

-} catch (error) {
+} catch (error) {
+  console.error("Chat API error:", error);
   if (abortController.signal.aborted) {
     return;
   }
   setMessages((prev) => [
🧰 Tools
🪛 Biome (1.9.4)

[error] 177-177: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4994fbe and c8843ae.

📒 Files selected for processing (1)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx

[error] 144-144: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 301-301: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 92-92: This hook specifies more dependencies than necessary: contextFilters

This dependency can be removed from the list.

(lint/correctness/useExhaustiveDependencies)


[error] 177-177: This variable is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.
Unsafe fix: If this is intentional, prepend error with an underscore.

(lint/correctness/noUnusedVariables)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (2)

206-226: The code elegantly handles conditional rendering

The component properly handles different states: showing an empty state when no messages have been submitted, and the chat interface otherwise. The props passed to child components are comprehensive and well-structured.


264-298: Well-designed login state with clear user guidance

The logged-out state provides a clear call-to-action for users to sign in, with appropriate styling and a useful link that preserves the current path for redirection after login.

@vercel vercel bot temporarily deployed to Preview – wallet-ui May 23, 2025 00:05 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 23, 2025 00:05 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 23, 2025 00:05 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 23, 2025 00:05 Inactive
Copy link
Contributor

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8843ae and dca105c.

📒 Files selected for processing (13)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (6 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (3)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx (1)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
🧬 Code Graph Analysis (2)
apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx (2)
apps/dashboard/src/app/(app)/api/lib/getAuthToken.ts (1)
  • getAuthToken (6-14)
apps/dashboard/src/@/api/team.ts (1)
  • getTeamBySlug (11-30)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx (2)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1)
  • CustomChatButton (16-92)
apps/dashboard/src/app/(app)/(dashboard)/support/page.tsx (1)
  • siwaExamplePrompts (121-126)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (27)
apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx (2)

71-71: Good addition of placeholder prop for better UI customization.

Adding the placeholder prop to the ChatBar component enhances UI flexibility and enables consistent placeholder text across different chat interfaces in the application.


146-146: Properly implemented placeholder text in the textarea.

The placeholder is correctly applied to the AutoResizeTextarea component, completing the implementation of the new prop.

apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx (2)

218-218: Correctly implemented the required placeholder prop.

The placeholder value "Ask Nebula" has been added to comply with the updated ChatBar component's requirements, maintaining consistency with other chat interfaces.


336-336: Good simplification of type annotation.

The type annotation for ExamplePromptButton props has been simplified from a multiline object type to a cleaner inline type, improving code readability without changing functionality.

apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx (2)

46-46: Correctly implemented the required placeholder prop.

The placeholder value "Ask Nebula" has been added to comply with the updated ChatBar component's requirements, maintaining consistency with other chat interfaces.


86-86: Good simplification of type annotation.

The type annotation for ExamplePrompt props has been simplified from a multiline object type to a cleaner inline type, improving code readability without changing functionality.

apps/dashboard/src/app/(app)/team/[team_slug]/layout.tsx (3)

8-8: Good addition of authentication token retrieval.

The import of getAuthToken enables proper authentication verification in the team layout.


22-22: Authentication token correctly retrieved.

The auth token is properly fetched using the imported getAuthToken function, which retrieves it from cookies.


29-31: Appropriate authentication check added.

This addition properly redirects unauthenticated users to the login page, enhancing security by ensuring only authenticated users can access team pages. The check is correctly positioned after team existence verification but before the onboarding completion check.

apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx (2)

8-9: Good addition of necessary imports.

Clean import statements for the new chat functionality components.


96-112: LGTM! Well-implemented chat button integration.

The CustomChatButton is properly positioned in a fixed container at the bottom-right corner. All required props are correctly passed, including authentication token, team context, and appropriate configuration.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/layout.tsx (2)

15-16: Good import declarations for chat functionality.

Clean import of the CustomChatButton component and reuse of example prompts from the support page.


83-95: Well-implemented project-context chat button.

The CustomChatButton is correctly positioned and configured with project-specific context, including teamId and clientId (from project.publishableKey). This maintains consistency with the team layout while adding project-specific context.

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (7)

11-14: Well-implemented thirdweb client initialization.

The client is correctly created using the public client ID constant.


16-27: Well-designed component props interface.

The props interface is clear, type-safe, and comprehensive, covering all necessary configuration options for the chat button.


28-31: Good state management.

State variables and the close modal callback are well-defined and appropriately scoped.


36-46: Well-implemented button component.

The button correctly handles state updates and provides appropriate visual feedback.


49-54: Good responsive modal implementation.

The modal uses conditional classes for responsive design and animation, with proper z-index and positioning.


57-71: Clean header implementation with appropriate accessibility.

The header includes proper aria-label for the close button and clear visual hierarchy.


73-88: Efficient conditional rendering of chat content.

The chat content is only rendered when needed (hasBeenOpened && isOpen) to improve performance, and all required props are correctly passed to CustomChatContent.

apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (7)

18-26: Well-defined component props with proper typing.

The props interface is comprehensive with appropriate types for all required properties.


27-40: Good conditional rendering for authentication.

The component correctly handles the authentication state, rendering different content based on the presence of an auth token.


43-50: Well-structured logged-in component props.

Props are clearly defined with appropriate types for the logged-in state.


51-61: Comprehensive state management.

All necessary states for managing chat functionality are properly defined.


63-150: Well-implemented message handling with proper error handling.

The handleSendMessage callback correctly manages the chat state, API communication, and error handling. The dependencies array is appropriate for the callback.


203-237: Well-designed logged-out state.

The logged-out state provides a clear call-to-action for users to sign in, with appropriate styling and UX.


239-284: Good empty state implementation with example prompts.

The empty state component provides helpful example prompts to guide users and is well-styled with appropriate spacing and layout.

@vercel vercel bot temporarily deployed to Preview – docs-v2 May 23, 2025 03:53 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 23, 2025 03:53 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 23, 2025 03:53 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 23, 2025 03:53 Inactive
Copy link
Contributor

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

🧹 Nitpick comments (1)
apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx (1)

230-230: Proper alignment with team-scoped chat features.

Adding the explicit teamId={undefined} prop aligns this component with other similar components in the codebase that now pass this property, maintaining consistency with the team-scoped chat features implementation.

Consider adding a story variant that demonstrates the behavior when teamId is set to a valid value to showcase the team-scoped chat features.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dca105c and ae19f80.

📒 Files selected for processing (7)
  • apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx (2 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx (6 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx (1 hunks)
  • apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/(team)/layout.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/FloatingChat/FloatingChatContent.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
  • apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Analyze (javascript)

@vercel vercel bot temporarily deployed to Preview – login May 23, 2025 04:06 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 23, 2025 04:06 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 23, 2025 04:06 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 23, 2025 04:06 Inactive
@joaquim-verges joaquim-verges changed the title siwa chat widget [Dashboard] siwa chat widget May 23, 2025
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 23, 2025 04:12 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 23, 2025 04:12 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 23, 2025 04:12 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 23, 2025 04:12 Inactive
@joaquim-verges joaquim-verges merged commit 7130f9a into main May 23, 2025
24 checks passed
@joaquim-verges joaquim-verges deleted the yash/add-siwa branch May 23, 2025 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dashboard Involves changes to the Dashboard.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants