|
| 1 | +"use client"; |
| 2 | + |
| 3 | +import React, { useState } from "react"; |
| 4 | +import { useUserProfiles } from "@/components/profile/hooks/useUserProfiles"; |
| 5 | +import { MantineReactTable, MRT_ColumnDef } from "mantine-react-table"; |
| 6 | +import { |
| 7 | + CreateReportRequestDto, |
| 8 | + FindAllProfileResponseItemDto, |
| 9 | +} from "@/wrapper/server"; |
| 10 | +import CenteredLoading from "@/components/general/CenteredLoading"; |
| 11 | +import CenteredErrorMessage from "@/components/general/CenteredErrorMessage"; |
| 12 | +import { Badge, MantineColor, Menu, Modal, Paper } from "@mantine/core"; |
| 13 | +import { useCustomTable } from "@/components/table/hooks/use-custom-table"; |
| 14 | +import { UserAvatarGroup } from "@/components/general/avatar/UserAvatarGroup"; |
| 15 | +import { useDisclosure } from "@mantine/hooks"; |
| 16 | +import ReportCreateForm from "@/components/report/form/ReportCreateForm"; |
| 17 | +import sourceType = CreateReportRequestDto.sourceType; |
| 18 | + |
| 19 | +const columns: MRT_ColumnDef<FindAllProfileResponseItemDto>[] = [ |
| 20 | + { |
| 21 | + accessorKey: "profile.username", |
| 22 | + header: "Username", |
| 23 | + Cell: ({ row }) => { |
| 24 | + return <UserAvatarGroup userId={row.original.profile.userId} />; |
| 25 | + }, |
| 26 | + }, |
| 27 | + { |
| 28 | + accessorFn: (row) => { |
| 29 | + if (row.isSuspended) { |
| 30 | + return "SUSPENDED"; |
| 31 | + } else if (row.isBanned) { |
| 32 | + return "BANNED"; |
| 33 | + } |
| 34 | + return "NORMAL"; |
| 35 | + }, |
| 36 | + header: "Status", |
| 37 | + filterVariant: "select", |
| 38 | + mantineFilterSelectProps: { |
| 39 | + data: [ |
| 40 | + { label: "Normal", value: "NORMAL" }, |
| 41 | + { label: "Suspended", value: "SUSPENDED" }, |
| 42 | + { label: "Banned", value: "BANNED" }, |
| 43 | + ], |
| 44 | + }, |
| 45 | + Cell: ({ row, renderedCellValue }) => { |
| 46 | + const item = row.original; |
| 47 | + const color: MantineColor = |
| 48 | + item.isSuspended || item.isBanned ? "red" : "green"; |
| 49 | + return <Badge color={color}>{renderedCellValue}</Badge>; |
| 50 | + }, |
| 51 | + }, |
| 52 | + { |
| 53 | + header: "Joined at", |
| 54 | + accessorFn: (row) => |
| 55 | + new Date(row.profile.createdAt).toLocaleString("en-US"), |
| 56 | + sortingFn: (rowA, rowB, columnId) => { |
| 57 | + const createDateA = new Date(rowA.original.profile.createdAt); |
| 58 | + const createDateB = new Date(rowB.original.profile.createdAt); |
| 59 | + |
| 60 | + return createDateA.getTime() - createDateB.getTime(); |
| 61 | + }, |
| 62 | + id: "createdAt", |
| 63 | + }, |
| 64 | +]; |
| 65 | + |
| 66 | +const UsersManagementTable = () => { |
| 67 | + const { data, isLoading, isError, isFetching } = useUserProfiles(); |
| 68 | + |
| 69 | + const [reportModalOpened, reportModalUtils] = useDisclosure(); |
| 70 | + |
| 71 | + const [reportedUserId, setReportedUserId] = useState<string | undefined>( |
| 72 | + undefined, |
| 73 | + ); |
| 74 | + |
| 75 | + const table = useCustomTable<FindAllProfileResponseItemDto>({ |
| 76 | + columns, |
| 77 | + data: data ?? [], |
| 78 | + rowCount: data?.length ?? 0, |
| 79 | + state: { |
| 80 | + isLoading: isLoading, |
| 81 | + showAlertBanner: isError, |
| 82 | + showProgressBars: isFetching, |
| 83 | + }, |
| 84 | + enableRowActions: true, |
| 85 | + renderRowActionMenuItems: (item) => { |
| 86 | + const profile = item.row.original.profile; |
| 87 | + return ( |
| 88 | + <> |
| 89 | + <Menu.Item |
| 90 | + onClick={() => { |
| 91 | + setReportedUserId(profile.userId); |
| 92 | + reportModalUtils.open(); |
| 93 | + }} |
| 94 | + > |
| 95 | + Generate report |
| 96 | + </Menu.Item> |
| 97 | + </> |
| 98 | + ); |
| 99 | + }, |
| 100 | + }); |
| 101 | + |
| 102 | + if (isLoading) { |
| 103 | + return <CenteredLoading message="Loading..." />; |
| 104 | + } else if (isError) { |
| 105 | + return ( |
| 106 | + <CenteredErrorMessage |
| 107 | + message={"Failed to load users. Please try again."} |
| 108 | + /> |
| 109 | + ); |
| 110 | + } else if (data == undefined) { |
| 111 | + return null; |
| 112 | + } |
| 113 | + |
| 114 | + return ( |
| 115 | + <Paper withBorder radius="md" p="md" mt="lg"> |
| 116 | + <Modal |
| 117 | + title={"Generate report"} |
| 118 | + opened={reportModalOpened} |
| 119 | + onClose={reportModalUtils.close} |
| 120 | + > |
| 121 | + {reportedUserId && ( |
| 122 | + <ReportCreateForm |
| 123 | + sourceId={reportedUserId} |
| 124 | + sourceType={sourceType.PROFILE} |
| 125 | + onSuccess={reportModalUtils.close} |
| 126 | + /> |
| 127 | + )} |
| 128 | + </Modal> |
| 129 | + <MantineReactTable table={table} /> |
| 130 | + </Paper> |
| 131 | + ); |
| 132 | +}; |
| 133 | + |
| 134 | +export default UsersManagementTable; |
0 commit comments