mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-16 00:50:18 -04:00
UI improvements
This commit is contained in:
parent
cb7a6c8d05
commit
6529d1c39f
|
@ -1,6 +1,7 @@
|
||||||
import { CSSProperties, lazy, Suspense } from 'react';
|
import { CSSProperties, lazy, Suspense } from 'react';
|
||||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||||
import NotificationsProvider from '../state/Notifications/NotificationsProvider';
|
import NotificationsProvider from '../state/Notifications/NotificationsProvider';
|
||||||
|
import Header from './Header/Header';
|
||||||
import { useMe } from './hooks';
|
import { useMe } from './hooks';
|
||||||
import WheelShare from './WheelShare';
|
import WheelShare from './WheelShare';
|
||||||
import WheelShareLoggedOut from './WheelShareLoggedOut';
|
import WheelShareLoggedOut from './WheelShareLoggedOut';
|
||||||
|
@ -31,11 +32,8 @@ export default function App() {
|
||||||
<Switch>
|
<Switch>
|
||||||
{user ? (
|
{user ? (
|
||||||
<NotificationsProvider>
|
<NotificationsProvider>
|
||||||
|
<Header />
|
||||||
<Route path="/" exact component={WheelShare} />
|
<Route path="/" exact component={WheelShare} />
|
||||||
<Route
|
|
||||||
component={Authenticator}
|
|
||||||
path="/auth/:provider/callback"
|
|
||||||
/>
|
|
||||||
<Route path="/carpools/:id" component={CarpoolPage} />
|
<Route path="/carpools/:id" component={CarpoolPage} />
|
||||||
<Route path="/events/:id" component={EventPage} />
|
<Route path="/events/:id" component={EventPage} />
|
||||||
<Route path="/groups/:id" component={Group} />
|
<Route path="/groups/:id" component={Group} />
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import Header from '../Header/Header';
|
|
||||||
import Carpool from './Carpool';
|
import Carpool from './Carpool';
|
||||||
|
|
||||||
export default function CarpoolPage() {
|
export default function CarpoolPage() {
|
||||||
const id = +useParams<{ id: string }>().id;
|
const id = +useParams<{ id: string }>().id;
|
||||||
|
|
||||||
return (
|
return <Carpool id={id} />;
|
||||||
<>
|
|
||||||
<Header />
|
|
||||||
<Carpool id={id} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { green, lightgrey } from '../../lib/colors';
|
import { getEvent } from '../api';
|
||||||
import getPlaceDetails from '../../lib/getPlaceDetails';
|
|
||||||
import { addOrUpdateEventSignup, getEvent, removeEventSignup } from '../api';
|
|
||||||
import { useMe } from '../hooks';
|
|
||||||
import { IEvent } from '../types';
|
import { IEvent } from '../types';
|
||||||
import UIButton from '../UI/UIButton';
|
|
||||||
import UILink from '../UI/UILink';
|
import UILink from '../UI/UILink';
|
||||||
import UIPlacesAutocomplete from '../UI/UIPlacesAutocomplete';
|
|
||||||
import UISecondaryBox from '../UI/UISecondaryBox';
|
import UISecondaryBox from '../UI/UISecondaryBox';
|
||||||
import UISecondaryHeader from '../UI/UISecondaryHeader';
|
import UISecondaryHeader from '../UI/UISecondaryHeader';
|
||||||
import useImmutable from '../useImmutable';
|
import useImmutable from '../useImmutable';
|
||||||
import EventCarpools from './EventCarpools';
|
|
||||||
import EventContext from './EventContext';
|
import EventContext from './EventContext';
|
||||||
import EventDetails from './EventDetails';
|
import EventDetails from './EventDetails';
|
||||||
import EventSignups from './EventSignups';
|
import EventInterestForm from './EventInterestForm';
|
||||||
|
import EventPlaceholder from './EventPlaceholder';
|
||||||
|
|
||||||
function GroupName({ group }: { group: IEvent['group'] }) {
|
function GroupName({ group }: { group: IEvent['group'] }) {
|
||||||
return <UILink href={`/groups/${group.id}`}>{group.name}</UILink>;
|
return <UILink href={`/groups/${group.id}`}>{group.name}</UILink>;
|
||||||
|
@ -26,89 +21,28 @@ export default function Event({
|
||||||
id: number;
|
id: number;
|
||||||
initial?: IEvent;
|
initial?: IEvent;
|
||||||
}) {
|
}) {
|
||||||
const [event, setEvent] = useImmutable<IEvent>({
|
const [event, setEvent] = useImmutable<IEvent | null>(initial ?? null);
|
||||||
id,
|
const [loading, setLoading] = useState(true);
|
||||||
name: '',
|
|
||||||
group: {
|
|
||||||
id: 0,
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
signups: {},
|
|
||||||
carpools: [],
|
|
||||||
startTime: '',
|
|
||||||
endTime: '',
|
|
||||||
daysOfWeek: 0,
|
|
||||||
placeId: '',
|
|
||||||
formattedAddress: '',
|
|
||||||
latitude: 0,
|
|
||||||
longitude: 0,
|
|
||||||
duration: 0,
|
|
||||||
...(initial || {}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const [found, setFound] = useState(false);
|
|
||||||
|
|
||||||
const me = useMe() || { id: 0, name: '' };
|
|
||||||
|
|
||||||
const [tentativeInvites] = useImmutable<Record<number, boolean>>({});
|
const [tentativeInvites] = useImmutable<Record<number, boolean>>({});
|
||||||
|
|
||||||
const refresh = useCallback(() => {
|
const refresh = useCallback(() => {
|
||||||
getEvent(id).then((e) => {
|
setLoading(true);
|
||||||
if (e) {
|
getEvent(id)
|
||||||
setFound(true);
|
.then((e) => e && setEvent(e))
|
||||||
setEvent(e);
|
.finally(() => setLoading(false));
|
||||||
} else {
|
|
||||||
setFound(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, [id, setEvent]);
|
}, [id, setEvent]);
|
||||||
|
|
||||||
useEffect(refresh, [refresh]);
|
useEffect(refresh, [refresh]);
|
||||||
|
|
||||||
const updateSignup = useCallback(
|
if (loading) {
|
||||||
async (placeId: string | null) => {
|
return <EventPlaceholder />;
|
||||||
await addOrUpdateEventSignup(id, placeId);
|
|
||||||
|
|
||||||
if (placeId) {
|
|
||||||
const details = await getPlaceDetails(placeId);
|
|
||||||
|
|
||||||
event.signups[me.id] = {
|
|
||||||
user: { id: me.id, name: me.name },
|
|
||||||
placeId,
|
|
||||||
...details,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
event.signups[me.id] = {
|
|
||||||
user: { id: me.id, name: me.name },
|
|
||||||
placeId: null,
|
|
||||||
latitude: null,
|
|
||||||
longitude: null,
|
|
||||||
formattedAddress: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[event.signups, id, me.id, me.name]
|
|
||||||
);
|
|
||||||
|
|
||||||
const removeSignup = useCallback(async () => {
|
|
||||||
await removeEventSignup(id);
|
|
||||||
|
|
||||||
if (event.signups[me.id]) {
|
|
||||||
delete event.signups[me.id];
|
|
||||||
}
|
|
||||||
}, [id, me.id, event.signups]);
|
|
||||||
|
|
||||||
const interested = !!event.signups[me.id];
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>Event Not Found</h1>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, group, formattedAddress, startTime, endTime } = event;
|
if (!event) {
|
||||||
|
return <h1>Event Not Found</h1>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { name, group } = event;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EventContext.Provider
|
<EventContext.Provider
|
||||||
|
@ -124,36 +58,8 @@ export default function Event({
|
||||||
<UISecondaryHeader>{name}</UISecondaryHeader>
|
<UISecondaryHeader>{name}</UISecondaryHeader>
|
||||||
{group && <GroupName group={group} />}
|
{group && <GroupName group={group} />}
|
||||||
</div>
|
</div>
|
||||||
<EventDetails {...{ startTime, endTime, formattedAddress }} />
|
<EventDetails />
|
||||||
<UIButton
|
<EventInterestForm />
|
||||||
onClick={interested ? () => removeSignup() : () => updateSignup(null)}
|
|
||||||
style={{
|
|
||||||
backgroundColor: interested ? green : lightgrey,
|
|
||||||
color: interested ? 'white' : 'black',
|
|
||||||
transition: 'color 0.2s, background-color 0.2s',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{interested ? 'Interested' : 'Not interested'}
|
|
||||||
</UIButton>
|
|
||||||
{interested && (
|
|
||||||
<>
|
|
||||||
<UIPlacesAutocomplete
|
|
||||||
placeholder="Pickup and dropoff location"
|
|
||||||
onSelected={(_address, placeId) => {
|
|
||||||
updateSignup(placeId);
|
|
||||||
}}
|
|
||||||
style={
|
|
||||||
event.signups[me.id]?.placeId != null
|
|
||||||
? { border: '2px solid ' + green }
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
placeId={event.signups[me.id]?.placeId}
|
|
||||||
/>
|
|
||||||
<br />
|
|
||||||
<EventCarpools />
|
|
||||||
{event.signups !== null && <EventSignups />}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</UISecondaryBox>
|
</UISecondaryBox>
|
||||||
</EventContext.Provider>
|
</EventContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
import formatStartAndEndTime from '../../lib/dates';
|
import formatStartAndEndTime from '../../lib/dates';
|
||||||
import EventIcon from '@material-ui/icons/Event';
|
import EventIcon from '@material-ui/icons/Event';
|
||||||
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import EventContext from './EventContext';
|
||||||
|
|
||||||
|
export default function EventDetails() {
|
||||||
|
const { startTime, endTime, formattedAddress } =
|
||||||
|
useContext(EventContext).event;
|
||||||
|
|
||||||
export default function Details({
|
|
||||||
startTime,
|
|
||||||
endTime,
|
|
||||||
formattedAddress,
|
|
||||||
}: {
|
|
||||||
startTime: string;
|
|
||||||
endTime: string | null;
|
|
||||||
formattedAddress: string;
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
|
@ -37,3 +37,7 @@ export function useMyCarpool() {
|
||||||
|
|
||||||
return carpool;
|
return carpool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useMutableEvent() {
|
||||||
|
return useContext(EventContext).event;
|
||||||
|
}
|
||||||
|
|
84
src/components/Event/EventInterestForm.tsx
Normal file
84
src/components/Event/EventInterestForm.tsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { green, lightgrey } from '../../lib/colors';
|
||||||
|
import getPlaceDetails from '../../lib/getPlaceDetails';
|
||||||
|
import { addOrUpdateEventSignup, removeEventSignup } from '../api';
|
||||||
|
import { useMe } from '../hooks';
|
||||||
|
import UIButton from '../UI/UIButton';
|
||||||
|
import UIPlacesAutocomplete from '../UI/UIPlacesAutocomplete';
|
||||||
|
import EventCarpools from './EventCarpools';
|
||||||
|
import { useMutableEvent } from './EventHooks';
|
||||||
|
import EventSignups from './EventSignups';
|
||||||
|
|
||||||
|
export default function EventInterestForm() {
|
||||||
|
const event = useMutableEvent();
|
||||||
|
const me = useMe() || { id: 0, name: '' };
|
||||||
|
|
||||||
|
const updateSignup = useCallback(
|
||||||
|
async (placeId: string | null) => {
|
||||||
|
await addOrUpdateEventSignup(event.id, placeId);
|
||||||
|
|
||||||
|
if (placeId) {
|
||||||
|
const details = await getPlaceDetails(placeId);
|
||||||
|
|
||||||
|
event.signups[me.id] = {
|
||||||
|
user: { id: me.id, name: me.name },
|
||||||
|
placeId,
|
||||||
|
...details,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
event.signups[me.id] = {
|
||||||
|
user: { id: me.id, name: me.name },
|
||||||
|
placeId: null,
|
||||||
|
latitude: null,
|
||||||
|
longitude: null,
|
||||||
|
formattedAddress: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[event.id, event.signups, me.id, me.name]
|
||||||
|
);
|
||||||
|
|
||||||
|
const removeSignup = useCallback(async () => {
|
||||||
|
await removeEventSignup(event.id);
|
||||||
|
|
||||||
|
if (event.signups[me.id]) {
|
||||||
|
delete event.signups[me.id];
|
||||||
|
}
|
||||||
|
}, [event.id, event.signups, me.id]);
|
||||||
|
|
||||||
|
const interested = !!event.signups[me.id];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<UIButton
|
||||||
|
onClick={interested ? () => removeSignup() : () => updateSignup(null)}
|
||||||
|
style={{
|
||||||
|
backgroundColor: interested ? green : lightgrey,
|
||||||
|
color: interested ? 'white' : 'black',
|
||||||
|
transition: 'color 0.2s, background-color 0.2s',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{interested ? 'Interested' : 'Not interested'}
|
||||||
|
</UIButton>
|
||||||
|
{interested && (
|
||||||
|
<>
|
||||||
|
<UIPlacesAutocomplete
|
||||||
|
placeholder="Pickup and dropoff location"
|
||||||
|
onSelected={(_address, placeId) => {
|
||||||
|
updateSignup(placeId);
|
||||||
|
}}
|
||||||
|
style={
|
||||||
|
event.signups[me.id]?.placeId != null
|
||||||
|
? { border: '2px solid ' + green }
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
placeId={event.signups[me.id]?.placeId}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<EventCarpools />
|
||||||
|
{event.signups !== null && <EventSignups />}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,14 +1,8 @@
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import Header from '../Header/Header';
|
|
||||||
import Event from './Event';
|
import Event from './Event';
|
||||||
|
|
||||||
export default function EventPage() {
|
export default function EventPage() {
|
||||||
const id = +useParams<{ id: string }>().id;
|
const id = +useParams<{ id: string }>().id;
|
||||||
|
|
||||||
return (
|
return <Event id={id} />;
|
||||||
<>
|
|
||||||
<Header />
|
|
||||||
<Event id={id} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
7
src/components/Event/EventPlaceholder.tsx
Normal file
7
src/components/Event/EventPlaceholder.tsx
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import UISecondaryBox from '../UI/UISecondaryBox';
|
||||||
|
|
||||||
|
export default function EventPlaceholder() {
|
||||||
|
return (
|
||||||
|
<UISecondaryBox style={{ height: '10rem' }}>Loading...</UISecondaryBox>
|
||||||
|
);
|
||||||
|
}
|
|
@ -84,7 +84,7 @@ export default function EventCreator({ group }: { group: IGroup }) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox style={{ width: '100%', boxSizing: 'border-box' }}>
|
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
||||||
<h1 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
|
<h1 style={{ textAlign: 'center', marginBottom: '0.5rem' }}>
|
||||||
Create Event
|
Create Event
|
||||||
</h1>
|
</h1>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { GroupContext } from '../Group/Group';
|
import { GroupContext } from '../Group/Group';
|
||||||
|
import UIPressable from '../UI/UIPressable';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
import EventCreator from './EventCreator';
|
import EventCreator from './EventCreator';
|
||||||
|
|
||||||
|
@ -8,22 +9,14 @@ export default function EventCreatorLink() {
|
||||||
const { group } = useContext(GroupContext);
|
const { group } = useContext(GroupContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<div
|
<UIPressable onClick={toggle}>Create Event</UIPressable>
|
||||||
style={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
|
||||||
onClick={toggle}
|
|
||||||
>
|
|
||||||
Create Event
|
|
||||||
</div>
|
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<>
|
||||||
<br />
|
<br />
|
||||||
<EventCreator group={group} />
|
<EventCreator group={group} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,48 +19,50 @@ const DEFAULT_GROUP = (): IGroup => ({
|
||||||
export const GroupContext = createContext({ group: DEFAULT_GROUP() });
|
export const GroupContext = createContext({ group: DEFAULT_GROUP() });
|
||||||
|
|
||||||
export default function Group({ id }: { id: number }) {
|
export default function Group({ id }: { id: number }) {
|
||||||
const [group, setGroup] = useImmutable<IGroup>(DEFAULT_GROUP());
|
const [group, setGroup] = useImmutable<IGroup | null>(null);
|
||||||
const [found, setFound] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getGroup(id)
|
getGroup(id)
|
||||||
.then(setGroup)
|
.then(setGroup)
|
||||||
.catch(() => setFound(false));
|
.finally(() => setLoading(false));
|
||||||
}, [id, setGroup]);
|
}, [id, setGroup]);
|
||||||
|
|
||||||
return found ? (
|
if (loading) {
|
||||||
|
return <h1>Loading...</h1>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return group ? (
|
||||||
<GroupContext.Provider value={{ group }}>
|
<GroupContext.Provider value={{ group }}>
|
||||||
|
<h1>{group.name}</h1>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
textAlign: 'center',
|
display: 'flex',
|
||||||
maxWidth: '30rem',
|
flexDirection: 'column',
|
||||||
marginLeft: 'auto',
|
width: '100%',
|
||||||
marginRight: 'auto',
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1>{group.name}</h1>
|
|
||||||
<UILink href="/">Home</UILink>
|
<UILink href="/">Home</UILink>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
|
||||||
<GroupMembersLink />
|
<GroupMembersLink />
|
||||||
<br />
|
<br />
|
||||||
<GroupSettingsLink />
|
<GroupSettingsLink />
|
||||||
<br />
|
<br />
|
||||||
<EventCreatorLink />
|
<EventCreatorLink />
|
||||||
<br />
|
|
||||||
|
|
||||||
{group.events.length > 0 ? (
|
|
||||||
<EventStream events={group.events} />
|
|
||||||
) : (
|
|
||||||
<span>
|
|
||||||
There are no events yet. Click 'create event' above to add one!
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{group.events.length > 0 ? (
|
||||||
|
<EventStream events={group.events} />
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
There are no events yet. Click 'create event' above to add one!
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</GroupContext.Provider>
|
</GroupContext.Provider>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<h1>Group not found</h1>
|
||||||
<h1>Group not found</h1>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useContext } from 'react';
|
import { useCallback, useContext, useState } from 'react';
|
||||||
import { lightgrey } from '../../lib/colors';
|
import { lightgrey } from '../../lib/colors';
|
||||||
import { generateCode, resetCode } from '../api';
|
import { generateCode, resetCode } from '../api';
|
||||||
import UIButton from '../UI/UIButton';
|
import UIButton from '../UI/UIButton';
|
||||||
|
@ -7,6 +7,8 @@ import { GroupContext } from './Group';
|
||||||
export default function GroupInviteCodeGenerator() {
|
export default function GroupInviteCodeGenerator() {
|
||||||
const { group } = useContext(GroupContext);
|
const { group } = useContext(GroupContext);
|
||||||
|
|
||||||
|
const [shown, setShown] = useState(false);
|
||||||
|
|
||||||
const generateJoinCode = useCallback(() => {
|
const generateJoinCode = useCallback(() => {
|
||||||
generateCode(group.id).then((code) => {
|
generateCode(group.id).then((code) => {
|
||||||
group.joinCode = code;
|
group.joinCode = code;
|
||||||
|
@ -22,11 +24,15 @@ export default function GroupInviteCodeGenerator() {
|
||||||
if (group.joinCode) {
|
if (group.joinCode) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span>
|
<span style={{ userSelect: 'none' }}>
|
||||||
Join this group with the code{' '}
|
Join this group with the code{' '}
|
||||||
<b>
|
<code
|
||||||
<code>{group.joinCode}</code>
|
style={{ userSelect: 'text' }}
|
||||||
</b>
|
onClick={() => setShown((shown) => !shown)}
|
||||||
|
>
|
||||||
|
{shown ? group.joinCode : 'XXXXXX'}
|
||||||
|
</code>{' '}
|
||||||
|
(click to show/hide)
|
||||||
</span>
|
</span>
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
<UIButton
|
<UIButton
|
||||||
|
|
|
@ -17,14 +17,15 @@ export default function GroupMembersLink() {
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<>
|
||||||
<br />
|
<br />
|
||||||
<UISecondaryBox>
|
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
||||||
<h1>Members</h1>
|
<h1>Members</h1>
|
||||||
|
|
||||||
<GroupInviteCodeGenerator />
|
|
||||||
|
|
||||||
{group.users.map(({ name }) => (
|
{group.users.map(({ name }) => (
|
||||||
<span key={name}>{name}</span>
|
<span key={name}>{name}</span>
|
||||||
))}
|
))}
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<GroupInviteCodeGenerator />
|
||||||
</UISecondaryBox>
|
</UISecondaryBox>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default function GroupSettings({ group }: { group: IGroup }) {
|
||||||
}, [group.id]);
|
}, [group.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UISecondaryBox>
|
<UISecondaryBox style={{ width: '100%', textAlign: 'center' }}>
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
{deletionSuccessful !== true && (
|
{deletionSuccessful !== true && (
|
||||||
<UIPressable onClick={onClickedDelete}>Delete Group</UIPressable>
|
<UIPressable onClick={onClickedDelete}>Delete Group</UIPressable>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
import UIPressable from '../UI/UIPressable';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
import { GroupContext } from './Group';
|
import { GroupContext } from './Group';
|
||||||
import GroupSettings from './GroupSettings';
|
import GroupSettings from './GroupSettings';
|
||||||
|
@ -8,22 +9,14 @@ export default function GroupSettingsLink() {
|
||||||
const { group } = useContext(GroupContext);
|
const { group } = useContext(GroupContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<div
|
<UIPressable onClick={toggle}>Settings</UIPressable>
|
||||||
style={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
}}
|
|
||||||
onClick={toggle}
|
|
||||||
>
|
|
||||||
Settings
|
|
||||||
</div>
|
|
||||||
{open && (
|
{open && (
|
||||||
<>
|
<>
|
||||||
<br />
|
<br />
|
||||||
<GroupSettings group={group} />
|
<GroupSettings group={group} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import ActiveCarpools from './ActiveCarpools/ActiveCarpools';
|
import ActiveCarpools from './ActiveCarpools/ActiveCarpools';
|
||||||
import ActiveEvents from './ActiveEvents/Events';
|
import ActiveEvents from './ActiveEvents/Events';
|
||||||
import Groups from './Groups/Groups';
|
import Groups from './Groups/Groups';
|
||||||
import Header from './Header/Header';
|
|
||||||
|
|
||||||
export default function WheelShare() {
|
export default function WheelShare() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header />
|
|
||||||
|
|
||||||
<Groups />
|
<Groups />
|
||||||
<ActiveCarpools />
|
<ActiveCarpools />
|
||||||
<ActiveEvents />
|
<ActiveEvents />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user