@@ -50,6 +50,7 @@ function App() {
5050
5151 // Product selection
5252 const [ selectedProducts , setSelectedProducts ] = useState < Product [ ] > ( [ ] ) ;
53+ const [ availableProducts , setAvailableProducts ] = useState < Product [ ] > ( [ ] ) ;
5354
5455 // Generated content
5556 const [ generatedContent , setGeneratedContent ] = useState < GeneratedContent | null > ( null ) ;
@@ -86,27 +87,23 @@ function App() {
8687 const response = await fetch ( '/api/user' ) ;
8788 if ( response . ok ) {
8889 const user : UserInfo = await response . json ( ) ;
89- // Use user_principal_id if authenticated, otherwise empty string for dev mode
90- setUserId ( user . user_principal_id || '' ) ;
90+ setUserId ( user . user_principal_id || 'anonymous' ) ;
9191 }
9292 } catch ( err ) {
9393 console . error ( 'Error fetching user:' , err ) ;
94- // Default to empty string for development mode
95- setUserId ( '' ) ;
94+ setUserId ( 'anonymous' ) ;
9695 }
9796 } ;
9897 fetchUser ( ) ;
9998 } , [ ] ) ;
10099
101100 // Handle selecting a conversation from history
102101 const handleSelectConversation = useCallback ( async ( selectedConversationId : string ) => {
103- setIsLoading ( true ) ;
104102 try {
105103 const response = await fetch ( `/api/conversations/${ selectedConversationId } ?user_id=${ encodeURIComponent ( userId ) } ` ) ;
106104 if ( response . ok ) {
107105 const data = await response . json ( ) ;
108106 setConversationId ( selectedConversationId ) ;
109- // Map messages to ChatMessage format
110107 const loadedMessages : ChatMessage [ ] = ( data . messages || [ ] ) . map ( ( msg : { role : string ; content : string ; timestamp ?: string ; agent ?: string } , index : number ) => ( {
111108 id : `${ selectedConversationId } -${ index } ` ,
112109 role : msg . role as 'user' | 'assistant' ,
@@ -118,24 +115,18 @@ function App() {
118115 setPendingBrief ( null ) ;
119116 setConfirmedBrief ( data . brief || null ) ;
120117
121- // Restore generated content if it exists
122118 if ( data . generated_content ) {
123119 const gc = data . generated_content ;
124- // Parse text_content if it's a string
125120 let textContent = gc . text_content ;
126121 if ( typeof textContent === 'string' ) {
127122 try {
128123 textContent = JSON . parse ( textContent ) ;
129124 } catch {
130- // Keep as string if not valid JSON
131125 }
132126 }
133127
134- // Build image URL: convert old blob URLs to proxy URLs, or use existing proxy URL
135128 let imageUrl : string | undefined = gc . image_url ;
136129 if ( imageUrl && imageUrl . includes ( 'blob.core.windows.net' ) ) {
137- // Convert old blob URL to proxy URL
138- // blob URL format: https://account.blob.core.windows.net/container/conv_id/filename.png
139130 const parts = imageUrl . split ( '/' ) ;
140131 const filename = parts [ parts . length - 1 ] ;
141132 const convId = parts [ parts . length - 2 ] ;
@@ -159,14 +150,12 @@ function App() {
159150 } : undefined ,
160151 violations : gc . violations || [ ] ,
161152 requires_modification : gc . requires_modification || false ,
162- // Restore any generation errors
163153 error : gc . error ,
164154 image_error : gc . image_error ,
165155 text_error : gc . text_error ,
166156 } ;
167157 setGeneratedContent ( restoredContent ) ;
168158
169- // Restore selected products if they exist
170159 if ( gc . selected_products && Array . isArray ( gc . selected_products ) ) {
171160 setSelectedProducts ( gc . selected_products ) ;
172161 } else {
@@ -179,8 +168,6 @@ function App() {
179168 }
180169 } catch ( error ) {
181170 console . error ( 'Error loading conversation:' , error ) ;
182- } finally {
183- setIsLoading ( false ) ;
184171 }
185172 } , [ userId ] ) ;
186173
@@ -406,10 +393,16 @@ function App() {
406393 setConfirmedBrief ( pendingBrief ) ;
407394 setPendingBrief ( null ) ;
408395
396+ const productsResponse = await fetch ( '/api/products' ) ;
397+ if ( productsResponse . ok ) {
398+ const productsData = await productsResponse . json ( ) ;
399+ setAvailableProducts ( productsData . products || [ ] ) ;
400+ }
401+
409402 const assistantMessage : ChatMessage = {
410403 id : uuidv4 ( ) ,
411404 role : 'assistant' ,
412- content : "Great! Your creative brief has been confirmed. Now let's select products to feature in your campaign. Tell me what products you'd like to include - you can describe them by name, category, or characteristics ." ,
405+ content : "Great! Your creative brief has been confirmed. Here are the available products for your campaign. Select the ones you'd like to feature, or tell me what you're looking for ." ,
413406 agent : 'ProductAgent' ,
414407 timestamp : new Date ( ) . toISOString ( ) ,
415408 } ;
@@ -442,6 +435,17 @@ function App() {
442435 setMessages ( prev => [ ...prev , assistantMessage ] ) ;
443436 } , [ ] ) ;
444437
438+ const handleProductSelect = useCallback ( ( product : Product ) => {
439+ setSelectedProducts ( prev => {
440+ const isSelected = prev . some ( p => ( p . sku || p . product_name ) === ( product . sku || product . product_name ) ) ;
441+ if ( isSelected ) {
442+ return prev . filter ( p => ( p . sku || p . product_name ) !== ( product . sku || product . product_name ) ) ;
443+ } else {
444+ return [ ...prev , product ] ;
445+ }
446+ } ) ;
447+ } , [ ] ) ;
448+
445449 const handleStopGeneration = useCallback ( ( ) => {
446450 if ( abortControllerRef . current ) {
447451 abortControllerRef . current . abort ( ) ;
@@ -635,12 +639,15 @@ function App() {
635639 confirmedBrief = { confirmedBrief }
636640 generatedContent = { generatedContent }
637641 selectedProducts = { selectedProducts }
642+ availableProducts = { availableProducts }
638643 onBriefConfirm = { handleBriefConfirm }
639644 onBriefCancel = { handleBriefCancel }
640645 onGenerateContent = { handleGenerateContent }
641646 onRegenerateContent = { handleGenerateContent }
642647 onProductsStartOver = { handleProductsStartOver }
648+ onProductSelect = { handleProductSelect }
643649 imageGenerationEnabled = { imageGenerationEnabled }
650+ onNewConversation = { handleNewConversation }
644651 />
645652 </ div >
646653
0 commit comments