Add Stripe notifications, messaging improvements, and code cleanup
Stripe Notifications: - Add periodic task to check Stripe Connect accounts for requirements - Create in-app notifications for business owners when action needed - Add management command to setup Stripe periodic tasks - Display Stripe notifications with credit card icon in notification bell - Navigate to payments page when Stripe notification clicked Messaging Improvements: - Add "Everyone" option to broadcast message recipients - Allow sending messages to yourself (remove self-exclusion) - Fix broadcast message ID not returned after creation - Add real-time websocket support for broadcast notifications - Show toast when broadcast message received via websocket UI Fixes: - Remove "View all" button from notifications (no page exists) - Add StripeNotificationBanner component for Connect alerts - Connect useUserNotifications hook in TopBar for app-wide websocket Code Cleanup: - Remove legacy automations app and plugin system - Remove safe_scripting module (moved to Activepieces) - Add migration to remove plugin-related models - Various test improvements and coverage additions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Bell, Check, CheckCheck, Trash2, X, Ticket, Calendar, MessageSquare, Clock } from 'lucide-react';
|
||||
import { Bell, Check, CheckCheck, Trash2, X, Ticket, Calendar, MessageSquare, Clock, CreditCard } from 'lucide-react';
|
||||
import {
|
||||
useNotifications,
|
||||
useUnreadNotificationCount,
|
||||
@@ -64,6 +64,13 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ variant = '
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle Stripe requirements notifications - navigate to payments page
|
||||
if (notification.data?.type === 'stripe_requirements') {
|
||||
navigate('/dashboard/payments');
|
||||
setIsOpen(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigate to target if available
|
||||
if (notification.target_url) {
|
||||
navigate(notification.target_url);
|
||||
@@ -85,6 +92,11 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ variant = '
|
||||
return <Clock size={16} className="text-amber-500" />;
|
||||
}
|
||||
|
||||
// Check for Stripe requirements notifications
|
||||
if (notification.data?.type === 'stripe_requirements') {
|
||||
return <CreditCard size={16} className="text-purple-500" />;
|
||||
}
|
||||
|
||||
switch (notification.target_type) {
|
||||
case 'ticket':
|
||||
return <Ticket size={16} className="text-blue-500" />;
|
||||
@@ -192,9 +204,9 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ variant = '
|
||||
{' '}
|
||||
{notification.verb}
|
||||
</p>
|
||||
{notification.target_display && (
|
||||
{(notification.target_display || notification.data?.description) && (
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 truncate mt-0.5">
|
||||
{notification.target_display}
|
||||
{notification.target_display || notification.data?.description}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-400 dark:text-gray-500 mt-1">
|
||||
@@ -213,7 +225,7 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ variant = '
|
||||
|
||||
{/* Footer */}
|
||||
{notifications.length > 0 && (
|
||||
<div className="px-4 py-3 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||
<div className="px-4 py-3 border-t border-gray-200 dark:border-gray-700 flex items-center justify-center">
|
||||
<button
|
||||
onClick={handleClearAll}
|
||||
disabled={clearAllMutation.isPending}
|
||||
@@ -222,15 +234,6 @@ const NotificationDropdown: React.FC<NotificationDropdownProps> = ({ variant = '
|
||||
<Trash2 size={12} />
|
||||
{t('notifications.clearRead', 'Clear read')}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigate('/dashboard/notifications');
|
||||
setIsOpen(false);
|
||||
}}
|
||||
className="text-xs text-brand-600 hover:text-brand-700 dark:text-brand-400 font-medium"
|
||||
>
|
||||
{t('notifications.viewAll', 'View all')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user