From 9571912910919ba7330ba97f8be2e1256399bbc1 Mon Sep 17 00:00:00 2001 From: Delilah <23665803+goplayoutside3@users.noreply.github.com> Date: Mon, 21 Oct 2024 12:11:47 -0500 Subject: [PATCH 1/3] refactor homepage RecentProjects with useStats() --- .../RecentProjects/RecentProjects.js | 61 ++++++------ .../RecentProjects/RecentProjectsContainer.js | 96 ++++++------------- .../ContentBox/components/ContentLink.js | 6 +- 3 files changed, 59 insertions(+), 104 deletions(-) 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..199acf51b7 100644 --- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js +++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js @@ -7,26 +7,23 @@ import { ContentBox } from '@components/shared' export default function RecentProjects({ isLoading = false, - projectPreferences = [], + recentProjectsStats = [], error = undefined }) { const size = useContext(ResponsiveContext) - return ( - {isLoading && ( + {isLoading ? ( - )} - {!isLoading && error && ( + ) : error ? ( There was an error fetching your recent projects - )} - {!isLoading && !projectPreferences.length && !error && ( + ) : !recentProjectsStats.length ? ( No Recent Projects found @@ -37,39 +34,37 @@ export default function RecentProjects({ . + ) : ( + + {recentProjectsStats.map(project => ( +
  • + +
  • + ))} +
    )} - {!isLoading && - projectPreferences?.length ? ( - - {projectPreferences.map(preference => ( -
  • - -
  • - ))} -
    - ) : null}
    ) } RecentProjects.propTypes = { isLoading: bool, - projectPreferences: arrayOf( + recentProjectsStats: arrayOf( shape({ id: 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..6593f9b797 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,50 @@ 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) - // Get more info about each project and attach it to correct projectPreference object - const recentProjectIds = projectPreferences?.map( - preference => preference.links.project + const { + data: stats, + isLoading: statsLoading, + error: statsError + } = useStats({ sourceId: authUser?.id, query: recentProjectsQuery }) + + // Get more info about each project + const projectIds = stats?.project_contributions?.map( + project => project.project_id ) + const { data: projects, isLoading: projectsLoading, error: projectsError } = usePanoptesProjects({ cards: true, - id: recentProjectIds?.join(',') + id: projectIds?.join(','), + page_size: 20 }) - - // 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 - } - return preference - }) - .filter(preference => preference?.project?.slug) - .slice(0, 10) + // Attach contributions to each project + if (projects?.length && stats.project_contributions.length) { + projects.forEach(project => { + const projectStat = stats.project_contributions.find( + stat => stat.project_id === parseInt(project.id) + ) + project.userContributions = projectStat.count + }) } 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 }) From 74ec2fa5c16de7883499e3783286d57fa34b64e3 Mon Sep 17 00:00:00 2001 From: Delilah <23665803+goplayoutside3@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:15:18 -0500 Subject: [PATCH 2/3] correct the ordering in RecentProjectsContainer --- .../RecentProjects/RecentProjects.js | 26 ++++++++++++------- .../RecentProjects/RecentProjectsContainer.js | 25 +++++++++--------- 2 files changed, 29 insertions(+), 22 deletions(-) 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 199acf51b7..12a5053614 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' @@ -44,14 +44,14 @@ export default function RecentProjects({ style={{ listStyle: 'none' }} margin='0' > - {recentProjectsStats.map(project => ( -
  • + {recentProjectsStats.map(stat => ( +
  • @@ -66,7 +66,15 @@ RecentProjects.propTypes = { isLoading: bool, recentProjectsStats: arrayOf( shape({ - id: string + count: number, + project_id: number, + projectInfo: shape({ + avatar_src: string, + 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 6593f9b797..04bc727fa2 100644 --- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js +++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js @@ -15,28 +15,27 @@ function RecentProjectsContainer({ authUser }) { error: statsError } = useStats({ sourceId: authUser?.id, query: recentProjectsQuery }) - // Get more info about each project - const projectIds = stats?.project_contributions?.map( - project => project.project_id - ) + // limit to 20 projects fetched from panoptes + const contributionStats = stats?.project_contributions.slice(0, 20) + const projectIds = contributionStats?.map(project => project.project_id) + // Get more info about each project const { data: projects, isLoading: projectsLoading, error: projectsError } = usePanoptesProjects({ cards: true, - id: projectIds?.join(','), - page_size: 20 + id: projectIds?.join(',') }) - // Attach contributions to each project - if (projects?.length && stats.project_contributions.length) { - projects.forEach(project => { - const projectStat = stats.project_contributions.find( - stat => stat.project_id === parseInt(project.id) + // Attach project info to each contribution stat + if (projects?.length && contributionStats?.length) { + contributionStats.forEach(stat => { + const projectObj = projects.find( + project => parseInt(project.id) === stat.project_id ) - project.userContributions = projectStat.count + stat.projectInfo = projectObj }) } @@ -44,7 +43,7 @@ function RecentProjectsContainer({ authUser }) { ) } From ccf090c847237b57aeb419690124b123d173f551 Mon Sep 17 00:00:00 2001 From: Delilah <23665803+goplayoutside3@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:53:23 -0500 Subject: [PATCH 3/3] filter out private or deleted projects --- .../RecentProjects/RecentProjects.js | 34 +++++++++---------- .../RecentProjects/RecentProjectsContainer.js | 29 ++++++++++------ 2 files changed, 34 insertions(+), 29 deletions(-) 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 12a5053614..04d860ace3 100644 --- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js +++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjects.js @@ -7,10 +7,11 @@ import { ContentBox } from '@components/shared' export default function RecentProjects({ isLoading = false, - recentProjectsStats = [], + recentProjects = [], error = undefined }) { const size = useContext(ResponsiveContext) + return ( {isLoading ? ( @@ -23,7 +24,7 @@ export default function RecentProjects({ There was an error fetching your recent projects - ) : !recentProjectsStats.length ? ( + ) : !recentProjects.length ? ( No Recent Projects found @@ -44,14 +45,14 @@ export default function RecentProjects({ style={{ listStyle: 'none' }} margin='0' > - {recentProjectsStats.map(stat => ( -
  • + {recentProjects.map(project => ( +
  • @@ -64,17 +65,14 @@ export default function RecentProjects({ RecentProjects.propTypes = { isLoading: bool, - recentProjectsStats: arrayOf( + recentProjects: arrayOf( shape({ + avatar_src: string, count: number, - project_id: number, - projectInfo: shape({ - avatar_src: string, - description: string, - display_name: string, - id: string, - slug: string - }) + 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 04bc727fa2..a19b75656a 100644 --- a/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js +++ b/packages/lib-user/src/components/UserHome/components/RecentProjects/RecentProjectsContainer.js @@ -16,8 +16,8 @@ function RecentProjectsContainer({ authUser }) { } = useStats({ sourceId: authUser?.id, query: recentProjectsQuery }) // limit to 20 projects fetched from panoptes - const contributionStats = stats?.project_contributions.slice(0, 20) - const projectIds = contributionStats?.map(project => project.project_id) + const contributions = stats?.project_contributions.slice(0, 20) + const projectIds = contributions?.map(project => project.project_id) // Get more info about each project const { @@ -29,21 +29,28 @@ function RecentProjectsContainer({ authUser }) { id: projectIds?.join(',') }) - // Attach project info to each contribution stat - if (projects?.length && contributionStats?.length) { - contributionStats.forEach(stat => { - const projectObj = projects.find( - project => parseInt(project.id) === stat.project_id - ) - stat.projectInfo = projectObj - }) + // 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 + } + }) + .filter(project => project?.id) // exclude private or deleted projects } return ( ) }