-
Notifications
You must be signed in to change notification settings - Fork 543
[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
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
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. |
WalkthroughThe 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
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
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms (6)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
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
🚀 New features to boost your workflow:
|
There was a problem hiding this 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 pathsThe 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
) intsconfig.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 messagesA 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 earlyreturn
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 codeThere'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 readabilityThe 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 stringsThe 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 buttonThe 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
📒 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 throughcustomApiParams.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 renderingThis conditional check on
isDismissed
will never be true sincesetIsDismissed
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 neededThe 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 theany
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)
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatButton.tsx
Outdated
Show resolved
Hide resolved
size-limit report 📦
|
There was a problem hiding this 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 componentThere are several minor issues that should be addressed:
- The
feedback
state is set but never read- Buttons miss an explicit
type="button"
attribute - default "submit" can cause unintended form submissions- The error variable
e
in the catch block is unused- 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
: Avoidany
– givepayload
a typeUsing
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 issueHard-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 theany
type in TypeScriptThe
customApiParams
prop is typed asany
, which bypasses TypeScript's type checking and can lead to runtime errors. Based on how this prop is used inCustomChatContent
, 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 variablesetIsDismissed
The
setIsDismissed
state setter is defined but never used in the component, while theisDismissed
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 dependencyThe
contextFilters
dependency is specified in theuseCallback
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 callsThe 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 consistencyThe 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 supportThe chat modal lacks keyboard navigation support (Escape to close, focus trapping). This would improve accessibility.
Consider adding:
- Event listener for Escape key to close modal
- Focus trap to keep keyboard focus within the modal
- 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
📒 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 messagesThe new dedicated rendering for assistant messages with integrated feedback buttons creates a cleaner user experience and will help gather useful feedback.
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 theany
type for payload objectUsing
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
: Fixany
type in EmptyStateChatPageContent propsThe
sendMessage
prop in EmptyStateChatPageContent is typed asany
, 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" commentThe 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 IDThe 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 variableThe 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 blockThe 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
📒 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 renderingThe 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 guidanceThe 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.
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
📒 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.
apps/dashboard/src/app/nebula-app/(app)/components/CustomChat/CustomChatContent.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
📒 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)
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
teamId
andplaceholder
props to various components (Chats
,ChatBar
, etc.).FeedbackButtons
for user feedback on assistant messages.CustomChatButton
for initiating chat interactions.ExamplePrompt
andExamplePromptButton
functions for cleaner syntax.SupportPage
to utilize new prompt structures and chat button.Summary by CodeRabbit
New Features
Improvements