Compare commits
No commits in common. "45778d83d04d0403f8a918ae8a1c1d6db9d24c33" and "478f2429f5146c68092a3bae7f5589cab49c299b" have entirely different histories.
45778d83d0
...
478f2429f5
9
exam/dist/assets/index-BFREkcQ0.js
vendored
9
exam/dist/assets/index-BFREkcQ0.js
vendored
File diff suppressed because one or more lines are too long
9
exam/dist/assets/index-DBCDWqoJ.js
vendored
Normal file
9
exam/dist/assets/index-DBCDWqoJ.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
exam/dist/index.html
vendored
2
exam/dist/index.html
vendored
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>GuestBook</title>
|
<title>GuestBook</title>
|
||||||
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-BFREkcQ0.js"></script>
|
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-DBCDWqoJ.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/react-C9_qfvjK.js">
|
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/react-C9_qfvjK.js">
|
||||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/mui-BnAUJOoN.js">
|
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/mui-BnAUJOoN.js">
|
||||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/tanstack-BqkrhB-y.js">
|
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/tanstack-BqkrhB-y.js">
|
||||||
|
|||||||
6
exam/dist/locales/de/translation.json
vendored
6
exam/dist/locales/de/translation.json
vendored
@ -97,9 +97,5 @@
|
|||||||
"Session expired": "Deine Sitzung ist abgelaufen.",
|
"Session expired": "Deine Sitzung ist abgelaufen.",
|
||||||
"General error": "Da ist wohl was schief gelaufen.",
|
"General error": "Da ist wohl was schief gelaufen.",
|
||||||
|
|
||||||
"Favicon": "Gästebuch Icons erstellt von Smashicons - Flaticon",
|
"Favicon": "Gästebuch Icons erstellt von Smashicons - Flaticon"
|
||||||
|
|
||||||
"Password confirm": "Passwort bestätigen",
|
|
||||||
"Password match": "Passwörter stimmen nicht überein",
|
|
||||||
"Change password": "Passwort ändern"
|
|
||||||
}
|
}
|
||||||
|
|||||||
6
exam/dist/locales/en/translation.json
vendored
6
exam/dist/locales/en/translation.json
vendored
@ -98,9 +98,5 @@
|
|||||||
"Session expired": "Your session has expired.",
|
"Session expired": "Your session has expired.",
|
||||||
"General error": "Looks like something went wrong.",
|
"General error": "Looks like something went wrong.",
|
||||||
|
|
||||||
"Favicon": "Guests book icons created by Smashicons - Flaticon",
|
"Favicon": "Guests book icons created by Smashicons - Flaticon"
|
||||||
|
|
||||||
"Password confirm": "Confirm password",
|
|
||||||
"Password match": "Password do not match",
|
|
||||||
"Change password": "Change password"
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
exam/dist/stats.html
vendored
2
exam/dist/stats.html
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "react",
|
"name": "react",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.1.0",
|
"version": "1.0.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -97,9 +97,5 @@
|
|||||||
"Session expired": "Deine Sitzung ist abgelaufen.",
|
"Session expired": "Deine Sitzung ist abgelaufen.",
|
||||||
"General error": "Da ist wohl was schief gelaufen.",
|
"General error": "Da ist wohl was schief gelaufen.",
|
||||||
|
|
||||||
"Favicon": "Gästebuch Icons erstellt von Smashicons - Flaticon",
|
"Favicon": "Gästebuch Icons erstellt von Smashicons - Flaticon"
|
||||||
|
|
||||||
"Password confirm": "Passwort bestätigen",
|
|
||||||
"Password match": "Passwörter stimmen nicht überein",
|
|
||||||
"Change password": "Passwort ändern"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,9 +98,5 @@
|
|||||||
"Session expired": "Your session has expired.",
|
"Session expired": "Your session has expired.",
|
||||||
"General error": "Looks like something went wrong.",
|
"General error": "Looks like something went wrong.",
|
||||||
|
|
||||||
"Favicon": "Guests book icons created by Smashicons - Flaticon",
|
"Favicon": "Guests book icons created by Smashicons - Flaticon"
|
||||||
|
|
||||||
"Password confirm": "Confirm password",
|
|
||||||
"Password match": "Password do not match",
|
|
||||||
"Change password": "Change password"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,23 +40,16 @@ const RegisterDialog: FC<Props> = ({ open, onClose }) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm<UserCreate & { passwordConfirm: string }>({
|
const form = useForm<UserCreate>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
username: '',
|
username: '',
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
passwordConfirm: '',
|
|
||||||
},
|
},
|
||||||
onSubmit: async ({ value }) => {
|
onSubmit: async ({ value }) => {
|
||||||
try {
|
try {
|
||||||
createMutation.mutate(
|
createMutation.mutate(
|
||||||
{
|
{ data: value },
|
||||||
data: {
|
|
||||||
username: value.username,
|
|
||||||
email: value.email,
|
|
||||||
password: value.password,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
onSuccess: () => setError(undefined),
|
onSuccess: () => setError(undefined),
|
||||||
onError: setError,
|
onError: setError,
|
||||||
@ -120,7 +113,7 @@ const RegisterDialog: FC<Props> = ({ open, onClose }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle>{t('Register')}</DialogTitle>
|
<DialogTitle>{t('Register')}</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent sx={{ gap: 2 }}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<form.Field
|
<form.Field
|
||||||
@ -222,48 +215,6 @@ const RegisterDialog: FC<Props> = ({ open, onClose }) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
|
||||||
<form.Field
|
|
||||||
name="passwordConfirm"
|
|
||||||
validators={{
|
|
||||||
onChangeListenTo: ['password'],
|
|
||||||
onChange: ({ value, fieldApi }) =>
|
|
||||||
!value
|
|
||||||
? t('Password required')
|
|
||||||
: value !== fieldApi.form.getFieldValue('password')
|
|
||||||
? t('Password match')
|
|
||||||
: undefined,
|
|
||||||
onChangeAsyncDebounceMs: 250,
|
|
||||||
onChangeAsync: async ({ value, fieldApi }) =>
|
|
||||||
!value
|
|
||||||
? t('Password required')
|
|
||||||
: value !== fieldApi.form.getFieldValue('password')
|
|
||||||
? t('Password match')
|
|
||||||
: undefined,
|
|
||||||
}}
|
|
||||||
children={(field) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TextField
|
|
||||||
variant="outlined"
|
|
||||||
name={field.name}
|
|
||||||
value={field.state.value}
|
|
||||||
onBlur={field.handleBlur}
|
|
||||||
onChange={(e) => field.handleChange(e.target.value)}
|
|
||||||
size="small"
|
|
||||||
label={t('Password confirm')}
|
|
||||||
required
|
|
||||||
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
|
||||||
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
|
||||||
type="password"
|
|
||||||
autoComplete="new-password"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<form.Subscribe
|
<form.Subscribe
|
||||||
selector={(state) => [state.canSubmit, state.isSubmitting]}
|
selector={(state) => [state.canSubmit, state.isSubmitting]}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid,
|
|
||||||
TextField,
|
TextField,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useTheme,
|
useTheme,
|
||||||
@ -99,72 +98,66 @@ const UserEditDialog: FC<Props> = ({ user, open, onClose }) => {
|
|||||||
>
|
>
|
||||||
<DialogTitle>{t('Edit data')}</DialogTitle>
|
<DialogTitle>{t('Edit data')}</DialogTitle>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Grid container spacing={2}>
|
<form.Field
|
||||||
<Grid item xs={12}>
|
name="username"
|
||||||
<form.Field
|
validators={{
|
||||||
name="username"
|
onChange: ({ value }) => (!value ? t('Username required') : undefined),
|
||||||
validators={{
|
onChangeAsyncDebounceMs: 250,
|
||||||
onChange: ({ value }) => (!value ? t('Username required') : undefined),
|
onChangeAsync: async ({ value }) => {
|
||||||
onChangeAsyncDebounceMs: 250,
|
return !value && t('Username required');
|
||||||
onChangeAsync: async ({ value }) => {
|
},
|
||||||
return !value && t('Username required');
|
}}
|
||||||
},
|
children={(field) => {
|
||||||
}}
|
return (
|
||||||
children={(field) => {
|
<>
|
||||||
return (
|
<TextField
|
||||||
<>
|
name={field.name}
|
||||||
<TextField
|
value={field.state.value}
|
||||||
name={field.name}
|
onBlur={field.handleBlur}
|
||||||
value={field.state.value}
|
onChange={(e) => field.handleChange(e.target.value)}
|
||||||
onBlur={field.handleBlur}
|
size="small"
|
||||||
onChange={(e) => field.handleChange(e.target.value)}
|
label={t('Username')}
|
||||||
size="small"
|
required
|
||||||
label={t('Username')}
|
margin="dense"
|
||||||
required
|
autoComplete="new-username"
|
||||||
margin="dense"
|
fullWidth
|
||||||
autoComplete="new-username"
|
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
||||||
fullWidth
|
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
||||||
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
/>
|
||||||
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
</>
|
||||||
/>
|
);
|
||||||
</>
|
}}
|
||||||
);
|
/>
|
||||||
}}
|
<form.Field
|
||||||
/>
|
name="email"
|
||||||
</Grid>
|
validators={{
|
||||||
<Grid item xs={12}>
|
onChange: ({ value }) => (!value ? t('Email required') : undefined),
|
||||||
<form.Field
|
onChangeAsyncDebounceMs: 250,
|
||||||
name="email"
|
onChangeAsync: async ({ value }) => {
|
||||||
validators={{
|
return !value && t('Email required');
|
||||||
onChange: ({ value }) => (!value ? t('Email required') : undefined),
|
},
|
||||||
onChangeAsyncDebounceMs: 250,
|
}}
|
||||||
onChangeAsync: async ({ value }) => {
|
children={(field) => {
|
||||||
return !value && t('Email required');
|
return (
|
||||||
},
|
<>
|
||||||
}}
|
<TextField
|
||||||
children={(field) => {
|
name={field.name}
|
||||||
return (
|
value={field.state.value}
|
||||||
<>
|
onBlur={field.handleBlur}
|
||||||
<TextField
|
onChange={(e) => field.handleChange(e.target.value)}
|
||||||
name={field.name}
|
size="small"
|
||||||
value={field.state.value}
|
label={t('Email')}
|
||||||
onBlur={field.handleBlur}
|
required
|
||||||
onChange={(e) => field.handleChange(e.target.value)}
|
margin="dense"
|
||||||
size="small"
|
autoComplete="new-email"
|
||||||
label={t('Email')}
|
fullWidth
|
||||||
required
|
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
||||||
margin="dense"
|
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
||||||
autoComplete="new-email"
|
/>
|
||||||
fullWidth
|
</>
|
||||||
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
);
|
||||||
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<form.Subscribe
|
<form.Subscribe
|
||||||
|
|||||||
@ -1,215 +0,0 @@
|
|||||||
import {
|
|
||||||
Button,
|
|
||||||
CircularProgress,
|
|
||||||
Dialog,
|
|
||||||
DialogActions,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
Grid,
|
|
||||||
TextField,
|
|
||||||
useMediaQuery,
|
|
||||||
useTheme,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useForm } from '@tanstack/react-form';
|
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
||||||
import { t } from 'i18next';
|
|
||||||
import { FC, FormEvent, useEffect, useState } from 'react';
|
|
||||||
import { useApi } from '../../../api/Api';
|
|
||||||
import { User, UserUpdate } from '../../../types/User';
|
|
||||||
import ErrorComponent from '../../Error/ErrorComponent';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
user: User;
|
|
||||||
open: boolean;
|
|
||||||
onClose: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UserPasswordDialog: FC<Props> = ({ user, open, onClose }) => {
|
|
||||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const [error, setError] = useState<any>();
|
|
||||||
|
|
||||||
const theme = useTheme();
|
|
||||||
const fullScreen = useMediaQuery(theme.breakpoints.only('xs'), { noSsr: true });
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const Api = useApi();
|
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
|
||||||
mutationFn: ({ data, id }: { data: UserUpdate; id?: number }) => {
|
|
||||||
return Api.updateUser(data, id);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = useForm<UserUpdate & { passwordConfirm: string }>({
|
|
||||||
defaultValues: {
|
|
||||||
password: '',
|
|
||||||
passwordConfirm: '',
|
|
||||||
},
|
|
||||||
onSubmit: async ({ value }) => {
|
|
||||||
try {
|
|
||||||
updateMutation.mutate(
|
|
||||||
{ data: { password: value.password }, id: Api.authenticatedUser?.id === user.id ? undefined : user.id },
|
|
||||||
{
|
|
||||||
onSuccess: () => {
|
|
||||||
handleClose();
|
|
||||||
|
|
||||||
const queryKey = Api.authenticatedUser?.id === user.id ? ['profile'] : ['profile', { id: user.id }];
|
|
||||||
queryClient.invalidateQueries({ queryKey });
|
|
||||||
},
|
|
||||||
onError: setError,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
} catch (_error: any) {
|
|
||||||
setError(_error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
form.reset();
|
|
||||||
setError(undefined);
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!Api.hasAuth) handleClose();
|
|
||||||
}, [Api.hasAuth]); //eslint-disable-line react-hooks/exhaustive-deps
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
open={open}
|
|
||||||
onClose={handleClose}
|
|
||||||
fullWidth
|
|
||||||
fullScreen={fullScreen}
|
|
||||||
PaperProps={{
|
|
||||||
component: 'form',
|
|
||||||
onSubmit: (e: FormEvent<HTMLFormElement>) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit();
|
|
||||||
},
|
|
||||||
onKeyDown: (event: React.KeyboardEvent<HTMLFormElement>) => {
|
|
||||||
if (event.key === 'Tab') {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
noValidate: true,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogTitle>{t('Edit data')}</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<form.Field
|
|
||||||
name="password"
|
|
||||||
validators={{
|
|
||||||
onChange: ({ value }) => (!value ? t('Password required') : undefined),
|
|
||||||
onChangeAsyncDebounceMs: 250,
|
|
||||||
onChangeAsync: async ({ value }) => {
|
|
||||||
return !value && t('Password required');
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
children={(field) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TextField
|
|
||||||
variant="outlined"
|
|
||||||
name={field.name}
|
|
||||||
value={field.state.value}
|
|
||||||
onBlur={field.handleBlur}
|
|
||||||
onChange={(e) => field.handleChange(e.target.value)}
|
|
||||||
size="small"
|
|
||||||
label={t('Password')}
|
|
||||||
required
|
|
||||||
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
|
||||||
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
|
||||||
type="password"
|
|
||||||
autoComplete="new-password"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<form.Field
|
|
||||||
name="passwordConfirm"
|
|
||||||
validators={{
|
|
||||||
onChangeListenTo: ['password'],
|
|
||||||
onChange: ({ value, fieldApi }) =>
|
|
||||||
!value
|
|
||||||
? t('Password required')
|
|
||||||
: value !== fieldApi.form.getFieldValue('password')
|
|
||||||
? t('Password match')
|
|
||||||
: undefined,
|
|
||||||
onChangeAsyncDebounceMs: 250,
|
|
||||||
onChangeAsync: async ({ value, fieldApi }) =>
|
|
||||||
!value
|
|
||||||
? t('Password required')
|
|
||||||
: value !== fieldApi.form.getFieldValue('password')
|
|
||||||
? t('Password match')
|
|
||||||
: undefined,
|
|
||||||
}}
|
|
||||||
children={(field) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TextField
|
|
||||||
variant="outlined"
|
|
||||||
name={field.name}
|
|
||||||
value={field.state.value}
|
|
||||||
onBlur={field.handleBlur}
|
|
||||||
onChange={(e) => field.handleChange(e.target.value)}
|
|
||||||
size="small"
|
|
||||||
label={t('Password confirm')}
|
|
||||||
required
|
|
||||||
error={field.state.meta.isTouched && field.state.meta.errors.length > 0}
|
|
||||||
helperText={field.state.meta.isTouched ? field.state.meta.errors.join(',') : ''}
|
|
||||||
type="password"
|
|
||||||
autoComplete="new-password"
|
|
||||||
fullWidth
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<form.Subscribe
|
|
||||||
selector={(state) => [state.canSubmit, state.isSubmitting]}
|
|
||||||
children={([canSubmit]) => (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => {
|
|
||||||
handleClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Cancel')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
disabled={!canSubmit || updateMutation.isPending}
|
|
||||||
autoFocus
|
|
||||||
variant="contained"
|
|
||||||
endIcon={updateMutation.isPending && <CircularProgress color="inherit" size="20px" />}
|
|
||||||
>
|
|
||||||
{t('Save')}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</DialogActions>
|
|
||||||
{error && (
|
|
||||||
<DialogContent>
|
|
||||||
<ErrorComponent error={error} context="userUpdate" />
|
|
||||||
</DialogContent>
|
|
||||||
)}
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UserPasswordDialog;
|
|
||||||
@ -17,8 +17,7 @@ import { PostAuth } from '../../types/Post';
|
|||||||
import { User } from '../../types/User';
|
import { User } from '../../types/User';
|
||||||
import convertDate from '../../utils/date';
|
import convertDate from '../../utils/date';
|
||||||
import UserEditDialog from '../Dialogs/UserEdit/UserEditDialog';
|
import UserEditDialog from '../Dialogs/UserEdit/UserEditDialog';
|
||||||
import UserImageDialog from '../Dialogs/UserEdit/UserImageDialog';
|
import UserImageDialog from '../Dialogs/UserImage/UserImageDialog';
|
||||||
import UserPasswordDialog from '../Dialogs/UserEdit/UserPasswordDialog';
|
|
||||||
import Post from '../Post/Post';
|
import Post from '../Post/Post';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -30,7 +29,6 @@ interface Props {
|
|||||||
const Profile: FC<Props> = ({ user, posts, canEdit }) => {
|
const Profile: FC<Props> = ({ user, posts, canEdit }) => {
|
||||||
const [editOpen, setEditOpen] = useState(false);
|
const [editOpen, setEditOpen] = useState(false);
|
||||||
const [imageOpen, setImageOpen] = useState(false);
|
const [imageOpen, setImageOpen] = useState(false);
|
||||||
const [passwordOpen, setPasswordOpen] = useState(false);
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -67,12 +65,8 @@ const Profile: FC<Props> = ({ user, posts, canEdit }) => {
|
|||||||
<Button size="small" onClick={() => setEditOpen(true)}>
|
<Button size="small" onClick={() => setEditOpen(true)}>
|
||||||
{t('Edit')}
|
{t('Edit')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="small" color="secondary" onClick={() => setPasswordOpen(true)}>
|
|
||||||
{t('Change password')}
|
|
||||||
</Button>
|
|
||||||
<UserEditDialog user={user} open={editOpen} onClose={() => setEditOpen(false)} />
|
<UserEditDialog user={user} open={editOpen} onClose={() => setEditOpen(false)} />
|
||||||
<UserImageDialog user={user} open={imageOpen} onClose={() => setImageOpen(false)} />
|
<UserImageDialog user={user} open={imageOpen} onClose={() => setImageOpen(false)} />
|
||||||
<UserPasswordDialog user={user} open={passwordOpen} onClose={() => setPasswordOpen(false)} />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CardActions>
|
</CardActions>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user