Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

@google-labs-jules google-labs-jules bot commented Jan 21, 2026

This PR introduces a complete Confirmation Dialog system to the Web application, replacing the native and intrusive window.confirm dialogs with a custom, accessible, and themable UI.

Changes:

  1. New Component: web/components/ui/ConfirmDialog.tsx - A specialized modal for confirmations with support for 'danger', 'warning', and 'info' variants.
  2. New Context: web/contexts/ConfirmContext.tsx - Provides a useConfirm hook that returns a Promise, allowing for cleaner async/await usage in components.
  3. Integration: Wrapped the application in ConfirmProvider within web/App.tsx.
  4. Refactor: Updated web/pages/GroupDetails.tsx to use the new system for all destructive actions.
  5. Accessibility: Improved the existing Modal component to include proper ARIA attributes, ensuring it is correctly identified by screen readers.

Verification:

  • Verified via Playwright (script created, run, and then cleaned up) that the dialog appears, captures focus, and correctly resolves the promise upon user interaction.
  • Verified that the integration with existing Modal styles works for both themes.

PR created automatically by Jules for task 12669270586709539879 started by @Devasy23

Summary by CodeRabbit

  • New Features

    • Added a confirmation dialog system for destructive actions (delete, remove members, leave groups) with promise-based async confirm flow and themed dialog variants.
  • Improvements

    • Replaced native browser confirms with the new dialog across relevant flows.
    • Enhanced modal accessibility with ARIA attributes and improved screen-reader labeling.

✏️ Tip: You can customize this high-level summary in your review settings.

- Replaces `window.confirm` with a custom, accessible `ConfirmDialog` component.
- Implements `ConfirmContext` for asynchronous confirmation handling using Promises.
- Adds `ConfirmProvider` to `App.tsx` to enable global usage.
- Updates `GroupDetails.tsx` to use `useConfirm` for destructive actions (Delete Group, Delete Expense, Leave Group, Remove Member).
- Enhances `Modal.tsx` accessibility by adding `role="dialog"`, `aria-modal="true"`, and `aria-labelledby`.
- Supports both Neobrutalism and Glassmorphism themes.
@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@netlify
Copy link

netlify bot commented Jan 21, 2026

Deploy Preview for split-but-wiser ready!

Name Link
🔨 Latest commit 1b9cd60
🔍 Latest deploy log https://app.netlify.com/projects/split-but-wiser/deploys/6978aa664b70bc0008c752f0
😎 Deploy Preview https://deploy-preview-256--split-but-wiser.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

Walkthrough

Adds a promise-based Confirmation Dialog System (ConfirmProvider, useConfirm, ConfirmDialog), integrates it into the app, replaces native window.confirm usages in GroupDetails, and improves Modal accessibility with ARIA attributes; updates related docs.

Changes

Cohort / File(s) Summary
Confirmation Dialog System
web/components/ui/ConfirmDialog.tsx, web/contexts/ConfirmContext.tsx
New ConfirmDialog component and ConfirmProvider + useConfirm hook implementing an async promise-based confirm API, variants (danger/warning/info), theme-aware styling, and internal promise resolution logic.
Modal Accessibility
web/components/ui/Modal.tsx
Adds role="dialog", aria-modal="true", generated aria-labelledby/id for the title, and aria-label on close button; close button changed to type="button".
App Integration
web/App.tsx
Wraps application with ConfirmProvider so useConfirm is available app-wide.
Feature Migration
web/pages/GroupDetails.tsx
Replaces window.confirm calls with useConfirm-driven async confirmations for deleting expenses/groups, leaving groups, and removing members; adds pre-check flow for unsettled balances.
Docs / Metadata
.Jules/changelog.md, .Jules/knowledge.md, .Jules/todo.md
Updates documentation and TODOs to describe the Confirmation Dialog System, usage patterns, and accessibility changes.

