Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 22x 22x 2x 24x 2x 24x 24x 24x 24x 26x 26x 19x 79x 136x 21x 79x 127x 64x 64x 2x 22x 24x 24x 2x 26x 106x | import { Badge } from "@/ahuora-design-system/ui/badge";
import type {
CostCurveEquipmentCategoryRead,
CostCurveRead,
PatchedCostCurveAuthoring,
} from "@/api/apiStore.gen";
import { EconomicsWarningNotice } from "../../shared/ui/EconomicsWarningNotice";
import { CostCurveDialog } from "../authoring/CostCurveDialog";
import {
type CostCurveDraft,
costCurveFormulaSummary,
costCurvePatchPayload,
} from "../model/payloads";
import type { CostCurveUsageSummary } from "../types";
import { CostCurveDeleteButton } from "./CostCurveDeleteButton";
import { formatCostCurveLabel } from "./labels";
export function CostCurveLibraryCard({
curve,
curves,
canEdit,
saving,
equipmentOptions,
usage,
onPatchCurve,
onDeleteCurve,
onSaved,
}: {
curve: CostCurveRead;
curves: CostCurveRead[];
canEdit: boolean;
saving: boolean;
equipmentOptions: readonly CostCurveEquipmentCategoryRead[];
usage: CostCurveUsageSummary;
onPatchCurve: (
curveId: number,
patch: PatchedCostCurveAuthoring,
) => Promise<void>;
onDeleteCurve: (curveId: number) => Promise<void>;
onSaved: (message: string) => void;
}) {
return (
<article
className="rounded-md border bg-background p-2.5"
aria-label={`Cost curve ${curve.name}`}
>
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
<div className="truncate text-sm font-medium leading-tight">
{curve.name}
</div>
<div className="mt-1 flex flex-wrap gap-1">
<Badge
variant="secondary"
size="xs"
borderRadius="round"
className="px-1.5 py-0 text-[10px] leading-4"
>
{formatCostCurveLabel(curve.equipment_category)}
</Badge>
<Badge
variant="secondary"
size="xs"
borderRadius="round"
className="px-1.5 py-0 text-[10px] leading-4"
>
Basis: {formatCostCurveLabel(curve.cost_basis)}
</Badge>
</div>
</div>
<div className="flex shrink-0 items-center gap-1">
<CostCurveDialog
curve={curve}
canEdit={canEdit}
saving={saving}
equipmentOptions={equipmentOptions}
existingCurves={curves}
onSubmit={async (draft: CostCurveDraft) => {
await onPatchCurve(curve.id, costCurvePatchPayload(draft));
onSaved("Cost curve updated");
}}
/>
<CostCurveDeleteButton
curve={curve}
canEdit={canEdit}
saving={saving}
usage={usage}
onDelete={async () => {
await onDeleteCurve(curve.id);
onSaved("Cost curve deleted");
}}
/>
</div>
</div>
<div className="mt-2 grid gap-1">
<div className="text-[11px] font-medium text-muted-foreground">
Expression
</div>
<code className="block rounded-md bg-muted/30 px-2 py-1 text-[11px] leading-4 text-foreground">
{costCurveFormulaSummary(curve)}
</code>
</div>
{curve.applicability_warning && (
<div className="mt-2">
<EconomicsWarningNotice
aria-label={`Cost curve warning for ${curve.name}`}
>
<span>{curve.applicability_warning}</span>
</EconomicsWarningNotice>
</div>
)}
</article>
);
}
|