mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 00:45:41 +00:00
Updated signature handling, added booking detail components, introduced a signature management page, updated routing, enabled document downloads, and simplified the profile page.
This commit is contained in:
@@ -50,11 +50,8 @@ export default function BookingContractPage() {
|
||||
enabled: Boolean(id),
|
||||
});
|
||||
|
||||
const signRole: "CUSTOMER" | "STAFF" | null = data?.canSignCustomer
|
||||
? "CUSTOMER"
|
||||
: data?.canSignStaff
|
||||
? "STAFF"
|
||||
: null;
|
||||
// Backoffice only ever signs as STAFF — customers sign in the portal.
|
||||
const canSign = Boolean(data?.canSignStaff);
|
||||
|
||||
const savedSignature = data?.savedSignature ?? null;
|
||||
const savedSignatureImage = savedSignature?.signatureImageUrl ?? null;
|
||||
@@ -106,12 +103,12 @@ export default function BookingContractPage() {
|
||||
};
|
||||
|
||||
const confirmSign = () => {
|
||||
if (!signRole || !signerName.trim()) return;
|
||||
if (!canSign || !signerName.trim()) return;
|
||||
// Approve the saved signature, or submit the freshly drawn one.
|
||||
const image = usingSaved ? savedSignatureImage : signatureData;
|
||||
if (!image) return;
|
||||
signMutation.mutate({
|
||||
role: signRole,
|
||||
role: "STAFF",
|
||||
signatureImageBase64: image,
|
||||
signerDisplayName: signerName.trim(),
|
||||
consentText: "I agree to the terms of this contract.",
|
||||
@@ -167,10 +164,10 @@ export default function BookingContractPage() {
|
||||
<Download className="size-4" />
|
||||
Download PDF
|
||||
</Button>
|
||||
{signRole && (
|
||||
{canSign && (
|
||||
<Button size="sm" className="gap-2" onClick={openSign}>
|
||||
<FileSignature className="size-4" />
|
||||
Sign as {signRole === "CUSTOMER" ? "Customer" : "Staff"}
|
||||
{usingSaved ? "Approve & sign" : "Sign contract"}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -194,9 +191,7 @@ export default function BookingContractPage() {
|
||||
<Dialog open={signOpen} onOpenChange={setSignOpen}>
|
||||
<DialogContent className="sm:max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{signRole === "CUSTOMER" ? "Customer signature" : "Staff signature"}
|
||||
</DialogTitle>
|
||||
<DialogTitle>Staff signature</DialogTitle>
|
||||
<DialogDescription>
|
||||
{usingSaved
|
||||
? `Review your saved signature and approve it to execute the contract for ${data.reference}.`
|
||||
|
||||
@@ -24,11 +24,16 @@ import {
|
||||
BookingRouteServiceCard,
|
||||
BookingMileServicesCard,
|
||||
BookingCargoCard,
|
||||
BookingCompanyCard,
|
||||
BookingContractSummaryCard,
|
||||
BookingDocumentsCard,
|
||||
type BookingFileView,
|
||||
} from "@/components/bookings/detail";
|
||||
import { getStatusMeta } from "@/features/bookings/booking-status.config";
|
||||
import { toBookingListRow } from "@/features/bookings/mapBookingListRow";
|
||||
import { downloadBookingFile } from "@/services/files.service";
|
||||
import { useBookingDetail, useBookingMutations } from "@/hooks/bookings/useBookings";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
export default function BookingRequestDetailPage() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
@@ -36,6 +41,14 @@ export default function BookingRequestDetailPage() {
|
||||
const { data: booking, isLoading, isError, refetch, isFetching } = useBookingDetail(id);
|
||||
const mutations = useBookingMutations(id ?? "");
|
||||
|
||||
const handleDownloadFile = async (file: BookingFileView) => {
|
||||
try {
|
||||
await downloadBookingFile(file.id, file.name);
|
||||
} catch {
|
||||
toast.error("Could not download file.");
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box style={detailStyles.page}>
|
||||
@@ -147,6 +160,10 @@ export default function BookingRequestDetailPage() {
|
||||
{booking.contractSummary && (
|
||||
<BookingContractSummaryCard summary={booking.contractSummary} />
|
||||
)}
|
||||
<BookingDocumentsCard
|
||||
files={booking.files ?? []}
|
||||
onDownload={handleDownloadFile}
|
||||
/>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
|
||||
@@ -154,6 +171,7 @@ export default function BookingRequestDetailPage() {
|
||||
<Grid.Col span={{ base: 12, lg: 4 }}>
|
||||
<Box style={{ position: "sticky", top: 24 }}>
|
||||
<Stack gap="lg">
|
||||
<BookingCompanyCard booking={booking} />
|
||||
<BookingPricingSummary booking={booking} />
|
||||
<BookingActionsToolbar booking={booking} mutations={mutations} />
|
||||
{showContractButton && (
|
||||
|
||||
Reference in New Issue
Block a user