diff --git a/frontend/src/app/(main)/dashboard/page.tsx b/frontend/src/app/(main)/dashboard/page.tsx index 898acda2..fe8405bc 100644 --- a/frontend/src/app/(main)/dashboard/page.tsx +++ b/frontend/src/app/(main)/dashboard/page.tsx @@ -23,57 +23,68 @@ const DashboardContent: React.FC = () => { const bottomLeftRef = useRef(null); const bottomRightRef = useRef(null); + const { summary, isSummaryLoading } = useEmissionSummary(); + // Function to adjust heights + useEffect(() => { + // Function to adjust heights const adjustHeights = () => { + // Only adjust on desktop layout + if (window.innerWidth < 1024) return; + // Reset heights before recalculating if (topLeftRef.current) topLeftRef.current.style.height = "auto"; if (topRightRef.current) topRightRef.current.style.height = "auto"; if (bottomLeftRef.current) bottomLeftRef.current.style.height = "auto"; if (bottomRightRef.current) bottomRightRef.current.style.height = "auto"; - // Wait for next frame to ensure heights have been reset + // Use requestAnimationFrame to ensure DOM has updated requestAnimationFrame(() => { - // Adjust only on desktop layout - if (window.innerWidth >= 1024) { - // lg breakpoint - // Adjust top row - if (topLeftRef.current && topRightRef.current) { - const height = Math.max( - topLeftRef.current.scrollHeight, - topRightRef.current.scrollHeight - ); - topLeftRef.current.style.height = `${height}px`; - topRightRef.current.style.height = `${height}px`; - } - - // Adjust bottom row - if (bottomLeftRef.current && bottomRightRef.current) { - const height = Math.max( - bottomLeftRef.current.scrollHeight, - bottomRightRef.current.scrollHeight - ); - bottomLeftRef.current.style.height = `${height}px`; - bottomRightRef.current.style.height = `${height}px`; - } + // Adjust top row + if (topLeftRef.current && topRightRef.current) { + const height = Math.max( + topLeftRef.current.scrollHeight, + topRightRef.current.scrollHeight + ); + topLeftRef.current.style.height = `${height}px`; + topRightRef.current.style.height = `${height}px`; + } + + // Adjust bottom row + if (bottomLeftRef.current && bottomRightRef.current) { + const height = Math.max( + bottomLeftRef.current.scrollHeight, + bottomRightRef.current.scrollHeight + ); + bottomLeftRef.current.style.height = `${height}px`; + bottomRightRef.current.style.height = `${height}px`; } }); }; - // Initial adjustment with a slight delay to ensure components are fully rendered - const timer = setTimeout(adjustHeights, 100); + // Run adjustment when component mounts with a longer delay + const initialTimer = setTimeout(adjustHeights, 700); - // Adjust on window resize - window.addEventListener("resize", adjustHeights); + // Run again after data is likely loaded + const dataLoadedTimer = setTimeout(adjustHeights, 2000); + + // Adjust on window resize (debounced to prevent excessive calls) + let resizeTimer: NodeJS.Timeout; + const handleResize = () => { + clearTimeout(resizeTimer); + resizeTimer = setTimeout(adjustHeights, 100); + }; + + window.addEventListener("resize", handleResize); // Cleanup return () => { - clearTimeout(timer); - window.removeEventListener("resize", adjustHeights); + clearTimeout(initialTimer); + clearTimeout(dataLoadedTimer); + window.removeEventListener("resize", handleResize); }; - }, []); - - const { summary, isSummaryLoading } = useEmissionSummary(); + }, [summary, dateRange]); return (
diff --git a/frontend/src/components/contacts/ContactDetailsColumns.tsx b/frontend/src/components/contacts/ContactDetailsColumns.tsx index f056aa93..619f2692 100644 --- a/frontend/src/components/contacts/ContactDetailsColumns.tsx +++ b/frontend/src/components/contacts/ContactDetailsColumns.tsx @@ -35,7 +35,7 @@ const scopeColumn: ColumnDef = { const co2Column: ColumnDef = { accessorKey: "co2", header: ({ column }) => { - return ; + return ; }, cell: ({ row }) => { const value = row.getValue("co2") as number; diff --git a/frontend/src/components/contacts/ContactDetailsContent.tsx b/frontend/src/components/contacts/ContactDetailsContent.tsx index c1187e4b..6b068dcc 100644 --- a/frontend/src/components/contacts/ContactDetailsContent.tsx +++ b/frontend/src/components/contacts/ContactDetailsContent.tsx @@ -392,15 +392,15 @@ export default function ContactDetailsContent() {

{summary.totalOffsetTransactions}

-

Reconciled Emissions

-

- {formatNumber(summary.totalEmissions)} Kg CO2 +

Reconciled Emissions

+

+ {formatNumber(summary.totalEmissions)} kg CO2e

Offset Emissions

-

- {summary.totalOffset.toFixed(0)} Kg CO2 +

+ {formatNumber(summary.totalOffset, "0")} kg CO2e

diff --git a/frontend/src/components/contacts/ContactLineItemTable.tsx b/frontend/src/components/contacts/ContactLineItemTable.tsx index 75c3fab6..13d0fd9e 100644 --- a/frontend/src/components/contacts/ContactLineItemTable.tsx +++ b/frontend/src/components/contacts/ContactLineItemTable.tsx @@ -20,14 +20,21 @@ import { import { ChevronRight } from "lucide-react"; import { LineItem } from "@/types"; import { ModalDialog } from "@/components/transactions/ModalDialog"; -import { reconciledColumns, offsetColumns, unreconciledColumns } from "./ContactDetailsColumns"; +import { + reconciledColumns, + offsetColumns, + unreconciledColumns, +} from "./ContactDetailsColumns"; interface ContactLineItemTableProps { data: LineItem[]; tableType: "reconciled" | "unreconciled" | "offsets"; } -export function ContactLineItemTable({ data, tableType }: ContactLineItemTableProps) { +export function ContactLineItemTable({ + data, + tableType, +}: ContactLineItemTableProps) { const [sorting, setSorting] = useState([]); const [selectedRow, setSelectedRow] = useState | null>(null); const [isDialogOpen, setIsDialogOpen] = useState(false); @@ -64,7 +71,7 @@ export function ContactLineItemTable({ data, tableType }: ContactLineItemTablePr <>
- + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( @@ -77,14 +84,18 @@ export function ContactLineItemTable({ data, tableType }: ContactLineItemTablePr )} ))} - {/* Empty header for action column */} + + {/* Empty header for action column */} ))} {table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => ( - + {row.getVisibleCells().map((cell) => ( {flexRender( @@ -126,4 +137,4 @@ export function ContactLineItemTable({ data, tableType }: ContactLineItemTablePr )} ); -} \ No newline at end of file +} diff --git a/frontend/src/components/contacts/ContactTable.tsx b/frontend/src/components/contacts/ContactTable.tsx index 862a5ee6..f4e57e74 100644 --- a/frontend/src/components/contacts/ContactTable.tsx +++ b/frontend/src/components/contacts/ContactTable.tsx @@ -63,7 +63,7 @@ export default function ContactTable() { <>
- + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { diff --git a/frontend/src/components/dashboard/GrossEmissionsBarGraph.tsx b/frontend/src/components/dashboard/GrossEmissionsBarGraph.tsx index 7aff6e26..0fcf527e 100644 --- a/frontend/src/components/dashboard/GrossEmissionsBarGraph.tsx +++ b/frontend/src/components/dashboard/GrossEmissionsBarGraph.tsx @@ -64,8 +64,8 @@ export default function GrossEmissionsBarGraph() { Gross Emissions - - {totalEmissions || 0} kg + + {totalEmissions || 0} kg CO₂e Total emissions (kg) for{" "} diff --git a/frontend/src/components/dashboard/NetEmissionsBarGraph.tsx b/frontend/src/components/dashboard/NetEmissionsBarGraph.tsx index 19aacbe9..3f92860d 100644 --- a/frontend/src/components/dashboard/NetEmissionsBarGraph.tsx +++ b/frontend/src/components/dashboard/NetEmissionsBarGraph.tsx @@ -98,8 +98,8 @@ export default function NetEmissionsBarGraph() { Net Emissions - - {totalEmissions || 0} kg + + {totalEmissions || 0} kg CO₂e diff --git a/frontend/src/components/dashboard/TopEmissions.tsx b/frontend/src/components/dashboard/TopEmissions.tsx index 47a0b076..4b009c94 100644 --- a/frontend/src/components/dashboard/TopEmissions.tsx +++ b/frontend/src/components/dashboard/TopEmissions.tsx @@ -55,48 +55,48 @@ export default function TopEmissionsFactors() { {formattedDateRange} - - {emissions && emissions.length > 0 ? ( - emissions.map((factor, index) => ( -
-
- - {factor.rank} - - - {factor.emission_factor} - -
-
- {formatNumber(factor.total_co2)} kg -
-
- )) - ) : ( - [1, 2, 3, 4, 5].map((index) => ( -
-
-
-
+ +
+ {emissions && emissions.length > 0 + ? emissions.map((factor, index) => ( +
+
+ + {factor.rank} + + + {factor.emission_factor} + +
+
+ {formatNumber(factor.total_co2)} kg +
-
-
+ )) + : [1, 2, 3, 4, 5].map((index) => ( +
+
+
+
+
+
+
+
+
+
-
-
-
- )) - )} + ))} +
); diff --git a/frontend/src/components/scope-breakdown/piechart.tsx b/frontend/src/components/scope-breakdown/piechart.tsx index 0d228e59..903403d5 100644 --- a/frontend/src/components/scope-breakdown/piechart.tsx +++ b/frontend/src/components/scope-breakdown/piechart.tsx @@ -39,7 +39,7 @@ const ScopeChart: React.FC<{ ))}
))} diff --git a/frontend/src/components/scope-breakdown/tooltip.tsx b/frontend/src/components/scope-breakdown/tooltip.tsx deleted file mode 100644 index a16526cd..00000000 --- a/frontend/src/components/scope-breakdown/tooltip.tsx +++ /dev/null @@ -1,23 +0,0 @@ -"use client" -import React from "react"; -import { Tooltip } from "recharts"; - -function ToolTip() { - return ( - [ -
-
- {name} -
-
- {`${value.toLocaleString()} kg CO2`} -
-
- ]} - labelFormatter={(label: string) => label} - /> - ); -} - -export default ToolTip; diff --git a/frontend/src/components/transactions/ItemForm.tsx b/frontend/src/components/transactions/ItemForm.tsx index 9f411831..3d89f3c7 100644 --- a/frontend/src/components/transactions/ItemForm.tsx +++ b/frontend/src/components/transactions/ItemForm.tsx @@ -517,7 +517,8 @@ export default function TransactionForm() { render={({ field }) => ( - CO2e Amount (kg) * + CO2e Amount (kg){" "} + * = { id: "select", @@ -136,11 +138,21 @@ const co2Column: ColumnDef = { accessorKey: "co2", header: ({ column }) => { return ( - + ); }, cell: ({ row }) => { diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 4cba1fec..35353625 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -24,8 +24,8 @@ export function formatISOString(date: string) { return `${month}/${day}`; } -export function formatNumber(number?: number) { - if (!number) return ""; +export function formatNumber(number?: number, appendString: string = "") { + if (!number) return appendString; return Number(number?.toFixed()).toLocaleString(); }