Add avatar uploader to profile screen
This commit is contained in:
parent
476db89eea
commit
8509368360
3 changed files with 69 additions and 4 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import { Edit } from '@mui/icons-material';
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
|
@ -10,6 +11,7 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
Container,
|
Container,
|
||||||
Button,
|
Button,
|
||||||
|
Fab,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
@ -19,10 +21,18 @@ import { COURSES } from '../../utils/constants';
|
||||||
import { createArrayFrom1ToN } from '../../utils/createArrayFrom1ToN';
|
import { createArrayFrom1ToN } from '../../utils/createArrayFrom1ToN';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
function View({ data, onChangeInput, layoutType }) {
|
function View({
|
||||||
|
data,
|
||||||
|
onChangeInput,
|
||||||
|
onChangeFile,
|
||||||
|
hiddenInputImageFileRef,
|
||||||
|
layoutType,
|
||||||
|
}) {
|
||||||
const {
|
const {
|
||||||
profileSummaryBox,
|
profileSummaryBox,
|
||||||
|
avatarStack,
|
||||||
avatar,
|
avatar,
|
||||||
|
avatarFab,
|
||||||
profileSummaryStack,
|
profileSummaryStack,
|
||||||
formBox,
|
formBox,
|
||||||
formField,
|
formField,
|
||||||
|
@ -36,7 +46,25 @@ function View({ data, onChangeInput, layoutType }) {
|
||||||
return (
|
return (
|
||||||
<Container disableGutters sx={{ display: 'flex', flexDirection: 'column' }}>
|
<Container disableGutters sx={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
<Box sx={profileSummaryBox}>
|
<Box sx={profileSummaryBox}>
|
||||||
<Avatar alt={fullName} src={data.avatar} sx={avatar} />
|
<Stack sx={avatarStack}>
|
||||||
|
<Avatar alt={fullName} src={data.avatar} sx={avatar} />
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
name="avatar"
|
||||||
|
ref={hiddenInputImageFileRef}
|
||||||
|
onChange={onChangeFile}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
/>
|
||||||
|
<Fab
|
||||||
|
onClick={() => hiddenInputImageFileRef.current.click()}
|
||||||
|
sx={avatarFab}
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
aria-label="add"
|
||||||
|
>
|
||||||
|
<Edit />
|
||||||
|
</Fab>
|
||||||
|
</Stack>
|
||||||
<Stack sx={profileSummaryStack}>
|
<Stack sx={profileSummaryStack}>
|
||||||
<Typography sx={fullNameTypography} variant="h4">
|
<Typography sx={fullNameTypography} variant="h4">
|
||||||
{fullName}
|
{fullName}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { useUser } from '../../context/user';
|
import { useUser } from '../../context/user';
|
||||||
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
|
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
|
||||||
import useLayoutType from '../../hooks/useLayoutType';
|
import useLayoutType from '../../hooks/useLayoutType';
|
||||||
|
@ -9,6 +9,14 @@ function Profile() {
|
||||||
const layoutType = useLayoutType();
|
const layoutType = useLayoutType();
|
||||||
const { state } = useUser();
|
const { state } = useUser();
|
||||||
const [data, setData] = useState(state && state.user);
|
const [data, setData] = useState(state && state.user);
|
||||||
|
const hiddenInputImageFileRef = useRef();
|
||||||
|
|
||||||
|
const onChangeFile = e => {
|
||||||
|
const name = e.target.name;
|
||||||
|
const file = e.target.files[0];
|
||||||
|
|
||||||
|
setData(prev => ({ ...prev, [name]: URL.createObjectURL(file) }));
|
||||||
|
};
|
||||||
|
|
||||||
const onChangeInput = e => {
|
const onChangeInput = e => {
|
||||||
const name = e.target.name;
|
const name = e.target.name;
|
||||||
|
@ -18,7 +26,13 @@ function Profile() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View data={data} onChangeInput={onChangeInput} layoutType={layoutType} />
|
<View
|
||||||
|
data={data}
|
||||||
|
onChangeInput={onChangeInput}
|
||||||
|
onChangeFile={onChangeFile}
|
||||||
|
hiddenInputImageFileRef={hiddenInputImageFileRef}
|
||||||
|
layoutType={layoutType}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,21 @@ const desktopProfileSummaryBox = {
|
||||||
marginTop: '70px',
|
marginTop: '70px',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const desktopAvatarStack = {
|
||||||
|
position: 'relative',
|
||||||
|
};
|
||||||
|
|
||||||
const desktopAvatar = {
|
const desktopAvatar = {
|
||||||
width: 200,
|
width: 200,
|
||||||
height: 200,
|
height: 200,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const desktopAvatarFab = {
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '10%',
|
||||||
|
right: 0,
|
||||||
|
};
|
||||||
|
|
||||||
const desktopProfileSummaryStack = {
|
const desktopProfileSummaryStack = {
|
||||||
marginLeft: '30px',
|
marginLeft: '30px',
|
||||||
};
|
};
|
||||||
|
@ -42,7 +52,9 @@ const desktopButton = {
|
||||||
|
|
||||||
const desktop = {
|
const desktop = {
|
||||||
profileSummaryBox: desktopProfileSummaryBox,
|
profileSummaryBox: desktopProfileSummaryBox,
|
||||||
|
avatarStack: desktopAvatarStack,
|
||||||
avatar: desktopAvatar,
|
avatar: desktopAvatar,
|
||||||
|
avatarFab: desktopAvatarFab,
|
||||||
profileSummaryStack: desktopProfileSummaryStack,
|
profileSummaryStack: desktopProfileSummaryStack,
|
||||||
formBox: desktopFormBox,
|
formBox: desktopFormBox,
|
||||||
formField: desktopFormField,
|
formField: desktopFormField,
|
||||||
|
@ -59,12 +71,20 @@ const mobileProfileSummaryBox = {
|
||||||
height: 'fit-content',
|
height: 'fit-content',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mobileAvatarStack = {
|
||||||
|
...desktopAvatarStack,
|
||||||
|
};
|
||||||
|
|
||||||
const mobileAvatar = {
|
const mobileAvatar = {
|
||||||
...desktopAvatar,
|
...desktopAvatar,
|
||||||
width: 170,
|
width: 170,
|
||||||
height: 170,
|
height: 170,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mobileAvatarFab = {
|
||||||
|
...desktopAvatarFab,
|
||||||
|
};
|
||||||
|
|
||||||
const mobileProfileSummaryStack = {};
|
const mobileProfileSummaryStack = {};
|
||||||
|
|
||||||
const mobileFormBox = {
|
const mobileFormBox = {
|
||||||
|
@ -96,7 +116,9 @@ const mobileButton = {
|
||||||
|
|
||||||
const mobile = {
|
const mobile = {
|
||||||
profileSummaryBox: mobileProfileSummaryBox,
|
profileSummaryBox: mobileProfileSummaryBox,
|
||||||
|
avatarStack: mobileAvatarStack,
|
||||||
avatar: mobileAvatar,
|
avatar: mobileAvatar,
|
||||||
|
avatarFab: mobileAvatarFab,
|
||||||
profileSummaryStack: mobileProfileSummaryStack,
|
profileSummaryStack: mobileProfileSummaryStack,
|
||||||
formBox: mobileFormBox,
|
formBox: mobileFormBox,
|
||||||
formField: mobileFormField,
|
formField: mobileFormField,
|
||||||
|
@ -108,6 +130,7 @@ const mobile = {
|
||||||
// ========== Unset ==========
|
// ========== Unset ==========
|
||||||
const unset = {
|
const unset = {
|
||||||
profileSummaryBox: null,
|
profileSummaryBox: null,
|
||||||
|
avatarStack: null,
|
||||||
avatar: null,
|
avatar: null,
|
||||||
profileSummaryStack: null,
|
profileSummaryStack: null,
|
||||||
formBox: null,
|
formBox: null,
|
||||||
|
|
Loading…
Reference in a new issue