11import React from 'react' ;
2- import { format } from 'date-fns' ;
3- import { MoreVertical , Edit2 , Trash2 , Plus } from 'lucide-react' ;
2+ // import { format } from 'date-fns';
3+ import { MoreVertical , Edit2 , Trash2 , Save , X } from 'lucide-react' ;
44import { Button } from '../ui/button' ;
55import { Input } from '../ui/input' ;
66import {
@@ -10,10 +10,14 @@ import {
1010 DropdownMenuItem ,
1111} from '../ui/dropdown-menu' ;
1212import type { Action } from '../../../types/types' ;
13+ import { format , parse } from 'date-fns' ;
1314
1415export interface ActionPreviewProps {
1516 actions : Action [ ] ;
16- onEditAction : ( actionId : string ) => void ;
17+ onEditAction : (
18+ actionId : string ,
19+ updated : { text : string ; dueDate : string }
20+ ) => void ;
1721 onDeleteAction : ( actionId : string ) => void ;
1822 onAddAction : ( newAction : { text : string ; dueDate : string } ) => void ;
1923}
@@ -24,74 +28,194 @@ const ActionPreview: React.FC<ActionPreviewProps> = ({
2428 onDeleteAction,
2529 onAddAction,
2630} ) => {
27- const [ newAction , setNewAction ] = React . useState < {
28- text : string ;
29- dueDate : string ;
30- } > ( {
31- text : '' ,
32- dueDate : '' ,
33- } ) ;
31+ // Add Action State
32+ const [ isAddingNew , setIsAddingNew ] = React . useState ( false ) ;
33+ const [ newAction , setNewAction ] = React . useState ( { text : '' , dueDate : '' } ) ;
3434
35- const handleAddAction = ( ) => {
36- if ( newAction . text && newAction . dueDate ) {
37- onAddAction ( newAction ) ;
38- setNewAction ( { text : '' , dueDate : '' } ) ;
39- }
35+ // Edit Action State
36+ const [ editingActionId , setEditingActionId ] = React . useState < string | null > (
37+ null
38+ ) ;
39+ const [ editForm , setEditForm ] = React . useState ( { text : '' , dueDate : '' } ) ;
40+
41+ // ---------------------------
42+ // ADD ACTION LOGIC
43+ // ---------------------------
44+ const handleStartAdd = ( ) => {
45+ setIsAddingNew ( true ) ;
46+ setNewAction ( { text : '' , dueDate : '' } ) ;
47+ } ;
48+
49+ const handleSaveNew = ( ) => {
50+ if ( ! newAction . text || ! newAction . dueDate ) return ;
51+ onAddAction ( newAction ) ;
52+ setIsAddingNew ( false ) ;
53+ setNewAction ( { text : '' , dueDate : '' } ) ;
54+ } ;
55+
56+ const handleCancelNew = ( ) => {
57+ setIsAddingNew ( false ) ;
58+ setNewAction ( { text : '' , dueDate : '' } ) ;
59+ } ;
60+
61+ // ---------------------------
62+ // EDIT ACTION LOGIC
63+ // ---------------------------
64+ const handleStartEdit = ( action : Action ) => {
65+ setEditingActionId ( action . id ) ;
66+ // Directly use the stored dueDate, which is assumed to be in "YYYY-MM-DD" format.
67+ setEditForm ( {
68+ text : action . text ,
69+ dueDate : action . dueDate ,
70+ } ) ;
71+ } ;
72+
73+ const handleSaveEdit = ( actionId : string ) => {
74+ if ( ! editForm . text || ! editForm . dueDate ) return ;
75+ onEditAction ( actionId , { text : editForm . text , dueDate : editForm . dueDate } ) ;
76+ setEditingActionId ( null ) ;
77+ setEditForm ( { text : '' , dueDate : '' } ) ;
78+ } ;
79+
80+ const handleCancelEdit = ( ) => {
81+ setEditingActionId ( null ) ;
82+ setEditForm ( { text : '' , dueDate : '' } ) ;
4083 } ;
4184
4285 return (
43- < div className = 'space-y-2 mt-4' >
44- { actions . map ( ( action ) => (
45- < div
46- key = { action . id }
47- className = 'bg-gray-50 p-3 rounded-lg flex items-center justify-between'
48- >
49- < div >
50- < p > { action . text } </ p >
51- < p className = 'text-sm text-gray-500 mt-1' >
52- Due: { format ( new Date ( action . dueDate ) , 'PP' ) }
53- </ p >
54- </ div >
55- < DropdownMenu >
56- < DropdownMenuTrigger asChild >
57- < Button variant = 'ghost' size = 'icon' >
58- < MoreVertical size = { 18 } className = 'text-gray-500' />
86+ < div className = 'space-y-2' >
87+ { actions . map ( ( action ) => {
88+ const isEditing = editingActionId === action . id ;
89+
90+ if ( ! isEditing ) {
91+ // Normal (read-only) view
92+ // Since dueDate is already in "YYYY-MM-DD", we can display it directly or format it if needed.
93+ return (
94+ < div
95+ key = { action . id }
96+ className = 'flex items-center justify-between bg-gray-50 p-2 rounded'
97+ >
98+ < span className = 'flex-1' > { action . text } </ span >
99+ < span className = 'mx-4 text-sm text-gray-500' >
100+ Due:{ ' ' }
101+ { action . dueDate
102+ ? format (
103+ parse ( action . dueDate , 'yyyy-MM-dd' , new Date ( ) ) ,
104+ 'dd/MM/yyyy'
105+ )
106+ : 'No due date' }
107+ </ span >
108+
109+ < DropdownMenu >
110+ < DropdownMenuTrigger asChild >
111+ < button onClick = { ( e ) => e . stopPropagation ( ) } >
112+ < MoreVertical size = { 18 } className = 'text-gray-500' />
113+ </ button >
114+ </ DropdownMenuTrigger >
115+ < DropdownMenuContent align = 'end' >
116+ < DropdownMenuItem onClick = { ( ) => handleStartEdit ( action ) } >
117+ < Edit2 className = 'mr-2 h-4 w-4' />
118+ Edit
119+ </ DropdownMenuItem >
120+ < DropdownMenuItem
121+ onClick = { ( ) => onDeleteAction ( action . id ) }
122+ className = 'text-red-600'
123+ >
124+ < Trash2 className = 'mr-2 h-4 w-4' />
125+ Delete
126+ </ DropdownMenuItem >
127+ </ DropdownMenuContent >
128+ </ DropdownMenu >
129+ </ div >
130+ ) ;
131+ } else {
132+ // Editing this action
133+ return (
134+ < div
135+ key = { action . id }
136+ className = 'flex items-center bg-gray-50 p-2 rounded space-x-2'
137+ >
138+ < Input
139+ placeholder = 'Action text'
140+ value = { editForm . text }
141+ onChange = { ( e ) =>
142+ setEditForm ( { ...editForm , text : e . target . value } )
143+ }
144+ className = 'flex-1'
145+ />
146+ < Input
147+ type = 'date'
148+ value = { editForm . dueDate }
149+ onChange = { ( e ) =>
150+ setEditForm ( { ...editForm , dueDate : e . target . value } )
151+ }
152+ className = 'w-36'
153+ />
154+ < Button
155+ variant = 'ghost'
156+ size = 'sm'
157+ onClick = { ( ) => handleSaveEdit ( action . id ) }
158+ className = 'text-green-500 hover:text-green-700'
159+ >
160+ < Save size = { 16 } />
59161 </ Button >
60- </ DropdownMenuTrigger >
61- < DropdownMenuContent align = 'end' >
62- < DropdownMenuItem onClick = { ( ) => onEditAction ( action . id ) } >
63- < Edit2 className = 'mr-2 h-4 w-4' />
64- Edit
65- </ DropdownMenuItem >
66- < DropdownMenuItem
67- onClick = { ( ) => onDeleteAction ( action . id ) }
68- className = 'text-red-600'
162+ < Button
163+ variant = 'ghost'
164+ size = 'sm'
165+ onClick = { handleCancelEdit }
166+ className = 'text-gray-500 hover:text-gray-700'
69167 >
70- < Trash2 className = 'mr-2 h-4 w-4' />
71- Delete
72- </ DropdownMenuItem >
73- </ DropdownMenuContent >
74- </ DropdownMenu >
168+ < X size = { 16 } />
169+ </ Button >
170+ </ div >
171+ ) ;
172+ }
173+ } ) }
174+
175+ { /* Add Action row or inline form */ }
176+ { ! isAddingNew ? (
177+ < div
178+ className = 'flex items-center justify-between bg-gray-50 p-2 rounded cursor-pointer hover:bg-gray-100'
179+ onClick = { handleStartAdd }
180+ >
181+ < span className = 'flex-1' > + Add Action</ span >
182+ </ div >
183+ ) : (
184+ < div className = 'flex items-center bg-gray-50 p-2 rounded space-x-2' >
185+ < Input
186+ placeholder = 'Action text'
187+ value = { newAction . text }
188+ onChange = { ( e ) =>
189+ setNewAction ( { ...newAction , text : e . target . value } )
190+ }
191+ className = 'flex-1'
192+ />
193+ < Input
194+ type = 'date'
195+ value = { newAction . dueDate }
196+ onChange = { ( e ) =>
197+ setNewAction ( { ...newAction , dueDate : e . target . value } )
198+ }
199+ className = 'w-36'
200+ />
201+ < Button
202+ variant = 'ghost'
203+ size = 'sm'
204+ onClick = { handleSaveNew }
205+ className = 'text-green-500 hover:text-green-700'
206+ >
207+ < Save size = { 16 } />
208+ </ Button >
209+ < Button
210+ variant = 'ghost'
211+ size = 'sm'
212+ onClick = { handleCancelNew }
213+ className = 'text-gray-500 hover:text-gray-700'
214+ >
215+ < X size = { 16 } />
216+ </ Button >
75217 </ div >
76- ) ) }
77- < div className = 'space-y-2 pt-4 border-t' >
78- < Input
79- placeholder = 'New action'
80- value = { newAction . text }
81- onChange = { ( e ) => setNewAction ( { ...newAction , text : e . target . value } ) }
82- />
83- < Input
84- type = 'date'
85- value = { newAction . dueDate }
86- onChange = { ( e ) =>
87- setNewAction ( { ...newAction , dueDate : e . target . value } )
88- }
89- />
90- < Button onClick = { handleAddAction } className = 'w-full' >
91- < Plus className = 'w-4 h-4 mr-2' />
92- Add Action
93- </ Button >
94- </ div >
218+ ) }
95219 </ div >
96220 ) ;
97221} ;
0 commit comments