mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
save
This commit is contained in:
parent
276b23a900
commit
4d61224cf3
3 changed files with 114 additions and 36 deletions
|
|
@ -50,7 +50,7 @@ export function Toolbar({ portfolioId, scenarios }: ToolbarProps) {
|
|||
}
|
||||
|
||||
function handleClickProgressReport() {
|
||||
router.push(`/portfolio/${portfolioId}/reports`);
|
||||
router.push(`/portfolio/${portfolioId}/live-projects`);
|
||||
}
|
||||
|
||||
const [modalIsOpen, setModalIsOpen] = useState(false);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ interface ReportsProps {
|
|||
deals: Record<string, any>[];
|
||||
}
|
||||
|
||||
export default function Reports({ deals }: ReportsProps) {
|
||||
// 🟩 Stage mapping: “Major Condition Issues” = dealstage 3061261536
|
||||
const MAJOR_CONDITION_STAGE_ID = "3061261536";
|
||||
|
||||
export default function LiveTracker({ deals }: ReportsProps) {
|
||||
const [openTable, setOpenTable] = useState<{
|
||||
stage: string;
|
||||
data: any[];
|
||||
|
|
@ -39,46 +42,120 @@ export default function Reports({ deals }: ReportsProps) {
|
|||
const [currentProjectCode, setCurrentProjectCode] = useState(projectCodes[0]);
|
||||
const currentDeals = groupedDeals[currentProjectCode];
|
||||
|
||||
// 🔹 Compute overall summary (across all projects)
|
||||
const totalProperties = deals.length;
|
||||
const majorConditionDeals = deals.filter(
|
||||
(d) => d.dealstage === MAJOR_CONDITION_STAGE_ID
|
||||
);
|
||||
const majorIssues = majorConditionDeals.length;
|
||||
const majorPercent = ((majorIssues / totalProperties) * 100).toFixed(1);
|
||||
|
||||
// 🔹 Click handlers
|
||||
const handleTotalClick = () => {
|
||||
console.log("Opening all deals (global)");
|
||||
handleOpenTable("All Properties", deals);
|
||||
};
|
||||
|
||||
const handleMajorClick = () => {
|
||||
console.log("Opening all Major Condition Issues (global)");
|
||||
handleOpenTable("Major Condition Issues", majorConditionDeals);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
{/* 🔹 Centered Dropdown Selector for Projects */}
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<h2 className="text-xl font-semibold text-gray-800">
|
||||
Select Project
|
||||
</h2>
|
||||
<div className="p-6 space-y-8">
|
||||
{/* 🔹 Global Overview Row */}
|
||||
<div className="border rounded-xl bg-gray-50 shadow-sm p-6 space-y-4">
|
||||
<h2 className="text-lg font-semibold text-gray-700 text-center uppercase tracking-wide">
|
||||
🌍 Global Portfolio Overview
|
||||
</h2>
|
||||
|
||||
<div className="relative w-full max-w-xs">
|
||||
<select
|
||||
value={currentProjectCode}
|
||||
onChange={(e) => setCurrentProjectCode(e.target.value)}
|
||||
className="w-full appearance-none px-4 py-2 pr-10 border border-gray-300 rounded-lg bg-white text-center text-gray-800 shadow-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
||||
>
|
||||
{projectCodes.map((code) => (
|
||||
<option key={code} value={code}>
|
||||
{code}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 items-center text-center">
|
||||
{/* Total Properties */}
|
||||
<button
|
||||
onClick={handleTotalClick}
|
||||
className="group transition rounded-lg border border-transparent hover:border-blue-500 hover:bg-blue-50 p-4 cursor-pointer"
|
||||
>
|
||||
<p className="text-sm text-gray-500 uppercase tracking-wide">
|
||||
Total Properties
|
||||
</p>
|
||||
<p className="text-2xl font-semibold text-gray-800 group-hover:text-blue-600">
|
||||
{totalProperties}
|
||||
</p>
|
||||
</button>
|
||||
|
||||
{/* Custom dropdown arrow */}
|
||||
<div className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-gray-500">
|
||||
▼
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Major Condition Issues */}
|
||||
<button
|
||||
onClick={handleMajorClick}
|
||||
className="group transition rounded-lg border border-transparent hover:border-red-500 hover:bg-red-50 p-4 cursor-pointer"
|
||||
>
|
||||
<p className="text-sm text-gray-500 uppercase tracking-wide">
|
||||
Major Condition Issues
|
||||
</p>
|
||||
<p className="text-2xl font-semibold text-red-600 group-hover:text-red-700">
|
||||
{majorIssues}{" "}
|
||||
<span className="text-gray-500 text-base font-normal">
|
||||
({majorPercent}%)
|
||||
</span>
|
||||
</p>
|
||||
</button>
|
||||
|
||||
{/* Charts */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="border rounded-xl p-4 shadow-sm bg-white">
|
||||
<DealStageChart deals={currentDeals} onOpenTable={handleOpenTable} />
|
||||
</div>
|
||||
<div className="border rounded-xl p-4 shadow-sm bg-white">
|
||||
<SurveyedPieChart deals={currentDeals} onOpenTable={handleOpenTable} />
|
||||
{/* Project Dropdown Selector */}
|
||||
<div>
|
||||
<label
|
||||
htmlFor="projectSelect"
|
||||
className="block text-sm font-medium text-gray-700 mb-1"
|
||||
>
|
||||
Select Project
|
||||
</label>
|
||||
<div className="relative max-w-xs mx-auto">
|
||||
<select
|
||||
id="projectSelect"
|
||||
value={currentProjectCode}
|
||||
onChange={(e) => setCurrentProjectCode(e.target.value)}
|
||||
className="w-full appearance-none px-4 py-2 pr-10 border border-gray-300 rounded-lg bg-white text-gray-800 shadow-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
||||
>
|
||||
{projectCodes.map((code) => (
|
||||
<option key={code} value={code}>
|
||||
{code}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
{/* Custom dropdown arrow */}
|
||||
<div className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-gray-500">
|
||||
▼
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center text-gray-500 text-sm">
|
||||
Showing project <span className="font-medium">{currentProjectCode}</span>
|
||||
{/* 🔹 Project-Level Section */}
|
||||
<div className="border rounded-xl bg-gray-50 shadow-sm p-6 space-y-4">
|
||||
<h2 className="text-lg font-semibold text-gray-700 text-center uppercase tracking-wide">
|
||||
📊 Project-Level Insights
|
||||
</h2>
|
||||
<p className="text-center text-gray-500 text-sm -mt-2">
|
||||
Showing data for{" "}
|
||||
<span className="font-medium text-gray-700">
|
||||
{currentProjectCode}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="border rounded-xl p-4 shadow-sm bg-white">
|
||||
<DealStageChart
|
||||
deals={currentDeals}
|
||||
onOpenTable={handleOpenTable}
|
||||
/>
|
||||
</div>
|
||||
<div className="border rounded-xl p-4 shadow-sm bg-white">
|
||||
<SurveyedPieChart
|
||||
deals={currentDeals}
|
||||
onOpenTable={handleOpenTable}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 🔹 Modal Table */}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { surveyDB } from "../../../../db/surveyDB/connection";
|
|||
import { hubspotDealData } from "../../../../db/schema/crm/hubspot_deal_table";
|
||||
import { eq } from "drizzle-orm";
|
||||
import Reports from "./Report";
|
||||
import LiveTracker from "./Report";
|
||||
|
||||
const Demo = async () => {
|
||||
const user = await getServerSession(AuthOptions);
|
||||
|
|
@ -25,7 +26,7 @@ const Demo = async () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Reports deals={deals} />
|
||||
<LiveTracker deals={deals} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue