11import React from 'react' ;
2- // import { format } from 'date-fns';
3- import { MoreVertical , Edit2 , Trash2 , Save , X } from 'lucide-react' ;
4- import { Button } from '../ui/button' ;
5- import { Input } from '../ui/input' ;
2+ import { format , parse } from 'date-fns' ;
3+ import { MoreVertical , Edit2 , Trash2 } from 'lucide-react' ;
64import {
75 DropdownMenu ,
86 DropdownMenuTrigger ,
97 DropdownMenuContent ,
108 DropdownMenuItem ,
119} from '../ui/dropdown-menu' ;
10+ import ActionForm from './ActionForm' ;
1211import type { Action } from '../../../types/types' ;
13- import { format , parse } from 'date-fns' ;
1412
1513export interface ActionPreviewProps {
1614 actions : Action [ ] ;
@@ -28,84 +26,64 @@ const ActionPreview: React.FC<ActionPreviewProps> = ({
2826 onDeleteAction,
2927 onAddAction,
3028} ) => {
31- // Add Action State
32- const [ isAddingNew , setIsAddingNew ] = React . useState ( false ) ;
33- const [ newAction , setNewAction ] = React . useState ( { text : '' , dueDate : '' } ) ;
34-
35- // Edit Action State
29+ // State to track which action is being edited.
3630 const [ editingActionId , setEditingActionId ] = React . useState < string | null > (
3731 null
3832 ) ;
39- const [ editForm , setEditForm ] = React . useState ( { text : '' , dueDate : '' } ) ;
33+ // State to control whether we're adding a new action.
34+ const [ isAddingNew , setIsAddingNew ] = React . useState ( false ) ;
4035
41- // ---------------------------
42- // ADD ACTION LOGIC
43- // ---------------------------
44- const handleStartAdd = ( ) => {
45- setIsAddingNew ( true ) ;
46- setNewAction ( { text : '' , dueDate : '' } ) ;
36+ // --- Handlers for Editing ---
37+ const handleStartEdit = ( action : Action ) => {
38+ setEditingActionId ( action . id ) ;
4739 } ;
4840
49- const handleSaveNew = ( ) => {
50- if ( ! newAction . text || ! newAction . dueDate ) return ;
51- onAddAction ( newAction ) ;
52- setIsAddingNew ( false ) ;
53- setNewAction ( { text : '' , dueDate : '' } ) ;
41+ const handleSaveEdit = (
42+ actionId : string ,
43+ data : { text : string ; dueDate : string }
44+ ) => {
45+ onEditAction ( actionId , data ) ;
46+ setEditingActionId ( null ) ;
5447 } ;
5548
56- const handleCancelNew = ( ) => {
57- setIsAddingNew ( false ) ;
58- setNewAction ( { text : '' , dueDate : '' } ) ;
49+ const handleCancelEdit = ( ) => {
50+ setEditingActionId ( null ) ;
5951 } ;
6052
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- } ) ;
53+ // --- Handlers for Adding New Action ---
54+ const handleStartAdd = ( ) => {
55+ setIsAddingNew ( true ) ;
7156 } ;
7257
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 : '' } ) ;
58+ const handleSaveNew = ( data : { text : string ; dueDate : string } ) => {
59+ onAddAction ( data ) ;
60+ setIsAddingNew ( false ) ;
7861 } ;
7962
80- const handleCancelEdit = ( ) => {
81- setEditingActionId ( null ) ;
82- setEditForm ( { text : '' , dueDate : '' } ) ;
63+ const handleCancelNew = ( ) => {
64+ setIsAddingNew ( false ) ;
8365 } ;
8466
8567 return (
8668 < div className = 'space-y-2' >
8769 { actions . map ( ( action ) => {
8870 const isEditing = editingActionId === action . id ;
89-
9071 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.
72+ // Read-only view for an action.
73+ // Parse stored "yyyy-MM-dd" into a Date object, then format as "dd/MM/yyyy"
74+ const dueDateObj = parse ( action . dueDate , 'yyyy-MM-dd' , new Date ( ) ) ;
75+ const dueDateText = ! isNaN ( dueDateObj . getTime ( ) )
76+ ? format ( dueDateObj , 'dd/MM/yyyy' )
77+ : 'No due date' ;
9378 return (
9479 < div
9580 key = { action . id }
9681 className = 'flex items-center justify-between bg-gray-50 p-2 rounded'
9782 >
9883 < span className = 'flex-1' > { action . text } </ span >
9984 < 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' }
85+ Due: { dueDateText }
10786 </ span >
108-
10987 < DropdownMenu >
11088 < DropdownMenuTrigger asChild >
11189 < button onClick = { ( e ) => e . stopPropagation ( ) } >
@@ -129,50 +107,20 @@ const ActionPreview: React.FC<ActionPreviewProps> = ({
129107 </ div >
130108 ) ;
131109 } else {
132- // Editing this action
110+ // Editing mode: use the ActionForm prefilled with the action data.
133111 return (
134- < div
112+ < ActionForm
135113 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 } />
161- </ Button >
162- < Button
163- variant = 'ghost'
164- size = 'sm'
165- onClick = { handleCancelEdit }
166- className = 'text-gray-500 hover:text-gray-700'
167- >
168- < X size = { 16 } />
169- </ Button >
170- </ div >
114+ initialText = { action . text }
115+ initialDueDate = { action . dueDate }
116+ onSave = { ( data ) => handleSaveEdit ( action . id , data ) }
117+ onCancel = { handleCancelEdit }
118+ />
171119 ) ;
172120 }
173121 } ) }
174122
175- { /* Add Action row or inline form */ }
123+ { /* Add new action: either show the "+ Add Action" row or the inline form */ }
176124 { ! isAddingNew ? (
177125 < div
178126 className = 'flex items-center justify-between bg-gray-50 p-2 rounded cursor-pointer hover:bg-gray-100'
@@ -181,40 +129,7 @@ const ActionPreview: React.FC<ActionPreviewProps> = ({
181129 < span className = 'flex-1' > + Add Action</ span >
182130 </ div >
183131 ) : (
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 >
217- </ div >
132+ < ActionForm onSave = { handleSaveNew } onCancel = { handleCancelNew } />
218133 ) }
219134 </ div >
220135 ) ;
0 commit comments