1
1
"use client" ;
2
- import React , { useEffect , useRef } from "react" ;
2
+ import React , { useEffect , useRef , useState } from "react" ;
3
3
import Drawer from "./ui/Drawer" ;
4
4
import { Button } from "./ui/Button" ;
5
5
import ReactQuill from "react-quill" ;
6
- import { BookTextIcon } from "lucide-react" ;
6
+ import { BookTextIcon , Check , Loader2 , X } from "lucide-react" ;
7
+ import { Textarea } from "./ui/Textarea" ;
8
+ import { draft_with_ai } from "@/services/chat" ;
9
+ import toast from "react-hot-toast" ;
7
10
8
11
interface IProps {
9
12
draft : string ;
@@ -48,6 +51,10 @@ const ChatDraftDrawer = ({
48
51
onCancel,
49
52
} : IProps ) => {
50
53
const quillRef = useRef < ReactQuill | null > ( null ) ;
54
+ const [ step , setStep ] = useState < number > ( 0 ) ;
55
+ const [ userInput , setUserInput ] = useState < string > ( "" ) ;
56
+ const [ aiDraft , setAIDraft ] = useState < string > ( "" ) ;
57
+ const [ loadingAIDraft , setLoadingAIDraft ] = useState < boolean > ( false ) ;
51
58
52
59
useEffect ( ( ) => {
53
60
if ( quillRef . current ) {
@@ -59,28 +66,131 @@ const ChatDraftDrawer = ({
59
66
}
60
67
} , [ draft ] ) ;
61
68
69
+ const handleUserInputChange = (
70
+ event : React . ChangeEvent < HTMLTextAreaElement >
71
+ ) => {
72
+ setUserInput ( event . target . value ) ;
73
+ } ;
74
+
75
+ const handleUserInputKeyPress = async (
76
+ event : React . KeyboardEvent < HTMLTextAreaElement >
77
+ ) => {
78
+ if ( event . key === "Enter" && userInput . trim ( ) !== "" ) {
79
+ event . preventDefault ( ) ;
80
+ try {
81
+ if ( userInput . length === 0 ) {
82
+ toast . error ( "Please provide the prompt and try again!" ) ;
83
+ return ;
84
+ }
85
+ setLoadingAIDraft ( true ) ;
86
+ const data = await draft_with_ai ( { content : draft , prompt : userInput } ) ;
87
+ setAIDraft ( data . response ) ;
88
+ setUserInput ( "" ) ;
89
+ setStep ( 2 ) ;
90
+ setLoadingAIDraft ( false ) ;
91
+ } catch ( error ) {
92
+ console . error ( error ) ;
93
+ toast . error ( "Failed to draft with AI. Try again!" ) ;
94
+ setLoadingAIDraft ( false ) ;
95
+ }
96
+ }
97
+ } ;
98
+
62
99
return (
63
100
< Drawer isOpen = { isOpen } onClose = { onCancel } title = "Draft Chat" >
64
101
< div className = "flex flex-col h-full" >
65
- < ReactQuill
66
- ref = { quillRef }
67
- theme = "snow"
68
- value = { draft }
69
- onChange = { onSubmit }
70
- modules = { quill_modules }
71
- formats = { quill_formats }
72
- />
73
- < div className = "sticky bottom-0 bg-white pb-4" >
74
- < div className = "flex gap-2" >
75
- < Button
76
- // onClick={onSubmit}
77
- className = "mt-4 px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark"
78
- >
79
- < BookTextIcon className = "inline-block mr-2" size = { 16 } />
80
- Rewrite with AI
81
- </ Button >
102
+ { ( step === 0 || step === 1 ) && (
103
+ < >
104
+ < ReactQuill
105
+ ref = { quillRef }
106
+ theme = "snow"
107
+ value = { draft }
108
+ onChange = { onSubmit }
109
+ modules = { quill_modules }
110
+ formats = { quill_formats }
111
+ />
112
+
113
+ < div className = "sticky bottom-0 bg-white pb-4 pt-4" >
114
+ < Button
115
+ onClick = { ( ) => {
116
+ setStep ( 1 ) ;
117
+ } }
118
+ disabled = { draft . length == 0 }
119
+ className = "px-4 bg-primary text-white rounded hover:bg-primary-dark"
120
+ >
121
+ < BookTextIcon className = "inline-block mr-2" size = { 16 } />
122
+ Rewrite with AI
123
+ </ Button >
124
+ </ div >
125
+ </ >
126
+ ) }
127
+
128
+ { step === 2 && (
129
+ < >
130
+ < ReactQuill
131
+ ref = { quillRef }
132
+ theme = "snow"
133
+ value = { aiDraft }
134
+ readOnly = { true }
135
+ modules = { { toolbar : false } }
136
+ />
137
+
138
+ < div className = "sticky bottom-0 bg-white pb-4" >
139
+ < div className = "flex gap-2" >
140
+ < Button
141
+ onClick = { ( ) => setStep ( 0 ) }
142
+ className = "mt-4 px-4 py-2 bg-red-600 text-white rounded hover:bg-red-800"
143
+ >
144
+ < X className = "inline-block mr-2" size = { 16 } />
145
+ Cancel
146
+ </ Button >
147
+ < Button
148
+ onClick = { ( ) => {
149
+ onSubmit ( aiDraft ) ;
150
+ setStep ( 0 ) ;
151
+ } }
152
+ className = "mt-4 px-4 py-2 bg-green-600 text-white rounded hover:bg-green-800"
153
+ >
154
+ < Check className = "inline-block mr-2" size = { 16 } />
155
+ Accept
156
+ </ Button >
157
+ < Button
158
+ onClick = { ( ) => setStep ( 1 ) }
159
+ className = "mt-4 px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark"
160
+ >
161
+ < BookTextIcon className = "inline-block mr-2" size = { 16 } />
162
+ Rewrite
163
+ </ Button >
164
+ </ div >
165
+ </ div >
166
+ </ >
167
+ ) }
168
+ { /* Centered overlay input for step 1 */ }
169
+ { step === 1 && (
170
+ < div className = "absolute inset-0 flex items-center justify-center z-50 bg-opacity-75 bg-gray-800" >
171
+ < div className = "bg-white p-6 rounded-lg shadow-lg max-w-lg w-full text-center" >
172
+ { loadingAIDraft ? (
173
+ < Loader2 className = "mx-auto my-4 h-8 w-8 animate-spin text-gray-500" />
174
+ ) : (
175
+ < >
176
+ < Textarea
177
+ className = "w-full p-2 border border-gray-300 rounded mb-4"
178
+ placeholder = "Write prompt to edit content and press enter..."
179
+ value = { userInput }
180
+ onChange = { handleUserInputChange }
181
+ onKeyDown = { handleUserInputKeyPress }
182
+ />
183
+ < Button
184
+ onClick = { ( ) => setStep ( 0 ) }
185
+ className = "text-sm text-gray-500 hover:text-gray-700"
186
+ >
187
+ Close
188
+ </ Button >
189
+ </ >
190
+ ) }
191
+ </ div >
82
192
</ div >
83
- </ div >
193
+ ) }
84
194
</ div >
85
195
</ Drawer >
86
196
) ;
0 commit comments