1- import { FC } from 'react' ;
1+ import { FC , useEffect , useRef , useState } from 'react' ;
22import { Send } from 'lucide-react' ;
3+ import { API } from '@/enums/api.enums' ;
4+ import { BugFixBody , BugFixMessage , BugFixResponse } from './bug-fix.types' ;
5+ import { usePost } from '@/core/react-query' ;
6+ import { toast } from 'sonner' ;
7+ import { BeatLoader } from 'react-spinners' ;
38
49const BugFix : FC = ( ) => {
10+ const { mutateAsync } = usePost < BugFixResponse , BugFixBody > (
11+ API . BugFix ,
12+ 'bug-fix' ,
13+ ) ;
14+
15+ const [ minToken , setMinToken ] = useState ( '100' ) ;
16+ const [ maxToken , setMaxToken ] = useState ( '500' ) ;
17+ const [ service , setService ] = useState ( 'terraform' ) ;
18+ const [ version , setVersion ] = useState ( 'latest' ) ;
19+ const [ bugDescription , setBugDescription ] = useState ( '' ) ;
20+ const [ messages , setMessages ] = useState < BugFixMessage [ ] > ( [ ] ) ;
21+
22+ const messagesRef = useRef < HTMLDivElement > ( null ) ;
23+
24+ useEffect ( ( ) => {
25+ if ( messagesRef . current ) {
26+ messagesRef . current . scrollTo ( {
27+ top : messagesRef . current . scrollHeight ,
28+ behavior : 'smooth' ,
29+ } ) ;
30+ }
31+ } , [ messages ] ) ;
32+
33+ const handleSendMessage = async ( ) => {
34+ try {
35+ setMessages ( ( prev ) => [
36+ ...prev ,
37+ { role : 'user' , content : bugDescription } ,
38+ { role : 'assistant' , content : '' , loading : true } ,
39+ ] ) ;
40+
41+ const body : BugFixBody = {
42+ max_tokens : parseInt ( maxToken ) ,
43+ min_tokens : parseInt ( minToken ) ,
44+ service,
45+ bug_description : bugDescription ,
46+ version,
47+ } ;
48+ const {
49+ data : { output } ,
50+ } = await mutateAsync ( body ) ;
51+ setBugDescription ( '' ) ;
52+ setMessages ( ( prev ) =>
53+ prev . map ( ( message , index ) =>
54+ index === prev . length - 1
55+ ? { ...message , content : output , loading : false }
56+ : message ,
57+ ) ,
58+ ) ;
59+ } catch ( error ) {
60+ console . log ( error ) ;
61+ setMessages ( ( prev ) => prev . slice ( 0 , - 1 ) ) ;
62+ toast . error ( 'Something went wrong' ) ;
63+ }
64+ } ;
65+
566 return (
667 < div className = "flex h-full w-full items-center justify-center" >
768 < div className = "w-full max-w-[768px]" >
@@ -13,87 +74,87 @@ const BugFix: FC = () => {
1374 </ label >
1475 < input
1576 id = "min_token"
77+ type = "number"
78+ value = { minToken }
79+ onChange = { ( e ) => setMinToken ( e . target . value ) }
1680 className = "w-full rounded-md p-3 outline-none"
1781 />
1882 </ div >
1983 < div className = "flex w-full flex-col" >
20- < label htmlFor = "min_token " className = "mb-2" >
84+ < label htmlFor = "max_token " className = "mb-2" >
2185 Max Token
2286 </ label >
2387 < input
24- id = "min_token"
88+ id = "max_token"
89+ type = "number"
90+ value = { maxToken }
91+ onChange = { ( e ) => setMaxToken ( e . target . value ) }
2592 className = "w-full rounded-md p-3 outline-none"
2693 />
2794 </ div >
2895 < div className = "flex w-full flex-col" >
29- < label htmlFor = "min_token " className = "mb-2" >
96+ < label htmlFor = "service " className = "mb-2" >
3097 Service
3198 </ label >
3299 < input
33- id = "min_token"
100+ id = "service"
101+ type = "text"
102+ value = { service }
103+ onChange = { ( e ) => setService ( e . target . value ) }
34104 className = "w-full rounded-md p-3 outline-none"
35105 />
36106 </ div >
37107 < div className = "flex w-full flex-col" >
38- < label htmlFor = "min_token " className = "mb-2" >
108+ < label htmlFor = "version " className = "mb-2" >
39109 Version
40110 </ label >
41111 < input
42- id = "min_token"
112+ id = "version"
113+ type = "text"
114+ value = { version }
115+ onChange = { ( e ) => setVersion ( e . target . value ) }
43116 className = "w-full rounded-md p-3 outline-none"
44117 />
45118 </ div >
46119 </ div >
47120 < div className = "mt-4" >
48- < div className = "scrollbar-corner-transparent scrollbar-thin scrollbar-track-transparent h-96 w-full overflow-y-auto rounded-md bg-slate-900 p-3" >
49- < div className = "chat chat-end max-w-full" >
50- < div className = "chat-bubble bg-gray-600 text-white" >
51- You underestimate my power!
52- </ div >
53- </ div >
54- < div className = "chat chat-start max-w-full" >
55- < div className = "chat-bubble text-white" >
56- You underestimate my power!
57- </ div >
58- </ div >
59- < div className = "chat chat-end max-w-full" >
60- < div className = "chat-bubble bg-gray-600 text-white" >
61- You underestimate my power!
62- </ div >
63- </ div >
64- < div className = "chat chat-start max-w-full" >
65- < div className = "chat-bubble text-white" >
66- You underestimate my power!
67- </ div >
68- </ div >
69- < div className = "chat chat-end max-w-full" >
70- < div className = "chat-bubble bg-gray-600 text-white" >
71- You underestimate my power!
72- </ div >
73- </ div >
74- < div className = "chat chat-start max-w-full" >
75- < div className = "chat-bubble text-white" >
76- You underestimate my power!
77- </ div >
78- </ div >
79- < div className = "chat chat-end max-w-full" >
80- < div className = "chat-bubble bg-gray-600 text-white" >
81- You underestimate my power!
82- </ div >
83- </ div >
84- < div className = "chat chat-start max-w-full" >
85- < div className = "chat-bubble text-white" >
86- You underestimate my power!
87- </ div >
88- </ div >
121+ < div
122+ ref = { messagesRef }
123+ className = "h-96 w-full overflow-y-auto rounded-md bg-slate-900 p-3 scrollbar-thin scrollbar-track-transparent scrollbar-corner-transparent"
124+ >
125+ { messages . map ( ( message ) =>
126+ message . role === 'user' ? (
127+ < div className = "chat chat-end max-w-full" >
128+ < div className = "chat-bubble bg-gray-600 text-white" >
129+ { message . content }
130+ </ div >
131+ </ div >
132+ ) : (
133+ < div className = "chat chat-start max-w-full" >
134+ < div className = "chat-bubble text-white" >
135+ { message . loading ? (
136+ < BeatLoader color = "#e3e3e3" size = { 10 } />
137+ ) : (
138+ message . content
139+ ) }
140+ </ div >
141+ </ div >
142+ ) ,
143+ ) }
89144 </ div >
90145 </ div >
91146 < div className = "relative mt-4" >
92147 < textarea
93- className = "w-full resize-none rounded-md p-4 pr-16 outline-none"
148+ value = { bugDescription }
149+ onChange = { ( e ) => setBugDescription ( e . target . value ) }
94150 rows = { 2 }
151+ className = "w-full resize-none rounded-md p-4 pr-16 outline-none"
95152 />
96- < button className = "absolute right-3 top-5 flex items-center justify-center rounded-full bg-white p-2" >
153+ < button
154+ disabled = { ! bugDescription }
155+ onClick = { handleSendMessage }
156+ className = "absolute right-3 top-5 flex items-center justify-center rounded-full bg-white p-2 transition-all disabled:opacity-50"
157+ >
97158 < Send className = "size-6 stroke-[#121212]" />
98159 </ button >
99160 </ div >
0 commit comments