Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C-3255] Sub-route logic & redirects for sign up flow #6489

Merged
merged 13 commits into from
Oct 28, 2023
15 changes: 13 additions & 2 deletions packages/web/src/pages/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ import {
PURCHASES_PAGE,
SALES_PAGE,
WITHDRAWALS_PAGE,
EXPLORE_PREMIUM_TRACKS_PAGE
EXPLORE_PREMIUM_TRACKS_PAGE,
SIGN_UP_STEP_PAGE,
SIGN_UP_START_PAGE
} from 'utils/route'
import { getTheme as getSystemTheme } from 'utils/theme/theme'

Expand Down Expand Up @@ -514,11 +516,20 @@ class App extends Component {
</Route>
<Route exact path={SIGN_UP_PAGE} isMobile={isMobileClient}>
{isSignInRedesignEnabled ? (
<SignUpRootPage />
<Redirect to={SIGN_UP_START_PAGE} />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeps all the links the same (i.e. /signup will redirect to /signup/create-account)

) : (
<SignOn signIn={false} initialPage={initialPage} />
)}
</Route>
{isSignInRedesignEnabled ? (
<Route
exact
path={SIGN_UP_STEP_PAGE}
isMobile={isMobileClient}
>
<SignUpRootPage />
</Route>
) : null}
<Route
exact
path={FEED_PAGE}
Expand Down
97 changes: 74 additions & 23 deletions packages/web/src/pages/sign-up-page/SignUpRootPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { useState } from 'react'
import { useEffect, useState } from 'react'

import { useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'

import { getSignOn } from 'common/store/pages/signon/selectors'
import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { SIGN_UP_PAGE } from 'utils/route'

import { AppCtaPage, AppCtaState } from './pages/AppCtaPage'
import {
CreatePasswordPage,
CreatePasswordState
Expand All @@ -16,6 +22,7 @@ import {
} from './pages/SelectArtistsPage'
import { SelectGenrePage, SelectGenreState } from './pages/SelectGenrePage'
import { SignUpPage, SignUpState } from './pages/SignUpPage'
import { SignUpStep } from './pages/types'

type SignUpRootState =
| SignUpState
Expand All @@ -24,38 +31,82 @@ type SignUpRootState =
| FinishProfileState
| SelectGenreState
| SelectArtistsState
| AppCtaState
// | AppCtaState

// TODO: type this correctly
const determineAllowedRoute = (signUpData: any, routeAttempt: SignUpStep) => {
DejayJD marked this conversation as resolved.
Show resolved Hide resolved
let allowedRoutes = [SignUpStep.createAccount]
if (signUpData.email.value) {
allowedRoutes.push(SignUpStep.createPassword)
// SignUpStep.createAccount
}
if (signUpData.password.value) {
allowedRoutes.push(SignUpStep.pickHandle)
}
if (signUpData.handle.value) {
allowedRoutes.push(SignUpStep.finishProfile)
}
if (signUpData.name.value) {
// At this point the account is created and we can no longer go back to previous steps
allowedRoutes = [SignUpStep.selectGenres]
}
// TODO: need to get this from a different part of the store
if (signUpData.genres?.value) {
allowedRoutes.push(SignUpStep.selectArtists)
}
if (signUpData.artists?.value) {
// TODO: if we're here we should be redirecting to /trending
}

const isAllowedRoute = allowedRoutes.includes(routeAttempt)
// If requested route is allowed return that, otherwise return the last step in the route stack
return isAllowedRoute ? routeAttempt : allowedRoutes[allowedRoutes.length - 1]
}

export const SignUpRootPage = () => {
const [signUpState, setSignUpState] = useState<SignUpRootState>({
stage: 'sign-up'
stage: SignUpStep.createAccount
})
const currentStage = signUpState.stage
const currentParams = useParams<{ step: SignUpStep }>()
const navigate = useNavigateToPage()
// @ts-ignore
const signOnState = useSelector((state) => getSignOn(state))

// Redirect handler logic
useEffect(() => {
const allowedRoute = determineAllowedRoute(signOnState, currentParams.step)
// console.log(
// 'Attempted to route to:',
// currentParams.step,
// '; now routing to ',
// allowedRoute
// )
// If the requested step is not allowed, redirect accordingly
if (allowedRoute !== currentParams.step) {
navigate(`${SIGN_UP_PAGE}/${allowedRoute}`)
}
// Sync the stage accordingly
// @ts-ignore
setSignUpState({ stage: allowedRoute })
}, [currentParams, currentStage, navigate, signOnState])

return (
<div>
{signUpState.stage === 'sign-up' ? (
<SignUpPage onNext={setSignUpState} />
) : null}
{signUpState.stage === 'create-password' ? (
<CreatePasswordPage
params={signUpState.params}
onPrevious={setSignUpState}
onNext={setSignUpState}
/>
) : null}
{signUpState.stage === 'pick-handle' ? (
<PickHandlePage onNext={setSignUpState} />
{signUpState.stage === SignUpStep.createAccount ? <SignUpPage /> : null}
{signUpState.stage === SignUpStep.createPassword ? (
<CreatePasswordPage params={signUpState.params} />
) : null}
{signUpState.stage === 'finish-profile' ? (
<FinishProfilePage onNext={setSignUpState} />
{signUpState.stage === SignUpStep.pickHandle ? <PickHandlePage /> : null}
{signUpState.stage === SignUpStep.finishProfile ? (
<FinishProfilePage />
) : null}
{signUpState.stage === 'select-genre' ? (
<SelectGenrePage onNext={setSignUpState} />
{signUpState.stage === SignUpStep.selectGenres ? (
<SelectGenrePage />
) : null}
{signUpState.stage === 'select-artists' ? (
<SelectArtistsPage onNext={setSignUpState} />
{signUpState.stage === SignUpStep.selectArtists ? (
<SelectArtistsPage />
) : null}
{signUpState.stage === 'app-cta' ? <AppCtaPage /> : null}
</div>
)
}
17 changes: 8 additions & 9 deletions packages/web/src/pages/sign-up-page/pages/CreatePasswordPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { useDispatch } from 'react-redux'

import { setValueField } from 'common/store/pages/signon/actions'
import { TextField } from 'components/form-fields'
import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { SIGN_UP_PAGE } from 'utils/route'

import { PickHandleState } from './PickHandlePage'
import { SignUpState } from './SignUpPage'
import { SignUpStep } from './types'

const messages = {
header: 'Create Your Password',
Expand All @@ -21,7 +22,7 @@ const messages = {
}

export type CreatePasswordState = {
stage: 'create-password'
stage: SignUpStep.createPassword
params: {
email: string
}
Expand All @@ -39,22 +40,20 @@ type CreatePasswordValues = {

type CreatePasswordPageProps = {
params: { email: string }
onPrevious: (state: SignUpState) => void
onNext: (state: PickHandleState) => void
}

export const CreatePasswordPage = (props: CreatePasswordPageProps) => {
const { params, onNext } = props
const { email } = params
const { email } = { email: '' }
const dispatch = useDispatch()
const navigate = useNavigateToPage()

const handleSubmit = useCallback(
(values: CreatePasswordValues) => {
const { password } = values
dispatch(setValueField('password', password))
onNext({ stage: 'pick-handle' })
navigate(`${SIGN_UP_PAGE}/${SignUpStep.pickHandle}`)
},
[dispatch, onNext]
[dispatch, navigate]
)

return (
Expand Down
16 changes: 8 additions & 8 deletions packages/web/src/pages/sign-up-page/pages/FinishProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { useDispatch } from 'react-redux'

import { setValueField } from 'common/store/pages/signon/actions'
import { TextField } from 'components/form-fields'
import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { SIGN_UP_PAGE } from 'utils/route'

import { CoverPhotoField } from '../components/CoverPhotoField'
import { ProfilePictureField } from '../components/ProfilePictureField'

import { SelectGenreState } from './SelectGenrePage'
import { SignUpStep } from './types'

const messages = {
header: 'Finish Your Profile',
Expand All @@ -22,12 +24,10 @@ const messages = {
}

export type FinishProfileState = {
stage: 'finish-profile'
stage: SignUpStep.finishProfile
}

type FinishProfilePageProps = {
onNext: (state: SelectGenreState) => void
}
type FinishProfilePageProps = {}

type FinishProfileValues = {
profile_picture: Nullable<{ file: File; url: string }>
Expand All @@ -42,16 +42,16 @@ const initialValues = {
}

export const FinishProfilePage = (props: FinishProfilePageProps) => {
const { onNext } = props
const dispatch = useDispatch()
const navigate = useNavigateToPage()

const handleSubmit = useCallback(
(values: FinishProfileValues) => {
const { displayName } = values
dispatch(setValueField('name', displayName))
onNext({ stage: 'select-genre' })
navigate(`${SIGN_UP_PAGE}/${SignUpStep.selectGenres}`)
},
[dispatch, onNext]
[dispatch, navigate]
)

return (
Expand Down
16 changes: 8 additions & 8 deletions packages/web/src/pages/sign-up-page/pages/PickHandlePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { useDispatch } from 'react-redux'

import { setValueField } from 'common/store/pages/signon/actions'
import { TextField } from 'components/form-fields'
import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { SIGN_UP_PAGE } from 'utils/route'

import { FinishProfileState } from './FinishProfilePage'
import { SignUpStep } from './types'

const messages = {
header: 'Pick Your Handle',
Expand All @@ -18,7 +20,7 @@ const messages = {
}

export type PickHandleState = {
stage: 'pick-handle'
stage: SignUpStep.pickHandle
}

const initialValues = {
Expand All @@ -29,21 +31,19 @@ type PickHandleValues = {
handle: string
}

type PickHandlePageProps = {
onNext: (state: FinishProfileState) => void
}
type PickHandlePageProps = {}

export const PickHandlePage = (props: PickHandlePageProps) => {
const { onNext } = props
const dispatch = useDispatch()
const navigate = useNavigateToPage()

const handleSubmit = useCallback(
(values: PickHandleValues) => {
const { handle } = values
dispatch(setValueField('handle', handle))
onNext({ stage: 'finish-profile' })
navigate(`${SIGN_UP_PAGE}/${SignUpStep.finishProfile}`)
},
[dispatch, onNext]
[dispatch, navigate]
)

return (
Expand Down
17 changes: 9 additions & 8 deletions packages/web/src/pages/sign-up-page/pages/SelectArtistsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { useDispatch } from 'react-redux'

import { addFollowArtists } from 'common/store/pages/signon/actions'
import { getGenres } from 'common/store/pages/signon/selectors'
import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { useSelector } from 'utils/reducer'
import { TRENDING_PAGE } from 'utils/route'

import { AppCtaState } from './AppCtaPage'
import { SignUpStep } from './types'

const messages = {
header: 'Follow At Least 3 Artists',
Expand All @@ -26,7 +28,7 @@ const messages = {
}

export type SelectArtistsState = {
stage: 'select-artists'
stage: SignUpStep.selectArtists
}

type SelectArtistsValues = {
Expand All @@ -37,15 +39,13 @@ const initialValues: SelectArtistsValues = {
artists: []
}

type SelectArtistsPageProps = {
onNext: (state: AppCtaState) => void
}
type SelectArtistsPageProps = {}

export const SelectArtistsPage = (props: SelectArtistsPageProps) => {
const { onNext } = props
const genres = useSelector((state) => ['Featured', ...getGenres(state)])
const [currentGenre, setCurrentGenre] = useState('Featured')
const dispatch = useDispatch()
const navigate = useNavigateToPage()

const handleChangeGenre = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setCurrentGenre(e.target.value)
Expand All @@ -55,9 +55,10 @@ export const SelectArtistsPage = (props: SelectArtistsPageProps) => {
(values: SelectArtistsValues) => {
const { artists } = values
dispatch(addFollowArtists(artists))
onNext({ stage: 'app-cta' })
// TODO: trigger CTA modal on trending page
navigate(TRENDING_PAGE)
},
[dispatch, onNext]
[dispatch, navigate]
)

const isFeaturedArtists = currentGenre === 'Featured'
Expand Down
Loading