Add days of week picker and binary encoding

This commit is contained in:
Michael Fatemi 2021-06-30 10:18:27 -04:00
parent 12c0f9d32f
commit 3fc96ca3d4
4 changed files with 122 additions and 14 deletions

View File

@ -1,4 +1,5 @@
import { useState } from 'react';
import { green, lightgrey } from './colors';
import latlongdist, { R_miles } from './latlongdist';
import UIButton from './UIButton';
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
@ -8,9 +9,6 @@ import usePlace from './usePlace';
import useThrottle from './useThrottle';
import useToggle from './useToggle';
const green = '#60f760';
const lightgrey = '#e0e0e0';
export type IEvent = {
id: number;
name: string;
@ -18,6 +16,8 @@ export type IEvent = {
formattedAddress: string;
startTime: string;
endTime: string;
latitude: number;
longitude: number;
};
function formatStartAndEndTime(
@ -211,8 +211,8 @@ function People({ event, placeId }: { event: IEvent; placeId: string }) {
// eslint-disable-next-line
const [people, setPeople] = useState(dummyPeopleData);
const placeDetails = usePlace(placeId);
const myLatitude = 10;
const myLongitude = 10;
const locationLongitude = event.latitude;
const locationLatitude = event.longitude;
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
@ -220,28 +220,28 @@ function People({ event, placeId }: { event: IEvent; placeId: string }) {
{people.map(({ name, latitude, longitude, id }) => {
let extraDistance = null;
if (placeDetails != null) {
const locationLatitude = placeDetails.latitude;
const locationLongitude = placeDetails.longitude;
const myLatitude = placeDetails.latitude;
const myLongitude = placeDetails.longitude;
const meToThem = latlongdist(
latitude,
longitude,
myLatitude,
myLongitude,
locationLongitude,
locationLatitude,
R_miles
);
const themToLocation = latlongdist(
latitude,
longitude,
locationLatitude,
locationLongitude,
myLatitude,
myLongitude,
R_miles
);
const totalWithThem = meToThem + themToLocation;
const totalWithoutThem = latlongdist(
locationLongitude,
locationLatitude,
myLatitude,
myLongitude,
locationLatitude,
locationLongitude,
R_miles
);
extraDistance = totalWithThem - totalWithoutThem;

View File

@ -1,14 +1,81 @@
import { useCallback, useState } from 'react';
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
import { post } from './api';
import { toggleBit } from './bits';
import { green, lightgrey } from './colors';
import { IGroup } from './Group';
import UIButton from './UIButton';
import UIDatetimeInput from './UIDatetimeInput';
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
import UISecondaryBox from './UISecondaryBox';
import UITextInput from './UITextInput';
import useToggle from './useToggle';
const noop = () => {};
const DAY_NAMES = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
];
function DaysOfWeekSelector({
daysOfWeek,
update,
}: {
daysOfWeek: number;
update: Dispatch<SetStateAction<number>>;
}) {
const toggleDayOfWeek = useCallback(
function (idx: 1 | 2 | 3 | 4 | 5 | 6 | 7) {
update((daysOfWeek) => toggleBit(daysOfWeek, idx));
},
[update]
);
return (
<div
style={{
display: 'flex',
flexDirection: 'row',
margin: '1rem auto',
}}
>
{DAY_NAMES.map((name, idx) => {
const mask = 0b1000_0000 >> (idx + 1);
const active = (daysOfWeek & mask) !== 0;
return (
<div
style={{
borderRadius: '100%',
cursor: 'pointer',
backgroundColor: active ? green : lightgrey,
color: active ? 'white' : 'black',
userSelect: 'none',
width: '2em',
height: '2em',
margin: '0.5rem',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}}
onClick={() =>
// @ts-ignore
toggleDayOfWeek(idx + 1)
}
>
{name.charAt(0)}
</div>
);
})}
</div>
);
}
export default function EventCreator({ group }: { group: IGroup }) {
const [name, setName] = useState('');
const [startTime, setStartTime] = useState<Date | null>(null);
@ -17,6 +84,9 @@ export default function EventCreator({ group }: { group: IGroup }) {
const [creating, setCreating] = useState(false);
const [createdEventId, setCreatedEventId] = useState(-1);
const [recurring, toggleRecurring] = useToggle(false);
const [daysOfWeek, setDaysOfWeek] = useState(0);
const buttonEnabled =
name.length > 0 &&
startTime != null &&
@ -63,6 +133,19 @@ export default function EventCreator({ group }: { group: IGroup }) {
setPlaceId(placeId);
}}
/>
<UIButton
onClick={toggleRecurring}
style={{
backgroundColor: recurring ? green : lightgrey,
color: recurring ? 'white' : 'black',
transition: 'color 0.2s, background-color 0.2s',
}}
>
Recurring event
</UIButton>
{recurring && (
<DaysOfWeekSelector daysOfWeek={daysOfWeek} update={setDaysOfWeek} />
)}
{createdEventId === -1 ? (
<UIButton
onClick={buttonEnabled ? createEvent : noop}

View File

@ -0,0 +1,23 @@
export function setBit(n: number, idx: number, active: boolean) {
if (idx < 1 || idx > 7 || !isFinite(idx)) {
throw new Error('invalid idx. idx must be from 1 - 7.');
}
const mask = 0b1000_0000 >> idx;
if (active) {
return n | mask;
} else {
return n & ~mask;
}
}
export function toggleBit(n: number, idx: number) {
if (idx < 1 || idx > 7 || !isFinite(idx)) {
throw new Error('invalid idx. idx must be from 1 - 7.');
}
const mask = 0b1000_0000 >> idx;
return n ^ mask;
}

View File

@ -0,0 +1,2 @@
export const green = '#60f760';
export const lightgrey = '#e0e0e0';