mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
handling incorrect aggregation due to timezones
This commit is contained in:
parent
02282cbb90
commit
35aa72bce8
5 changed files with 55 additions and 10 deletions
|
|
@ -48,7 +48,7 @@ export const hubspotDealData = pgTable("hubspot_deal_data", {
|
|||
damnpMouldAndRepairComments: text("damp_mould_and_repairs_comments"),
|
||||
confirmedSurveyDate: timestamp("confirmed_survey_date", { precision: 6, withTimezone: true }),
|
||||
confirmedSurveyTime: text("confirmed_survey_time"),
|
||||
SurveyedDate: timestamp("surveyed_date", { precision: 6, withTimezone: true }),
|
||||
surveyedDate: timestamp("surveyed_date", { precision: 6, withTimezone: true }),
|
||||
|
||||
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
|
||||
.defaultNow()
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ const DESIGN_TYPE_ORDER = [
|
|||
|
||||
function getMondayOfWeek(date: Date): string {
|
||||
const d = new Date(date);
|
||||
const day = d.getDay();
|
||||
d.setDate(d.getDate() - (day === 0 ? 6 : day - 1));
|
||||
d.setHours(0, 0, 0, 0);
|
||||
const day = d.getUTCDay();
|
||||
d.setUTCDate(d.getUTCDate() - (day === 0 ? 6 : day - 1));
|
||||
d.setUTCHours(0, 0, 0, 0);
|
||||
return d.toISOString().split("T")[0];
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ function fillWeekGaps(keys: string[]): string[] {
|
|||
const end = new Date(sorted[sorted.length - 1]);
|
||||
while (current <= end) {
|
||||
result.push(current.toISOString().split("T")[0]);
|
||||
current.setDate(current.getDate() + 7);
|
||||
current.setUTCDate(current.getUTCDate() + 7);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -314,14 +314,28 @@ export default function CompletionTrendsChart({
|
|||
const isDesign = metric === "design";
|
||||
const isStacked = isCoordination || isAssessments || isLodgement || isDesign;
|
||||
|
||||
// External assessments with no date
|
||||
// Assessments (retrofit or EPC) with no date
|
||||
const undatedAssessments = isAssessments
|
||||
? deals.filter((d) => {
|
||||
const o = d.outcome ?? "";
|
||||
return (o === "Surveyed" || o === "Surveyed - Pending Upload") && !d.surveyedDate;
|
||||
return (
|
||||
(o === "Surveyed" || o === "Surveyed - Pending Upload" || o === "EPC Completed") &&
|
||||
!d.surveyedDate
|
||||
);
|
||||
})
|
||||
: [];
|
||||
|
||||
// Dated assessments broken down by type — used for summary badges
|
||||
const retrofitDeals = isAssessments
|
||||
? deals.filter((d) => {
|
||||
const o = d.outcome ?? "";
|
||||
return (o === "Surveyed" || o === "Surveyed - Pending Upload") && !!d.surveyedDate;
|
||||
})
|
||||
: [];
|
||||
const epcDeals = isAssessments
|
||||
? deals.filter((d) => d.outcome === "EPC Completed" && !!d.surveyedDate)
|
||||
: [];
|
||||
|
||||
// Build chart data
|
||||
let chartData: Record<string, string | number>[];
|
||||
let categories: string[];
|
||||
|
|
@ -363,7 +377,37 @@ export default function CompletionTrendsChart({
|
|||
<Title className="text-brandblue text-lg font-bold">
|
||||
Trends Over Time
|
||||
</Title>
|
||||
{totalCompleted !== null && (
|
||||
{isAssessments ? (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{([
|
||||
{ label: "Retrofit Assessments", dealList: retrofitDeals },
|
||||
{ label: "EPCs", dealList: epcDeals },
|
||||
] as const).filter(({ dealList }) => dealList.length > 0).map(({ label, dealList }) => (
|
||||
<button
|
||||
key={label}
|
||||
type="button"
|
||||
onClick={() =>
|
||||
onOpenTable?.(
|
||||
`Completed — ${label}`,
|
||||
dealList,
|
||||
["dealname", "landlordPropertyId", "outcome", "surveyedDate"],
|
||||
{
|
||||
dealname: "Address",
|
||||
landlordPropertyId: "Property Ref.",
|
||||
outcome: "Work Type",
|
||||
surveyedDate: "Survey Date",
|
||||
},
|
||||
)
|
||||
}
|
||||
className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-gradient-to-r from-brandmidblue/10 to-brandlightblue/50 border border-brandblue/20 shadow-sm hover:border-brandblue/40 hover:shadow-md transition-all cursor-pointer"
|
||||
>
|
||||
<span className="text-brandmidblue font-bold text-base leading-none">{dealList.length}</span>
|
||||
<span className="text-xs text-brandblue font-medium">{label}</span>
|
||||
<span className="text-brandmidblue text-xs leading-none">✦</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
) : totalCompleted !== null && (
|
||||
<div className="inline-flex items-center gap-2 self-start px-3 py-1.5 rounded-full bg-gradient-to-r from-brandmidblue/10 to-brandlightblue/50 border border-brandblue/20 shadow-sm">
|
||||
<span className="text-brandmidblue font-bold text-base leading-none" suppressHydrationWarning>{totalCompleted}</span>
|
||||
<span className="text-xs text-brandblue font-medium">
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { AlertCircle } from "lucide-react";
|
|||
import { Card, CardContent } from "@/app/shadcn_components/ui/card";
|
||||
import type { ClassifiedDeal } from "./types";
|
||||
|
||||
const SUCCESSFUL_OUTCOMES = new Set(["Surveyed", "Surveyed - Pending Upload"]);
|
||||
const SUCCESSFUL_OUTCOMES = new Set(["Surveyed", "Surveyed - Pending Upload", "EPC Completed"]);
|
||||
|
||||
const COLUMNS: (keyof ClassifiedDeal)[] = [
|
||||
"dealname",
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ function mapDbRowToHubspotDeal(row: DbDeal): HubspotDeal {
|
|||
measuresLodgementDate: row.measuresLodgementDate,
|
||||
fullLodgementDate: row.lodgementDate,
|
||||
confirmedSurveyDate: row.confirmedSurveyDate,
|
||||
surveyedDate: row.SurveyedDate,
|
||||
surveyedDate: row.surveyedDate,
|
||||
designType: row.dealType,
|
||||
createdAt: row.createdAt,
|
||||
updatedAt: row.updatedAt,
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ export type DocumentDrawerState = {
|
|||
export const SURVEYOR_OUTCOMES = [
|
||||
"Surveyed",
|
||||
"Surveyed - Pending Upload",
|
||||
"EPC Completed",
|
||||
"Tenant Refusal",
|
||||
"Other",
|
||||
"Not Viable",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue