Added kwh and co2 to building passport

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-29 12:58:48 +00:00
parent 3b259d7611
commit 4df0276829
7 changed files with 78 additions and 32 deletions

View file

@ -30,6 +30,14 @@ export async function GET(
updatedAt: true,
},
where: eq(property.id, BigInt(propertyId)),
with: {
detailsEpc: {
columns: {
adjustedEnergyConsumption: true,
co2Emissions: true,
},
},
},
});
return new NextResponse(JSON.stringify(propertyMeta, serializeBigInt));

View file

@ -1,11 +1,17 @@
import { getEpcColorClass } from "@/app/utils";
export default function EpcCard({
epcRating,
fullMargin = true,
expected = false,
kwh = null,
carbon = null,
}: {
epcRating: string;
fullMargin: boolean;
expected?: boolean;
kwh?: number | null;
carbon?: number | null;
}) {
let marginClass = "";
if (fullMargin) {
@ -13,24 +19,42 @@ export default function EpcCard({
}
let title;
let bgStyling;
if (expected) {
title = "Expected Energy Rating";
bgStyling = "bg-green-600";
} else {
title = "Energy Rating";
bgStyling = "bg-brandblue";
}
const bgColour = getEpcColorClass(epcRating);
return (
<div
className={
"flex flex-col items-center p-4 shadow rounded-md max-w-xl justify-start text-gray-100 " +
bgStyling
bgColour
}
>
<div className="text-xl font-bold mb-4 text-center">{title}</div>
<div className="text-6xl font-bold">{epcRating}</div>
<div className="text-6xl font-bold ">{epcRating}</div>
{(kwh || carbon) && (
<table className="mt-6 text-sm">
<tbody>
{kwh && (
<tr>
<td className="text-gray-50 pr-2 py-1">Energy:</td>
<td className="text-gray-50">{kwh.toFixed(0)} kWh</td>
</tr>
)}
{carbon && (
<tr>
<td className="text-gray-50 pr-2 py-1">CO2:</td>
<td className="text-gray-50">{carbon}t</td>
</tr>
)}
</tbody>
</table>
)}
</div>
);
}

View file

@ -31,6 +31,10 @@ export interface PropertyMeta {
currentEpcRating: string;
currentSapPoints: number;
updatedAt: string;
detailsEpc: {
adjustedEnergyConsumption: number | null;
co2Emissions: number | null;
};
}
export type Rating = "Very good" | "Good" | "Poor" | "Very poor" | "N/A";

View file

@ -1,7 +1,7 @@
// This script contains ALL relations for the database, used by drizzle-orm
import { relations } from "drizzle-orm";
import { property, propertyTargets } from "./property";
import { property, propertyDetailsEpc, propertyTargets } from "./property";
import {
plan,
planRecommendations,
@ -77,6 +77,10 @@ export const propertyRelations = relations(property, ({ one, many }) => ({
references: [propertyTargets.propertyId],
}),
recommendations: many(recommendation),
detailsEpc: one(propertyDetailsEpc, {
fields: [property.id],
references: [propertyDetailsEpc.propertyId],
}),
}));
// We have a many to many relationship between users and portfolios

View file

@ -1,5 +1,4 @@
import EpcCard from "@/app/components/building-passport/EpcCard";
import { PropertyMeta } from "@/app/db/schema/property";
import { formatDateTime } from "@/app/utils";
import {
HomeIcon,
@ -22,10 +21,17 @@ export default async function BuildingPassportHome({
// the response is cached so we just gain access to the data
const propertyMeta = await getPropertyMeta(params.propertyId);
console.log(propertyMeta);
return (
<div className="flex flex-col items-center mt-4">
<div className="flex justify-center mt-4 space-x-2">
<EpcCard epcRating={propertyMeta.currentEpcRating} fullMargin={false} />
<EpcCard
epcRating={propertyMeta.currentEpcRating}
fullMargin={false}
kwh={propertyMeta.detailsEpc.adjustedEnergyConsumption}
carbon={propertyMeta.detailsEpc.co2Emissions}
/>
<div className="flex flex-col p-8 bg-white shadow rounded-md max-w-2xl mx-auto justify-start text-gray-700">
<div className="text-2xl font-bold mb-4">Your property</div>
<div className="flex items-center space-x-2 mb-2">
@ -55,7 +61,7 @@ export default async function BuildingPassportHome({
</div>
<div className="flex items-center space-x-2 mb-2">
<HomeModernIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Number of Rooms:</div>
<div className="text-gray-500">Number of Habitable Rooms:</div>
<div className="text-gray-700">{propertyMeta.numberOfRooms}</div>
</div>
</div>

View file

@ -14,7 +14,7 @@ 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, sapToEpc } from "@/app/utils";
import { formatNumber, getEpcColorClass, sapToEpc } from "@/app/utils";
import { cn } from "@/lib/utils";
import { PortfolioStatus } from "@/app/db/schema/portfolio";
import {
@ -29,30 +29,9 @@ interface DataTableColumnHeaderProps<TData, TValue>
}
const EpcLetterBubble = ({ letter }: { letter: string }) => {
const getColorClass = (letter: string) => {
switch (letter.toUpperCase()) {
case "A":
return "bg-epc_a";
case "B":
return "bg-epc_b";
case "C":
return "bg-epc_c";
case "D":
return "bg-epc_d";
case "E":
return "bg-epc_e";
case "F":
return "bg-epc_f";
case "G":
return "bg-epc_d";
default:
return "bg-gray-500";
}
};
return (
<div
className={`inline-flex items-center justify-center w-6 h-6 rounded-full ${getColorClass(
className={`inline-flex items-center justify-center w-6 h-6 rounded-full ${getEpcColorClass(
letter
)} text-white text-m font-bold shadow-outline-black`}
>

View file

@ -1,5 +1,26 @@
import { Rating } from "./db/schema/property";
export const getEpcColorClass = (letter: string) => {
switch (letter.toUpperCase()) {
case "A":
return "bg-epc_a";
case "B":
return "bg-epc_b";
case "C":
return "bg-epc_c";
case "D":
return "bg-epc_d";
case "E":
return "bg-epc_e";
case "F":
return "bg-epc_f";
case "G":
return "bg-epc_d";
default:
return "bg-gray-500";
}
};
export const getRating = (rating: number | null): Rating => {
if (rating == null) {
return "N/A";