Date: Thu, 6 Jun 2024 15:30:15 -0500
Subject: [PATCH 4/7] add responsive styling to avatar
---
.../components/Dashboard/Dashboard.js | 24 +++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
index f7cd046b26..d08e8c6b5d 100644
--- a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
+++ b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
@@ -1,6 +1,7 @@
-import { Box, Image } from 'grommet'
+import { Box, Image, ResponsiveContext } from 'grommet'
import styled from 'styled-components'
import { shape, string } from 'prop-types'
+import { useContext } from 'react'
const Relative = styled(Box)`
position: relative;
@@ -11,19 +12,32 @@ const StyledAvatar = styled(Image)`
height: 128px;
object-fit: cover;
border-radius: 50%;
- border: solid white 5px;
+ border: solid white 6px;
position: absolute;
- top: 206px;
+ top: 203px;
+
+ // For Grommet breakpoint small
+ @media (width < 769px) {
+ width: 80px;
+ height: 80px;
+ top: 137px;
+ }
`
export default function Dashboard({ authUser, profileBannerSrc = '' }) {
+ const size = useContext(ResponsiveContext)
+
return (
Date: Thu, 6 Jun 2024 20:58:30 -0500
Subject: [PATCH 5/7] fetch user resource via panoptes in DashboardContainer
---
.../components/Dashboard/Dashboard.js | 26 ++++++++++-------
.../components/Dashboard/Dashboard.stories.js | 25 ++++++++++++----
.../Dashboard/DashboardContainer.js | 29 +++++++++++--------
3 files changed, 53 insertions(+), 27 deletions(-)
diff --git a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
index d08e8c6b5d..df1c3316a9 100644
--- a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
+++ b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.js
@@ -1,6 +1,6 @@
import { Box, Image, ResponsiveContext } from 'grommet'
import styled from 'styled-components'
-import { shape, string } from 'prop-types'
+import { bool, shape, string } from 'prop-types'
import { useContext } from 'react'
const Relative = styled(Box)`
@@ -24,7 +24,7 @@ const StyledAvatar = styled(Image)`
}
`
-export default function Dashboard({ authUser, profileBannerSrc = '' }) {
+export default function Dashboard({ isLoading = false, user }) {
const size = useContext(ResponsiveContext)
return (
@@ -36,15 +36,19 @@ export default function Dashboard({ authUser, profileBannerSrc = '' }) {
? { min: '270px', max: '270px' }
: { min: '180px', max: '180px' }
}
- background={{ image: `url(${profileBannerSrc})`, color: 'neutral-1' }}
+ background={
+ isLoading || !user?.profile_header
+ ? 'brand'
+ : { image: `url(${user.profile_header})` }
+ }
round={size !== 'small' ? { size: '16px', corner: 'top' } : false}
>
@@ -52,8 +56,10 @@ export default function Dashboard({ authUser, profileBannerSrc = '' }) {
}
Dashboard.propTypes = {
- authUser: shape({
- id: string
- }),
- profileBannerSrc: string
+ isLoading: bool,
+ user: shape({
+ avatar_src: string,
+ id: string.isRequired,
+ profile_header: string
+ })
}
diff --git a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.stories.js b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.stories.js
index 5088c1acc0..0ec141f612 100644
--- a/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.stories.js
+++ b/packages/lib-user/src/components/UserHome/components/Dashboard/Dashboard.stories.js
@@ -1,4 +1,3 @@
-import { GROUP_ADMIN_USER, USER } from '../../../../../test/mocks/panoptes/users.js'
import Dashboard from './Dashboard.js'
export default {
@@ -6,16 +5,32 @@ export default {
component: Dashboard
}
+const USER = {
+ admin: false,
+ avatar_src: 'https://panoptes-uploads-staging.zooniverse.org/user_avatar/e638f5a3-7ffb-4d23-bb08-f296377a2e74.jpeg',
+ display_name: 'Test User 1',
+ id: '12345',
+ login: 'TestUser',
+ profile_header: 'https://panoptes-uploads.zooniverse.org/user_profile_header/9da9fd16-46c1-4d84-a272-83ac19fb32c3.jpeg'
+}
+
+const USER_NO_IMAGES = {
+ admin: false,
+ avatar_src: '',
+ display_name: 'Zootester 123',
+ id: '847637',
+ login: 'zootester123',
+ profile_header: ''
+}
+
export const Default = {
args: {
- authUser: USER,
- profileBannerSrc: 'https://panoptes-uploads.zooniverse.org/user_profile_header/9da9fd16-46c1-4d84-a272-83ac19fb32c3.jpeg'
+ user: USER
}
}
export const NoAvatarOrBanner = {
args: {
- authUser: GROUP_ADMIN_USER,
- profileBannerSrc: ''
+ user: USER_NO_IMAGES
}
}
diff --git a/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js b/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
index 617506a822..4ca53b6746 100644
--- a/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
+++ b/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
@@ -4,6 +4,15 @@ import useSWR from 'swr'
import Dashboard from './Dashboard'
+const SWROptions = {
+ revalidateIfStale: true,
+ revalidateOnMount: true,
+ revalidateOnFocus: true,
+ revalidateOnReconnect: true,
+ refreshInterval: 0
+}
+
+/* This is a similar pattern to usePanoptesUser hook, but includes the profile_header */
const fetchProfileBanner = async ({ authUser }) => {
const token = await auth.checkBearerToken()
const authorization = `Bearer ${token}`
@@ -11,25 +20,21 @@ const fetchProfileBanner = async ({ authUser }) => {
try {
const { body } = await panoptes.get('/users', query, { authorization })
- const profileBannerSrc = body.linked.profile_headers[0].src
- return profileBannerSrc
+ const user = body.users?.[0]
+
+ if (body.linked?.profile_headers?.length) {
+ user.profile_header = body.linked.profile_headers[0].src
+ }
+ return user
} catch (error) {
console.error(error)
return null
}
}
-const SWROptions = {
- revalidateIfStale: true,
- revalidateOnMount: true,
- revalidateOnFocus: true,
- revalidateOnReconnect: true,
- refreshInterval: 0
-}
-
export default function DashboardContainer({ authUser }) {
const key = { authUser }
- const { data: profileBannerSrc } = useSWR(key, fetchProfileBanner, SWROptions)
+ const { data: user, isLoading } = useSWR(key, fetchProfileBanner, SWROptions)
- return
+ return
}
From 0685e44ab10c85a54463bdbe5f3a0a75412d7fe1 Mon Sep 17 00:00:00 2001
From: Delilah <23665803+goplayoutside3@users.noreply.github.com>
Date: Thu, 6 Jun 2024 21:07:33 -0500
Subject: [PATCH 6/7] import UserHome into lib-user dev App
---
packages/lib-user/dev/components/App/App.js | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/packages/lib-user/dev/components/App/App.js b/packages/lib-user/dev/components/App/App.js
index e6be895c39..374a164169 100644
--- a/packages/lib-user/dev/components/App/App.js
+++ b/packages/lib-user/dev/components/App/App.js
@@ -9,6 +9,7 @@ import {
Contributors,
GroupStats,
MyGroups,
+ UserHome,
UserStats
} from '@components'
@@ -31,7 +32,7 @@ function App({
useEffect(() => {
async function checkUserSession() {
setLoading(true)
-
+
try {
const user = await auth.checkCurrent()
setUser(user)
@@ -41,7 +42,7 @@ function App({
setLoading(false)
}
}
-
+
auth.listen('change', checkUserSession)
return function () {
@@ -93,13 +94,14 @@ function App({
+ {user?.id ? : null}
)
if (groups) {
const subpaths = groups.split('/')
const groupId = subpaths[0] || ''
-
+
if (subpaths[0] === '[user_group_id]') {
content = In the url query param ?groups=
, please replace [user_group_id]
with a user group id.
} else if (subpaths[1] === 'contributors') {
@@ -185,7 +187,7 @@ function App({
/>
- {loading ?
+ {loading ?
Loading...
: (
{content}
From 6359f59b739f0494530a8297f060338ca1c25b98 Mon Sep 17 00:00:00 2001
From: Delilah <23665803+goplayoutside3@users.noreply.github.com>
Date: Fri, 7 Jun 2024 17:26:54 -0500
Subject: [PATCH 7/7] add endpoint to DashboardContainer key and no need for
authorization
---
.../components/Dashboard/DashboardContainer.js | 11 +++--------
.../UserHome/components/SubjectCard/SubjectCard.js | 4 ++--
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js b/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
index 4ca53b6746..31ab8f324d 100644
--- a/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
+++ b/packages/lib-user/src/components/UserHome/components/Dashboard/DashboardContainer.js
@@ -1,5 +1,4 @@
import { panoptes } from '@zooniverse/panoptes-js'
-import auth from 'panoptes-client/lib/auth'
import useSWR from 'swr'
import Dashboard from './Dashboard'
@@ -13,13 +12,9 @@ const SWROptions = {
}
/* This is a similar pattern to usePanoptesUser hook, but includes the profile_header */
-const fetchProfileBanner = async ({ authUser }) => {
- const token = await auth.checkBearerToken()
- const authorization = `Bearer ${token}`
- const query = { include: 'profile_header', user_id: authUser.id }
-
+const fetchProfileBanner = async ({ authUser}) => {
try {
- const { body } = await panoptes.get('/users', query, { authorization })
+ const { body } = await panoptes.get(`/users/${authUser.id}/?include=profile_header`)
const user = body.users?.[0]
if (body.linked?.profile_headers?.length) {
@@ -33,7 +28,7 @@ const fetchProfileBanner = async ({ authUser }) => {
}
export default function DashboardContainer({ authUser }) {
- const key = { authUser }
+ const key = { endpoint: '/users/[id]', authUser }
const { data: user, isLoading } = useSWR(key, fetchProfileBanner, SWROptions)
return
diff --git a/packages/lib-user/src/components/UserHome/components/SubjectCard/SubjectCard.js b/packages/lib-user/src/components/UserHome/components/SubjectCard/SubjectCard.js
index 2c131ad333..4fbac524a5 100644
--- a/packages/lib-user/src/components/UserHome/components/SubjectCard/SubjectCard.js
+++ b/packages/lib-user/src/components/UserHome/components/SubjectCard/SubjectCard.js
@@ -12,7 +12,7 @@
import styled from 'styled-components'
import { Anchor, Box } from 'grommet'
import { Media, SpacedText } from '@zooniverse/react-components'
-import { number, string } from 'prop-types'
+import { string } from 'prop-types'
const StyledAnchor = styled(Anchor)`
text-decoration: none;
@@ -99,5 +99,5 @@ SubjectCard.propTypes = {
size: string,
projectSlug: string,
mediaSrc: string,
- subjectID: number.isRequired
+ subjectID: string.isRequired
}