Suggested reviewers

  • vrajpatelll
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and directly describes the main change: introducing a custom Confirmation Dialog System to replace native window.confirm dialogs across the application.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

❤️ Share

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

@Devasy Devasy marked this pull request as ready for review January 23, 2026 16:19
@Devasy Devasy requested a review from vrajpatelll as a code owner January 23, 2026 16:19
@Devasy
Copy link
Owner

Devasy commented Jan 23, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

✅ Actions performed

Review triggered.

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

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

Caution

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

⚠️ Outside diff range comments (1)
web/pages/GroupDetails.tsx (1)

366-393: Unsettled balance check happens after confirmation.

The check for unsettled balances (lines 379-385) occurs after the user confirms removal. Consider validating this before showing the confirmation dialog to avoid a confusing experience where the user confirms but the action still fails.

Move validation before confirmation
     const handleKickMember = async (memberId: string, memberName: string) => {
         if (!id || !isAdmin) return;
         if (memberId === user?._id) return;
 
+        const hasUnsettled = settlements.some(
+            s => (s.fromUserId === memberId || s.toUserId === memberId) && (s.amount || 0) > 0
+        );
+        if (hasUnsettled) {
+            addToast('Cannot remove: This member has unsettled balances in the group.', 'error');
+            return;
+        }
+
         const confirmed = await confirm({
             title: 'Remove Member',
             description: `Are you sure you want to remove ${memberName} from the group?`,
             confirmText: 'Remove',
             variant: 'danger'
         });
 
         if (confirmed) {
             try {
-                const hasUnsettled = settlements.some(
-                    s => (s.fromUserId === memberId || s.toUserId === memberId) && (s.amount || 0) > 0
-                );
-                if (hasUnsettled) {
-                    alert('Cannot remove: This member has unsettled balances in the group.');
-                    return;
-                }
                 await removeMember(id, memberId);
                 fetchData();
                 addToast(`Removed ${memberName} from group`, 'success');
             } catch (err: any) {
                 addToast(err.response?.data?.detail || "Failed to remove member", 'error');
             }
         }
     };
🤖 Fix all issues with AI agents
In `@web/components/ui/ConfirmDialog.tsx`:
- Around line 31-32: The destructured but unused variable `mode` from useTheme()
should be removed to eliminate the unused variable warning: update the
destructuring in the ConfirmDialog component (where useTheme() is called) to
only pull `style` (e.g., change `const { style, mode } = useTheme()` to `const {
style } = useTheme()`), leaving the rest of the logic that uses `style`/`isNeo`
(`THEMES.NEOBRUTALISM`, `isNeo`) untouched.
- Around line 71-79: The ConfirmDialog currently sets autoFocus on the Confirm
button which can cause accidental destructive confirmations; update the footer
so that autoFocus is applied conditionally: if getButtonVariant() returns a
destructive variant (e.g., "danger" or "warning") move the autoFocus prop from
the confirm Button (onConfirm) to the cancel Button (onCancel), otherwise keep
autoFocus on the confirm Button; reference ConfirmDialog, getButtonVariant,
onConfirm, onCancel, cancelText and confirmText when making this change.

In `@web/components/ui/Modal.tsx`:
- Around line 68-70: The close button in Modal.tsx currently can act as a submit
button when placed inside forms; update the <button> element that calls onClose
(the button rendering the X icon) to include an explicit type="button" attribute
so it never triggers form submission, keeping the onClose handler and existing
classes/aria-label unchanged.
- Line 46: The Modal component currently hardcodes id="modal-title", which can
collide when multiple modals render; update the Modal (in
web/components/ui/Modal.tsx) to generate a unique id (e.g., call React's useId()
at top of the Modal component), assign that generated id to the dialog's
aria-labelledby attribute and to the modal title element (the element that
currently has id="modal-title"); add the necessary import for useId and replace
the hardcoded string with the generated id so each Modal instance gets a unique,
matching aria-labelledby/title id pair.

