Files
d8d-admin-mobile-starter-pu…/client/mobile/pages_messages.tsx
yourname 1df9f7fea2 创建了api目录并拆分为10个功能模块文件
建立了index.ts统一导出
精简了原api.ts文件
2025-05-13 09:00:58 +00:00

110 lines
3.5 KiB
TypeScript

import React from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { BellIcon } from '@heroicons/react/24/outline';
import { MessageStatus } from '../share/types.ts';
// 添加通知页面组件
import { MessageAPI } from './api/index.ts';
export const NotificationsPage = () => {
const queryClient = useQueryClient();
// 获取消息列表
const { data: messages, isLoading } = useQuery({
queryKey: ['messages'],
queryFn: () => MessageAPI.getMessages(),
});
// 获取未读消息数量
const { data: unreadCount } = useQuery({
queryKey: ['unreadCount'],
queryFn: () => MessageAPI.getUnreadCount(),
});
// 标记消息为已读
const markAsReadMutation = useMutation({
mutationFn: (id: number) => MessageAPI.markAsRead(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['messages'] });
queryClient.invalidateQueries({ queryKey: ['unreadCount'] });
},
});
// 删除消息
const deleteMutation = useMutation({
mutationFn: (id: number) => MessageAPI.deleteMessage(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['messages'] });
},
});
const handleMarkAsRead = (id: number) => {
markAsReadMutation.mutate(id);
};
const handleDelete = (id: number) => {
if (confirm('确定要删除这条消息吗?')) {
deleteMutation.mutate(id);
}
};
if (isLoading) {
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4"></h1>
<div className="flex justify-center items-center h-40">
<div className="w-8 h-8 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin"></div>
</div>
</div>
);
}
return (
<div className="p-4">
<div className="flex items-center justify-between mb-4">
<h1 className="text-2xl font-bold"></h1>
{unreadCount && unreadCount.count > 0 ? (
<div className="flex items-center">
<BellIcon className="h-5 w-5 text-red-500 mr-1" />
<span className="text-sm text-red-500">{unreadCount.count}</span>
</div>
) : null}
</div>
<div className="bg-white rounded-lg shadow divide-y">
{messages?.data.map((message) => (
<div key={message.id} className="p-4">
<div className="flex justify-between items-start">
<h3 className="font-medium">{message.title}</h3>
<div className="flex space-x-2">
{message.user_status === MessageStatus.UNREAD && (
<button
type="button"
onClick={() => handleMarkAsRead(message.id)}
className="text-xs text-blue-600 hover:text-blue-800"
>
</button>
)}
<button
type="button"
onClick={() => handleDelete(message.id)}
className="text-xs text-red-600 hover:text-red-800"
>
</button>
</div>
</div>
<p className="text-gray-500 text-sm mt-1">{message.content}</p>
<p className="text-xs text-gray-400 mt-2">
{dayjs(message.created_at).format('YYYY-MM-DD HH:mm')}
</p>
</div>
))}
</div>
</div>
);
};