refactor code

This commit is contained in:
Jun-te Kim 2025-10-23 19:48:49 +00:00
parent 3a3de0943b
commit b8051ad1e3
4 changed files with 134 additions and 92 deletions

View file

@ -0,0 +1,120 @@
"use client";
import { useState } from "react";
import EpcCard from "@/app/components/building-passport/EpcCard";
import { Button } from "@/app/shadcn_components/ui/button";
import { formatDateTime } from "@/app/utils";
import {
CalendarIcon,
HomeIcon,
BuildingOfficeIcon,
ClockIcon,
UserGroupIcon,
HomeModernIcon,
} from "@heroicons/react/24/solid";
import BookSurveyModal from "../../components/BookSurveyModal";
import BookingSuccessToast from "../../components/BookingSuccessToast";
interface BuildingPassportHomeClientProps {
propertyMeta: any;
portfolioId: string; // ✅ from URL (slug)
}
export default function BuildingPassportHomeClient({
propertyMeta,
portfolioId,
}: BuildingPassportHomeClientProps) {
const [openModal, setOpenModal] = useState(false);
const [showToast, setShowToast] = useState(false);
console.log(portfolioId)
console.log(propertyMeta)
return (
<div className="flex flex-col items-center mt-4">
{/* EPC Card + Property Info */}
<div className="flex justify-center mt-4 space-x-2">
{/* EPC Rating Card */}
<EpcCard
epcRating={propertyMeta.currentEpcRating}
fullMargin={false}
kwh={propertyMeta.detailsEpc?.currentEnergyDemand}
carbon={propertyMeta.detailsEpc?.co2Emissions}
/>
{/* Property Info Card */}
<div className="flex flex-col p-8 bg-white shadow rounded-md max-w-2xl mx-auto text-gray-700">
<div className="text-2xl font-bold mb-4">Your Property</div>
<div className="flex items-center space-x-2 mb-2">
<CalendarIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Building Passport Created At:</div>
<div>{formatDateTime(propertyMeta.createdAt)}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<HomeIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Property Type:</div>
<div className="text-gray-700">{propertyMeta.propertyType}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<BuildingOfficeIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Built Form:</div>
<div className="text-gray-700">{propertyMeta.builtForm}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<ClockIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Year Built:</div>
<div className="text-gray-700">{propertyMeta.yearBuilt}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<UserGroupIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Tenure:</div>
<div className="text-gray-700">{propertyMeta.tenure}</div>
</div>
<div className="flex items-center space-x-2 mb-6">
<HomeModernIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Number of Habitable Rooms:</div>
<div className="text-gray-700">{propertyMeta.numberOfRooms}</div>
</div>
</div>
</div>
{/* ✅ "Book a Survey" Button */}
<div className="mt-6">
<Button
onClick={() => setOpenModal(true)}
className="bg-brandmidblue text-white hover:bg-branddarkblue"
>
Book a Survey
</Button>
</div>
{/* ✅ Modal for booking a survey */}
{openModal && (
<BookSurveyModal
open={openModal}
onOpenChange={setOpenModal}
propertyId={propertyMeta.id}
portfolioId={portfolioId} // ✅ from URL (slug)
address={propertyMeta.address}
onSuccess={() => {
setOpenModal(false);
setShowToast(true);
}}
/>
)}
{/* ✅ Success Toast */}
<BookingSuccessToast
show={showToast}
onClose={() => setShowToast(false)}
message="Survey Booked Successfully!"
subtext="Your survey request has been sent to Domna. We'll contact you shortly. 🎉"
/>
</div>
);
}

View file

