Fix Profile picture uploader (#1471)
This commit is contained in:
@ -12,12 +12,13 @@ import {
|
|||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export function ProfilePictureUploader() {
|
export function ProfilePictureUploader() {
|
||||||
const [uploadPicture] = useUploadProfilePictureMutation();
|
const [uploadPicture, { loading: isUploading }] =
|
||||||
|
useUploadProfilePictureMutation();
|
||||||
const [removePicture] = useRemoveProfilePictureMutation();
|
const [removePicture] = useRemoveProfilePictureMutation();
|
||||||
const [currentUser] = useRecoilState(currentUserState);
|
const [currentUser] = useRecoilState(currentUserState);
|
||||||
const [uploadController, setUploadController] =
|
const [uploadController, setUploadController] =
|
||||||
useState<AbortController | null>(null);
|
useState<AbortController | null>(null);
|
||||||
const [error, setError] = useState<Error | null>(null);
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
|
|
||||||
async function handleUpload(file: File) {
|
async function handleUpload(file: File) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -41,10 +42,10 @@ export function ProfilePictureUploader() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setUploadController(null);
|
setUploadController(null);
|
||||||
setError(null);
|
setErrorMessage(null);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError(error as Error);
|
setErrorMessage('An error occured while uploading the picture.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +73,8 @@ export function ProfilePictureUploader() {
|
|||||||
onUpload={handleUpload}
|
onUpload={handleUpload}
|
||||||
onRemove={handleRemove}
|
onRemove={handleRemove}
|
||||||
onAbort={handleAbort}
|
onAbort={handleAbort}
|
||||||
error={error}
|
isUploading={isUploading}
|
||||||
|
errorMessage={errorMessage}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { Button } from '@/ui/button/components/Button';
|
import { Button } from '@/ui/button/components/Button';
|
||||||
import { IconFileUpload, IconTrash, IconUpload } from '@/ui/icon';
|
import { IconFileUpload, IconTrash, IconUpload, IconX } from '@/ui/icon';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -67,6 +67,12 @@ const StyledText = styled.span`
|
|||||||
font-size: ${({ theme }) => theme.font.size.xs};
|
font-size: ${({ theme }) => theme.font.size.xs};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledErrorText = styled.span`
|
||||||
|
color: ${({ theme }) => theme.font.color.danger};
|
||||||
|
font-size: ${({ theme }) => theme.font.size.xs};
|
||||||
|
margin-top: ${({ theme }) => theme.spacing(1)};
|
||||||
|
`;
|
||||||
|
|
||||||
const StyledHiddenFileInput = styled.input`
|
const StyledHiddenFileInput = styled.input`
|
||||||
display: none;
|
display: none;
|
||||||
`;
|
`;
|
||||||
@ -76,7 +82,8 @@ type Props = Omit<React.ComponentProps<'div'>, 'children'> & {
|
|||||||
onUpload?: (file: File) => void;
|
onUpload?: (file: File) => void;
|
||||||
onRemove?: () => void;
|
onRemove?: () => void;
|
||||||
onAbort?: () => void;
|
onAbort?: () => void;
|
||||||
error?: Error | null;
|
isUploading?: boolean;
|
||||||
|
errorMessage?: string | null;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,7 +92,8 @@ export function ImageInput({
|
|||||||
onUpload,
|
onUpload,
|
||||||
onRemove,
|
onRemove,
|
||||||
onAbort,
|
onAbort,
|
||||||
error,
|
isUploading = false,
|
||||||
|
errorMessage,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
...restProps
|
...restProps
|
||||||
}: Props) {
|
}: Props) {
|
||||||
@ -125,37 +133,38 @@ export function ImageInput({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
{isUploading && onAbort ? (
|
||||||
icon={<IconUpload size={theme.icon.size.sm} />}
|
|
||||||
onClick={onUploadButtonClick}
|
|
||||||
variant="secondary"
|
|
||||||
title="Upload"
|
|
||||||
disabled={disabled}
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
icon={<IconTrash size={theme.icon.size.sm} />}
|
|
||||||
onClick={onRemove}
|
|
||||||
variant="secondary"
|
|
||||||
title="Remove"
|
|
||||||
disabled={!picture || disabled}
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
{onAbort && (
|
|
||||||
<Button
|
<Button
|
||||||
icon={<IconTrash size={theme.icon.size.sm} />}
|
icon={<IconX />}
|
||||||
onClick={onAbort}
|
onClick={onAbort}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Abort"
|
title="Abort"
|
||||||
disabled={!picture || disabled}
|
disabled={!picture || disabled}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
icon={<IconUpload />}
|
||||||
|
onClick={onUploadButtonClick}
|
||||||
|
variant="secondary"
|
||||||
|
title="Upload"
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
<Button
|
||||||
|
icon={<IconTrash />}
|
||||||
|
onClick={onRemove}
|
||||||
|
variant="secondary"
|
||||||
|
title="Remove"
|
||||||
|
disabled={!picture || disabled}
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
<StyledText>
|
<StyledText>
|
||||||
We support your best PNGs, JPEGs and GIFs portraits under 10MB
|
We support your best PNGs, JPEGs and GIFs portraits under 10MB
|
||||||
</StyledText>
|
</StyledText>
|
||||||
{error && <StyledText>{error.message}</StyledText>}
|
{errorMessage && <StyledErrorText>{errorMessage}</StyledErrorText>}
|
||||||
</StyledContent>
|
</StyledContent>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user