From 6f8e7b256edc12613c7c8d77fbd5e0ce69d3119e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 24 Jul 2023 18:42:54 +0100 Subject: [PATCH] Added status filter --- src/app/components/StatusBadge.tsx | 13 +- .../[slug]/components/propertyTable.tsx | 128 +++++++++++------- .../components/propertyTableColumns.tsx | 70 ++++++++-- .../components/propertyTablePagination.tsx | 3 - src/app/portfolio/[slug]/page.tsx | 10 +- 5 files changed, 147 insertions(+), 77 deletions(-) diff --git a/src/app/components/StatusBadge.tsx b/src/app/components/StatusBadge.tsx index 329f1b9..eca9dec 100644 --- a/src/app/components/StatusBadge.tsx +++ b/src/app/components/StatusBadge.tsx @@ -17,6 +17,9 @@ export default function StatusBadge({ }) { const statusConfig = statusColor[status]; + console.log("status"); + console.log(status); + return ( @@ -72,34 +75,34 @@ const statusColor: { hoverText: "This portfolio has begun works", propertyHoverText: "This property has begun works", }, - "completion; status 'on track'": { + "completion; status: on track": { class: "bg-emerald-500 hover:bg-emerald-500", text: "on track", hoverText: "This portfolio is on track to be completed on time", propertyHoverText: "This property is on track to be completed on time", }, - "completion; status 'delayed'": { + "completion; status: delayed": { class: "bg-orange-400 hover:bg-orange-400", text: "delayed", hoverText: "This portfolio is delayed and one or more properties require attention", propertyHoverText: "This property is delayed and requires attention", }, - "completion; status 'at risk'": { + "completion; status: at risk": { class: "bg-red-400 hover:bg-red-400", text: "at risk", hoverText: "This portfolio is at risk. One or more properties require attention", propertyHoverText: "This property is at risk and requires attention", }, - "completion; status 'completed'": { + "completion; status: completed": { class: "bg-gray-400 hover:bg-gray-400", text: "completed", hoverText: "This portfolio has been completed", propertyHoverText: "This property has been completed", }, "needs review": { - class: "bg-emerald-300 hover:bg-emerald-300", + class: "bg-indigo-600 hover:bg-indigo-400", text: "needs review", hoverText: "The works in this portfolio has been completed and need review", propertyHoverText: "The works on this property have been completed", diff --git a/src/app/portfolio/[slug]/components/propertyTable.tsx b/src/app/portfolio/[slug]/components/propertyTable.tsx index 730cc61..403fd22 100644 --- a/src/app/portfolio/[slug]/components/propertyTable.tsx +++ b/src/app/portfolio/[slug]/components/propertyTable.tsx @@ -2,9 +2,11 @@ import { ColumnDef, + ColumnFiltersState, SortingState, flexRender, getCoreRowModel, + getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable, @@ -22,6 +24,7 @@ import { useState } from "react"; import { DataTablePagination } from "./propertyTablePagination"; import { Property } from "./propertyTableColumns"; import React from "react"; +import { Input } from "@/app/shadcn_components/ui/input"; interface DataTableProps { columns: ColumnDef[]; @@ -55,6 +58,9 @@ export default function DataTable({ const [tableData, setTableData] = useState(data); const [offset, setOffset] = useState(0); const [currentPageIndex, setCurrentPageIndex] = useState(0); + const [columnFilters, setColumnFilters] = React.useState( + [] + ); // add page change handlers for DataTablePagination const loadPaginatedData = () => { @@ -76,63 +82,85 @@ export default function DataTable({ onSortingChange: setSorting, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), - + onColumnFiltersChange: setColumnFilters, + getFilteredRowModel: getFilteredRowModel(), state: { sorting, pagination: { pageIndex: currentPageIndex, pageSize: 7 }, + columnFilters, }, }); 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())} - - ))} + <> +
+ + table.getColumn("address")?.setFilterValue(event.target.value) + } + className="max-w-sm" + /> +
+
+
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext() + )} + + ); + })} - )) - ) : ( - - - No results. - - - )} - -
- -
+ ))} + + + {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 index f30f166..0b1b357 100644 --- a/src/app/portfolio/[slug]/components/propertyTableColumns.tsx +++ b/src/app/portfolio/[slug]/components/propertyTableColumns.tsx @@ -1,6 +1,6 @@ "use client"; -import { ColumnDef } from "@tanstack/react-table"; +import { Column, ColumnDef } from "@tanstack/react-table"; import { DropdownMenu, DropdownMenuContent, @@ -13,7 +13,10 @@ 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"; +import { FunnelIcon } from "@heroicons/react/24/outline"; import { formatNumber } from "@/app/utils"; +import { cn } from "@/lib/utils"; +import { PortfolioStatus } from "@/app/db/schema/portfolio"; export type Property = { id: number; @@ -26,6 +29,51 @@ export type Property = { cost: number; }; +interface DataTableColumnHeaderProps + extends React.HTMLAttributes { + column: Column; + title: string; +} + +export function DataTableFilterHeader({ + column, + title, + className, +}: DataTableColumnHeaderProps) { + if (!column.getCanSort()) { + return
{title}
; + } + + return ( +
+ + + + + + {PortfolioStatus.map((status) => ( + { + column.setFilterValue(status); + }} + > + {} + + ))} + + +
+ ); +} + export const columns: ColumnDef[] = [ { accessorKey: "address", @@ -64,7 +112,14 @@ export const columns: ColumnDef[] = [ }, { accessorKey: "status", - header: () =>
Status
, + // header: () =>
Status
, + header: ({ column }) => { + return ( +
+ +
+ ); + }, cell: ({ row }) => { const status = row.getValue("status") ?? ""; @@ -144,17 +199,11 @@ export const columns: ColumnDef[] = [ - + Settings - + Delete Property @@ -162,6 +211,5 @@ export const columns: ColumnDef[] = [ ); }, - meta: {}, }, ]; diff --git a/src/app/portfolio/[slug]/components/propertyTablePagination.tsx b/src/app/portfolio/[slug]/components/propertyTablePagination.tsx index 3506ecf..4906793 100644 --- a/src/app/portfolio/[slug]/components/propertyTablePagination.tsx +++ b/src/app/portfolio/[slug]/components/propertyTablePagination.tsx @@ -54,7 +54,6 @@ export function DataTablePagination({ className="hidden h-8 w-8 p-0 lg:flex" onClick={() => { setCurrentPageIndex(0); - // table.setPageIndex(0); }} disabled={!table.getCanPreviousPage()} > @@ -66,7 +65,6 @@ export function DataTablePagination({ className="h-8 w-8 p-0" onClick={() => { setCurrentPageIndex(currentPageIndex - 1); - // table.previousPage(); }} disabled={!table.getCanPreviousPage()} > @@ -79,7 +77,6 @@ export function DataTablePagination({ onClick={() => { requestMoreData(); setCurrentPageIndex(currentPageIndex + 1); - // table.nextPage(); }} disabled={!table.getCanNextPage()} > diff --git a/src/app/portfolio/[slug]/page.tsx b/src/app/portfolio/[slug]/page.tsx index 46405dc..1d3e545 100644 --- a/src/app/portfolio/[slug]/page.tsx +++ b/src/app/portfolio/[slug]/page.tsx @@ -1,10 +1,4 @@ -import { PencilSquareIcon, HomeIcon } from "@heroicons/react/24/outline"; -import { formatNumber } from "@/app/utils"; -import Link from "next/link"; -import { ArrowRightCircleIcon } from "@heroicons/react/20/solid"; -import { Badge } from "@/app/shadcn_components/ui/badge"; -import type { PortfolioStatus } from "@/app/db/schema/portfolio"; -import StatusBadge from "@/app/components/StatusBadge"; +import { HomeIcon } from "@heroicons/react/24/outline"; import { getPortfolio } from "./utils"; import { Toolbar } from "@/app/components/portfolio/Toolbar"; import DataTable from "@/app/portfolio/[slug]/components/propertyTable"; @@ -95,7 +89,7 @@ function SummaryBox({ const energySavingsFormatted = formatKwh(energySavings); return ( -
+

Portfolio Summary