Skip to content

Commit

Permalink
track auth modal's activeIndex in the UI store (#5871)
Browse files Browse the repository at this point in the history
  • Loading branch information
goplayoutside3 authored Jan 25, 2024
1 parent 1658e3e commit 439fee8
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const stores = {
project: {
isComplete: false
},
ui: {
setAuthModalActiveIndex: () => {}
},
user: {
isLoggedIn: false,
personalization: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,29 @@ function useStores(mockStore) {
const stores = useContext(MobXProviderContext)
const store = mockStore || stores.store

const { setAuthModalActiveIndex } = store.ui

const { isLoggedIn } = store.user
const { sessionCount } = store.user.personalization
const { isComplete } = store.project
const afterFive = sessionCount >= 5
const isVisible = !isLoggedIn && !isComplete && afterFive
return {
isVisible
isVisible,
setAuthModalActiveIndex
}
}

function AuthenticationInvitationConnector ({ mockStore }) {
const { isVisible = false } = useStores(mockStore)
function AuthenticationInvitationConnector({ mockStore }) {
const { isVisible = false, setAuthModalActiveIndex } = useStores(mockStore)

return (
<DynamicallyImportedAuthenticationInvitationContainer isVisible={isVisible} />
<DynamicallyImportedAuthenticationInvitationContainer
isVisible={isVisible}
setAuthModalActiveIndex={setAuthModalActiveIndex}
/>
)
}

export default observer(AuthenticationInvitationConnector)
export { AuthenticationInvitationConnector }
export { AuthenticationInvitationConnector }
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ describe('Component > AuthenticationInvitationConnector', function () {
project: {
isComplete: false
},
ui: {
setAuthModalActiveIndex: () => {}
},
user: {
isLoggedIn: false,
personalization: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
import { useState } from 'react'
import styled from 'styled-components'
import { useTranslation } from 'next-i18next'
import PlainButton from '@zooniverse/react-components/PlainButton'
import { bool, func } from 'prop-types'

import { Anchor } from 'grommet'
import NavLink from '@shared/components/NavLink'
import GenericAnnouncement from '../GenericAnnouncement'

const StyledAnchor = styled(Anchor)`
line-height: 19px;
`
const DEFAULT_HANDLER = () => {}

export default function AuthenticationInvitationContainer({ isVisible }) {
export default function AuthenticationInvitationContainer({
isVisible = false,
setAuthModalActiveIndex = DEFAULT_HANDLER
}) {
const { t } = useTranslation('components')
const [dismissed, setDismissed] = useState(false)
const { pathname } = window.location
const signInLink = {
href: `${pathname}?login=true`,
text: t('Announcements.AuthenticationInvitation.signIn')
}
const registerLink = {
href: `${pathname}?register=true`,
text: t('Announcements.AuthenticationInvitation.register')
}

// TODO: maybe show project specific message here. Then fallback on generic.
const announcement = t('Announcements.AuthenticationInvitation.announcement')

function dismissBanner() {
setDismissed(true)
}

const signInLabel = t('Announcements.AuthenticationInvitation.signIn')
const registerLabel = t('Announcements.AuthenticationInvitation.register')

if (isVisible && !dismissed) {
return (
<GenericAnnouncement
Expand All @@ -38,11 +31,26 @@ export default function AuthenticationInvitationContainer({ isVisible }) {
color='neutral-5'
dismissable
>
<NavLink color='#000000' link={signInLink} weight='normal' StyledAnchor={StyledAnchor} />
<NavLink color='#000000' link={registerLink} weight='normal' StyledAnchor={StyledAnchor} />
<PlainButton
color='black'
text={signInLabel}
onClick={() => setAuthModalActiveIndex(0)}
/>
<PlainButton
color='black'
text={registerLabel}
onClick={() => setAuthModalActiveIndex(1)}
/>
</GenericAnnouncement>
)
}

return null
}

AuthenticationInvitationContainer.propTypes = {
/** Announcement component is visible when not logged in and after 5 classifications */
isVisible: bool,
/** Handles AuthModal in PageHeader */
setAuthModalActiveIndex: func
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { mount, shallow } from 'enzyme'
import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime'
import { CloseButton } from '@zooniverse/react-components'
import { CloseButton, PlainButton } from '@zooniverse/react-components'
import AuthenticationInvitationContainer from './AuthenticationInvitationContainer'
import GenericAnnouncement from '../GenericAnnouncement'
import NavLink from '@shared/components/NavLink'

describe('Component > AuthenticationInvitationContainer', function () {
const mockRouter = {
Expand All @@ -29,16 +28,6 @@ describe('Component > AuthenticationInvitationContainer', function () {
expect(componentWrapper).to.have.lengthOf(1)
})

it('should have a link to the login form', function () {
const signInLink = wrapper.find(NavLink).first()
expect(signInLink.props().link.href).to.equal(`${window.location.pathname}?login=true`)
})

it('should have a link to the register form', function () {
const registerLink = wrapper.find(NavLink).last()
expect(registerLink.props().link.href).to.equal(`${window.location.pathname}?register=true`)
})

describe('when not visible', function () {
before(function () {
wrapper = shallow(<AuthenticationInvitationContainer />)
Expand Down
21 changes: 10 additions & 11 deletions packages/app-project/src/components/PageHeader/PageHeader.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { AuthModal, ZooHeader } from '@zooniverse/react-components'
import auth from 'panoptes-client/lib/auth'
import { MobXProviderContext, observer } from 'mobx-react'
import { useContext, useState } from 'react'
import { useContext } from 'react'
import { bool } from 'prop-types'
import ThemeModeContext from '@shared/contexts/ThemeModeContext.js'

function useStore() {
const { store } = useContext(MobXProviderContext)
const { user: userStore } = store
return { userStore }
const { user: userStore, ui: uiStore } = store
return { uiStore, userStore }
}

function PageHeader({ adminMode }) {
const [activeIndex, setActiveIndex] = useState(-1)

const { userStore } = useStore()
const { uiStore, userStore } = useStore()
const { authModalActiveIndex, setAuthModalActiveIndex } = uiStore
const { admin, display_name, login } = userStore

const userProp = userStore.isLoggedIn ? { admin, display_name, login } : {}
Expand All @@ -37,23 +36,23 @@ function PageHeader({ adminMode }) {
}

function openRegisterModal() {
setActiveIndex(1)
setAuthModalActiveIndex(1)
}

function openSignInModal() {
setActiveIndex(0)
setAuthModalActiveIndex(0)
}

function closeAuthModal() {
setActiveIndex(-1)
setAuthModalActiveIndex(-1)
}

return (
<>
<AuthModal
activeIndex={activeIndex}
activeIndex={authModalActiveIndex}
closeModal={closeAuthModal}
onActive={setActiveIndex}
onActive={setAuthModalActiveIndex}
onSignIn={onSignIn}
/>
<ZooHeader
Expand Down
5 changes: 5 additions & 0 deletions packages/app-project/stores/UI.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const canSetCookie = process.browser || process.env.BABEL_ENV === 'test'

const UI = types
.model('UI', {
authModalActiveIndex: types.optional(types.number, -1),
dismissedProjectAnnouncementBanner: types.maybeNull(types.number),
})

Expand Down Expand Up @@ -68,6 +69,10 @@ const UI = types
}
},

setAuthModalActiveIndex(index) {
self.authModalActiveIndex = index
},

setProjectAnnouncementBannerCookie() {
const { slug } = getRoot(self).project
document.cookie = cookie.serialize('dismissedProjectAnnouncementBanner', self.dismissedProjectAnnouncementBanner, {
Expand Down

0 comments on commit 439fee8

Please sign in to comment.