aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hooks/APIClient.ts17
-rw-r--r--src/pages/ProfilePage/ProfileInfo.tsx9
-rw-r--r--src/pages/ProfilePage/ProfilePage.tsx57
3 files changed, 40 insertions, 43 deletions
diff --git a/src/hooks/APIClient.ts b/src/hooks/APIClient.ts
new file mode 100644
index 0000000..fa23a21
--- /dev/null
+++ b/src/hooks/APIClient.ts
@@ -0,0 +1,17 @@
+import useSWR from 'swr';
+import { get } from '../requests';
+
+
+const fetcher = (endpoint: string) => get(endpoint).then(response => response.data);
+
+
+export const useUser = (username: string) => {
+ return useSWR(
+ `/users?username=${username}`,
+ (url: string) => get(url).then(response => response.data[0])
+ );
+};
+
+export const useProfile = (id: string) => {
+ return useSWR(id && `/profiles/${id}`, fetcher, { initialData: [] });
+};
diff --git a/src/pages/ProfilePage/ProfileInfo.tsx b/src/pages/ProfilePage/ProfileInfo.tsx
index e4ef66a..8b1447a 100644
--- a/src/pages/ProfilePage/ProfileInfo.tsx
+++ b/src/pages/ProfilePage/ProfileInfo.tsx
@@ -16,7 +16,6 @@ interface PropTypes {
totalVotes: number;
userInfo: User | undefined;
setUserInfo: (userInfo: User) => void;
- isLoading: boolean;
}
const useStyles = makeStyles(theme => ({
@@ -83,7 +82,7 @@ const useStyles = makeStyles(theme => ({
const ProfileInfo: React.FC<PropTypes> = ({
- savedPolls, totalVotes, setUserInfo, userInfo, isLoading
+ savedPolls, totalVotes, setUserInfo, userInfo
}) => {
const classes = useStyles();
const [input, setInput] = useState(false);
@@ -105,7 +104,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
return (
<div className={classes.root}>
{
- isLoading
+ !userInfo
? <Skeleton animation="wave" variant="circle" width={150} height={150} className={classes.avatar} />
: userInfo?._id === localStorage.getItem('userId')
? (
@@ -133,7 +132,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
: <Avatar className={classes.avatar} src={userInfo?.avatarUrl} />
}
{
- isLoading
+ !userInfo
? <Skeleton animation="wave" variant="rect" width={100} height={20} className={classes.skeleton} />
: (
<Typography variant="h5" className={classes.name}>
@@ -144,7 +143,7 @@ const ProfileInfo: React.FC<PropTypes> = ({
}
<div className={classes.profileMenu}>
{
- isLoading
+ !userInfo
? (
<>
<Skeleton animation="wave" variant="rect" width={170} height={20} className={classes.skeleton} />
diff --git a/src/pages/ProfilePage/ProfilePage.tsx b/src/pages/ProfilePage/ProfilePage.tsx
index ae94b9f..4769999 100644
--- a/src/pages/ProfilePage/ProfilePage.tsx
+++ b/src/pages/ProfilePage/ProfilePage.tsx
@@ -1,59 +1,41 @@
-import React, { useState, useEffect } from 'react';
+import React, { useEffect, useCallback } from 'react';
import { useHistory, useParams } from 'react-router-dom';
-import { User, Poll } from 'which-types';
+import { Poll } from 'which-types';
import { Container } from '@material-ui/core';
import ProfileInfo from './ProfileInfo';
import Feed from '../../components/Feed/Feed';
-import { get } from '../../requests';
import { useAuth } from '../../hooks/useAuth';
+import { useUser, useProfile } from '../../hooks/APIClient';
const ProfilePage: React.FC = () => {
- const [userInfo, setUserInfo] = useState<User>();
- const [polls, setPolls] = useState<Poll[]>([]);
- const [totalVotes, setTotalVotes] = useState<number>(0);
- const [isInfoLoading, setIsInfoLoading] = useState(false);
- const [isPollsLoading, setIsPollsLoading] = useState(false);
const history = useHistory();
const { username } = useParams();
const { user } = useAuth();
+ const { data: userInfo, mutate: setUserInfo } = useUser(username);
+ const { data: polls, mutate: fetchPolls } = useProfile(userInfo?._id);
+
useEffect(() => {
- setIsInfoLoading(true);
+ fetchPolls();
+ }, [userInfo, fetchPolls])
- const redirect = () => {
+ useEffect(() => {
+ if (!username) {
if (user) history.push(`/profile/${user.username}`);
else history.push('/login');
};
+ }, [username, history, user]);
- if (username) {
- get(`/users?username=${username}`).then(response => {
- if (!response.data.length) redirect(); // TODO: handle this case
- setUserInfo(response.data[0]);
- setIsInfoLoading(false);
- }).catch(() => redirect());
- } else redirect();
- }, [username, user, history]);
-
-
- useEffect(() => {
- if (userInfo?._id) {
- setIsPollsLoading(true);
- get(`/profiles/${userInfo._id}`).then(response => {
- setIsPollsLoading(false);
- setPolls([]);
- setPolls(response.data);
- setTotalVotes(response.data.reduce(
- (total: number, current: Poll) => {
- const { left, right } = current.contents;
- return total + left.votes + right.votes;
- }, 0
- ));
- });
- }
- }, [userInfo]);
+ const totalVotes = useCallback(
+ polls.reduce(
+ (total: number, current: Poll) => {
+ const { left, right } = current.contents;
+ return total + left.votes + right.votes;
+ }, 0
+ ), [polls]);
return (
<Container maxWidth="sm" disableGutters>
@@ -62,9 +44,8 @@ const ProfilePage: React.FC = () => {
setUserInfo={setUserInfo}
savedPolls={polls.length}
totalVotes={totalVotes}
- isLoading={isInfoLoading}
/>
- {isPollsLoading ? <Feed polls={[]} /> : (polls.length > 0 && <Feed polls={polls} />)}
+ <Feed polls={polls} />
</Container>
);
};