From 0759f4216fe9070c633234f6cbbb76c15af9bce4 Mon Sep 17 00:00:00 2001 From: Marco Pedone Date: Tue, 10 Mar 2026 13:57:29 +0100 Subject: [PATCH] feat: add telefono field to UsersTable and user controller for enhanced user information --- .../src/components/custom_ui/data-table.tsx | 38 ++- .../src/components/tables/users-table.tsx | 260 +++++++++--------- .../src/server/controllers/user.controller.ts | 1 + 3 files changed, 166 insertions(+), 133 deletions(-) diff --git a/apps/infoalloggi/src/components/custom_ui/data-table.tsx b/apps/infoalloggi/src/components/custom_ui/data-table.tsx index 74e0f1a..af2f72e 100644 --- a/apps/infoalloggi/src/components/custom_ui/data-table.tsx +++ b/apps/infoalloggi/src/components/custom_ui/data-table.tsx @@ -14,6 +14,7 @@ import { type VisibilityState, } from "@tanstack/react-table"; import { useVirtualizer } from "@tanstack/react-virtual"; +import type React from "react"; import { useEffect, useRef, useState } from "react"; import { DataTablePagination } from "~/components/custom_ui/dataTable-pagination"; import { @@ -30,8 +31,9 @@ import { TableRow, } from "~/components/ui/table"; import { cn } from "~/lib/utils"; +import { ContextMenu, ContextMenuTrigger } from "../ui/context-menu"; -interface DataTableProps { +type DataTableProps = { columns: ColumnDef[]; data: TData[]; pinnedFiltri?: PinnedFiltro[]; @@ -47,7 +49,23 @@ interface DataTableProps { onStateChange?: () => void; defaultFilterState?: ColumnFiltersState; onTableInit?: (table: TableType) => void; -} +} & ( + | { + withContextMenu: true; + + /** + * @example + * + * {data} + * + */ + contextMenuContent: (data: TData) => React.ReactNode; + } + | { + withContextMenu?: false; + contextMenuContent?: never; + } +); export function DataTable({ columns, @@ -65,6 +83,8 @@ export function DataTable({ onStateChange, defaultFilterState, onTableInit, + withContextMenu, + contextMenuContent, }: DataTableProps) { const [sorting, setSorting] = useState(defaultSort || []); const [rowSelection, setRowSelection] = useState({}); @@ -155,7 +175,8 @@ export function DataTable({ virtualizer.getVirtualItems().map((virtualRow, index) => { // biome-ignore lint/style/noNonNullAssertion: const row = rows[virtualRow.index]!; - return ( + + const rowElem = ( ({ })} ); + + if (withContextMenu && contextMenuContent) { + return ( + + {rowElem} + + {contextMenuContent(row.original)} + + ); + } + return rowElem; }) ) : ( diff --git a/apps/infoalloggi/src/components/tables/users-table.tsx b/apps/infoalloggi/src/components/tables/users-table.tsx index e772636..d08a7c4 100644 --- a/apps/infoalloggi/src/components/tables/users-table.tsx +++ b/apps/infoalloggi/src/components/tables/users-table.tsx @@ -3,7 +3,6 @@ import { Crown, Mail, MessagesSquare, - MoreHorizontal, Paperclip, Search, ShoppingBag, @@ -19,23 +18,25 @@ import type { PinnedFiltro, SearchFiltro, } from "~/components/custom_ui/dataTable-toolbar"; -import { Button } from "~/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "~/components/ui/dropdown-menu"; import { UserAvatar } from "~/components/user_avatar"; import { cn } from "~/lib/utils"; import type { Users } from "~/schemas/public/Users"; import { api } from "~/utils/api"; +import { + ContextMenuContent, + ContextMenuItem, + ContextMenuSeparator, +} from "../ui/context-menu"; type UserWChatInfo = Pick< Users, - "id" | "username" | "email" | "isAdmin" | "isBlocked" | "created_at" + | "id" + | "username" + | "email" + | "telefono" + | "isAdmin" + | "isBlocked" + | "created_at" > & { chatid: string | null }; export const UsersTable = (props: { data: UserWChatInfo[] }) => { @@ -51,10 +52,10 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { const tabledata = data.map((user) => { return { - actions: "Azioni", chatid: user.chatid, created_at: user.created_at, email: user.email, + telefono: user.telefono, id: user.id, isAdmin: user.isAdmin ? "Admin" : "Utente", isBanned: user.isBlocked ? "Bloccato" : "Attivo", @@ -68,9 +69,9 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { ]; const columns_titles = { - actions: "Azioni", created_at: "Creato il", email: "Email", + telefono: "Telefono", isAdmin: "Ruolo", isBanned: "Status", username: "User", @@ -111,6 +112,30 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { ), }, + { + accessorKey: "telefono", + header: ({ column }) => ( + + ), + }, + { + accessorKey: "created_at", + cell: ({ row }) => { + const date = row.getValue("created_at"); + return new Date(date as Date).toLocaleDateString(); + }, + enableHiding: false, + header: ({ column }) => ( + + ), + sortingFn: "datetime", + }, { accessorKey: "isAdmin", cell: ({ row }) => { @@ -141,6 +166,7 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { ), }, + { accessorKey: "isBanned", filterFn: (row, id, value) => { @@ -153,123 +179,6 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { /> ), }, - { - accessorKey: "created_at", - cell: ({ row }) => { - const date = row.getValue("created_at"); - return new Date(date as Date).toLocaleDateString(); - }, - enableHiding: false, - header: ({ column }) => ( - - ), - sortingFn: "datetime", - }, - { - accessorKey: "actions", - cell: ({ row }) => { - const user = row.original; - return ( - - - - - - Azioni - - - - Ricerca - - - - - Comunicazioni - - - - - Profilo - - - - - - Ordini - - - - - Allegati - - - - - - Chat - - - - - - - - - ); - }, - enableHiding: false, - enableSorting: false, - header: ({ column }) => ( - - ), - }, ]; const pinnedFiltri: PinnedFiltro[] = [ { @@ -298,10 +207,101 @@ export const UsersTable = (props: { data: UserWChatInfo[] }) => { ( + + + + Ricerca + + + + + Comunicazioni + + + + + Profilo + + + + + + Ordini + + + + + Allegati + + + + + + Chat + + + + + + + + )} data={tabledata} + defaultColumnVisibility={{ + actions: true, + created_at: true, + email: true, + telefono: true, + isAdmin: true, + isBanned: false, + username: true, + }} defaultSort={[{ desc: true, id: "created_at" }]} pinnedFiltri={pinnedFiltri} searchColumn={searchFiltro} + withContextMenu={true} /> ); diff --git a/apps/infoalloggi/src/server/controllers/user.controller.ts b/apps/infoalloggi/src/server/controllers/user.controller.ts index 46014ce..cfc4457 100644 --- a/apps/infoalloggi/src/server/controllers/user.controller.ts +++ b/apps/infoalloggi/src/server/controllers/user.controller.ts @@ -173,6 +173,7 @@ export const getUsersWithChatInfoHandler = async ({ db }: { db: Querier }) => { .select([ "users.id", "users.username", + "users.telefono", "users.email", "users.isAdmin", "users.isBlocked",