Skip to content

Commit

Permalink
Add download invoice button
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbeno committed Nov 18, 2024
1 parent 1009875 commit 7c798eb
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./use-upload-billing-profile-invoice-by-id";
export * from "./use-accept-or-decline-billing-profile-mandate-by-id";
export * from "./use-get-billing-profile-invoiceable-rewards";
export * from "./use-get-my-billing-profiles";
export * from "./use-download-billing-profile-invoice-by-id";
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useQuery } from "@tanstack/react-query";

import {
UseQueryFacadeParams,
useQueryAdapter,
} from "@/core/application/react-query-adapter/helpers/use-query-adapter";
import { bootstrap } from "@/core/bootstrap";
import { BillingProfileFacadePort } from "@/core/domain/billing-profile/input/billing-profile-facade-port";

export function useDownloadBillingProfileInvoiceById({
options,
pathParams,
queryParams,
}: UseQueryFacadeParams<BillingProfileFacadePort["downloadBillingProfileInvoiceById"], Blob>) {
const billingProfileStoragePort = bootstrap.getBillingProfileStoragePortForClient();

return useQuery(
useQueryAdapter({
...billingProfileStoragePort.downloadBillingProfileInvoiceById({ pathParams, queryParams }),
options,
})
);
}
12 changes: 12 additions & 0 deletions core/domain/billing-profile/billing-profile-contract.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ export type GetBillingProfileInvoicePreviewByIdPortResponse =

/* ------------------------ Upload Billing Profile Invoice by ID ------------------------ */

type DownloadBillingProfileInvoiceByIdPathParams = operations["downloadInvoice"]["parameters"]["path"];
type DownloadBillingProfileInvoiceByIdQueryParams = operations["downloadInvoice"]["parameters"]["query"];

export type DownloadBillingProfileInvoiceByIdPortParams = HttpClientParameters<{
PathParams: DownloadBillingProfileInvoiceByIdPathParams;
QueryParams: DownloadBillingProfileInvoiceByIdQueryParams;
}>;

export type DownloadBillingProfileInvoiceByIdPortResponse = HttpStorageResponse<Blob>;

/* ------------------------ Download Billing Profile Invoice by ID ------------------------ */

