feat: comprehensive update with Signal, Copilot, themes, and PDF features
## Signal Messaging Integration - Added SignalService for sending messages to drivers via Signal - SignalMessage model for tracking message history - Driver chat modal for real-time messaging - Send schedule via Signal (ICS + PDF attachments) ## AI Copilot - Natural language interface for VIP Coordinator - Capabilities: create VIPs, schedule events, assign drivers - Help and guidance for users - Floating copilot button in UI ## Theme System - Dark/light/system theme support - Color scheme selection (blue, green, purple, orange, red) - ThemeContext for global state - AppearanceMenu in header ## PDF Schedule Export - VIPSchedulePDF component for schedule generation - PDF settings (header, footer, branding) - Preview PDF in browser - Settings stored in database ## Database Migrations - add_signal_messages: SignalMessage model - add_pdf_settings: Settings model for PDF config - add_reminder_tracking: lastReminderSent for events - make_driver_phone_optional: phone field nullable ## Event Management - Event status service for automated updates - IN_PROGRESS/COMPLETED status tracking - Reminder tracking for notifications ## UI/UX Improvements - Driver schedule modal - Improved My Schedule page - Better error handling and loading states - Responsive design improvements ## Other Changes - AGENT_TEAM.md documentation - Seed data improvements - Ability factory updates - Driver profile page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { Auth0Provider } from '@auth0/auth0-react';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import { AuthProvider } from '@/contexts/AuthContext';
|
||||
import { AbilityProvider } from '@/contexts/AbilityContext';
|
||||
import { ThemeProvider } from '@/contexts/ThemeContext';
|
||||
import { ProtectedRoute } from '@/components/ProtectedRoute';
|
||||
import { Layout } from '@/components/Layout';
|
||||
import { ErrorBoundary } from '@/components/ErrorBoundary';
|
||||
@@ -20,6 +21,20 @@ import { EventList } from '@/pages/EventList';
|
||||
import { FlightList } from '@/pages/FlightList';
|
||||
import { UserList } from '@/pages/UserList';
|
||||
import { AdminTools } from '@/pages/AdminTools';
|
||||
import { DriverProfile } from '@/pages/DriverProfile';
|
||||
import { MySchedule } from '@/pages/MySchedule';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
|
||||
// Smart redirect based on user role
|
||||
function HomeRedirect() {
|
||||
const { backendUser } = useAuth();
|
||||
|
||||
// Drivers go to their schedule, everyone else goes to dashboard
|
||||
if (backendUser?.role === 'DRIVER') {
|
||||
return <Navigate to="/my-schedule" replace />;
|
||||
}
|
||||
return <Navigate to="/dashboard" replace />;
|
||||
}
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
@@ -37,6 +52,7 @@ const audience = import.meta.env.VITE_AUTH0_AUDIENCE;
|
||||
function App() {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ThemeProvider>
|
||||
<Auth0Provider
|
||||
domain={domain}
|
||||
clientId={clientId}
|
||||
@@ -61,22 +77,24 @@ function App() {
|
||||
position="top-right"
|
||||
toastOptions={{
|
||||
duration: 4000,
|
||||
className: 'bg-card text-card-foreground border border-border shadow-elevated',
|
||||
style: {
|
||||
background: '#333',
|
||||
color: '#fff',
|
||||
background: 'hsl(var(--card))',
|
||||
color: 'hsl(var(--card-foreground))',
|
||||
border: '1px solid hsl(var(--border))',
|
||||
},
|
||||
success: {
|
||||
duration: 3000,
|
||||
iconTheme: {
|
||||
primary: '#10b981',
|
||||
secondary: '#fff',
|
||||
primary: 'hsl(142, 76%, 36%)',
|
||||
secondary: 'hsl(0, 0%, 100%)',
|
||||
},
|
||||
},
|
||||
error: {
|
||||
duration: 5000,
|
||||
iconTheme: {
|
||||
primary: '#ef4444',
|
||||
secondary: '#fff',
|
||||
primary: 'hsl(0, 84%, 60%)',
|
||||
secondary: 'hsl(0, 0%, 100%)',
|
||||
},
|
||||
},
|
||||
}}
|
||||
@@ -102,8 +120,10 @@ function App() {
|
||||
<Route path="/flights" element={<FlightList />} />
|
||||
<Route path="/users" element={<UserList />} />
|
||||
<Route path="/admin-tools" element={<AdminTools />} />
|
||||
<Route path="/" element={<Navigate to="/dashboard" replace />} />
|
||||
<Route path="*" element={<Navigate to="/dashboard" replace />} />
|
||||
<Route path="/profile" element={<DriverProfile />} />
|
||||
<Route path="/my-schedule" element={<MySchedule />} />
|
||||
<Route path="/" element={<HomeRedirect />} />
|
||||
<Route path="*" element={<HomeRedirect />} />
|
||||
</Routes>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
@@ -115,6 +135,7 @@ function App() {
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</Auth0Provider>
|
||||
</ThemeProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user