Skip to content

Commit

Permalink
Merge branch 'master' into homepage-groups-preview
Browse files Browse the repository at this point in the history
  • Loading branch information
mcbouslog authored Jun 17, 2024
2 parents 57a10a4 + 37bef25 commit f80440d
Show file tree
Hide file tree
Showing 57 changed files with 1,119 additions and 251 deletions.
Binary file added packages/app-root/public/assets/LTSignature.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MyGroups } from '@zooniverse/user'
import { useContext } from 'react'

import { PanoptesAuthContext } from '../../../../contexts'
import AuthenticatedUsersPageContainer from '../components/AuthenticatedUsersPageContainer'
import AuthenticatedUsersPageContainer from '../../../../components/AuthenticatedUsersPageContainer'

function MyGroupsContainer({
login
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
import { UserStats } from '@zooniverse/user'
import { useContext } from 'react'

import { PanoptesAuthContext } from '../../../../contexts'
import AuthenticatedUsersPageContainer from '../components/AuthenticatedUsersPageContainer'
import { PanoptesAuthContext, UserStatsContext } from '../../../../contexts'
import AuthenticatedUsersPageContainer from '../../../../components/AuthenticatedUsersPageContainer'

function UserStatsContainer({
login
}) {
const { adminMode, isLoading, user } = useContext(PanoptesAuthContext)
const {
selectedDateRange,
selectedProject,
setSelectedDateRange,
setSelectedProject
} = useContext(UserStatsContext)

return (
<AuthenticatedUsersPageContainer
Expand All @@ -21,6 +27,10 @@ function UserStatsContainer({
<UserStats
authUser={user}
login={login}
selectedDateRange={selectedDateRange}
selectedProject={selectedProject}
setSelectedDateRange={setSelectedDateRange}
setSelectedProject={setSelectedProject}
/>
</AuthenticatedUsersPageContainer>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client'

import { Certificate } from '@zooniverse/user'
import { useContext } from 'react'

import { PanoptesAuthContext, UserStatsContext } from '../../../../../contexts'
import AuthenticatedUsersPageContainer from '../../../../../components/AuthenticatedUsersPageContainer'

function CertificateContainer({
login
}) {
const { adminMode, isLoading, user } = useContext(PanoptesAuthContext)
const {
selectedDateRange,
selectedProject
} = useContext(UserStatsContext)

return (
<AuthenticatedUsersPageContainer
adminMode={adminMode}
isLoading={isLoading}
login={login}
user={user}
>
<Certificate
authUser={user}
login={login}
selectedDateRange={selectedDateRange}
selectedProject={selectedProject}
/>
</AuthenticatedUsersPageContainer>
)
}

export default CertificateContainer
14 changes: 14 additions & 0 deletions packages/app-root/src/app/users/[login]/stats/certificate/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CertificateContainer from './CertificateContainer'

export const metadata = {
title: 'Certificate',
description: 'My Zooniverse certificate page'
}

export default function Certificate({ params }) {
return (
<CertificateContainer
login={params.login}
/>
)
}
9 changes: 9 additions & 0 deletions packages/app-root/src/app/users/[login]/stats/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UserStatsContextProvider from '../../../../components/UserStatsContextProvider'

export default function UserStatsLayout({ children }) {
return (
<UserStatsContextProvider>
{children}
</UserStatsContextProvider>
)
}
27 changes: 27 additions & 0 deletions packages/app-root/src/components/UserStatsContextProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client'

import { useContext } from 'react'

import { PanoptesAuthContext, UserStatsContext } from '../contexts'
import { useStatsDateRange, useStatsProject } from '../hooks'

function UserStatsContextProvider({ children }) {
const { isLoading, user } = useContext(PanoptesAuthContext)
const { selectedDateRange, setSelectedDateRange } = useStatsDateRange({ isLoading, user })
const { selectedProject, setSelectedProject } = useStatsProject({ isLoading, user })

const statsContext = {
selectedDateRange,
selectedProject,
setSelectedDateRange,
setSelectedProject
}

return (
<UserStatsContext.Provider value={statsContext}>
{children}
</UserStatsContext.Provider>
)
}

export default UserStatsContextProvider
5 changes: 5 additions & 0 deletions packages/app-root/src/contexts/UserStatsContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from 'react'

const UserStatsContext = createContext({})

export default UserStatsContext
1 change: 1 addition & 0 deletions packages/app-root/src/contexts/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as PanoptesAuthContext } from './PanoptesAuthContext.js'
export { default as ThemeModeContext } from './ThemeModeContext.js'
export { default as UserStatsContext } from './UserStatsContext.js'
2 changes: 2 additions & 0 deletions packages/app-root/src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { default as useAdminMode } from './useAdminMode.js'
export { default as usePreferredTheme } from './usePreferredTheme.js'
export { default as useStatsDateRange } from './useStatsDateRange.js'
export { default as useStatsProject } from './useStatsProject.js'
26 changes: 26 additions & 0 deletions packages/app-root/src/hooks/useStatsDateRange.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react'

const isBrowser = typeof window !== 'undefined'
const localStorage = isBrowser ? window.localStorage : null

let initialDateRange = 'Last7Days'
if (isBrowser) {
initialDateRange = localStorage?.getItem('selectedDateRange') || initialDateRange
}

export default function useStatsDateRange({ isLoading, user }) {
const [selectedDateRange, setSelectedDateRange] = useState(initialDateRange)

useEffect(function onDateRangeChange() {
localStorage?.setItem('selectedDateRange', selectedDateRange)
}, [selectedDateRange])

useEffect(function onUserChange() {
// when a user successfully logs out isLoading is false and user is undefined
if (!isLoading && !user?.login) {
setSelectedDateRange('Last7Days')
}
}, [isLoading, user?.login])

return { selectedDateRange, setSelectedDateRange }
}
26 changes: 26 additions & 0 deletions packages/app-root/src/hooks/useStatsProject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react'

const isBrowser = typeof window !== 'undefined'
const localStorage = isBrowser ? window.localStorage : null

let initialProject = 'AllProjects'
if (isBrowser) {
initialProject = localStorage?.getItem('selectedProject') || initialProject
}

export default function useStatsProject({ isLoading, user }) {
const [selectedProject, setSelectedProject] = useState(initialProject)

useEffect(function onProjectChange() {
localStorage?.setItem('selectedProject', selectedProject)
}, [selectedProject])

useEffect(function onUserChange() {
// when a user successfully logs out isLoading is false and user is undefined
if (!isLoading && !user?.login) {
setSelectedProject('AllProjects')
}
}, [isLoading, user?.login])

return { selectedProject, setSelectedProject }
}
7 changes: 7 additions & 0 deletions packages/lib-react-components/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# Change Log

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

- ZooFooter and ZooHeader styling to include `display: none;` when printing (`@media print`)

## [1.13.0] 2024-05-17

### Added
Expand Down
53 changes: 35 additions & 18 deletions packages/lib-react-components/src/ProjectCard/ProjectCard.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Box } from 'grommet'
import { string } from 'prop-types'
import { Box, Text } from 'grommet'
import { number, string } from 'prop-types'
import styled from 'styled-components'
import SpacedText from '../SpacedText'

Expand Down Expand Up @@ -42,42 +42,55 @@ const StyledProjectDescription = styled(SpacedText)`
}
`

function cardWidth (size) {
const StyledBadge = styled(Text)`
display: flex;
margin: 5px 5px 5px auto;
border-radius: 50%;
padding: 3px;
background: white;
aspect-ratio: 1 / 1;
text-align: center;
align-items: center;
justify-content: center;
`

function cardWidth(size) {
switch (size) {
case 'small':
return 157;
return 157
case 'medium':
return 189;
return 189
case 'large':
return 220;
return 220
case 'xlarge':
return 252;
return 252
default:
return 189;
return 189
}
}

function cardFontSize (size) {
function cardFontSize(size) {
switch (size) {
case 'small':
return '0.625rem';
return '0.625rem'
case 'medium':
return '0.656rem';
return '0.656rem'
case 'large':
return '0.688rem';
return '0.688rem'
case 'xlarge':
return '0.8rem';
return '0.8rem'
default:
return '0.656rem';
return '0.656rem'
}
}

function ProjectCard ({
function ProjectCard({
badge = undefined,
description = '',
displayName = '',
href = '',
imageSrc = '',
size = 'medium',
size = 'medium'
}) {
return (
<StyledProjectCard
Expand All @@ -87,19 +100,22 @@ function ProjectCard ({
href={href}
round='8px'
cardFontSize={cardFontSize(size)}
height={`${cardWidth(size) * 14 / 11}px`}
height={`${(cardWidth(size) * 14) / 11}px`}
width={`${cardWidth(size)}px`}
>
<Box
className='project-image'
background={{
image: `url(${imageSrc})`,
position: 'top',
size: 'cover',
size: 'cover'
}}
height={`${cardWidth(size)}px`}
round={{ corner: 'top', size: '8px' }}
>
{badge ? <StyledBadge color='black' size='0.75rem' weight='bold'>
{badge}
</StyledBadge> : null}
</Box>
<StyledProjectContent
flex='grow'
Expand Down Expand Up @@ -129,6 +145,7 @@ function ProjectCard ({
}

ProjectCard.propTypes = {
badge: number,
description: string,
displayName: string,
href: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {

export const NfnCaliFlowers = {
args: {
badge: 3,
description: 'Using digital images to investigate ​phenological change in a biodiversity hotspot​',
displayName: `Notes from Nature - Capturing California's Flowers`,
imageSrc: 'https://panoptes-uploads.zooniverse.org/project_avatar/0c4cfec1-a15b-468e-9f57-e9133993532d.jpeg',
Expand Down
14 changes: 11 additions & 3 deletions packages/lib-react-components/src/ZooFooter/ZooFooter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Box, Grid } from 'grommet'
import { arrayOf, node, string } from 'prop-types'
import { useEffect } from 'react'
import styled from 'styled-components'
import i18n, { useTranslation } from '../translations/i18n'
import { useHasMounted } from '../hooks'

Expand All @@ -11,6 +12,13 @@ import {
SocialAnchor
} from './components'

const StyledFooter = styled(Box)`
// hide the footer when printing, added for the user stats certificate, but applies generally
@media print {
display: none;
}
`

const defaultProps = {
aboutNavListURLs: [
'https://www.zooniverse.org/about',
Expand Down Expand Up @@ -112,8 +120,8 @@ export default function ZooFooter({
const talkNavListLabels = [t('ZooFooter.talkLabels.talk')]

return (
<Box
as='footer'
<StyledFooter
forwardedAs='footer'
background={{
dark: 'dark-1',
light: 'white'
Expand Down Expand Up @@ -191,7 +199,7 @@ export default function ZooFooter({
/>
<Box>{hasMounted && adminContainer}</Box>
</Box>
</Box>
</StyledFooter>
)
}

Expand Down
5 changes: 5 additions & 0 deletions packages/lib-react-components/src/ZooHeader/ZooHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import ZooniverseLogo from '../ZooniverseLogo'
export const StyledHeader = styled(Box)`
color: #b2b2b2;
font-size: 1em;
// hide the header when printing, added for the user stats certificate, but applies generally
@media print {
display: none;
}
`

export const StyledLogoAnchor = styled(Anchor)`
Expand Down
Loading

0 comments on commit f80440d

Please sign in to comment.