11import { useState } from 'react' ;
22import { api , ApiError } from '../../services' ;
3+ import { calculateDiff } from '../../utils' ;
34import { Button } from './Button' ;
5+ import { DiffDisplay } from './DiffDisplay' ;
46import { LoadingSpinner } from './LoadingSpinner' ;
57import { ErrorAlert } from './ErrorAlert' ;
68
@@ -65,46 +67,7 @@ export function AIEditingDialog({
6567 }
6668 } ;
6769
68- // Calculate diff for display
69- const originalLines = originalContent . split ( '\n' ) ;
70- const newLines = editedContent ?. split ( '\n' ) || [ ] ;
71-
72- const calculateLCS = ( arr1 : string [ ] , arr2 : string [ ] ) => {
73- const m = arr1 . length ;
74- const n = arr2 . length ;
75- const dp : number [ ] [ ] = Array ( m + 1 ) . fill ( 0 ) . map ( ( ) => Array ( n + 1 ) . fill ( 0 ) as number [ ] ) ;
76-
77- for ( let i = 1 ; i <= m ; i ++ ) {
78- for ( let j = 1 ; j <= n ; j ++ ) {
79- if ( arr1 [ i - 1 ] === arr2 [ j - 1 ] ) {
80- dp [ i ] [ j ] = dp [ i - 1 ] [ j - 1 ] + 1 ;
81- } else {
82- dp [ i ] [ j ] = Math . max ( dp [ i - 1 ] [ j ] , dp [ i ] [ j - 1 ] ) ;
83- }
84- }
85- }
86-
87- const result : { type : string ; content : string ; oldLine : number | null ; newLine : number | null } [ ] = [ ] ;
88- let i = m , j = n ;
89-
90- while ( i > 0 || j > 0 ) {
91- if ( i > 0 && j > 0 && arr1 [ i - 1 ] === arr2 [ j - 1 ] ) {
92- result . unshift ( { type : 'unchanged' , content : arr1 [ i - 1 ] , oldLine : i , newLine : j } ) ;
93- i -- ;
94- j -- ;
95- } else if ( j > 0 && ( i === 0 || dp [ i ] [ j - 1 ] >= dp [ i - 1 ] [ j ] ) ) {
96- result . unshift ( { type : 'added' , content : arr2 [ j - 1 ] , oldLine : null , newLine : j } ) ;
97- j -- ;
98- } else if ( i > 0 ) {
99- result . unshift ( { type : 'deleted' , content : arr1 [ i - 1 ] , oldLine : i , newLine : null } ) ;
100- i -- ;
101- }
102- }
103-
104- return result ;
105- } ;
106-
107- const diffLines = editedContent !== null ? calculateLCS ( originalLines , newLines ) : [ ] ;
70+ const diffLines = editedContent !== null ? calculateDiff ( originalContent , editedContent ) : [ ] ;
10871
10972 return (
11073 < div className = "fixed inset-0 bg-black bg-opacity-30 overflow-y-auto h-full w-full z-50" >
@@ -113,9 +76,7 @@ export function AIEditingDialog({
11376 { /* Header */ }
11477 < div className = "mb-4" >
11578 < h3 className = "text-lg font-medium text-black" > AI Editing</ h3 >
116- < p className = "mt-1 text-sm text-gray-500" >
117- Use AI to proofread and improve your content
118- </ p >
79+ < p className = "mt-1 text-sm text-gray-500" > Use AI to proofread and improve your content</ p >
11980 </ div >
12081
12182 { /* Mode Selection */ }
@@ -168,58 +129,17 @@ export function AIEditingDialog({
168129 { /* Diff Display */ }
169130 { editedContent !== null && ! isLoading && (
170131 < div className = "mb-4 flex-1 overflow-hidden" >
171- < label className = "block text-sm font-medium text-black mb-2" >
172- Changes Preview
173- </ label >
174- < div className = "bg-gray-50 border border-gray-200 p-4 overflow-y-auto overflow-x-auto max-h-96" >
175- < div className = "grid grid-cols-12 gap-0 text-xs font-mono min-w-max" >
176- < div className = "col-span-1 text-gray-500 font-medium" > Line</ div >
177- < div className = "col-span-11 text-gray-500 font-medium" > Content</ div >
178- </ div >
179-
180- { diffLines . map ( ( line , index ) => (
181- < div
182- key = { index }
183- className = { `grid grid-cols-12 gap-0 text-xs font-mono py-1 min-w-max ${
184- line . type === 'added'
185- ? 'bg-green-50 text-green-700'
186- : line . type === 'deleted'
187- ? 'bg-red-50 text-red-700'
188- : 'text-black'
189- } `}
190- >
191- < div className = "col-span-1 text-gray-400" >
192- { line . type === 'deleted' ? line . oldLine : line . type === 'added' ? line . newLine : line . oldLine }
193- </ div >
194- < div className = "col-span-11 whitespace-pre-wrap break-words overflow-hidden" >
195- < span className = "inline-block w-4" >
196- { line . type === 'added' && < span className = "text-green-600" > +</ span > }
197- { line . type === 'deleted' && < span className = "text-red-600" > -</ span > }
198- { line . type === 'unchanged' && < span className = "text-gray-300" > </ span > }
199- </ span >
200- { line . content || < span className = "text-gray-400" > (empty line)</ span > }
201- </ div >
202- </ div >
203- ) ) }
204- </ div >
132+ < label className = "block text-sm font-medium text-black mb-2" > Changes Preview</ label >
133+ < DiffDisplay diffLines = { diffLines } />
205134 </ div >
206135 ) }
207136
208137 { /* Actions */ }
209138 < div className = "flex justify-end space-x-3 pt-4 border-t border-gray-200" >
210- < Button
211- type = "button"
212- variant = "secondary"
213- onClick = { onClose }
214- disabled = { isLoading }
215- >
139+ < Button type = "button" variant = "secondary" onClick = { onClose } disabled = { isLoading } >
216140 Cancel
217141 </ Button >
218- < Button
219- type = "button"
220- onClick = { handleApply }
221- disabled = { isLoading || editedContent === null }
222- >
142+ < Button type = "button" onClick = { handleApply } disabled = { isLoading || editedContent === null } >
223143 Apply Changes
224144 </ Button >
225145 </ div >
0 commit comments