diff --git a/apps/user/public/assets/locales/en-US/dashboard.json b/apps/user/public/assets/locales/en-US/dashboard.json index d507d96..8ca073d 100644 --- a/apps/user/public/assets/locales/en-US/dashboard.json +++ b/apps/user/public/assets/locales/en-US/dashboard.json @@ -11,6 +11,12 @@ "finished": "Finished", "import": "Import", "latestAnnouncement": "Latest Announcement", + "announcements": "Announcements", + "all": "All", + "pinned": "Pinned", + "pinnedOnly": "Pinned Only", + "popup": "Popup", + "popupOnly": "Popup Only", "manualImportMessage": "Please import manually", "mySubscriptions": "My Subscriptions", "nextResetDays": "Next Reset Days", diff --git a/apps/user/public/assets/locales/zh-CN/dashboard.json b/apps/user/public/assets/locales/zh-CN/dashboard.json index 9c3fbe2..5e573b2 100644 --- a/apps/user/public/assets/locales/zh-CN/dashboard.json +++ b/apps/user/public/assets/locales/zh-CN/dashboard.json @@ -11,6 +11,12 @@ "finished": "已完成", "import": "一键导入", "latestAnnouncement": "最新公告", + "announcements": "公告管理", + "all": "全部", + "pinned": "置顶", + "pinnedOnly": "仅置顶", + "popup": "弹窗", + "popupOnly": "仅弹窗", "manualImportMessage": "请手动导入", "mySubscriptions": "我的订阅", "nextResetDays": "距离下次重置天数", diff --git a/apps/user/src/sections/user/announcement.tsx b/apps/user/src/sections/user/announcement.tsx index 1ddf27b..ed73692 100644 --- a/apps/user/src/sections/user/announcement.tsx +++ b/apps/user/src/sections/user/announcement.tsx @@ -32,7 +32,7 @@ export default function Announcement({ type }: { type: "popup" | "pinned" }) { skipErrorHandler: true, } ); - return result.data.data?.announcements.find((item) => item[type]) || null; + return result.data.data?.announcements?.[0] || null; }, enabled: !!user, }); @@ -44,13 +44,16 @@ export default function Announcement({ type }: { type: "popup" | "pinned" }) { - {data?.title} + {data.title} - {data?.content} + + {data.content} + ); } + if (type === "pinned") { return ( <> @@ -59,9 +62,17 @@ export default function Announcement({ type }: { type: "popup" | "pinned" }) { {t("latestAnnouncement", "Latest Announcement")} - {data?.content ? {data?.content} : } + {data.content ? ( + + {data.content} + + ) : ( + + )} > ); } + + return null; } diff --git a/apps/user/src/sections/user/announcement/index.tsx b/apps/user/src/sections/user/announcement/index.tsx index df52097..c46ecdc 100644 --- a/apps/user/src/sections/user/announcement/index.tsx +++ b/apps/user/src/sections/user/announcement/index.tsx @@ -1,34 +1,133 @@ "use client"; import { useQuery } from "@tanstack/react-query"; -import { Timeline } from "@workspace/ui/components/timeline"; -import Empty from "@workspace/ui/composed/empty"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@workspace/ui/components/card"; +import { + Tabs, + TabsContent, + TabsList, + TabsTrigger, +} from "@workspace/ui/components/tabs"; +import { + ProList, + type ProListActions, +} from "@workspace/ui/composed/pro-list/pro-list"; +import { Icon } from "@workspace/ui/composed/icon"; import { Markdown } from "@workspace/ui/composed/markdown"; import { queryAnnouncement } from "@workspace/ui/services/user/announcement"; +import { formatDate } from "@workspace/ui/utils/formatting"; +import { useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; export default function Announcement() { - const { data } = useQuery({ - queryKey: ["queryAnnouncement"], - queryFn: async () => { - const { data } = await queryAnnouncement({ - page: 1, - size: 99, - pinned: false, - popup: false, - }); - return data.data?.announcements || []; - }, - }); - return data && data.length > 0 ? ( - ({ - title: item.title, - content: {item.content}, - })) || [] - } - /> - ) : ( - + const { t } = useTranslation("dashboard"); + const [activeTab, setActiveTab] = useState("all"); + const pinnedRef = useRef(null); + const normalRef = useRef(null); + + const requestAnnouncements = async ( + pagination: { page: number; size: number }, + filter: { pinned?: boolean; popup?: boolean } + ) => { + const response = await queryAnnouncement({ + ...pagination, + ...filter, + }); + return { + list: response.data.data?.announcements || [], + total: response.data.data?.total || 0, + }; + }; + + const renderAnnouncement = (item: any) => ( + + + + + {item.title} + {item.pinned && ( + + + {t("pinned", "Pinned")} + + )} + {item.popup && ( + + + {t("popup", "Popup")} + + )} + + + + {formatDate(item.created_at)} + + + + + + + {item.content} + + + + ); + + return ( + + + + {t("announcements", "Announcements")} + + + + + {t("all", "All")} + + + {t("pinnedOnly", "Pinned Only")} + + + {t("popupOnly", "Popup Only")} + + + + + { + return requestAnnouncements(pagination, {}); + }} + /> + + + + { + return requestAnnouncements(pagination, { pinned: true }); + }} + /> + + + + { + return requestAnnouncements(pagination, { popup: true }); + }} + /> + + + ); }