diff --git a/packages/common/src/messages/sign-on/pages.ts b/packages/common/src/messages/sign-on/pages.ts index a55dd4a1383..1db7cfba326 100644 --- a/packages/common/src/messages/sign-on/pages.ts +++ b/packages/common/src/messages/sign-on/pages.ts @@ -69,7 +69,11 @@ export const finishProfilePageMessages = { displayName: 'Display Name', inputPlaceholder: 'express yourself 💫', uploadProfilePhoto: 'Upload a profile photo to continue', - goBack: 'Go back' + goBack: 'Go back', + profileImageUploadError: 'There was an issue uploading your profile image.', + coverPhotoUploadError: 'There was an issue uploading your cover photo image.', + bothImageUploadError: + 'There was an issue uploading your profile and cover photo image.' } export const selectGenresPageMessages = { diff --git a/packages/web/src/pages/sign-up-page/components/AccountHeader.tsx b/packages/web/src/pages/sign-up-page/components/AccountHeader.tsx index 56754d5a477..9f24b14c487 100644 --- a/packages/web/src/pages/sign-up-page/components/AccountHeader.tsx +++ b/packages/web/src/pages/sign-up-page/components/AccountHeader.tsx @@ -50,6 +50,7 @@ const ProfileImageAvatar = ({ display: 'flex', alignItems: 'center', justifyContent: 'center', + cursor: 'pointer', ...(isSmallSize ? { transform: 'translateY(20px)' } : null) }} > diff --git a/packages/web/src/pages/sign-up-page/components/CoverPhotoBanner.tsx b/packages/web/src/pages/sign-up-page/components/CoverPhotoBanner.tsx index 6205b7a05f4..186bea12da4 100644 --- a/packages/web/src/pages/sign-up-page/components/CoverPhotoBanner.tsx +++ b/packages/web/src/pages/sign-up-page/components/CoverPhotoBanner.tsx @@ -35,6 +35,8 @@ export const CoverPhotoBanner = (props: CoverPhotoBannerProps) => { w='100%' borderRadius={isEditing ? 'm' : undefined} css={{ + borderBottomLeftRadius: 0, + borderBottomRightRadius: 0, '&:before': { content: '""', position: 'absolute', @@ -53,6 +55,7 @@ export const CoverPhotoBanner = (props: CoverPhotoBannerProps) => { : undefined), ...(isEditing && { overflow: 'hidden', + cursor: 'pointer', borderTopLeftRadius: cornerRadius.m, borderTopRightRadius: cornerRadius.m }) diff --git a/packages/web/src/pages/sign-up-page/components/ImageField.tsx b/packages/web/src/pages/sign-up-page/components/ImageField.tsx index 748ef9a1897..67173f1b1fa 100644 --- a/packages/web/src/pages/sign-up-page/components/ImageField.tsx +++ b/packages/web/src/pages/sign-up-page/components/ImageField.tsx @@ -1,6 +1,6 @@ import { ReactNode, useCallback } from 'react' -import { Nullable } from '@audius/common' +import { Nullable, finishProfilePageMessages as messages } from '@audius/common' import cn from 'classnames' import { useField } from 'formik' import ReactDropzone, { DropFilesEventHandler } from 'react-dropzone' @@ -31,25 +31,29 @@ type ImageFieldProps = { export const ImageField = (props: ImageFieldProps) => { const { name, className, children, onChange, imageResizeOptions } = props - const [field, , { setValue }] = useField(name) + const [field, , { setValue, setError }] = useField(name) const { value } = field const handleChange: DropFilesEventHandler = useCallback( async (files) => { - const [file] = files - const resizedFile = await resizeImage( - file, - imageResizeOptions?.maxWidth, - imageResizeOptions?.square - ) - const url = URL.createObjectURL(resizedFile) - const image = { file: resizedFile, url } - setValue(image) - if (onChange) { - onChange(image) + try { + const [file] = files + const resizedFile = await resizeImage( + file, + imageResizeOptions?.maxWidth, + imageResizeOptions?.square + ) + const url = URL.createObjectURL(resizedFile) + const image = { file: resizedFile, url } + setValue(image) + if (onChange) { + onChange(image) + } + } catch (e) { + setError(messages[`${name}UploadError` as keyof typeof messages]) } }, - [setValue, onChange, imageResizeOptions] + [setValue, onChange, setError, name, imageResizeOptions] ) return ( diff --git a/packages/web/src/pages/sign-up-page/pages/FinishProfilePage.tsx b/packages/web/src/pages/sign-up-page/pages/FinishProfilePage.tsx index 496afcd0d12..7aa374ed55e 100644 --- a/packages/web/src/pages/sign-up-page/pages/FinishProfilePage.tsx +++ b/packages/web/src/pages/sign-up-page/pages/FinishProfilePage.tsx @@ -5,13 +5,14 @@ import { finishProfilePageMessages as messages } from '@audius/common' import { + Flex, Paper, PlainButton, PlainButtonType, Text, useTheme } from '@audius/harmony' -import { Formik, Form, useField } from 'formik' +import { Formik, Form, useField, useFormikContext } from 'formik' import { useDispatch, useSelector } from 'react-redux' import { useHistory } from 'react-router-dom' import { toFormikValidationSchema } from 'zod-formik-adapter' @@ -46,6 +47,33 @@ export type FinishProfileValues = { const formSchema = toFormikValidationSchema(finishProfileSchema) +const ImageUploadErrorText = () => { + const { errors } = useFormikContext() + let errorText + if (errors.coverPhoto === messages.coverPhotoUploadError) { + errorText = errors.coverPhoto + } + // Profile image error takes priority + if (errors.profileImage === messages.profileImageUploadError) { + // If both images have errors, we show a combined error message + if (errorText !== undefined) { + errorText = messages.bothImageUploadError + } else { + errorText = errors.profileImage + } + } + + return ( + + {errorText ? ( + + {errorText} + + ) : null} + + ) +} + export const FinishProfilePage = () => { const { isMobile } = useMedia() const history = useHistory() @@ -111,6 +139,7 @@ export const FinishProfilePage = () => { formDisplayName={values.displayName} formProfileImage={values.profileImage} /> + { required maxLength={32} css={(theme) => ({ - padding: theme.spacing.l, - paddingTop: theme.spacing.unit10 + padding: theme.spacing.l })} />