1- import React , { useState } from 'react' ;
2- import { Trash2 , Copy , Sparkles , ArrowDownUp , Upload , Download } from 'lucide-react' ;
1+ import React from 'react' ;
2+ import { Trash2 , Copy , Sparkles } from 'lucide-react' ;
33import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from './ui/select' ;
44import { decodePolyline } from '../utils/polylineDecoder' ;
5- import { cn } from '../lib/utils' ;
6- import { Switch } from './ui/switch' ;
7- import { Info } from 'lucide-react' ;
85
96interface PolylineInputProps {
107 value : string ;
118 onChange : ( value : string ) => void ;
129 onClear : ( ) => void ;
1310 precision ?: number ;
1411 onPrecisionChange ?: ( precision : number ) => void ;
15- mode ?: 'decode' | 'encode' ;
16- onModeChange ?: ( ) => void ;
17- isEncoding ?: boolean ;
18- onCoordinatesInput ?: ( text : string ) => void ;
1912}
2013
2114const PolylineInput : React . FC < PolylineInputProps > = ( {
@@ -24,61 +17,31 @@ const PolylineInput: React.FC<PolylineInputProps> = ({
2417 onClear,
2518 precision = 5 ,
2619 onPrecisionChange,
27- mode = 'decode' ,
28- onModeChange,
29- isEncoding = false ,
30- onCoordinatesInput,
3120} ) => {
32- const [ coordinatesText , setCoordinatesText ] = useState ( '' ) ;
33-
3421 const handlePaste = async ( ) => {
3522 try {
3623 const text = await navigator . clipboard . readText ( ) ;
37- if ( mode === 'decode' ) {
38- onChange ( text ) ;
39- } else {
40- setCoordinatesText ( text ) ;
41- }
24+ onChange ( text ) ;
4225 } catch ( err ) {
4326 console . error ( 'Failed to read clipboard contents: ' , err ) ;
4427 }
4528 } ;
4629
47- const handleCoordinatesSubmit = ( ) => {
48- if ( onCoordinatesInput && coordinatesText ) {
49- onCoordinatesInput ( coordinatesText ) ;
50- }
51- } ;
52-
5330 const primaryCoordinates = value ? decodePolyline ( value , precision ) : [ ] ;
5431
55- const isEmpty = mode === 'decode' ? ! value : ! coordinatesText ;
56-
5732 return (
5833 < div className = "panel" >
5934 < div className = "mb-3 flex items-center justify-between" >
60- < div className = "flex items-center space-x-2" >
61- < span className = "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary" >
62- { mode === 'decode' ? 'Decode' : 'Encode' }
63- </ span >
64- < div className = "hidden items-center text-xs text-muted-foreground sm:flex" >
65- < Info className = "mr-1 h-3 w-3" />
66- < span > { mode === 'decode' ? 'Polyline → Coordinates' : 'Coordinates → Polyline' } </ span >
67- </ div >
68- </ div >
35+ < span className = "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary" >
36+ Polyline
37+ </ span >
38+ < span className = "text-xs text-muted-foreground" >
39+ Paste encoded polyline or draw on map
40+ </ span >
6941 </ div >
7042
7143 < div className = "mb-2 flex items-center justify-between" >
72- < div className = "flex items-center space-x-2" >
73- { onModeChange && (
74- < div className = "flex items-center space-x-2" >
75- < div className = "flex items-center space-x-1" >
76- < Switch checked = { mode === 'encode' } onCheckedChange = { onModeChange } />
77- < ArrowDownUp className = "h-3 w-3 text-muted-foreground" />
78- </ div >
79- </ div >
80- ) }
81- </ div >
44+ < div />
8245 < div className = "flex items-center space-x-1" >
8346 { onPrecisionChange && (
8447 < Select
@@ -104,73 +67,46 @@ const PolylineInput: React.FC<PolylineInputProps> = ({
10467 < button
10568 onClick = { onClear }
10669 className = "rounded-md p-1.5 text-muted-foreground transition-colors hover:text-destructive"
107- disabled = { ! value && ! coordinatesText }
70+ disabled = { ! value }
10871 >
10972 < Trash2 className = "h-4 w-4" />
11073 </ button >
11174 </ div >
11275 </ div >
11376
114- { mode === 'decode' ? (
115- < textarea
116- value = { value }
117- onChange = { e => onChange ( e . target . value ) }
118- placeholder = "Paste your encoded polyline here..."
119- className = "h-24 w-full resize-none border-0 bg-transparent p-0 font-mono text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-0"
120- />
121- ) : (
122- < textarea
123- value = { coordinatesText }
124- onChange = { e => setCoordinatesText ( e . target . value ) }
125- placeholder = "Paste your coordinates here (format: longitude,latitude or one coordinate per line)..."
126- className = "h-24 w-full resize-none border-0 bg-transparent p-0 font-mono text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-0"
127- />
128- ) }
77+ < textarea
78+ value = { value }
79+ onChange = { e => onChange ( e . target . value ) }
80+ placeholder = "Paste your encoded polyline here or use edit mode to draw on the map..."
81+ className = "h-24 w-full resize-none border-0 bg-transparent p-0 font-mono text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-0"
82+ />
12983
13084 < div className = "mt-2 flex items-center justify-between" >
13185 < div className = "text-xs text-muted-foreground" >
132- { mode === 'decode'
133- ? value
134- ? `${ value . length } characters, ${ primaryCoordinates . length } points`
135- : 'No polyline data'
136- : value
137- ? `Encoded polyline (${ value . length } chars)`
138- : 'No encoded result yet' }
86+ { value
87+ ? `${ value . length } characters, ${ primaryCoordinates . length } points`
88+ : 'No polyline data' }
13989 </ div >
14090 < div className = "flex space-x-1" >
141- { mode === 'encode' ? (
142- < button
143- onClick = { handleCoordinatesSubmit }
144- disabled = { ! coordinatesText || isEncoding }
145- className = "flex items-center space-x-1 rounded-md bg-primary p-1.5 text-xs text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50"
146- >
147- < Upload className = "mr-1 h-3 w-3" />
148- < span > { isEncoding ? 'Encoding...' : 'Encode' } </ span >
149- </ button >
150- ) : null }
151- { value ? (
91+ { value && (
15292 < button
15393 onClick = { ( ) => navigator . clipboard . writeText ( value ) }
15494 className = "flex items-center space-x-1 rounded-md bg-secondary p-1.5 text-xs transition-colors hover:bg-secondary/80"
15595 >
15696 < Copy className = "mr-1 h-3 w-3" />
15797 < span > Copy</ span >
15898 </ button >
159- ) : null }
99+ ) }
160100 < button
161101 onClick = { ( ) => {
162- if ( mode === 'decode' ) {
163- onChange (
164- '}~kvHmzrr@ba\\hnc@jiu@r{Zqx~@hjp@pwEhnc@zhu@zflAbxn@fhjBvqHroaAgcnAp}gAeahAtqGkngAinc@_h|@r{Zad\\y|_D}_y@swg@ysg@}llBpoZqa{@xrw@~eBaaX}{uAero@uqGadY}nr@`dYs_NquNgbjAf{l@|yh@bfc@}nr@z}q@i|i@zgz@r{ZhjFr}gApob@ff}@laIsen@dgYhdPvbIren@'
165- ) ;
166- } else {
167- setCoordinatesText ( '-122.4194,37.7749\n-122.4099,37.7912\n-122.4330,37.7866' ) ;
168- }
102+ onChange (
103+ '}~kvHmzrr@ba\\hnc@jiu@r{Zqx~@hjp@pwEhnc@zhu@zflAbxn@fhjBvqHroaAgcnAp}gAeahAtqGkngAinc@_h|@r{Zad\\y|_D}_y@swg@ysg@}llBpoZqa{@xrw@~eBaaX}{uAero@uqGadY}nr@`dYs_NquNgbjAf{l@|yh@bfc@}nr@z}q@i|i@zgz@r{ZhjFr}gApob@ff}@laIsen@dgYhdPvbIren@'
104+ ) ;
169105 } }
170106 className = "flex items-center space-x-1 rounded-md bg-primary/10 p-1.5 text-xs text-primary transition-colors hover:bg-primary/20"
171107 >
172- < Sparkles className = { cn ( ' h-3 w-3' , isEmpty && 'mr-1' ) } />
173- { isEmpty ? < span > Sample</ span > : null }
108+ < Sparkles className = { ` h-3 w-3 ${ ! value ? 'mr-1' : '' } ` } />
109+ { ! value && < span > Sample</ span > }
174110 </ button >
175111 </ div >
176112 </ div >
0 commit comments