@ -1,70 +1,20 @@
import EpcCard from "@/app/components/building-passport/EpcCard";
import { formatDateTime } from "@/app/utils";
import {
HomeIcon,
BuildingOfficeIcon,
CalendarIcon,
HomeModernIcon,
ClockIcon,
UserGroupIcon,
} from "@heroicons/react/24/solid";
import { getPropertyMeta } from "./utils";
import BuildingPassportHomeClient from "./BuildingPassportHomeClient";
export const revalidate = 1;
export default async function BuildingPassportHome(
props: {
params: Promise<{ slug: string; propertyId: string }>;
}
) {
const params = await props.params;
// This is a server component and because we make the exact same request in the layout,
// the response is cached so we just gain access to the data
export default async function BuildingPassportHome({
params,
}: {
params: { slug: string; propertyId: string };
}) {
const propertyMeta = await getPropertyMeta(params.propertyId);
// ✅ pass both property data and the portfolio slug (from the URL)
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}
kwh={propertyMeta.detailsEpc.currentEnergyDemand}
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">
<CalendarIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Building Passport Created At:</div>
<div>{formatDateTime(propertyMeta.createdAt)}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<HomeIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Property Type:</div>
<div className="text-gray-700">{propertyMeta.propertyType}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<BuildingOfficeIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Built Form:</div>
<div className="text-gray-700">{propertyMeta.builtForm}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<ClockIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Year Built:</div>
<div className="text-gray-700">{propertyMeta.yearBuilt}</div>
</div>
<div className="flex items-center space-x-2 mb-2">
<UserGroupIcon className="h-5 w-5 text-gray-400" />
<div className="text-gray-500">Tenure:</div>
<div className="text-gray-700">{propertyMeta.tenure}</div>
</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 Habitable Rooms:</div>
<div className="text-gray-700">{propertyMeta.numberOfRooms}</div>
</div>
</div>
</div>
</div>
<BuildingPassportHomeClient
propertyMeta={propertyMeta}
portfolioId={params.slug} // ✅ pass slug as portfolioId
/>
);
}
}

View file

@ -17,7 +17,7 @@ interface BookSurveyModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
propertyId: bigint;
portfolioId: bigint;
portfolioId: string;
address: string;
onSuccess?: () => void; // ✅ fix: properly declare optional callback
}
@ -41,7 +41,7 @@ export default function BookSurveyModal({
pipelineId: "2400089278",
dealStageId: "3288115388",
propertyId: propertyId.toString(),
portfolioId: portfolioId.toString(),
portfolioId: portfolioId,
}),
});

View file

@ -21,9 +21,6 @@ import {
PropertyToRecommendation,
PropertyWithRelations,
} from "@/app/db/schema/property";
import BookSurveyModal from "./BookSurveyModal";
import BookingSuccessToast from "./BookingSuccessToast";
import { useState } from "react";
interface DataTableColumnHeaderProps<TData, TValue>
@ -218,10 +215,7 @@ export const columns: ColumnDef<PropertyWithRelations>[] = [
{
id: "actions",
cell: ({ row }) => {
const [openModal, setOpenModal] = useState(false);
const [showToast, setShowToast] = useState(false);
const property = row.original;
const address = String(row.getValue("address"));
const propertyId = property.id;
const portfolioId = property.portfolioId;
@ -246,9 +240,6 @@ export const columns: ColumnDef<PropertyWithRelations>[] = [
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={()=> setOpenModal(true)}>
Book a survey
</DropdownMenuItem>
<DropdownMenuItem
// onClick={() => navigator.clipboard.writeText(payment.id)}
className="text-gray-700 cursor-pointer"
@ -268,25 +259,6 @@ export const columns: ColumnDef<PropertyWithRelations>[] = [
</DropdownMenuContent>
</DropdownMenu>
</div>
{/* ✅ Render modal outside dropdown context */}
{openModal && (
<BookSurveyModal
open={openModal}
onOpenChange={setOpenModal}
propertyId={propertyId}
portfolioId={portfolioId}
address={address}
onSuccess={() => setShowToast(true)}
/>
)}
{/* 💥 Toast */}
<BookingSuccessToast
show={showToast}
onClose={() => setShowToast(false)}
message="Survey Booked Successfully!"
subtext="Your Survey Request is with Domna and will be in contact with you shortly. 🎉"
/>
</>
);
},