128 lines
5.0 KiB
TypeScript
128 lines
5.0 KiB
TypeScript
import { useState, useMemo, useCallback, useEffect } from 'react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
import Header from './header';
|
|
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';
|
|
|
|
export default function WriteLetterPage() {
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const [selectedDept, setSelectedDept] = useState<string>();
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const pageSize = 10;
|
|
|
|
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]);
|
|
|
|
return (
|
|
<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">
|
|
<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>
|
|
|
|
<AnimatePresence>
|
|
{isLoading ? (
|
|
<div className="flex justify-center items-center py-12">
|
|
<Spin size="large" tip="加载中..." />
|
|
</div>
|
|
) : data?.items.length > 0 ? (
|
|
<motion.div
|
|
className="grid grid-cols-1 gap-6"
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
>
|
|
{data?.items.map((item) => (
|
|
<SendCard
|
|
key={item.id}
|
|
staff={item as any}
|
|
/>
|
|
))}
|
|
</motion.div>
|
|
) : (
|
|
<motion.div
|
|
className="text-center py-12"
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
>
|
|
<Empty
|
|
description="没有找到匹配的收信人"
|
|
className="py-12"
|
|
/>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
|
|
{/* 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>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|