Skip to content

Commit 2d69cde

Browse files
author
Steve Hansen
committed
feat: improve driver submission UX across both Add-Ins
Portal Add-In: - Add 'Driver Submissions' tab showing all submissions with status - Show linked submission badge in Requests table - Allow creating report requests directly from submission list - Add CSS for request options badges Drive Add-In: - Show detailed status descriptions (Awaiting Merge, Report Created, etc) - Display report ID when submission is merged/converted - Add periodic status refresh from AddInData (60s interval) - Add 'converted' status type for standalone reports
1 parent c3941ad commit 2d69cde

29 files changed

Lines changed: 515 additions & 28 deletions

src/FleetClaim.AddIn.React/app/components/App.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import { useGeotab } from '@/contexts';
1111
import { useToast } from '@/hooks';
1212
import { ReportsTab } from './ReportsTab';
1313
import { RequestsTab } from './RequestsTab';
14+
import { SubmissionsTab } from './SubmissionsTab';
1415
import { SettingsTab } from './SettingsTab';
1516
import { AboutTab } from './AboutTab';
1617
import { ToastContainer } from './ToastContainer';
1718
import { NewRequestModal } from './NewRequestModal';
1819
import '../styles/app.css';
1920

20-
type TabId = 'reports' | 'requests' | 'settings' | 'about';
21+
type TabId = 'reports' | 'requests' | 'submissions' | 'settings' | 'about';
2122

2223
const App: React.FC = () => {
2324
const isMobile = useMobile();
@@ -45,13 +46,20 @@ const App: React.FC = () => {
4546
const [activeTab, setActiveTab] = useState<TabId>('reports');
4647
const [isNewRequestOpen, setIsNewRequestOpen] = useState(false);
4748
const [requestsRefreshKey, setRequestsRefreshKey] = useState(0);
49+
const [preselectedSubmissionId, setPreselectedSubmissionId] = useState<string | null>(null);
4850

4951
const handleRefresh = useCallback(() => {
5052
// Will be passed to child components
5153
toast.info('Refreshing...', 2000);
5254
}, [toast]);
5355

5456
const handleNewRequest = useCallback(() => {
57+
setPreselectedSubmissionId(null);
58+
setIsNewRequestOpen(true);
59+
}, []);
60+
61+
const handleCreateRequestFromSubmission = useCallback((submissionId: string) => {
62+
setPreselectedSubmissionId(submissionId);
5563
setIsNewRequestOpen(true);
5664
}, []);
5765

@@ -65,6 +73,7 @@ const App: React.FC = () => {
6573
const tabs = [
6674
{ id: 'reports', name: 'Reports' },
6775
{ id: 'requests', name: 'Requests' },
76+
{ id: 'submissions', name: 'Driver Submissions' },
6877
{ id: 'settings', name: 'Settings' },
6978
{ id: 'about', name: 'About' }
7079
];
@@ -108,6 +117,9 @@ const App: React.FC = () => {
108117
{activeTab === 'requests' && (
109118
<RequestsTab key={requestsRefreshKey} onRefresh={handleRefresh} toast={toast} />
110119
)}
120+
{activeTab === 'submissions' && (
121+
<SubmissionsTab onCreateRequest={handleCreateRequestFromSubmission} toast={toast} />
122+
)}
111123
{activeTab === 'settings' && (
112124
<SettingsTab toast={toast} />
113125
)}
@@ -120,6 +132,7 @@ const App: React.FC = () => {
120132
isOpen={isNewRequestOpen}
121133
onClose={() => setIsNewRequestOpen(false)}
122134
onSubmit={handleRequestSubmitted}
135+
preselectedSubmissionId={preselectedSubmissionId}
123136
toast={toast}
124137
/>
125138

src/FleetClaim.AddIn.React/app/components/NewRequestModal.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ interface NewRequestModalProps {
1515
isOpen: boolean;
1616
onClose: () => void;
1717
onSubmit: () => void;
18+
preselectedSubmissionId?: string | null;
1819
toast: {
1920
success: (msg: string) => void;
2021
error: (msg: string) => void;
@@ -112,6 +113,7 @@ export const NewRequestModal: React.FC<NewRequestModalProps> = ({
112113
isOpen,
113114
onClose,
114115
onSubmit,
116+
preselectedSubmissionId,
115117
toast
116118
}) => {
117119
const { api, devices, loadDevices } = useGeotab();
@@ -145,14 +147,23 @@ export const NewRequestModal: React.FC<NewRequestModalProps> = ({
145147
if (isOpen && api) {
146148
setLoadingSubmissions(true);
147149
loadUnmergedSubmissions(api)
148-
.then(setSubmissions)
150+
.then(loaded => {
151+
setSubmissions(loaded);
152+
// Auto-select preselected submission
153+
if (preselectedSubmissionId) {
154+
const match = loaded.find(s => s.submission.id === preselectedSubmissionId);
155+
if (match) {
156+
handleSubmissionSelect(preselectedSubmissionId);
157+
}
158+
}
159+
})
149160
.catch(err => {
150161
console.warn('Failed to load submissions:', err);
151162
setSubmissions([]);
152163
})
153164
.finally(() => setLoadingSubmissions(false));
154165
}
155-
}, [isOpen, api]);
166+
}, [isOpen, api, preselectedSubmissionId]);
156167

157168
const deviceOptions = useMemo(() =>
158169
devices.map(d => ({

src/FleetClaim.AddIn.React/app/components/RequestsTab.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,17 @@ export const RequestsTab: React.FC<RequestsTabProps> = ({ onRefresh, toast }) =>
116116
{
117117
id: 'options',
118118
title: 'Options',
119-
meta: { defaultWidth: 100 },
119+
meta: { defaultWidth: 140 },
120120
sortable: false,
121121
columnComponent: {
122122
render: (entity) => (
123123
<span className="request-options">
124124
{entity.request.forceReport && (
125125
<span className="badge" title="Force Report"></span>
126126
)}
127+
{entity.request.linkedSubmissionId && (
128+
<span className="badge linked" title={`Linked to driver submission: ${entity.request.linkedSubmissionId}`}>🔗 Driver</span>
129+
)}
127130
</span>
128131
),
129132
renderHeader: (title) => title

0 commit comments

Comments
 (0)