@@ -131,34 +131,73 @@ const ExpiryDateField = ({
131131 [ field , handleFieldChange , startTransition , useUtcTimestamp , fieldName ] ,
132132 )
133133
134+ const handleShortcut = React . useCallback (
135+ ( days : number ) => {
136+ const now = new Date ( )
137+ const targetDate = new Date ( now )
138+ targetDate . setDate ( now . getDate ( ) + days )
139+ // Use current time instead of end of day
140+ handleDateChange ( targetDate )
141+ } ,
142+ [ handleDateChange ] ,
143+ )
144+
134145 const now = new Date ( )
135146 const maxDate = new Date ( now . getFullYear ( ) + 15 , 11 , 31 )
136147
148+ const shortcuts = [
149+ { label : '7d' , days : 7 } ,
150+ { label : '1m' , days : 30 } ,
151+ { label : '2m' , days : 60 } ,
152+ { label : '3m' , days : 90 } ,
153+ { label : '1y' , days : 365 } ,
154+ ]
155+
137156 return (
138157 < FormItem className = "flex flex-1 flex-col" >
139158 < FormLabel className = 'mb-0.5' > { label } </ FormLabel >
140- < div className = "relative" >
141- < DatePicker
142- mode = "single"
143- date = { displayDate }
144- onDateChange = { handleDateChange }
145- showTime = { true }
146- useUtcTimestamp = { useUtcTimestamp }
147- placeholder = { t ( 'userDialog.expireDate' , { defaultValue : 'Expire date' } ) }
148- minDate = { now }
149- maxDate = { maxDate }
150- open = { calendarOpen }
151- onOpenChange = { setCalendarOpen }
152- fieldName = { fieldName }
153- onFieldChange = { handleFieldChange }
154- />
155- { expireInfo && (
156- < p className = { cn ( 'absolute top-full text-end right-0 mt-1 whitespace-nowrap text-xs text-muted-foreground' , ! expireInfo . time && 'hidden' , dir === 'rtl' ? 'right-0' : 'left-0' ) } >
157- { expireInfo . time !== '0' && expireInfo . time !== '0s'
158- ? t ( 'expires' , { time : expireInfo . time , defaultValue : 'Expires in {{time}}' } )
159- : t ( 'expired' , { time : expireInfo . time , defaultValue : 'Expired in {{time}}' } ) }
160- </ p >
161- ) }
159+ < div className = "space-y-2" >
160+ < div className = "flex lg:hidden items-center gap-1.5 flex-wrap" >
161+ { shortcuts . map ( ( { label, days } ) => (
162+ < Button
163+ key = { label }
164+ type = "button"
165+ variant = "ghost"
166+ size = "sm"
167+ className = "h-7 px-2.5 text-xs text-muted-foreground hover:text-foreground"
168+ onClick = { ( e ) => {
169+ e . preventDefault ( )
170+ e . stopPropagation ( )
171+ handleShortcut ( days )
172+ } }
173+ >
174+ { label }
175+ </ Button >
176+ ) ) }
177+ </ div >
178+ < div className = "relative" >
179+ < DatePicker
180+ mode = "single"
181+ date = { displayDate }
182+ onDateChange = { handleDateChange }
183+ showTime = { true }
184+ useUtcTimestamp = { useUtcTimestamp }
185+ placeholder = { t ( 'userDialog.expireDate' , { defaultValue : 'Expire date' } ) }
186+ minDate = { now }
187+ maxDate = { maxDate }
188+ open = { calendarOpen }
189+ onOpenChange = { setCalendarOpen }
190+ fieldName = { fieldName }
191+ onFieldChange = { handleFieldChange }
192+ />
193+ { expireInfo && (
194+ < p className = { cn ( 'absolute top-full text-end right-0 mt-1 whitespace-nowrap text-xs text-muted-foreground' , ! expireInfo . time && 'hidden' , dir === 'rtl' ? 'right-0' : 'left-0' ) } >
195+ { expireInfo . time !== '0' && expireInfo . time !== '0s'
196+ ? t ( 'expires' , { time : expireInfo . time , defaultValue : 'Expires in {{time}}' } )
197+ : t ( 'expired' , { time : expireInfo . time , defaultValue : 'Expired in {{time}}' } ) }
198+ </ p >
199+ ) }
200+ </ div >
162201 </ div >
163202 < FormMessage />
164203 </ FormItem >
0 commit comments