aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/Feed/Feed.tsx5
-rw-r--r--src/components/Header/Header.tsx10
-rw-r--r--src/components/Header/SearchBar.tsx9
-rw-r--r--src/components/PollCard/PollCard.tsx5
-rw-r--r--src/components/UserStrip/UserStrip.tsx16
-rw-r--r--src/hooks/useNavigate.tsx42
-rw-r--r--src/index.tsx71
-rw-r--r--src/pages/FeedPage/FeedPage.tsx8
-rw-r--r--src/pages/FeedPage/PollSubmission.tsx2
-rw-r--r--src/pages/Page.tsx31
-rw-r--r--src/pages/ProfilePage/ProfilePage.tsx14
-rw-r--r--src/types.d.ts4
12 files changed, 117 insertions, 100 deletions
diff --git a/src/components/Feed/Feed.tsx b/src/components/Feed/Feed.tsx
index 0c4d84f..7636573 100644
--- a/src/components/Feed/Feed.tsx
+++ b/src/components/Feed/Feed.tsx
@@ -5,7 +5,6 @@ import PollCard from '../PollCard/PollCard';
interface PropTypes {
polls: Poll[];
- navigate: (prefix: string, id: string) => void;
}
const useStyles = makeStyles(theme => ({
@@ -16,11 +15,11 @@ const useStyles = makeStyles(theme => ({
}
}));
-const Feed: React.FC<PropTypes> = ({ polls, navigate }) => {
+const Feed: React.FC<PropTypes> = ({ polls }) => {
const classes = useStyles();
return (
<div className={classes.root}>
- {polls.map(poll => <PollCard initialPoll={poll} key={poll._id} navigate={navigate} />)}
+ {polls.map(poll => <PollCard initialPoll={poll} key={poll._id} />)}
</div>
);
};
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index 49f427f..546ecc3 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -10,13 +10,10 @@ import AccountCircle from '@material-ui/icons/AccountCircle';
import NotificationsIcon from '@material-ui/icons/Notifications';
import HomeIcon from '@material-ui/icons/Home';
import { useAuth } from '../../hooks/useAuth';
+import { useNavigate } from '../../hooks/useNavigate';
import SearchBar from './SearchBar';
-interface PropTypes {
- navigate: (prefix: string) => void;
-}
-
const useStyles = makeStyles({
root: {
display: 'flex',
@@ -33,9 +30,10 @@ const useStyles = makeStyles({
}
});
-const Header: React.FC<PropTypes> = ({ navigate }) => {
+const Header: React.FC = () => {
const classes = useStyles();
const { user } = useAuth();
+ const { navigate } = useNavigate();
const handleHome = (): void => {
navigate('feed');
@@ -53,7 +51,7 @@ const Header: React.FC<PropTypes> = ({ navigate }) => {
<Typography variant="h5" className={classes.logo}>
Which
</Typography>
- <SearchBar navigate={navigate} />
+ <SearchBar />
<div>
<IconButton onClick={handleHome}>
<HomeIcon />
diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx
index bff16a0..253e77f 100644
--- a/src/components/Header/SearchBar.tsx
+++ b/src/components/Header/SearchBar.tsx
@@ -12,10 +12,8 @@ import { makeStyles } from '@material-ui/core/styles';
import { User } from 'which-types';
import { get } from '../../requests';
import UserStrip from '../UserStrip/UserStrip';
+import { useNavigate } from '../../hooks/useNavigate';
-interface PropTypes {
- navigate: (prefix: string, id: string) => void;
-}
const INTERVAL = 300;
const LIMIT = 7;
@@ -36,10 +34,11 @@ const useStyles = makeStyles(theme => ({
}
}));
-const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
+const SearchBar: React.FC = () => {
const [results, setResults] = useState<User[]>([]);
const [query, setQuery] = useState<string>('');
const [debouncedQuery, setDebouncedQuery] = useState<string>(query);
+ const { navigate } = useNavigate();
const classes = useStyles();
useEffect(() => {
@@ -79,7 +78,7 @@ const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
results.map((result, index) => (
<div key={result._id}>
<ListItem button onClick={handleNavigate(index)}>
- <UserStrip user={result} navigate={navigate} />
+ <UserStrip user={result} />
</ListItem>
{(index < results.length - 1) && <Divider />}
</div>
diff --git a/src/components/PollCard/PollCard.tsx b/src/components/PollCard/PollCard.tsx
index 156315a..2a23522 100644
--- a/src/components/PollCard/PollCard.tsx
+++ b/src/components/PollCard/PollCard.tsx
@@ -13,7 +13,6 @@ import { post } from '../../requests';
interface PropTypes {
initialPoll: Poll;
- navigate: (prefix: string, id: string) => void;
}
const DATE_FORMAT = {
@@ -54,7 +53,7 @@ const useStyles = makeStyles(theme => ({
}
}));
-const PollCard: React.FC<PropTypes> = ({ initialPoll, navigate }) => {
+const PollCard: React.FC<PropTypes> = ({ initialPoll }) => {
const [poll, setPoll] = useState<Poll>(initialPoll);
const classes = useStyles();
const { author, contents: { left, right }, vote } = poll;
@@ -87,7 +86,7 @@ const PollCard: React.FC<PropTypes> = ({ initialPoll, navigate }) => {
return (
<Card className={classes.root}>
- <UserStrip user={author} info={date} navigate={navigate} />
+ <UserStrip user={author} info={date} />
<div className={classes.imagesBlock}>
<CardActionArea onDoubleClick={handleLeft}>
<CardMedia
diff --git a/src/components/UserStrip/UserStrip.tsx b/src/components/UserStrip/UserStrip.tsx
index f02adc3..bbd595e 100644
--- a/src/components/UserStrip/UserStrip.tsx
+++ b/src/components/UserStrip/UserStrip.tsx
@@ -1,16 +1,13 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import VerifiedIcon from '@material-ui/icons/CheckCircleOutline';
-import {
- Avatar,
- CardHeader
-} from '@material-ui/core/';
+import { Avatar, CardHeader } from '@material-ui/core/';
import { User } from 'which-types';
+import { useNavigate } from '../../hooks/useNavigate';
interface PropTypes {
user: User;
- navigate: (prefix: string, id: string) => void;
info?: string | JSX.Element
}
@@ -31,13 +28,10 @@ const useStyles = makeStyles(theme => ({
}));
-const UserStrip: React.FC<PropTypes> = ({ user, info, navigate }) => {
+const UserStrip: React.FC<PropTypes> = ({ user, info }) => {
const classes = useStyles();
- const {
- username,
- avatarUrl,
- verified
- } = user;
+ const { navigate } = useNavigate();
+ const { username, avatarUrl, verified } = user;
const handleNavigate = () => {
navigate('profile', user._id);
diff --git a/src/hooks/useNavigate.tsx b/src/hooks/useNavigate.tsx
new file mode 100644
index 0000000..0650f55
--- /dev/null
+++ b/src/hooks/useNavigate.tsx
@@ -0,0 +1,42 @@
+import React, { useState, useContext, createContext } from 'react';
+import { User } from 'which-types';
+
+export interface Page {
+ prefix: string;
+ id?: string;
+}
+
+interface ContextType {
+ page: Page;
+ setPage: (page: Page) => void;
+ navigate: (prefix: string, id?: string) => void;
+}
+
+const landingPage = { prefix: 'feed' };
+
+const context = createContext<ContextType>({
+ page: landingPage,
+ setPage: () => {},
+ navigate: () => {}
+});
+
+const useProvideNavigation = () => {
+ const [page, setPage] = useState<Page>(landingPage);
+
+ const navigate = (prefix: string, id?: string): void => {
+ setPage({ prefix, id });
+ };
+
+ return { page, setPage, navigate };
+};
+
+export const NavigationProvider: React.FC = ({ children }) => {
+ const navigation = useProvideNavigation();
+ const { Provider } = context;
+ return <Provider value={navigation}>{children}</Provider>;
+};
+
+export const useNavigate = () => {
+ return useContext(context);
+}
+
diff --git a/src/index.tsx b/src/index.tsx
index a82a28b..180f80c 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,23 +1,15 @@
-import React, { useState, useEffect } from 'react';
+import React from 'react';
import ReactDOM from 'react-dom';
-import {
- createMuiTheme,
- ThemeProvider,
- makeStyles
-} from '@material-ui/core/styles';
+import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import { CssBaseline } from '@material-ui/core';
import teal from '@material-ui/core/colors/teal';
import 'typeface-roboto';
-import { User } from 'which-types';
import Header from './components/Header/Header';
-import ProfilePage from './pages/ProfilePage/ProfilePage';
-import FeedPage from './pages/FeedPage/FeedPage';
-import AuthPage from './pages/AuthPage/AuthPage';
-import { Page } from './types';
-import { get, post } from './requests';
import ScrollTopArrow from './components/ScrollTopArrow/ScrollTopArrow';
-import { useAuth, AuthProvider } from './hooks/useAuth';
+import Page from './pages/Page';
+import { AuthProvider } from './hooks/useAuth';
+import { NavigationProvider } from './hooks/useNavigate';
const theme = createMuiTheme({
@@ -29,52 +21,21 @@ const theme = createMuiTheme({
}
});
-const useStyles = makeStyles({
- root: {
- width: theme.spacing(75),
- marginTop: theme.spacing(15),
- margin: '0 auto'
- }
-});
const App: React.FC = () => {
- const [page, setPage] = useState<Page>({ prefix: 'feed', id: '' });
- const classes = useStyles();
- const { user } = useAuth();
-
- const navigate = (prefix: string, id?: string): void => {
- if (prefix === 'profile' && !id && !user) {
- setPage({
- prefix: 'auth',
- id: ''
- });
- } else {
- setPage({
- prefix,
- id: (id || user?._id || '')
- });
- }
- };
-
return (
- <ThemeProvider theme={theme}>
- <CssBaseline />
- <Header navigate={navigate} />
- <div className={classes.root}>
- { page.prefix === 'profile' && (
- <ProfilePage
- id={page.id}
- navigate={navigate}
- />
- ) }
- { page.prefix === 'feed' && <FeedPage navigate={navigate} /> }
- { page.prefix === 'auth' && <AuthPage /> }
- </div>
- <ScrollTopArrow />
- </ThemeProvider>
-
+ <NavigationProvider>
+ <AuthProvider>
+ <ThemeProvider theme={theme}>
+ <CssBaseline />
+ <Header />
+ <Page />
+ <ScrollTopArrow />
+ </ThemeProvider>
+ </AuthProvider>
+ </NavigationProvider>
);
};
-ReactDOM.render(<AuthProvider> <App /> </AuthProvider>, document.getElementById('root'));
+ReactDOM.render(<App />, document.getElementById('root'));
diff --git a/src/pages/FeedPage/FeedPage.tsx b/src/pages/FeedPage/FeedPage.tsx
index 6561991..87a56ec 100644
--- a/src/pages/FeedPage/FeedPage.tsx
+++ b/src/pages/FeedPage/FeedPage.tsx
@@ -7,11 +7,7 @@ import PollSubmission from './PollSubmission';
import { useAuth } from '../../hooks/useAuth';
-interface PropTypes {
- navigate: (prefix: string, id: string) => void;
-}
-
-const FeedPage: React.FC<PropTypes> = ({ navigate }) => {
+const FeedPage: React.FC = () => {
const [polls, setPolls] = useState<Poll[]>([]);
const { isAuthenticated } = useAuth();
@@ -30,7 +26,7 @@ const FeedPage: React.FC<PropTypes> = ({ navigate }) => {
return (
<>
{isAuthenticated() && <PollSubmission addPoll={addPoll} />}
- <Feed polls={polls} navigate={navigate} />
+ <Feed polls={polls} />
</>
);
};
diff --git a/src/pages/FeedPage/PollSubmission.tsx b/src/pages/FeedPage/PollSubmission.tsx
index 4e06254..42612f0 100644
--- a/src/pages/FeedPage/PollSubmission.tsx
+++ b/src/pages/FeedPage/PollSubmission.tsx
@@ -60,7 +60,7 @@ const PollSubmission: React.FC<PropTypes> = ({ addPoll }) => {
<ClickAwayListener onClickAway={handleClickAway}>
<Card>
<Collapse in={expanded} timeout="auto" unmountOnExit>
- {user && <UserStrip user={user} info="" navigate={() => {}} />}
+ {user && <UserStrip user={user} info="" />}
<Divider />
<div className={classes.root}>
<PollSubmissionImage url={contents.left.url} setUrl={setUrl('left')} />
diff --git a/src/pages/Page.tsx b/src/pages/Page.tsx
new file mode 100644
index 0000000..6d4315e
--- /dev/null
+++ b/src/pages/Page.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import ProfilePage from './ProfilePage/ProfilePage';
+import FeedPage from './FeedPage/FeedPage';
+import AuthPage from './AuthPage/AuthPage';
+import { useNavigate } from '../hooks/useNavigate';
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ width: theme.spacing(75),
+ marginTop: theme.spacing(15),
+ margin: '0 auto'
+ }
+}));
+
+const Page: React.FC = () => {
+ const { page } = useNavigate();
+ const classes = useStyles();
+
+ return (
+ <div className={classes.root}>
+ { page.prefix === 'profile' && <ProfilePage />}
+ { page.prefix === 'feed' && <FeedPage /> }
+ { page.prefix === 'auth' && <AuthPage /> }
+ </div>
+ );
+};
+
+
+export default Page;
+
diff --git a/src/pages/ProfilePage/ProfilePage.tsx b/src/pages/ProfilePage/ProfilePage.tsx
index ad2da46..808d43a 100644
--- a/src/pages/ProfilePage/ProfilePage.tsx
+++ b/src/pages/ProfilePage/ProfilePage.tsx
@@ -4,16 +4,18 @@ import { User, Poll } from 'which-types';
import ProfileInfo from './ProfileInfo';
import Feed from '../../components/Feed/Feed';
import { get } from '../../requests';
+import { useAuth } from '../../hooks/useAuth';
+import { useNavigate } from '../../hooks/useNavigate';
-interface PropTypes {
- navigate: (prefix: string, id: string) => void;
- id: string;
-}
-const ProfilePage: React.FC<PropTypes> = ({ id, navigate }) => {
+const ProfilePage: React.FC = () => {
const [userInfo, setUserInfo] = useState<User>();
const [polls, setPolls] = useState<Poll[]>([]);
const [totalVotes, setTotalVotes] = useState<number>(0);
+ const { page } = useNavigate();
+ const { user } = useAuth();
+
+ const id = page?.id || user?._id;
useEffect(() => {
get(`/users/${id}`).then(response => {
@@ -41,7 +43,7 @@ const ProfilePage: React.FC<PropTypes> = ({ id, navigate }) => {
savedPolls={polls.length}
totalVotes={totalVotes}
/>
- <Feed polls={[...polls]} navigate={navigate} />
+ <Feed polls={[...polls]} />
</>
);
};
diff --git a/src/types.d.ts b/src/types.d.ts
index 4b1ffd6..e69de29 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -1,4 +0,0 @@
-export interface Page {
- prefix: string;
- id: string;
-}