1+ const API_BASE = "http://localhost:5127/api/items" ;
2+
3+ const itemForm = document . getElementById ( "itemForm" ) ;
4+ const itemsBody = document . getElementById ( "itemsBody" ) ;
5+ const searchBox = document . getElementById ( "searchBox" ) ;
6+ const refreshBtn = document . getElementById ( "refreshBtn" ) ;
7+ const clearBtn = document . getElementById ( "clearBtn" ) ;
8+
9+ let items = [ ] ;
10+ let editingId = null ;
11+
12+ async function fetchItems ( ) {
13+ const response = await fetch ( API_BASE ) ;
14+ items = await response . json ( ) ;
15+ renderItems ( ) ;
16+ }
17+
18+ function renderItems ( ) {
19+ const q = searchBox . value . trim ( ) . toLowerCase ( ) ;
20+
21+ const filtered = items . filter ( item =>
22+ item . driverName . toLowerCase ( ) . includes ( q ) ||
23+ item . loadNumber . toLowerCase ( ) . includes ( q ) ||
24+ item . brokerName . toLowerCase ( ) . includes ( q ) ||
25+ item . note . toLowerCase ( ) . includes ( q ) ||
26+ q === ""
27+ ) ;
28+
29+ itemsBody . innerHTML = filtered . map ( item => `
30+ <tr>
31+ <td>${ item . id } </td>
32+ <td>${ escapeHtml ( item . driverName ) } </td>
33+ <td>${ escapeHtml ( item . loadNumber ) } </td>
34+ <td>${ escapeHtml ( item . brokerName || "-" ) } </td>
35+ <td>${ escapeHtml ( item . status ) } </td>
36+ <td>${ escapeHtml ( item . priority || "Medium" ) } </td>
37+ <td>${ escapeHtml ( item . assignedTo || "-" ) } </td>
38+ <td>${ item . claimedBy ? escapeHtml ( item . claimedBy ) : "-" } </td>
39+ <td>${ item . needsReply ? "Yes" : "No" } </td>
40+ <td>${ formatDate ( item . lastUpdateTime ) } </td>
41+ <td>${ escapeHtml ( item . note || "" ) } </td>
42+ <td>
43+ <div class="row-actions">
44+ <button onclick="editItem(${ item . id } )">Edit</button>
45+ <button onclick="claimItem(${ item . id } )">Claim</button>
46+ <button onclick="unclaimItem(${ item . id } )">Unclaim</button>
47+ <button onclick="deleteItem(${ item . id } )">Delete</button>
48+ </div>
49+ </td>
50+ </tr>
51+ ` ) . join ( "" ) ;
52+ }
53+
54+ itemForm . addEventListener ( "submit" , async ( e ) => {
55+ e . preventDefault ( ) ;
56+
57+ const payload = {
58+ driverName : document . getElementById ( "driverName" ) . value . trim ( ) ,
59+ loadNumber : document . getElementById ( "loadNumber" ) . value . trim ( ) ,
60+ brokerName : document . getElementById ( "brokerName" ) . value . trim ( ) ,
61+ assignedTo : document . getElementById ( "assignedTo" ) . value . trim ( ) ,
62+ source : document . getElementById ( "source" ) . value ,
63+ status : document . getElementById ( "status" ) . value ,
64+ priority : document . getElementById ( "priority" ) . value ,
65+ note : document . getElementById ( "note" ) . value . trim ( ) ,
66+ needsReply : document . getElementById ( "needsReply" ) . checked
67+ } ;
68+
69+ const url = editingId ? `${ API_BASE } /${ editingId } ` : API_BASE ;
70+ const method = editingId ? "PUT" : "POST" ;
71+
72+ const response = await fetch ( url , {
73+ method,
74+ headers : { "Content-Type" : "application/json" } ,
75+ body : JSON . stringify ( payload )
76+ } ) ;
77+
78+ if ( ! response . ok ) {
79+ const error = await response . json ( ) ;
80+ alert ( error . message || "Failed" ) ;
81+ return ;
82+ }
83+
84+ resetForm ( ) ;
85+ fetchItems ( ) ;
86+ } ) ;
87+
88+ function editItem ( id ) {
89+ const item = items . find ( x => x . id === id ) ;
90+ if ( ! item ) return ;
91+
92+ editingId = id ;
93+ document . getElementById ( "driverName" ) . value = item . driverName ;
94+ document . getElementById ( "loadNumber" ) . value = item . loadNumber ;
95+ document . getElementById ( "brokerName" ) . value = item . brokerName || "" ;
96+ document . getElementById ( "assignedTo" ) . value = item . assignedTo || "" ;
97+ document . getElementById ( "source" ) . value = item . source || "Email" ;
98+ document . getElementById ( "status" ) . value = item . status || "Pending" ;
99+ document . getElementById ( "priority" ) . value = item . priority || "Medium" ;
100+ document . getElementById ( "note" ) . value = item . note || "" ;
101+ document . getElementById ( "needsReply" ) . checked = item . needsReply ;
102+ }
103+
104+ async function deleteItem ( id ) {
105+ if ( ! confirm ( "Delete item?" ) ) return ;
106+
107+ await fetch ( `${ API_BASE } /${ id } ` , { method : "DELETE" } ) ;
108+ fetchItems ( ) ;
109+ }
110+
111+ async function claimItem ( id ) {
112+ const userName = document . getElementById ( "claimUser" ) . value . trim ( ) ;
113+ if ( ! userName ) {
114+ alert ( "Enter your name in claim field" ) ;
115+ return ;
116+ }
117+
118+ const response = await fetch ( `${ API_BASE } /${ id } /claim` , {
119+ method : "POST" ,
120+ headers : { "Content-Type" : "application/json" } ,
121+ body : JSON . stringify ( { userName } )
122+ } ) ;
123+
124+ const result = await response . json ( ) ;
125+ if ( ! response . ok ) {
126+ alert ( result . message || "Claim failed" ) ;
127+ return ;
128+ }
129+
130+ fetchItems ( ) ;
131+ }
132+
133+ async function unclaimItem ( id ) {
134+ await fetch ( `${ API_BASE } /${ id } /unclaim` , {
135+ method : "POST"
136+ } ) ;
137+ fetchItems ( ) ;
138+ }
139+
140+ function resetForm ( ) {
141+ editingId = null ;
142+ itemForm . reset ( ) ;
143+ document . getElementById ( "source" ) . value = "Email" ;
144+ document . getElementById ( "status" ) . value = "Pending" ;
145+ document . getElementById ( "priority" ) . value = "Medium" ;
146+ }
147+
148+ function formatDate ( value ) {
149+ if ( ! value ) return "-" ;
150+ return new Date ( value ) . toLocaleString ( ) ;
151+ }
152+
153+ function escapeHtml ( str ) {
154+ return String ( str )
155+ . replaceAll ( "&" , "&" )
156+ . replaceAll ( "<" , "<" )
157+ . replaceAll ( ">" , ">" )
158+ . replaceAll ( '"' , """ )
159+ . replaceAll ( "'" , "'" ) ;
160+ }
161+
162+ clearBtn . addEventListener ( "click" , resetForm ) ;
163+ refreshBtn . addEventListener ( "click" , fetchItems ) ;
164+ searchBox . addEventListener ( "input" , renderItems ) ;
165+
166+ fetchItems ( ) ;
167+
168+ window . editItem = editItem ;
169+ window . deleteItem = deleteItem ;
170+ window . claimItem = claimItem ;
171+ window . unclaimItem = unclaimItem ;
0 commit comments