add bio/profile

This commit is contained in:
Michael Fatemi 2021-08-22 19:09:56 -04:00
parent e2eaaa0fbb
commit cca03563f2
5 changed files with 101 additions and 0 deletions

View File

@ -19,6 +19,7 @@ const CarpoolPage = lazy(() => import('./Carpool/CarpoolPage'));
const EventPage = lazy(() => import('./Event/EventPage'));
const GroupPage = lazy(() => import('./Group/GroupPage'));
const GroupSharedLinkResolver = lazy(() => import('./GroupSharedLinkResolver'));
const ProfileForSelf = lazy(() => import('./ProfileForSelf/ProfileForSelf'));
const style: CSSProperties = {
display: 'flex',
@ -63,6 +64,7 @@ export default function App() {
<BrowserRouter>
<Switch>
<Route path="/" exact component={WheelShare} />
<Route path="/me" exact component={ProfileForSelf} />
<Route
path="/join/:code"
component={GroupSharedLinkResolver}

View File

@ -3,6 +3,7 @@ import { createContext } from 'react';
export type User = {
name: string;
id: number;
bio: string;
email?: string;
};

View File

@ -30,6 +30,7 @@ export default function Header() {
{me.name}
{me.email && ` (${me.email})`}
<UIPressable onClick={logout}>Log out</UIPressable>
<a href="/me">Profile</a>
<br />
{notifications.length > 0 ? (
<Notifications

View File

@ -0,0 +1,93 @@
import { useCallback, useEffect, useState } from 'react';
import { updateBio } from '../api';
import {
AsyncCallbackStatus,
useAsyncCallback,
} from '../Event/EventAdminControls';
import { useAuth } from '../hooks';
import UIButton from '../UI/UIButton';
import UITextInput from '../UI/UITextInput';
export default function ProfileForSelf() {
const [editingBio, setEditingBio] = useState(false);
const [temporaryBio, setTemporaryBio] = useState('');
const { user: me, refresh: refreshLocalUser } = useAuth();
const [onClickedSaveBio, onClickedSaveBioStatus] = useAsyncCallback(
useCallback(
async (temporaryBio: string) => {
await updateBio(temporaryBio);
refreshLocalUser();
setEditingBio(false);
},
[refreshLocalUser]
)
);
useEffect(() => {
if (me?.bio) {
setTemporaryBio(me?.bio);
}
}, [me?.bio]);
if (!me) {
return null;
}
return (
<div style={{ minWidth: '16rem', width: '20rem' }}>
<h1>{me.name}</h1>
<p>{me.bio}</p>
{editingBio ? (
<>
{onClickedSaveBioStatus === AsyncCallbackStatus.REJECTED && (
<p>Error saving bio.</p>
)}
{onClickedSaveBioStatus !== AsyncCallbackStatus.PENDING ? (
<>
<UITextInput
onChangeText={setTemporaryBio}
value={temporaryBio}
style={{
border: '2px solid grey',
width: '100%',
}}
/>
<UIButton
onClick={() => onClickedSaveBio(temporaryBio)}
style={{
backgroundColor: '#f8f8f8',
width: '100%',
}}
>
Save
</UIButton>
</>
) : (
<UIButton
onClick={() => {}}
style={{
backgroundColor: '#f8f8f8',
width: '100%',
}}
>
Saving...
</UIButton>
)}
</>
) : (
<>
<UIButton
onClick={() => setEditingBio(true)}
style={{
backgroundColor: '#f8f8f8',
width: '100%',
}}
>
Edit Bio
</UIButton>
</>
)}
</div>
);
}

View File

@ -298,3 +298,7 @@ export async function getPotentialInvitees(
): Promise<PotentialInvitee[]> {
return await get(`/carpools/${carpoolId}/potential_invitees`);
}
export async function updateBio(bio: string) {
return await post('/users/@me/bio', { bio });
}