From 9f6df6d948d784d46548836432e46119955b8366 Mon Sep 17 00:00:00 2001 From: longdayi <13477510+longdayilongdayi@user.noreply.gitee.com> Date: Sat, 25 Jan 2025 00:52:30 +0800 Subject: [PATCH] 01250052 --- apps/web/src/app/main/letter/list/Header.tsx | 20 +-- .../src/app/main/letter/list/Pagination.tsx | 167 ------------------ .../src/app/main/letter/list/SearchFilter.tsx | 90 ---------- apps/web/src/app/main/letter/list/page.tsx | 27 +-- .../app/main/letter/list/useLetterFilters.ts | 33 ---- .../models/post}/LetterCard.tsx | 22 ++- .../models/post/list/LetterList.tsx | 18 ++ .../components/models/post/list/PostList.tsx | 5 - packages/client/src/api/hooks/useStaff.ts | 1 - 9 files changed, 31 insertions(+), 352 deletions(-) delete mode 100644 apps/web/src/app/main/letter/list/Pagination.tsx delete mode 100644 apps/web/src/app/main/letter/list/SearchFilter.tsx delete mode 100644 apps/web/src/app/main/letter/list/useLetterFilters.ts rename apps/web/src/{app/main/letter/list => components/models/post}/LetterCard.tsx (90%) create mode 100644 apps/web/src/components/models/post/list/LetterList.tsx delete mode 100644 apps/web/src/components/models/post/list/PostList.tsx diff --git a/apps/web/src/app/main/letter/list/Header.tsx b/apps/web/src/app/main/letter/list/Header.tsx index ab7ba5b..382272a 100644 --- a/apps/web/src/app/main/letter/list/Header.tsx +++ b/apps/web/src/app/main/letter/list/Header.tsx @@ -1,16 +1,6 @@ -import { SearchFilters } from "./SearchFilter"; -import { useQueryClient } from '@tanstack/react-query'; export function Header() { - const handleSearch = (value: string) => { - - }; - - const handleFilterChange = () => { - - }; - return (

公开信件列表

@@ -24,15 +14,7 @@ export function Header() { 高效解决实际问题 - +
); } diff --git a/apps/web/src/app/main/letter/list/Pagination.tsx b/apps/web/src/app/main/letter/list/Pagination.tsx deleted file mode 100644 index 9f31cbf..0000000 --- a/apps/web/src/app/main/letter/list/Pagination.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline'; -import { useMemo } from 'react'; - -interface PaginationProps { - totalItems: number; - itemsPerPage: number; - currentPage?: number; - onPageChange?: (page: number) => void; -} -export function Pagination({ - totalItems, - itemsPerPage, - currentPage = 1, - onPageChange = () => { }, -}: PaginationProps) { - const STYLE_CONFIG = { - colors: { - primary: 'bg-primary', // USAF Blue - hover: 'hover:bg-[#00264d]', // Darker USAF Blue - disabled: 'bg-disabled', - text: { - primary: 'text-primary', - light: 'text-white', - secondary: 'text-tertiary-400' - } - }, - components: { - container: ` - flex items-center justify-between - px-4 py-3 sm:px-6 - `, - pagination: ` - inline-flex shadow-sm rounded-md - divide-x divide-gray-200 - `, - button: ` - relative inline-flex items-center justify-center - min-w-[2.5rem] h-10 - text-sm font-medium - transition-colors duration-200 - focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 - ` - } - }; - // Memoized calculations - const totalPages = useMemo(() => Math.ceil(totalItems / itemsPerPage), [totalItems, itemsPerPage]); - const startItem = (currentPage - 1) * itemsPerPage + 1; - const endItem = Math.min(currentPage * itemsPerPage, totalItems); - - // Navigation handlers - const handlePrevious = () => currentPage > 1 && onPageChange(currentPage - 1); - const handleNext = () => currentPage < totalPages && onPageChange(currentPage + 1); - - // Generate page numbers with improved logic - const getPageNumbers = () => { - const maxVisiblePages = 5; - if (totalPages <= maxVisiblePages) { - return Array.from({ length: totalPages }, (_, i) => i + 1); - } - if (currentPage <= 3) { - return [1, 2, 3, '...', totalPages]; - } - if (currentPage >= totalPages - 2) { - return [1, '...', totalPages - 2, totalPages - 1, totalPages]; - } - return [ - 1, - '...', - currentPage - 1, - currentPage, - currentPage + 1, - '...', - totalPages - ]; - }; - - const renderPageButton = (pageNum: number | string, index: number) => { - if (pageNum === '...') { - return ( - - … - - ); - } - - const isCurrentPage = currentPage === pageNum; - const buttonStyle = isCurrentPage - ? ` - ${STYLE_CONFIG.components.button} - ${STYLE_CONFIG.colors.primary} - ${STYLE_CONFIG.colors.text.light} - ${STYLE_CONFIG.colors.hover} - ` - : ` - ${STYLE_CONFIG.components.button} - bg-white - ${STYLE_CONFIG.colors.text.primary} - hover:bg-gray-50 - `; - - return ( - - ); - }; - return ( -
-
-
-

- Showing {startItem} to{' '} - {endItem} of{' '} - {totalItems} results -

-
- - -
-
- ); -} \ No newline at end of file diff --git a/apps/web/src/app/main/letter/list/SearchFilter.tsx b/apps/web/src/app/main/letter/list/SearchFilter.tsx deleted file mode 100644 index f74cd28..0000000 --- a/apps/web/src/app/main/letter/list/SearchFilter.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { SearchOutlined } from '@ant-design/icons'; -import { Form, Input, Select, Spin } from 'antd'; -import { useEffect } from 'react'; - -interface SearchFiltersProps { - searchTerm: string; - onSearchChange: (value: string) => void; - filterCategory: string; - onCategoryChange: (value: string) => void; - filterStatus: string; - onStatusChange: (value: string) => void; - className?: string; - isLoading?: boolean; -} - -const LoadingIndicator = () => ( - -); - -export function SearchFilters({ - searchTerm, - onSearchChange, - filterCategory, - onCategoryChange, - filterStatus, - onStatusChange, - className, - isLoading = false -}: SearchFiltersProps) { - const [form] = Form.useForm(); - - // 统一处理表单初始值 - const initialValues = { - search: searchTerm, - category: filterCategory, - status: filterStatus - }; - - useEffect(() => { - form.setFieldsValue(initialValues); - }, [searchTerm, filterCategory, filterStatus, form]); - - return ( -
-
- - } - placeholder="搜索关键词、发件人或单位..." - onChange={(e) => onSearchChange(e.target.value)} - allowClear - suffix={isLoading ? : null} - /> - - - - - -
-
- ); -} diff --git a/apps/web/src/app/main/letter/list/page.tsx b/apps/web/src/app/main/letter/list/page.tsx index 4ec963b..e494780 100644 --- a/apps/web/src/app/main/letter/list/page.tsx +++ b/apps/web/src/app/main/letter/list/page.tsx @@ -1,37 +1,14 @@ - -import { letters } from "./constants"; import { Header } from "./Header"; -import { LetterCard } from "./LetterCard"; -import { Pagination } from "./Pagination"; -import { SearchFilters } from "./SearchFilter"; -import { useLetterFilters } from "./useLetterFilters"; export default function LetterListPage() { - const { - searchTerm, - setSearchTerm, - filterCategory, - setFilterCategory, - filterStatus, - setFilterStatus, - filteredLetters, - } = useLetterFilters(letters); return ( // 添加 flex flex-col 使其成为弹性布局容器
{/* 添加 flex-grow 使内容区域自动填充剩余空间 */} -
- {filteredLetters.map((letter) => ( - - ))} -
- {/* Pagination 会自然固定在底部 */} - + +
); } diff --git a/apps/web/src/app/main/letter/list/useLetterFilters.ts b/apps/web/src/app/main/letter/list/useLetterFilters.ts deleted file mode 100644 index 3dd7f74..0000000 --- a/apps/web/src/app/main/letter/list/useLetterFilters.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { useState, useMemo } from 'react'; -import { Letter } from './types'; - -export function useLetterFilters(letters: Letter[]) { - const [currentPage, setCurrentPage] = useState(1); - const [searchTerm, setSearchTerm] = useState(''); - const [filterStatus, setFilterStatus] = useState('all'); - const [filterCategory, setFilterCategory] = useState('all'); - - const filteredLetters = useMemo(() => { - return letters.filter(letter => { - const matchesSearch = [letter.title, letter.sender, letter.unit] - .some(field => field.toLowerCase().includes(searchTerm.toLowerCase())); - - const matchesCategory = filterCategory === 'all' || letter.category === filterCategory; - const matchesStatus = filterStatus === 'all' || letter.status === filterStatus; - - return matchesSearch && matchesCategory && matchesStatus; - }); - }, [letters, searchTerm, filterCategory, filterStatus]); - - return { - currentPage, - setCurrentPage, - searchTerm, - setSearchTerm, - filterStatus, - setFilterStatus, - filterCategory, - setFilterCategory, - filteredLetters, - }; -} diff --git a/apps/web/src/app/main/letter/list/LetterCard.tsx b/apps/web/src/components/models/post/LetterCard.tsx similarity index 90% rename from apps/web/src/app/main/letter/list/LetterCard.tsx rename to apps/web/src/components/models/post/LetterCard.tsx index b322c5b..e6232e5 100644 --- a/apps/web/src/app/main/letter/list/LetterCard.tsx +++ b/apps/web/src/components/models/post/LetterCard.tsx @@ -1,14 +1,14 @@ import { EyeOutlined, LikeOutlined, LikeFilled, UserOutlined, BankOutlined, CalendarOutlined, FileTextOutlined } from '@ant-design/icons'; import { Button, Typography, Space, Tooltip } from 'antd'; import toast from 'react-hot-toast'; -import { Letter } from './types'; -import { getBadgeStyle } from './utils'; import { useState } from 'react'; - +import { getBadgeStyle } from '@web/src/app/main/letter/list/utils'; +import { PostDto } from '@nice/common'; +import dayjs from 'dayjs'; const { Title, Paragraph, Text } = Typography; interface LetterCardProps { - letter: Letter; + letter: PostDto; } export function LetterCard({ letter }: LetterCardProps) { @@ -54,9 +54,7 @@ export function LetterCard({ letter }: LetterCardProps) { {letter.title} - {letter.priority && ( - - )} + {/* Meta Info */} @@ -64,17 +62,17 @@ export function LetterCard({ letter }: LetterCardProps) { - {letter.sender} + {letter.author.showname} | - {letter.unit} + {letter.author.department.name} - {letter.date} + {dayjs(letter.createdAt).format('YYYY-MM-DD')} @@ -94,8 +92,8 @@ export function LetterCard({ letter }: LetterCardProps) { {/* Badges & Interactions */}
- - + +
diff --git a/apps/web/src/components/models/post/list/LetterList.tsx b/apps/web/src/components/models/post/list/LetterList.tsx new file mode 100644 index 0000000..36b47c6 --- /dev/null +++ b/apps/web/src/components/models/post/list/LetterList.tsx @@ -0,0 +1,18 @@ +import { api, RouterInputs } from "@nice/client"; +import { Prisma } from "packages/common/dist"; +import { LetterCard } from "../LetterCard"; + +export default function LetterList({ params }: { params: RouterInputs["post"]["findManyWithPagination"] }) { + + const { data, isLoading } = api.post.findManyWithPagination.useQuery({ + page: 1, + pageSize: 1, + where: {}, + select: {} + }) + return
+ {data?.items.map((letter: any) => ( + + ))} +
+} \ No newline at end of file diff --git a/apps/web/src/components/models/post/list/PostList.tsx b/apps/web/src/components/models/post/list/PostList.tsx deleted file mode 100644 index b0382d5..0000000 --- a/apps/web/src/components/models/post/list/PostList.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { api } from "@nice/client"; - -export default function LetterList(){ - -} \ No newline at end of file diff --git a/packages/client/src/api/hooks/useStaff.ts b/packages/client/src/api/hooks/useStaff.ts index c79977b..3659652 100755 --- a/packages/client/src/api/hooks/useStaff.ts +++ b/packages/client/src/api/hooks/useStaff.ts @@ -9,7 +9,6 @@ export function useStaff() { const getStaff = (key: string) => { return findQueryData(queryClient, api.staff, key); }; - return { ...useEntity("staff", { create: {