1+ import { useState , useEffect } from "react" ;
2+ import { Button } from "@/components/ui/button" ;
3+ import {
4+ Dialog ,
5+ DialogContent ,
6+ DialogDescription ,
7+ DialogHeader ,
8+ DialogTitle ,
9+ DialogFooter ,
10+ } from "@/components/ui/dialog" ;
11+ import { Input } from "@/components/ui/input" ;
12+ import { Label } from "@/components/ui/label" ;
13+ import { Textarea } from "@/components/ui/textarea" ;
14+ import { Checkbox } from "@/components/ui/checkbox" ;
15+ import {
16+ Select ,
17+ SelectContent ,
18+ SelectItem ,
19+ SelectTrigger ,
20+ SelectValue ,
21+ } from "@/components/ui/select" ;
22+ import { TimelineEntryData } from "./TimelineEntry" ;
23+ import { format , parse } from "date-fns" ;
24+
25+ interface EditEntryDialogProps {
26+ entry : TimelineEntryData ;
27+ isOpen : boolean ;
28+ onClose : ( ) => void ;
29+ onUpdate : ( entry : TimelineEntryData ) => void ;
30+ onRemove : ( id : string ) => void ;
31+ }
32+
33+ export function EditEntryDialog ( { entry, isOpen, onClose, onUpdate, onRemove } : EditEntryDialogProps ) {
34+ const [ type , setType ] = useState < TimelineEntryData [ "type" ] > ( entry . type ) ;
35+ const [ title , setTitle ] = useState ( entry . title ) ;
36+ const [ description , setDescription ] = useState ( entry . description ) ;
37+ const [ date , setDate ] = useState ( entry . date ) ;
38+ const [ time , setTime ] = useState ( ( ) => format ( parse ( entry . time , "hh:mm a" , new Date ( ) ) , "HH:mm" ) ) ;
39+ const [ provider , setProvider ] = useState ( entry . provider || "" ) ;
40+ const [ recurring , setRecurring ] = useState ( ! ! entry . recurring ) ;
41+ const [ recurrence , setRecurrence ] = useState < TimelineEntryData [ 'recurring' ] > ( entry . recurring || 'daily' ) ;
42+
43+ useEffect ( ( ) => {
44+ if ( isOpen ) {
45+ setType ( entry . type ) ;
46+ setTitle ( entry . title ) ;
47+ setDescription ( entry . description ) ;
48+ setDate ( entry . date ) ;
49+ setTime ( format ( parse ( entry . time , "hh:mm a" , new Date ( ) ) , "HH:mm" ) ) ;
50+ setProvider ( entry . provider || "" ) ;
51+ setRecurring ( ! ! entry . recurring ) ;
52+ setRecurrence ( entry . recurring || 'daily' ) ;
53+ }
54+ } , [ entry , isOpen ] ) ;
55+
56+ const handleUpdate = ( e : React . FormEvent ) => {
57+ e . preventDefault ( ) ;
58+ if ( ! title || ! description || ! date || ! time ) return ;
59+
60+ const [ hours , minutes ] = time . split ( ":" ) ;
61+ const hoursNum = parseInt ( hours , 10 ) ;
62+ const ampm = hoursNum >= 12 ? "PM" : "AM" ;
63+ const formattedHours = hoursNum % 12 || 12 ;
64+ const formattedTime = `${ String ( formattedHours ) . padStart ( 2 , '0' ) } :${ minutes } ${ ampm } ` ;
65+
66+ onUpdate ( {
67+ ...entry ,
68+ type,
69+ title,
70+ description,
71+ time : formattedTime ,
72+ provider : provider || undefined ,
73+ date : date ,
74+ recurring : recurring ? recurrence : undefined ,
75+ } ) ;
76+ } ;
77+
78+ const handleDelete = ( ) => {
79+ if ( window . confirm ( "Are you sure you want to delete this entry?" ) ) {
80+ onRemove ( entry . id ) ;
81+ onClose ( ) ;
82+ }
83+ } ;
84+
85+ return (
86+ < Dialog open = { isOpen } onOpenChange = { onClose } >
87+ < DialogContent className = "sm:max-w-[500px]" >
88+ < DialogHeader >
89+ < DialogTitle > Edit Timeline Entry</ DialogTitle >
90+ < DialogDescription >
91+ Update the details for this entry or delete it.
92+ </ DialogDescription >
93+ </ DialogHeader >
94+ < form onSubmit = { handleUpdate } className = "space-y-4" >
95+ < div className = "space-y-2" >
96+ < Label htmlFor = "type" > Entry Type</ Label >
97+ < Select value = { type } onValueChange = { ( value ) => setType ( value as TimelineEntryData [ "type" ] ) } >
98+ < SelectTrigger id = "type" > < SelectValue /> </ SelectTrigger >
99+ < SelectContent >
100+ < SelectItem value = "medication" > Medication</ SelectItem >
101+ < SelectItem value = "lab" > Lab Result</ SelectItem >
102+ < SelectItem value = "appointment" > Appointment</ SelectItem >
103+ </ SelectContent >
104+ </ Select >
105+ </ div >
106+
107+ < div className = "space-y-2" >
108+ < Label htmlFor = "title" > Title</ Label >
109+ < Input id = "title" value = { title } onChange = { ( e ) => setTitle ( e . target . value ) } required />
110+ </ div >
111+
112+ < div className = "space-y-2" >
113+ < Label htmlFor = "description" > Description</ Label >
114+ < Textarea id = "description" value = { description } onChange = { ( e ) => setDescription ( e . target . value ) } required />
115+ </ div >
116+
117+ < div className = "grid grid-cols-2 gap-4" >
118+ < div className = "space-y-2" >
119+ < Label htmlFor = "date" > Date</ Label >
120+ < Input id = "date" type = "date" value = { date } onChange = { ( e ) => setDate ( e . target . value ) } required />
121+ </ div >
122+ < div className = "space-y-2" >
123+ < Label htmlFor = "time" > Time</ Label >
124+ < Input id = "time" type = "time" value = { time } onChange = { ( e ) => setTime ( e . target . value ) } required />
125+ </ div >
126+ </ div >
127+
128+ < div className = "space-y-2" >
129+ < Label htmlFor = "provider" > Provider (Optional)</ Label >
130+ < Input id = "provider" value = { provider } onChange = { ( e ) => setProvider ( e . target . value ) } />
131+ </ div >
132+
133+ < div className = "flex items-center gap-4" >
134+ < div className = "flex items-center space-x-2" >
135+ < Checkbox id = "recurring" checked = { recurring } onCheckedChange = { ( checked ) => setRecurring ( checked as boolean ) } />
136+ < Label htmlFor = "recurring" className = "text-sm font-normal cursor-pointer" > Recurring Event</ Label >
137+ </ div >
138+ { recurring && (
139+ < Select value = { recurrence } onValueChange = { ( value ) => setRecurrence ( value as TimelineEntryData [ 'recurring' ] ) } >
140+ < SelectTrigger id = "recurrence" className = "h-9" > < SelectValue /> </ SelectTrigger >
141+ < SelectContent >
142+ < SelectItem value = "daily" > Daily</ SelectItem >
143+ < SelectItem value = "weekly" > Weekly</ SelectItem >
144+ </ SelectContent >
145+ </ Select >
146+ ) }
147+ </ div >
148+
149+ < DialogFooter className = "gap-2 sm:justify-between" >
150+ < Button type = "button" variant = "destructive" onClick = { handleDelete } > Delete</ Button >
151+ < div className = "flex gap-2" >
152+ < Button type = "button" variant = "outline" onClick = { onClose } > Cancel</ Button >
153+ < Button type = "submit" > Save Changes</ Button >
154+ </ div >
155+ </ DialogFooter >
156+ </ form >
157+ </ DialogContent >
158+ </ Dialog >
159+ ) ;
160+ }
0 commit comments