import { useState } from 'react';
import { useNavigate } from 'react-router';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { adminPinnedMessagesApi, PinnedMessageResponse } from '../api/adminPinnedMessages';
import { AdminBackButton } from '../components/admin';
import { useNativeDialog } from '../platform/hooks/useNativeDialog';
// Icons
const PinIcon = () => (
);
const PlusIcon = () => (
);
const RefreshIcon = () => (
);
const PhotoIcon = () => (
);
const VideoIcon = () => (
);
const MenuIcon = () => (
);
const RepeatIcon = () => (
);
const BroadcastIcon = () => (
);
const TrashIcon = () => (
);
const EditIcon = () => (
);
const CheckIcon = () => (
);
const XIcon = () => (
);
const UnpinIcon = () => (
);
// Message card component
function PinnedMessageCard({
message,
onActivate,
onDeactivate,
onBroadcast,
onDelete,
onEdit,
onUnpin,
}: {
message: PinnedMessageResponse;
onActivate: (id: number) => void;
onDeactivate: () => void;
onBroadcast: (id: number) => void;
onDelete: (id: number) => void;
onEdit: (id: number) => void;
onUnpin: () => void;
}) {
const { t } = useTranslation();
return (
{/* Status + ID + media indicator */}
{message.is_active
? t('admin.pinnedMessages.active')
: t('admin.pinnedMessages.inactive')}
#{message.id}
{message.media_type && (
{message.media_type === 'photo' ? : }
)}
{message.send_before_menu && (
)}
{message.send_on_every_start && (
)}
{/* Content preview */}
{message.content || t('admin.pinnedMessages.noContent')}
{/* Date */}
{new Date(message.created_at).toLocaleDateString()}
{/* Action buttons */}
{message.is_active ? (
<>
>
) : (
)}
{!message.is_active && (
)}
);
}
// Main component
export default function AdminPinnedMessages() {
const { t } = useTranslation();
const navigate = useNavigate();
const queryClient = useQueryClient();
const [page, setPage] = useState(0);
const limit = 20;
// Fetch pinned messages
const { data, isLoading, refetch } = useQuery({
queryKey: ['admin', 'pinned-messages', 'list', page],
queryFn: () => adminPinnedMessagesApi.list(limit, page * limit),
});
const messages = data?.items || [];
const total = data?.total || 0;
const totalPages = Math.ceil(total / limit);
// Mutations
const activateMutation = useMutation({
mutationFn: (id: number) => adminPinnedMessagesApi.activate(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'pinned-messages'] });
},
});
const deactivateMutation = useMutation({
mutationFn: () => adminPinnedMessagesApi.deactivate(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'pinned-messages'] });
},
});
const unpinMutation = useMutation({
mutationFn: () => adminPinnedMessagesApi.unpin(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'pinned-messages'] });
},
});
const broadcastMutation = useMutation({
mutationFn: (id: number) => adminPinnedMessagesApi.broadcast(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'pinned-messages'] });
},
});
const deleteMutation = useMutation({
mutationFn: (id: number) => adminPinnedMessagesApi.delete(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin', 'pinned-messages'] });
},
});
const handleActivate = (id: number) => {
activateMutation.mutate(id);
};
const handleDeactivate = () => {
deactivateMutation.mutate();
};
const { confirm: confirmDialog } = useNativeDialog();
const handleUnpin = async () => {
if (await confirmDialog(t('admin.pinnedMessages.unpinConfirm'))) {
unpinMutation.mutate();
}
};
const handleBroadcast = async (id: number) => {
if (await confirmDialog(t('admin.pinnedMessages.broadcastConfirm'))) {
broadcastMutation.mutate(id);
}
};
const handleDelete = async (id: number) => {
if (await confirmDialog(t('admin.pinnedMessages.deleteConfirm'))) {
deleteMutation.mutate(id);
}
};
const handleEdit = (id: number) => {
navigate(`/admin/pinned-messages/${id}/edit`);
};
return (
{/* Header */}
{t('admin.pinnedMessages.title')}
{t('admin.pinnedMessages.subtitle')}
{/* Messages list */}
{isLoading ? (
) : messages.length === 0 ? (
{t('admin.pinnedMessages.empty')}
) : (
{messages.map((message: PinnedMessageResponse) => (
))}
)}
{/* Pagination */}
{totalPages > 1 && (
{page + 1} / {totalPages}
)}
);
}