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

feat: discord username field introduced #429

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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 src/hooks/useUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const useUser = (id: string | undefined): UserReadSerializer | null => {
if (userId === self.id) {
return {
avatar: self.avatar,
discord_username: self.discord_username,
id: self.id!,
is_manual_contribution_allowed: self.is_manual_contribution_allowed,
username: self.username!,
Expand Down
14 changes: 14 additions & 0 deletions src/modals/ProfileEditModal/Styles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import styled from 'styled-components';

import UModal from 'components/Modal';
import {InlineInput as UInlineInput} from 'components/FormElements';

export const Bumper = styled.div`
margin-bottom: 24px;
`;

export const FormField = styled.div`
margin: 20px 0;
`;

export const FormLabel = styled.div`
font-size: 12px;
margin-bottom: 5px;
`;

export const FormTextInput = styled(UInlineInput)`
width: 100%;
`;

export const Modal = styled(UModal)`
width: 360px;
`;
58 changes: 39 additions & 19 deletions src/modals/ProfileEditModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React, {ChangeEvent, useEffect, useMemo, useState} from 'react';
import {ChangeEvent, useEffect, useMemo, useState} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {Field, Form, Formik} from 'formik';

import Button, {ButtonType} from 'components/Button';
import {FileInput} from 'components/FormElements';
import ImagePreview from 'components/ImagePreview';
import {updateUser} from 'dispatchers/users';
import {getSelf} from 'selectors/state';
import {AppDispatch, SFC} from 'types';
import {displayErrorToast} from 'utils/toasts';
import {FileInput} from 'components/FormElements';
import {ToastType} from 'enums';
import {displayErrorToast, displayToast} from 'utils/toasts';
import {getSelf} from 'selectors/state';
import {updateUser} from 'dispatchers/users';

import * as S from './Styles';

export interface ProfileEditModalProps {
Expand All @@ -17,14 +19,16 @@ export interface ProfileEditModalProps {

const ProfileEditModal: SFC<ProfileEditModalProps> = ({className, close}) => {
const [preview, setPreview] = useState<string | null>(null);
const [isAvatarCleared, setIsAvatarCleared] = useState<boolean | null>(null);
const dispatch = useDispatch<AppDispatch>();
const self = useSelector(getSelf);

const initialValues = useMemo(
() => ({
avatar: self.avatar || '',
discord_username: self.discord_username || '',
}),
[self.avatar],
[self.avatar, self.discord_username],
);

type FormValues = typeof initialValues;
Expand All @@ -47,30 +51,46 @@ const ProfileEditModal: SFC<ProfileEditModalProps> = ({className, close}) => {
const handleSubmit = async (values: FormValues): Promise<void> => {
try {
const requestData = new FormData();
requestData.append('avatar', values.avatar);
if (initialValues.avatar !== values.avatar) requestData.append('avatar', values.avatar);
requestData.append('is_avatar_cleared', isAvatarCleared ? 'True' : 'False');
requestData.append('discord_username', values.discord_username);
await dispatch(updateUser(self.id!, requestData));
close();
displayToast('Profile successfully updated', ToastType.SUCCESS);
} catch (error) {
console.error(error);
displayErrorToast('Error updating avatar');
displayErrorToast('Error updating your profile');
}
};

return (
<S.Modal className={className} close={close} header="Edit Profile">
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
{({dirty, isSubmitting, isValid, setFieldValue, touched, values}) => (
{({dirty, errors, isSubmitting, isValid, setFieldValue, touched, values}) => (
<Form>
{!values.avatar && (
<Field component={FileInput} name="avatar" onChange={handleFileChange} touched={touched} />
)}
<ImagePreview
onClear={async () => {
await setFieldValue('avatar', '');
setPreview(null);
}}
src={preview}
/>
<S.FormField>
<S.FormLabel>Profile Picture</S.FormLabel>
{!values.avatar && (
<Field component={FileInput} name="avatar" onChange={handleFileChange} touched={touched} />
)}
<ImagePreview
onClear={async () => {
await setFieldValue('avatar', '');
setPreview(null);
setIsAvatarCleared(true);
}}
src={preview}
/>
</S.FormField>
<S.FormField>
<S.FormLabel>Link your TNB Account to Discord</S.FormLabel>
<S.FormTextInput
errors={errors}
touched={touched}
name="discord_username"
placeholder="Discord Username"
/>
</S.FormField>
<S.Bumper />
<Button
dirty={dirty}
Expand Down
1 change: 1 addition & 0 deletions src/store/self.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Self} from 'types';

const initialState: Self = {
avatar: null,
discord_username: null,
id: null,
is_manual_contribution_allowed: false,
username: null,
Expand Down
1 change: 1 addition & 0 deletions src/types/api/users.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface UserReadSerializer {
avatar: string | null;
discord_username: string | null;
id: number;
is_manual_contribution_allowed: boolean;
username: string;
Expand Down
1 change: 1 addition & 0 deletions src/types/self.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface Self {
avatar: string | null;
discord_username: string | null;
id: number | null;
is_manual_contribution_allowed: boolean;
username: string | null;
Expand Down