adding booking, assessment graphs, removed repeated section, added survey issues

This commit is contained in:
Khalim Conn-Kowlessar 2026-04-01 17:29:20 +00:00
parent a7790e04b2
commit 4106dc3e2d
2 changed files with 30 additions and 24 deletions

View file

@ -4,10 +4,10 @@ import { useState } from "react";
import { motion } from "framer-motion";
import { Home, AlertTriangle, ToggleLeft, ToggleRight } from "lucide-react";
import { Card, CardContent } from "@/app/shadcn_components/ui/card";
import ProgressOverview from "./ProgressOverview";
import SurveyedResultsPieChart from "./SurveyedResultsPieChart";
import DampMouldRiskPanel from "./DampMouldRiskPanel";
import CompletionTrendsChart from "./CompletionTrendsChart";
import SurveyIssuesPanel from "./SurveyIssuesPanel";
import { STAGE_COLORS, STAGE_ORDER } from "./types";
import type {
ProjectData,
@ -351,19 +351,6 @@ export default function AnalyticsView({
</h2>
</div>
{/* Row 3: Progress overview only (no donut chart) */}
<div>
<motion.div
whileHover={{ scale: 1.005 }}
className="transition-all duration-300"
>
<ProgressOverview
data={currentProject.progress}
onOpenTable={onOpenTable}
/>
</motion.div>
</div>
{/* Row 4: Pipeline Funnel */}
<PipelineFunnel
funnelStages={currentProject.progress.funnelStages}
@ -376,6 +363,12 @@ export default function AnalyticsView({
risk={currentProject.progress.dampMouldRisk}
onOpenTable={onOpenTable}
/>
{/* Row 6: Survey Issues */}
<SurveyIssuesPanel
deals={currentProject.allDeals}
onOpenTable={onOpenTable}
/>
</div>
);
}

View file

@ -1,7 +1,7 @@
"use client";
import { useState } from "react";
import { Card, Title, LineChart, Legend } from "@tremor/react";
import { Card, Title, BarChart, Legend } from "@tremor/react";
import { Button } from "@/app/shadcn_components/ui/button";
import { Input } from "@/app/shadcn_components/ui/input";
import {
@ -56,9 +56,14 @@ function formatMonday(isoDate: string): string {
});
}
function aggregateByWeek(deals: ClassifiedDeal[], dateField: string) {
function aggregateByWeek(
deals: ClassifiedDeal[],
dateField: string,
filter?: (deal: ClassifiedDeal) => boolean,
) {
const weekCounts: Record<string, number> = {};
for (const deal of deals) {
if (filter && !filter(deal)) continue;
const date = deal[dateField as keyof ClassifiedDeal] as
| string
| Date
@ -69,9 +74,11 @@ function aggregateByWeek(deals: ClassifiedDeal[], dateField: string) {
const key = getMondayOfWeek(d);
weekCounts[key] = (weekCounts[key] || 0) + 1;
}
return Object.entries(weekCounts)
.sort(([a], [b]) => a.localeCompare(b))
.map(([isoKey, value]) => ({ week: formatMonday(isoKey), value }));
const allKeys = fillWeekGaps(Object.keys(weekCounts));
return allKeys.map((isoKey) => ({
week: formatMonday(isoKey),
value: weekCounts[isoKey] ?? 0,
}));
}
// Fills all missing Monday ISO-date keys between min and max with 0s
@ -141,11 +148,18 @@ export default function CompletionTrendsChart({
const selectedMetric = METRICS.find((m) => m.key === metric)!;
const isCoordination = metric === "coordination";
const isDesign = metric === "design";
const coordData = isCoordination ? aggregateCoordinationByWeek(deals) : null;
const singleData = isCoordination
? null
: aggregateByWeek(deals, selectedMetric.dateField);
: aggregateByWeek(
deals,
selectedMetric.dateField,
isDesign
? (d) => d.designStatus?.toUpperCase() === "UPLOADED"
: undefined,
);
// Merge targets into non-coordination chart data
const chartData = isCoordination
@ -227,7 +241,7 @@ export default function CompletionTrendsChart({
{isCoordination ? (
<>
<LineChart
<BarChart
data={chartData}
index="week"
categories={["V1 (MTP)", "V2 (Re-model)"]}
@ -236,7 +250,7 @@ export default function CompletionTrendsChart({
className="h-72"
showLegend={true}
showGridLines={true}
curveType="monotone"
stack={true}
/>
<Legend
categories={["V1 (MTP)", "V2 (Re-model)"]}
@ -246,7 +260,7 @@ export default function CompletionTrendsChart({
</>
) : (
<>
<LineChart
<BarChart
data={chartData}
index="week"
categories={[selectedMetric.label, ...(isDomnaUser ? ["Target"] : [])]}
@ -255,7 +269,6 @@ export default function CompletionTrendsChart({
className="h-72"
showLegend={true}
showGridLines={true}
curveType="monotone"
/>
<Legend
categories={[selectedMetric.label, ...(isDomnaUser ? ["Target"] : [])]}