Merge branch 'main' of github.com:myfatemi04/wheelshare-frontend into main

This commit is contained in:
Joshua Hsueh 2021-07-06 22:44:29 -04:00
commit efa076e6d5
6 changed files with 166 additions and 35649 deletions

35636
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,17 +3,25 @@ import { Redirect, useLocation, useParams } from 'react-router-dom';
import AuthenticationContext from './AuthenticationContext';
import { createSession } from './createSession';
function useCode() {
function useCodeAndError() {
const location = useLocation();
const query = new URLSearchParams(location.search);
const code = query.get('code');
const error = query.get('error');
return code;
return [code, error];
}
function inferRedirectUrl() {
// Strip query parameters
const { protocol, host, pathname } = window.location;
const redirectUrl = `${protocol}//${host}${pathname}`;
return redirectUrl;
}
export default function Authenticator() {
const { provider } = useParams<{ provider: string }>();
const code = useCode();
const [code, error] = useCodeAndError();
const { refresh } = useContext(AuthenticationContext);
const [pending, setPending] = useState(true);
@ -28,27 +36,54 @@ export default function Authenticator() {
}, [token]);
useEffect(() => {
setPending(true);
createSession(code!)
.then(({ token }) => {
setToken(token ?? null);
})
.finally(() => setPending(false));
if (code) {
setPending(true);
createSession(code, inferRedirectUrl())
.then(({ token }) => {
setToken(token ?? null);
})
.finally(() => setPending(false));
}
}, [code, provider]);
useEffect(() => {
// Refresh when the token changes
refresh();
}, [token, refresh]);
let children: JSX.Element;
if (pending) {
if (error != null) {
switch (error) {
case 'access_denied':
children = (
<>
<h1>Sign In Error</h1>
We couldn't use your Ion account to log in.
<br />
<br />
<a href="/">Home</a>
</>
);
break;
default:
console.error('Unhandled OAuth error case:', error);
children = <h1>Sign In Error</h1>;
}
} else if (pending) {
children = <h1>Signing In</h1>;
} else if (token) {
children = <Redirect to="/" />;
} else {
// If we aren't pending anymore, but don't have a token, we must have errored
children = <h1>Sign In Error</h1>;
children = (
<>
<h1>Sign In Error</h1>
<br />
<br />
<a href="/">Home</a>
</>
);
}
return (

View File

@ -1,7 +1,7 @@
export async function createSession(code: string) {
export async function createSession(code: string, redirectUrl: string) {
const res = await fetch('http://localhost:5000/create_session', {
method: 'post',
body: JSON.stringify({ code }),
body: JSON.stringify({ code, redirectUrl }),
headers: {
'Content-Type': 'application/json',
},

View File

@ -0,0 +1,25 @@
import { ICarpool } from './types';
import UISecondaryBox from './UISecondaryBox';
function MemberList({ members }: { members: ICarpool['members'] }) {
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
{members.length > 0
? members.map((member) => {
return <div key={member.id}>{member.name}</div>;
})
: 'This carpool has no members.'}
</div>
);
}
export default function Carpool({ carpool }: { carpool: ICarpool }) {
return (
<UISecondaryBox style={{ width: '100%', alignItems: 'center' }}>
<h2 style={{ textAlign: 'center' }}>{carpool.name}</h2>
{carpool.description}
<h3>Members</h3>
<MemberList members={carpool.members} />
</UISecondaryBox>
);
}

View File

@ -1,7 +1,9 @@
import { CSSProperties } from 'react';
import logout from './Authentication/logout';
import Carpool from './Carpool';
import Events from './Events';
import Groups from './Groups';
import { useMe } from './hooks';
import UIPressable from './UIPressable';
import UIPrimaryTitle from './UIPrimaryTitle';
@ -16,10 +18,24 @@ const style: CSSProperties = {
};
export default function WheelShare() {
const user = useMe()!;
return (
<div style={style}>
<UIPrimaryTitle>WheelShare</UIPrimaryTitle>
<Carpool
carpool={{
name: 'Carpool',
id: 0,
description: 'Test carpool',
eventId: null,
members: [],
invitations: [],
}}
/>
{user.name}
<UIPressable onClick={logout}>Log out</UIPressable>
<Groups />

77
src/components/types.ts Normal file
View File

@ -0,0 +1,77 @@
/**
* Model User
*/
export type IUser = {
id: number;
email: string;
name: string | null;
};
/**
* Model Invitation
*/
export type IInvitation = {
userId: number;
carpoolId: number;
isRequest: boolean;
sentTime: Date;
};
/**
* Model Carpool
*/
export type ICarpool = {
id: number;
name: string;
description: string;
eventId: number | null;
event?: IEvent;
members: {
id: number;
name: string;
}[];
invitations: IInvitation[];
};
/**
* Model Group
*/
export type IGroup = {
id: number;
name: string;
};
/**
* Model Event
*/
export type IEvent = {
id: number;
name: string;
groupId: number;
startTime: Date;
duration: number;
endTime: Date | null;
daysOfWeek: number;
placeId: string;
formattedAddress: string;
latitude: number;
longitude: number;
};
/**
* Model EventSignup
*/
export type IEventSignup = {
eventId: number;
userId: number;
placeId: string | null;
formattedAddress: string | null;
latitude: number | null;
longitude: number | null;
};