11'use client'
2- import React , { useState } from 'react'
2+ import React , { useEffect , useState } from 'react'
33import { Button } from '@/components/ui/button'
44import { Label } from '@/components/ui/label'
55import {
@@ -12,13 +12,89 @@ import {
1212 PlusCircle ,
1313 Trash2 ,
1414} from 'lucide-react'
15- import { DeliveryLeadSubmissionData , Milestone } from './types'
15+ import { DeliveryLeadSubmissionData , DeliveryLeadSubmissionPrefill , Milestone } from './types'
1616import { Select , SelectTrigger , SelectContent , SelectItem , SelectValue } from '@/components/ui/select'
1717
18- const initialMilestones : Milestone [ ] = [ { name : '' , commentary : '' , dueDate : '' , rag : 'On-Track' } ]
18+ const createEmptyMilestone = ( ) : Milestone => ( {
19+ name : '' ,
20+ commentary : '' ,
21+ dueDate : '' ,
22+ rag : 'On-Track' ,
23+ id : null ,
24+ } )
1925
2026const ragOptions = [ 'On-Track' , 'Off-Track' , 'At Risk' , 'Complete' ]
2127
28+ const formatDateInputValue = ( value ?: string | null ) => {
29+ if ( ! value ) return ''
30+ const parsed = new Date ( value )
31+ if ( ! Number . isNaN ( parsed . getTime ( ) ) ) {
32+ return parsed . toISOString ( ) . slice ( 0 , 10 )
33+ }
34+ const [ dateOnly ] = value . split ( 'T' )
35+ return dateOnly ?? ''
36+ }
37+
38+ const getNumericId = ( value : number | { id ?: number | string | null } | null | undefined ) : number | null => {
39+ if ( typeof value === 'number' ) return value
40+ if ( value && typeof value === 'object' ) {
41+ const numericId = value . id
42+ if ( typeof numericId === 'number' ) return numericId
43+ if ( typeof numericId === 'string' ) {
44+ const parsed = Number ( numericId )
45+ return Number . isNaN ( parsed ) ? null : parsed
46+ }
47+ }
48+ return null
49+ }
50+
51+ const getCustomerOption = ( customer : DeliveryLeadSubmissionPrefill [ 'customer' ] ) => {
52+ const id = getNumericId ( customer )
53+ if ( id === null ) return null
54+ if ( customer && typeof customer === 'object' ) {
55+ const name = ( customer as { name ?: string | null } ) . name ?? `Customer ${ id } `
56+ return { id, name }
57+ }
58+ return { id, name : `Customer ${ id } ` }
59+ }
60+
61+ const getProjectOption = (
62+ project : DeliveryLeadSubmissionPrefill [ 'project' ] ,
63+ fallbackCustomerId : number | null ,
64+ ) => {
65+ const id = getNumericId ( project )
66+ if ( id === null ) return null
67+
68+ if ( project && typeof project === 'object' ) {
69+ const name =
70+ ( project as { name ?: string | null ; projectName ?: string | null } ) . name ??
71+ ( project as { projectName ?: string | null } ) . projectName ??
72+ `Project ${ id } `
73+ const customerId =
74+ getNumericId ( ( project as { customer ?: number | { id ?: number | string | null } } ) . customer ) ??
75+ fallbackCustomerId
76+ return { id, name, customerId }
77+ }
78+
79+ return { id, name : `Project ${ id } ` , customerId : fallbackCustomerId }
80+ }
81+
82+ const buildMilestonesFromPrefill = (
83+ prefilled : DeliveryLeadSubmissionPrefill [ 'milestones' ] ,
84+ ) : Milestone [ ] => {
85+ if ( ! prefilled || prefilled . length === 0 ) return [ createEmptyMilestone ( ) ]
86+
87+ return prefilled
88+ . filter ( Boolean )
89+ . map ( ( milestone ) => ( {
90+ name : milestone ?. name ?? '' ,
91+ commentary : milestone ?. commentary ?? '' ,
92+ dueDate : formatDateInputValue ( milestone ?. dueDate ?? '' ) ,
93+ rag : milestone ?. rag ?? 'On-Track' ,
94+ id : milestone ?. id ?? null ,
95+ } ) )
96+ }
97+
2298const tabConfig = [
2399 { name : 'Project Summary' , icon : FileText } ,
24100 { name : 'Milestones' , icon : ListChecks } ,
@@ -38,28 +114,52 @@ export interface DeliveryLeadSubmissionProps {
38114 formData : DeliveryLeadSubmissionData ,
39115 ) => Promise < { success : boolean ; message : string } >
40116 customerProjectPairs ?: CustomerProjectPair [ ]
117+ initialData ?: DeliveryLeadSubmissionPrefill
41118}
42119
43- export function DeliveryLeadSubmissionComponent ( { onSubmit, customerProjectPairs } : DeliveryLeadSubmissionProps ) {
120+ export function DeliveryLeadSubmissionComponent ( { onSubmit, customerProjectPairs, initialData } : DeliveryLeadSubmissionProps ) {
44121 const [ currentTab , setCurrentTab ] = useState ( tabConfig [ 0 ] . name )
45- const [ clientId , setClientId ] = useState < number | null > ( null )
46- const [ projectId , setProjectId ] = useState < number | null > ( null )
47- const [ deliveryLead , setDeliveryLead ] = useState ( '' )
48- const [ projectSummary , setProjectSummary ] = useState ( '' )
49- const [ milestones , setMilestones ] = useState ( initialMilestones )
50- const [ projectUpdate , setProjectUpdate ] = useState ( '' )
51- const [ projectConcerns , setProjectConcerns ] = useState ( '' )
52- const [ commercialOpportunities , setCommercialOpportunities ] = useState ( '' )
53- const [ commercialRisks , setCommercialRisks ] = useState ( '' )
122+ const [ clientId , setClientId ] = useState < number | null > ( ( ) => getNumericId ( initialData ?. customer ) )
123+ const [ projectId , setProjectId ] = useState < number | null > ( ( ) => getNumericId ( initialData ?. project ) )
124+ const [ projectSummary , setProjectSummary ] = useState ( initialData ?. projectSummary ?? '' )
125+ const [ milestones , setMilestones ] = useState < Milestone [ ] > ( ( ) => buildMilestonesFromPrefill ( initialData ?. milestones ) )
126+ const [ projectUpdate , setProjectUpdate ] = useState ( initialData ?. projectUpdate ?? '' )
127+ const [ projectConcerns , setProjectConcerns ] = useState ( initialData ?. projectConcerns ?? '' )
128+ const [ commercialOpportunities , setCommercialOpportunities ] = useState ( initialData ?. commercialOpportunities ?? '' )
129+ const [ commercialRisks , setCommercialRisks ] = useState ( initialData ?. commercialRisks ?? '' )
54130
55- // Derive unique customers
56- const customers = Array . from (
57- new Map ( ( customerProjectPairs ?? [ ] ) . map ( cp => [ cp . customer . id , cp . customer ] ) ) . values ( )
131+ useEffect ( ( ) => {
132+ setClientId ( getNumericId ( initialData ?. customer ) )
133+ setProjectId ( getNumericId ( initialData ?. project ) )
134+ setProjectSummary ( initialData ?. projectSummary ?? '' )
135+ setProjectUpdate ( initialData ?. projectUpdate ?? '' )
136+ setProjectConcerns ( initialData ?. projectConcerns ?? '' )
137+ setCommercialOpportunities ( initialData ?. commercialOpportunities ?? '' )
138+ setCommercialRisks ( initialData ?. commercialRisks ?? '' )
139+ setMilestones ( buildMilestonesFromPrefill ( initialData ?. milestones ) )
140+ } , [ initialData ] )
141+
142+ const prefilledCustomer = getCustomerOption ( initialData ?. customer )
143+ const customersFromPairs = Array . from (
144+ new Map ( ( customerProjectPairs ?? [ ] ) . map ( ( cp ) => [ cp . customer . id , cp . customer ] ) ) . values ( ) ,
58145 )
59- // Filter projects by selected customer
60- const filteredProjects = ( customerProjectPairs ?? [ ] )
61- . filter ( cp => cp . customer . id === clientId )
62- . map ( cp => cp . project )
146+ const customers =
147+ prefilledCustomer && ! customersFromPairs . some ( ( customer ) => customer . id === prefilledCustomer . id )
148+ ? [ ...customersFromPairs , prefilledCustomer ]
149+ : customersFromPairs
150+
151+ const prefilledProject = getProjectOption ( initialData ?. project , getNumericId ( initialData ?. customer ) )
152+ const projectsForCustomer = ( customerProjectPairs ?? [ ] )
153+ . filter ( ( cp ) => cp . customer . id === clientId )
154+ . map ( ( cp ) => cp . project )
155+
156+ const filteredProjects =
157+ clientId &&
158+ prefilledProject &&
159+ prefilledProject . customerId === clientId &&
160+ ! projectsForCustomer . some ( ( project ) => project . id === prefilledProject . id )
161+ ? [ ...projectsForCustomer , { id : prefilledProject . id , name : prefilledProject . name } ]
162+ : projectsForCustomer
63163
64164 const handleMilestoneChange = ( idx : number , field : string , value : string ) => {
65165 setMilestones ( ( prev ) => {
@@ -73,7 +173,7 @@ export function DeliveryLeadSubmissionComponent({ onSubmit, customerProjectPairs
73173 }
74174
75175 const addMilestone = ( ) => {
76- setMilestones ( ( prev ) => [ ...prev , { name : '' , commentary : '' , dueDate : '' , rag : 'On-Track' } ] )
176+ setMilestones ( ( prev ) => [ ...prev , createEmptyMilestone ( ) ] )
77177 }
78178
79179 const removeMilestone = ( idx : number ) => {
@@ -82,11 +182,21 @@ export function DeliveryLeadSubmissionComponent({ onSubmit, customerProjectPairs
82182
83183 const handleSubmit = async ( e : React . FormEvent < HTMLFormElement > ) => {
84184 e . preventDefault ( )
185+
186+ const normalizedMilestones =
187+ milestones . length > 0
188+ ? milestones . map ( ( milestone ) => ( {
189+ ...milestone ,
190+ commentary : milestone . commentary || null ,
191+ dueDate : milestone . dueDate || null ,
192+ } ) )
193+ : null
194+
85195 const data : DeliveryLeadSubmissionData = {
86196 customer : clientId as number , // must be number
87197 project : projectId as number , // must be number
88198 projectSummary,
89- milestones : milestones . length > 0 ? milestones : null ,
199+ milestones : normalizedMilestones ,
90200 projectUpdate,
91201 projectConcerns : projectConcerns || null ,
92202 commercialOpportunities : commercialOpportunities || null ,
0 commit comments