33import React , { FC , useEffect , useState } from "react" ;
44import { observer } from "mobx-react" ;
55import { Controller , useForm } from "react-hook-form" ;
6- import { ArchiveIcon , ArchiveRestoreIcon , ChevronRight , EllipsisIcon , LinkIcon , Trash2 } from "lucide-react" ;
6+ import {
7+ ArchiveIcon ,
8+ ArchiveRestoreIcon ,
9+ ArrowRight ,
10+ ChevronRight ,
11+ EllipsisIcon ,
12+ LinkIcon ,
13+ Trash2 ,
14+ } from "lucide-react" ;
715// types
816import { CYCLE_STATUS , CYCLE_UPDATED , EUserPermissions , EUserPermissionsLevel } from "@plane/constants" ;
917import { useTranslation } from "@plane/i18n" ;
@@ -20,6 +28,7 @@ import { useCycle, useEventTracker, useUserPermissions } from "@/hooks/store";
2028import { useAppRouter } from "@/hooks/use-app-router" ;
2129// plane web constants
2230// services
31+ import { useTimeZoneConverter } from "@/hooks/use-timezone-converter" ;
2332import { CycleService } from "@/services/cycle.service" ;
2433// local components
2534import { ArchiveCycleModal } from "../archived-cycles" ;
@@ -52,6 +61,10 @@ export const CycleSidebarHeader: FC<Props> = observer((props) => {
5261 const { updateCycleDetails, restoreCycle } = useCycle ( ) ;
5362 const { setTrackElement, captureCycleEvent } = useEventTracker ( ) ;
5463 const { t } = useTranslation ( ) ;
64+ const { renderFormattedDateInUserTimezone, getProjectUTCOffset } = useTimeZoneConverter ( projectId ) ;
65+
66+ // derived values
67+ const projectUTCOffset = getProjectUTCOffset ( ) ;
5568
5669 // form info
5770 const { control, reset } = useForm ( {
@@ -289,34 +302,50 @@ export const CycleSidebarHeader: FC<Props> = observer((props) => {
289302 control = { control }
290303 name = "start_date"
291304 render = { ( { field : { value : startDateValue , onChange : onChangeStartDate } } ) => (
292- < Controller
293- control = { control }
294- name = "end_date"
295- render = { ( { field : { value : endDateValue , onChange : onChangeEndDate } } ) => (
296- < DateRangeDropdown
297- className = "h-7"
298- buttonVariant = "border-with-text"
299- minDate = { new Date ( ) }
300- value = { {
301- from : getDate ( startDateValue ) ,
302- to : getDate ( endDateValue ) ,
303- } }
304- onSelect = { async ( val ) => {
305- const isDateValid = await handleDateChange ( val ?. from , val ?. to ) ;
306- if ( isDateValid ) {
307- onChangeStartDate ( val ?. from ? renderFormattedPayloadDate ( val . from ) : null ) ;
308- onChangeEndDate ( val ?. to ? renderFormattedPayloadDate ( val . to ) : null ) ;
305+ < div className = "flex gap-2 items-center" >
306+ < Controller
307+ control = { control }
308+ name = "end_date"
309+ render = { ( { field : { value : endDateValue , onChange : onChangeEndDate } } ) => (
310+ < DateRangeDropdown
311+ className = "h-7"
312+ buttonVariant = "border-with-text"
313+ minDate = { new Date ( ) }
314+ value = { {
315+ from : getDate ( startDateValue ) ,
316+ to : getDate ( endDateValue ) ,
317+ } }
318+ onSelect = { async ( val ) => {
319+ const isDateValid = await handleDateChange ( val ?. from , val ?. to ) ;
320+ if ( isDateValid ) {
321+ onChangeStartDate ( val ?. from ? renderFormattedPayloadDate ( val . from ) : null ) ;
322+ onChangeEndDate ( val ?. to ? renderFormattedPayloadDate ( val . to ) : null ) ;
323+ }
324+ } }
325+ placeholder = { {
326+ from : t ( "project_cycles.start_date" ) ,
327+ to : t ( "project_cycles.end_date" ) ,
328+ } }
329+ customTooltipHeading = { t ( "project_cycles.in_your_timezone" ) }
330+ customTooltipContent = {
331+ < span className = "flex gap-1" >
332+ { renderFormattedDateInUserTimezone ( cycleDetails . start_date ?? "" ) }
333+ < ArrowRight className = "h-3 w-3 flex-shrink-0 my-auto" />
334+ { renderFormattedDateInUserTimezone ( cycleDetails . end_date ?? "" ) }
335+ </ span >
309336 }
310- } }
311- placeholder = { {
312- from : "Start date" ,
313- to : "End date" ,
314- } }
315- required = { cycleDetails . status !== "draft" }
316- disabled = { ! isEditingAllowed || isArchived || isCompleted }
317- />
337+ showTooltip = { ! ! cycleDetails . start_date && ! ! cycleDetails . end_date } // show tooltip only if both start and end date are present
338+ required = { cycleDetails . status !== "draft" }
339+ disabled = { ! isEditingAllowed || isArchived || isCompleted }
340+ />
341+ ) }
342+ />
343+ { projectUTCOffset && (
344+ < span className = "rounded-md text-xs px-2 cursor-default py-1 bg-custom-background-80 text-custom-text-300" >
345+ { projectUTCOffset }
346+ </ span >
318347 ) }
319- / >
348+ </ div >
320349 ) }
321350 />
322351 </ div >
0 commit comments