Implemented sticky time options based on localStorage
This commit is contained in:
		
							parent
							
								
									7d6a631f5d
								
							
						
					
					
						commit
						cf06e91e30
					
				
					 2 changed files with 50 additions and 24 deletions
				
			
		|  | @ -40,15 +40,45 @@ export default function Type(props) { | |||
|         setIsTimeOptionsOpen(!isTimeOptionsOpen); | ||||
|     } | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|       // Setting timezone only client-side
 | ||||
|       setSelectedTimeZone(dayjs.tz.guess()) | ||||
|     }, []) | ||||
|     function toggleClockSticky() { | ||||
|         localStorage.setItem('timeOption.is24hClock', (!is24h).toString()); | ||||
|         setIs24h(!is24h); | ||||
|     } | ||||
| 
 | ||||
|     function setPreferredTimeZoneSticky({ value }: string) { | ||||
|         localStorage.setItem('timeOption.preferredTimeZone', value); | ||||
|         setSelectedTimeZone(value); | ||||
|     } | ||||
| 
 | ||||
|     function initializeTimeOptions() { | ||||
|         setSelectedTimeZone(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess()); | ||||
|         setIs24h(!!localStorage.getItem('timeOption.is24hClock')); | ||||
|     } | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) | ||||
|     }) | ||||
|     }); | ||||
| 
 | ||||
|     // Handle date change and timezone change
 | ||||
|     useEffect(() => { | ||||
| 
 | ||||
|         if ( ! selectedTimeZone ) { | ||||
|             initializeTimeOptions(); | ||||
|         } | ||||
| 
 | ||||
|         const changeDate = async () => { | ||||
|             if (!selectedDate) { | ||||
|                 return | ||||
|             } | ||||
| 
 | ||||
|             setLoading(true); | ||||
|             const res = await fetch(`/api/availability/${user}?dateFrom=${lowerBound.utc().format()}&dateTo=${upperBound.utc().format()}`); | ||||
|             const busyTimes = await res.json(); | ||||
|             if (busyTimes.length > 0) setBusy(busyTimes); | ||||
|             setLoading(false); | ||||
|         } | ||||
|         changeDate(); | ||||
|     }, [selectedDate, selectedTimeZone]); | ||||
| 
 | ||||
|     // Get router variables
 | ||||
|     const router = useRouter(); | ||||
|  | @ -108,22 +138,6 @@ export default function Type(props) { | |||
|         </button> | ||||
|     )]; | ||||
| 
 | ||||
|     // Handle date change and timezone change
 | ||||
|     useEffect(() => { | ||||
|         const changeDate = async () => { | ||||
|             if (!selectedDate) { | ||||
|                 return | ||||
|             } | ||||
| 
 | ||||
|             setLoading(true); | ||||
|             const res = await fetch(`/api/availability/${user}?dateFrom=${lowerBound.utc().format()}&dateTo=${upperBound.utc().format()}`); | ||||
|             const busyTimes = await res.json(); | ||||
|             if (busyTimes.length > 0) setBusy(busyTimes); | ||||
|             setLoading(false); | ||||
|         } | ||||
|         changeDate(); | ||||
|     }, [selectedDate, selectedTimeZone]); | ||||
| 
 | ||||
|     const times = useMemo(() => | ||||
|       getSlots({ | ||||
|         calendarTimeZone: props.user.timeZone, | ||||
|  | @ -225,7 +239,7 @@ export default function Type(props) { | |||
|                           </Switch.Label> | ||||
|                           <Switch | ||||
|                             checked={is24h} | ||||
|                             onChange={setIs24h} | ||||
|                             onChange={toggleClockSticky} | ||||
|                             className={classNames( | ||||
|                               is24h ? "bg-blue-600" : "bg-gray-200", | ||||
|                               "relative inline-flex flex-shrink-0 h-5 w-8 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" | ||||
|  | @ -249,7 +263,7 @@ export default function Type(props) { | |||
|                     <TimezoneSelect | ||||
|                       id="timeZone" | ||||
|                       value={selectedTimeZone} | ||||
|                       onChange={({ value }) => setSelectedTimeZone(value)} | ||||
|                       onChange={setPreferredTimeZoneSticky} | ||||
|                       className="mb-2 shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md" | ||||
|                     /> | ||||
|                   </div> | ||||
|  |  | |||
|  | @ -6,20 +6,32 @@ import prisma from '../../lib/prisma'; | |||
| import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import dayjs from 'dayjs'; | ||||
| import utc from 'dayjs/plugin/utc'; | ||||
| import timezone from 'dayjs/plugin/timezone'; | ||||
| import 'react-phone-number-input/style.css'; | ||||
| import PhoneInput from 'react-phone-number-input'; | ||||
| import { LocationType } from '../../lib/location'; | ||||
| import Avatar from '../../components/Avatar'; | ||||
| 
 | ||||
| dayjs.extend(utc); | ||||
| dayjs.extend(timezone); | ||||
| 
 | ||||
| export default function Book(props) { | ||||
|     const router = useRouter(); | ||||
|     const { date, user } = router.query; | ||||
| 
 | ||||
|     const [ is24h, setIs24h ] = useState(false); | ||||
|     const [ preferredTimeZone, setPreferredTimeZone ] = useState(''); | ||||
| 
 | ||||
|     const locations = props.eventType.locations || []; | ||||
| 
 | ||||
|     const [ selectedLocation, setSelectedLocation ] = useState<LocationType>(locations.length === 1 ? locations[0].type : ''); | ||||
|     const telemetry = useTelemetry(); | ||||
|     useEffect(() => { | ||||
| 
 | ||||
|         setPreferredTimeZone(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess()); | ||||
|         setIs24h(!!localStorage.getItem('timeOption.is24hClock')); | ||||
| 
 | ||||
|         telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.timeSelected, collectPageParameters())); | ||||
|     }); | ||||
| 
 | ||||
|  | @ -92,7 +104,7 @@ export default function Book(props) { | |||
|                             </p>} | ||||
|                             <p className="text-blue-600 mb-4"> | ||||
|                                 <CalendarIcon className="inline-block w-4 h-4 mr-1 -mt-1" /> | ||||
|                                 {dayjs(date).format("hh:mma, dddd DD MMMM YYYY")} | ||||
|                                 {preferredTimeZone && dayjs(date).tz(preferredTimeZone).format( (is24h ? "H:mm" : "h:mma") + ", dddd DD MMMM YYYY")} | ||||
|                             </p> | ||||
|                             <p className="text-gray-600">{props.eventType.description}</p> | ||||
|                         </div> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Alex van Andel
						Alex van Andel