Skip to content

Commit

Permalink
lib-user: Setup react-i18next for Contributors components (#6553)
Browse files Browse the repository at this point in the history
* setup react-i18next for Contributors components

* lib-user: Setup react-i18next for GroupStats components (#6554)

* lib-user: Setup react-i18next for MyGroups components (#6555)

* lib-user: Setup react-i18next for UserHome components (#6556)

* lib-user: Setup react-i18next for BarChart and GroupContainer (#6557)

* lib-user: Setup react-i18next for GroupForm (#6558)

* Setup react-i18next for MainContent components (#6561)
  • Loading branch information
goplayoutside3 authored Jan 7, 2025
1 parent 34d9680 commit fd585a1
Show file tree
Hide file tree
Showing 47 changed files with 669 additions and 334 deletions.
2 changes: 2 additions & 0 deletions packages/lib-user/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
"@zooniverse/async-states": "~0.0.1",
"@zooniverse/panoptes-js": "~0.5.0",
"dayjs": "~1.11.11",
"i18next": "~24.0.2",
"panoptes-client": "~5.6.0",
"react-i18next": "~14.1.3",
"swr": "~2.2.4",
"uuid": "~11.0.3"
},
Expand Down
24 changes: 13 additions & 11 deletions packages/lib-user/src/components/Contributors/Contributors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Loader, SpacedText } from '@zooniverse/react-components'
import { Box, Layer } from 'grommet'
import { arrayOf, bool, shape, string } from 'prop-types'
import { useState } from 'react'
import { useTranslation } from '../../translations/i18n.js'

import { fetchPanoptesUsers } from '../../utils'

Expand Down Expand Up @@ -30,10 +31,11 @@ function Contributors({
group,
membership
}) {
const { t } = useTranslation()
const [exportLoading, setExportLoading] = useState(false)
const [page, setPage] = useState(1)

const showContributors = adminMode
const showContributors = adminMode
|| membership?.roles.includes('group_admin')
|| (membership?.roles.includes('group_member') && group?.stats_visibility === 'private_show_agg_and_ind')
|| (membership?.roles.includes('group_member') && group?.stats_visibility === 'public_agg_show_ind_if_member')
Expand All @@ -43,7 +45,7 @@ function Contributors({
const statsQuery = {
individual_stats_breakdown: true,
}

const {
data: stats,
error: statsError,
Expand All @@ -68,7 +70,7 @@ function Contributors({
error: usersError,
isLoading: usersLoading
} = usePanoptesUsers(usersQuery)

// fetch projects
const arrayOfProjectContributionArrays = stats?.group_member_stats_breakdown?.map(member => member.project_contributions)
const flattenedProjectContributionArray = arrayOfProjectContributionArrays?.flat()
Expand Down Expand Up @@ -96,7 +98,7 @@ function Contributors({
})
}

const loadingExportMessage = 'Generating stats export...'
const loadingExportMessage = t('Contributors.generating')

async function handleGenerateExport() {
setExportLoading(true)
Expand All @@ -114,7 +116,7 @@ function Contributors({
stats,
users: allUsers
})

// Create an anchor element and trigger download
const link = document.createElement('a')
link.href = dataExportUrl
Expand Down Expand Up @@ -159,24 +161,24 @@ function Contributors({
primaryHeaderItem={
<HeaderLink
href={`/groups/${group.id}`}
label='back'
label={t('common.back')}
primaryItem={true}
/>
}
>
<ContentBox
linkLabel='Export all stats'
linkLabel={t('Contributors.exportLink')}
linkProps={{
as: 'button',
disabled: disableStatsExport,
onClick: handleGenerateExport
}}
title='Full Group Stats'
title={t('Contributors.title')}
>
{!showContributors ? (
<Box align='center' justify='center' fill pad='medium'>
<SpacedText uppercase={false}>
You do not have permission to view this group&apos;s contributors.
{t('Contributors.noPermission')}
</SpacedText>
</Box>
) : loading ? (
Expand All @@ -186,7 +188,7 @@ function Contributors({
) : error ? (
<Box align='center' justify='center' fill pad='medium'>
<SpacedText uppercase={false}>
There was an error.
{t('Contributors.error')}
</SpacedText>
<SpacedText uppercase={false}>
{error?.message}
Expand All @@ -200,7 +202,7 @@ function Contributors({
) : (
<Box align='center' justify='center' fill pad='medium'>
<SpacedText uppercase={false}>
There are no contributors to this group.
{t('Contributors.none')}
</SpacedText>
</Box>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Box } from 'grommet'
import { arrayOf, number, shape, string } from 'prop-types'
import { useTranslation } from '../../../../translations/i18n.js'

import { convertStatsSecondsToHours } from '@utils'

Expand All @@ -10,6 +11,8 @@ function ContributorsList({
contributors = [],
projects = []
}) {
const { t } = useTranslation()

let privateProjectIndex = 1
contributors.sort((a, b) => b.count - a.count)

Expand All @@ -24,11 +27,11 @@ function ContributorsList({
return (
<Box
key={contributor.id}
a11yTitle={`${contributor.display_name} member stats`}
a11yTitle={t('Contributors.ContributorsList.a11y', { name: contributor.display_name })}
as='li'
background={index % 2 === 0 ?
background={index % 2 === 0 ?
{ dark: 'dark-3', light: 'neutral-6' }
:
:
{ dark: 'dark-1', light: 'light-1' }
}
border={{ color: 'light-5', size: '0.5px' }}
Expand Down Expand Up @@ -56,7 +59,7 @@ function ContributorsList({
>
{contributor.project_contributions.map(statsProject => {
const project = projects.find(project => project.id === statsProject.project_id.toString())
const projectDisplayName = project?.display_name || `Private Project ${privateProjectIndex++}`
const projectDisplayName = project?.display_name || t('Contributors.ContributorsList.privateProject', { index: privateProjectIndex })
const projectHoursSpent = convertStatsSecondsToHours(statsProject.session_time)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SpacedText } from '@zooniverse/react-components'
import { Box } from 'grommet'
import { number, string } from 'prop-types'
import styled from 'styled-components'
import { useTranslation } from '../../../../translations/i18n.js'

const StyledBox = styled(Box)`
box-shadow: 8px 0px 6px -6px rgba(0, 0, 0, 0.25);
Expand All @@ -16,6 +17,7 @@ function MemberStats({
hours = 0,
login = ''
}) {
const { t } = useTranslation()
return (
<StyledBox
align='center'
Expand All @@ -31,7 +33,7 @@ function MemberStats({
gap='xsmall'
>
<Avatar
alt={`${login} avatar`}
alt={t('common.avatarAlt', { login })}
src={avatar || 'https://static.zooniverse.org/fem-assets/simple-avatar.jpg'}
/>
<Box
Expand Down Expand Up @@ -60,7 +62,7 @@ function MemberStats({
color={{ dark: 'neutral-6', light: 'neutral-7' }}
uppercase={false}
>
Classifications
{t('common.classifications')}
</SpacedText>
<SpacedText
color={{ light: 'neutral-1', dark: 'accent-1' }}
Expand All @@ -77,7 +79,7 @@ function MemberStats({
color={{ dark: 'neutral-6', light: 'neutral-7' }}
uppercase={false}
>
Hours
{t('common.hours')}
</SpacedText>
<SpacedText
color={{ light: 'neutral-1', dark: 'accent-1' }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { SpacedText } from '@zooniverse/react-components'
import { Box } from 'grommet'
import { string, number } from 'prop-types'
import { useTranslation } from '../../../../translations/i18n.js'

function ProjectStats({
classifications = 0,
hours = 0,
projectDisplayName = ''
}) {
const { t } = useTranslation()
return (
<Box
a11yTitle={`${projectDisplayName} member stats`}
a11yTitle={t('Contributors.ProjectStats.a11y', { project: projectDisplayName })}
align='center'
as='li'
border={{ color: 'light-5', side: 'vertical', size: '0.5px' }}
Expand All @@ -30,13 +32,13 @@ function ProjectStats({
textAlign='center'
uppercase={false}
>
{`${classifications.toLocaleString()} Classifications`}
{classifications.toLocaleString()} {t('common.classifications')}
</SpacedText>
<SpacedText
textAlign='center'
uppercase={false}
>
{`${hours.toLocaleString()} Hours`}
{hours.toLocaleString()} {t('common.hours')}
</SpacedText>
</Box>
)
Expand Down
23 changes: 13 additions & 10 deletions packages/lib-user/src/components/GroupStats/GroupStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Grid, ResponsiveContext } from 'grommet'
import { arrayOf, bool, func, shape, string } from 'prop-types'
import { useContext, useState } from 'react'
import useSWRMutation from 'swr/mutation'
import { useTranslation } from '../../translations/i18n.js'

import {
usePanoptesProjects,
Expand Down Expand Up @@ -40,10 +41,11 @@ function GroupStats({
setSelectedDateRange = DEFAULT_HANDLER,
setSelectedProject = DEFAULT_HANDLER
}) {
const { t } = useTranslation()
const [groupModalActive, setGroupModalActive] = useState(false)

const size = useContext(ResponsiveContext)

// define user_group membership key
const membershipKey = {
authUserId: authUser?.id,
Expand All @@ -55,7 +57,7 @@ function GroupStats({
// define user_group membership delete mutation
const { trigger: deleteMembership } = useSWRMutation(membershipKey, deletePanoptesMembership)

const showTopContributors = adminMode
const showTopContributors = adminMode
|| membership?.roles.includes('group_admin')
|| (membership?.roles.includes('group_member') && group?.stats_visibility === 'private_show_agg_and_ind')
|| (membership?.roles.includes('group_member') && group?.stats_visibility === 'public_agg_show_ind_if_member')
Expand All @@ -66,7 +68,7 @@ function GroupStats({
if (showTopContributors) {
allProjectsStatsQuery.top_contributors = 10
}

const {
data: allProjectsStats,
error: statsError,
Expand All @@ -77,14 +79,14 @@ function GroupStats({
sourceId: paramsValidationMessage ? null : group?.id,
query: allProjectsStatsQuery
})

// fetch individual project stats
const projectStatsQuery = getDateInterval(selectedDateRange)
projectStatsQuery.project_id = parseInt(selectedProject)
if (showTopContributors) {
projectStatsQuery.top_contributors = 10
}

const {
data: projectStats,
error: projectStatsError,
Expand All @@ -109,7 +111,7 @@ function GroupStats({
error: topContributorsError,
isLoading: topContributorsLoading
} = usePanoptesUsers(usersQuery)

// fetch projects
const projectIds = allProjectsStats?.project_contributions?.map(project => project.project_id)
const projectsQuery = {
Expand All @@ -135,13 +137,13 @@ function GroupStats({
async function handleGroupMembershipLeave ({
membershipId
}) {
const userConfirmed = window.confirm('Are you sure you want to leave this group?')
const userConfirmed = window.confirm(t('GroupStats.leaveQuestion'))
if (!userConfirmed) return

await deleteMembership({ membershipId }, {
revalidate: true
})

window.location.href = '/'
}

Expand All @@ -152,7 +154,8 @@ function GroupStats({
group,
handleGroupMembershipLeave,
handleGroupModalActive,
membership
membership,
t
})

const error = statsError || projectStatsError || projectsError
Expand All @@ -163,7 +166,7 @@ function GroupStats({
<GroupModal
active={groupModalActive}
handleClose={handleGroupModalActive}
title='manage group'
title={t('GroupStats.manage')}
titleColor='black'
>
<GroupUpdateFormContainer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { bool, func, node, shape, string } from 'prop-types'
import useSWRMutation from 'swr/mutation'
import { useTranslation } from '../../../../translations/i18n.js'

import {
deletePanoptesUserGroup,
Expand All @@ -18,6 +19,7 @@ function GroupUpdateFormContainer({
handleGroupModalActive = DEFAULT_HANDLER,
login
}) {
const { t } = useTranslation()
const { trigger: updateGroup } = useSWRMutation({
adminMode,
authUserId,
Expand All @@ -28,7 +30,7 @@ function GroupUpdateFormContainer({
try {
const deleteResponse = await deletePanoptesUserGroup({ groupId: group?.id })
if (!deleteResponse.ok) {
await alert(`Something went wrong. Please try again.\nError: ${deleteResponse?.statusText}`)
await alert(`${t('GroupStats.GroupUpdateFormContainer.error')} \n ${deleteResponse?.statusText}`)
return console.error(deleteResponse)
} else {
window.location.href = `/users/${login}/groups`
Expand All @@ -37,15 +39,15 @@ function GroupUpdateFormContainer({
console.error(error)
}
}

async function onSubmit(event) {
const { display_name, stats_visibility } = event.value
const data = {
display_name,
private: stats_visibility.startsWith('private'),
stats_visibility
}

try {
updateGroup({ groupId: group.id, data }, {
optimisticData: { ...group, ...data },
Expand Down
Loading

0 comments on commit fd585a1

Please sign in to comment.