@qite/tide-booking-component
Version:
React Booking wizard & Booking product component for Tide
118 lines (100 loc) • 3.26 kB
text/typescript
import { useCallback, useContext, useState } from "react";
import SettingsContext from "./settings-context";
import { buildTideClientConfig } from "../shared/utils/tide-api-utils";
import { book, print } from "@qite/tide-client";
import type {
BookingPackage,
BookingPackageBookRequest,
BookingPackageDossier,
BookingPackageRequest,
AgentPrintActionRequest,
Pax,
BookingPackagePax,
} from "@qite/tide-client/build/types";
export interface UseOfferPrinterArgs {
bookingPackage?: BookingPackage;
getPax: () => Pax[] | undefined;
tagIds?: number[];
printActionId?: number | null;
onPrinted?: (pdfUrl: string) => void;
}
export function useOfferPrinter({
bookingPackage,
getPax,
tagIds = [],
printActionId = null,
onPrinted,
}: UseOfferPrinterArgs) {
const settings = useContext(SettingsContext);
if (!settings)
throw new Error("useOfferPrinter must be used inside <BookingWizard>");
const { language, officeId } = settings;
const agentId = (settings as any).agentAdressId;
if (typeof agentId !== "number" || agentId <= 0) {
throw new Error("Missing agentAdressId in wizard settings");
}
const [stage, setStage] = useState<"idle" | "creating" | "printing">("idle");
const loading = stage !== "idle";
const createOffer = useCallback(async (): Promise<BookingPackageDossier> => {
const paxRaw = getPax();
if (!bookingPackage || !paxRaw?.length) {
throw new Error("Missing booking package or pax");
}
const pax = paxRaw as unknown as BookingPackagePax[];
const request: BookingPackageRequest<BookingPackageBookRequest> = {
officeId,
agentId,
payload: {
package: bookingPackage,
status: 0,
pax,
nonTravelPax: [],
notifications: [],
tagIds,
customerRequests: [],
},
};
const cfg = buildTideClientConfig();
return book(cfg, request, undefined, language);
}, [agentId, bookingPackage, getPax, language, officeId, tagIds]);
const languageData = [
{ code: "nl-BE", tideId: 1 },
{ code: "fr-BE", tideId: 2 },
{ code: "en-GB", tideId: 3 },
];
function getTideLanguageId(code: string) {
return languageData.find((l) => l.code === code)?.tideId || 1;
}
const printOffer = useCallback(
async (offer: BookingPackageDossier) => {
const cfg = buildTideClientConfig();
const req: AgentPrintActionRequest = {
id: printActionId ?? 0,
dossierNumber: (offer as any).dossierNumber ?? (offer as any).number,
languageId: getTideLanguageId(language),
};
const res = await print(cfg, req);
const buf = await res.arrayBuffer();
const url = URL.createObjectURL(
new Blob([buf], { type: "application/pdf" })
);
onPrinted?.(url);
window.open(url);
},
[language, onPrinted]
);
const handlePrint = useCallback(async () => {
try {
setStage("creating");
const offer = await createOffer();
setStage("printing");
await printOffer(offer);
} catch (err) {
console.error("Offer print failed:", err);
throw err;
} finally {
setStage("idle");
}
}, [createOffer, printOffer]);
return { handlePrint, loading, stage };
}