@@ -10,7 +10,12 @@ import "@/app/globals.css";
1010import { fetchLocationFromZip } from "@/util/fetchLocation" ;
1111
1212import { PrintableReferralsReport } from "@/util/printReferrals" ;
13- import { fetchActionPlan , ActionPlan } from "@/util/fetchActionPlan" ;
13+ import {
14+ fetchActionPlan , // eslint-disable-line @typescript-eslint/no-unused-vars -- will be used for user preference between streaming/non-streaming
15+ fetchActionPlanStreaming ,
16+ ActionPlan ,
17+ PartialActionPlan ,
18+ } from "@/util/fetchActionPlan" ;
1419import { ActionPlanSection } from "@/components/ActionPlanSection" ;
1520
1621import ResourcesList from "@/components/ResourcesList" ;
@@ -46,6 +51,10 @@ export default function Page() {
4651 const [ selectedResources , setSelectedResources ] = useState < Resource [ ] > ( [ ] ) ;
4752 const [ actionPlan , setActionPlan ] = useState < ActionPlan | null > ( null ) ;
4853 const [ isGeneratingActionPlan , setIsGeneratingActionPlan ] = useState ( false ) ;
54+ const [ streamingPlan , setStreamingPlan ] = useState < PartialActionPlan | null > (
55+ null ,
56+ ) ;
57+ const [ isStreaming , setIsStreaming ] = useState ( false ) ;
4958 const [ activeTab , setActiveTab ] = useState ( "find-referrals" ) ;
5059 const [ errorMessage , setErrorMessage ] = useState < string | undefined > (
5160 undefined ,
@@ -176,29 +185,66 @@ export default function Page() {
176185 if ( selectedResources . length === 0 ) return ;
177186
178187 setIsGeneratingActionPlan ( true ) ;
188+ setIsStreaming ( true ) ;
179189 setActionPlan ( null ) ;
190+ setStreamingPlan ( null ) ;
180191 setErrorMessage ( undefined ) ;
181192
182193 try {
183194 const {
184- actionPlan : plan ,
195+ actionPlan : finalPlan ,
185196 resultId,
186197 errorMessage : planError ,
187- } = await fetchActionPlan (
198+ } = await fetchActionPlanStreaming (
188199 selectedResources ,
189200 userEmail ,
190201 clientDescription ,
202+ // onChunk callback - receive structured partial plan
203+ ( partialPlan : PartialActionPlan ) => {
204+ setStreamingPlan ( partialPlan ) ;
205+ } ,
206+ // onComplete callback - stop streaming UI
207+ ( ) => {
208+ setIsStreaming ( false ) ;
209+ } ,
210+ // onError callback - clear content and show error
211+ ( error : string ) => {
212+ setIsStreaming ( false ) ;
213+ setIsGeneratingActionPlan ( false ) ;
214+ setStreamingPlan ( null ) ;
215+ setActionPlan ( null ) ;
216+ setErrorMessage ( error ) ;
217+ } ,
191218 ) ;
192- setActionPlan ( plan ) ;
193- setActionPlanResultId ( resultId ) ;
219+
220+ // Handle errors from the streaming response
194221 if ( planError ) {
195222 setErrorMessage ( planError ) ;
196- setActionPlanResultId ( "" ) ; // set the Action PLan Id to "" so we don't email an empty or errant result
223+ setActionPlanResultId ( "" ) ; // set the Action Plan Id to "" so we don't email an empty or errant result
224+ setStreamingPlan ( null ) ;
225+ setActionPlan ( null ) ;
226+ return ;
227+ }
228+
229+ // Set the final parsed action plan
230+ if ( finalPlan ) {
231+ setActionPlan ( finalPlan ) ;
232+ setActionPlanResultId ( resultId ) ;
233+ setStreamingPlan ( null ) ; // Clear streaming state
234+ } else {
235+ setErrorMessage (
236+ "There was an issue streaming the Action Plan. Please try again." ,
237+ ) ;
238+ setActionPlanResultId ( "" ) ;
197239 }
198240 } catch ( error ) {
199241 console . error ( "Error generating action plan:" , error ) ;
242+ setIsStreaming ( false ) ;
243+ setIsGeneratingActionPlan ( false ) ;
244+ setStreamingPlan ( null ) ;
245+ setActionPlan ( null ) ;
200246 setErrorMessage (
201- "The server encountered an unexpected error . Please try again later ." ,
247+ "There was an issue streaming the Action Plan . Please try again." ,
202248 ) ;
203249 } finally {
204250 setIsGeneratingActionPlan ( false ) ;
@@ -419,6 +465,7 @@ export default function Page() {
419465 onPrint = { handlePrint }
420466 resourcesResultId = { resourcesResultId }
421467 actionPlanResultId = { actionPlanResultId }
468+ disabled = { isStreaming }
422469 />
423470 </ div >
424471 </ div >
@@ -446,6 +493,8 @@ export default function Page() {
446493 selectedResources = { selectedResources }
447494 actionPlan = { actionPlan }
448495 isGeneratingActionPlan = { isGeneratingActionPlan }
496+ streamingPlan = { streamingPlan }
497+ isStreaming = { isStreaming }
449498 onResourceSelection = { handleResourceSelection }
450499 onSelectAllResources = { handleSelectAllResources }
451500 onGenerateActionPlan = { ( ) => void generateActionPlan ( ) }
@@ -463,6 +512,7 @@ export default function Page() {
463512 actionPlanResultId = { actionPlanResultId }
464513 className = "justify-end"
465514 testIdSuffix = "bottom"
515+ disabled = { isStreaming }
466516 />
467517 </ div >
468518 ) }
0 commit comments