type UploadBillingProfileInvoiceByIdPathParams = operations["uploadInvoice"]["parameters"]["path"];
type UploadBillingProfileInvoiceByIdQueryParams = operations["uploadInvoice"]["parameters"]["query"];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
AcceptOrDeclineBillingProfileMandatePortParams,
AcceptOrDeclineBillingProfileMandatePortResponse,
DownloadBillingProfileInvoiceByIdPortParams,
DownloadBillingProfileInvoiceByIdPortResponse,
GetBillingProfileByIdPortParams,
GetBillingProfileByIdPortResponse,
GetBillingProfileInvoicePreviewByIdPortParams,
Expand All @@ -26,6 +28,9 @@ export interface BillingProfileFacadePort {
uploadBillingProfileInvoiceById(
p: UploadBillingProfileInvoiceByIdPortParams
): UploadBillingProfileInvoiceByIdPortResponse;
downloadBillingProfileInvoiceById(
p: DownloadBillingProfileInvoiceByIdPortParams
): DownloadBillingProfileInvoiceByIdPortResponse;
acceptOrDeclineBillingProfileMandateById(
p: AcceptOrDeclineBillingProfileMandatePortParams
): AcceptOrDeclineBillingProfileMandatePortResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
AcceptOrDeclineBillingProfileMandatePortParams,
AcceptOrDeclineBillingProfileMandatePortResponse,
DownloadBillingProfileInvoiceByIdPortParams,
DownloadBillingProfileInvoiceByIdPortResponse,
GetBillingProfileByIdPortParams,
GetBillingProfileByIdPortResponse,
GetBillingProfileInvoicePreviewByIdPortParams,
Expand All @@ -27,6 +29,9 @@ export interface BillingProfileStoragePort {
uploadBillingProfileInvoiceById(
p: UploadBillingProfileInvoiceByIdPortParams
): UploadBillingProfileInvoiceByIdPortResponse;
downloadBillingProfileInvoiceById(
p: DownloadBillingProfileInvoiceByIdPortParams
): DownloadBillingProfileInvoiceByIdPortResponse;
acceptOrDeclineBillingProfileMandateById(
p: AcceptOrDeclineBillingProfileMandatePortParams
): AcceptOrDeclineBillingProfileMandatePortResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class BillingProfileClientAdapter implements BillingProfileStoragePort {
getBillingProfilePayoutInfoById: "billing-profiles/:billingProfileId/payout-info",
getBillingProfileInvoicePreviewById: "billing-profiles/:billingProfileId/invoice-preview",
uploadBillingProfileInvoiceById: "billing-profiles/:billingProfileId/invoices/:invoiceId",
downloadBillingProfileInvoiceById: "billing-profiles/:billingProfileId/invoices/:invoiceId",
acceptOrDeclineBillingProfileMandateById: "billing-profiles/:billingProfileId/invoices/mandate",
getMyBillingProfiles: "me/billing-profiles",
getBillingProfileInvoiceableRewards: "billing-profiles/:billingProfileId/invoiceable-rewards",
Expand Down Expand Up @@ -125,6 +126,31 @@ export class BillingProfileClientAdapter implements BillingProfileStoragePort {
};
};

downloadBillingProfileInvoiceById = ({
pathParams,
queryParams,
}: FirstParameter<BillingProfileStoragePort["downloadBillingProfileInvoiceById"]>) => {
const path = this.routes["downloadBillingProfileInvoiceById"];
const method = "POST";
const tag = HttpClient.buildTag({ path, pathParams, queryParams });
const request = async () =>
this.client.request<Blob>({
path,
method,
tag,
pathParams,
queryParams,
headers: {
"Content-Type": "application/pdf",
},
});

return {
request,
tag,
};
};

acceptOrDeclineBillingProfileMandateById = ({
pathParams,
}: FirstParameter<BillingProfileStoragePort["acceptOrDeclineBillingProfileMandateById"]>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export class BillingProfileClientAdapterMock implements BillingProfileStoragePor
BillingProfileStoragePort["uploadBillingProfileInvoiceById"]
>;

downloadBillingProfileInvoiceById = mockHttpStorageResponse<
BillingProfileStoragePort["downloadBillingProfileInvoiceById"]
>;

acceptOrDeclineBillingProfileMandateById = mockHttpStorageResponse<
BillingProfileStoragePort["acceptOrDeclineBillingProfileMandateById"]
>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"title": "Reward detail",
"download": "Invoice",
"emptyState": {
"title": "No reward details available",
"description": "There are no reward details available."
Expand Down
64 changes: 57 additions & 7 deletions shared/panels/reward-detail-sidepanel/reward-detail-sidepanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { CloudDownload } from "lucide-react";
import { useMemo } from "react";

import { BillingProfileReactQueryAdapter } from "@/core/application/react-query-adapter/billing-profile";
import { RewardReactQueryAdapter } from "@/core/application/react-query-adapter/reward";
import { bootstrap } from "@/core/bootstrap";

import { Button } from "@/design-system/atoms/button/variants/button-default";
import { Skeleton } from "@/design-system/atoms/skeleton";

import { EmptyStateLite } from "@/shared/components/empty-state-lite/empty-state-lite";
Expand Down Expand Up @@ -63,19 +68,64 @@ export function Content() {
);
}

export function RewardDetailSidepanel() {
export function Header() {
const { name } = useRewardDetailSidepanel();
const idKernelPort = bootstrap.getIdKernelPort();
const { Panel } = useSidePanel({ name });
const { rewardId } = useSinglePanelData<RewardDetailSidepanelData>(name) ?? {};
const { data: reward } = RewardReactQueryAdapter.client.useGetRewardId({
pathParams: { rewardId: rewardId ?? "" },
options: {
enabled: Boolean(rewardId),
},
});

const { data: downloadedInvoice } = BillingProfileReactQueryAdapter.client.useDownloadBillingProfileInvoiceById({
pathParams: {
billingProfileId: reward?.billingProfileId ?? "",
invoiceId: reward?.invoiceId ?? "",
},
options: { enabled: Boolean(reward?.invoiceId && reward?.billingProfileId) },
});

const downloadButton = useMemo(() => {
if (!downloadedInvoice || !rewardId) {
return null;
}

return (
<Button
size={"sm"}
variant={"secondary"}
startIcon={{ component: CloudDownload }}
translate={{
token: "panels:rewardDetail.download",
}}
as={"a"}
htmlProps={{
href: window.URL.createObjectURL(downloadedInvoice),
download: idKernelPort.prettyId(rewardId) ?? "invoice.pdf",
}}
/>
);
}, [reward, downloadedInvoice]);

return (
<SidePanelHeader
canGoBack={false}
canClose={true}
title={{ children: rewardId ? `#${idKernelPort.prettyId(rewardId)}` : "" }}
titleEndContent={downloadButton}
/>
);
}

export function RewardDetailSidepanel() {
const { name } = useRewardDetailSidepanel();
const { Panel } = useSidePanel({ name });

return (
<Panel>
<SidePanelHeader
canGoBack={false}
canClose={true}
title={{ children: rewardId ? `#${idKernelPort.prettyId(rewardId)}` : "" }}
/>
<Header />
<Content />
</Panel>
);
Expand Down

0 comments on commit 7c798eb

Please sign in to comment.