Skip to content

Commit

Permalink
#106 Loading indicators on group routes
Browse files Browse the repository at this point in the history
  • Loading branch information
blms committed Dec 28, 2020
1 parent eff051b commit e640ba9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 21 deletions.
60 changes: 47 additions & 13 deletions src/pages/groups/[id]/edit.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useSession } from 'next-auth/client';
import { Pencil, TrashFill } from 'react-bootstrap-icons';
import { useState, useRef } from 'react';
import { useState, useRef, useEffect } from 'react';
import {
Button,
Card,
Expand Down Expand Up @@ -40,6 +40,15 @@ const EditGroup = ({
statefulSession,
}) => {
const [session, loading] = useSession();
const [pageLoading, setPageLoading] = useState(true);

useEffect(() => {
if (loading === false) {
setPageLoading(false);
}
}, [loading]);


const [alerts, setAlerts] = useState(initAlerts || []);

const router = useRouter();
Expand Down Expand Up @@ -80,10 +89,10 @@ const EditGroup = ({
return (
<Layout alerts={alerts} type="group" title={`Manage Group: ${group.name}`} statefulSession={statefulSession}>
<Card>
{!session && loading && (
{((!session && loading) || pageLoading) && (
<LoadingSpinner />
)}
{session && !loading
{session && !loading && !pageLoading
&& (session.user.role === 'admin'
|| roleInGroup(session) === 'owner'
|| roleInGroup(session) === 'manager')
Expand Down Expand Up @@ -115,6 +124,7 @@ const EditGroup = ({
})}
onSubmit={(values, actions) => {
setTimeout(() => {
setPageLoading(true);
renameGroup(group, values.groupName).then(() => {
setAlerts([...alerts, {
text: 'Group successfully renamed.',
Expand All @@ -123,8 +133,10 @@ const EditGroup = ({
setState({
...state, editingGroupName: false, groupName: values.groupName,
});
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
actions.setSubmitting(false);
}, 1000);
Expand Down Expand Up @@ -200,6 +212,7 @@ const EditGroup = ({
<Dropdown.Item
disabled={member.role === 'member'}
onClick={() => {
setPageLoading(true);
changeUserRole(group, member, 'member').then(() => {
const newArray = [...state.members];
const newMember = { ...member, role: 'member' };
Expand All @@ -209,8 +222,10 @@ const EditGroup = ({
text: 'User\'s role changed successfully.',
variant: 'success',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Expand All @@ -219,6 +234,7 @@ const EditGroup = ({
<Dropdown.Item
disabled={member.role === 'manager'}
onClick={() => {
setPageLoading(true);
changeUserRole(group, member, 'manager').then(() => {
const newArray = [...state.members];
const newMember = { ...member, role: 'manager' };
Expand All @@ -228,8 +244,10 @@ const EditGroup = ({
text: 'User\'s role changed successfully.',
variant: 'success',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Expand All @@ -245,16 +263,21 @@ const EditGroup = ({
variant="outline-danger"
className="btn-sm"
type="button"
onClick={() => removeUserFromGroup(group, member).then(() => {
const members = state.members.filter((val, i) => i !== idx);
setState({ ...state, members });
setAlerts([...alerts, {
text: 'User successfully removed from group.',
variant: 'warning',
}]);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
})}
onClick={() => {
setPageLoading(true);
removeUserFromGroup(group, member).then(() => {
const members = state.members.filter((val, i) => i !== idx);
setState({ ...state, members });
setAlerts([...alerts, {
text: 'User successfully removed from group.',
variant: 'warning',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Remove
</Button>
Expand All @@ -274,6 +297,7 @@ const EditGroup = ({
<Button
variant="outline-secondary"
onClick={(event) => {
setPageLoading(true);
event.target.setAttribute('disabled', 'true');
generateInviteToken(group).then((data) => {
const inviteUrl = `${baseUrl}/auth/signin?callbackUrl=${baseUrl}&groupToken=${data.value.inviteToken}`;
Expand All @@ -282,8 +306,10 @@ const EditGroup = ({
text: 'Group invite token created successfully.',
variant: 'success',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Expand All @@ -304,14 +330,17 @@ const EditGroup = ({
size="sm"
style={{ padding: 0 }}
onClick={() => {
setPageLoading(true);
deleteInviteToken(group).then(() => {
setState({ ...state, inviteUrl: '' });
setAlerts([...alerts, {
text: 'Group invite token deleted successfully.',
variant: 'warning',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Expand Down Expand Up @@ -373,6 +402,7 @@ const EditGroup = ({
})}
onSubmit={(values, actions) => {
setTimeout(async () => {
setPageLoading(true);
await addUserToGroup(group, values.email).then((data) => {
const { _id, name } = data[state.members.length].value;
const { email } = values;
Expand All @@ -385,8 +415,10 @@ const EditGroup = ({
variant: 'success',
}]);
actions.resetForm();
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
actions.setSubmitting(false);
}, 1000);
Expand Down Expand Up @@ -457,6 +489,7 @@ const EditGroup = ({
handleCloseModal={handleCloseModal}
show={state.showModal}
onClick={(event) => {
setPageLoading(true);
event.target.setAttribute('disabled', 'true');
deleteGroup(group).then(() => {
router.push({
Expand All @@ -468,6 +501,7 @@ const EditGroup = ({
}, '/groups');
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
handleCloseModal();
}}
Expand Down
18 changes: 14 additions & 4 deletions src/pages/groups/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { deepEqual } from '../../utils/objectUtil';
const GroupList = ({ query, initAlerts, statefulSession }) => {
const [session, loading] = useSession();
const [alerts, setAlerts] = useState(initAlerts);
const [pageLoading, setPageLoading] = useState(true);
const [groups, setGroups] = useState([]);

const [showModal, setShowModal] = useState('');
Expand All @@ -30,22 +31,25 @@ const GroupList = ({ query, initAlerts, statefulSession }) => {
};

if (query.deletedGroupId && groups.some((g) => g.id === query.deletedGroupId)) {
setGroups(groups.filter((g) => g.id !== query.deletedGroupId));
setGroups(groups.filter((g) => g.id !== query.deletedGroupId))
.then(setPageLoading(false))
.catch((err) => setAlerts([...alerts, { text: err.message, variant: 'danger' }]));
}

React.useEffect(() => {
if (session && !deepEqual(session.user.groups, groups)) {
setGroups(session.user.groups);
setPageLoading(false);
}
}, [session]);

return (
<Layout alerts={alerts} type="group" statefulSession={statefulSession}>
<Card>
{!session && loading && (
{((!session && loading) || pageLoading) && (
<LoadingSpinner />
)}
{session && (
{session && !loading && !pageLoading && (
<>
<Card.Header>
Groups
Expand Down Expand Up @@ -88,16 +92,19 @@ const GroupList = ({ query, initAlerts, statefulSession }) => {
<Button
variant="outline-danger"
onClick={async () => {
setPageLoading(true);
await getUserByEmail(session.user.email).then((user) => {
removeUserFromGroup(group, user).then(() => {
setGroups(groups.filter((g) => g.id !== group.id));
setAlerts([...alerts, {
text: 'You have successfully left the group.',
variant: 'warning',
}]);
setPageLoading(false);
});
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
}}
>
Expand All @@ -113,7 +120,7 @@ const GroupList = ({ query, initAlerts, statefulSession }) => {
onClick={handleShowModal}
data-key={group.id}
>
<TrashFill
<TrashFill
data-key={group.id}
className="align-text-bottom mr-1"
/>
Expand All @@ -125,15 +132,18 @@ const GroupList = ({ query, initAlerts, statefulSession }) => {
handleCloseModal={handleCloseModal}
show={showModal === group.id}
onClick={(event) => {
setPageLoading(true);
event.target.setAttribute('disabled', 'true');
deleteGroupById(group.id).then(() => {
setGroups(groups.filter((g) => g.id !== group.id));
setAlerts([...alerts, {
text: 'You have successfully deleted the group.',
variant: 'warning',
}]);
setPageLoading(false);
}).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
handleCloseModal();
}}
Expand Down
17 changes: 13 additions & 4 deletions src/pages/groups/new.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fetch from 'unfetch';
import { Formik } from 'formik';
import { useSession } from 'next-auth/client';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import {
Button, Card, Col, Form, Row,
} from 'react-bootstrap';
Expand All @@ -12,9 +12,16 @@ import Layout from '../../components/Layout';
import LoadingSpinner from '../../components/LoadingSpinner';

const NewGroup = ({ statefulSession }) => {
const [session] = useSession();
const [session, loading] = useSession();
const [pageLoading, setPageLoading] = useState(true);
const [alerts, setAlerts] = useState([]);

useEffect(() => {
if (loading === false) {
setPageLoading(false);
}
}, [loading]);

const createGroup = async (values) => {
const url = '/api/group';
const { name } = values;
Expand Down Expand Up @@ -56,18 +63,20 @@ const NewGroup = ({ statefulSession }) => {
<Layout alerts={alerts} type="group" title="New Group" statefulSession={statefulSession}>
<Col lg="8" className="mx-auto">
<Card>
{!session && (
{((!session && loading) || pageLoading) && (
<LoadingSpinner />
)}
{session && (
{session && !loading && !pageLoading && (
<Card.Body className="text-center">
<Card.Title>Create a new group</Card.Title>

<Formik
onSubmit={(values, actions) => {
setPageLoading(true);
setTimeout(() => {
createGroup(values).catch((err) => {
setAlerts([...alerts, { text: err.message, variant: 'danger' }]);
setPageLoading(false);
});
actions.setSubmitting(false);
}, 1000);
Expand Down

0 comments on commit e640ba9

Please sign in to comment.