new lay out

This commit is contained in:
Jun-te Kim 2025-10-23 20:18:09 +00:00
parent b8051ad1e3
commit d156ce2b45
4 changed files with 133 additions and 65 deletions

View file

@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import {
Cog6ToothIcon,
NewspaperIcon,
@ -8,6 +9,7 @@ import {
SunIcon,
CircleStackIcon,
HeartIcon,
CalendarDaysIcon,
} from "@heroicons/react/24/outline";
import {
NavigationMenu,
@ -15,12 +17,17 @@ import {
NavigationMenuList,
NavigationMenuLink,
} from "@/app/shadcn_components/ui/navigation-menu";
import { Button } from "@/app/shadcn_components/ui/button";
import { cva } from "class-variance-authority";
import { getUploadedFile } from "@/app/db/surveyDB/schema/surveyDB";
import BookSurveyModal from "@/app/portfolio/[slug]/components/BookSurveyModal";
import BookingSuccessToast from "@/app/portfolio/[slug]/components/BookingSuccessToast";
import { PropertyMeta } from "@/app/db/schema/property";
interface ToolbarProps {
propertyId: string;
portfolioId: string;
propertyMeta: PropertyMeta
decentHomes: getUploadedFile;
}
@ -50,7 +57,6 @@ const navigationMenuTriggerStyle = cva(
"disabled:opacity-50",
"data-[active]:bg-accent/50",
"data-[state=open]:bg-gray-200",
//
"text-gray-900",
].join(" ")
);
@ -58,8 +64,12 @@ const navigationMenuTriggerStyle = cva(
export function Toolbar({
propertyId,
portfolioId,
propertyMeta,
decentHomes,
}: ToolbarProps) {
const [openModal, setOpenModal] = useState(false);
const [showToast, setShowToast] = useState(false);
function handleClickSettings() {
console.log("Settings were clicked, implement me");
}
@ -115,33 +125,67 @@ export function Toolbar({
);
return (
<NavigationMenu>
<NavigationMenuLink
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
href={`/portfolio/${portfolioId}/building-passport/${propertyId}`}
>
<HomeModernIcon className="h-4 w-4 mr-2" />
Summary
</NavigationMenuLink>
<>
<div className="flex items-center justify-between w-full">
{/* Left side: navigation */}
<NavigationMenu>
<NavigationMenuLink
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
href={`/portfolio/${portfolioId}/building-passport/${propertyId}`}
>
<HomeModernIcon className="h-4 w-4 mr-2" />
Summary
</NavigationMenuLink>
<NavigationMenuList>
{preAssessmentReportButton}
{/* We only show decent homes button if decent homes is not an empty object */}
{Object.keys(decentHomes).length > 0 &&
decentHomes.uprn &&
decentHomesButton}
{solarAnalysisButton}
{recommendationsButton}
{documentsButton}
<NavigationMenuList>
{preAssessmentReportButton}
{Object.keys(decentHomes).length > 0 &&
decentHomes.uprn &&
decentHomesButton}
{solarAnalysisButton}
{recommendationsButton}
{documentsButton}
<NavigationMenuItem
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
onClick={handleClickSettings}
>
<Cog6ToothIcon className="h-4 w-4 mr-2" />
Settings
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<NavigationMenuItem
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
onClick={handleClickSettings}
>
<Cog6ToothIcon className="h-4 w-4 mr-2" />
Settings
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
{/* ✅ Right side: Book a Survey button */}
<div className="mr-3">
<Button
onClick={() => setOpenModal(true)}
className="bg-brandblue text-white hover:bg-branddarkblue flex items-center"
>
Book a Survey
</Button>
</div>
</div>
{/* ✅ Modal */}
{openModal && (
<BookSurveyModal
open={openModal}
onOpenChange={setOpenModal}
propertyId={propertyId}
portfolioId={portfolioId}
address={propertyMeta.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. 🎉"
/>
</>
);
}

View file

@ -24,10 +24,6 @@ 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">
@ -92,29 +88,6 @@ export default function BuildingPassportHomeClient({
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

@ -60,6 +60,7 @@ export default async function DashboardLayout(props: {
<Toolbar
propertyId={propertyId}
portfolioId={portfolioId}
propertyMeta={propertyMeta}
decentHomes={decentHomes}
/>
</div>

View file

@ -1,20 +1,70 @@
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({
params,
}: {
params: { slug: string; propertyId: string };
}) {
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
const propertyMeta = await getPropertyMeta(params.propertyId);
// ✅ pass both property data and the portfolio slug (from the URL)
return (
<BuildingPassportHomeClient
propertyMeta={propertyMeta}
portfolioId={params.slug} // ✅ pass slug as portfolioId
/>
<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>
);
}