Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved asset details page #6256

Merged
merged 6 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 41 additions & 41 deletions src/Components/Assets/AssetManage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { UserRole, USER_TYPES } from "../../Common/constants";
import ConfirmDialog from "../Common/ConfirmDialog";
import RecordMeta from "../../CAREUI/display/RecordMeta";
import { useTranslation } from "react-i18next";
const PageTitle = lazy(() => import("../Common/PageTitle"));
const Loading = lazy(() => import("../Common/Loading"));
import * as Notification from "../../Utils/Notifications.js";
import AuthorizeFor, { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
Expand All @@ -35,6 +34,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser";
import dayjs from "dayjs";
import RelativeDateUserMention from "../Common/RelativeDateUserMention";
import { AssetServiceEditModal } from "./AssetServiceEditModal";
import Page from "../Common/components/Page";

interface AssetManageProps {
assetId: string;
Expand Down Expand Up @@ -329,18 +329,28 @@ const AssetManage = (props: AssetManageProps) => {
};

return (
<div className="px-2 pb-2">
<PageTitle
title="Asset Details"
crumbsReplacements={{
[facilityId]: { name: asset?.location_object.facility.name },
assets: { uri: `/assets?facility=${facilityId}` },
[assetId]: {
name: asset?.name,
},
}}
backUrl="/assets"
/>
<Page
title="Asset Details"
crumbsReplacements={{
[facilityId]: { name: asset?.location_object.facility.name },
assets: { uri: `/assets?facility=${facilityId}` },
[assetId]: {
name: asset?.name,
},
}}
backUrl="/assets"
options={
<ButtonV2
onClick={handleDownload}
className="tooltip py-2"
ghost
border
>
<CareIcon className="care-l-export text-lg" />
Export as JSON
</ButtonV2>
}
>
<ConfirmDialog
title="Delete Asset"
description="Are you sure you want to delete this asset?"
Expand All @@ -359,21 +369,22 @@ const AssetManage = (props: AssetManageProps) => {
<span className="break-words text-2xl font-bold md:text-3xl">
{asset?.name}
</span>
<ButtonV2
id="export-asset"
onClick={handleDownload}
className="tooltip p-4"
variant="secondary"
ghost
circle
>
<CareIcon className="care-l-export text-lg" />
<span className="tooltip-text tooltip-bottom -translate-x-16">
Export as JSON
</span>
</ButtonV2>
<div className="tooltip tooltip-bottom">
<CareIcon
className={`care-l-${assetClassProp.icon} fill-gray-700 text-3xl`}
/>
<span className="tooltip-text">{assetClassProp.name}</span>
</div>
</div>
<div className="mb-2 w-full text-gray-700 sm:hidden">
{asset?.description}
</div>
<div className="flex flex-wrap gap-2">
{asset?.asset_type === "INTERNAL" ? (
<Chip text="Internal" startIcon="l-building" />
) : (
<Chip text="External" startIcon="l-globe" />
)}
{asset?.status === "ACTIVE" ? (
<Chip text="Active" startIcon="l-check" />
) : (
Expand All @@ -394,7 +405,9 @@ const AssetManage = (props: AssetManageProps) => {
)}
</div>
</div>
<span className="text-gray-700">{asset?.description}</span>
<div className="mt-3 hidden text-gray-700 sm:block">
{asset?.description}
</div>
</div>
<div className="flex flex-col gap-6">
{[
Expand All @@ -403,19 +416,6 @@ const AssetManage = (props: AssetManageProps) => {
icon: "location-pin-alt",
content: asset?.location_object.name,
},
{
label: "Asset Type",
icon: "apps",
content:
asset?.asset_type === "INTERNAL"
? "Internal Asset"
: "External Asset",
},
{
label: "Asset Class",
icon: assetClassProp.icon,
content: assetClassProp.name,
},
{
label: "Asset QR Code ID",
icon: "qrcode-scan",
Expand Down Expand Up @@ -586,7 +586,7 @@ const AssetManage = (props: AssetManageProps) => {
viewOnly={serviceEditData.viewOnly}
/>
)}
</div>
</Page>
);
};

Expand Down
40 changes: 36 additions & 4 deletions src/Components/Assets/AssetWarrantyCard.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,68 @@
import CareIcon from "../../CAREUI/icons/CareIcon";
import { AssetData } from "./AssetTypes";
import { classNames, formatDate } from "../../Utils/utils";
import CopyToClipboard from "react-copy-to-clipboard";
import { t } from "i18next";
import { useEffect, useState } from "react";

export default function AssetWarrantyCard(props: { asset: AssetData }) {
const { asset } = props;

const details = {
"Serial Number": asset.serial_number,
Expiry:
"Warranty/AMC Expiry":
asset.warranty_amc_end_of_validity &&
formatDate(asset.warranty_amc_end_of_validity),
Vendor: asset.vendor_name,
};

const [isCopied, setIsCopied] = useState(false);

useEffect(() => {
if (isCopied) {
const timeout = setTimeout(() => {
setIsCopied(false);
}, 2000);
return () => clearTimeout(timeout);
}
}, [isCopied]);

return (
<div className="warranty-card relative z-10 flex h-full w-screen flex-col overflow-hidden p-6 text-white transition-all hover:scale-[1.01] hover:from-primary-600 hover:to-primary-700 md:w-full md:rounded-xl xl:w-96">
<div className="mb-3 text-right text-lg font-bold italic">
{asset.manufacturer}
</div>
<div className="flex h-full flex-col justify-between gap-6 md:flex-row xl:flex-col">
<div className="flex h-full w-full flex-col gap-4 border-b border-white/40 md:border-b-0 md:border-r xl:w-auto xl:border-b xl:border-r-0">
<div className="flex h-full flex-col justify-between gap-2 md:flex-row xl:flex-col">
<div className="flex h-full w-full flex-col gap-4 md:border-r xl:w-auto xl:border-r-0">
{Object.keys(details).map((key) => (
<div className="">
<div className="mb-1 text-xs uppercase italic tracking-widest text-gray-200">
{key}
</div>
<div className="font-semibold">
<div className="flex items-center gap-2 font-semibold">
{details[key as keyof typeof details] || "--"}
{key === "Serial Number" && (
<button className="tooltip tooltip-bottom">
<CopyToClipboard
text={details[key as keyof typeof details] || "--"}
onCopy={() => setIsCopied(true)}
>
{isCopied ? (
<span className="text-sm text-white">
{t("copied_to_clipboard")}
</span>
) : (
<CareIcon className="care-l-copy text-lg" />
)}
</CopyToClipboard>
<span className="tooltip-text">Copy to clipboard</span>
</button>
)}
</div>
</div>
))}
</div>
<div className="mb-2 hidden h-[1px] w-full bg-white/40 xl:block" />
<div className="shrink-0">
<div>
<div className="mb-1 text-xs uppercase italic tracking-widest text-gray-200">
Expand Down
Loading