fix: resolve toast message visibility and deployment success notifications

## Issues Fixed
- Toast messages appearing in background/blurred due to z-index conflicts
- Missing success toast notifications for deployment completions
- Scoped ToastContainer limiting toast visibility to chat component only

## Changes Made

### Global Toast System
- Move ToastContainer from Chat.client.tsx to root.tsx for global availability
- Add highest z-index (1000) to ensure toasts appear above all UI elements
- Remove duplicate ToastContainer from chat component

### Z-Index System Updates
- Add .z-toast class with z-index: $zIndexMax + 1 (1000)
- Apply toast z-index to .Toastify__toast-container in toast.scss
- Ensure proper layering hierarchy for all toast messages

### Deployment Success Notifications
- Add missing toast.success() calls to all deployment services:
  - NetlifyDeploy: "🚀 Netlify deployment completed successfully!"
  - VercelDeploy: "🚀 Vercel deployment completed successfully!"
  - GitHubDeploy: "🚀 GitHub deployment preparation completed successfully!"
  - GitLabDeploy: "🚀 GitLab deployment preparation completed successfully!"

## Result
- All toast messages now appear in foreground with proper z-index
- Deployment success notifications are clearly visible to users
- Consistent toast behavior across the entire application
- No more blurred or background toast messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Stijnus
2025-09-29 14:05:22 +02:00
parent d34852c227
commit 4e37f5a80c
8 changed files with 54 additions and 34 deletions

View File

@@ -3,7 +3,7 @@ import type { Message } from 'ai';
import { useChat } from '@ai-sdk/react';
import { useAnimate } from 'framer-motion';
import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { cssTransition, toast, ToastContainer } from 'react-toastify';
import { toast } from 'react-toastify';
import { useMessageParser, usePromptEnhancer, useShortcuts } from '~/lib/hooks';
import { description, useChatHistory } from '~/lib/persistence';
import { chatStore } from '~/lib/stores/chat';
@@ -29,11 +29,6 @@ import type { TextUIPart, FileUIPart, Attachment } from '@ai-sdk/ui-utils';
import { useMCPStore } from '~/lib/stores/mcp';
import type { LlmErrorAlertType } from '~/types/actions';
const toastAnimation = cssTransition({
enter: 'animated fadeInRight',
exit: 'animated fadeOutRight',
});
const logger = createScopedLogger('Chat');
export function Chat() {
@@ -56,34 +51,6 @@ export function Chat() {
importChat={importChat}
/>
)}
<ToastContainer
closeButton={({ closeToast }) => {
return (
<button className="Toastify__close-button" onClick={closeToast}>
<div className="i-ph:x text-lg" />
</button>
);
}}
icon={({ type }) => {
/**
* @todo Handle more types if we need them. This may require extra color palettes.
*/
switch (type) {
case 'success': {
return <div className="i-ph:check-bold text-bolt-elements-icon-success text-2xl" />;
}
case 'error': {
return <div className="i-ph:warning-circle-bold text-bolt-elements-icon-error text-2xl" />;
}
}
return undefined;
}}
position="bottom-right"
pauseOnFocusLoss
transition={toastAnimation}
autoClose={3000}
/>
</>
);
}

View File

@@ -145,6 +145,9 @@ export function useGitHubDeploy() {
source: 'github',
});
// Show success toast notification
toast.success(`🚀 GitHub deployment preparation completed successfully!`);
return {
success: true,
files: fileContents,

View File

@@ -145,6 +145,9 @@ export function useGitLabDeploy() {
source: 'gitlab',
});
// Show success toast notification
toast.success(`🚀 GitLab deployment preparation completed successfully!`);
return {
success: true,
files: fileContents,

View File

@@ -224,6 +224,9 @@ export function useNetlifyDeploy() {
source: 'netlify',
});
// Show success toast notification
toast.success(`🚀 Netlify deployment completed successfully!`);
return true;
} catch (error) {
console.error('Deploy error:', error);

View File

@@ -213,6 +213,9 @@ export function useVercelDeploy() {
source: 'vercel',
});
// Show success toast notification
toast.success(`🚀 Vercel deployment completed successfully!`);
return true;
} catch (err) {
console.error('Vercel deploy error:', err);

View File

@@ -9,6 +9,7 @@ import { useEffect } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { ClientOnly } from 'remix-utils/client-only';
import { cssTransition, ToastContainer } from 'react-toastify';
import reactToastifyStyles from 'react-toastify/dist/ReactToastify.css?url';
import globalStyles from './styles/index.scss?url';
@@ -16,6 +17,11 @@ import xtermStyles from '@xterm/xterm/css/xterm.css?url';
import 'virtual:uno.css';
const toastAnimation = cssTransition({
enter: 'animated fadeInRight',
exit: 'animated fadeOutRight',
});
export const links: LinksFunction = () => [
{
rel: 'icon',
@@ -75,6 +81,31 @@ export function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<ClientOnly>{() => <DndProvider backend={HTML5Backend}>{children}</DndProvider>}</ClientOnly>
<ToastContainer
closeButton={({ closeToast }) => {
return (
<button className="Toastify__close-button" onClick={closeToast}>
<div className="i-ph:x text-lg" />
</button>
);
}}
icon={({ type }) => {
switch (type) {
case 'success': {
return <div className="i-ph:check-bold text-bolt-elements-icon-success text-2xl" />;
}
case 'error': {
return <div className="i-ph:warning-circle-bold text-bolt-elements-icon-error text-2xl" />;
}
}
return undefined;
}}
position="bottom-right"
pauseOnFocusLoss
transition={toastAnimation}
autoClose={3000}
/>
<ScrollRestoration />
<Scripts />
</>

View File

@@ -1,3 +1,9 @@
@use '../z-index';
.Toastify__toast-container {
@extend .z-toast;
}
.Toastify__toast {
--at-apply: shadow-md;

View File

@@ -31,3 +31,7 @@ $zIndexMax: 999;
.z-max {
z-index: $zIndexMax;
}
.z-toast {
z-index: $zIndexMax + 1;
}