mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
added decent homes reporting
This commit is contained in:
parent
0a90eecc91
commit
ce1a78005a
7 changed files with 436 additions and 420 deletions
98
package-lock.json
generated
98
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
|||
"@headlessui/react": "^2.2.7",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.5",
|
||||
|
|
@ -2734,6 +2735,43 @@
|
|||
"integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-accordion": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz",
|
||||
"integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-collapsible": "1.1.12",
|
||||
"@radix-ui/react-collection": "1.1.7",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-direction": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/primitive": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
|
||||
"integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-arrow": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
|
||||
|
|
@ -2787,6 +2825,66 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz",
|
||||
"integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-id": "1.1.1",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/primitive": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
|
||||
"integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
|
||||
"integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
"@headlessui/react": "^2.2.7",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@hookform/resolvers": "^3.9.1",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.5",
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export function Toolbar({ propertyId, portfolioId, conditionReport }: ToolbarPro
|
|||
const preAssessmentReportButton = (
|
||||
<NavigationMenuLink
|
||||
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
|
||||
href={`/portfolio/${portfolioId}/building-passport/${propertyId}/pre-assessment-report`}
|
||||
href={`/portfolio/${portfolioId}/building-passport/${propertyId}/assessment`}
|
||||
>
|
||||
<NewspaperIcon className="h-4 w-4 mr-2" />
|
||||
Data
|
||||
|
|
@ -110,18 +110,6 @@ export function Toolbar({ propertyId, portfolioId, conditionReport }: ToolbarPro
|
|||
</NavigationMenuLink>
|
||||
);
|
||||
|
||||
const conditionButton = (
|
||||
<NavigationMenuLink
|
||||
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
|
||||
href={`/portfolio/${portfolioId}/building-passport/${propertyId}/condition`}
|
||||
>
|
||||
<WrenchScrewdriverIcon className="h-4 w-4 mr-2" />
|
||||
Condition Report
|
||||
</NavigationMenuLink>
|
||||
);
|
||||
|
||||
console.log("conditionReport", conditionReport)
|
||||
|
||||
return (
|
||||
<NavigationMenu>
|
||||
<NavigationMenuLink
|
||||
|
|
@ -137,9 +125,7 @@ export function Toolbar({ propertyId, portfolioId, conditionReport }: ToolbarPro
|
|||
{solarAnalysisButton}
|
||||
{recommendationsButton}
|
||||
{documentsButton}
|
||||
{/*We only show the conditionButton if the condition report is not empty*/}
|
||||
{Object.keys(conditionReport).length > 0 && conditionButton}
|
||||
{energyAssessmentsReportButton}
|
||||
{/* {energyAssessmentsReportButton} */}
|
||||
<NavigationMenuItem
|
||||
className={navigationMenuTriggerStyle() + " ml-3 mr-2"}
|
||||
onClick={handleClickSettings}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ export default async function DashboardLayout(
|
|||
{ uprn: String(propertyMeta.uprn), documentType: "ECO_CONDITION_REPORT" }
|
||||
);
|
||||
|
||||
console.log("conditionReport", conditionReport)
|
||||
|
||||
if (!propertyId && propertyId !== "0") {
|
||||
throw Error("Invalid propertyId");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,193 +0,0 @@
|
|||
import EpcCard from "@/app/components/building-passport/EpcCard";
|
||||
import FeatureTable from "@/app/components/building-passport/FeatureTable";
|
||||
import {
|
||||
ConditionReportData,
|
||||
PropertyDetailsEpc,
|
||||
PropertyDetailsSpatial,
|
||||
PropertyMeta,
|
||||
} from "@/app/db/schema/property";
|
||||
import { formatDateTime } from "@/app/utils";
|
||||
import {
|
||||
generalColumns,
|
||||
nonInstrusiveColumns,
|
||||
retrofitColumns,
|
||||
} from "@/app/components/building-passport/FeatureTableColumns";
|
||||
import {
|
||||
formatGeneralFeatures,
|
||||
formatHeatDemandFeatures,
|
||||
formatRetrofitFeatures,
|
||||
getConditionReport,
|
||||
getPropertyMeta,
|
||||
getSpatialData,
|
||||
getNonIntrusiveSurvey,
|
||||
} from "../utils";
|
||||
|
||||
function AddressCard({ address }: { address: string | null }) {
|
||||
// In the future, we might want to use react-wrap-balancer for some of this text
|
||||
return (
|
||||
<div className="flex flex-col items-center p-4 shadow rounded-md max-w-xl mx-auto justify-start text-gray-100 bg-brandblue">
|
||||
<div className="text-2xl font-bold max-w-l">{address}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface PropertyDetailsCardProps {
|
||||
conditionReportData: PropertyDetailsEpc;
|
||||
propertyMeta: PropertyMeta;
|
||||
propertyDetailsSpatial: PropertyDetailsSpatial;
|
||||
}
|
||||
|
||||
const rowTitleStyle = "text-brandblue align-top pb-3";
|
||||
const rowValueStyle = "text-brandblue text-end pr-8 pt-1 align-top pb-3";
|
||||
|
||||
function PropertyDetailsCard({
|
||||
conditionReportData,
|
||||
propertyMeta,
|
||||
propertyDetailsSpatial,
|
||||
}: PropertyDetailsCardProps) {
|
||||
const propertyText = [propertyMeta.builtForm, propertyMeta.propertyType]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col items-center p-4 shadow rounded-md justify-start bg-gray-100">
|
||||
<div className="grid grid-cols-2 gap-8 text-m w-full h-full text-sm">
|
||||
<div className="border-r">
|
||||
<table className="w-full ">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Year built:</td>
|
||||
<td className={rowValueStyle}>{propertyMeta.yearBuilt}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Property Type:</td>
|
||||
<td className={rowValueStyle}>{propertyText}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Total floor area:</td>
|
||||
<td className={rowValueStyle}>
|
||||
{`${conditionReportData.totalFloorArea} m`}
|
||||
<sup>2</sup>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>In conservation area:</td>
|
||||
<td className={rowValueStyle}>
|
||||
{propertyDetailsSpatial.conservationStatus ? "Yes" : "No"}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Is listed:</td>
|
||||
<td className={rowValueStyle}>
|
||||
{propertyDetailsSpatial.isListedBuilding ? "Yes" : "No"}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Is heritage:</td>
|
||||
<td className={rowValueStyle}>
|
||||
{propertyDetailsSpatial.isHeritageBuilding ? "Yes" : "No"}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table className="w-full">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Local Authority:</td>
|
||||
<td className={rowValueStyle}>{propertyMeta.localAuthority}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Constituency:</td>
|
||||
<td className={rowValueStyle}>{propertyMeta.constituency}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Tenure</td>
|
||||
<td className={rowValueStyle}>{propertyMeta.tenure}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className={rowTitleStyle}>Number of Habitable Rooms:</td>
|
||||
<td className={rowValueStyle}>
|
||||
{propertyMeta.numberOfRooms || "unkown"}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const formatDate = (dateString: Date) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleDateString("en-GB", {
|
||||
weekday: "long", // "Monday" through "Sunday"
|
||||
year: "numeric", // "2024"
|
||||
month: "long", // "January" through "December"
|
||||
day: "numeric", // "1", "2", ..., "31"
|
||||
});
|
||||
};
|
||||
|
||||
export default async function PreAssessmentReport(
|
||||
props: {
|
||||
params: Promise<{ slug: string; propertyId: string }>;
|
||||
}
|
||||
) {
|
||||
const params = await props.params;
|
||||
const propertyMeta = await getPropertyMeta(params.propertyId);
|
||||
const conditionReportData = await getConditionReport(params.propertyId);
|
||||
const propertyDetailsSpatial = await getSpatialData(propertyMeta.uprn);
|
||||
const generalFeatures = formatGeneralFeatures(
|
||||
conditionReportData,
|
||||
propertyMeta.propertyType
|
||||
);
|
||||
|
||||
const nonIntrusiveSurvey = await getNonIntrusiveSurvey(propertyMeta.uprn);
|
||||
|
||||
const retrofitFeatures = formatRetrofitFeatures(conditionReportData);
|
||||
|
||||
const heatingDemand = formatHeatDemandFeatures(conditionReportData);
|
||||
|
||||
return (
|
||||
<div className="leading-loose tracking-wider">
|
||||
<div className="flex py-8 text-lg">Pre Assessment Report</div>
|
||||
<div className="text-gray-700 text-sm">
|
||||
Last updated: {formatDateTime(propertyMeta.updatedAt)}
|
||||
</div>
|
||||
<div className="flex flex-col items-stretch mb-4">
|
||||
<div className="flex flex-row justify-start mt-4 space-x-4">
|
||||
<EpcCard
|
||||
epcRating={propertyMeta.currentEpcRating}
|
||||
fullMargin={false}
|
||||
/>
|
||||
|
||||
<PropertyDetailsCard
|
||||
conditionReportData={conditionReportData}
|
||||
propertyMeta={propertyMeta}
|
||||
propertyDetailsSpatial={propertyDetailsSpatial}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{nonIntrusiveSurvey && (
|
||||
<div>
|
||||
<div className="flex py-8 text-lg">Non-Intrusive Survey</div>
|
||||
<div className="flex mb-2 text-sm text-gray-500">
|
||||
Conducted by: {nonIntrusiveSurvey.surveyor} on{" "}
|
||||
{formatDate(nonIntrusiveSurvey.surveyDate)}
|
||||
</div>
|
||||
<FeatureTable
|
||||
data={nonIntrusiveSurvey.notes}
|
||||
columns={nonInstrusiveColumns}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex py-8 text-lg">General Features</div>
|
||||
<FeatureTable data={generalFeatures} columns={generalColumns} />
|
||||
<div className="flex py-8 text-lg">Existing Property Features</div>
|
||||
<FeatureTable data={retrofitFeatures} columns={retrofitColumns} />
|
||||
<div className="flex py-8 text-lg">Heating Demand</div>
|
||||
<FeatureTable data={heatingDemand} columns={generalColumns} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import S3 from "aws-sdk/clients/s3";
|
||||
import {
|
||||
Recommendation,
|
||||
planRecommendations,
|
||||
|
|
@ -31,6 +32,35 @@ import {
|
|||
} from "@/app/db/schema/funding";
|
||||
import { getUploadedFile, uploadedFiles, DB_REPORT_TYPES } from "@/app/db/surveyDB/schema/surveyDB";
|
||||
|
||||
|
||||
export async function getEnergyAssessmentFromS3(s3Uri: string): Promise<any> {
|
||||
const url = new URL(s3Uri);
|
||||
|
||||
const bucketMatch = url.hostname.match(/^(.+)\.s3/);
|
||||
const bucket = bucketMatch?.[1];
|
||||
const key = url.pathname.startsWith("/") ? url.pathname.slice(1) : url.pathname;
|
||||
|
||||
if (!bucket || !key) {
|
||||
throw new Error("Could not extract bucket or key from URI");
|
||||
}
|
||||
|
||||
const s3 = new S3({
|
||||
region: "eu-west-2",
|
||||
accessKeyId: process.env.RETROFIT_ENERGY_ASSESSMENTS_AWS_ACCESS_KEY,
|
||||
secretAccessKey: process.env.ENERGY_ASSESSMENTS_AWS_SECRET,
|
||||
});
|
||||
|
||||
const result = await s3
|
||||
.getObject({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
})
|
||||
.promise();
|
||||
|
||||
const body = result.Body?.toString("utf-8");
|
||||
return body ? JSON.parse(body) : null;
|
||||
}
|
||||
|
||||
type RecommendationList = {
|
||||
recommendation: Recommendation;
|
||||
}[];
|
||||
|
|
|
|||
|
|
@ -12,193 +12,227 @@ module.exports = {
|
|||
"./node_modules/@tremor/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
transparent: "transparent",
|
||||
current: "currentColor",
|
||||
container: {
|
||||
center: true,
|
||||
padding: "2rem",
|
||||
screens: {
|
||||
"2xl": "1400px",
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
},
|
||||
colors: {
|
||||
// Tremor light mode
|
||||
tremor: {
|
||||
brand: {
|
||||
faint: colors.blue[50],
|
||||
muted: colors.blue[200],
|
||||
subtle: colors.blue[400],
|
||||
DEFAULT: colors.blue[500],
|
||||
emphasis: colors.blue[700],
|
||||
inverted: colors.white,
|
||||
},
|
||||
background: {
|
||||
muted: colors.gray[50],
|
||||
subtle: colors.gray[100],
|
||||
DEFAULT: colors.white,
|
||||
emphasis: colors.gray[700],
|
||||
},
|
||||
border: {
|
||||
DEFAULT: colors.gray[200],
|
||||
},
|
||||
ring: {
|
||||
DEFAULT: colors.gray[200],
|
||||
},
|
||||
content: {
|
||||
subtle: colors.gray[400],
|
||||
DEFAULT: colors.gray[500],
|
||||
emphasis: colors.gray[700],
|
||||
strong: colors.gray[900],
|
||||
inverted: colors.white,
|
||||
},
|
||||
},
|
||||
// Tremor dark mode
|
||||
// dark mode
|
||||
"dark-tremor": {
|
||||
brand: {
|
||||
faint: "#0B1229",
|
||||
muted: colors.blue[950],
|
||||
subtle: colors.blue[800],
|
||||
DEFAULT: colors.blue[500],
|
||||
emphasis: colors.blue[400],
|
||||
inverted: colors.blue[950],
|
||||
},
|
||||
background: {
|
||||
muted: "#131A2B",
|
||||
subtle: colors.gray[800],
|
||||
DEFAULT: colors.gray[900],
|
||||
emphasis: colors.gray[300],
|
||||
},
|
||||
border: {
|
||||
DEFAULT: colors.gray[800],
|
||||
},
|
||||
ring: {
|
||||
DEFAULT: colors.gray[800],
|
||||
},
|
||||
content: {
|
||||
subtle: colors.gray[600],
|
||||
DEFAULT: colors.gray[500],
|
||||
emphasis: colors.gray[200],
|
||||
strong: colors.gray[50],
|
||||
inverted: colors.gray[950],
|
||||
},
|
||||
},
|
||||
epc_a: "#117d58",
|
||||
epc_b: "#2da55c",
|
||||
epc_c: "#8dbd40",
|
||||
epc_d: "#f7cd14",
|
||||
epc_e: "#f3a96a",
|
||||
epc_f: "#ef8026",
|
||||
epc_g: "#e41e3b",
|
||||
brandblue: "#14163d",
|
||||
hoverblue: "#3e4073",
|
||||
brandtan: "#d3b488",
|
||||
hovertan: "#947750",
|
||||
brandgold: "#f1bb06",
|
||||
hovergold: "#c79d12",
|
||||
brandbrown: "#c4a47c",
|
||||
brandmidblue: "#3943b7",
|
||||
brandlightblue: "#00a9f4",
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
},
|
||||
textColor: {
|
||||
brandblue: "#14163d",
|
||||
hoverblue: "#3e4073",
|
||||
brandtan: "#d3b488",
|
||||
hovertan: "#947750",
|
||||
brandbrown: "#c4a47c",
|
||||
brandmidblue: "#3943b7",
|
||||
brandlightblue: "#00a9f4",
|
||||
},
|
||||
borderRadius: {
|
||||
lg: `var(--radius)`,
|
||||
md: `calc(var(--radius) - 2px)`,
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ["var(--font-sans)", ...fontFamily.sans],
|
||||
},
|
||||
keyframes: {
|
||||
"accordion-down": {
|
||||
from: { height: 0 },
|
||||
to: { height: "var(--radix-accordion-content-height)" },
|
||||
},
|
||||
"accordion-up": {
|
||||
from: { height: "var(--radix-accordion-content-height)" },
|
||||
to: { height: 0 },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"accordion-down": "accordion-down 0.2s ease-out",
|
||||
"accordion-up": "accordion-up 0.2s ease-out",
|
||||
},
|
||||
maxWidth: {
|
||||
"8xl": "90rem",
|
||||
},
|
||||
boxShadow: {
|
||||
// light
|
||||
"tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
||||
"tremor-card":
|
||||
"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
|
||||
"tremor-dropdown":
|
||||
"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
||||
// dark
|
||||
"dark-tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
||||
"dark-tremor-card":
|
||||
"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
|
||||
"dark-tremor-dropdown":
|
||||
"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
||||
},
|
||||
borderRadius: {
|
||||
"tremor-small": "0.375rem",
|
||||
"tremor-default": "0.5rem",
|
||||
"tremor-full": "9999px",
|
||||
},
|
||||
fontSize: {
|
||||
"tremor-label": ["0.75rem", { lineHeight: "1rem" }],
|
||||
"tremor-default": ["0.875rem", { lineHeight: "1.25rem" }],
|
||||
"tremor-title": ["1.125rem", { lineHeight: "1.75rem" }],
|
||||
"tremor-metric": ["1.875rem", { lineHeight: "2.25rem" }],
|
||||
},
|
||||
},
|
||||
transparent: 'transparent',
|
||||
current: 'currentColor',
|
||||
container: {
|
||||
center: true,
|
||||
padding: '2rem',
|
||||
screens: {
|
||||
'2xl': '1400px'
|
||||
}
|
||||
},
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
|
||||
},
|
||||
colors: {
|
||||
tremor: {
|
||||
brand: {
|
||||
faint: 'colors.blue[50]',
|
||||
muted: 'colors.blue[200]',
|
||||
subtle: 'colors.blue[400]',
|
||||
DEFAULT: 'colors.blue[500]',
|
||||
emphasis: 'colors.blue[700]',
|
||||
inverted: 'colors.white'
|
||||
},
|
||||
background: {
|
||||
muted: 'colors.gray[50]',
|
||||
subtle: 'colors.gray[100]',
|
||||
DEFAULT: 'colors.white',
|
||||
emphasis: 'colors.gray[700]'
|
||||
},
|
||||
border: {
|
||||
DEFAULT: 'colors.gray[200]'
|
||||
},
|
||||
ring: {
|
||||
DEFAULT: 'colors.gray[200]'
|
||||
},
|
||||
content: {
|
||||
subtle: 'colors.gray[400]',
|
||||
DEFAULT: 'colors.gray[500]',
|
||||
emphasis: 'colors.gray[700]',
|
||||
strong: 'colors.gray[900]',
|
||||
inverted: 'colors.white'
|
||||
}
|
||||
},
|
||||
'dark-tremor': {
|
||||
brand: {
|
||||
faint: '#0B1229',
|
||||
muted: 'colors.blue[950]',
|
||||
subtle: 'colors.blue[800]',
|
||||
DEFAULT: 'colors.blue[500]',
|
||||
emphasis: 'colors.blue[400]',
|
||||
inverted: 'colors.blue[950]'
|
||||
},
|
||||
background: {
|
||||
muted: '#131A2B',
|
||||
subtle: 'colors.gray[800]',
|
||||
DEFAULT: 'colors.gray[900]',
|
||||
emphasis: 'colors.gray[300]'
|
||||
},
|
||||
border: {
|
||||
DEFAULT: 'colors.gray[800]'
|
||||
},
|
||||
ring: {
|
||||
DEFAULT: 'colors.gray[800]'
|
||||
},
|
||||
content: {
|
||||
subtle: 'colors.gray[600]',
|
||||
DEFAULT: 'colors.gray[500]',
|
||||
emphasis: 'colors.gray[200]',
|
||||
strong: 'colors.gray[50]',
|
||||
inverted: 'colors.gray[950]'
|
||||
}
|
||||
},
|
||||
epc_a: '#117d58',
|
||||
epc_b: '#2da55c',
|
||||
epc_c: '#8dbd40',
|
||||
epc_d: '#f7cd14',
|
||||
epc_e: '#f3a96a',
|
||||
epc_f: '#ef8026',
|
||||
epc_g: '#e41e3b',
|
||||
brandblue: '#14163d',
|
||||
hoverblue: '#3e4073',
|
||||
brandtan: '#d3b488',
|
||||
hovertan: '#947750',
|
||||
brandgold: '#f1bb06',
|
||||
hovergold: '#c79d12',
|
||||
brandbrown: '#c4a47c',
|
||||
brandmidblue: '#3943b7',
|
||||
brandlightblue: '#00a9f4',
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
ring: 'hsl(var(--ring))',
|
||||
background: 'hsl(var(--background))',
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
foreground: 'hsl(var(--primary-foreground))'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
foreground: 'hsl(var(--destructive-foreground))'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted))',
|
||||
foreground: 'hsl(var(--muted-foreground))'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
foreground: 'hsl(var(--accent-foreground))'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover))',
|
||||
foreground: 'hsl(var(--popover-foreground))'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))'
|
||||
}
|
||||
},
|
||||
textColor: {
|
||||
brandblue: '#14163d',
|
||||
hoverblue: '#3e4073',
|
||||
brandtan: '#d3b488',
|
||||
hovertan: '#947750',
|
||||
brandbrown: '#c4a47c',
|
||||
brandmidblue: '#3943b7',
|
||||
brandlightblue: '#00a9f4'
|
||||
},
|
||||
borderRadius: {
|
||||
'tremor-small': '0.375rem',
|
||||
'tremor-default': '0.5rem',
|
||||
'tremor-full': '9999px'
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [
|
||||
'var(--font-sans)',
|
||||
...fontFamily.sans
|
||||
]
|
||||
},
|
||||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: {
|
||||
height: 0
|
||||
},
|
||||
to: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
}
|
||||
},
|
||||
'accordion-up': {
|
||||
from: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
},
|
||||
to: {
|
||||
height: 0
|
||||
}
|
||||
},
|
||||
'accordion-down': {
|
||||
from: {
|
||||
height: '0'
|
||||
},
|
||||
to: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
}
|
||||
},
|
||||
'accordion-up': {
|
||||
from: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
},
|
||||
to: {
|
||||
height: '0'
|
||||
}
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out'
|
||||
},
|
||||
maxWidth: {
|
||||
'8xl': '90rem'
|
||||
},
|
||||
boxShadow: {
|
||||
'tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
||||
'tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
|
||||
'tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
|
||||
'dark-tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
||||
'dark-tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
|
||||
'dark-tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)'
|
||||
},
|
||||
fontSize: {
|
||||
'tremor-label': [
|
||||
'0.75rem',
|
||||
{
|
||||
lineHeight: '1rem'
|
||||
}
|
||||
],
|
||||
'tremor-default': [
|
||||
'0.875rem',
|
||||
{
|
||||
lineHeight: '1.25rem'
|
||||
}
|
||||
],
|
||||
'tremor-title': [
|
||||
'1.125rem',
|
||||
{
|
||||
lineHeight: '1.75rem'
|
||||
}
|
||||
],
|
||||
'tremor-metric': [
|
||||
'1.875rem',
|
||||
{
|
||||
lineHeight: '2.25rem'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
extend: {
|
||||
|
|
@ -234,28 +268,90 @@ module.exports = {
|
|||
/^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
|
||||
},
|
||||
// This enables the EPC colours for tremor. They're listed from EPC G -> A
|
||||
...[
|
||||
"[#e41e3b]",
|
||||
"[#ef8026]",
|
||||
"[#f3a96a]",
|
||||
"[#f7cd14]",
|
||||
"[#8dbd40]",
|
||||
"[#2da55c]",
|
||||
"[#117d58]",
|
||||
].flatMap((customColor) => [
|
||||
`bg-${customColor}`,
|
||||
`border-${customColor}`,
|
||||
`hover:bg-${customColor}`,
|
||||
`hover:border-${customColor}`,
|
||||
`hover:text-${customColor}`,
|
||||
`fill-${customColor}`,
|
||||
`ring-${customColor}`,
|
||||
`stroke-${customColor}`,
|
||||
`text-${customColor}`,
|
||||
`ui-selected:bg-${customColor}`,
|
||||
`ui-selected:border-${customColor}`,
|
||||
`ui-selected:text-${customColor}`,
|
||||
]),
|
||||
"bg-[#e41e3b]",
|
||||
"border-[#e41e3b]",
|
||||
"hover:bg-[#e41e3b]",
|
||||
"hover:border-[#e41e3b]",
|
||||
"hover:text-[#e41e3b]",
|
||||
"fill-[#e41e3b]",
|
||||
"ring-[#e41e3b]",
|
||||
"stroke-[#e41e3b]",
|
||||
"text-[#e41e3b]",
|
||||
"ui-selected:bg-[#e41e3b]",
|
||||
"ui-selected:border-[#e41e3b]",
|
||||
"ui-selected:text-[#e41e3b]",
|
||||
"bg-[#ef8026]",
|
||||
"border-[#ef8026]",
|
||||
"hover:bg-[#ef8026]",
|
||||
"hover:border-[#ef8026]",
|
||||
"hover:text-[#ef8026]",
|
||||
"fill-[#ef8026]",
|
||||
"ring-[#ef8026]",
|
||||
"stroke-[#ef8026]",
|
||||
"text-[#ef8026]",
|
||||
"ui-selected:bg-[#ef8026]",
|
||||
"ui-selected:border-[#ef8026]",
|
||||
"ui-selected:text-[#ef8026]",
|
||||
"bg-[#f3a96a]",
|
||||
"border-[#f3a96a]",
|
||||
"hover:bg-[#f3a96a]",
|
||||
"hover:border-[#f3a96a]",
|
||||
"hover:text-[#f3a96a]",
|
||||
"fill-[#f3a96a]",
|
||||
"ring-[#f3a96a]",
|
||||
"stroke-[#f3a96a]",
|
||||
"text-[#f3a96a]",
|
||||
"ui-selected:bg-[#f3a96a]",
|
||||
"ui-selected:border-[#f3a96a]",
|
||||
"ui-selected:text-[#f3a96a]",
|
||||
"bg-[#f7cd14]",
|
||||
"border-[#f7cd14]",
|
||||
"hover:bg-[#f7cd14]",
|
||||
"hover:border-[#f7cd14]",
|
||||
"hover:text-[#f7cd14]",
|
||||
"fill-[#f7cd14]",
|
||||
"ring-[#f7cd14]",
|
||||
"stroke-[#f7cd14]",
|
||||
"text-[#f7cd14]",
|
||||
"ui-selected:bg-[#f7cd14]",
|
||||
"ui-selected:border-[#f7cd14]",
|
||||
"ui-selected:text-[#f7cd14]",
|
||||
"bg-[#8dbd40]",
|
||||
"border-[#8dbd40]",
|
||||
"hover:bg-[#8dbd40]",
|
||||
"hover:border-[#8dbd40]",
|
||||
"hover:text-[#8dbd40]",
|
||||
"fill-[#8dbd40]",
|
||||
"ring-[#8dbd40]",
|
||||
"stroke-[#8dbd40]",
|
||||
"text-[#8dbd40]",
|
||||
"ui-selected:bg-[#8dbd40]",
|
||||
"ui-selected:border-[#8dbd40]",
|
||||
"ui-selected:text-[#8dbd40]",
|
||||
"bg-[#2da55c]",
|
||||
"border-[#2da55c]",
|
||||
"hover:bg-[#2da55c]",
|
||||
"hover:border-[#2da55c]",
|
||||
"hover:text-[#2da55c]",
|
||||
"fill-[#2da55c]",
|
||||
"ring-[#2da55c]",
|
||||
"stroke-[#2da55c]",
|
||||
"text-[#2da55c]",
|
||||
"ui-selected:bg-[#2da55c]",
|
||||
"ui-selected:border-[#2da55c]",
|
||||
"ui-selected:text-[#2da55c]",
|
||||
"bg-[#117d58]",
|
||||
"border-[#117d58]",
|
||||
"hover:bg-[#117d58]",
|
||||
"hover:border-[#117d58]",
|
||||
"hover:text-[#117d58]",
|
||||
"fill-[#117d58]",
|
||||
"ring-[#117d58]",
|
||||
"stroke-[#117d58]",
|
||||
"text-[#117d58]",
|
||||
"ui-selected:bg-[#117d58]",
|
||||
"ui-selected:border-[#117d58]",
|
||||
"ui-selected:text-[#117d58]",
|
||||
],
|
||||
plugins: [
|
||||
function ({ addVariant }) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue