Made multiple ui improvements

This commit is contained in:
Khalim Conn-Kowlessar 2023-06-02 19:16:31 +01:00
parent 3bc12fdfdb
commit 083aff0d4a
3 changed files with 191 additions and 109 deletions

View file

@ -0,0 +1,109 @@
"use client";
import { PortfolioStage } from "@/types/portfolio";
import { Badge } from "@/app/shadcn_components/ui/badge";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/app/shadcn_components/ui/hover-card";
export default function StatusBadge({
status,
isProperty = false,
}: {
status: PortfolioStage;
isProperty?: boolean;
}) {
const statusConfig = statusColor[status];
return (
<div className="flex justify-end w-full pr-4">
<HoverCard>
<HoverCardTrigger>
<Badge className={statusConfig.class}>{statusConfig.text}</Badge>
</HoverCardTrigger>
<HoverCardContent>
<div className="flex items-center">
<div>
<div
className={"w-6 h-6 rounded-full mr-2 " + statusConfig.class}
/>
</div>
<p className="text-sm text-muted-foreground">
{!isProperty
? statusConfig.hoverText
: statusConfig.propertyHoverText}
</p>
</div>
</HoverCardContent>
</HoverCard>
</div>
);
}
const statusColor: {
[key in PortfolioStage]: {
class: string;
text: string;
hoverText: string;
propertyHoverText: string;
};
} = {
scoping: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "scoping",
hoverText: "This portfolio is currently in scoping",
propertyHoverText: "This property is currently in scoping",
},
assessment: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "assessment",
hoverText: "This portfolio is currently in the assessment stage",
propertyHoverText: "This property is currently in the assessment stage",
},
tendering: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "tendering",
hoverText: "This portfolio is currently in the tendering stage",
propertyHoverText: "This property is currently in tender",
},
"project underway": {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "project underway",
hoverText: "This portfolio has begun works",
propertyHoverText: "This property has begun works",
},
"completion; status 'on track'": {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "on track",
hoverText: "This portfolio is on track to be completed on time",
propertyHoverText: "This property is on track to be completed on time",
},
"completion; status 'delayed'": {
class: "bg-orange-400 hover:bg-orange-400",
text: "delayed",
hoverText:
"This portfolio is delayed and one or more properties require attention",
propertyHoverText: "This property is delayed and requires attention",
},
"completion; status 'at risk'": {
class: "bg-red-400 hover:bg-red-400",
text: "at risk",
hoverText:
"This portfolio is at risk. One or more properties require attention",
propertyHoverText: "This property is at risk and requires attention",
},
"completion; status 'completed'": {
class: "bg-gray-400 hover:bg-gray-400",
text: "completed",
hoverText: "This portfolio has been completed",
propertyHoverText: "This property has been completed",
},
"needs review": {
class: "bg-emerald-300 hover:bg-emerald-300",
text: "needs review",
hoverText: "The works in this portfolio has been completed and need review",
propertyHoverText: "The works on this property have been completed",
},
};

View file

