Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 63x 166x 166x 13x 12x 166x 48x 166x 9x 166x 166x | import { useQuery } from "react-query";
import { customInstance } from "@services/api";
import { LEGAL_DOC_KEYS } from "./keys";
import type { LegalDocument, DocumentVersion } from "../types";
/**
* Resolves the currently-published document of a given `typeName`
* (e.g. "merchant_agreement") readable by an account:
* list -> match the type's PUBLISHED row -> read that version's content.
*
* `accountID` is the caller's OWN account (the current portal account), not the
* acquirer's: an acquirer gets its own documents; a merchant/provider gets its
* parent acquirer's documents read-only — published only, no drafts, no editor
* PII — with the hierarchy resolved by the backend. The public endpoint only
* serves privacy_policy / terms_of_service, so agreement prose must come from
* these authenticated routes. Callers without read access simply get no content
* (retry disabled), so consumers render nothing / fall back to the legacy
* hardcoded terms.
*/
export const usePublishedDocumentByType = (
accountID?: number | string | null,
type?: string,
options?: { enabled?: boolean },
) => {
const baseEnabled = (options?.enabled ?? true) && !!accountID && !!type;
const listQuery = useQuery<LegalDocument[]>(
[LEGAL_DOC_KEYS.list, accountID],
() =>
// Endpoint returns a { total, data } envelope; unwrap to the array.
customInstance({
url: `/merchants/${accountID}/legal-documents`,
method: "GET",
}).then((res) => res?.data ?? []),
{ enabled: baseEnabled, retry: false, refetchOnWindowFocus: false },
);
// The type's published row — never the draft (drafts are pinned on top of
// the list, and a draft's version id 404s on the read-gated version read).
const versionID = listQuery.data?.find(
(doc) => doc.typeName === type && !doc.isDraft,
)?.versionID;
const versionQuery = useQuery<DocumentVersion>(
[LEGAL_DOC_KEYS.version, accountID, versionID],
() =>
customInstance({
url: `/merchants/${accountID}/legal-documents/versions/${versionID}`,
method: "GET",
}),
{
enabled: baseEnabled && !!versionID,
retry: false,
refetchOnWindowFocus: false,
},
);
// Whether we are still DETERMINING if there is a published document to show.
// This is a two-step fetch (list -> version), so we cannot rely on the
// version query's own `isLoading`: while the list is still loading the
// version query is DISABLED, which react-query v3 reports as `idle`
// (`isLoading:false`, `data:undefined`) — indistinguishable from "nothing
// published". Consumers must show a loading state while this is true so the
// hardcoded fallback agreement does not flash before the published one
// resolves. (Only the query window; the feature-flag async window is surfaced
// separately via `useGetFeatureFlagValues().isFeatureFlagLoading`.)
const isResolving =
baseEnabled &&
(listQuery.isLoading || (!!versionID && versionQuery.isLoading));
return { ...versionQuery, isResolving };
};
|