mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 19:29:51 -04:00
add event creation ui
This commit is contained in:
parent
64e08154e9
commit
b7244c91e5
|
@ -1,3 +1,4 @@
|
||||||
|
import EventCreator from './EventCreator';
|
||||||
import Group from './Group';
|
import Group from './Group';
|
||||||
import UIPrimaryTitle from './UIPrimaryTitle';
|
import UIPrimaryTitle from './UIPrimaryTitle';
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ export default function App() {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<UIPrimaryTitle>WheelShare</UIPrimaryTitle>
|
<UIPrimaryTitle>WheelShare</UIPrimaryTitle>
|
||||||
|
<EventCreator />
|
||||||
<Group
|
<Group
|
||||||
events={[
|
events={[
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import UIButton from './UIButton';
|
||||||
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
|
import UIPlacesAutocomplete from './UIPlacesAutocomplete';
|
||||||
|
import UISecondaryBox from './UISecondaryBox';
|
||||||
import UISecondaryHeader from './UISecondaryHeader';
|
import UISecondaryHeader from './UISecondaryHeader';
|
||||||
import UITimeInput from './UITimeInput';
|
import UITimeInput from './UITimeInput';
|
||||||
|
|
||||||
|
@ -25,16 +27,7 @@ export default function Event({ title, group, location, time }: IEvent) {
|
||||||
}, [rideTherePickupPlaceID, rideBackDropoffPlaceID]);
|
}, [rideTherePickupPlaceID, rideBackDropoffPlaceID]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<UISecondaryBox>
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
backgroundColor: '#f9f9f9',
|
|
||||||
borderRadius: '0.5rem',
|
|
||||||
padding: '1rem',
|
|
||||||
marginBottom: '1em',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<UISecondaryHeader>{title}</UISecondaryHeader>
|
<UISecondaryHeader>{title}</UISecondaryHeader>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
|
@ -76,44 +69,32 @@ export default function Event({ title, group, location, time }: IEvent) {
|
||||||
marginTop: '1rem',
|
marginTop: '1rem',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<UIButton
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: needRideThere ? green : lightgrey,
|
backgroundColor: needRideThere ? green : lightgrey,
|
||||||
color: needRideThere ? 'white' : 'black',
|
color: needRideThere ? 'white' : 'black',
|
||||||
transition: 'color 0.2s, background-color 0.2s',
|
transition: 'color 0.2s, background-color 0.2s',
|
||||||
padding: '1rem',
|
|
||||||
borderRadius: '0.5em',
|
|
||||||
textTransform: 'uppercase',
|
|
||||||
fontWeight: 500,
|
|
||||||
marginRight: '0.5em',
|
marginRight: '0.5em',
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setNeedRideThere((needRideThere) => !needRideThere);
|
setNeedRideThere((needRideThere) => !needRideThere);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
I need a ride there
|
I need a ride there
|
||||||
</div>
|
</UIButton>
|
||||||
<div
|
<UIButton
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: needRideBack ? green : lightgrey,
|
backgroundColor: needRideBack ? green : lightgrey,
|
||||||
color: needRideBack ? 'white' : 'black',
|
color: needRideBack ? 'white' : 'black',
|
||||||
transition: 'color 0.2s, background-color 0.2s',
|
transition: 'color 0.2s, background-color 0.2s',
|
||||||
padding: '1rem',
|
|
||||||
borderRadius: '0.5em',
|
|
||||||
textTransform: 'uppercase',
|
|
||||||
fontWeight: 500,
|
|
||||||
marginLeft: '0.5em',
|
marginLeft: '0.5em',
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setNeedRideBack((needRideBack) => !needRideBack);
|
setNeedRideBack((needRideBack) => !needRideBack);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
I need a ride back
|
I need a ride back
|
||||||
</div>
|
</UIButton>
|
||||||
</div>
|
</div>
|
||||||
{needRideThere && (
|
{needRideThere && (
|
||||||
<>
|
<>
|
||||||
|
@ -161,25 +142,18 @@ export default function Event({ title, group, location, time }: IEvent) {
|
||||||
)}
|
)}
|
||||||
{(needRideThere || needRideBack) &&
|
{(needRideThere || needRideBack) &&
|
||||||
(rideTherePickupPlaceID || rideBackDropoffPlaceID) && (
|
(rideTherePickupPlaceID || rideBackDropoffPlaceID) && (
|
||||||
<div
|
<UIButton
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: confirmed ? green : lightgrey,
|
backgroundColor: confirmed ? green : lightgrey,
|
||||||
color: confirmed ? 'white' : 'black',
|
color: confirmed ? 'white' : 'black',
|
||||||
padding: '1rem',
|
|
||||||
borderRadius: '0.5em',
|
|
||||||
textTransform: 'uppercase',
|
|
||||||
fontWeight: 500,
|
|
||||||
marginTop: '0.5em',
|
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setConfirmed((confirmed) => !confirmed);
|
setConfirmed((confirmed) => !confirmed);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{confirmed ? 'Confirmed' : 'Confirm'}
|
{confirmed ? 'Confirmed' : 'Confirm'}
|
||||||
</div>
|
</UIButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</UISecondaryBox>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
53
src/components/NewUI/EventCreator.tsx
Normal file
53
src/components/NewUI/EventCreator.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
|
@ -7,9 +7,9 @@ export type IGroup = {
|
||||||
|
|
||||||
export default function Group({ events, name }: IGroup) {
|
export default function Group({ events, name }: IGroup) {
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'center', width: '100%' }}>
|
||||||
<h1>{name}</h1>
|
<h1>{name}</h1>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
|
||||||
{events.map((event) => (
|
{events.map((event) => (
|
||||||
<Event {...event} key={event.title} />
|
<Event {...event} key={event.title} />
|
||||||
))}
|
))}
|
||||||
|
|
33
src/components/NewUI/UIButton.tsx
Normal file
33
src/components/NewUI/UIButton.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
22
src/components/NewUI/UIDatetimeInput.tsx
Normal file
22
src/components/NewUI/UIDatetimeInput.tsx
Normal 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)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
26
src/components/NewUI/UISecondaryBox.tsx
Normal file
26
src/components/NewUI/UISecondaryBox.tsx
Normal 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>;
|
||||||
|
}
|
24
src/components/NewUI/UITextInput.tsx
Normal file
24
src/components/NewUI/UITextInput.tsx
Normal 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)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user