split out uvalue columns and recommendations modal

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-28 17:13:26 +01:00
parent cc6ea6c73c
commit 30962b20cf

View file

@ -1,204 +1,9 @@
"use client";
import { ComponentRecommendation } from "@/app/db/schema/recommendations";
import { Dispatch, Fragment, SetStateAction, useState } from "react";
import { Dispatch, SetStateAction, useState } from "react";
import { formatNumber } from "@/app/utils";
import { Dialog, Transition } from "@headlessui/react";
import RecommendationTable from "@/app/components/building-passport/RecommendationTable";
import { ColumnDef } from "@tanstack/react-table";
import { Checkbox } from "@/app/shadcn_components/ui/checkbox";
import { RecommendationMetricMap } from "@/types/recommendations";
import { sumRecommendationMetricMap } from "@/app/portfolio/[slug]/building-passport/[propertyId]/recommendations/utils";
export const uvalueColumns: ColumnDef<ComponentRecommendation>[] = [
{
accessorKey: "description",
header: "Description",
},
{
accessorKey: "estimatedCost",
header: "Estimated Cost",
cell: ({ row }) => {
return <div>£{formatNumber(row.getValue("estimatedCost"))}</div>;
},
},
{
accessorKey: "newUValue",
header: "New U-Value",
},
{
accessorKey: "default",
id: "default",
header: "Selected?",
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => {
if (value === true && !row.getIsSelected()) {
row.toggleSelected(true);
}
}}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
},
];
interface RecommendationModalProps {
title: string;
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
recommendationData: ComponentRecommendation[];
setCardComponent: Dispatch<SetStateAction<ComponentRecommendation>>;
setCostMap: Dispatch<SetStateAction<RecommendationMetricMap>>;
costMap: RecommendationMetricMap;
setTotalEstimatedCost: Dispatch<SetStateAction<number>>;
sapMap: RecommendationMetricMap;
setSapMap: Dispatch<SetStateAction<RecommendationMetricMap>>;
setTotalSapPoints: Dispatch<SetStateAction<number>>;
}
export function RecommendationModal({
title,
isOpen = false,
setIsOpen,
recommendationData,
setCardComponent,
setCostMap,
costMap,
setTotalEstimatedCost,
sapMap,
setSapMap,
setTotalSapPoints,
}: RecommendationModalProps) {
const [saveButtonDisabled, setSaveButtonDisabled] = useState(true);
// Find the row where default is true
const [defaultRowIndex, setDefaultRowIndex] = useState(
recommendationData.findIndex((d) => d.default)
);
// Initialise the state with the default row index
const [rowSelection, setRowSelection] = useState(
defaultRowIndex !== -1 ? { [defaultRowIndex]: true } : {}
);
function closeModal() {
setIsOpen(false);
// If the user closes the modal, re-set the state of the row selection to the default, since nothing has changed
setRowSelection({ [defaultRowIndex]: true });
}
function saveChanges() {
// disable the button to prevent multiple clicks
// TODO: Add a loading state to show we're saving
setSaveButtonDisabled(true);
setIsOpen(false);
// Update the card component data
const newIndex = parseInt(Object.keys(rowSelection)[0]);
setCardComponent(recommendationData[newIndex]);
// Set the default index
setDefaultRowIndex(newIndex);
// Update the cost map
const newCostMap = {
...costMap,
[title]: recommendationData[newIndex].estimatedCost,
};
setCostMap(newCostMap);
// update the cost sum
setTotalEstimatedCost(sumRecommendationMetricMap(newCostMap));
// Update the sap map
const newSapMap = {
...sapMap,
[title]: recommendationData[newIndex].sapPoints,
};
setSapMap(newSapMap);
// update the sap sum
console.log("setTotalSapPoints", setTotalSapPoints);
setTotalSapPoints(sumRecommendationMetricMap(newSapMap));
}
return (
<>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-screen-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-brandblue mb-3"
>
{title}
</Dialog.Title>
<RecommendationTable
data={recommendationData}
columns={uvalueColumns}
defaultRowIndex={defaultRowIndex}
rowSelection={rowSelection}
setRowSelection={setRowSelection}
setSaveButtonDisabled={setSaveButtonDisabled}
/>
<div className="mt-4 flex justify-end gap-2">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent hover:text-red-600 bg-gray-200 px-4 py-2 text-sm font-medium text-red-600 hover:bg-gray-300 focus:outline-none focus-visible:ring-2 focus-visible:none focus-visible:ring-offset-2"
onClick={() => {
setRowSelection({});
}}
>
Remove Recommendation
</button>
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={closeModal}
>
Cancel
</button>
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-brandblue px-4 py-2 text-sm font-medium text-gray-100 hover:bg-hoverblue focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-brandblue"
onClick={saveChanges}
disabled={saveButtonDisabled}
>
Save
</button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</>
);
}
import RecommendationModal from "./RecommendationModal";
const selectionStyling =
"shadow active:shadow active:bg-brandmidblue w-full border rounded p-4 cursor-pointer text-gray-900 bg-gray-100 hover:bg-hoverblue hover:text-gray-100 transition-colors rounded-md flex flex-col justify-start";