fix: etrade loading

This commit is contained in:
ghost2023
2026-08-02 01:39:46 +03:00
parent e6ce19ad22
commit 7619952b74
2 changed files with 61 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
import { Alert, Button, Group, Loader, Stack, TextInput } from "@mantine/core";
import { Alert, Button, Loader, Stack, TextInput } from "@mantine/core";
import { useEffect, useRef } from "react";
import type { UseFormRegisterReturn } from "react-hook-form";
import { AlertCircle, Download } from "lucide-react";
@@ -24,6 +24,8 @@ interface ETradeInfoProps {
onDataLoaded: (data: CompanyRegistrationData) => void;
/** Reports the live lookup status so the parent step can gate on it. */
onStatusChange?: (status: ETradeStatus) => void;
/** Called when the TIN changes away from the last fetched value — clear whatever it filled in. */
onReset?: () => void;
}
const isValidTin = (tin: string) => tin.length === 10;
@@ -34,14 +36,22 @@ export default function ETradeInfo({
error,
onDataLoaded,
onStatusChange,
onReset,
}: ETradeInfoProps) {
const mutation = useETradeData();
const isLoading = mutation.isPending;
const tinTaken = mutation.data?.tinTaken;
// Bumped on every TIN change so a fetch already in flight for an older TIN
// is ignored when it lands — otherwise a slow lookup can resolve after the
// user has typed a different TIN and overwrite its fields with stale data.
const requestIdRef = useRef(0);
const handleFetch = async () => {
if (!isValidTin(tin)) return;
const requestId = ++requestIdRef.current;
const result = await mutation.mutateAsync(tin);
if (requestIdRef.current !== requestId) return;
if (result && !result.tinTaken) {
onDataLoaded(result);
}
@@ -53,6 +63,16 @@ export default function ETradeInfo({
// doesn't refire the lookup the moment this mounts.
const lastFetchedTin = useRef<string | null>(tin || null);
useEffect(() => {
if (tin !== lastFetchedTin.current) {
// TIN moved away from whatever we last fetched — that result (verified
// data, "taken", or an error) no longer describes this TIN. Drop it so
// the UI doesn't keep showing the previous TIN's outcome.
requestIdRef.current++;
if (mutation.data || mutation.error) {
mutation.reset();
onReset?.();
}
}
if (isValidTin(tin) && lastFetchedTin.current !== tin) {
lastFetchedTin.current = tin;
handleFetch();
@@ -90,8 +110,13 @@ export default function ETradeInfo({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status]);
const showRetry =
isValidTin(tin) && status !== "verified" && status !== "loading";
// True for the one render between the TIN reaching 10 digits and the
// effect above actually starting the fetch — without this, "Get Data"
// flashes on screen for that frame before `isLoading` ever turns true.
const willAutoFetch = isValidTin(tin) && lastFetchedTin.current !== tin;
const showLoading = isLoading || willAutoFetch;
const showRetry = isValidTin(tin) && status !== "verified" && !showLoading;
return (
<Stack gap="md">
@@ -103,18 +128,27 @@ export default function ETradeInfo({
error={error}
{...register}
/>
{showLoading && (
<Button
className="max-w-none"
variant="filled"
color="edr-green"
disabled
leftSection={<Loader size={16} />}
>
Getting...
</Button>
)}
{showRetry && (
<Button
className="max-w-none"
variant="filled"
color="edr-green"
onClick={handleFetch}
disabled={!isValidTin(tin) || isLoading}
leftSection={
isLoading ? <Loader size={16} /> : <Download size={16} />
}
disabled={!isValidTin(tin)}
leftSection={<Download size={16} />}
>
{isLoading ? "Getting..." : "Get Data"}
Get Data
</Button>
)}
</div>

View File

@@ -288,6 +288,24 @@ export default function CompanyProfileForm({
});
};
// TIN changed since the last successful lookup — the registration/address
// fields it filled in describe the OLD TIN, not this one, so clear them
// rather than leaving them stale on screen.
const handleETradeReset = () => {
setValue("licenceNumber", "");
setValue("statusDescription", "");
setValue("dateRegistered", "");
setValue("renewedFrom", "");
setValue("renewalDate", "");
setValue("renewedTo", "");
setValue("region", "");
setValue("zone", "");
setValue("woreda", "");
setValue("kebele", "");
setValue("houseNo", "");
setEtradeOwner(null);
};
// companyEmail/companyPhone are no longer typed — the Fayda-verified owner
// is the highest-trust source (that's the whole point of verifying), eTrade's
// registered number and the account email/phone are the fallbacks used
@@ -718,6 +736,7 @@ export default function CompanyProfileForm({
error={errors.tinNumber?.message}
onDataLoaded={handleETradeDataLoaded}
onStatusChange={setTinStatus}
onReset={handleETradeReset}
/>
{tinVerified && (
<ETradeCompanyCard