feat: add Help page with search, streamline copilot, misc UI fixes
Adds searchable Help/User Guide page, trims copilot tool bloat, adds OTHER department option, and various form/layout improvements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10
frontend/package-lock.json
generated
@@ -16,6 +16,7 @@
|
||||
"axios": "^1.6.5",
|
||||
"clsx": "^2.1.0",
|
||||
"date-fns": "^3.2.0",
|
||||
"fuse.js": "^7.1.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"lucide-react": "^0.309.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
@@ -3442,6 +3443,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/fuse.js": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz",
|
||||
"integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"axios": "^1.6.5",
|
||||
"clsx": "^2.1.0",
|
||||
"date-fns": "^3.2.0",
|
||||
"fuse.js": "^7.1.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"lucide-react": "^0.309.0",
|
||||
"qrcode.react": "^4.2.0",
|
||||
|
||||
BIN
frontend/public/help-assets/screenshots/01-login-page.png
Normal file
|
After Width: | Height: | Size: 468 KiB |
BIN
frontend/public/help-assets/screenshots/02-auth0-login.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
frontend/public/help-assets/screenshots/03-dashboard.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
frontend/public/help-assets/screenshots/04-war-room.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
frontend/public/help-assets/screenshots/05-vip-list.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
frontend/public/help-assets/screenshots/06-vip-edit-form.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 93 KiB |
BIN
frontend/public/help-assets/screenshots/08-fleet-drivers.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
frontend/public/help-assets/screenshots/09-fleet-vehicles.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
frontend/public/help-assets/screenshots/10-activities.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
frontend/public/help-assets/screenshots/11-flights.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
frontend/public/help-assets/screenshots/12-reports.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
frontend/public/help-assets/screenshots/13-users.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
frontend/public/help-assets/screenshots/14-admin-tools.png
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
frontend/public/help-assets/screenshots/15-gps-tracking.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
frontend/public/help-assets/screenshots/16-gps-devices.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
frontend/public/help-assets/screenshots/17-gps-settings.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
frontend/public/help-assets/screenshots/18-ai-assistant.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
@@ -24,6 +24,7 @@ import { DriverProfile } from '@/pages/DriverProfile';
|
||||
import { MySchedule } from '@/pages/MySchedule';
|
||||
import { GpsTracking } from '@/pages/GpsTracking';
|
||||
import { Reports } from '@/pages/Reports';
|
||||
import { Help } from '@/pages/Help';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
|
||||
// Smart redirect based on user role
|
||||
@@ -63,7 +64,7 @@ function App() {
|
||||
scope: 'openid profile email offline_access',
|
||||
}}
|
||||
useRefreshTokens={true}
|
||||
cacheLocation="memory"
|
||||
cacheLocation="localstorage"
|
||||
>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
@@ -124,6 +125,7 @@ function App() {
|
||||
<Route path="/admin-tools" element={<AdminTools />} />
|
||||
<Route path="/gps-tracking" element={<GpsTracking />} />
|
||||
<Route path="/reports" element={<Reports />} />
|
||||
<Route path="/help" element={<Help />} />
|
||||
<Route path="/profile" element={<DriverProfile />} />
|
||||
<Route path="/my-schedule" element={<MySchedule />} />
|
||||
<Route path="/" element={<HomeRedirect />} />
|
||||
|
||||
@@ -114,6 +114,7 @@ export function DriverForm({ driver, onSubmit, onCancel, isSubmitting }: DriverF
|
||||
<option value="">Select Department</option>
|
||||
<option value="OFFICE_OF_DEVELOPMENT">Office of Development</option>
|
||||
<option value="ADMIN">Admin</option>
|
||||
<option value="OTHER">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
Phone,
|
||||
AlertCircle,
|
||||
FileText,
|
||||
HelpCircle,
|
||||
} from 'lucide-react';
|
||||
import { UserMenu } from '@/components/UserMenu';
|
||||
import { AppearanceMenu } from '@/components/AppearanceMenu';
|
||||
@@ -98,6 +99,7 @@ export function Layout({ children }: LayoutProps) {
|
||||
{ name: 'Reports', href: '/reports', icon: FileText },
|
||||
{ name: 'GPS Tracking', href: '/gps-tracking', icon: Radio },
|
||||
{ name: 'Admin Tools', href: '/admin-tools', icon: Settings },
|
||||
{ name: 'Help Guide', href: '/help', icon: HelpCircle },
|
||||
];
|
||||
|
||||
// Filter navigation based on role and CASL permissions
|
||||
|
||||
@@ -196,6 +196,7 @@ export function VIPForm({ vip, onSubmit, onCancel, isSubmitting }: VIPFormProps)
|
||||
>
|
||||
<option value="OFFICE_OF_DEVELOPMENT">Office of Development</option>
|
||||
<option value="ADMIN">Admin</option>
|
||||
<option value="OTHER">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export const copilotApi = axios.create({
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
timeout: 120000, // 2 minute timeout for AI requests
|
||||
timeout: 300000, // 5 minute timeout for AI requests (large tasks need multiple tool calls)
|
||||
});
|
||||
|
||||
// Token getter function - set by AuthContext when authenticated
|
||||
|
||||
@@ -196,6 +196,7 @@ export function DriverList({ embedded = false }: { embedded?: boolean }) {
|
||||
const labels = {
|
||||
'OFFICE_OF_DEVELOPMENT': 'Office of Development',
|
||||
'ADMIN': 'Admin',
|
||||
'OTHER': 'Other',
|
||||
};
|
||||
return labels[value as keyof typeof labels] || value;
|
||||
};
|
||||
@@ -541,6 +542,7 @@ export function DriverList({ embedded = false }: { embedded?: boolean }) {
|
||||
options: [
|
||||
{ value: 'OFFICE_OF_DEVELOPMENT', label: 'Office of Development' },
|
||||
{ value: 'ADMIN', label: 'Admin' },
|
||||
{ value: 'OTHER', label: 'Other' },
|
||||
],
|
||||
selectedValues: selectedDepartments,
|
||||
onToggle: handleDepartmentToggle,
|
||||
|
||||
1078
frontend/src/pages/Help.tsx
Normal file
@@ -234,6 +234,7 @@ export function Reports() {
|
||||
<option value="all">All Departments</option>
|
||||
<option value="OFFICE_OF_DEVELOPMENT">Office of Development</option>
|
||||
<option value="ADMIN">Admin</option>
|
||||
<option value="OTHER">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -192,6 +192,7 @@ export function VIPList() {
|
||||
department: {
|
||||
'OFFICE_OF_DEVELOPMENT': 'Office of Development',
|
||||
'ADMIN': 'Admin',
|
||||
'OTHER': 'Other',
|
||||
},
|
||||
arrivalMode: {
|
||||
'FLIGHT': 'Flight',
|
||||
@@ -546,6 +547,7 @@ export function VIPList() {
|
||||
options: [
|
||||
{ value: 'OFFICE_OF_DEVELOPMENT', label: 'Office of Development' },
|
||||
{ value: 'ADMIN', label: 'Admin' },
|
||||
{ value: 'OTHER', label: 'Other' },
|
||||
],
|
||||
selectedValues: selectedDepartments,
|
||||
onToggle: handleDepartmentToggle,
|
||||
|
||||