In `@web/contexts/ConfirmContext.tsx`:
- Around line 26-32: The current confirm function overwrites the previous
pending promise's resolver, leaving it unresolved; update confirm to first check
for an existing resolver (e.g., resolveRef.current or the existing value held by
setResolveRef) and settle it (call the previous resolve with false or call a
stored reject) before storing the new resolve and returning the new Promise;
specifically, in confirm, before setResolveRef(() => resolve) call the existing
resolver if present to resolve(false) (or reject) so the previous promise is not
left hanging, then proceed to setOptions, setIsOpen, and set the new resolver.

@Devasy
Copy link
Owner

Devasy commented Jan 24, 2026

@jules In @web/components/ui/ConfirmDialog.tsx: - Around line 31-32: The destructured but unused variable mode from useTheme() should be removed to eliminate the unused variable warning: update the destructuring in the ConfirmDialog component (where useTheme() is called) to only pull style (e.g., change const { style, mode } = useTheme() to const { style } = useTheme()), leaving the rest of the logic that uses style/isNeo (THEMES.NEOBRUTALISM, isNeo) untouched. - Around line 71-79: The ConfirmDialog currently sets autoFocus on the Confirm button which can cause accidental destructive confirmations; update the footer so that autoFocus is applied conditionally: if getButtonVariant() returns a destructive variant (e.g., "danger" or "warning") move the autoFocus prop from the confirm Button (onConfirm) to the cancel Button (onCancel), otherwise keep autoFocus on the confirm Button; reference ConfirmDialog, getButtonVariant, onConfirm, onCancel, cancelText and confirmText when making this change. In @web/components/ui/Modal.tsx: - Around line 68-70: The close button in Modal.tsx currently can act as a submit button when placed inside forms; update the element that calls onClose (the button rendering the X icon) to include an explicit type="button" attribute so it never triggers form submission, keeping the onClose handler and existing classes/aria-label unchanged. - Line 46: The Modal component currently hardcodes id="modal-title", which can collide when multiple modals render; update the Modal (in web/components/ui/Modal.tsx) to generate a unique id (e.g., call React's useId() at top of the Modal component), assign that generated id to the dialog's aria-labelledby attribute and to the modal title element (the element that currently has id="modal-title"); add the necessary import for useId and replace the hardcoded string with the generated id so each Modal instance gets a unique, matching aria-labelledby/title id pair. In @web/contexts/ConfirmContext.tsx: - Around line 26-32: The current confirm function overwrites the previous pending promise's resolver, leaving it unresolved; update confirm to first check for an existing resolver (e.g., resolveRef.current or the existing value held by setResolveRef) and settle it (call the previous resolve with false or call a stored reject) before storing the new resolve and returning the new Promise; specifically, in confirm, before setResolveRef(() => resolve) call the existing resolver if present to resolve(false) (or reject) so the previous promise is not left hanging, then proceed to setOptions, setIsOpen, and set the new resolver.

366-393: Unsettled balance check happens after confirmation.

The check for unsettled balances (lines 379-385) occurs after the user confirms removal. Consider validating this before showing the confirmation dialog to avoid a confusing experience where the user confirms but the action still fails.

@Devasy
Copy link
Owner

Devasy commented Jan 27, 2026

@jules In @web/components/ui/ConfirmDialog.tsx: - Around line 31-32: The destructured but unused variable mode from useTheme() should be removed to eliminate the unused variable warning: update the destructuring in the ConfirmDialog component (where useTheme() is called) to only pull style (e.g., change const { style, mode } = useTheme() to const { style } = useTheme()), leaving the rest of the logic that uses style/isNeo (THEMES.NEOBRUTALISM, isNeo) untouched. - Around line 71-79: The ConfirmDialog currently sets autoFocus on the Confirm button which can cause accidental destructive confirmations; update the footer so that autoFocus is applied conditionally: if getButtonVariant() returns a destructive variant (e.g., "danger" or "warning") move the autoFocus prop from the confirm Button (onConfirm) to the cancel Button (onCancel), otherwise keep autoFocus on the confirm Button; reference ConfirmDialog, getButtonVariant, onConfirm, onCancel, cancelText and confirmText when making this change. In @web/components/ui/Modal.tsx: - Around line 68-70: The close button in Modal.tsx currently can act as a submit button when placed inside forms; update the element that calls onClose (the button rendering the X icon) to include an explicit type="button" attribute so it never triggers form submission, keeping the onClose handler and existing classes/aria-label unchanged. - Line 46: The Modal component currently hardcodes id="modal-title", which can collide when multiple modals render; update the Modal (in web/components/ui/Modal.tsx) to generate a unique id (e.g., call React's useId() at top of the Modal component), assign that generated id to the dialog's aria-labelledby attribute and to the modal title element (the element that currently has id="modal-title"); add the necessary import for useId and replace the hardcoded string with the generated id so each Modal instance gets a unique, matching aria-labelledby/title id pair. In @web/contexts/ConfirmContext.tsx: - Around line 26-32: The current confirm function overwrites the previous pending promise's resolver, leaving it unresolved; update confirm to first check for an existing resolver (e.g., resolveRef.current or the existing value held by setResolveRef) and settle it (call the previous resolve with false or call a stored reject) before storing the new resolve and returning the new Promise; specifically, in confirm, before setResolveRef(() => resolve) call the existing resolver if present to resolve(false) (or reject) so the previous promise is not left hanging, then proceed to setOptions, setIsOpen, and set the new resolver.

366-393: Unsettled balance check happens after confirmation.

The check for unsettled balances (lines 379-385) occurs after the user confirms removal. Consider validating this before showing the confirmation dialog to avoid a confusing experience where the user confirms but the action still fails.

@google-labs-jules
Copy link
Contributor Author

@jules In @web/components/ui/ConfirmDialog.tsx: - Around line 31-32: The destructured but unused variable mode from useTheme() should be removed to eliminate the unused variable warning: update the destructuring in the ConfirmDialog component (where useTheme() is called) to only pull style (e.g., change const { style, mode } = useTheme() to const { style } = useTheme()), leaving the rest of the logic that uses style/isNeo (THEMES.NEOBRUTALISM, isNeo) untouched. - Around line 71-79: The ConfirmDialog currently sets autoFocus on the Confirm button which can cause accidental destructive confirmations; update the footer so that autoFocus is applied conditionally: if getButtonVariant() returns a destructive variant (e.g., "danger" or "warning") move the autoFocus prop from the confirm Button (onConfirm) to the cancel Button (onCancel), otherwise keep autoFocus on the confirm Button; reference ConfirmDialog, getButtonVariant, onConfirm, onCancel, cancelText and confirmText when making this change. In @web/components/ui/Modal.tsx: - Around line 68-70: The close button in Modal.tsx currently can act as a submit button when placed inside forms; update the element that calls onClose (the button rendering the X icon) to include an explicit type="button" attribute so it never triggers form submission, keeping the onClose handler and existing classes/aria-label unchanged. - Line 46: The Modal component currently hardcodes id="modal-title", which can collide when multiple modals render; update the Modal (in web/components/ui/Modal.tsx) to generate a unique id (e.g., call React's useId() at top of the Modal component), assign that generated id to the dialog's aria-labelledby attribute and to the modal title element (the element that currently has id="modal-title"); add the necessary import for useId and replace the hardcoded string with the generated id so each Modal instance gets a unique, matching aria-labelledby/title id pair. In @web/contexts/ConfirmContext.tsx: - Around line 26-32: The current confirm function overwrites the previous pending promise's resolver, leaving it unresolved; update confirm to first check for an existing resolver (e.g., resolveRef.current or the existing value held by setResolveRef) and settle it (call the previous resolve with false or call a stored reject) before storing the new resolve and returning the new Promise; specifically, in confirm, before setResolveRef(() => resolve) call the existing resolver if present to resolve(false) (or reject) so the previous promise is not left hanging, then proceed to setOptions, setIsOpen, and set the new resolver.

366-393: Unsettled balance check happens after confirmation.

The check for unsettled balances (lines 379-385) occurs after the user confirms removal. Consider validating this before showing the confirmation dialog to avoid a confusing experience where the user confirms but the action still fails.

Thank you for the detailed feedback. I have implemented all suggested changes:

  1. ConfirmDialog.tsx: Removed the unused mode variable and updated the autoFocus logic to focus the Cancel button for destructive actions (danger/warning variants).
  2. Modal.tsx: Added type="button" to the close button and implemented React.useId() for unique aria-labelledby IDs.
  3. ConfirmContext.tsx: Updated the confirm function to safely resolve any pending promises (with false) before starting a new one, using useRef to track the resolver synchronously.
  4. GroupDetails.tsx: Moved the unsettled balance check to before the confirmation dialog to prevent a confusing UX.

@google-labs-jules
Copy link
Contributor Author

@jules In @web/components/ui/ConfirmDialog.tsx: - Around line 31-32: The destructured but unused variable mode from useTheme() should be removed to eliminate the unused variable warning: update the destructuring in the ConfirmDialog component (where useTheme() is called) to only pull style (e.g., change const { style, mode } = useTheme() to const { style } = useTheme()), leaving the rest of the logic that uses style/isNeo (THEMES.NEOBRUTALISM, isNeo) untouched. - Around line 71-79: The ConfirmDialog currently sets autoFocus on the Confirm button which can cause accidental destructive confirmations; update the footer so that autoFocus is applied conditionally: if getButtonVariant() returns a destructive variant (e.g., "danger" or "warning") move the autoFocus prop from the confirm Button (onConfirm) to the cancel Button (onCancel), otherwise keep autoFocus on the confirm Button; reference ConfirmDialog, getButtonVariant, onConfirm, onCancel, cancelText and confirmText when making this change. In @web/components/ui/Modal.tsx: - Around line 68-70: The close button in Modal.tsx currently can act as a submit button when placed inside forms; update the element that calls onClose (the button rendering the X icon) to include an explicit type="button" attribute so it never triggers form submission, keeping the onClose handler and existing classes/aria-label unchanged. - Line 46: The Modal component currently hardcodes id="modal-title", which can collide when multiple modals render; update the Modal (in web/components/ui/Modal.tsx) to generate a unique id (e.g., call React's useId() at top of the Modal component), assign that generated id to the dialog's aria-labelledby attribute and to the modal title element (the element that currently has id="modal-title"); add the necessary import for useId and replace the hardcoded string with the generated id so each Modal instance gets a unique, matching aria-labelledby/title id pair. In @web/contexts/ConfirmContext.tsx: - Around line 26-32: The current confirm function overwrites the previous pending promise's resolver, leaving it unresolved; update confirm to first check for an existing resolver (e.g., resolveRef.current or the existing value held by setResolveRef) and settle it (call the previous resolve with false or call a stored reject) before storing the new resolve and returning the new Promise; specifically, in confirm, before setResolveRef(() => resolve) call the existing resolver if present to resolve(false) (or reject) so the previous promise is not left hanging, then proceed to setOptions, setIsOpen, and set the new resolver.

366-393: Unsettled balance check happens after confirmation.

The check for unsettled balances (lines 379-385) occurs after the user confirms removal. Consider validating this before showing the confirmation dialog to avoid a confusing experience where the user confirms but the action still fails.

I have moved the unsettled balance check to before the confirmation dialog in GroupDetails.tsx. Now, if a member has an unsettled balance, an info dialog is shown immediately, and the removal confirmation is only shown if the check passes.

- **ConfirmDialog.tsx**: Removed unused `mode` variable and updated `autoFocus` logic to prioritize Cancel button for destructive actions.
- **Modal.tsx**: Added `type="button"` to close button and implemented `React.useId()` for unique accessibility IDs.
- **ConfirmContext.tsx**: Updated to safely resolve pending promises using `useRef` before starting new confirmations.
- **GroupDetails.tsx**: Moved unsettled balance check before the removal confirmation dialog for better UX.

Co-authored-by: Devasy <110348311+Devasy@users.noreply.github.com>
@Devasy
Copy link
Owner

Devasy commented Jan 27, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

✅ Actions performed

Review triggered.

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

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

Caution

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

⚠️ Outside diff range comments (1)
web/pages/GroupDetails.tsx (1)

360-361: Consider typing error objects instead of using any.

The err: any pattern bypasses TypeScript's type checking. Consider using a more specific type or a type guard for safer error handling.

♻️ Optional: Type-safe error handling
-            } catch (err: any) {
-                addToast(err.response?.data?.detail || "Cannot leave - please settle balances first", 'error');
+            } catch (err) {
+                const message = err instanceof Error ? err.message : "Cannot leave - please settle balances first";
+                const detail = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
+                addToast(detail || message, 'error');
             }

Alternatively, create a utility function for extracting API error messages.

Also applies to: 397-398

🤖 Fix all issues with AI agents
In `@web/components/ui/ConfirmDialog.tsx`:
- Around line 35-44: The switch statements in getIcon and getIconBg should
include explicit default branches to return a safe fallback icon/background when
variant (ConfirmVariant) is unexpected; update getIcon to add a default case
that returns a neutral icon (e.g., Info or AlertTriangle with neutral styling)
and update getIconBg to add a default background case so the UI still renders if
a new/unknown variant is passed, keeping existing cases intact.

Comment on lines +35 to +44
const getIcon = () => {
switch (variant) {
case 'danger':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
case 'warning':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-yellow-500'} />;
case 'info':
return <Info size={32} className={isNeo ? 'text-black' : 'text-blue-500'} />;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding default cases to switch statements for defensive coding.

The getIcon() and getIconBg() functions lack default cases. While currently safe due to the typed ConfirmVariant union and default prop value, adding explicit defaults would future-proof against accidental omissions if new variants are added.

♻️ Optional: Add default cases
   const getIcon = () => {
     switch (variant) {
       case 'danger':
         return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
       case 'warning':
         return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-yellow-500'} />;
       case 'info':
         return <Info size={32} className={isNeo ? 'text-black' : 'text-blue-500'} />;
+      default:
+        return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
     }
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const getIcon = () => {
switch (variant) {
case 'danger':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
case 'warning':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-yellow-500'} />;
case 'info':
return <Info size={32} className={isNeo ? 'text-black' : 'text-blue-500'} />;
}
};
const getIcon = () => {
switch (variant) {
case 'danger':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
case 'warning':
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-yellow-500'} />;
case 'info':
return <Info size={32} className={isNeo ? 'text-black' : 'text-blue-500'} />;
default:
return <AlertTriangle size={32} className={isNeo ? 'text-black' : 'text-red-500'} />;
}
};
🤖 Prompt for AI Agents
In `@web/components/ui/ConfirmDialog.tsx` around lines 35 - 44, The switch
statements in getIcon and getIconBg should include explicit default branches to
return a safe fallback icon/background when variant (ConfirmVariant) is
unexpected; update getIcon to add a default case that returns a neutral icon
(e.g., Info or AlertTriangle with neutral styling) and update getIconBg to add a
default background case so the UI still renders if a new/unknown variant is
passed, keeping existing cases intact.

@Devasy Devasy merged commit 1352cdc into main Jan 27, 2026
12 checks passed
@Devasy Devasy deleted the jules-ux-confirm-dialog-12669270586709539879 branch January 27, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant