From 106561189fd9570935ea6fb07ee3214ba14371d0 Mon Sep 17 00:00:00 2001 From: Tracewebstudio Dev Date: Fri, 14 Aug 2026 18:43:31 +0200 Subject: [PATCH] feat(ai-widget): Save to Profile button for profile_draft responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added confirmSaveProfile() — calls POST /api/ai/chat/confirm with action='save_profile', extracting the quoted improved text from the LLM's message automatically - Green 'Save to Profile' button appears on profile_draft messages (actionType === 'profile_draft'), distinct from the ticket confirm flow - actionLabel() extended with 'save_profile' key Co-Authored-By: Claude Sonnet 4.6 --- src/components/AiChatWidget.tsx | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/components/AiChatWidget.tsx b/src/components/AiChatWidget.tsx index 8cec2b7..cc123fa 100644 --- a/src/components/AiChatWidget.tsx +++ b/src/components/AiChatWidget.tsx @@ -77,6 +77,7 @@ function actionLabel(action: string | undefined): string { case "open_auto_apply": return "Auto Apply →"; case "open_form_extract": return "Form Assistant →"; case "create_ticket": return "Create Support Ticket"; + case "save_profile": return "Save to Profile"; default: return ""; } } @@ -278,6 +279,61 @@ export function AiChatWidget() { } }; + /** Called when user clicks "Save to Profile" on a profile_draft message. */ + const confirmSaveProfile = async (msgIdx: number, draftText: string) => { + // Extract just the quoted improved text if it's wrapped in our "Here's an improved..." message + const quotedMatch = draftText.match(/"([^"]+)"/); + const cleanDraft = quotedMatch ? quotedMatch[1] : draftText; + + setMessages((prev) => prev.map((m, i) => (i === msgIdx ? { ...m, confirmed: true } : m))); + setIsLoading(true); + try { + const res = await fetch(`${API}/ai/chat/confirm`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${sessionStorage.getItem("nxtgauge_access_token") || ""}`, + }, + credentials: "include", + body: JSON.stringify({ + action: "save_profile", + conversation_id: conversationId() || undefined, + fields: { draft_text: cleanDraft }, + }), + }); + const data = await res.json().catch(() => ({})); + if (res.ok && data.success) { + setMessages((prev) => [ + ...prev, + { + role: "assistant", + content: data.message || "Your profile summary has been updated!", + status: "profile_saved", + confirmed: true, + }, + ]); + } else { + setMessages((prev) => [ + ...prev, + { + role: "assistant", + content: data.error || "Couldn't save the profile summary. Please try again or update it manually from your profile page.", + }, + ]); + } + } catch { + setMessages((prev) => [ + ...prev, + { + role: "assistant", + content: "Couldn't connect to save your profile. Please update it manually from your profile page.", + }, + ]); + } finally { + setIsLoading(false); + } + }; + return ( <> {/* Floating button */} @@ -533,6 +589,27 @@ export function AiChatWidget() { Create Support Ticket + + {/* Save-profile button — for profile_draft messages */} + + +