@ -1,16 +1,12 @@
import { PortfolioStage } from "@/types/portfolio";
import Link from "next/link";
import React from "react";
import { Badge } from "@/app/shadcn_components/ui/badge";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/app/shadcn_components/ui/hover-card";
import React, { use } from "react";
import StatusBadge from "@/app/components/StatusBadge";
import { useRouter } from "next/navigation";
const styles = {
wrapper:
"font-medium leading-none text-base tracking-wider text-gray-400 hover:text-gray-300 bg-white hover:bg-hoverblue shadow-xl hover:shadow-none cursor-pointer w-60 rounded-3xl flex flex-col items-center justify-center",
"active:bg-brandmidblue font-medium leading-none text-base tracking-wider text-gray-400 hover:text-gray-300 bg-white hover:bg-hoverblue shadow-xl hover:shadow-none cursor-pointer w-60 rounded-3xl flex flex-col items-center justify-center",
header: "relative mt-2 mx-2 border-red",
imageWrapper: "h-56 rounded-2xl overflow-hidden flex items-center",
wrapperAnime: "transition-all duration-500 ease-in-out",
@ -26,88 +22,19 @@ interface CardProps {
status: PortfolioStage;
}
function StatusBadge({ status }: { status: PortfolioStage }) {
const statusConfig = statusColor[status];
return (
<div className="flex justify-end w-full mb-1 pr-4">
<HoverCard>
<HoverCardTrigger>
<Badge className={statusConfig.class}>{statusConfig.text}</Badge>
</HoverCardTrigger>
<HoverCardContent>
<div className="flex items-center">
<div>
<div
className={"w-6 h-6 rounded-full mr-2 " + statusConfig.class}
/>
</div>
<p className="text-sm text-muted-foreground">
{statusConfig.hoverText}
</p>
</div>
</HoverCardContent>
</HoverCard>
</div>
);
}
const statusColor: {
[key in PortfolioStage]: { class: string; text: string; hoverText: string };
} = {
scoping: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "scoping",
hoverText: "This portfolio is currently in scoping",
},
assessment: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "assessment",
hoverText: "This portfolio is currently in the assessment stage",
},
tendering: {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "tendering",
hoverText: "This portfolio is currently in the tendering stage",
},
"project underway": {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "project underway",
hoverText: "This portfolio has begun works",
},
"completion; status 'on track'": {
class: "bg-emerald-500 hover:bg-emerald-500",
text: "on track",
hoverText: "This portfolio is on track to be completed on time",
},
"completion; status 'delayed'": {
class: "bg-orange-400 hover:bg-orange-400",
text: "delayed",
hoverText:
"This portfolio is delayed and one or more properties require attention",
},
"completion; status 'at risk'": {
class: "bg-red-400 hover:bg-red-400",
text: "at risk",
hoverText:
"This portfolio is at risk. One or more properties require attention",
},
"completion; status 'completed'": {
class: "bg-gray-400 hover:bg-gray-400",
text: "completed",
hoverText: "This portfolio has been completed",
},
"needs review": {
class: "bg-emerald-300 hover:bg-emerald-300",
text: "needs review",
hoverText: "The works in this portfolio has been completed and need review",
},
};
const Card = ({ id, title, image, budget, status }: CardProps) => {
const router = useRouter();
function handleClick() {
router.push(`/portfolio/${id}`);
}
return (
<Link href={`/portfolio/${id}`}>
<div className={[styles.wrapper, styles.wrapperAnime].join(" ")}>
<div>
<div
onClick={handleClick}
className={[styles.wrapper, styles.wrapperAnime].join(" ")}
>
<div className={styles.header}>
<div className={styles.imageWrapper}>
<img src={image} className={styles.image} alt="" />
@ -117,9 +44,11 @@ const Card = ({ id, title, image, budget, status }: CardProps) => {
<h1>{`${title}`}</h1>
<div>{budget}</div>
</div>
<StatusBadge status={status} />
<div className="mb-2 flex justify-end w-full">
<StatusBadge status={status} />
</div>
</div>
</Link>
</div>
);
};

View file

@ -3,8 +3,16 @@ import AddNew from "../../components/portfolio/AddNew";
import { formatNumber } from "@/app/utils";
import Link from "next/link";
import { SearchData } from "@/types/epc";
import { ArrowRightCircleIcon } from "@heroicons/react/20/solid";
import { Badge } from "@/app/shadcn_components/ui/badge";
import { PortfolioStage } from "@/types/portfolio";
import StatusBadge from "@/app/components/StatusBadge";
function generateProperties(value: number, suffix: string) {
function generateProperties(
value: number,
suffix: string,
status: PortfolioStage
) {
const length = Math.ceil(value / 30000);
return Array.from({ length }, (_, index) => ({
@ -15,6 +23,7 @@ function generateProperties(value: number, suffix: string) {
cost: 30000,
co2Reduction: 9 / 5,
targetEpcRating: "C",
status: status,
}));
}
@ -26,6 +35,7 @@ type Property = {
co2Reduction: number;
lmkKey: string;
targetEpcRating: string;
status: PortfolioStage;
};
function EmptyPropertyState() {
@ -54,27 +64,41 @@ function Propertycards({
{properties.map((property) => (
<li
key={property.id}
className="border-l-4 border-l-brandmidblue bg-white rounded-lg shadow mb-4 p-4 flex items-center justify-between"
className="bg-white rounded-lg shadow mb-4 p-4 flex items-center justify-between"
>
<div className="flex items-center ">
<div>
<HomeIcon className="h-10 w-10 mx-auto text-gray-200" />
<HomeIcon className="h-8 w-8 mx-auto text-gray-200" />
</div>
<div className="ml-4 ">
<h3 className="text-xl font-medium">{property.address}</h3>
<p className="text-gray-600">{property.postcode}</p>
<h3 className="text-xl font-medium font-semibold text-brandblue">
{property.address}
</h3>
<p className="text-sm text-muted-foreground">
{property.postcode}
</p>
</div>
<div className="ml-10">
<Badge className="bg-brandblue">
Cost: £{formatNumber(property.cost)}
</Badge>
</div>
<div className="ml-10">Cost: £{formatNumber(property.cost)}</div>
<div className="ml-4">
Co2 Savings (t): {property.co2Reduction}
<Badge className="bg-brandtan">
Co2 Savings (t): {property.co2Reduction}
</Badge>
</div>
<div className="ml-4">
<StatusBadge status={property.status} isProperty={true} />
</div>
</div>
<Link
href={`/portfolio/${portfolioId}/property/${property.lmkKey}/plan?postcode=${property.postcode}&targetEpcRating=${property.targetEpcRating}`}
className="bg-brandtan text-white rounded-lg px-4 py-2 hover:bg-hovertan transition-colors duration-200"
>
Go to Plan
<div className="w-10 h-10">
<ArrowRightCircleIcon className="text-brandblue" />
</div>
</Link>
</li>
))}
@ -101,7 +125,7 @@ export default async function Page({
id: "d290f1ee-6c54-4b01-90e6-d701748f0851",
title: "Portfolio 1",
budget: 500000,
properties: generateProperties(500000, "1") as Property[],
properties: generateProperties(500000, "1", "scoping") as Property[],
co2Reduction: 5.4,
totalWorksHours: 45,
totalValueIncrease: 500000 * 1.2,
@ -116,7 +140,7 @@ export default async function Page({
totalWorksHours: 30,
totalValueIncrease: 150000 * 1.2,
rentalYieldIncrease: 150000 * 0.002,
properties: generateProperties(150000, "2") as Property[],
properties: generateProperties(150000, "2", "assessment") as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0853",
@ -127,7 +151,7 @@ export default async function Page({
totalWorksHours: 100,
totalValueIncrease: 1000000 * 1.2,
rentalYieldIncrease: 1000000 * 0.002,
properties: generateProperties(1000000, "3") as Property[],
properties: generateProperties(1000000, "3", "tendering") as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0854",
@ -138,7 +162,7 @@ export default async function Page({
totalWorksHours: 150,
totalValueIncrease: 2000000 * 1.2,
rentalYieldIncrease: 2000000 * 0.002,
properties: generateProperties(2000000, "4") as Property[],
properties: generateProperties(2000000, "4", "tendering") as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0855",
@ -149,7 +173,11 @@ export default async function Page({
totalWorksHours: 15,
totalValueIncrease: 250000 * 1.2,
rentalYieldIncrease: 250000 * 0.002,
properties: generateProperties(250000, "5") as Property[],
properties: generateProperties(
250000,
"5",
"project underway"
) as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0856",
@ -160,7 +188,11 @@ export default async function Page({
totalWorksHours: 10,
totalValueIncrease: 410000 * 1.2,
rentalYieldIncrease: 410000 * 0.002,
properties: generateProperties(410000, "6") as Property[],
properties: generateProperties(
410000,
"6",
"completion; status 'on track'"
) as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0857",
@ -171,7 +203,11 @@ export default async function Page({
totalWorksHours: 25,
totalValueIncrease: 233000 * 1.2,
rentalYieldIncrease: 233000 * 0.002,
properties: generateProperties(233000, "7") as Property[],
properties: generateProperties(
233000,
"7",
"completion; status 'delayed'"
) as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0858",
@ -182,7 +218,11 @@ export default async function Page({
totalWorksHours: 65,
totalValueIncrease: 670000 * 1.2,
rentalYieldIncrease: 670000 * 0.002,
properties: generateProperties(670000, "8") as Property[],
properties: generateProperties(
670000,
"8",
"completion; status 'at risk'"
) as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0859",
@ -193,7 +233,11 @@ export default async function Page({
totalWorksHours: 40,
totalValueIncrease: 240000 * 1.2,
rentalYieldIncrease: 240000 * 0.002,
properties: generateProperties(240000, "9") as Property[],
properties: generateProperties(
240000,
"9",
"completion; status 'completed'"
) as Property[],
},
{
id: "d290f1ee-6c54-4b01-90e6-d701748f0860",
@ -204,7 +248,7 @@ export default async function Page({
totalWorksHours: 18,
totalValueIncrease: 93000 * 1.2,
rentalYieldIncrease: 93000 * 0.002,
properties: generateProperties(93000, "10") as Property[],
properties: generateProperties(93000, "10", "needs review") as Property[],
},
];
const demo_id = "f290f1ee-6c54-4b01-90e6-d701748f0851";