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 1/2] 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: { From 6214ac308cab6093dc63b8660a88d7bb677bbd3f Mon Sep 17 00:00:00 2001 From: longdayi <13477510+longdayilongdayi@user.noreply.gitee.com> Date: Sat, 25 Jan 2025 02:27:40 +0800 Subject: [PATCH 2/2] 01250227 --- apps/server/src/models/base/base.service.ts | 3 +- apps/web/package.json | 1 + apps/web/src/app/main/letter/editor/page.tsx | 25 +- apps/web/src/app/main/letter/list/page.tsx | 11 +- .../src/app/main/letter/write/SendCard.tsx | 80 +++--- .../write/{header.tsx => WriteHeader.tsx} | 4 +- apps/web/src/app/main/letter/write/mock.ts | 31 --- apps/web/src/app/main/letter/write/page.tsx | 35 +-- apps/web/src/app/main/letter/write/types.ts | 12 - .../src/components/layout/main/useNavItem.ts | 2 +- .../post/editor/form/LetterBasicForm.tsx | 210 ++++++--------- .../post/editor/layout/LetterEditorLayout.tsx | 101 ------- .../models/post/list/LetterList.tsx | 121 ++++++++- .../components/models/staff/staff-select.tsx | 4 + .../components/models/term/term-select.tsx | 12 +- apps/web/src/index.css | 250 ------------------ apps/web/src/routes/index.tsx | 4 +- packages/utils/src/index.ts | 4 +- packages/utils/src/types.ts | 1 + pnpm-lock.yaml | 3 + 20 files changed, 295 insertions(+), 619 deletions(-) rename apps/web/src/app/main/letter/write/{header.tsx => WriteHeader.tsx} (93%) delete mode 100644 apps/web/src/app/main/letter/write/mock.ts delete mode 100644 apps/web/src/app/main/letter/write/types.ts delete mode 100644 apps/web/src/components/models/post/editor/layout/LetterEditorLayout.tsx create mode 100644 packages/utils/src/types.ts diff --git a/apps/server/src/models/base/base.service.ts b/apps/server/src/models/base/base.service.ts index 346c314..19fa918 100644 --- a/apps/server/src/models/base/base.service.ts +++ b/apps/server/src/models/base/base.service.ts @@ -451,7 +451,7 @@ export class BaseService< pageSize?: number; where?: WhereArgs; select?: SelectArgs; - }): Promise<{ items: R['findMany']; totalPages: number }> { + }): Promise<{ items: R['findMany']; totalPages: number, totalCount: number }> { const { page = 1, pageSize = 10, where, select } = args; try { @@ -470,6 +470,7 @@ export class BaseService< return { items, totalPages, + totalCount: total }; } catch (error) { this.handleError(error, 'read'); diff --git a/apps/web/package.json b/apps/web/package.json index efe8d7d..379260d 100755 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -34,6 +34,7 @@ "@nice/common": "workspace:^", "@nice/iconer": "workspace:^", "@nice/theme": "workspace:^", + "@nice/utils": "workspace:^", "@nice/ui": "workspace:^", "@tanstack/query-async-storage-persister": "^5.51.9", "@tanstack/react-query": "^5.51.21", diff --git a/apps/web/src/app/main/letter/editor/page.tsx b/apps/web/src/app/main/letter/editor/page.tsx index e2ff2f9..61bd7bc 100644 --- a/apps/web/src/app/main/letter/editor/page.tsx +++ b/apps/web/src/app/main/letter/editor/page.tsx @@ -1,16 +1,19 @@ -import { motion } from "framer-motion"; -import LetterEditorLayout from "@web/src/components/models/post/editor/layout/LetterEditorLayout"; +import { LetterFormProvider } from "@web/src/components/models/post/editor/context/LetterEditorContext"; +import { LetterBasicForm } from "@web/src/components/models/post/editor/form/LetterBasicForm"; +import WriteHeader from "../write/WriteHeader"; +import { useSearchParams } from "react-router-dom"; + +export default function LetterEditorPage() { + const [searchParams] = useSearchParams(); + const receiverId = searchParams.get("receiverId"); + const termId = searchParams.get("termId"); -export default function EditorLetterPage() { return ( -
- - - +
+ + + +
); } diff --git a/apps/web/src/app/main/letter/list/page.tsx b/apps/web/src/app/main/letter/list/page.tsx index e494780..6d9fe18 100644 --- a/apps/web/src/app/main/letter/list/page.tsx +++ b/apps/web/src/app/main/letter/list/page.tsx @@ -1,14 +1,19 @@ +import LetterList from "@web/src/components/models/post/list/LetterList"; import { Header } from "./Header"; export default function LetterListPage() { return ( // 添加 flex flex-col 使其成为弹性布局容器 -
+
{/* 添加 flex-grow 使内容区域自动填充剩余空间 */} - - + +
); } diff --git a/apps/web/src/app/main/letter/write/SendCard.tsx b/apps/web/src/app/main/letter/write/SendCard.tsx index 7483167..3c67a97 100644 --- a/apps/web/src/app/main/letter/write/SendCard.tsx +++ b/apps/web/src/app/main/letter/write/SendCard.tsx @@ -1,37 +1,42 @@ import { motion } from 'framer-motion'; -import { PaperAirplaneIcon } from '@heroicons/react/24/outline'; import { StaffDto } from "@nice/common"; -import { Button } from 'antd'; +import { Button, Tooltip, Badge } from 'antd'; +import { SendOutlined } from '@ant-design/icons'; +import { useNavigate } from 'react-router-dom'; export interface SendCardProps { staff: StaffDto; + termId?: string; } -export function SendCard({ staff }: SendCardProps) { +export function SendCard({ staff, termId }: SendCardProps) { + const navigate = useNavigate(); + + const handleSendLetter = () => { + navigate(`/editor?termId=${termId || ''}&receiverId=${staff.id}`); + }; return (
{/* Image Container */} -
+
{staff.meta?.photoUrl ? ( {staff.showname} ) : (
{/* Content Container */} -
+
-
-

- {staff.showname} -

- - {staff.meta?.rank || '未设置职级'} - +
+
+
+

+ {staff.showname} +

+ +
+

{staff.department?.name || '未设置部门'}

+
+ + + {staff.meta?.rank || '未设置职级'} + +
-

{staff.department?.name || '未设置部门'}

{/* Contact Information */} -
-

- +

+
+ - {staff.meta?.email || '未设置邮箱'} -

-

- + {staff.meta?.email || '未设置邮箱'} +

+
+ - {staff.phoneNumber || '未设置电话'} -

-

- + {staff.phoneNumber || '未设置电话'} +

+
+ - {staff.meta?.office || '未设置办公室'} -

+ {staff.meta?.office || '未设置办公室'} +
diff --git a/apps/web/src/app/main/letter/write/header.tsx b/apps/web/src/app/main/letter/write/WriteHeader.tsx similarity index 93% rename from apps/web/src/app/main/letter/write/header.tsx rename to apps/web/src/app/main/letter/write/WriteHeader.tsx index f072d2b..8d84c6b 100644 --- a/apps/web/src/app/main/letter/write/header.tsx +++ b/apps/web/src/app/main/letter/write/WriteHeader.tsx @@ -1,5 +1,5 @@ -export default function Header() { - return
+export default function WriteHeader() { + return
{/* 主标题 */}
diff --git a/apps/web/src/app/main/letter/write/mock.ts b/apps/web/src/app/main/letter/write/mock.ts deleted file mode 100644 index 1a7ff1d..0000000 --- a/apps/web/src/app/main/letter/write/mock.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Leader } from "./types"; - -export const leaders: Leader[] = [ - { - id: "1", - name: "John Mitchell", - rank: "General", - division: "Air Combat Command", - imageUrl: - "https://th.bing.com/th/id/OIP.ea0spF2OAgI4I1KzgZFtTgHaHX?rs=1&pid=ImgDetMain", - email: "j.mitchell@af.mil", - phone: "(555) 123-4567", - office: "Pentagon, Wing A-123", - }, - { - id: "2", - name: "Sarah Williams", - rank: "Colonel", - division: "Air Force Space Command", - imageUrl: - "https://th.bing.com/th/id/OIP.ea0spF2OAgI4I1KzgZFtTgHaHX?rs=1&pid=ImgDetMain", - }, - { - id: "3", - name: "Michael Roberts", - rank: "Major General", - division: "Air Mobility Command", - imageUrl: - "https://th.bing.com/th/id/OIP.ea0spF2OAgI4I1KzgZFtTgHaHX?rs=1&pid=ImgDetMain", - }, -]; diff --git a/apps/web/src/app/main/letter/write/page.tsx b/apps/web/src/app/main/letter/write/page.tsx index 1ed0640..f4d8c8a 100644 --- a/apps/web/src/app/main/letter/write/page.tsx +++ b/apps/web/src/app/main/letter/write/page.tsx @@ -1,14 +1,18 @@ -import { useState, useMemo, useCallback, useEffect } from 'react'; +import { useState, useCallback, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; -import Header from './header'; +import { useSearchParams } from 'react-router-dom'; + import { SendCard } from './SendCard'; -import { Spin, Empty, Input, Alert, message, Pagination } from 'antd'; +import { Spin, Empty, Input, Alert, 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'; +import WriteHeader from './WriteHeader'; export default function WriteLetterPage() { + const [searchParams] = useSearchParams(); + const termId = searchParams.get('termId'); const [searchQuery, setSearchQuery] = useState(''); const [selectedDept, setSelectedDept] = useState(); const [currentPage, setCurrentPage] = useState(1); @@ -30,19 +34,19 @@ export default function WriteLetterPage() { }] } }); - useEffect(() => { - console.log(selectedDept) - console.log(data) - console.log(searchQuery) - }, [selectedDept, data, searchQuery]) - // Reset to first page when search query or department changes - useCallback(() => { + + const resetPage = useCallback(() => { setCurrentPage(1); - }, [searchQuery, selectedDept]); + }, []); + + // Reset page when search or department changes + useEffect(() => { + resetPage(); + }, [searchQuery, selectedDept, resetPage]); return ( -
-
+
+
{/* Search and Filter Section */} @@ -86,10 +90,11 @@ export default function WriteLetterPage() { animate={{ opacity: 1 }} exit={{ opacity: 0 }} > - {data?.items.map((item) => ( + {data?.items.map((item: any) => ( ))} diff --git a/apps/web/src/app/main/letter/write/types.ts b/apps/web/src/app/main/letter/write/types.ts deleted file mode 100644 index 4d0af62..0000000 --- a/apps/web/src/app/main/letter/write/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface Leader { - id: string; - name: string; - rank: string; - division: string; - imageUrl: string; - email: string; // Added - phone: string; // Added - office: string; // Added -} - - diff --git a/apps/web/src/components/layout/main/useNavItem.ts b/apps/web/src/components/layout/main/useNavItem.ts index d90d947..665c034 100644 --- a/apps/web/src/components/layout/main/useNavItem.ts +++ b/apps/web/src/components/layout/main/useNavItem.ts @@ -23,7 +23,7 @@ export function useNavItem() { // 构建分类导航项 const categoryItems = data.map(term => ({ - to: `/write-letter?category=${term.id}`, + to: `/write-letter?termId=${term.id}`, label: term.name })); diff --git a/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx b/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx index f5327b7..dadb265 100644 --- a/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx +++ b/apps/web/src/components/models/post/editor/form/LetterBasicForm.tsx @@ -1,164 +1,106 @@ import { Form, Input, Button, Checkbox, Select } from "antd"; -import { useState } from "react"; import { useLetterEditor } from "../context/LetterEditorContext"; -import { api } from "@nice/client"; -import { - UserOutlined, - FolderOutlined, - TagOutlined, - FileTextOutlined, -} from "@ant-design/icons"; - +import { SendOutlined } from "@ant-design/icons"; import QuillEditor from "@web/src/components/common/editor/quill/QuillEditor"; -import { PostBadge } from "../../detail/badge/PostBadge"; +import StaffSelect from "../../../staff/staff-select"; +import TermSelect from "../../../term/term-select"; export function LetterBasicForm() { const { onSubmit, receiverId, termId, form } = useLetterEditor(); - const { data: receiver } = api.staff.findFirst.useQuery( - { - where: { - id: receiverId, - }, - }, - { - enabled: !!receiverId, - } - ); - const { data: term } = api.term.findFirst.useQuery( - { - where: { id: termId }, - }, - { enabled: !!termId } - ); - const handleFinish = async (values: any) => { await onSubmit(values); }; - return ( -
+
- {/* 收件人和板块信息行 */} -
-
- -
收件人:{receiver?.showname}
-
- + initialValues={{ meta: { tags: [] }, receiverId, termId, isPublic: true }} + > +
+ + + + + +
+ + - - - 标题 - - (必选) + + /> + + + {/* Tags Input */} + + - -
+ )} + /> + + + {/* Content Editor */} + +
+ form.setFieldValue("content", content)} - {/* 标签输入 */} -
- - - 标签 - - } - name={["meta", "tags"]} - labelCol={{ span: 24 }} - wrapperCol={{ span: 24 }}> - handleSearch(e.target.value)} + prefix={} + /> +
+
+ + {/* Content Area */} +
+ {isLoading ? ( +
+ {[...Array(6)].map((_, index) => ( +
+ ))} +
+ ) : data?.items.length ? ( + <> +
+ {data.items.map((letter: any) => ( + + ))} +
+
+ +
+ + ) : ( +
+ + {searchText ? "未找到相关信件" : "暂无信件"} + + } + + className="flex flex-col items-center" + /> +
+ )} +
+ + +
+ ); +} diff --git a/apps/web/src/components/models/staff/staff-select.tsx b/apps/web/src/components/models/staff/staff-select.tsx index d6721b1..5fa44d6 100644 --- a/apps/web/src/components/models/staff/staff-select.tsx +++ b/apps/web/src/components/models/staff/staff-select.tsx @@ -3,6 +3,7 @@ import { Button, Select, Spin } from "antd"; import type { SelectProps } from "antd"; import { api } from "@nice/client"; import React from "react"; +import { SizeType } from "antd/es/config-provider/SizeContext"; interface StaffSelectProps { value?: string | string[]; onChange?: (value: string | string[]) => void; @@ -10,6 +11,7 @@ interface StaffSelectProps { multiple?: boolean; domainId?: string; placeholder?: string; + size?: SizeType } export default function StaffSelect({ @@ -19,6 +21,7 @@ export default function StaffSelect({ style, multiple, domainId, + size }: StaffSelectProps) { const [keyword, setQuery] = useState(""); @@ -67,6 +70,7 @@ export default function StaffSelect({ return ( <>