diff --git a/src/app/(dashboard)/inventory/assets/[assetId]/page.tsx b/src/app/(dashboard)/inventory/assets/[assetId]/page.tsx new file mode 100644 index 0000000..1bbb435 --- /dev/null +++ b/src/app/(dashboard)/inventory/assets/[assetId]/page.tsx @@ -0,0 +1,137 @@ +"use server" + +import Link from "next/link" + +import PageHeader from "@/components/common/pageheader" +import { Button } from "@/components/ui/button" +import { getI18n } from "@/i18n/server" +import { AssetService } from "@/services/asset.service" + +import type { AssetDetailCopy, AssetStatusCopy } from "../_components/asset.copy" + +function formatAssetStatus( + status: string, + statusCopy: AssetStatusCopy, + fallback: { unknownStatus: string }, +) { + return status in statusCopy + ? statusCopy[status as keyof AssetStatusCopy] + : fallback.unknownStatus +} + +function formatDate(value: Date | null | undefined, missingValue: string) { + return value ? value.toISOString().slice(0, 10) : missingValue +} + +function formatPrice( + value: { toString(): string } | null | undefined, + missingValue: string, +) { + return value ? value.toString() : missingValue +} + +function formatPersonName( + person: + | { + firstName?: string | null + lastName?: string | null + } + | null + | undefined, + missingValue: string, +) { + if (!person) return missingValue + + const fullName = [person.firstName, person.lastName].filter(Boolean).join(" ") + return fullName || missingValue +} + +export default async function AssetDetailPage({ + params, +}: { + params: Promise<{ assetId: string }> +}) { + const { assetId } = await params + const asset = await AssetService.findById(assetId) + const { dictionary } = await getI18n() + const copy = dictionary.inventory.assets.detail as AssetDetailCopy + const statusCopy = dictionary.inventory.assets.status + const missingValue = copy.fallback?.missingValue ?? "N/A" + + if (!asset) { + return
{copy.notFound}
+ } + + return ( +
+ +
+
+
{copy.labels.item}
+
{asset.item?.name ?? missingValue}
+
+
+
+ {copy.labels.serialNumber} +
+
{asset.serialNumber}
+
+
+
{copy.labels.assetTag}
+
{asset.assetTag ?? missingValue}
+
+
+
+ {copy.labels.manufacturer} +
+
{asset.manufacturer ?? missingValue}
+
+
+
{copy.labels.model}
+
{asset.model ?? missingValue}
+
+
+
+ {copy.labels.purchaseDate} +
+
{formatDate(asset.purchaseDate, missingValue)}
+
+
+
+ {copy.labels.purchasePrice} +
+
{formatPrice(asset.purchasePrice, missingValue)}
+
+
+
+ {copy.labels.warrantyEndsAt} +
+
{formatDate(asset.warrantyEndsAt, missingValue)}
+
+
+
+ {copy.labels.deliveryNote} +
+
{asset.deliveryNote ?? missingValue}
+
+
+
{copy.labels.notes}
+
{asset.notes ?? missingValue}
+
+
+
{copy.labels.status}
+
{formatAssetStatus(asset.status, statusCopy, { unknownStatus: missingValue })}
+
+
+
{copy.labels.person}
+
{formatPersonName(asset.assignment?.person, missingValue)}
+
+
+
+ + + +
+
+ ) +} diff --git a/src/app/(dashboard)/inventory/assets/_components/asset.copy.ts b/src/app/(dashboard)/inventory/assets/_components/asset.copy.ts index a166931..85f4d23 100644 --- a/src/app/(dashboard)/inventory/assets/_components/asset.copy.ts +++ b/src/app/(dashboard)/inventory/assets/_components/asset.copy.ts @@ -3,6 +3,7 @@ import type { AssetSchemaCopy } from "@/schemas/asset.schema" export type AssetListCopy = Dictionary["inventory"]["assets"]["list"] export type AssetFormCopy = Dictionary["inventory"]["assets"]["form"] +export type AssetDetailCopy = Dictionary["inventory"]["assets"]["detail"] export type AssetStatusCopy = Dictionary["inventory"]["assets"]["status"] export type AssetFallbackCopy = Dictionary["inventory"]["assets"]["fallback"] export type { AssetSchemaCopy } diff --git a/src/app/(dashboard)/inventory/assets/_components/edit.asset.form.tsx b/src/app/(dashboard)/inventory/assets/_components/edit.asset.form.tsx index 61aa38d..a5af2c3 100644 --- a/src/app/(dashboard)/inventory/assets/_components/edit.asset.form.tsx +++ b/src/app/(dashboard)/inventory/assets/_components/edit.asset.form.tsx @@ -10,7 +10,7 @@ import { SubmitButton, type SubmitButtonCopy, } from "@/components/forms/submitButton" -import { ITEM_STATUS } from "@/lib/constants" +import { UPDATE_ASSET_STATUSES } from "@/lib/constants" import { buildUpdateAssetSchema, type UpdateAssetFormType, @@ -102,6 +102,7 @@ export default function EditAssetForm({ + {errors?.assetTag && ( +

{errors.assetTag.message}

+ )} + +
+ + + {errors?.manufacturer && ( +

{errors.manufacturer.message}

+ )} +
+
+ + + {errors?.model &&

{errors.model.message}

} +
+
+ + + {errors?.purchaseDate && ( +

{errors.purchaseDate.message}

+ )} +
+
+ + + {errors?.purchasePrice && ( +

{errors.purchasePrice.message}

+ )} +
+
+ + + {errors?.warrantyEndsAt && ( +

{errors.warrantyEndsAt.message}

+ )} +
diff --git a/src/app/(dashboard)/inventory/assets/_components/new.asset.form.tsx b/src/app/(dashboard)/inventory/assets/_components/new.asset.form.tsx index aecd380..2ebc7f8 100644 --- a/src/app/(dashboard)/inventory/assets/_components/new.asset.form.tsx +++ b/src/app/(dashboard)/inventory/assets/_components/new.asset.form.tsx @@ -10,7 +10,7 @@ import { SubmitButton, type SubmitButtonCopy, } from "@/components/forms/submitButton" -import { ITEM_STATUS } from "@/lib/constants" +import { CREATE_ASSET_STATUSES } from "@/lib/constants" import { buildCreateAssetSchema, type CreateAssetFormType, @@ -119,6 +119,95 @@ export default function NewAssetForm({

{errors?.serialNumber?.message}

)}
+
+ + + {errors?.assetTag && ( +

{errors.assetTag.message}

+ )} +
+
+ + + {errors?.manufacturer && ( +

{errors.manufacturer.message}

+ )} +
+
+ + + {errors?.model &&

{errors.model.message}

} +
+
+ + + {errors?.purchaseDate && ( +

{errors.purchaseDate.message}

+ )} +
+
+ + + {errors?.purchasePrice && ( +

{errors.purchasePrice.message}

+ )} +
+
+ + + {errors?.warrantyEndsAt && ( +

{errors.warrantyEndsAt.message}

+ )} +