11"use client" ;
22
3+ import { useState } from "react" ;
34import { useAgent } from "@copilotkit/react-core/v2" ;
45import { TemplateCard } from "./template-card" ;
56
@@ -22,11 +23,39 @@ export function TemplateLibrary({ open, onClose, onSendPrompt }: TemplateLibrary
2223 const { agent } = useAgent ( ) ;
2324 const templates : Template [ ] = agent . state ?. templates || [ ] ;
2425
25- const handleApply = ( id : string , name : string ) => {
26- onSendPrompt ( `Apply the "${ name } " template (id: ${ id } ) to my new data` ) ;
26+ // Apply flow: show input for new data before sending
27+ const [ applyingTemplate , setApplyingTemplate ] = useState < Template | null > ( null ) ;
28+ const [ applyData , setApplyData ] = useState ( "" ) ;
29+
30+ const handleApplyClick = ( id : string ) => {
31+ const template = templates . find ( ( t ) => t . id === id ) ;
32+ if ( template ) {
33+ setApplyingTemplate ( template ) ;
34+ setApplyData ( "" ) ;
35+ }
36+ } ;
37+
38+ const handleApplyConfirm = ( ) => {
39+ if ( ! applyingTemplate ) return ;
40+ const dataDesc = applyData . trim ( ) ;
41+ if ( ! dataDesc ) return ;
42+
43+ // Send the template HTML directly in the prompt so the agent doesn't
44+ // need to look it up from state (frontend setState may not sync to backend)
45+ onSendPrompt (
46+ `Use this saved template called "${ applyingTemplate . name } " as a base layout and adapt it for the following new data: ${ dataDesc } \n\n` +
47+ `Here is the template HTML to adapt:\n\n${ applyingTemplate . html } `
48+ ) ;
49+ setApplyingTemplate ( null ) ;
50+ setApplyData ( "" ) ;
2751 onClose ( ) ;
2852 } ;
2953
54+ const handleApplyCancel = ( ) => {
55+ setApplyingTemplate ( null ) ;
56+ setApplyData ( "" ) ;
57+ } ;
58+
3059 const handleDelete = ( id : string ) => {
3160 agent . setState ( {
3261 templates : templates . filter ( ( t ) => t . id !== id ) ,
@@ -126,13 +155,79 @@ export function TemplateLibrary({ open, onClose, onSendPrompt }: TemplateLibrary
126155 html = { t . html }
127156 dataDescription = { t . data_description }
128157 version = { t . version }
129- onApply = { handleApply }
158+ onApply = { handleApplyClick }
130159 onDelete = { handleDelete }
131160 />
132161 ) ) }
133162 </ div >
134163 ) }
135164 </ div >
165+
166+ { /* Apply data input — slides up from bottom of drawer */ }
167+ { applyingTemplate && (
168+ < div
169+ className = "shrink-0 px-4 pb-4 pt-3"
170+ style = { {
171+ borderTop : "1px solid var(--color-border-glass, rgba(0,0,0,0.1))" ,
172+ animation : "tmpl-slideIn 0.2s ease-out" ,
173+ } }
174+ >
175+ < p
176+ className = "text-xs font-semibold mb-1"
177+ style = { { color : "var(--text-primary, #1a1a1a)" } }
178+ >
179+ Apply "{ applyingTemplate . name } "
180+ </ p >
181+ < p
182+ className = "text-[11px] mb-2"
183+ style = { { color : "var(--text-tertiary, #999)" } }
184+ >
185+ Describe the new data you want to populate this template with:
186+ </ p >
187+ < textarea
188+ value = { applyData }
189+ onChange = { ( e ) => setApplyData ( e . target . value ) }
190+ onKeyDown = { ( e ) => {
191+ if ( e . key === "Enter" && ! e . shiftKey ) {
192+ e . preventDefault ( ) ;
193+ handleApplyConfirm ( ) ;
194+ }
195+ if ( e . key === "Escape" ) handleApplyCancel ( ) ;
196+ } }
197+ autoFocus
198+ placeholder = 'e.g. "$2,400 web design project for Sarah Chen, due April 15"'
199+ rows = { 2 }
200+ className = "w-full text-xs px-3 py-2 rounded-lg outline-none resize-none"
201+ style = { {
202+ background : "var(--color-background-secondary, #f5f5f5)" ,
203+ color : "var(--text-primary, #1a1a1a)" ,
204+ border : "1px solid var(--color-border-tertiary, rgba(0,0,0,0.1))" ,
205+ } }
206+ />
207+ < div className = "flex gap-2 mt-2" >
208+ < button
209+ onClick = { handleApplyConfirm }
210+ disabled = { ! applyData . trim ( ) }
211+ className = "flex-1 text-xs font-medium py-1.5 rounded-lg text-white transition-all duration-150 disabled:opacity-40"
212+ style = { {
213+ background : "linear-gradient(135deg, var(--color-lilac-dark, #6366f1), var(--color-mint-dark, #10b981))" ,
214+ } }
215+ >
216+ Apply Template
217+ </ button >
218+ < button
219+ onClick = { handleApplyCancel }
220+ className = "text-xs px-3 py-1.5 rounded-lg"
221+ style = { {
222+ border : "1px solid var(--color-border-tertiary, rgba(0,0,0,0.1))" ,
223+ color : "var(--text-secondary, #666)" ,
224+ } }
225+ >
226+ Cancel
227+ </ button >
228+ </ div >
229+ </ div >
230+ ) }
136231 </ div >
137232 </ >
138233 ) ;
0 commit comments