137 lines
4.1 KiB
TypeScript
137 lines
4.1 KiB
TypeScript
import { Person } from '@mui/icons-material';
|
|
import {
|
|
Alert,
|
|
Avatar,
|
|
Button,
|
|
Card,
|
|
CardActions,
|
|
CardContent,
|
|
CardHeader,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogTitle,
|
|
Link as MUILink,
|
|
Snackbar,
|
|
Typography,
|
|
} from '@mui/material';
|
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { Link } from '@tanstack/react-router';
|
|
import { FC, useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import Api from '../../api/Api';
|
|
import { PostAuth, PostNonAuth } from '../../types/Post';
|
|
import convertDate from '../../utils/date';
|
|
import ErrorComponent from '../Error/ErrorComponent';
|
|
|
|
interface Props {
|
|
post: PostNonAuth | PostAuth;
|
|
}
|
|
|
|
const Post: FC<Props> = ({ post }) => {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const deleteMutation = useMutation({
|
|
mutationFn: (id: number) => {
|
|
return Api.deletePost(id);
|
|
},
|
|
});
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader
|
|
avatar={
|
|
'id' in post.user ? (
|
|
post.user.id !== Api.getAuthenticatedUser()?.id ? (
|
|
<MUILink component={Link} to="/profile/$id" params={{ id: post.user.id }}>
|
|
<Avatar alt={post.user.username} src={`storage/${post.user.image}`}>
|
|
<Person />
|
|
</Avatar>
|
|
</MUILink>
|
|
) : (
|
|
<MUILink component={Link} to="/profile">
|
|
<Avatar alt={post.user.username} src={`storage/${post.user.image}`}>
|
|
<Person />
|
|
</Avatar>
|
|
</MUILink>
|
|
)
|
|
) : (
|
|
<Avatar alt={post.user.username} src={`storage/${post.user.image}`}>
|
|
<Person />
|
|
</Avatar>
|
|
)
|
|
}
|
|
title={
|
|
'id' in post.user ? (
|
|
post.user.id !== Api.getAuthenticatedUser()?.id ? (
|
|
<MUILink component={Link} to="/profile/$id" params={{ id: post.user.id }}>
|
|
{post.user.username}
|
|
</MUILink>
|
|
) : (
|
|
<MUILink component={Link} to="/profile">
|
|
{post.user.username}
|
|
</MUILink>
|
|
)
|
|
) : (
|
|
post.user.username
|
|
)
|
|
}
|
|
subheader={convertDate(post.postedAt)}
|
|
/>
|
|
<CardContent>
|
|
<Typography>{post.content}</Typography>
|
|
</CardContent>
|
|
|
|
<CardActions>
|
|
{Api.isAdmin() && (
|
|
<>
|
|
<Button size="small" color="error" onClick={() => setOpen(true)}>
|
|
{t('Delete')}
|
|
</Button>
|
|
<Dialog open={open} onClose={() => setOpen(false)}>
|
|
<DialogTitle>{t('Confirm post delete title')}</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText>{t('Confirm post delete body', { name: post.user.username })}</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={() => setOpen(false)} autoFocus variant="contained">
|
|
{t('No')}
|
|
</Button>
|
|
<Button
|
|
variant="outlined"
|
|
color="error"
|
|
onClick={() => {
|
|
deleteMutation.mutate(post.id, {
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ['posts'],
|
|
});
|
|
},
|
|
});
|
|
setOpen(false);
|
|
}}
|
|
>
|
|
{t('Yes')}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</>
|
|
)}
|
|
</CardActions>
|
|
<Snackbar open={deleteMutation.isError} autoHideDuration={2000} onClose={() => deleteMutation.reset()}>
|
|
<Alert severity="error" variant="filled" sx={{ width: '100%' }}>
|
|
{deleteMutation.isError && <ErrorComponent error={deleteMutation.error} context="delete" />}
|
|
</Alert>
|
|
</Snackbar>
|
|
<Snackbar open={deleteMutation.isPending} message={t('Deleting')} />
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default Post;
|