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-3363] FollowArtistsPage initial layout #6692

Merged
merged 9 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/harmony/src/components/layout/Divider/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ import styled from '@emotion/styled'
export const Divider = styled.div(({ theme }) => ({
minHeight: 1,
minWidth: 1,
alignSelf: 'stretch',
backgroundColor: theme.color.border.strong
}))
6 changes: 4 additions & 2 deletions packages/harmony/src/components/layout/Paper/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import type {
ShadowOptions
} from 'foundations'

import type { FlexProps } from '../Flex'

/**
* An elevated container which stands out from the background.
*/
Expand All @@ -31,5 +33,5 @@ export type PaperProps = {
* Elevation Shadow
* @default mid
*/
shadow?: Exclude<ShadowOptions, 'drop'>
}
shadow?: Exclude<ShadowOptions, 'drop'> | 'none'
} & FlexProps
1 change: 1 addition & 0 deletions packages/harmony/src/foundations/spacing/spacing.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ root {
--harmony-spacing-2xl: 32px;
--harmony-spacing-3xl: 48px;
--harmony-spacing-4xl: 64px;
--harmony-spacing-5xl: 128px;
}
3 changes: 2 additions & 1 deletion packages/harmony/src/foundations/spacing/spacing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export const spacing = {
xl: 24,
'2xl': 32,
'3xl': 48,
'4xl': 64
'4xl': 64,
'5xl': 128
}

export type Spacing = typeof spacing
Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/pages/sign-up-page/SignUpRootPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box } from '@audius/harmony'
import { Paper } from '@audius/harmony'
import { useSelector } from 'react-redux'
import { Redirect, Route, RouteProps, Switch } from 'react-router-dom'

