@@ -55,6 +55,7 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
5555 emptyHybridMessage = 'Use voice or text to communicate' , // deprecated
5656 // Chat configuration
5757 chatFirstMessage,
58+ chatEndMessage,
5859 firstChatMessage, // deprecated
5960 chatPlaceholder,
6061 // Voice configuration
@@ -79,6 +80,7 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
7980 const [ isExpanded , setIsExpanded ] = useState ( false ) ;
8081 const [ hasConsent , setHasConsent ] = useState ( false ) ;
8182 const [ chatInput , setChatInput ] = useState ( '' ) ;
83+ const [ showEndScreen , setShowEndScreen ] = useState ( false ) ;
8284
8385 const conversationEndRef = useRef < HTMLDivElement > ( null ) ;
8486 const inputRef = useRef < HTMLInputElement > ( null ) ;
@@ -109,6 +111,8 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
109111 const effectiveOnVoiceStart = onVoiceStart ?? onCallStart ;
110112 const effectiveOnVoiceEnd = onVoiceEnd ?? onCallEnd ;
111113 const effectiveChatPlaceholder = chatPlaceholder ?? 'Type your message...' ;
114+ const effectiveChatEndMessage =
115+ chatEndMessage ?? 'This chat has ended. Thank you.' ;
112116
113117 const vapi = useVapiWidget ( {
114118 mode,
@@ -253,6 +257,7 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
253257
254258 const handleReset = ( ) => {
255259 vapi . clearConversation ( ) ;
260+ setShowEndScreen ( false ) ;
256261
257262 if ( vapi . voice . isCallActive ) {
258263 vapi . voice . endCall ( ) ;
@@ -267,6 +272,34 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
267272 }
268273 } ;
269274
275+ const handleChatComplete = async ( ) => {
276+ try {
277+ await vapi . chat . sendMessage ( 'Ending chat...' , true ) ;
278+ setShowEndScreen ( true ) ;
279+ } finally {
280+ setChatInput ( '' ) ;
281+ }
282+ } ;
283+
284+ const handleStartNewChat = ( ) => {
285+ vapi . clearConversation ( ) ;
286+ setShowEndScreen ( false ) ;
287+ if ( mode === 'chat' || mode === 'hybrid' ) {
288+ setTimeout ( ( ) => {
289+ inputRef . current ?. focus ( ) ;
290+ } , 100 ) ;
291+ }
292+ } ;
293+
294+ const handleCloseWidget = ( ) => {
295+ if ( showEndScreen ) {
296+ vapi . clearConversation ( ) ;
297+ setShowEndScreen ( false ) ;
298+ setChatInput ( '' ) ;
299+ }
300+ setIsExpanded ( false ) ;
301+ } ;
302+
270303 const handleFloatingButtonClick = ( ) => {
271304 setIsExpanded ( true ) ;
272305 } ;
@@ -316,6 +349,38 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
316349 } ;
317350
318351 const renderConversationArea = ( ) => {
352+ if ( showEndScreen ) {
353+ return (
354+ < div
355+ className = "flex flex-col items-center justify-center text-center gap-4"
356+ style = { { width : '100%' } }
357+ >
358+ < div
359+ className = { `text-base ${ styles . theme === 'dark' ? 'text-gray-200' : 'text-gray-800' } ` }
360+ >
361+ { effectiveChatEndMessage }
362+ </ div >
363+ < div className = "flex items-center gap-3" >
364+ < button
365+ onClick = { handleStartNewChat }
366+ className = "px-3 py-1.5 rounded-md"
367+ style = { {
368+ backgroundColor : colors . ctaButtonColor ,
369+ color : colors . ctaButtonTextColor ,
370+ } }
371+ >
372+ Start new chat
373+ </ button >
374+ < button
375+ onClick = { handleCloseWidget }
376+ className = { `px-3 py-1.5 rounded-md ${ styles . theme === 'dark' ? 'bg-gray-800 text-gray-100' : 'bg-gray-100 text-gray-800' } ` }
377+ >
378+ Close
379+ </ button >
380+ </ div >
381+ </ div >
382+ ) ;
383+ }
319384 // Chat mode: always show conversation messages
320385 if ( mode === 'chat' ) {
321386 return renderConversationMessages ( ) ;
@@ -380,6 +445,9 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
380445 } ;
381446
382447 const renderControls = ( ) => {
448+ if ( showEndScreen ) {
449+ return null ;
450+ }
383451 if ( mode === 'voice' ) {
384452 return (
385453 < VoiceControls
@@ -460,8 +528,10 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
460528 isTyping = { vapi . chat . isTyping }
461529 hasActiveConversation = { vapi . conversation . length > 0 }
462530 mainLabel = { effectiveTextWidgetTitle }
463- onClose = { ( ) => setIsExpanded ( false ) }
531+ onClose = { handleCloseWidget }
464532 onReset = { handleReset }
533+ onChatComplete = { handleChatComplete }
534+ showEndChatButton = { ! showEndScreen }
465535 colors = { colors }
466536 styles = { styles }
467537 />
0 commit comments