From 262f1e76b307730d2ebd34567da879c5f1503fcf Mon Sep 17 00:00:00 2001 From: dominionolonilebi Date: Mon, 22 Jul 2024 16:01:22 +0100 Subject: [PATCH] feat: super admin users page --- .../SuperAdminUsersPage/Users/Table.tsx | 57 ++++++ .../SuperAdminUsersPage/Users/card.tsx | 55 ++++++ .../SuperAdminUsersPage/Users/columns.tsx | 125 +++++++++++++ .../SuperAdminUsersPage/Users/data-table.tsx | 176 ++++++++++++++++++ .../SuperAdminUsersPage/Users/side-bar.tsx | 142 ++++++++++++++ app/components/ui/table.tsx | 117 ++++++++++++ app/routes/users/user.tsx | 28 +++ package-lock.json | 34 ++++ package.json | 1 + 9 files changed, 735 insertions(+) create mode 100644 app/components/SuperAdminUsersPage/Users/Table.tsx create mode 100644 app/components/SuperAdminUsersPage/Users/card.tsx create mode 100644 app/components/SuperAdminUsersPage/Users/columns.tsx create mode 100644 app/components/SuperAdminUsersPage/Users/data-table.tsx create mode 100644 app/components/SuperAdminUsersPage/Users/side-bar.tsx create mode 100644 app/components/ui/table.tsx create mode 100644 app/routes/users/user.tsx diff --git a/app/components/SuperAdminUsersPage/Users/Table.tsx b/app/components/SuperAdminUsersPage/Users/Table.tsx new file mode 100644 index 00000000..ddd28086 --- /dev/null +++ b/app/components/SuperAdminUsersPage/Users/Table.tsx @@ -0,0 +1,57 @@ +import { Payment, columns } from "./columns"; +import { DataTable } from "./data-table"; + +const data: Payment[] = [ + { + id: "728ed52f", + img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_oG6bIjXDj7SK7Oa0TfC4ERFx274A_puT8obuMz-k8MYeUIdkeemDybaytw&s", + name: "Afolabi Olanipekun", + email: "afolabiolanipekun@gmail.com", + phone: "09123456789", + date: "02/07/2024", + status: "active", + }, + { + id: "728ed52f", + img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_oG6bIjXDj7SK7Oa0TfC4ERFx274A_puT8obuMz-k8MYeUIdkeemDybaytw&s", + name: "Adetunji Oluwaseun", + email: "afolabiolanipekun@gmail.com", + phone: "09123456789", + date: "02/07/2024", + status: "inactive", + }, + { + id: "728ed52f", + img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_oG6bIjXDj7SK7Oa0TfC4ERFx274A_puT8obuMz-k8MYeUIdkeemDybaytw&s", + name: "Ifunanya Adedapo", + email: "afolabiolanipekun@gmail.com", + phone: "09123456789", + date: "02/07/2024", + status: "inactive", + }, + { + id: "728ed52f", + img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_oG6bIjXDj7SK7Oa0TfC4ERFx274A_puT8obuMz-k8MYeUIdkeemDybaytw&s", + name: "Busola Igwe", + email: "afolabiolanipekun@gmail.com", + phone: "09123456789", + date: "02/07/2024", + status: "inactive", + }, + { + id: "728ed52f", + img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_oG6bIjXDj7SK7Oa0TfC4ERFx274A_puT8obuMz-k8MYeUIdkeemDybaytw&s", + name: "Moshood Adedayo", + email: "afolabiolanipekun@gmail.com", + phone: "09123456789", + date: "02/07/2024", + status: "active", + }, +]; +export default function UsersTable({ client = "" }) { + return ( +
+ +
+ ); +} diff --git a/app/components/SuperAdminUsersPage/Users/card.tsx b/app/components/SuperAdminUsersPage/Users/card.tsx new file mode 100644 index 00000000..eb71ff23 --- /dev/null +++ b/app/components/SuperAdminUsersPage/Users/card.tsx @@ -0,0 +1,55 @@ +import { MoveUpRight, Package, User } from "lucide-react"; + +export default function UsersCard() { + return ( + <> +
+
+
+
Total Users
+ + +
+
+

4,000

+
+ + +10% from last month + +
+
+
+
+
+
Active Users
+ + +
+
+

1500

+
+ + +20% from last month + +
+
+
+
+
+
Deleted Users
+ + +
+
+

4,000

+
+ + +150% from last month + +
+
+
+
+ + ); +} diff --git a/app/components/SuperAdminUsersPage/Users/columns.tsx b/app/components/SuperAdminUsersPage/Users/columns.tsx new file mode 100644 index 00000000..720c0269 --- /dev/null +++ b/app/components/SuperAdminUsersPage/Users/columns.tsx @@ -0,0 +1,125 @@ +import { ColumnDef } from "@tanstack/react-table"; +import { DotIcon, EllipsisVertical } from "lucide-react"; +import { Button } from "~/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "~/components/ui/dropdown-menu"; + +// interface for your data +export interface Payment { + id: string; + phone: string; + status: "active" | "inactive"; + name: string; + email: string; + img: string; + date: string; +} + +// props interface for the columns +interface PaymentColumnsProps { + client: string; +} + +// column definitions +export const columns = ({ + client, +}: PaymentColumnsProps): ColumnDef[] => [ + { + accessorKey: "name", + header: "Name", + cell: ({ row }) => { + const { name, email, img } = row.original; + + return ( +
+ {img && ( + {name} + )} +
+
{name}
+
{email}
+
+
+ ); + }, + }, + { + accessorKey: "phone", + header: "Phone Number", + }, + { + accessorKey: "date", + header: "Date Created", + }, + { + accessorKey: "status", + header: "Status", + cell: ({ row }) => { + const payment = row.original; + + return ( + <> +
+ + + {payment.status === "active" ? "Active" : "Inactive"} + +
+ + ); + }, + }, + + { + id: "actions", + header: "Action", + cell: ({ row }) => { + const payment = row.original; + + const editData = () => { + // Implement edit functionality here + // Prompt user for new values and update payment data + }; + + const deleteData = () => { + // Implement delete functionality here + // Delete the payment entry + }; + + return ( + + + + + + Actions + Update + Delete + + {client === "premium" && ( + <> + Edit + Delete + + )} + + + ); + }, + }, +]; diff --git a/app/components/SuperAdminUsersPage/Users/data-table.tsx b/app/components/SuperAdminUsersPage/Users/data-table.tsx new file mode 100644 index 00000000..26503ac3 --- /dev/null +++ b/app/components/SuperAdminUsersPage/Users/data-table.tsx @@ -0,0 +1,176 @@ +"use client"; +import * as React from "react"; +import { + ColumnDef, + flexRender, + ColumnFiltersState, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + useReactTable, +} from "@tanstack/react-table"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "~/components/ui/table"; +// import { +// Pagination, +// PaginationContent, +// PaginationEllipsis, +// PaginationItem, +// PaginationLink, +// PaginationNext, +// PaginationPrevious, +// } from "~/components/ui/pagination"; +import { Button } from "~/components/ui/button"; +import { Filter } from "lucide-react"; + +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export function DataTable({ + columns, + data, +}: DataTableProps) { + const [columnFilters, setColumnFilters] = React.useState( + [] + ); + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onColumnFiltersChange: setColumnFilters, + getFilteredRowModel: getFilteredRowModel(), + state: { + columnFilters, + }, + }); + + return ( +
+
+
+

+ Users +

+

+ Manage users & track activities. +

+
+ +
+
+
+ +
+ + table.getColumn("name")?.setFilterValue(event.target.value) + } + type="text" + id="email-address-icon" + className=" border border-gray-300 text-gray-900 text-sm rounded-lg block w-full ps-10 p-2.5 " + /> +
+ +
+
+ +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+
+ {/* + + + + + + 1 + + + + 2 + + + + 3 + + + + + + + + + */} +
+
+ ); +} diff --git a/app/components/SuperAdminUsersPage/Users/side-bar.tsx b/app/components/SuperAdminUsersPage/Users/side-bar.tsx new file mode 100644 index 00000000..b6c777de --- /dev/null +++ b/app/components/SuperAdminUsersPage/Users/side-bar.tsx @@ -0,0 +1,142 @@ +import React from "react"; +import { + AlignJustify, + BookTextIcon, + CircleUserRound, + HomeIcon, + ListCollapseIcon, + MailIcon, + Package, + Settings, + SlidersHorizontalIcon, + Users, +} from "lucide-react"; + +const UserSideBar: React.FC = () => { + return ( + + ); +}; + +export default UserSideBar; diff --git a/app/components/ui/table.tsx b/app/components/ui/table.tsx new file mode 100644 index 00000000..b5f62e42 --- /dev/null +++ b/app/components/ui/table.tsx @@ -0,0 +1,117 @@ +import * as React from "react" + +import { cn } from "app/lib/utils/cn" + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = "Table" + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = "TableHeader" + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = "TableBody" + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0", + className + )} + {...props} + /> +)) +TableFooter.displayName = "TableFooter" + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = "TableRow" + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableHead.displayName = "TableHead" + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableCell.displayName = "TableCell" + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = "TableCaption" + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/app/routes/users/user.tsx b/app/routes/users/user.tsx new file mode 100644 index 00000000..1e05b09c --- /dev/null +++ b/app/routes/users/user.tsx @@ -0,0 +1,28 @@ +import type { MetaFunction } from "@remix-run/node"; +import UsersCard from "~/components/SuperAdminUsersPage/Users/card"; +import UserSideBar from "~/components/SuperAdminUsersPage/Users/side-bar"; +import UsersTable from "~/components/SuperAdminUsersPage/Users/Table"; + + +export const meta: MetaFunction = () => { + return [ + { title: "New Remix App" }, + { name: "description", content: "Welcome to Remix!" }, + ]; +}; + +export default function User() { + return ( +
+
+ +
+
+ + +
+
+
+
+ ); +} diff --git a/package-lock.json b/package-lock.json index a63564e2..a30b7404 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@remix-run/node": "^2.10.3", "@remix-run/react": "^2.10.3", "@remix-run/serve": "^2.10.3", + "@tanstack/react-table": "^8.19.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "isbot": "^4.4.0", @@ -3204,6 +3205,39 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@tanstack/react-table": { + "version": "8.19.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.19.3.tgz", + "integrity": "sha512-MtgPZc4y+cCRtU16y1vh1myuyZ2OdkWgMEBzyjYsoMWMicKZGZvcDnub3Zwb6XF2pj9iRMvm1SO1n57lS0vXLw==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.19.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.19.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.19.3.tgz", + "integrity": "sha512-IqREj9ADoml9zCAouIG/5kCGoyIxPFdqdyoxis9FisXFi5vT+iYfEfLosq4xkU/iDbMcEuAj+X8dWRLvKYDNoQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@types/acorn": { "version": "4.0.6", "dev": true, diff --git a/package.json b/package.json index f406b075..aa2d32a4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@remix-run/node": "^2.10.3", "@remix-run/react": "^2.10.3", "@remix-run/serve": "^2.10.3", + "@tanstack/react-table": "^8.19.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "isbot": "^4.4.0",