11"use client" ;
22
33import { useState , FormEvent } from "react" ;
4+ import clsx from "clsx" ;
45import { askAI } from "@/app/actions/chatActions" ;
56import { StyledMarkdown } from "./markdown" ;
7+ import { useChatHistory , type Message } from "../hooks/useChathistory" ;
68import useSWR from "swr" ;
79import { getQuestionExample } from "../actions/questionExample" ;
810import { getLanguageName } from "../pagesList" ;
911
10- export function ChatForm ( {
11- docs_id,
12- documentContent,
13- } : {
14- docs_id : string ;
12+ interface ChatFormProps {
1513 documentContent : string ;
16- } ) {
14+ sectionId : string ;
15+ }
16+
17+ export function ChatForm ( { documentContent, sectionId } : ChatFormProps ) {
18+ const [ messages , updateChatHistory ] = useChatHistory ( sectionId ) ;
1719 const [ inputValue , setInputValue ] = useState ( "" ) ;
18- const [ response , setResponse ] = useState ( "" ) ;
1920 const [ isLoading , setIsLoading ] = useState ( false ) ;
2021 const [ isFormVisible , setIsFormVisible ] = useState ( false ) ;
2122
22- const lang = getLanguageName ( docs_id ) ;
23+ const lang = getLanguageName ( sectionId ) ;
2324 const { data : exampleData , error : exampleError } = useSWR (
2425 // 質問フォームを開いたときだけで良い
2526 isFormVisible ? { lang, documentContent } : null ,
@@ -41,7 +42,9 @@ export function ChatForm({
4142 const handleSubmit = async ( e : FormEvent < HTMLFormElement > ) => {
4243 e . preventDefault ( ) ;
4344 setIsLoading ( true ) ;
44- setResponse ( "" ) ;
45+
46+ const userMessage : Message = { sender : "user" , text : inputValue } ;
47+ updateChatHistory ( [ userMessage ] ) ;
4548
4649 let userQuestion = inputValue ;
4750 if ( ! userQuestion && exampleData ) {
@@ -56,13 +59,21 @@ export function ChatForm({
5659 } ) ;
5760
5861 if ( result . error ) {
59- setResponse ( `エラー: ${ result . error } ` ) ;
62+ const errorMessage : Message = { sender : "ai" , text : `エラー: ${ result . error } ` , isError : true } ;
63+ updateChatHistory ( [ userMessage , errorMessage ] ) ;
6064 } else {
61- setResponse ( result . response ) ;
65+ const aiMessage : Message = { sender : "ai" , text : result . response } ;
66+ updateChatHistory ( [ userMessage , aiMessage ] ) ;
67+ setInputValue ( "" ) ;
6268 }
6369
6470 setIsLoading ( false ) ;
6571 } ;
72+
73+ const handleClearHistory = ( ) => {
74+ updateChatHistory ( [ ] ) ;
75+ } ;
76+
6677 return (
6778 < >
6879 { isFormVisible && (
@@ -92,8 +103,8 @@ export function ChatForm({
92103 < button
93104 className = "btn btn-soft btn-secondary rounded-full"
94105 onClick = { ( ) => setIsFormVisible ( false ) }
106+ type = "button"
95107 >
96-
97108 閉じる
98109 </ button >
99110 </ div >
@@ -122,14 +133,33 @@ export function ChatForm({
122133 </ button >
123134 ) }
124135
125- { response && (
126- < article >
127- < h3 className = "text-lg font-semibold mb-2" > AIの回答</ h3 >
128- < div className = "chat chat-start" >
129- < div className = "chat-bubble bg-secondary-content text-black" style = { { maxWidth : "100%" , wordBreak : "break-word" } } >
130- < div className = "response-container" > < StyledMarkdown content = { response } /> </ div >
131- </ div >
136+ { messages . length > 0 && (
137+ < article className = "mt-4" >
138+ < div className = "flex justify-between items-center mb-2" >
139+ < h3 className = "text-lg font-semibold" > AIとのチャット</ h3 >
140+ < button
141+ onClick = { handleClearHistory }
142+ className = "btn btn-ghost btn-sm text-xs"
143+ aria-label = "チャット履歴を削除"
144+ >
145+ 履歴を削除
146+ </ button >
132147 </ div >
148+ { messages . map ( ( msg , index ) => (
149+ < div key = { index } className = { `chat ${ msg . sender === 'user' ? 'chat-end' : 'chat-start' } ` } >
150+ < div
151+ className = { clsx (
152+ "chat-bubble" ,
153+ { "bg-primary text-primary-content" : msg . sender === 'user' } ,
154+ { "bg-secondary-content text-black" : msg . sender === 'ai' && ! msg . isError } ,
155+ { "chat-bubble-error" : msg . isError }
156+ ) }
157+ style = { { maxWidth : "100%" , wordBreak : "break-word" } }
158+ >
159+ < StyledMarkdown content = { msg . text } />
160+ </ div >
161+ </ div >
162+ ) ) }
133163 </ article >
134164 ) }
135165
@@ -141,4 +171,4 @@ export function ChatForm({
141171
142172 </ >
143173 ) ;
144- }
174+ }
0 commit comments