Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { Component, ChangeEvent, KeyboardEvent, CSSProperties } from 'react';
- import { WithStyles, CircularProgress, Snackbar } from '@material-ui/core';
- import classNames from 'classnames';
- import Button from '@material-ui/core/Button';
- import Paper from '@material-ui/core/Paper';
- import TextField from '@material-ui/core/TextField';
- import Scrollbars from 'react-custom-scrollbars';
- import { Theme, withStyles } from '@material-ui/core/styles';
- import { BigAvatar } from 'src/Component/Avatar';
- import { Query, MutationFn, Mutation } from 'react-apollo';
- import { GET_ME } from 'src/Graphql/User/query';
- import UserInterface from 'src/Interface/UserInterface';
- import { EDIT_ACCOUNT, CREATE_PRESIGNED_URL } from 'src/Graphql/Authentication/mutation';
- import { DataProxy } from 'apollo-cache';
- import axios from 'axios';
- import mime from 'mime-types';
- import uuid from 'uuid/v4';
- import { ReturnLink } from '../All/ReturnLink';
- import { REMOVE_USER } from 'src/Graphql/User/mutations';
- const styles = (theme: Theme): Record<string, CSSProperties | Record<string, CSSProperties>> => ({
- col: {
- boxSizing: 'border-box' as 'border-box',
- display: 'flex',
- flex: '0 1 auto',
- flexDirection: 'column' as 'column',
- msFlex: '0 1 auto',
- WebkitFlex: '0 1 auto',
- },
- row: {
- boxSizing: 'border-box' as 'border-box',
- display: 'flex',
- flex: '0 1 auto',
- flexDirection: 'row' as 'row',
- msFlex: '0 1 auto',
- WebkitFlex: '0 1 auto',
- },
- justifyEnd: {
- justifyContent: 'flex-end',
- padding: '0 44px 44px',
- },
- submitButtonWrapper: {
- marginTop: 0,
- },
- justifyCenter: {
- justifyContent: 'center',
- },
- contentEditAccount: {
- marginTop: 28,
- },
- paper: {
- '@media (max-width: 600px)': {
- width: '100%',
- },
- width: 454,
- margin: '0 auto',
- boxShadow:
- ' 0px 0px 1px 0px rgba(0,0,0,0.2), 0px 0px 0px 0px rgba(0,0,0,.1), 0px 0px 0px 0px rgba(0,0,0,0.12)',
- borderRadius: 0,
- paddingBottom: 20,
- },
- inputAvatar: {
- display: 'none',
- },
- wrapper: {
- position: 'relative' as 'relative',
- marginTop: 20,
- },
- buttonProgress: {
- color: theme.customPalette.primary.main,
- position: 'absolute' as 'absolute',
- top: '50%',
- left: '50%',
- marginTop: -8,
- marginLeft: -12,
- },
- contentForm: {
- margin: '14px 0 24px',
- padding: '0 44px',
- '@media (max-width: 600px)': {
- padding: '0 24px',
- },
- },
- textField: {
- width: '100%',
- margin: '20px 0 8px',
- fontWeight: 500,
- fontSize: 60,
- },
- actionButton: {
- color: 'white',
- },
- button: {
- margin: '0px 4px',
- padding: '14px 53px',
- textTransform: 'capitalize' as 'capitalize',
- fontWeight: 400,
- fontSize: 11,
- },
- input: {
- fontSize: 60,
- },
- title: {
- fontSize: 24,
- marginTop: 28,
- fontWeight: 400,
- },
- buttonSupressEmail: {
- backgroundColor: 'red',
- },
- });
- interface EditAccountProps {
- classes: any;
- }
- interface EditAccountStates {
- position?: string;
- isLoading: boolean;
- snackBarMessage?: string;
- username?: string;
- avatar?: string;
- avatarFile?: File;
- avatarName?: string;
- }
- class EditAccount extends Component<EditAccountProps & WithStyles<any>, EditAccountStates> {
- inputFile: any;
- oldUser?: UserInterface;
- constructor(props: any) {
- super(props);
- this.state = {
- isLoading: false,
- };
- }
- handleCloseSnackbar = () => {
- this.setState({ snackBarMessage: undefined });
- };
- preventDefaultKeyPress = (evt: KeyboardEvent<any>) => {
- evt.preventDefault();
- };
- handleChangeInput = (evt: ChangeEvent<HTMLInputElement>) => {
- this.setState({ ...this.state, [evt.target.id]: evt.target.value });
- };
- showSnackMessage = (snackBarMessage: string) => {
- this.setState({ snackBarMessage });
- };
- trigClickInInputFile = () => {
- this.inputFile.click();
- };
- handleDeleteAccount = async (
- mutationDeleteAccount: MutationFn<any, any>
- ) => {
- if (confirm('Do you really want to delete your account?')) {
- if (!this.oldUser) {
- return;
- }
- this.setState({ isLoading: true });
- mutationDeleteAccount({
- variables: {
- id: this.oldUser.id,
- },
- })
- .then(() => {
- this.showSnackMessage('Successfully modified');
- })
- .catch(err => {
- this.showSnackMessage('An error occurred');
- })
- .finally(() => {
- this.setState({ isLoading: false });
- });
- }
- }
- handleAvatarChange = (e: ChangeEvent<HTMLInputElement>) => {
- e.stopPropagation();
- const files = e.target.files;
- if (files && files[0]) {
- const reader = new FileReader();
- reader.onload = () => {
- const avatarFile = files[0];
- this.setState({
- avatar: reader.result as string,
- avatarFile,
- avatarName: `${uuid().replace(/-/g, '')}.${mime.extension(avatarFile.type)}`,
- });
- };
- reader.readAsDataURL(files[0]);
- }
- };
- handleSubmit = async (
- mutationEditAccount: MutationFn<any, any>,
- mutationCreatePresignedUrl: MutationFn<any, any>,
- ) => {
- if (!this.oldUser) {
- return;
- }
- const { position, username, avatarFile, avatarName } = this.state;
- if (
- (position !== undefined && !position.trim()) ||
- (username !== undefined && !username.trim())
- ) {
- return;
- }
- this.setState({ isLoading: true });
- let signedUrl = null;
- if (avatarName) {
- await mutationCreatePresignedUrl({ variables: { filePath: avatarName } })
- .then((rep: any) => (signedUrl = rep.data.createPresignedPutUrl))
- .catch(() => this.showSnackMessage('An error occurred'));
- }
- if (signedUrl && avatarFile) {
- const file = avatarFile;
- await axios
- .put(signedUrl, avatarFile, {
- headers: { 'Content-Type': file.type },
- })
- .catch(() => this.showSnackMessage('An error occurred'));
- }
- const avatar = avatarName || null;
- mutationEditAccount({
- variables: {
- username: username || this.oldUser.username,
- avatar,
- email: this.oldUser.email,
- position: position || this.oldUser.position,
- },
- })
- .then(() => {
- this.showSnackMessage('Successfully modified');
- })
- .catch(err => {
- this.showSnackMessage('An error occurred');
- })
- .finally(() => {
- this.setState({ isLoading: false });
- });
- };
- updateCache = (cache: DataProxy, editAccountResult: any) => {
- const data = cache.readQuery<{ me: UserInterface }>({ query: GET_ME });
- if (data) {
- const newUser: UserInterface = editAccountResult.data.editAccount;
- data.me = { ...data.me, ...newUser };
- cache.writeQuery({
- query: GET_ME,
- data,
- });
- }
- };
- handleKeyPress = (
- mutationEditAccount: MutationFn<any, any>,
- mutationCreatePresignedUrl: MutationFn<any, any>,
- evt: KeyboardEvent<HTMLFormElement>,
- ) => {
- if (evt.key === 'Enter') {
- this.handleSubmit(mutationEditAccount, mutationCreatePresignedUrl);
- }
- };
- render() {
- const { classes } = this.props;
- const { isLoading, snackBarMessage, position, username, avatar } = this.state;
- return (
- <Query query={GET_ME}>
- {({ data, loading, error }) => {
- if (loading) {
- return 'Loading...';
- }
- if (error) {
- return 'Error';
- }
- this.oldUser = data.me;
- return (
- <Mutation mutation={CREATE_PRESIGNED_URL}>
- {mutationCreatePresignedUrl => (
- <Mutation mutation={EDIT_ACCOUNT} update={this.updateCache}>
- {mutationEditAccount => (
- <Scrollbars
- style={{ height: '100vh' }}
- autoHide={true}
- autoHideTimeout={500}
- autoHideDuration={50}
- >
- <Snackbar
- open={!!snackBarMessage}
- message={snackBarMessage}
- onClose={this.handleCloseSnackbar}
- autoHideDuration={5000}
- />
- <div className={classes.contentEditAccount}>
- <ReturnLink />
- <Paper className={classes.paper} elevation={1}>
- <div
- className={classNames(
- classes.row,
- classes.submitButtonWrapper,
- classes.justifyCenter,
- )}
- >
- <div className={classes.wrapper}>
- <Button
- className={classNames(classes.actionButton, classes.button)}
- variant="contained"
- color="primary"
- id="btn-save"
- onClick={this.handleSubmit.bind(
- this,
- mutationEditAccount,
- mutationCreatePresignedUrl,
- )}
- disabled={isLoading}
- >
- Save
- </Button>
- {isLoading && (
- <CircularProgress size={21} className={classes.buttonProgress} />
- )}
- </div>
- </div>
- <div
- className={classNames(
- classes.row,
- classes.avatarInput,
- classes.justifyCenter,
- )}
- >
- <input
- accept="image/*"
- className={classes.inputAvatar}
- id="icon-button-avatar"
- type="file"
- ref={ref => {
- this.inputFile = ref;
- }}
- onChange={this.handleAvatarChange}
- />
- <label htmlFor="icon-button-file">
- <BigAvatar
- onClick={this.trigClickInInputFile}
- disabled={isLoading}
- alt={this.oldUser!.username || undefined}
- src={avatar || this.oldUser!.avatar}
- />
- </label>
- </div>
- <form
- className={classes.contentForm}
- onKeyPress={this.handleKeyPress.bind(
- this,
- mutationEditAccount,
- mutationCreatePresignedUrl,
- )}
- >
- <TextField
- autoFocus={true}
- className={classNames(classes.textField, 'Edit-account-input')}
- margin="dense"
- id="username"
- label="Username"
- value={
- username !== undefined ? username : this.oldUser!.username || ''
- }
- onChange={this.handleChangeInput}
- error={username !== undefined && !username.trim()}
- fullWidth={true}
- autoComplete="off"
- />
- <TextField
- className={classNames(classes.textField, 'Edit-account-input')}
- margin="dense"
- id="position"
- color="primary"
- label="Function"
- onChange={this.handleChangeInput}
- value={
- (position !== undefined ? position : this.oldUser!.position) || ''
- }
- error={position !== undefined && !position.trim()}
- fullWidth={true}
- autoComplete="off"
- />
- <TextField
- className={classNames(classes.textField, 'Edit-account-input')}
- margin="dense"
- id="email"
- color="primary"
- label="Email"
- type="email"
- value={this.oldUser!.email || ''}
- fullWidth={true}
- autoComplete="off"
- disabled={true}
- />
- <div style={{ flex: 1 }} />
- <Mutation mutation={REMOVE_USER} >
- {mutationDeleteAccount => (
- <Button
- className={classNames(classes.actionButton)}
- variant="flat"
- size="small"
- onClick={this.handleDeleteAccount.bind(
- this,
- mutationDeleteAccount,
- )}
- style={{ backgroundColor: 'red' }}
- id="btn-save"
- disabled={isLoading}
- >
- Delete Account
- </Button>
- )}
- </Mutation>
- </form>
- </Paper>
- </div>
- </Scrollbars>
- )}
- </Mutation>
- )}
- </Mutation>
- );
- }}
- </Query>
- );
- }
- }
- export default withStyles(styles as any)(EditAccount);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement