Files
traveling-around-the-world/client/src/features/visits/components/VisitList.tsx
2025-09-30 17:21:35 +08:00

73 lines
2.4 KiB
TypeScript

import { useTranslation } from 'react-i18next';
import { Button, Card, CardActions, CardContent, CircularProgress, Stack, Typography } from '@mui/material';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import { useDeleteVisitMutation, useVisitsQuery } from '../hooks/useVisitQueries';
import type { Visit } from '../types';
interface VisitListProps {
onEdit: (visit: Visit) => void;
}
export function VisitList({ onEdit }: VisitListProps) {
const { data: visits = [], isLoading } = useVisitsQuery();
const deleteMutation = useDeleteVisitMutation();
const { t } = useTranslation();
if (isLoading) {
return (
<Stack direction="row" spacing={1} alignItems="center" justifyContent="center" sx={{ py: 4 }}>
<CircularProgress size={20} />
<Typography variant="body2" color="text.secondary">
{t('list.loading')}
</Typography>
</Stack>
);
}
if (!visits.length) {
return (
<Typography variant="body2" color="text.secondary" sx={{ p: 3 }}>
{t('list.empty')}
</Typography>
);
}
return (
<Stack spacing={2} sx={{ p: 2 }}>
{visits.map((visit) => (
<Card key={visit.id} variant="outlined">
<CardContent>
<Typography variant="h6" fontWeight={600} gutterBottom>
{visit.location.country}
{visit.location.city ? ` · ${visit.location.city}` : ''}
</Typography>
<Typography variant="body2" color="text.secondary">
{visit.date.start}
{visit.date.end ? `${visit.date.end}` : ''}
</Typography>
{visit.notes ? (
<Typography variant="body2" color="text.primary" sx={{ mt: 1 }}>
{visit.notes}
</Typography>
) : null}
</CardContent>
<CardActions sx={{ justifyContent: 'flex-end', gap: 1, px: 2, pb: 2 }}>
<Button startIcon={<EditIcon />} size="small" onClick={() => onEdit(visit)}>
{t('list.edit')}
</Button>
<Button
startIcon={<DeleteIcon />}
size="small"
color="error"
onClick={() => deleteMutation.mutate(visit.id)}
>
{t('list.delete')}
</Button>
</CardActions>
</Card>
))}
</Stack>
);
}