From 6b9b7fb7f88b0bad020620ece45bce78de68a010 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 24 Jul 2023 14:42:53 +0100 Subject: [PATCH] Adding property table --- src/app/components/StatusBadge.tsx | 38 ++-- .../[slug]/components/propertyTable.tsx | 90 ++++++++ .../components/propertyTableColumns.tsx | 162 ++++++++++++++ src/app/portfolio/[slug]/page.tsx | 6 + .../shadcn_components/ui/dropdown-menu.tsx | 200 ++++++++++++++++++ src/app/shadcn_components/ui/table.tsx | 114 ++++++++++ 6 files changed, 590 insertions(+), 20 deletions(-) create mode 100644 src/app/portfolio/[slug]/components/propertyTable.tsx create mode 100644 src/app/portfolio/[slug]/components/propertyTableColumns.tsx create mode 100644 src/app/shadcn_components/ui/dropdown-menu.tsx create mode 100644 src/app/shadcn_components/ui/table.tsx diff --git a/src/app/components/StatusBadge.tsx b/src/app/components/StatusBadge.tsx index 3f1ac713..329f1b99 100644 --- a/src/app/components/StatusBadge.tsx +++ b/src/app/components/StatusBadge.tsx @@ -18,27 +18,25 @@ export default function StatusBadge({ const statusConfig = statusColor[status]; return ( -
- - - {statusConfig.text} - - -
-
-
-
-

- {!isProperty - ? statusConfig.hoverText - : statusConfig.propertyHoverText} -

+ + + {statusConfig.text} + + +
+
+
- - -
+

+ {!isProperty + ? statusConfig.hoverText + : statusConfig.propertyHoverText} +

+
+
+
); } diff --git a/src/app/portfolio/[slug]/components/propertyTable.tsx b/src/app/portfolio/[slug]/components/propertyTable.tsx new file mode 100644 index 00000000..2b6bbb25 --- /dev/null +++ b/src/app/portfolio/[slug]/components/propertyTable.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { + ColumnDef, + SortingState, + flexRender, + getCoreRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; + +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/app/shadcn_components/ui/table"; +import { useState } from "react"; + +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export default function DataTable({ + data, + columns, +}: DataTableProps) { + const [sorting, setSorting] = useState([]); + + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + state: { + sorting, + }, + }); + + return ( +
+ + + {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. + + + )} + +
+
+ ); +} diff --git a/src/app/portfolio/[slug]/components/propertyTableColumns.tsx b/src/app/portfolio/[slug]/components/propertyTableColumns.tsx new file mode 100644 index 00000000..c967776c --- /dev/null +++ b/src/app/portfolio/[slug]/components/propertyTableColumns.tsx @@ -0,0 +1,162 @@ +"use client"; + +import { ColumnDef } from "@tanstack/react-table"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/app/shadcn_components/ui/dropdown-menu"; +import { Button } from "@/app/shadcn_components/ui/button"; +import { ArrowUpDown, MoreHorizontal } from "lucide-react"; +import StatusBadge from "@/app/components/StatusBadge"; +import { HomeIcon } from "@heroicons/react/20/solid"; + +export type Property = { + id: number; + portfolioId: number; + address: string; + postcode: string; + loadingStatus: string; + status: string; + targetEpc: string; +}; + +export const columns: ColumnDef[] = [ + { + accessorKey: "address", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const address = String(row.getValue("address")); + const postcode = String(row.original.postcode); + const propertyId = row.original.id; + const portfolioId = row.original.portfolioId; + + return ( + + ); + }, + }, + { + accessorKey: "status", + header: () =>
Status
, + cell: ({ row }) => { + const status = row.getValue("status") ?? ""; + + return ( +
+ {status && } +
+ ); + }, + }, + { + accessorKey: "cost", + header: () =>
Cost
, + cell: ({ row }) => { + const cost = parseFloat(row.getValue("cost")); + + const loadingStatus = row.original.loadingStatus; + console.log("loadingStatus", loadingStatus); + if (loadingStatus === "loading") { + return
; + } + + const formatted = new Intl.NumberFormat("en-UK", { + style: "currency", + currency: "GBP", + }).format(cost); + + return ( +
+ {formatted} +
+ ); + }, + }, + { + accessorKey: "targetEpc", + header: () =>
Target EPC
, + cell: ({ row }) => { + return ( +
+ {row.original.targetEpc} +
+ ); + }, + }, + { + id: "actions", + cell: ({ row }) => { + const property = row.original; + const propertyId = property.id; + const porfolioId = property.portfolioId; + + const loadingStatus = property.loadingStatus; + if (loadingStatus === "loading") { + return ( +
+ Loading... +
+ ); + } + + return ( +
+ + + + + + Actions + navigator.clipboard.writeText(payment.id)} + className="cursor-pointer" + > + + Building Passport + + + + + Delete Property + + + +
+ ); + }, + meta: {}, + }, +]; diff --git a/src/app/portfolio/[slug]/page.tsx b/src/app/portfolio/[slug]/page.tsx index 0d75fa47..5bee4f72 100644 --- a/src/app/portfolio/[slug]/page.tsx +++ b/src/app/portfolio/[slug]/page.tsx @@ -228,16 +228,22 @@ export default async function Page({ properties = [ { id: 1, + portfolioId: portfolioId, address: "123 Fake Street", postcode: "AB1 2CD", loadingStatus: "loading", + status: "assessment", + targetEpc: "C", }, { id: 2, + portfolioId: portfolioId, address: "223 Fake Street", postcode: "AB1 2CD", loadingStatus: "complete", cost: 1000, + status: "assessment", + targetEpc: "C", }, ]; } else { diff --git a/src/app/shadcn_components/ui/dropdown-menu.tsx b/src/app/shadcn_components/ui/dropdown-menu.tsx new file mode 100644 index 00000000..f69a0d64 --- /dev/null +++ b/src/app/shadcn_components/ui/dropdown-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/src/app/shadcn_components/ui/table.tsx b/src/app/shadcn_components/ui/table.tsx new file mode 100644 index 00000000..bb3a87f3 --- /dev/null +++ b/src/app/shadcn_components/ui/table.tsx @@ -0,0 +1,114 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +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) => ( + +)) +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, +}