Add some UI components

This commit is contained in:
Michael Fatemi 2021-06-08 08:48:08 -04:00
parent 479ce77c82
commit 11272ce41a
6 changed files with 196 additions and 161 deletions

View File

@ -1,4 +1,5 @@
import Event from './Event';
import UIPrimaryTitle from './UIPrimaryTitle';
export default function App() {
return (
@ -7,20 +8,13 @@ export default function App() {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
maxWidth: '50rem',
width: '30rem',
maxWidth: '30rem',
marginLeft: 'auto',
marginRight: 'auto',
}}
>
<h1
style={{
fontSize: '4rem',
marginTop: '0.25em',
marginBottom: '0.25em',
}}
>
WheelShare
</h1>
<UIPrimaryTitle>WheelShare</UIPrimaryTitle>
<Event
title="TJ Track Regional Meet"
group="TJHSST Track and Field"

View File

@ -1,5 +1,7 @@
import { useState } from 'react';
import PlacesAutocomplete from 'react-places-autocomplete';
import { useEffect, useState } from 'react';
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
import UISecondaryHeader from './UISecondaryHeader';
import UITimeInput from './UITimeInput';
const green = '#60f760';
const lightgrey = '#e0e0e0';
@ -17,8 +19,12 @@ export default function Event({
}) {
const [needRideThere, setNeedRideThere] = useState(false);
const [needRideBack, setNeedRideBack] = useState(false);
const [rideThereLocation, setRideThereLocation] = useState('');
const [rideBackLocation, setRideBackLocation] = useState('');
const [rideTherePickupPlaceID, setRideTherePickupPlaceID] = useState('');
const [rideBackDropoffPlaceID, setRideBackDropoffPlaceID] = useState('');
useEffect(() => {
console.log({ rideTherePickupPlaceID, rideBackDropoffPlaceID });
}, [rideTherePickupPlaceID, rideBackDropoffPlaceID]);
return (
<div
@ -31,15 +37,7 @@ export default function Event({
marginBottom: '1em',
}}
>
<h2
style={{
marginTop: '0rem',
marginBottom: '0.25em',
textAlign: 'center',
}}
>
{title}
</h2>
<UISecondaryHeader>{title}</UISecondaryHeader>
<span
style={{
color: '#303030',
@ -121,154 +119,44 @@ export default function Event({
</div>
{needRideThere && (
<>
<PlacesAutocomplete
onChange={(address) => setRideThereLocation(address)}
value={rideThereLocation}
>
{({
getInputProps,
getSuggestionItemProps,
suggestions,
loading,
}) => (
<div
<span
style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
color: '#303030',
textTransform: 'uppercase',
fontWeight: 500,
marginTop: '1em',
}}
>
<input
{...getInputProps({
style: {
marginTop: '0.5em',
padding: '0.5em',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
zIndex: 1,
},
placeholder: 'Where would you be picked up?',
})}
/>
{loading
? 'Loading'
: suggestions.length > 0 && (
<div
style={{
marginTop: '-1em',
paddingTop: '2em',
paddingBottom: '1em',
paddingLeft: '1em',
paddingRight: '1em',
borderBottomLeftRadius: '0.5em',
borderBottomRightRadius: '0.5em',
backgroundColor: 'white',
}}
>
{suggestions.map((suggestion) => (
<div
{...getSuggestionItemProps(suggestion)}
style={{
cursor: 'pointer',
}}
key={suggestion.placeId}
>
{suggestion.description}
</div>
))}
</div>
)}
</div>
)}
</PlacesAutocomplete>
<input
type="time"
style={{
marginTop: '0.5em',
padding: '0.5em',
fontFamily: 'Inter',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
}}
Ride There
</span>
<UIPlacesAutocomplete
placeholder="Pickup location"
onSelected={(address, placeID) =>
setRideTherePickupPlaceID(placeID)
}
/>
<UITimeInput />
</>
)}
{needRideBack && (
<>
<PlacesAutocomplete
onChange={(address) => setRideBackLocation(address)}
value={rideBackLocation}
>
{({
getInputProps,
getSuggestionItemProps,
suggestions,
loading,
}) => (
<div
<span
style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
color: '#303030',
textTransform: 'uppercase',
fontWeight: 500,
marginTop: '1em',
}}
>
<input
{...getInputProps({
style: {
marginTop: '0.5em',
padding: '0.5em',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
zIndex: 1,
},
placeholder: 'Where would you be dropped off?',
})}
/>
{loading
? 'Loading'
: suggestions.length > 0 && (
<div
style={{
marginTop: '-1em',
paddingTop: '2em',
paddingBottom: '1em',
paddingLeft: '1em',
paddingRight: '1em',
borderBottomLeftRadius: '0.5em',
borderBottomRightRadius: '0.5em',
backgroundColor: 'white',
}}
>
{suggestions.map((suggestion) => (
<div
{...getSuggestionItemProps(suggestion)}
style={{
cursor: 'pointer',
}}
key={suggestion.placeId}
>
{suggestion.description}
</div>
))}
</div>
)}
</div>
)}
</PlacesAutocomplete>
<input
type="time"
style={{
marginTop: '0.5em',
padding: '0.5em',
fontFamily: 'Inter',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
}}
Ride Back
</span>
<UIPlacesAutocomplete
placeholder="Dropoff location"
onSelected={(address, placeID) =>
setRideBackDropoffPlaceID(placeID)
}
/>
<UITimeInput />
</>
)}
</div>

View File

@ -0,0 +1,100 @@
import { useRef, useState } from 'react';
import PlacesAutocomplete, { Suggestion } from 'react-places-autocomplete';
type Opts = Parameters<PlacesAutocomplete['props']['children']>['0'];
function SuggestionsList({
suggestions,
getSuggestionItemProps,
}: {
suggestions: readonly Suggestion[];
getSuggestionItemProps: Opts['getSuggestionItemProps'];
}) {
return (
<div
style={{
marginTop: '-1em',
paddingTop: '2em',
paddingBottom: '1em',
paddingLeft: '1em',
paddingRight: '1em',
borderBottomLeftRadius: '0.5em',
borderBottomRightRadius: '0.5em',
backgroundColor: 'white',
maxWidth: '100%',
}}
>
{suggestions.map((suggestion) => (
<div
{...getSuggestionItemProps(suggestion)}
style={{
cursor: 'pointer',
}}
key={suggestion.placeId}
>
{suggestion.description}
</div>
))}
</div>
);
}
export default function UIPlacesAutocomplete({
onSelected,
placeholder = 'Enter a location',
}: {
onSelected?: (address: string, placeID: string) => void;
placeholder?: string;
}) {
const [location, setLocation] = useState('');
const suggestionsRef = useRef<readonly Suggestion[]>([]);
return (
<PlacesAutocomplete
onChange={setLocation}
onSelect={(address, placeID) => {
setLocation(address);
if (onSelected) {
onSelected(address, placeID);
}
}}
value={location}
>
{({ getInputProps, getSuggestionItemProps, suggestions, loading }) => {
if (!loading) {
suggestionsRef.current = suggestions;
console.log(suggestions);
}
return (
<div
style={{
width: '100%',
maxWidth: '100%',
display: 'flex',
flexDirection: 'column',
}}
>
<input
{...getInputProps({
style: {
marginTop: '0.5em',
padding: '0.5em',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
zIndex: 1,
},
placeholder,
})}
/>
{suggestionsRef.current.length > 0 && (
<SuggestionsList
suggestions={suggestionsRef.current}
getSuggestionItemProps={getSuggestionItemProps}
/>
)}
</div>
);
}}
</PlacesAutocomplete>
);
}

View File

@ -0,0 +1,15 @@
import { ReactNode } from 'react';
export default function UIPrimaryTitle({ children }: { children: ReactNode }) {
return (
<h1
style={{
fontSize: '4rem',
marginTop: '0.25em',
marginBottom: '0.25em',
}}
>
{children}
</h1>
);
}

View File

@ -0,0 +1,17 @@
const baseStyle = {
marginTop: '0rem',
marginBottom: '0.25em',
textAlign: 'center',
} as const;
export default function UISecondaryHeader({
style,
children,
...props
}: JSX.IntrinsicElements['h2']) {
return (
<h2 style={style ? { ...baseStyle, ...style } : baseStyle} {...props}>
{children}
</h2>
);
}

View File

@ -0,0 +1,21 @@
const baseStyle = {
marginTop: '0.5em',
padding: '0.5em',
fontFamily: 'Inter',
fontSize: '1.25rem',
borderRadius: '0.5em',
border: '0px',
};
export default function UITimeInput({
style,
...props
}: JSX.IntrinsicElements['input']) {
return (
<input
{...props}
type="time"
style={style ? { ...style, ...baseStyle } : baseStyle}
/>
);
}