From 79aa8c10656df2c6073d3d13cb6451a481d18aa0 Mon Sep 17 00:00:00 2001 From: sijinhui Date: Sun, 24 Mar 2024 18:50:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app/(admin)/admin/ana/page.tsx | 18 ++++++++-------- app/app/(admin)/admin/layout.tsx | 18 ++++++++++++++-- app/app/(admin)/admin/users/page.tsx | 29 ++++++++++++++++++++++++++ app/app/(admin)/components/sidebar.tsx | 28 +++++-------------------- package.json | 3 ++- 5 files changed, 61 insertions(+), 35 deletions(-) create mode 100644 app/app/(admin)/admin/users/page.tsx diff --git a/app/app/(admin)/admin/ana/page.tsx b/app/app/(admin)/admin/ana/page.tsx index 1d5835598..f4def8561 100644 --- a/app/app/(admin)/admin/ana/page.tsx +++ b/app/app/(admin)/admin/ana/page.tsx @@ -1,17 +1,17 @@ import UsageByModel from "./usage-by-model-chart"; import UserByMap from "./user-by-map"; -import { getSession } from "@/lib/auth"; -import { isName, ADMIN_LIST } from "@/lib/auth_list"; -import { redirect } from "next/navigation"; +// import { getSession } from "@/lib/auth"; +// import { isName, ADMIN_LIST } from "@/lib/auth_list"; +// import { redirect } from "next/navigation"; import { Flex } from "antd"; export default async function AdminPage() { - const session = await getSession(); - const name = session?.user?.email || session?.user?.name; - if (!(name && ADMIN_LIST.includes(name))) { - // Replace '/dashboard' with the desired redirect path - redirect("/"); - } + // const session = await getSession(); + // const name = session?.user?.email || session?.user?.name; + // if (!(name && ADMIN_LIST.includes(name))) { + // // Replace '/dashboard' with the desired redirect path + // redirect("/"); + // } return ( <> diff --git a/app/app/(admin)/admin/layout.tsx b/app/app/(admin)/admin/layout.tsx index c60375cf8..a760b9960 100644 --- a/app/app/(admin)/admin/layout.tsx +++ b/app/app/(admin)/admin/layout.tsx @@ -1,6 +1,9 @@ "use client"; -import React, { ReactNode, useState } from "react"; +import { useSession } from "next-auth/react"; +import { redirect } from "next/navigation"; +import { ADMIN_LIST } from "@/lib/auth_list"; +import React, { ReactNode, useEffect, useState } from "react"; import { MenuFoldOutlined, MenuUnfoldOutlined, @@ -15,12 +18,23 @@ const { Header, Sider, Content } = Layout; function MainLayout({ children }: { children: ReactNode }) { // const [theme, setTheme] = useState('dark'); - + const { data, status } = useSession(); + const name = data?.user?.email || data?.user?.name; + // console.log('name', name, data, status) const [collapsed, setCollapsed] = useState(false); const { token: { colorBgContainer, borderRadiusLG, colorBgLayout }, } = theme.useToken(); + // 客户端才执行 + useEffect(() => { + // 用户已登录,且没设置密码 + // if (status === "loading") return; + if (status === "authenticated" && !(name && ADMIN_LIST.includes(name))) { + redirect("/"); + } + // 状态变化时,重新判断 + }, [name, status]); return ( + + + {/*
+
+ + ); +} diff --git a/app/app/(admin)/components/sidebar.tsx b/app/app/(admin)/components/sidebar.tsx index 89c98108a..0287214ba 100644 --- a/app/app/(admin)/components/sidebar.tsx +++ b/app/app/(admin)/components/sidebar.tsx @@ -68,33 +68,15 @@ const SideBar: React.FC = () => { setCurrent(e.key); router.push(e.key); }; - useEffect(() => { - // 如果按钮和路径不相等,那其实应该跳转到按钮的网址 - if (current != pathname) { - router.push(current); - } - }, [current, pathname, router]); // useEffect(() => { - // const handleStart = () => setLoading(true) - // const handleComplete = () => setLoading(false); - // router.events.on('routeChangeStart', handleStart); - // router.events.on('routeChangeComplete', handleStop); - // router.events.on('routeChangeError', handleStop); - // - // return () => { - // router. - // } - // - // }, [router]); + // // 如果按钮和路径不相等,那其实应该跳转到按钮的网址 + // if (current != pathname) { + // router.push(current); + // } + // }, [current, pathname, router]); return ( <> - {/**/}

Date: Tue, 26 Mar 2024 00:32:46 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app/(admin)/admin/users/page.tsx | 19 +-- app/app/(admin)/components/users-table.tsx | 165 +++++++++++++++++++++ app/utils/custom.ts | 6 +- lib/auth_list.ts | 2 +- package.json | 1 + 5 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 app/app/(admin)/components/users-table.tsx diff --git a/app/app/(admin)/admin/users/page.tsx b/app/app/(admin)/admin/users/page.tsx index 7f72c424d..7f3920222 100644 --- a/app/app/(admin)/admin/users/page.tsx +++ b/app/app/(admin)/admin/users/page.tsx @@ -1,28 +1,21 @@ -"use client"; - import { Flex } from "antd"; import prisma from "@/lib/prisma"; -import { Space, Table, Tag } from "antd"; - -const { Column, ColumnGroup } = Table; +import { User } from "@prisma/client"; +import UsersTable from "../../components/users-table"; async function getData() { const users = await prisma.user.findMany(); return users; } export default async function UsersPage() { - const data = await getData(); - console.log("data", data); + const users: User[] = await getData(); + + // console.log("data", data); return ( <> - - {/*
+
); diff --git a/app/app/(admin)/components/users-table.tsx b/app/app/(admin)/components/users-table.tsx new file mode 100644 index 000000000..11ad01c5d --- /dev/null +++ b/app/app/(admin)/components/users-table.tsx @@ -0,0 +1,165 @@ +"use client"; + +import React, { useRef, useState } from "react"; +import { User } from "@prisma/client"; +import { Space, Table, Tag, Input, Button } from "antd"; +import { SearchOutlined } from "@ant-design/icons"; +import type { FilterDropdownProps } from "antd/es/table/interface"; +import type { GetRef, TableColumnsType, TableColumnType } from "antd"; +import Highlighter from "react-highlight-words"; +// 后期考虑删除该依赖 + +const { Column, ColumnGroup } = Table; +import { getCurrentTime } from "@/app/utils/custom"; + +interface UserInterface { + users: User[]; +} +type DataIndex = keyof User; +type InputRef = GetRef; + +function UsersTable({ users }: UserInterface) { + // const data = {} + // console.log('[data]', users) + const [searchText, setSearchText] = useState(""); + const [searchedColumn, setSearchedColumn] = useState(""); + const searchInput = useRef(null); + const handleSearch = ( + selectedKeys: string[], + confirm: FilterDropdownProps["confirm"], + dataIndex: DataIndex, + ) => { + confirm(); + setSearchText(selectedKeys[0]); + setSearchedColumn(dataIndex); + }; + + const handleReset = (clearFilters: () => void) => { + clearFilters(); + setSearchText(""); + }; + + const getColumnSearchProps = ( + dataIndex: DataIndex, + ): TableColumnType => ({ + filterDropdown: ({ + setSelectedKeys, + selectedKeys, + confirm, + clearFilters, + close, + }) => ( +
e.stopPropagation()}> + + setSelectedKeys(e.target.value ? [e.target.value] : []) + } + onPressEnter={() => + handleSearch(selectedKeys as string[], confirm, dataIndex) + } + style={{ marginBottom: 8, display: "block" }} + /> + + + + + + +
+ ), + filterIcon: (filtered: boolean) => ( + + ), + onFilter: (value, record: User) => { + let result = record?.[dataIndex]; + if (result) { + return result + .toString() + .toLowerCase() + .includes((value as string).toLowerCase()); + } + return false; + }, + onFilterDropdownOpenChange: (visible) => { + if (visible) { + setTimeout(() => searchInput.current?.select(), 100); + } + }, + render: (text) => + searchedColumn === dataIndex ? ( + + ) : ( + text + ), + }); + + const columns: TableColumnsType = [ + { title: "Name", dataIndex: "name", ...getColumnSearchProps("name") }, + { + title: "UserName", + dataIndex: "username", + ...getColumnSearchProps("username"), + }, + { title: "Email", dataIndex: "email", ...getColumnSearchProps("email") }, + { + title: "createdAt", + dataIndex: "createdAt", + render: (value) => getCurrentTime(value), + sorter: (a, b) => { + if (a.createdAt < b.createdAt) return 1; + return -1; + }, + }, + { + title: "updatedAt", + dataIndex: "updatedAt", + render: (value) => getCurrentTime(value), + }, + ]; + + return ; +} + +export default UsersTable; diff --git a/app/utils/custom.ts b/app/utils/custom.ts index a6636f7d3..43aba914c 100644 --- a/app/utils/custom.ts +++ b/app/utils/custom.ts @@ -1,5 +1,7 @@ -export function getCurrentTime(): string { - const now = new Date(); +export function getCurrentTime(now?: Date): string { + if (!now) { + const now = new Date(); + } const formatter = new Intl.DateTimeFormat("zh-CN", { timeZone: "Asia/Shanghai", // 设置为中国标准时间 year: "numeric", diff --git a/lib/auth_list.ts b/lib/auth_list.ts index c28ea6df2..5dfd2a68b 100644 --- a/lib/auth_list.ts +++ b/lib/auth_list.ts @@ -1,6 +1,6 @@ export const DENY_LIST: string[] = [ - "suibian", "某某", "张三", "李四", "啊实打实", "官方回复电话", "笑死", "观化听风" + "suibian", "某某", "张三", "李四", "啊实打实", "官方回复电话", "笑死", "观化听风", "null", "undefined", ] export const ADMIN_LIST: string[] = [ "司金辉", "sijinhui", "sijinhui@qq.com", diff --git a/package.json b/package.json index cf35973cc..d555554c5 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "nodemailer": "^6.9.13", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight-words": "^0.20.0", "react-markdown": "^9.0.1", "react-router-dom": "^6.21.3", "rehype-highlight": "^7.0.0", From aa8859b186f8d5a4d529b82a5d86635b9d2b2a77 Mon Sep 17 00:00:00 2001 From: sijinhui Date: Tue, 26 Mar 2024 00:34:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app/(admin)/components/users-table.tsx | 1 - package.json | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app/(admin)/components/users-table.tsx b/app/app/(admin)/components/users-table.tsx index 11ad01c5d..b7c4a3d8b 100644 --- a/app/app/(admin)/components/users-table.tsx +++ b/app/app/(admin)/components/users-table.tsx @@ -9,7 +9,6 @@ import type { GetRef, TableColumnsType, TableColumnType } from "antd"; import Highlighter from "react-highlight-words"; // 后期考虑删除该依赖 -const { Column, ColumnGroup } = Table; import { getCurrentTime } from "@/app/utils/custom"; interface UserInterface { diff --git a/package.json b/package.json index d555554c5..91d625e44 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "@types/node": "^20.11.10", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.7", + "@types/react-highlight-words": "^0.16.7", "@types/react-katex": "^3.0.0", "@types/spark-md5": "^3.0.4", "autoprefixer": "^10.4.17",