feat: 完成代码编写
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
'use client';
|
||||
|
||||
import { queryAnnouncement } from '@/services/user/announcement';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import {
|
||||
ColumnFiltersState,
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getPaginationRowModel,
|
||||
PaginationState,
|
||||
useReactTable,
|
||||
} from '@tanstack/react-table';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@workspace/airo-ui/components/dialog';
|
||||
import { Pagination } from '@workspace/airo-ui/custom-components/pro-table/pagination';
|
||||
import { useImperativeHandle, useRef, useState } from 'react';
|
||||
import { Popup, PopupData, PopupRef } from './Popup';
|
||||
|
||||
export interface AnnouncementItem {
|
||||
id: number;
|
||||
title: string;
|
||||
content: string;
|
||||
pinned?: boolean;
|
||||
}
|
||||
|
||||
export interface DialogRef {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
interface DialogProps {
|
||||
ref?: React.Ref<DialogRef>;
|
||||
}
|
||||
|
||||
export const AnnouncementDialog = ({ ref }: DialogProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [pagination, setPagination] = useState<PaginationState>({
|
||||
pageIndex: 0,
|
||||
pageSize: 10,
|
||||
});
|
||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
||||
const popupRef = useRef<PopupRef>(null);
|
||||
|
||||
const { data: announcementData, isLoading } = useQuery({
|
||||
queryKey: ['queryAnnouncement', pagination.pageIndex + 1, pagination.pageSize],
|
||||
queryFn: async () => {
|
||||
const { data } = await queryAnnouncement({
|
||||
page: pagination.pageIndex + 1,
|
||||
size: pagination.pageSize,
|
||||
pinned: true,
|
||||
popup: true,
|
||||
});
|
||||
return {
|
||||
list: data.data?.announcements || [],
|
||||
total: data.data?.total || 0,
|
||||
};
|
||||
},
|
||||
enabled: open, // 只在弹窗打开时查询数据
|
||||
});
|
||||
|
||||
const table = useReactTable({
|
||||
data: announcementData?.list || [],
|
||||
columns: [],
|
||||
onPaginationChange: setPagination,
|
||||
onColumnFiltersChange: setColumnFilters,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
state: {
|
||||
columnFilters,
|
||||
pagination,
|
||||
},
|
||||
manualPagination: true,
|
||||
manualFiltering: true,
|
||||
rowCount: announcementData?.total || 0,
|
||||
});
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => {
|
||||
setOpen(false);
|
||||
},
|
||||
}));
|
||||
|
||||
const handleOpenPopup = (item: AnnouncementItem) => {
|
||||
const popupData: PopupData = {
|
||||
title: item.title,
|
||||
content: item.content,
|
||||
};
|
||||
popupRef.current?.open(popupData);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className='flex flex-col sm:grid sm:max-w-[600px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle className={'text-left text-2xl sm:text-4xl'}>网站公告</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className='space-y-4'>
|
||||
{isLoading ? (
|
||||
<div className='py-8 text-center'>加载中...</div>
|
||||
) : (
|
||||
<>
|
||||
{announcementData?.list?.map((item: AnnouncementItem) => {
|
||||
return (
|
||||
<div
|
||||
key={item.id}
|
||||
className='flex items-center rounded-[20px] bg-[#B5C9E2] px-4 py-2 sm:p-4'
|
||||
>
|
||||
<p className='line-clamp-2 flex-1 text-[10px] text-[#225BA9] sm:text-sm'>
|
||||
{item.pinned && '【置顶公告】'}{' '}
|
||||
<span className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'}`}>
|
||||
{item.content}
|
||||
</span>
|
||||
</p>
|
||||
<div className='ml-2 w-[65px] text-right'>
|
||||
<span
|
||||
className='cursor-pointer text-xs text-[#225BA9] sm:text-sm'
|
||||
onClick={() => handleOpenPopup(item)}
|
||||
>
|
||||
查看详情
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* 使用 table 的分页器组件 */}
|
||||
{announcementData && announcementData.list && announcementData.list.length > 0 && (
|
||||
<div className='mt-6'>
|
||||
<Pagination
|
||||
table={table}
|
||||
text={{
|
||||
textRowsPerPage: '每页显示',
|
||||
textPageOf: (pageIndex, pageCount) =>
|
||||
`第 ${pageIndex} 页,共 ${pageCount} 页`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Popup ref={popupRef} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@workspace/airo-ui/components/dialog';
|
||||
import { Markdown } from '@workspace/ui/custom-components/markdown';
|
||||
import { useImperativeHandle, useState } from 'react';
|
||||
|
||||
export interface PopupData {
|
||||
title: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface PopupRef {
|
||||
open: (data: PopupData) => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
interface PopupProps {
|
||||
ref?: React.Ref<PopupRef>;
|
||||
}
|
||||
|
||||
export const Popup = ({ ref }: PopupProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [data, setData] = useState<PopupData>({ title: '', content: '' });
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: (newData: PopupData) => {
|
||||
setData(newData);
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => {
|
||||
setOpen(false);
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className='max-h-[350px] min-h-[220px] max-w-[80%] rounded-[25px] sm:max-w-[425px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle className={'sr-only'}>{data.title}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className={'pt-[30%]'}>
|
||||
<div className={'mb-4 text-xl'}>{data.title}</div>
|
||||
<Markdown>{data.content}</Markdown>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user