Upload files to "src/components"
This commit is contained in:
parent
91186b4a8a
commit
4498d15e35
165
src/components/ClaimsItemsBuilder.tsx
Normal file
165
src/components/ClaimsItemsBuilder.tsx
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||||
|
|
||||||
|
import ButtonV2 from "@/components/Common/ButtonV2";
|
||||||
|
import AutocompleteFormField from "@/components/Form/FormFields/Autocomplete";
|
||||||
|
import FormField, { FieldLabel } from "@/components/Form/FormFields/FormField";
|
||||||
|
import TextFormField from "@/components/Form/FormFields/TextFormField";
|
||||||
|
import {
|
||||||
|
FieldChangeEvent,
|
||||||
|
FormFieldBaseProps,
|
||||||
|
useFormFieldPropsResolver,
|
||||||
|
} from "@/components/Form/FormFields/Utils";
|
||||||
|
|
||||||
|
import { ITEM_CATEGORIES } from "../constants";
|
||||||
|
import { HCXItemModel } from "../types";
|
||||||
|
import PMJAYProcedurePackageAutocomplete from "./PMJAYProcedurePackageAutocomplete";
|
||||||
|
|
||||||
|
type Props = FormFieldBaseProps<HCXItemModel[]>;
|
||||||
|
|
||||||
|
export default function ClaimsItemsBuilder(props: Props) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const field = useFormFieldPropsResolver(props);
|
||||||
|
|
||||||
|
const handleUpdate = (index: number) => {
|
||||||
|
return (event: FieldChangeEvent<any>) => {
|
||||||
|
if (event.name === "hbp") {
|
||||||
|
field.handleChange(
|
||||||
|
(props.value || [])?.map((obj, i) =>
|
||||||
|
i === index
|
||||||
|
? {
|
||||||
|
...obj,
|
||||||
|
id: event.value.code,
|
||||||
|
name: event.value.name,
|
||||||
|
price: event.value.price,
|
||||||
|
}
|
||||||
|
: obj,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
field.handleChange(
|
||||||
|
(props.value || [])?.map((obj, i) =>
|
||||||
|
i === index ? { ...obj, [event.name]: event.value } : obj,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = (index: number) => {
|
||||||
|
return () => {
|
||||||
|
field.handleChange((props.value || [])?.filter((obj, i) => i !== index));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField field={field}>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
{props.value?.map((obj, index) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="rounded-lg border-2 border-dashed border-secondary-200 p-4"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<FieldLabel className="my-auto !font-bold">
|
||||||
|
{t("claim__item")} {index + 1}
|
||||||
|
</FieldLabel>
|
||||||
|
{!props.disabled && (
|
||||||
|
<ButtonV2
|
||||||
|
variant="danger"
|
||||||
|
type="button"
|
||||||
|
ghost
|
||||||
|
onClick={handleRemove(index)}
|
||||||
|
disabled={props.disabled}
|
||||||
|
>
|
||||||
|
{t("remove")}
|
||||||
|
<CareIcon icon="l-trash-alt" className="text-lg" />
|
||||||
|
</ButtonV2>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="p-2">
|
||||||
|
<AutocompleteFormField
|
||||||
|
className="w-full"
|
||||||
|
required
|
||||||
|
name="category"
|
||||||
|
label={t("claim__item__category")}
|
||||||
|
options={ITEM_CATEGORIES}
|
||||||
|
optionLabel={(o) => o.display}
|
||||||
|
optionValue={(o) => o.code}
|
||||||
|
value={obj.category}
|
||||||
|
onChange={handleUpdate(index)}
|
||||||
|
disabled={props.disabled}
|
||||||
|
errorClassName="hidden"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="mt-2 grid grid-cols-4 gap-2 max-sm:grid-cols-1">
|
||||||
|
{obj.category === "HBP" && !obj.id ? (
|
||||||
|
<>
|
||||||
|
<PMJAYProcedurePackageAutocomplete
|
||||||
|
required
|
||||||
|
className="col-span-full"
|
||||||
|
labelClassName="text-sm text-secondary-700"
|
||||||
|
label={t("claim__item__procedure")}
|
||||||
|
name="hbp"
|
||||||
|
value={obj}
|
||||||
|
onChange={handleUpdate(index)}
|
||||||
|
errorClassName="hidden"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<TextFormField
|
||||||
|
className="col-span-1"
|
||||||
|
required
|
||||||
|
name="id"
|
||||||
|
label={t("claim__item__id")}
|
||||||
|
placeholder={t("claim__item__id__example")}
|
||||||
|
onChange={handleUpdate(index)}
|
||||||
|
value={obj.id}
|
||||||
|
disabled={props.disabled}
|
||||||
|
errorClassName="hidden"
|
||||||
|
/>
|
||||||
|
<TextFormField
|
||||||
|
className="col-span-2"
|
||||||
|
required
|
||||||
|
name="name"
|
||||||
|
label={t("claim__item__name")}
|
||||||
|
placeholder={t("claim__item__name__example")}
|
||||||
|
value={obj.name}
|
||||||
|
onChange={handleUpdate(index)}
|
||||||
|
disabled={props.disabled}
|
||||||
|
errorClassName="hidden"
|
||||||
|
/>
|
||||||
|
<TextFormField
|
||||||
|
className="col-span-1"
|
||||||
|
required
|
||||||
|
type="number"
|
||||||
|
name="price"
|
||||||
|
min={0}
|
||||||
|
label={t("claim__item__price")}
|
||||||
|
placeholder={t("claim__item__price__example")}
|
||||||
|
value={obj.price?.toString()}
|
||||||
|
onChange={(event) =>
|
||||||
|
handleUpdate(index)({
|
||||||
|
name: event.name,
|
||||||
|
value: parseFloat(event.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={props.disabled}
|
||||||
|
errorClassName="hidden"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</FormField>
|
||||||
|
);
|
||||||
|
}
|
267
src/components/CreateClaimCard.tsx
Normal file
267
src/components/CreateClaimCard.tsx
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||||
|
|
||||||
|
import ButtonV2, { Submit } from "@/components/Common/ButtonV2";
|
||||||
|
import DialogModal from "@/components/Common/Dialog";
|
||||||
|
import { ProcedureType } from "@/components/Common/prescription-builder/ProcedureBuilder";
|
||||||
|
import { SelectFormField } from "@/components/Form/FormFields/SelectFormField";
|
||||||
|
import PatientInsuranceDetailsEditor from "@/components/HCX/PatientInsuranceDetailsEditor";
|
||||||
|
import HCXPolicyEligibilityCheck from "@/components/HCX/PolicyEligibilityCheck";
|
||||||
|
import { HCXPolicyModel } from "@/components/HCX/models";
|
||||||
|
|
||||||
|
import * as Notification from "@/Utils/Notifications";
|
||||||
|
import coreRoutes from "@/Utils/request/api";
|
||||||
|
import request from "@/Utils/request/request";
|
||||||
|
import useQuery from "@/Utils/request/useQuery";
|
||||||
|
import { classNames, formatCurrency } from "@/Utils/utils";
|
||||||
|
|
||||||
|
import routes from "../api";
|
||||||
|
import { HCXClaimModel, HCXItemModel } from "../types";
|
||||||
|
import ClaimCreatedModal from "./ClaimCreatedModal";
|
||||||
|
import ClaimsItemsBuilder from "./ClaimsItemsBuilder";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
consultationId: string;
|
||||||
|
patientId: string;
|
||||||
|
setIsCreating: (creating: boolean) => void;
|
||||||
|
isCreating: boolean;
|
||||||
|
use?: "preauthorization" | "claim";
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CreateClaimCard({
|
||||||
|
consultationId,
|
||||||
|
patientId,
|
||||||
|
setIsCreating,
|
||||||
|
isCreating,
|
||||||
|
use = "preauthorization",
|
||||||
|
}: Props) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [showAddPolicy, setShowAddPolicy] = useState(false);
|
||||||
|
const [policy, setPolicy] = useState<HCXPolicyModel>();
|
||||||
|
const [items, setItems] = useState<HCXItemModel[]>();
|
||||||
|
const [itemsError, setItemsError] = useState<string>();
|
||||||
|
const [createdClaim, setCreatedClaim] = useState<HCXClaimModel>();
|
||||||
|
const [use_, setUse_] = useState(use);
|
||||||
|
|
||||||
|
const { res: consultationRes, data: consultationData } = useQuery(
|
||||||
|
coreRoutes.getConsultation,
|
||||||
|
{ pathParams: { id: consultationId }, prefetch: !!consultationId },
|
||||||
|
);
|
||||||
|
|
||||||
|
const autoFill = async (policy?: HCXPolicyModel) => {
|
||||||
|
if (!policy) {
|
||||||
|
setItems([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { res, data: latestApprovedPreAuth } = await request(
|
||||||
|
routes.hcx.claims.list,
|
||||||
|
{
|
||||||
|
query: {
|
||||||
|
consultation: consultationId,
|
||||||
|
policy: policy.id,
|
||||||
|
ordering: "-modified_date",
|
||||||
|
use: "preauthorization",
|
||||||
|
outcome: "complete",
|
||||||
|
limit: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res?.ok && latestApprovedPreAuth?.results.length !== 0) {
|
||||||
|
setItems(latestApprovedPreAuth?.results[0].items ?? []);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (consultationRes?.ok && Array.isArray(consultationData?.procedure)) {
|
||||||
|
setItems(
|
||||||
|
consultationData.procedure.map((obj: ProcedureType) => {
|
||||||
|
return {
|
||||||
|
id: obj.procedure ?? "",
|
||||||
|
name: obj.procedure ?? "",
|
||||||
|
price: 0.0,
|
||||||
|
category: "900000", // provider's packages
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setItems([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const validate = () => {
|
||||||
|
if (!policy) {
|
||||||
|
Notification.Error({ msg: t("select_policy") });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (policy?.outcome !== "Complete") {
|
||||||
|
Notification.Error({ msg: t("select_eligible_policy") });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!items || items.length === 0) {
|
||||||
|
setItemsError(t("claim__item__add_at_least_one"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (items?.some((p) => !p.id || !p.name || p.price === 0 || !p.category)) {
|
||||||
|
setItemsError(t("claim__item__fill_all_details"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!validate()) return;
|
||||||
|
|
||||||
|
setIsCreating(true);
|
||||||
|
|
||||||
|
const { res, data } = await request(routes.hcx.claims.create, {
|
||||||
|
body: {
|
||||||
|
policy: policy?.id,
|
||||||
|
items,
|
||||||
|
consultation: consultationId,
|
||||||
|
use: use_,
|
||||||
|
},
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res?.ok && data) {
|
||||||
|
setItems([]);
|
||||||
|
setItemsError(undefined);
|
||||||
|
setPolicy(undefined);
|
||||||
|
setCreatedClaim(data);
|
||||||
|
} else {
|
||||||
|
Notification.Error({ msg: t(`claim__failed_to_create_${use_}`) });
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsCreating(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-8">
|
||||||
|
{createdClaim && (
|
||||||
|
<ClaimCreatedModal
|
||||||
|
show
|
||||||
|
claim={createdClaim}
|
||||||
|
onClose={() => setCreatedClaim(undefined)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DialogModal
|
||||||
|
title={t("edit_policy")}
|
||||||
|
show={showAddPolicy}
|
||||||
|
onClose={() => setShowAddPolicy(false)}
|
||||||
|
description={t("edit_policy_description")}
|
||||||
|
className="w-full max-w-screen-md"
|
||||||
|
>
|
||||||
|
<PatientInsuranceDetailsEditor
|
||||||
|
patient={patientId}
|
||||||
|
onCancel={() => setShowAddPolicy(false)}
|
||||||
|
/>
|
||||||
|
</DialogModal>
|
||||||
|
|
||||||
|
{/* Check Insurance Policy Eligibility */}
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="flex items-center justify-between gap-2 pb-4 max-sm:flex-col max-sm:items-start">
|
||||||
|
<h1 className="text-lg font-bold">{t("check_policy_eligibility")}</h1>
|
||||||
|
<ButtonV2
|
||||||
|
id="edit-insurance-policy"
|
||||||
|
className="w-fit"
|
||||||
|
onClick={() => setShowAddPolicy(true)}
|
||||||
|
ghost
|
||||||
|
border
|
||||||
|
>
|
||||||
|
<CareIcon icon="l-edit-alt" className="text-lg" />
|
||||||
|
{t("edit_policy")}
|
||||||
|
</ButtonV2>
|
||||||
|
</div>
|
||||||
|
<HCXPolicyEligibilityCheck
|
||||||
|
patient={patientId}
|
||||||
|
onEligiblePolicySelected={(policy) => {
|
||||||
|
setPolicy(policy);
|
||||||
|
autoFill(policy);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Procedures */}
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
<div className="flex w-full items-center justify-between">
|
||||||
|
<h1 className="text-left text-lg font-bold">{t("claim__items")}</h1>
|
||||||
|
<ButtonV2
|
||||||
|
type="button"
|
||||||
|
variant="alert"
|
||||||
|
border
|
||||||
|
ghost={items?.length !== 0}
|
||||||
|
disabled={items === undefined || !policy}
|
||||||
|
onClick={() =>
|
||||||
|
setItems([...(items ?? []), { name: "", id: "", price: 0 }])
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CareIcon icon="l-plus" className="text-lg" />
|
||||||
|
<span>{t("claim__add_item")}</span>
|
||||||
|
</ButtonV2>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={classNames(
|
||||||
|
policy ? "opacity-0" : "opacity-100",
|
||||||
|
"text-secondary-700 transition-opacity duration-300 ease-in-out",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{t("select_policy_to_add_items")}
|
||||||
|
</span>
|
||||||
|
<ClaimsItemsBuilder
|
||||||
|
disabled={items === undefined || !policy}
|
||||||
|
name="items"
|
||||||
|
value={items}
|
||||||
|
onChange={({ value }) => setItems(value)}
|
||||||
|
error={itemsError}
|
||||||
|
/>
|
||||||
|
<div className="text-right sm:pr-8">
|
||||||
|
{t("total_amount")} :{" "}
|
||||||
|
{items ? (
|
||||||
|
<span className="font-bold tracking-wider">
|
||||||
|
{formatCurrency(
|
||||||
|
items.map((p) => p.price).reduce((a, b) => a + b, 0.0),
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
"--"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-4 flex items-center justify-between max-sm:flex-col">
|
||||||
|
<SelectFormField
|
||||||
|
name="use"
|
||||||
|
label={t("claim__use")}
|
||||||
|
labelClassName="max-sm:hidden"
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
id: "preauthorization",
|
||||||
|
label: t("claim__use__preauthorization"),
|
||||||
|
},
|
||||||
|
{ id: "claim", label: t("claim__use__claim") },
|
||||||
|
]}
|
||||||
|
value={use_}
|
||||||
|
onChange={({ value }) => setUse_(value)}
|
||||||
|
position="below"
|
||||||
|
className="w-52 max-sm:w-full"
|
||||||
|
optionLabel={(value) => value.label}
|
||||||
|
optionValue={(value) => value.id as "preauthorization" | "claim"}
|
||||||
|
/>
|
||||||
|
<Submit
|
||||||
|
disabled={items?.length === 0 || !policy || isCreating}
|
||||||
|
onClick={handleSubmit}
|
||||||
|
className="w-52 max-sm:w-full"
|
||||||
|
>
|
||||||
|
{isCreating && <CareIcon icon="l-spinner" className="animate-spin" />}
|
||||||
|
{isCreating
|
||||||
|
? t(`claim__creating_${use_}`)
|
||||||
|
: t(`claim__create_${use_}`)}
|
||||||
|
</Submit>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
45
src/components/ManagePatientOptions.tsx
Normal file
45
src/components/ManagePatientOptions.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { triggerGoal } from "@core/Integrations/Plausible";
|
||||||
|
import { Link } from "raviger";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||||
|
|
||||||
|
import useAuthUser from "@/hooks/useAuthUser";
|
||||||
|
|
||||||
|
import { ManagePatientOptionsComponentType } from "@/pluginTypes";
|
||||||
|
|
||||||
|
const ManagePatientOptions: ManagePatientOptionsComponentType = ({
|
||||||
|
patient,
|
||||||
|
consultation,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const authUser = useAuthUser();
|
||||||
|
|
||||||
|
if (!consultation) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Link
|
||||||
|
className="dropdown-item-primary pointer-events-auto m-2 flex cursor-pointer items-center justify-start gap-2 rounded border-0 p-2 text-sm font-normal transition-all duration-200 ease-in-out"
|
||||||
|
href={`/facility/${patient.facility}/patient/${patient.id}/consultation/${consultation.id}/claims`}
|
||||||
|
onClick={() => {
|
||||||
|
triggerGoal("Patient Card Button Clicked", {
|
||||||
|
buttonName: t("claims"),
|
||||||
|
consultationId: consultation?.id,
|
||||||
|
userId: authUser?.id,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CareIcon
|
||||||
|
icon="l-copy-landscape"
|
||||||
|
className="text-lg text-primary-500"
|
||||||
|
/>
|
||||||
|
<span>{t("claims")}</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ManagePatientOptions;
|
68
src/components/PMJAYProcedurePackageAutocomplete.tsx
Normal file
68
src/components/PMJAYProcedurePackageAutocomplete.tsx
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import {
|
||||||
|
FormFieldBaseProps,
|
||||||
|
useFormFieldPropsResolver,
|
||||||
|
} from "@/components/Form/FormFields/Utils";
|
||||||
|
|
||||||
|
import { Autocomplete } from "@/components/Form/FormFields/Autocomplete";
|
||||||
|
import FormField from "@/components/Form/FormFields/FormField";
|
||||||
|
import { mergeQueryOptions } from "@/Utils/utils";
|
||||||
|
import routes from "../api";
|
||||||
|
import useQuery from "@/Utils/request/useQuery";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export type PMJAYPackageItem = {
|
||||||
|
name?: string;
|
||||||
|
code?: string;
|
||||||
|
price?: number;
|
||||||
|
package_name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = FormFieldBaseProps<PMJAYPackageItem>;
|
||||||
|
|
||||||
|
export default function PMJAYProcedurePackageAutocomplete(props: Props) {
|
||||||
|
const field = useFormFieldPropsResolver(props);
|
||||||
|
|
||||||
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
|
const { data, loading } = useQuery(routes.hcx.claims.listPMJYPackages, {
|
||||||
|
query: { query, limit: 10 },
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormField field={field}>
|
||||||
|
<Autocomplete
|
||||||
|
required
|
||||||
|
id={field.id}
|
||||||
|
disabled={field.disabled}
|
||||||
|
value={field.value}
|
||||||
|
onChange={field.handleChange}
|
||||||
|
options={mergeQueryOptions(
|
||||||
|
(field.value ? [field.value] : []).map((o) => ({
|
||||||
|
...o,
|
||||||
|
price:
|
||||||
|
o.price && parseFloat(o.price?.toString().replaceAll(",", "")),
|
||||||
|
})),
|
||||||
|
data ?? [],
|
||||||
|
(obj) => obj.code,
|
||||||
|
)}
|
||||||
|
optionLabel={optionLabel}
|
||||||
|
optionDescription={optionDescription}
|
||||||
|
optionValue={(option) => option}
|
||||||
|
onQuery={setQuery}
|
||||||
|
isLoading={loading}
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const optionLabel = (option: PMJAYPackageItem) => {
|
||||||
|
if (option.name) return option.name;
|
||||||
|
if (option.package_name) return `${option.package_name} (Package)`;
|
||||||
|
return "Unknown";
|
||||||
|
};
|
||||||
|
|
||||||
|
const optionDescription = (option: PMJAYPackageItem) => {
|
||||||
|
const code = option.code || "Unknown";
|
||||||
|
const packageName = option.package_name || "Unknown";
|
||||||
|
return `Package: ${packageName} (${code})`;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user