feat: 修改样式

This commit is contained in:
2025-08-13 19:19:22 -07:00
parent 1b9e97ab3c
commit 4606412e68
13 changed files with 87 additions and 439 deletions
@@ -1,85 +1,31 @@
'use client';
import { Empty } from '@/components/empty';
import { ProList } from '@/components/pro-list';
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 { useTranslations } from 'next-intl';
import { useImperativeHandle, useRef, useState } from 'react';
import { Popup, PopupData, PopupRef } from './Popup';
import { Popup } from './Popup';
export interface AnnouncementItem {
id: number;
title: string;
content: string;
pinned?: boolean;
}
export interface DialogRef {
export interface AnnouncementDialogRef {
open: () => void;
close: () => void;
}
interface DialogProps {
ref?: React.Ref<DialogRef>;
interface AnnouncementDialogProps {
ref?: React.Ref<AnnouncementDialogRef>;
}
export const AnnouncementDialog = ({ ref }: DialogProps) => {
const t = useTranslations('dashboard');
export const AnnouncementDialog = ({ ref }: AnnouncementDialogProps) => {
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,
});
const t = useTranslations('dashboard');
const popupRef = useRef(null);
useImperativeHandle(ref, () => ({
open: () => {
@@ -90,73 +36,58 @@ export const AnnouncementDialog = ({ ref }: DialogProps) => {
},
}));
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'}>
{t('announcementTitle')}
</DialogTitle>
</DialogHeader>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className='overflow-y-auto sm:max-w-[800px]'>
<DialogHeader>
<DialogTitle className='text-left text-2xl sm:text-4xl'>
{t('announcementTitle')}
</DialogTitle>
</DialogHeader>
<div className='space-y-4'>
{isLoading ? (
<div className='py-8 text-center'>{t('loading')}</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'
<div className='mt-6'>
<ProList<API.Announcement, Record<string, unknown>>
request={async (pagination, filter) => {
const response = await queryAnnouncement({
...pagination,
...filter,
pinned: false,
popup: false,
});
return {
list: response.data.data?.announcements || [],
total: response.data.data?.total || 0,
};
}}
renderItem={(item) => {
return (
<div
className={`${item.pinned ? 'bg-[#B5C9E2]' : 'bg-white'} flex items-center rounded-[20px] px-4 py-2 shadow-[0_0_4.5px_0_rgba(0,0,0,0.25)]`}
>
<p
className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'} line-clamp-2 flex-1 text-[10px] sm:text-sm`}
>
{item.pinned && (
<span className={'text-[#225BA9]'}>{t('pinnedAnnouncement')}</span>
)}
<span>{item.content}</span>
</p>
<div className='ml-2 w-[65px] text-right'>
<span
className='cursor-pointer text-xs text-[#225BA9] sm:text-sm'
onClick={() => popupRef.current?.open(item)}
>
<p className='line-clamp-2 flex-1 text-[10px] text-[#225BA9] sm:text-sm'>
{item.pinned && t('pinnedAnnouncement')}{' '}
<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)}
>
{t('viewDetails')}
</span>
</div>
</div>
);
})}
{/* 使用 table 的分页器组件 */}
{announcementData && announcementData.list && announcementData.list.length > 0 && (
<div className='mt-6'>
<Pagination
table={table}
text={{
textRowsPerPage: t('rowsPerPage'),
textPageOf: (pageIndex, pageCount) =>
t('pageOf', { pageIndex: pageIndex, pageCount: pageCount }),
}}
/>
{t('viewDetails')}
</span>
</div>
)}
</>
)}
</div>
</DialogContent>
</Dialog>
<Popup ref={popupRef} />
</>
</div>
);
}}
empty={<Empty />}
/>
</div>
<Popup ref={popupRef} />
</DialogContent>
</Dialog>
);
};
@@ -65,8 +65,8 @@ export default function Content() {
const { data } = await queryAnnouncement({
page: 1,
size: 4,
pinned: true,
popup: true,
pinned: false,
popup: false,
});
return data.data?.announcements || [];
},
@@ -246,12 +246,16 @@ export default function Content() {
{/* 置顶公告 */}
{announcementData?.map((item) => {
return (
<div 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 && t('pinnedAnnouncement')}{' '}
<span className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'}`}>
{item.content}
</span>
<div
className={`${item.pinned ? 'bg-[#B5C9E2]' : 'bg-white'} flex items-center rounded-[20px] px-4 py-2`}
>
<p
className={`${item.pinned ? 'text-white' : 'text-[#4D4D4D]'} line-clamp-2 flex-1 text-[10px] sm:text-sm`}
>
{item.pinned && (
<span className={'text-[#225BA9]'}>{t('pinnedAnnouncement')}</span>
)}
<span>{item.content}</span>
</p>
<div className='ml-2 w-[65px] text-right'>
<span
+2 -3
View File
@@ -41,8 +41,8 @@ export async function generateMetadata(): Promise<Metadata> {
const defaultMetadata = {
title: {
default: site?.site_name || `PPanel`,
template: `%s | ${site?.site_name || 'PPanel'}`,
default: site?.site_name || `airoPort`,
template: `%s | ${site?.site_name || 'airoPort'}`,
},
description: site?.site_desc || '',
keywords: site?.keywords || '',
@@ -60,7 +60,6 @@ export async function generateMetadata(): Promise<Metadata> {
],
apple: site?.site_logo || '/apple-touch-icon.png',
},
manifest: '/site.webmanifest',
};
return defaultMetadata;
}