@@ -21,8 +21,19 @@ const FLOWS_WITH_ADD_ITEM_BUTTON: string[] = [
2121
2222type CatalogAddOn = { id : string } ;
2323type CatalogItem = { id : string ; parent_item_id ?: string ; add_ons ?: CatalogAddOn [ ] } ;
24- type CatalogFulfillment = { id : string } ;
25- type CatalogProvider = { id : string ; fulfillments : CatalogFulfillment [ ] ; items ?: CatalogItem [ ] } ;
24+ type CatalogFulfillmentStop = {
25+ type : string ;
26+ instructions ?: Record < string , unknown > ;
27+ time ?: Record < string , unknown > ;
28+ } ;
29+ type CatalogFulfillment = {
30+ id : string ;
31+ type ?: string ;
32+ stops ?: CatalogFulfillmentStop [ ] ;
33+ agent ?: Record < string , unknown > ;
34+ vehicle ?: Record < string , unknown > ;
35+ } ;
36+ type CatalogProvider = { id : string ; items ?: CatalogItem [ ] ; fulfillments ?: CatalogFulfillment [ ] } ;
2637type OnSearchPayload = { message ?: { catalog ?: { providers ?: CatalogProvider [ ] } } } ;
2738
2839type FormItem = {
@@ -35,8 +46,8 @@ type FormItem = {
3546
3647type FormValues = {
3748 provider : string ;
38- fulfillment ?: string ;
3949 items : FormItem [ ] ;
50+ fulfillmentId : string ;
4051} ;
4152
4253export default function TRVSelect ( {
@@ -53,6 +64,7 @@ export default function TRVSelect({
5364 defaultValues : {
5465 provider : "" ,
5566 items : [ { itemId : "" , count : 1 , addOns : [ ] , addOnsQuantity : 1 } ] ,
67+ fulfillmentId : "" ,
5668 } ,
5769 } ) ;
5870
@@ -63,9 +75,26 @@ export default function TRVSelect({
6375
6476 const selectedItems = watch ( "items" ) ;
6577 const [ itemOptions , setItemOptions ] = useState < ExtractedItem [ ] > ( [ ] ) ;
78+ const [ fulfillmentOptions , setFulfillmentOptions ] = useState < CatalogFulfillment [ ] > ( [ ] ) ;
6679
6780 const onSubmit = async ( data : FormValues ) => {
68- await submitEvent ( { jsonPath : { } , formData : data as unknown as Record < string , string > } ) ;
81+ const selectedFulfillment = fulfillmentOptions . find ( ( f ) => f . id === data . fulfillmentId ) ;
82+ const output = {
83+ provider : data . provider ,
84+ items : data . items ,
85+ fulfillments : selectedFulfillment
86+ ? [
87+ {
88+ id : selectedFulfillment . id ,
89+ stops : ( selectedFulfillment . stops || [ ] ) . map ( ( stop ) => ( {
90+ type : stop . type ,
91+ time : stop . time ,
92+ } ) ) ,
93+ } ,
94+ ]
95+ : [ ] ,
96+ } ;
97+ await submitEvent ( { jsonPath : { } , formData : output as unknown as Record < string , string > } ) ;
6998 } ;
7099
71100 const handlePaste = ( payload : unknown ) => {
@@ -77,15 +106,16 @@ export default function TRVSelect({
77106 const providers = parsed . message . catalog . providers ;
78107
79108 const results : ExtractedItem [ ] = [ ] ;
109+ const allFulfillments : CatalogFulfillment [ ] = [ ] ;
80110
81111 providers . forEach ( ( provider : CatalogProvider ) => {
82112 const providerId = provider . id ;
83- const fulfillmentId = provider . fulfillments [ 0 ] ! . id ;
84- if ( ! fulfillmentId ) return ;
85113
86- if ( ! provider . items ) return ;
114+ if ( provider . fulfillments ) {
115+ allFulfillments . push ( ...provider . fulfillments ) ;
116+ }
87117
88- setValue ( "fulfillment" , provider . fulfillments [ 0 ] ! . id ) ;
118+ if ( ! provider . items ) return ;
89119
90120 provider . items . forEach ( ( item : CatalogItem ) => {
91121 if ( item . parent_item_id ) {
@@ -100,6 +130,7 @@ export default function TRVSelect({
100130 } ) ;
101131
102132 setItemOptions ( results ) ;
133+ setFulfillmentOptions ( allFulfillments ) ;
103134 } catch ( err ) {
104135 setErrorWhilePaste ( "Invalid payload structure." ) ;
105136 toast . error ( "Invalid payload structure. Please check the pasted data." ) ;
@@ -281,6 +312,31 @@ export default function TRVSelect({
281312 ) }
282313 </ div >
283314
315+ { /* Fulfillment Selection */ }
316+ < div className = "border p-3 rounded space-y-2" >
317+ < div className = { fieldWrapperStyle } >
318+ < label className = { labelStyle } > Select Fulfillment</ label >
319+ { fulfillmentOptions . length === 0 ? (
320+ < input
321+ type = "text"
322+ { ...register ( "fulfillmentId" ) }
323+ placeholder = "Fulfillment ID"
324+ className = { inputStyle }
325+ />
326+ ) : (
327+ < select { ...register ( "fulfillmentId" ) } className = { inputStyle } >
328+ < option value = "" > Select Fulfillment...</ option >
329+ { fulfillmentOptions . map ( ( f ) => (
330+ < option key = { f . id } value = { f . id } >
331+ { f . id }
332+ { f . type ? ` (${ f . type } )` : "" }
333+ </ option >
334+ ) ) }
335+ </ select >
336+ ) }
337+ </ div >
338+ </ div >
339+
284340 < button
285341 type = "submit"
286342 className = "w-full bg-green-600 text-white py-2 rounded hover:bg-green-700"
@@ -291,55 +347,3 @@ export default function TRVSelect({
291347 </ div >
292348 ) ;
293349}
294-
295- // type FormData = {
296- // provider: string;
297- // provider_location: string[];
298- // location_gps: string;
299- // location_pin_code: string;
300- // items: {
301- // itemId: string;
302- // quantity: number;
303- // location: string;
304- // }[];
305- // [key: string]: any; // to allow dynamic offer keys like offers_FLAT50
306- // };
307-
308- // function validateFormData(data: FormData): {
309- // valid: boolean;
310- // errors: string[];
311- // } {
312- // const errors: string[] = [];
313-
314- // for (const key in data) {
315- // if (data[key] === undefined || data[key] === null || data[key] === "") {
316- // errors.push(`Field ${key} cannot be empty.`);
317- // }
318- // }
319-
320- // // Rule 1: At least 2 items
321- // if (!data.items || data.items.length < 2) {
322- // errors.push("At least 2 items must be selected.");
323- // }
324-
325- // // Rule 2: All items must be unique
326- // const itemIds = data.items.map((item) => item.itemId);
327- // const uniqueItemIds = new Set(itemIds);
328- // if (itemIds.length !== uniqueItemIds.size) {
329- // errors.push("All selected items must be unique.");
330- // }
331-
332- // // Rule 3: Only one offer can be selected (non-falsy)
333- // const offerKeys = Object.keys(data).filter((key) =>
334- // key.startsWith("offers_")
335- // );
336- // const selectedOffers = offerKeys.filter((key) => Boolean(data[key]));
337- // if (selectedOffers.length > 1) {
338- // errors.push("Only one offer can be selected.");
339- // }
340-
341- // return {
342- // valid: errors.length === 0,
343- // errors,
344- // };
345- // }
0 commit comments