add event creation ui

This commit is contained in:
Michael Fatemi 2021-06-22 21:19:08 -04:00
parent 64e08154e9
commit b7244c91e5
8 changed files with 172 additions and 38 deletions

View File

@ -1,3 +1,4 @@
import EventCreator from './EventCreator';
import Group from './Group';
import UIPrimaryTitle from './UIPrimaryTitle';
@ -15,6 +16,7 @@ export default function App() {
}}
>
<UIPrimaryTitle>WheelShare</UIPrimaryTitle>
<EventCreator />
<Group
events={[
{

View File

@ -1,5 +1,7 @@
import { useEffect, useState } from 'react';
import UIButton from './UIButton';
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
import UISecondaryBox from './UISecondaryBox';
import UISecondaryHeader from './UISecondaryHeader';
import UITimeInput from './UITimeInput';
@ -25,16 +27,7 @@ export default function Event({ title, group, location, time }: IEvent) {
}, [rideTherePickupPlaceID, rideBackDropoffPlaceID]);
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
backgroundColor: '#f9f9f9',
borderRadius: '0.5rem',
padding: '1rem',
marginBottom: '1em',
}}
>
<UISecondaryBox>
<UISecondaryHeader>{title}</UISecondaryHeader>
<span
style={{
@ -76,44 +69,32 @@ export default function Event({ title, group, location, time }: IEvent) {
marginTop: '1rem',
}}
>
<div
<UIButton
style={{
backgroundColor: needRideThere ? green : lightgrey,
color: needRideThere ? 'white' : 'black',
transition: 'color 0.2s, background-color 0.2s',
padding: '1rem',
borderRadius: '0.5em',
textTransform: 'uppercase',
fontWeight: 500,
marginRight: '0.5em',
cursor: 'pointer',
userSelect: 'none',
}}
onClick={() => {
setNeedRideThere((needRideThere) => !needRideThere);
}}
>
I need a ride there
</div>
<div
</UIButton>
<UIButton
style={{
backgroundColor: needRideBack ? green : lightgrey,
color: needRideBack ? 'white' : 'black',
transition: 'color 0.2s, background-color 0.2s',
padding: '1rem',
borderRadius: '0.5em',
textTransform: 'uppercase',
fontWeight: 500,
marginLeft: '0.5em',
cursor: 'pointer',
userSelect: 'none',
}}
onClick={() => {
setNeedRideBack((needRideBack) => !needRideBack);
}}
>
I need a ride back
</div>
</UIButton>
</div>
{needRideThere && (
<>
@ -161,25 +142,18 @@ export default function Event({ title, group, location, time }: IEvent) {
)}
{(needRideThere || needRideBack) &&
(rideTherePickupPlaceID || rideBackDropoffPlaceID) && (
<div
<UIButton
style={{
backgroundColor: confirmed ? green : lightgrey,
color: confirmed ? 'white' : 'black',
padding: '1rem',
borderRadius: '0.5em',
textTransform: 'uppercase',
fontWeight: 500,
marginTop: '0.5em',
cursor: 'pointer',
userSelect: 'none',
}}
onClick={() => {
setConfirmed((confirmed) => !confirmed);
}}
>
{confirmed ? 'Confirmed' : 'Confirm'}
</div>
</UIButton>
)}
</div>
</UISecondaryBox>
);
}

View File

@ -0,0 +1,53 @@
import { useCallback, useState } from 'react';
import UIButton from './UIButton';
import UIDatetimeInput from './UIDatetimeInput';
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
import UISecondaryBox from './UISecondaryBox';
import UITextInput from './UITextInput';
export default function EventCreator() {
const [name, setName] = useState('');
const [startTime, setStartTime] = useState<Date | null>(null);
const [endTime, setEndTime] = useState<Date | null>(null);
const [placeId, setPlaceId] = useState<string | null>(null);
const [groupId, setGroupId] = useState('');
const createEvent = useCallback(() => {
fetch('http://localhost:5000/api/events', {
method: 'post',
body: JSON.stringify({
name,
startTime,
endTime,
groupId,
}),
headers: {
'Content-Type': 'application/json',
},
});
}, [name, startTime, endTime, groupId]);
return (
<UISecondaryBox style={{ width: '100%', boxSizing: 'border-box' }}>
Name
<UITextInput value={name} onChangeText={setName} />
<br />
Group
<UITextInput value={groupId} onChangeText={setGroupId} />
<br />
Start time
<UIDatetimeInput onChangedDate={setStartTime} />
<br />
End time
<UIDatetimeInput onChangedDate={setEndTime} />
<br />
Location
<UIPlacesAutocomplete
onSelected={(address, placeId) => {
setPlaceId(placeId);
}}
/>
<UIButton onClick={createEvent}>Create Event</UIButton>
</UISecondaryBox>
);
}

View File

@ -7,9 +7,9 @@ export type IGroup = {
export default function Group({ events, name }: IGroup) {
return (
<div style={{ textAlign: 'center' }}>
<div style={{ textAlign: 'center', width: '100%' }}>
<h1>{name}</h1>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
{events.map((event) => (
<Event {...event} key={event.title} />
))}

View File

@ -0,0 +1,33 @@
import { useMemo, CSSProperties, MouseEventHandler, ReactNode } from 'react';
const baseStyle: CSSProperties = {
padding: '1rem',
borderRadius: '0.5em',
textTransform: 'uppercase',
fontWeight: 500,
marginTop: '0.5em',
cursor: 'pointer',
userSelect: 'none',
};
export default function UIButton({
style,
children,
onClick,
}: {
style?: CSSProperties;
children: ReactNode;
onClick: MouseEventHandler<HTMLDivElement>;
}) {
const computedStyle = useMemo(() => {
if (!style) {
return baseStyle;
}
return { ...baseStyle, ...style };
}, [style]);
return (
<div style={computedStyle} onClick={onClick}>
{children}
</div>
);
}

View File

@ -0,0 +1,22 @@
const baseStyle = {
marginTop: '0.5em',
padding: '0.5em',
fontFamily: 'Inter',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
};
export default function UIDatetimeInput({
onChangedDate,
}: {
onChangedDate: (date: Date | null) => void;
}) {
return (
<input
style={baseStyle}
type="datetime-local"
onChange={(e) => onChangedDate(e.target.valueAsDate)}
/>
);
}

View File

@ -0,0 +1,26 @@
import { CSSProperties, ReactNode, useMemo } from 'react';
const baseStyle: CSSProperties = {
display: 'flex',
flexDirection: 'column',
backgroundColor: '#f9f9f9',
borderRadius: '0.5rem',
padding: '1rem',
marginBottom: '1em',
};
export default function UISecondaryBox({
children,
style,
}: {
children: ReactNode;
style?: CSSProperties;
}) {
const computedStyle = useMemo(() => {
if (!style) {
return baseStyle;
}
return { ...baseStyle, ...style };
}, [style]);
return <div style={computedStyle}>{children}</div>;
}

View File

@ -0,0 +1,24 @@
const baseStyle = {
marginTop: '0.5em',
padding: '0.5em',
fontFamily: 'Inter',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
};
export default function UITextInput({
value,
onChangeText,
}: {
value: string;
onChangeText: (text: string) => void;
}) {
return (
<input
style={baseStyle}
value={value}
onChange={(e) => onChangeText(e.target.value)}
/>
);
}