Upload files to "src/components"
This commit is contained in:
parent
91c29219c2
commit
91186b4a8a
@ -1 +1,78 @@
|
||||
aa
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useMessageListener } from "@/hooks/useMessageListener";
|
||||
|
||||
import * as Notification from "@/Utils/Notifications";
|
||||
import useQuery from "@/Utils/request/useQuery";
|
||||
import { AdditionalDischargeProceduresComponentType } from "@/pluginTypes";
|
||||
|
||||
import routes from "../api";
|
||||
import { HCXClaimModel } from "../types";
|
||||
import ClaimCard from "./ClaimCard";
|
||||
import CreateClaimCard from "./CreateClaimCard";
|
||||
|
||||
const AdditionalDischargeProcedures: AdditionalDischargeProceduresComponentType =
|
||||
({ consultation }) => {
|
||||
const { t } = useTranslation();
|
||||
const [latestClaim, setLatestClaim] = useState<HCXClaimModel>();
|
||||
const [isCreateClaimLoading, setIsCreateClaimLoading] = useState(false);
|
||||
|
||||
const { refetch: refetchLatestClaim } = useQuery(routes.hcx.claims.list, {
|
||||
query: {
|
||||
consultation: consultation.id,
|
||||
ordering: "-modified_date",
|
||||
use: "claim",
|
||||
outcome: "complete",
|
||||
limit: 1,
|
||||
},
|
||||
onResponse: (res) => {
|
||||
if (!isCreateClaimLoading) return;
|
||||
|
||||
setIsCreateClaimLoading(false);
|
||||
|
||||
if (res?.data?.results?.length !== 0) {
|
||||
setLatestClaim(res?.data?.results[0]);
|
||||
Notification.Success({
|
||||
msg: t("claim__fetched_claim_approval_results"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setLatestClaim(undefined);
|
||||
Notification.Success({
|
||||
msg: t("claim__error_fetching_claim_approval_results"),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
useMessageListener((data) => {
|
||||
if (
|
||||
data.type === "MESSAGE" &&
|
||||
(data.from === "claim/on_submit" ||
|
||||
data.from === "preauth/on_submit") &&
|
||||
data.message === "success"
|
||||
) {
|
||||
refetchLatestClaim();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="my-5 rounded p-5 shadow">
|
||||
<h2 className="mb-2">{t("claim_insurance")}</h2>
|
||||
{latestClaim ? (
|
||||
<ClaimCard claim={latestClaim} />
|
||||
) : (
|
||||
<CreateClaimCard
|
||||
consultationId={consultation.id ?? ""}
|
||||
patientId={consultation.patient ?? ""}
|
||||
use="claim"
|
||||
isCreating={isCreateClaimLoading}
|
||||
setIsCreating={setIsCreateClaimLoading}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdditionalDischargeProcedures;
|
||||
|
55
src/components/ClaimCard.tsx
Normal file
55
src/components/ClaimCard.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import { useLayoutEffect, useRef, useState } from "react";
|
||||
|
||||
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||
import ClaimCardCommunication from "./ClaimCardCommunication";
|
||||
import ClaimCardInfo from "./ClaimCardInfo";
|
||||
import { HCXClaimModel } from "../types";
|
||||
|
||||
interface IProps {
|
||||
claim: HCXClaimModel;
|
||||
}
|
||||
|
||||
export default function ClaimCard({ claim }: IProps) {
|
||||
const [showMessages, setShowMessages] = useState(false);
|
||||
const [containerDimensions, setContainerDimensions] = useState({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
const cardContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (cardContainerRef.current) {
|
||||
setContainerDimensions({
|
||||
width: cardContainerRef.current.offsetWidth,
|
||||
height: cardContainerRef.current.offsetHeight,
|
||||
});
|
||||
}
|
||||
}, [cardContainerRef]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative flex justify-end">
|
||||
<CareIcon
|
||||
icon={showMessages ? "l-info-circle" : "l-chat"}
|
||||
className="absolute right-0 top-0 z-30 h-7 w-7 cursor-pointer text-gray-600 hover:text-gray-800"
|
||||
onClick={() => setShowMessages((prev) => !prev)}
|
||||
/>
|
||||
</div>
|
||||
{showMessages ? (
|
||||
<div
|
||||
style={{ ...containerDimensions }}
|
||||
className="relative w-full px-2 lg:px-8"
|
||||
>
|
||||
<ClaimCardCommunication claim={claim} />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
ref={cardContainerRef}
|
||||
className="w-full px-2 lg:px-8" // TODO: add a card flip animation
|
||||
>
|
||||
<ClaimCardInfo claim={claim} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
304
src/components/ClaimCardCommunication.tsx
Normal file
304
src/components/ClaimCardCommunication.tsx
Normal file
@ -0,0 +1,304 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||
|
||||
import ButtonV2 from "@/components/Common/ButtonV2";
|
||||
import TextAreaFormField from "@/components/Form/FormFields/TextAreaFormField";
|
||||
import { FileUploadModel } from "@/components/Patient/models";
|
||||
|
||||
import useFileUpload from "@/hooks/useFileUpload";
|
||||
|
||||
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 } from "@/Utils/utils";
|
||||
|
||||
import routes from "../api";
|
||||
import { HCXClaimModel, HCXCommunicationModel } from "../types";
|
||||
|
||||
interface IProps {
|
||||
claim: HCXClaimModel;
|
||||
}
|
||||
|
||||
export default function ClaimCardCommunication({ claim }: IProps) {
|
||||
const { t } = useTranslation();
|
||||
const [inputText, setInputText] = useState("");
|
||||
const [isSendingCommunication, setIsSendingCommunication] = useState(false);
|
||||
|
||||
const {
|
||||
Input,
|
||||
files,
|
||||
error,
|
||||
removeFile,
|
||||
clearFiles,
|
||||
handleFileUpload,
|
||||
validateFiles,
|
||||
} = useFileUpload({
|
||||
multiple: true,
|
||||
type: "COMMUNICATION",
|
||||
allowedExtensions: [".pdf", ".jpg", ".jpeg", ".png"],
|
||||
});
|
||||
|
||||
const { data: communicationsResult, refetch: refetchCommunications } =
|
||||
useQuery(routes.hcx.communications.list, {
|
||||
query: {
|
||||
claim: claim.id,
|
||||
ordering: "-created_date",
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!claim.id) return;
|
||||
|
||||
if (!validateFiles()) return;
|
||||
|
||||
setIsSendingCommunication(true);
|
||||
|
||||
const { res, data } = await request(routes.hcx.communications.create, {
|
||||
body: {
|
||||
claim: claim.id,
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
data: inputText,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
if (res?.status === 201 && data) {
|
||||
await handleFileUpload(data.id as string);
|
||||
|
||||
const { res } = await request(routes.hcx.communications.send, {
|
||||
body: {
|
||||
communication: data.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (res?.ok) {
|
||||
Notification.Success({ msg: t("communication__sent_to_hcx") });
|
||||
|
||||
await refetchCommunications();
|
||||
|
||||
setInputText("");
|
||||
clearFiles();
|
||||
}
|
||||
}
|
||||
|
||||
setIsSendingCommunication(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-full !w-full flex-col justify-end">
|
||||
<CommunicationChatInterface
|
||||
communications={communicationsResult?.results ?? []}
|
||||
/>
|
||||
|
||||
<div className="flex w-full items-center gap-3 max-md:flex-col">
|
||||
<div className="relative w-full flex-1">
|
||||
<div className="absolute bottom-full flex max-w-full items-center gap-2 overflow-x-auto rounded-md bg-white p-2">
|
||||
{files.map((file, i) => (
|
||||
<div
|
||||
key={file.name}
|
||||
className="flex min-w-36 max-w-36 items-center gap-2"
|
||||
>
|
||||
<div>
|
||||
{file.type.includes("image") ? (
|
||||
<img
|
||||
src={URL.createObjectURL(file)}
|
||||
alt={file.name}
|
||||
className="h-10 w-10 rounded object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded bg-gray-300">
|
||||
<CareIcon icon="l-file" className="h-5 w-5" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<p className="w-24 truncate text-sm">{file.name}</p>
|
||||
<div className="flex !items-center gap-2.5">
|
||||
<p className="text-xs text-gray-500">
|
||||
{(file.size / 1024).toFixed(2)} KB
|
||||
</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
removeFile(i);
|
||||
}}
|
||||
>
|
||||
<CareIcon
|
||||
icon="l-trash"
|
||||
className="h-4 w-4 text-danger-500"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<TextAreaFormField
|
||||
name="message"
|
||||
value={inputText}
|
||||
onChange={(e) => setInputText(e.value)}
|
||||
placeholder={t("enter_message")}
|
||||
rows={1}
|
||||
className="-mb-3 flex-1"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-center max-md:w-full">
|
||||
<label className="button-size-default button-shape-square button-primary-default inline-flex h-min w-full cursor-pointer items-center justify-center gap-2 whitespace-pre font-medium outline-offset-1 transition-all duration-200 ease-in-out">
|
||||
<CareIcon icon="l-paperclip" className="h-5 w-5" />
|
||||
<span className="md:hidden">{t("add_attachments")}</span>
|
||||
<Input />
|
||||
</label>
|
||||
</div>
|
||||
<ButtonV2
|
||||
disabled={!inputText}
|
||||
loading={isSendingCommunication}
|
||||
onClick={handleSubmit}
|
||||
className="max-md:w-full"
|
||||
>
|
||||
{t("send_message")}
|
||||
</ButtonV2>
|
||||
</div>
|
||||
{error && (
|
||||
<p className="pt-1.5 text-xs font-medium text-danger-600">{error}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ICommunicationChatInterfaceProps {
|
||||
communications: HCXCommunicationModel[];
|
||||
}
|
||||
|
||||
function CommunicationChatInterface({
|
||||
communications,
|
||||
}: ICommunicationChatInterfaceProps) {
|
||||
return (
|
||||
<div className="my-3 flex h-full w-full flex-col-reverse gap-4 overflow-y-auto">
|
||||
{communications?.map((communication) => (
|
||||
<CommunicationChatMessage communication={communication} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ICommunicationChatMessageProps {
|
||||
communication: HCXCommunicationModel;
|
||||
}
|
||||
|
||||
function CommunicationChatMessage({
|
||||
communication,
|
||||
}: ICommunicationChatMessageProps) {
|
||||
const { t } = useTranslation();
|
||||
const [attachments, setAttachments] = useState<null | FileUploadModel[]>(
|
||||
null,
|
||||
);
|
||||
const [isFetchingAttachments, setIsFetchingAttachments] = useState(false);
|
||||
const [isDownloadingAttachment, setIsDownloadingAttachment] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"mb-4 flex flex-col gap-2",
|
||||
communication.created_by ? "items-end pr-2" : "items-start pl-2",
|
||||
)}
|
||||
>
|
||||
{communication.content?.map((message) => (
|
||||
<p
|
||||
className={classNames(
|
||||
"ml-2 px-4 py-3 text-white",
|
||||
communication.created_by
|
||||
? "rounded-bl-3xl rounded-tl-3xl rounded-tr-xl bg-blue-400"
|
||||
: "rounded-br-3xl rounded-tl-xl rounded-tr-3xl bg-gray-500",
|
||||
)}
|
||||
>
|
||||
{message.data}
|
||||
</p>
|
||||
))}
|
||||
{attachments ? (
|
||||
<div className="flex max-w-full items-center gap-2 overflow-x-auto pb-2.5">
|
||||
{attachments.length === 0 ? (
|
||||
<p className="text-sm text-secondary-600">
|
||||
{t("no_attachments_found")}
|
||||
</p>
|
||||
) : (
|
||||
attachments.map((attachment) => (
|
||||
<div
|
||||
key={attachment.id}
|
||||
className="flex min-w-36 max-w-36 items-center gap-2"
|
||||
>
|
||||
<div>
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded bg-gray-300">
|
||||
<CareIcon icon="l-file" className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-start gap-1">
|
||||
<p className="w-24 truncate text-sm">{attachment.name}</p>
|
||||
<button
|
||||
disabled={isDownloadingAttachment}
|
||||
onClick={async () => {
|
||||
if (!attachment.id) return;
|
||||
|
||||
setIsDownloadingAttachment(true);
|
||||
|
||||
const { res, data } = await request(
|
||||
coreRoutes.retrieveUpload,
|
||||
{
|
||||
query: {
|
||||
file_type: "COMMUNICATION",
|
||||
associating_id: communication.id,
|
||||
},
|
||||
pathParams: { id: attachment.id },
|
||||
},
|
||||
);
|
||||
|
||||
if (res?.ok) {
|
||||
const url = data?.read_signed_url;
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
|
||||
setIsDownloadingAttachment(false);
|
||||
}}
|
||||
className="cursor-pointer text-xs text-blue-500 hover:text-blue-700 hover:underline"
|
||||
>
|
||||
{t("open")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
onClick={async () => {
|
||||
setIsFetchingAttachments(true);
|
||||
|
||||
const { res, data } = await request(coreRoutes.viewUpload, {
|
||||
query: {
|
||||
file_type: "COMMUNICATION",
|
||||
associating_id: communication.id,
|
||||
is_archived: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (res?.ok) {
|
||||
Notification.Success({
|
||||
msg: t("fetched_attachments_successfully"),
|
||||
});
|
||||
setAttachments(data?.results ?? []);
|
||||
}
|
||||
|
||||
setIsFetchingAttachments(false);
|
||||
}}
|
||||
className="cursor-pointer text-sm text-secondary-700 hover:text-secondary-900 hover:underline"
|
||||
>
|
||||
{isFetchingAttachments ? t("fetching") + "..." : t("see_attachments")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
168
src/components/ClaimCardInfo.tsx
Normal file
168
src/components/ClaimCardInfo.tsx
Normal file
@ -0,0 +1,168 @@
|
||||
import { classNames, formatCurrency, formatDateTime } from "@/Utils/utils";
|
||||
|
||||
import { HCXClaimModel } from "../types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface IProps {
|
||||
claim: HCXClaimModel;
|
||||
}
|
||||
|
||||
const claimStatus = {
|
||||
PENDING: "pending",
|
||||
APPROVED: "approved",
|
||||
REJECTED: "rejected",
|
||||
};
|
||||
|
||||
export default function ClaimCardInfo({ claim }: IProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const status =
|
||||
claim.outcome === "Complete"
|
||||
? claim.error_text
|
||||
? claimStatus.REJECTED
|
||||
: claimStatus.APPROVED
|
||||
: claimStatus.PENDING;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sm:flex sm:items-end">
|
||||
<div className="sm:flex-auto">
|
||||
<h1 className="text-xl font-semibold text-secondary-700">
|
||||
#{claim.id?.slice(0, 5)}
|
||||
</h1>
|
||||
|
||||
<p className="mt-2 text-sm text-secondary-700">
|
||||
{t("created_on")}{" "}
|
||||
<time dateTime={claim.created_date}>
|
||||
{formatDateTime(claim.created_date ?? "")}
|
||||
</time>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 flex flex-row-reverse items-center justify-center gap-3 max-sm:justify-end sm:ml-16 sm:mt-0">
|
||||
{claim.use && (
|
||||
<span className="rounded bg-primary-100 p-1 px-2 text-sm font-bold text-primary-500 shadow">
|
||||
{claim.use}
|
||||
</span>
|
||||
)}
|
||||
<span
|
||||
className={classNames(
|
||||
"rounded p-1 px-2 text-sm font-bold text-white shadow",
|
||||
status === claimStatus.APPROVED && "bg-primary-400",
|
||||
status === claimStatus.REJECTED && "bg-danger-400",
|
||||
status === claimStatus.PENDING && "bg-yellow-400",
|
||||
)}
|
||||
>
|
||||
{t(`claim__status__${status}`)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 grid gap-4 sm:grid-cols-2">
|
||||
<div className="text-center">
|
||||
<h2 className="text-lg font-bold text-secondary-800">
|
||||
{claim.policy_object?.policy_id || "NA"}
|
||||
</h2>
|
||||
<p className="text-sm text-secondary-500">{t("policy__policy_id")}</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h2 className="text-lg font-bold text-secondary-800">
|
||||
{claim.policy_object?.subscriber_id || "NA"}
|
||||
</h2>
|
||||
<p className="text-sm text-secondary-500">
|
||||
{t("policy__subscriber_id")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h2 className="text-lg font-bold text-secondary-800">
|
||||
{claim.policy_object?.insurer_id?.split("@").shift() || "NA"}
|
||||
</h2>
|
||||
<p className="text-sm text-secondary-500">
|
||||
{t("policy__insurer_id")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<h2 className="text-lg font-bold text-secondary-800">
|
||||
{claim.policy_object?.insurer_name || "NA"}
|
||||
</h2>
|
||||
<p className="text-sm text-secondary-500">
|
||||
{t("policy__insurer_name")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="-mx-6 mt-8 flow-root sm:mx-0">
|
||||
<table className="min-w-full divide-y divide-secondary-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
className="py-3.5 pl-6 pr-3 text-left text-sm font-semibold text-secondary-900 sm:pl-0"
|
||||
>
|
||||
{t("claim__items")}
|
||||
</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th
|
||||
scope="col"
|
||||
className="py-3.5 pl-3 pr-6 text-right text-sm font-semibold text-secondary-900 sm:pr-0"
|
||||
>
|
||||
{t("claim__item__price")}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{claim.items?.map((item) => (
|
||||
<tr key={item.id} className="border-b border-secondary-200">
|
||||
<td className="py-4 pl-6 pr-3 text-sm sm:pl-0">
|
||||
<div className="font-medium text-secondary-900">
|
||||
{item.name}
|
||||
</div>
|
||||
<div className="mt-0.5 text-secondary-500">{item.id}</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td className="py-4 pl-3 pr-6 text-right text-sm text-secondary-500 sm:pr-0">
|
||||
{formatCurrency(item.price)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th
|
||||
scope="row"
|
||||
colSpan={3}
|
||||
className="table-cell pl-6 pr-3 pt-6 text-right text-sm font-normal text-secondary-500 sm:pl-0"
|
||||
>
|
||||
{t("claim__total_claim_amount")}
|
||||
</th>
|
||||
<td className="pl-3 pr-6 pt-6 text-right text-sm text-secondary-500 sm:pr-0">
|
||||
{claim.total_claim_amount &&
|
||||
formatCurrency(claim.total_claim_amount)}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th
|
||||
scope="row"
|
||||
colSpan={3}
|
||||
className="table-cell pl-6 pr-3 pt-4 text-right text-sm font-semibold text-secondary-900 sm:pl-0"
|
||||
>
|
||||
{t("claim__total_approved_amount")}
|
||||
</th>
|
||||
<td className="pl-3 pr-6 pt-4 text-right text-sm font-semibold text-secondary-900 sm:pr-0">
|
||||
{claim.total_amount_approved
|
||||
? formatCurrency(claim.total_amount_approved)
|
||||
: "NA"}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
{claim.error_text && (
|
||||
<div className="mt-4 text-center text-sm font-bold text-red-500">
|
||||
{claim.error_text}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
66
src/components/ClaimCreatedModal.tsx
Normal file
66
src/components/ClaimCreatedModal.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import CareIcon from "@/CAREUI/icons/CareIcon";
|
||||
|
||||
import { Submit } from "@/components/Common/ButtonV2";
|
||||
import DialogModal from "@/components/Common/Dialog";
|
||||
import { FileUpload } from "@/components/Files/FileUpload";
|
||||
|
||||
import * as Notification from "@/Utils/Notifications";
|
||||
import request from "@/Utils/request/request";
|
||||
|
||||
import routes from "../api";
|
||||
import { HCXClaimModel } from "../types";
|
||||
|
||||
interface Props {
|
||||
claim: HCXClaimModel;
|
||||
show: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function ClaimCreatedModal({ claim, ...props }: Props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isMakingClaim, setIsMakingClaim] = useState(false);
|
||||
|
||||
const { use } = claim;
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setIsMakingClaim(true);
|
||||
|
||||
const { res } = await request(routes.hcx.claims.makeClaim, {
|
||||
body: { claim: claim.id },
|
||||
});
|
||||
|
||||
if (res?.ok) {
|
||||
Notification.Success({ msg: `${use} requested` });
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
setIsMakingClaim(false);
|
||||
};
|
||||
return (
|
||||
<DialogModal
|
||||
show={props.show}
|
||||
onClose={props.onClose}
|
||||
title={t("add_attachments")}
|
||||
description={`${t("claim__use__claim")}: #${claim.id?.slice(0, 5)}`}
|
||||
className="w-full max-w-screen-lg"
|
||||
titleAction={
|
||||
<Submit disabled={isMakingClaim} onClick={handleSubmit}>
|
||||
{isMakingClaim && (
|
||||
<CareIcon icon="l-spinner" className="animate-spin" />
|
||||
)}
|
||||
{isMakingClaim
|
||||
? t("claim__requesting_claim")
|
||||
: t("claim__request_claim")}
|
||||
</Submit>
|
||||
}
|
||||
>
|
||||
<div className="p-4 pt-8">
|
||||
<FileUpload type="CLAIM" claimId={claim.id} />
|
||||
</div>
|
||||
</DialogModal>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user