diff --git a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js
index 107da9beb7..04d860ace3 100644
--- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js
+++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js
@@ -1,5 +1,5 @@
import { Anchor, Box, ResponsiveContext, Text } from 'grommet'
-import { arrayOf, bool, shape, string } from 'prop-types'
+import { arrayOf, bool, number, shape, string } from 'prop-types'
import { useContext } from 'react'
import { Loader, ProjectCard, SpacedText } from '@zooniverse/react-components'
@@ -7,26 +7,24 @@ import { ContentBox } from '@components/shared'
export default function RecentProjects({
isLoading = false,
- projectPreferences = [],
+ recentProjects = [],
error = undefined
}) {
const size = useContext(ResponsiveContext)
return (
- {isLoading && (
+ {isLoading ? (
- )}
- {!isLoading && error && (
+ ) : error ? (
There was an error fetching your recent projects
- )}
- {!isLoading && !projectPreferences.length && !error && (
+ ) : !recentProjects.length ? (
No Recent Projects found
@@ -37,41 +35,44 @@ export default function RecentProjects({
.
+ ) : (
+
+ {recentProjects.map(project => (
+
+
+
+ ))}
+
)}
- {!isLoading &&
- projectPreferences?.length ? (
-
- {projectPreferences.map(preference => (
-
-
-
- ))}
-
- ) : null}
)
}
RecentProjects.propTypes = {
isLoading: bool,
- projectPreferences: arrayOf(
+ recentProjects: arrayOf(
shape({
- id: string
+ avatar_src: string,
+ count: number,
+ description: string,
+ display_name: string,
+ id: string,
+ slug: string
})
)
}
diff --git a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js
index d085aa9f4a..a19b75656a 100644
--- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js
+++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js
@@ -1,90 +1,56 @@
import { shape, string } from 'prop-types'
-import { panoptes } from '@zooniverse/panoptes-js'
-import useSWR from 'swr'
-import auth from 'panoptes-client/lib/auth'
-
-import { usePanoptesProjects } from '@hooks'
+import { usePanoptesProjects, useStats } from '@hooks'
import RecentProjects from './RecentProjects.js'
-const SWROptions = {
- revalidateIfStale: true,
- revalidateOnMount: true,
- revalidateOnFocus: true,
- revalidateOnReconnect: true,
- refreshInterval: 0
-}
-
-async function fetchUserProjectPreferences() {
- const user = await auth.checkCurrent()
- const token = await auth.checkBearerToken()
- const authorization = `Bearer ${token}`
- try {
- const query = {
- sort: '-updated_at',
- user_id: user.id
- }
- const response = await panoptes.get('/project_preferences', query, { authorization })
- if (response.ok) {
- const projectPreferencesUserHasClassified =
- response.body.project_preferences
- .filter(preference => preference.activity_count > 0)
- return projectPreferencesUserHasClassified
- }
- return []
- } catch (error) {
- console.error(error)
- throw error
- }
-}
-
function RecentProjectsContainer({ authUser }) {
- // Get user's project preference.activity_count for 10 most recently classified projects
- const cacheKey = {
- name: 'user-project-preferences',
- userId: authUser.id
+ const recentProjectsQuery = {
+ project_contributions: true,
+ order_project_contributions_by: 'recents',
+ period: 'day'
}
+
const {
- data: projectPreferences,
- isLoading: preferencesLoading,
- error: preferencesError
- } = useSWR(cacheKey, fetchUserProjectPreferences, SWROptions)
+ data: stats,
+ isLoading: statsLoading,
+ error: statsError
+ } = useStats({ sourceId: authUser?.id, query: recentProjectsQuery })
- // Get more info about each project and attach it to correct projectPreference object
- const recentProjectIds = projectPreferences?.map(
- preference => preference.links.project
- )
+ // limit to 20 projects fetched from panoptes
+ const contributions = stats?.project_contributions.slice(0, 20)
+ const projectIds = contributions?.map(project => project.project_id)
+
+ // Get more info about each project
const {
data: projects,
isLoading: projectsLoading,
error: projectsError
} = usePanoptesProjects({
cards: true,
- id: recentProjectIds?.join(',')
+ id: projectIds?.join(',')
})
-
- // Attach project object to each project preference
- let projectPreferencesWithProjectObj
- if (projects?.length) {
- projectPreferencesWithProjectObj = projectPreferences
- .map(preference => {
- const matchedProjectObj = projects.find(
- project => project.id === preference.links?.project
- )
- if (matchedProjectObj) {
- preference.project = matchedProjectObj
+ // Attach project info to each contribution stat (see similar behavior in TopProjects)
+ let recentProjects = []
+
+ if (projects?.length && contributions?.length) {
+ recentProjects = contributions
+ .map(projectContribution => {
+ const projectData = projects?.find(
+ project => project.id === projectContribution.project_id.toString()
+ )
+ return {
+ count: projectContribution.count,
+ ...projectData
}
- return preference
})
- .filter(preference => preference?.project?.slug)
- .slice(0, 10)
+ .filter(project => project?.id) // exclude private or deleted projects
}
return (
)
}
diff --git a/packages/lib-user/src/components/shared/ContentBox/components/ContentLink.js b/packages/lib-user/src/components/shared/ContentBox/components/ContentLink.js
index f162e4d3ee..a9a117f9d3 100644
--- a/packages/lib-user/src/components/shared/ContentBox/components/ContentLink.js
+++ b/packages/lib-user/src/components/shared/ContentBox/components/ContentLink.js
@@ -1,10 +1,10 @@
import { SpacedText } from '@zooniverse/react-components'
import { Anchor } from 'grommet'
-import { shape, string } from 'prop-types'
+import { object, oneOfType, shape, string } from 'prop-types'
import styled from 'styled-components'
const StyledAnchor = styled(Anchor)`
- font-family: 'Karla', Arial, sans-serif;
+ font-family: 'Karla', Arial, sans-serif;
font-size: 1rem;
line-height: normal;
background: none;
@@ -45,7 +45,7 @@ function ContentLink({
ContentLink.propTypes = {
link: shape({
- as: string,
+ as: oneOfType([object, string]),
href: string,
text: string
})