Expand Down Expand Up @@ -103,7 +103,7 @@ export function SignUpRoute({ children, ...rest }: RouteProps) {

export const SignUpRootPage = () => {
return (
<Box h='100%'>
<Paper w={1280} h={864} direction='column' m='4xl'>
<Switch>
<SignUpRoute exact path={SIGN_UP_EMAIL_PAGE}>
<SignUpPage />
Expand Down Expand Up @@ -144,6 +144,6 @@ export const SignUpRootPage = () => {
</Switch>
</SignUpRoute>
</Switch>
</Box>
</Paper>
)
}
102 changes: 102 additions & 0 deletions packages/web/src/pages/sign-up-page/components/FollowArtistTile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { HTMLProps } from 'react'

import { UserMetadata } from '@audius/common'
import {
Avatar,
Box,
Divider,
Flex,
IconNote,
IconUser,
IconUserFollow,
IconVerified,
Paper,
Text
} from '@audius/harmony'

import audiusCoverPhoto from 'assets/img/4-Conductor-16-9.jpg'
import audiusProfilePic from 'assets/img/appIcon240.png'

type FollowArtistTileProps = {
user: UserMetadata
} & HTMLProps<HTMLInputElement>

const FollowArtistTile = (props: FollowArtistTileProps) => {
const {
user: { name, user_id, is_verified, track_count, follower_count },
onChange
} = props
return (
<Paper w={235} h={220}>
<Flex w='100%' direction='column' alignItems='center'>
<Box w={72} h={72} css={{ position: 'absolute', top: 34 }}>
<Avatar variant='strong' src={audiusProfilePic} />
</Box>
<Box
w='100%'
h={68}
css={{ backgroundImage: `url(${audiusCoverPhoto})` }}
/>
<Flex
direction='column'
alignItems='center'
gap='l'
pt='3xl'
pb='l'
ph='s'
w='100%'
>
<Flex direction='column' alignItems='center' gap='s'>
<Flex direction='row' gap='xs' alignItems='center'>
<Text
variant='title'
size='s'
strength='default'
css={{
// TODO: Need to contain width
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}}
>
{name}
</Text>
{is_verified ? (
<IconVerified css={{ width: 12, height: 12 }} />
) : null}
</Flex>
<Flex direction='row' gap='s' alignItems='center'>
<Flex direction='row' gap='xs' alignItems='center'>
<IconNote width={16} height={16} color='subdued' />
<Text variant='body' size='s' strength='strong'>
{track_count}
</Text>
</Flex>
{/* TODO: Divider height not working */}
<Divider />
<Flex direction='row' gap='xs' alignItems='center'>
<IconUser width={16} height={16} color='subdued' />
<Text variant='body' size='s' strength='strong'>
{follower_count}
</Text>
</Flex>
</Flex>
</Flex>
{/* TODO: Use Harmony FollowButton */}
Comment on lines +56 to +84
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these TODOs to be addressed in this PR or in a future one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Future. Just wanted to get what I have merged so we can work off it and it's not all in one big PR at the end

<label key={user_id}>
<Flex alignItems='center' gap='xs'>
<input
type='checkbox'
name={String(user_id)}
onChange={onChange}
/>
<IconUserFollow color='subdued' />
Follow
</Flex>
</label>
</Flex>
</Flex>
</Paper>
)
}

export default FollowArtistTile
172 changes: 114 additions & 58 deletions packages/web/src/pages/sign-up-page/pages/SelectArtistsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ import {
useGetFeaturedArtists,
useGetTopArtistsInGenre
} from '@audius/common'
import { Button } from '@audius/harmony'
import {
Button,
Flex,
Text,
IconArrowRight,
SelectablePill,
Paper,
Box
} from '@audius/harmony'
import { Form, Formik } from 'formik'
import { useDispatch } from 'react-redux'

Expand All @@ -17,12 +25,16 @@ import { useNavigateToPage } from 'hooks/useNavigateToPage'
import { useSelector } from 'utils/reducer'
import { TRENDING_PAGE } from 'utils/route'

import { ContinueFooter } from '../components/ContinueFooter'
import FollowArtistTile from '../components/FollowArtistTile'

const messages = {
header: 'Follow At Least 3 Artists',
description:
'Curate your feed with tracks uploaded or reposted by anyone you follow. Click the artist’s photo to preview their music.',
genresLabel: 'Selected genres',
continue: 'Continue',
goBack: 'Go Back',
pickArtists: (genre: string) => `Pick ${genre} Artists`
}

Expand All @@ -41,9 +53,10 @@ export const SelectArtistsPage = () => {
const dispatch = useDispatch()
const navigate = useNavigateToPage()

const handleChangeGenre = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setCurrentGenre(e.target.value)
}, [])
// TODO: adopt SelectablePill as input
// const handleChangeGenre = useCallback((e: ChangeEvent<HTMLInputElement>) => {
// setCurrentGenre(e.target.value)
// }, [])

const handleSubmit = useCallback(
(values: SelectArtistsValues) => {
Expand Down Expand Up @@ -74,61 +87,104 @@ export const SelectArtistsPage = () => {
Status.LOADING

return (
<div>
<h1>{messages.header}</h1>
<p>{messages.description}</p>
<div role='radiogroup' aria-label={messages.genresLabel}>
{genres.map((genre) => (
<label key={genre}>
<input
type='radio'
value={genre}
checked={genre === currentGenre}
onChange={handleChangeGenre}
<Flex
direction='column'
gap='2xl'
css={{
overflow: 'scroll',
// Hide scrollbar
scrollbarWidth: 'none', // Firefox
msOverflowStyle: 'none', // IE + Edge
// Chrome + Safari
'::-webkit-scrollbar': {
display: 'none'
}
Comment on lines +96 to +101
Copy link
Contributor

Choose a reason for hiding this comment

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

i wish there was some emotion autoprefix magic for this

}}
>
<Flex direction='column' gap='2xl' mh='5xl' mb='xl'>
{/* TODO: Placeholder for AccountHeader */}
<Box />
<Flex direction='column' gap='l'>
<Text variant='heading' size='l' strength='default' color='heading'>
{messages.header}
</Text>
<Text variant='body' size='l' strength='default'>
{messages.description}
</Text>
</Flex>
<Flex
w='100%'
gap='s'
justifyContent='center'
role='radiogroup'
aria-label={messages.genresLabel}
>
{genres.map((genre) => (
// TODO: max of 6, kebab overflow
<SelectablePill
key={genre}
label={genre}
onClick={() => {
setCurrentGenre(genre)
}}
/>
{genre}
</label>
))}
</div>
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, setValues }) => {
const { artists: selectedArtists } = values
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { checked, name } = e.target
const userId = parseInt(name, 10)
const newArtists = checked
? [userId, ...selectedArtists]
: selectedArtists.filter((value) => value !== userId)

setValues({ artists: newArtists })
}
return (
<Form>
<fieldset>
<legend>{messages.pickArtists(currentGenre)}</legend>
{isLoading
? null
: artists?.map((user) => {
const { user_id, name } = user
))}
</Flex>
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{({ values, setValues }) => {
const { artists: selectedArtists } = values
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { checked, name } = e.target
const userId = parseInt(name, 10)
const newArtists = checked
? [userId, ...selectedArtists]
: selectedArtists.filter((value) => value !== userId)

return (
<label key={user_id}>
<input
type='checkbox'
name={String(user_id)}
onChange={handleChange}
checked={selectedArtists.includes(user_id)}
/>
{name}
</label>
)
})}
</fieldset>
<Button type='submit'>{messages.continue}</Button>
</Form>
)
}}
</Formik>
</div>
setValues({ artists: newArtists })
}
return (
<Form>
<fieldset>
<Paper
css={{
background: 'var(--harmony-bg-default)',
boxShadow: 'none'
}}
p='xl'
gap='m'
rowGap='m'
wrap='wrap'
>
{isLoading
? null
: artists?.map((user) => {
return (
<FollowArtistTile
key={user.user_id}
user={user}
onChange={handleChange}
/>
)
})}
</Paper>
</fieldset>
</Form>
)
}}
</Formik>
</Flex>
<ContinueFooter>
<Button
minWidth={343}
type='submit'
// disabled={!isValid || isSubmitting}
// isLoading={isSubmitting || isValidating}
iconRight={IconArrowRight}
>
{messages.continue}
</Button>
<Text variant='body'>Selected TODO/3</Text>
</ContinueFooter>
</Flex>
)
}