Merge pull request #216 from emrysal/feature/sticky-time-options

Implemented sticky time options based on localStorage
This commit is contained in:
Bailey Pumfleet 2021-05-26 19:56:00 +01:00 committed by GitHub
commit efa443a912
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 24 deletions

View file

@ -40,15 +40,45 @@ export default function Type(props) {
setIsTimeOptionsOpen(!isTimeOptionsOpen); setIsTimeOptionsOpen(!isTimeOptionsOpen);
} }
useEffect(() => { function toggleClockSticky() {
// Setting timezone only client-side localStorage.setItem('timeOption.is24hClock', (!is24h).toString());
setSelectedTimeZone(dayjs.tz.guess()) 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(() => { useEffect(() => {
telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) 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 // Get router variables
const router = useRouter(); const router = useRouter();
@ -108,22 +138,6 @@ export default function Type(props) {
</button> </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(() => const times = useMemo(() =>
getSlots({ getSlots({
calendarTimeZone: props.user.timeZone, calendarTimeZone: props.user.timeZone,
@ -225,7 +239,7 @@ export default function Type(props) {
</Switch.Label> </Switch.Label>
<Switch <Switch
checked={is24h} checked={is24h}
onChange={setIs24h} onChange={toggleClockSticky}
className={classNames( className={classNames(
is24h ? "bg-blue-600" : "bg-gray-200", 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" "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 <TimezoneSelect
id="timeZone" id="timeZone"
value={selectedTimeZone} 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" 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> </div>

View file

@ -6,20 +6,32 @@ import prisma from '../../lib/prisma';
import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import 'react-phone-number-input/style.css'; import 'react-phone-number-input/style.css';
import PhoneInput from 'react-phone-number-input'; import PhoneInput from 'react-phone-number-input';
import { LocationType } from '../../lib/location'; import { LocationType } from '../../lib/location';
import Avatar from '../../components/Avatar'; import Avatar from '../../components/Avatar';
dayjs.extend(utc);
dayjs.extend(timezone);
export default function Book(props) { export default function Book(props) {
const router = useRouter(); const router = useRouter();
const { date, user } = router.query; const { date, user } = router.query;
const [ is24h, setIs24h ] = useState(false);
const [ preferredTimeZone, setPreferredTimeZone ] = useState('');
const locations = props.eventType.locations || []; const locations = props.eventType.locations || [];
const [ selectedLocation, setSelectedLocation ] = useState<LocationType>(locations.length === 1 ? locations[0].type : ''); const [ selectedLocation, setSelectedLocation ] = useState<LocationType>(locations.length === 1 ? locations[0].type : '');
const telemetry = useTelemetry(); const telemetry = useTelemetry();
useEffect(() => { useEffect(() => {
setPreferredTimeZone(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess());
setIs24h(!!localStorage.getItem('timeOption.is24hClock'));
telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.timeSelected, collectPageParameters())); telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.timeSelected, collectPageParameters()));
}); });
@ -92,7 +104,7 @@ export default function Book(props) {
</p>} </p>}
<p className="text-blue-600 mb-4"> <p className="text-blue-600 mb-4">
<CalendarIcon className="inline-block w-4 h-4 mr-1 -mt-1" /> <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>
<p className="text-gray-600">{props.eventType.description}</p> <p className="text-gray-600">{props.eventType.description}</p>
</div> </div>