@@ -5,6 +5,9 @@ import clsx from "clsx";
55import { askAI } from "@/app/actions/chatActions" ;
66import { StyledMarkdown } from "./markdown" ;
77import { useChatHistory , type Message } from "../hooks/useChathistory" ;
8+ import useSWR from "swr" ;
9+ import { getQuestionExample } from "../actions/questionExample" ;
10+ import { getLanguageName } from "../pagesList" ;
811
912interface ChatFormProps {
1013 documentContent : string ;
@@ -13,7 +16,6 @@ interface ChatFormProps {
1316
1417export function ChatForm ( { documentContent, sectionId } : ChatFormProps ) {
1518 const [ messages , updateChatHistory ] = useChatHistory ( sectionId ) ;
16-
1719 const [ inputValue , setInputValue ] = useState ( "" ) ;
1820 const [ isLoading , setIsLoading ] = useState ( false ) ;
1921 const [ isFormVisible , setIsFormVisible ] = useState ( false ) ;
@@ -23,15 +25,41 @@ export function ChatForm({ documentContent, sectionId }: ChatFormProps) {
2325 setIsMounted ( true ) ;
2426 } , [ ] ) ;
2527
28+ const lang = getLanguageName ( docs_id ) ;
29+ const { data : exampleData , error : exampleError } = useSWR (
30+ // 質問フォームを開いたときだけで良い
31+ isFormVisible ? { lang, documentContent } : null ,
32+ getQuestionExample ,
33+ {
34+ // リクエストは古くても構わないので1回でいい
35+ revalidateIfStale : false ,
36+ revalidateOnFocus : false ,
37+ revalidateOnReconnect : false ,
38+ }
39+ ) ;
40+ if ( exampleError ) {
41+ console . error ( "Error getting question example:" , exampleError ) ;
42+ }
43+ // 質問フォームを開くたびにランダムに選び直し、
44+ // exampleData[Math.floor(exampleChoice * exampleData.length)] を採用する
45+ const [ exampleChoice , setExampleChoice ] = useState < number > ( 0 ) ; // 0〜1
46+
2647 const handleSubmit = async ( e : FormEvent < HTMLFormElement > ) => {
2748 e . preventDefault ( ) ;
2849 setIsLoading ( true ) ;
2950
3051 const userMessage : Message = { sender : "user" , text : inputValue } ;
3152 updateChatHistory ( [ userMessage ] ) ;
3253
54+ let userQuestion = inputValue ;
55+ if ( ! userQuestion && exampleData ) {
56+ // 質問が空欄なら、質問例を使用
57+ userQuestion = exampleData [ Math . floor ( exampleChoice * exampleData . length ) ] ;
58+ setInputValue ( userQuestion ) ;
59+ }
60+
3361 const result = await askAI ( {
34- userQuestion : inputValue ,
62+ userQuestion,
3563 documentContent : documentContent ,
3664 } ) ;
3765
@@ -54,22 +82,28 @@ export function ChatForm({ documentContent, sectionId }: ChatFormProps) {
5482 return (
5583 < >
5684 { isFormVisible && (
57- < form className = "border border-2 border-secondary shadow-xl p-6 rounded-lg bg-base-100" style = { { width :"100%" , textAlign :"center" , boxShadow :"-moz-initial" } } onSubmit = { handleSubmit } >
58- < h2 className = "text-xl font-bold mb-4 text-left relative -top-2 font-mono h-2" >
59- AIへ質問
60- </ h2 >
61- < div className = "input-area" style = { { height :"80px" } } >
85+ < form className = "border border-2 border-secondary shadow-md rounded-lg bg-base-100" style = { { width :"100%" , textAlign :"center" , boxShadow :"-moz-initial" } } onSubmit = { handleSubmit } >
86+ < div className = "input-area" >
6287 < textarea
63- className = "textarea textarea-white textarea-md"
64- placeholder = "質問を入力してください"
65- style = { { width : "100%" , height : "110px" , resize : "none" } }
88+ className = "textarea textarea-ghost textarea-md rounded-lg"
89+ placeholder = {
90+ "質問を入力してください" +
91+ ( exampleData
92+ ? ` (例:「${ exampleData [ Math . floor ( exampleChoice * exampleData . length ) ] } 」)`
93+ : "" )
94+ }
95+ style = { {
96+ width : "100%" ,
97+ height : "110px" ,
98+ resize : "none" ,
99+ outlineStyle : "none" ,
100+ } }
66101 value = { inputValue }
67102 onChange = { ( e ) => setInputValue ( e . target . value ) }
68103 disabled = { isLoading }
69104 > </ textarea >
70105 </ div >
71- < br />
72- < div className = "controls" style = { { position :"relative" , top :"22px" , display :"flex" , alignItems :"center" , justifyContent :"space-between" } } >
106+ < div className = "controls" style = { { margin :"10px" , display :"flex" , alignItems :"center" , justifyContent :"space-between" } } >
73107 < div className = "left-icons" >
74108 < button
75109 className = "btn btn-soft btn-secondary rounded-full"
@@ -96,7 +130,10 @@ export function ChatForm({ documentContent, sectionId }: ChatFormProps) {
96130 { ! isFormVisible && (
97131 < button
98132 className = "btn btn-soft btn-secondary rounded-full"
99- onClick = { ( ) => setIsFormVisible ( true ) }
133+ onClick = { ( ) => {
134+ setIsFormVisible ( true ) ;
135+ setExampleChoice ( Math . random ( ) ) ;
136+ } }
100137 >
101138 チャットを開く
102139 </ button >
0 commit comments