doctor-mail/apps/web/src/app/main/letter/write/page.tsx

128 lines
5.0 KiB
TypeScript
Raw Normal View History

2025-01-25 00:37:59 +08:00
import { useState, useMemo, useCallback, useEffect } from 'react';
2025-01-24 15:05:03 +08:00
import { motion, AnimatePresence } from 'framer-motion';
2025-01-22 23:19:58 +08:00
import Header from './header';
2025-01-25 00:37:59 +08:00
import { SendCard } from './SendCard';
import { Spin, Empty, Input, Alert, message, Pagination } from 'antd';
import { api } from '@nice/client';
import DepartmentSelect from '@web/src/components/models/department/department-select';
import debounce from 'lodash/debounce';
import { SearchOutlined } from '@ant-design/icons';
2025-01-22 19:24:52 +08:00
export default function WriteLetterPage() {
const [searchQuery, setSearchQuery] = useState('');
2025-01-25 00:37:59 +08:00
const [selectedDept, setSelectedDept] = useState<string>();
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 10;
2025-01-22 19:24:52 +08:00
2025-01-25 00:37:59 +08:00
const { data, isLoading, error } = api.staff.findManyWithPagination.useQuery({
page: currentPage,
pageSize,
where: {
deptId: selectedDept,
OR: [{
showname: {
contains: searchQuery
}
}, {
username: {
contains: searchQuery
}
}]
}
});
useEffect(() => {
console.log(selectedDept)
console.log(data)
console.log(searchQuery)
}, [selectedDept, data, searchQuery])
// Reset to first page when search query or department changes
useCallback(() => {
setCurrentPage(1);
}, [searchQuery, selectedDept]);
2025-01-22 19:24:52 +08:00
return (
2025-01-24 15:05:03 +08:00
<div className="min-h-screen bg-gradient-to-b from-slate-50 to-slate-100">
<Header />
<div className="container mx-auto px-4 py-8">
2025-01-25 00:37:59 +08:00
<div className="mb-8 space-y-4">
{/* Search and Filter Section */}
<div className="flex flex-col md:flex-row gap-4 items-center">
<div className="w-full md:w-96">
<Input
prefix={<SearchOutlined className="text-gray-400" />}
placeholder="搜索领导姓名或职级..."
onChange={debounce((e) => setSearchQuery(e.target.value), 300)}
className="w-full"
size="large"
/>
</div>
<DepartmentSelect
size="large"
value={selectedDept}
onChange={setSelectedDept as any}
className="w-full md:w-64"
/>
</div>
{error && (
<Alert
message="加载失败"
description="获取数据时出现错误,请刷新页面重试。"
type="error"
showIcon
/>
)}
</div>
2025-01-22 19:24:52 +08:00
2025-01-24 15:05:03 +08:00
<AnimatePresence>
2025-01-25 00:37:59 +08:00
{isLoading ? (
<div className="flex justify-center items-center py-12">
<Spin size="large" tip="加载中..." />
</div>
) : data?.items.length > 0 ? (
2025-01-24 15:05:03 +08:00
<motion.div
className="grid grid-cols-1 gap-6"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
2025-01-25 00:37:59 +08:00
{data?.items.map((item) => (
<SendCard
key={item.id}
staff={item as any}
2025-01-24 15:05:03 +08:00
/>
))}
</motion.div>
) : (
2025-01-22 19:24:52 +08:00
<motion.div
2025-01-24 15:05:03 +08:00
className="text-center py-12"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
2025-01-22 19:24:52 +08:00
>
2025-01-25 00:37:59 +08:00
<Empty
description="没有找到匹配的收信人"
className="py-12"
/>
2025-01-22 19:24:52 +08:00
</motion.div>
2025-01-24 15:05:03 +08:00
)}
</AnimatePresence>
2025-01-25 00:37:59 +08:00
{/* Pagination */}
{data?.items.length > 0 && (
<div className="flex justify-center mt-8">
<Pagination
current={currentPage}
total={data?.totalPages || 0}
pageSize={pageSize}
onChange={(page) => setCurrentPage(page)}
showSizeChanger={false}
showTotal={(total) => `${total} 条记录`}
/>
</div>
)}
2025-01-22 19:24:52 +08:00
</div>
</div>
);
}