Skip to content

Commit

Permalink
Add explorer functionality (#25)
Browse files Browse the repository at this point in the history
* Modularize location-match

* Init explorer context

* Init explorer refactor

* Refactor total classifications stat

* Refactor contexts

* Refactor favs for explorer view

* Refactor heading for explorer view
  • Loading branch information
mcbouslog authored Dec 4, 2018
1 parent 97939d5 commit 8ea4054
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 149 deletions.
93 changes: 56 additions & 37 deletions src/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import GrommetApp from 'grommet/components/App';
import Box from 'grommet/components/Box';
import { ZooFooter, ZooHeader } from 'zooniverse-react-components';

import { ExplorerProvider, ExplorerContext } from '../context/ExplorerContext';
import {
FavoritesProvider,
FavoritesContext
Expand All @@ -27,44 +28,62 @@ const App = () => (
<ZooHeader authContainer={<AuthContainer />} />
<ProjectContext.Consumer>
{({ project }) => (
<Box className="main" pad="large" tag="main">
<UserHeading project={project} user={user} />
<Box
direction="row"
full="horizontal"
margin={{ bottom: 'medium' }}
responsive
>
<FavoritesProvider project={project} user={user}>
<FavoritesContext.Consumer>
{({ favoriteCollection, linkedSubjects }) => (
<Box
basis="2/3"
colorIndex="light-1"
justify="between"
margin={{ right: 'medium' }}
<ExplorerProvider project={project} user={user}>
<ExplorerContext>
{({ explorer, matchesUser }) => (
<Box className="main" pad="large" tag="main">
<UserHeading
project={project}
explorer={explorer}
matchesUser={matchesUser}
/>
<Box
direction="row"
full="horizontal"
margin={{ bottom: 'medium' }}
responsive
>
<FavoritesProvider
project={project}
explorer={explorer}
>
<RecentsContainer user={user} />
<hr className="main__hr" />
<FavoritesContainer
favoriteCollection={favoriteCollection}
linkedSubjects={linkedSubjects}
/>
</Box>
)}
</FavoritesContext.Consumer>
</FavoritesProvider>
<StatsContainer user={user} />
</Box>
<Box
colorIndex="light-1"
full="horizontal"
pad="medium"
style={{ height: '250px' }}
>
<Title>Your Badges</Title>
</Box>
</Box>
<FavoritesContext.Consumer>
{({ favoriteCollection, linkedSubjects }) => (
<Box
basis="2/3"
colorIndex="light-1"
justify="between"
margin={{ right: 'medium' }}
>
<RecentsContainer explorer={explorer} />
<hr className="main__hr" />
<div>
{matchesUser ? (
<FavoritesContainer
favoriteCollection={favoriteCollection}
linkedSubjects={linkedSubjects}
matchesUser={matchesUser}
/>
) : null}
</div>
</Box>
)}
</FavoritesContext.Consumer>
</FavoritesProvider>
<StatsContainer explorer={explorer} />
</Box>
<Box
colorIndex="light-1"
full="horizontal"
pad="medium"
style={{ height: '250px' }}
>
<Title>Your Badges</Title>
</Box>
</Box>
)}
</ExplorerContext>
</ExplorerProvider>
)}
</ProjectContext.Consumer>
<ZooFooter />
Expand Down
34 changes: 24 additions & 10 deletions src/components/SubjectCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import Box from 'grommet/components/Box';
import { Thumbnail } from 'zooniverse-react-components';

import { config } from '../config';
import { ExplorerContext } from '../context/ExplorerContext';
import { FavoritesContext } from '../context/FavoritesContext';
import { ProjectContext } from '../context/ProjectContext';
import getSubjectLocations from '../lib/get-subject-locations';
import { FavoritesContext } from '../context/FavoritesContext';
import FavoritesButton from './FavoritesButton';

export default function SubjectCard({ subject }) {
Expand Down Expand Up @@ -46,16 +47,29 @@ export default function SubjectCard({ subject }) {
/>
</a>
<Box direction="row" justify="center">
<FavoritesContext.Consumer>
{({ addSubjectTo, linkedSubjects, removeSubjectFrom }) => (
<FavoritesButton
addSubjectTo={addSubjectTo}
linkedSubjects={linkedSubjects}
removeSubjectFrom={removeSubjectFrom}
subject={subject}
/>
<ExplorerContext.Consumer>
{({ matchesUser }) => (
<div>
{matchesUser ? (
<FavoritesContext.Consumer>
{({
addSubjectTo,
linkedSubjects,
removeSubjectFrom
}) => (
<FavoritesButton
addSubjectTo={addSubjectTo}
linkedSubjects={linkedSubjects}
matchesUser={matchesUser}
removeSubjectFrom={removeSubjectFrom}
subject={subject}
/>
)}
</FavoritesContext.Consumer>
) : null}
</div>
)}
</FavoritesContext.Consumer>
</ExplorerContext.Consumer>
</Box>
</Box>
)}
Expand Down
22 changes: 14 additions & 8 deletions src/components/UserHeading.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import Heading from 'grommet/components/Heading';

import { config } from '../config';

export default function UserHeading({ project, user }) {
if (user && project) {
export default function UserHeading({ project, explorer, matchesUser }) {
if (explorer && project) {
const projectLink = (
<a href={`${config.zooniverse}/projects/${project.slug}`}>
{project.display_name}
</a>
);

const headingClassName = matchesUser
? 'user-heading'
: 'user-heading user-heading--explorer';

return (
<Heading className="user-heading" strong tag="h2">
{`${user.display_name}'s `}
<Heading className={headingClassName} strong tag="h2">
{`${explorer.display_name}'s `}
{projectLink}
{' Field Book'}
</Heading>
Expand All @@ -32,17 +36,19 @@ UserHeading.propTypes = {
display_name: PropTypes.string,
slug: PropTypes.string
}),
user: PropTypes.shape({
explorer: PropTypes.shape({
display_name: PropTypes.string
})
}),
matchesUser: PropTypes.bool
};

UserHeading.defaultProps = {
project: {
display_name: '',
slug: ''
},
user: {
explorer: {
display_name: ''
}
},
matchesUser: true
};
22 changes: 10 additions & 12 deletions src/components/UserStats.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import Value from 'grommet/components/Value';

import Title from './Title';

export default function UserStats({
activityCount,
userStatsByDay,
userStatsByMonth
}) {
export default function UserStats({ userStatsByDay, userStatsByMonth }) {
let totalClassifications = 0;

let maxDay = { label: '', value: 0 };
if (userStatsByDay) {
maxDay = userStatsByDay.reduce(
Expand All @@ -22,10 +20,12 @@ export default function UserStats({

let maxMonth = { label: '', value: 0 };
if (userStatsByMonth) {
maxMonth = userStatsByMonth.reduce(
(max, stat) => (stat.value > max.value ? stat : max),
maxMonth
);
userStatsByMonth.forEach(stat => {
if (stat.value > maxMonth.value) {
maxMonth = stat;
}
totalClassifications += stat.value;
});
}

return (
Expand All @@ -41,7 +41,7 @@ export default function UserStats({
<Value
align="start"
colorIndex="accent-2"
value={activityCount.toLocaleString()}
value={totalClassifications.toLocaleString()}
/>
<Label margin="none">Total Classifications</Label>
</Box>
Expand Down Expand Up @@ -71,7 +71,6 @@ export default function UserStats({
}

UserStats.propTypes = {
activityCount: PropTypes.number,
userStatsByDay: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string,
Expand All @@ -87,7 +86,6 @@ UserStats.propTypes = {
};

UserStats.defaultProps = {
activityCount: 0,
userStatsByDay: null,
userStatsByMonth: null
};
14 changes: 1 addition & 13 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ By default, this is the development environment, but this can be changed either
- The NODE_ENV environment variable on the system running the app.
*/

// Try and match the window.location.search property against a regex. Basically mimics
// the CoffeeScript existential operator, in case we're not in a browser.
function locationMatch(regex) {
let match;
if (
window &&
typeof window.location !== 'undefined' &&
window.location !== null
) {
match = window.location.search.match(regex);
}
return match && match[1] ? match[1] : undefined;
}
import locationMatch from './lib/location-match';

const DEFAULT_ENV = 'development';
const envFromBrowser = locationMatch(/\W?env=(\w+)/);
Expand Down
12 changes: 6 additions & 6 deletions src/containers/RecentsContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class RecentsContainer extends React.Component {
}

componentDidUpdate(prevProps) {
if (prevProps.user !== this.props.user) {
if (prevProps.explorer !== this.props.explorer) {
this.fetchRecents();
}
}
Expand All @@ -33,16 +33,16 @@ class RecentsContainer extends React.Component {
}

fetchRecents(page = 1) {
const { user } = this.props;
if (user && user.get) {
const { explorer } = this.props;
if (explorer && explorer.get) {
const query = {
project_id: config.projectId,
sort: '-created_at',
page,
page_size: 3
};

user
explorer
.get('recents', query)
.then(recents => {
this.setState({ meta: recents[0].getMeta(), recents });
Expand Down Expand Up @@ -81,13 +81,13 @@ class RecentsContainer extends React.Component {
}

RecentsContainer.propTypes = {
user: PropTypes.shape({
explorer: PropTypes.shape({
get: PropTypes.func
})
};

RecentsContainer.defaultProps = {
user: null
explorer: null
};

export default RecentsContainer;
Loading

0 comments on commit 8ea4054

Please sign in to comment.