69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useMemo, useState } from "react";
|
|
import type { FunnelDefinition } from "@/lib/funnel/types";
|
|
import { loadFunnelPaymentById } from "@/entities/session/funnel/loaders";
|
|
import type { IFunnelPaymentPlacement } from "@/entities/session/funnel/types";
|
|
|
|
interface UsePaymentPlacementArgs {
|
|
funnel: FunnelDefinition;
|
|
paymentId: string;
|
|
}
|
|
|
|
interface UsePaymentPlacementResult {
|
|
placement: IFunnelPaymentPlacement | null;
|
|
isLoading: boolean;
|
|
error: string | null;
|
|
}
|
|
|
|
export function usePaymentPlacement({
|
|
funnel,
|
|
paymentId,
|
|
}: UsePaymentPlacementArgs): UsePaymentPlacementResult {
|
|
const [placement, setPlacement] = useState<IFunnelPaymentPlacement | null>(
|
|
null
|
|
);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const funnelKey = useMemo(() => funnel?.meta?.id ?? "", [funnel]);
|
|
|
|
useEffect(() => {
|
|
let isMounted = true;
|
|
if (!funnelKey || !paymentId) return;
|
|
|
|
(async () => {
|
|
try {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
const data = await loadFunnelPaymentById(
|
|
{ funnel: funnelKey },
|
|
paymentId
|
|
);
|
|
|
|
// Normalize union: record value can be IFunnelPaymentPlacement or IFunnelPaymentPlacement[] or null
|
|
const normalized: IFunnelPaymentPlacement | null = Array.isArray(data)
|
|
? data[0] ?? null
|
|
: data ?? null;
|
|
|
|
if (!isMounted) return;
|
|
setPlacement(normalized);
|
|
} catch (e) {
|
|
if (!isMounted) return;
|
|
const message =
|
|
e instanceof Error ? e.message : "Failed to load payment placement";
|
|
setError(message);
|
|
} finally {
|
|
if (isMounted) setIsLoading(false);
|
|
}
|
|
})();
|
|
|
|
return () => {
|
|
isMounted = false;
|
|
};
|
|
}, [funnelKey, paymentId]);
|
|
|
|
return { placement, isLoading, error };
|
|
}
|