feature/IO-3499-React-19: Bug Fixes / Checkpoint
This commit is contained in:
@@ -18,3 +18,4 @@ VITE_PUBLIC_POSTHOG_KEY=phc_xtLmBIu0rjWwExY73Oj5DTH1bGbwq1G1Y8jnlTceien
|
||||
VITE_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
|
||||
VITE_APP_AMP_URL=https://vp8k908qy2.execute-api.ca-central-1.amazonaws.com
|
||||
VITE_APP_AMP_KEY=6228a598e57cd66875cfd41604f1f891
|
||||
#VITE_ENABLE_COMPILER_IN_DEV=1
|
||||
|
||||
@@ -46,6 +46,8 @@ const CardPaymentModalComponent = ({
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const [paymentLink, setPaymentLink] = useState();
|
||||
const isMountedRef = useRef(true);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
||||
const { t } = useTranslation();
|
||||
@@ -69,6 +71,16 @@ const CardPaymentModalComponent = ({
|
||||
[called, loadRoAndOwnerByJobPks, refetch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
isMountedRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const setLoadingSafe = useCallback((value) => {
|
||||
if (isMountedRef.current) setLoading(value);
|
||||
}, []);
|
||||
|
||||
// Watch form payments so we can query jobs when all jobids are filled (without side effects during render)
|
||||
const payments = Form.useWatch(["payments"], form);
|
||||
|
||||
@@ -106,24 +118,49 @@ const CardPaymentModalComponent = ({
|
||||
const SetIntellipayCallbackFunctions = () => {
|
||||
console.log("*** Set IntelliPay callback functions.");
|
||||
|
||||
const isLikelyUserCancel = (response) => {
|
||||
const reason = String(response?.declinereason ?? "").toLowerCase();
|
||||
// Heuristics: adjust if IntelliPay gives you a known cancel code/message
|
||||
return (
|
||||
reason.includes("cancel") ||
|
||||
reason.includes("canceled") ||
|
||||
reason.includes("closed") ||
|
||||
// many gateways won't have a paymentid if user cancels before submitting
|
||||
!response?.paymentid
|
||||
);
|
||||
};
|
||||
|
||||
window.intellipay.runOnClose(() => {
|
||||
//window.intellipay.initialize();
|
||||
// This is the path for Cancel / X
|
||||
try {
|
||||
// If IntelliPay uses this flag, clear it so initialize() won't reopen unexpectedly
|
||||
window.intellipay.isAutoOpen = false;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// Optional: if IntelliPay needs re-init after close, uncomment:
|
||||
// try { window.intellipay.initialize?.(); } catch {}
|
||||
|
||||
setLoadingSafe(false);
|
||||
});
|
||||
|
||||
window.intellipay.runOnApproval(() => {
|
||||
// 2024-04-25: Nothing is going to happen here anymore. We'll completely rely on the callback.
|
||||
// Add a slight delay to allow the refetch to properly get the data.
|
||||
// keep your existing behavior
|
||||
setTimeout(() => {
|
||||
if (actions?.refetch) actions.refetch();
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
toggleModalVisible();
|
||||
}, 750);
|
||||
});
|
||||
|
||||
window.intellipay.runOnNonApproval(async (response) => {
|
||||
// Mutate unsuccessful payment
|
||||
try {
|
||||
// If cancel is reported as "non-approval", don't record it as a failed payment
|
||||
if (isLikelyUserCancel(response)) return;
|
||||
|
||||
const { payments } = form.getFieldsValue();
|
||||
|
||||
await insertPaymentResponse({
|
||||
variables: {
|
||||
paymentResponse: payments.map((payment) => ({
|
||||
@@ -131,7 +168,7 @@ const CardPaymentModalComponent = ({
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid: payment.jobid,
|
||||
declinereason: response.declinereason,
|
||||
ext_paymentid: response.paymentid.toString(),
|
||||
ext_paymentid: response.paymentid?.toString?.() ?? null,
|
||||
successful: false,
|
||||
response
|
||||
}))
|
||||
@@ -145,6 +182,10 @@ const CardPaymentModalComponent = ({
|
||||
type: "failedpayment"
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
// IMPORTANT: always clear loading, even on errors
|
||||
setLoadingSafe(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -154,7 +195,7 @@ const CardPaymentModalComponent = ({
|
||||
try {
|
||||
await form.validateFields();
|
||||
} catch {
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,7 +226,7 @@ const CardPaymentModalComponent = ({
|
||||
document.documentElement.appendChild(node);
|
||||
pollForIntelliPay(() => {
|
||||
SetIntellipayCallbackFunctions();
|
||||
// eslint-disable-next-line react-compiler/react-compiler
|
||||
|
||||
window.intellipay.isAutoOpen = true;
|
||||
window.intellipay.initialize();
|
||||
});
|
||||
@@ -194,7 +235,7 @@ const CardPaymentModalComponent = ({
|
||||
notification.error({
|
||||
title: t("job_payments.notifications.error.openingip")
|
||||
});
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -204,7 +245,7 @@ const CardPaymentModalComponent = ({
|
||||
try {
|
||||
await form.validateFields();
|
||||
} catch {
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -227,12 +268,12 @@ const CardPaymentModalComponent = ({
|
||||
await navigator.clipboard.writeText(response.data.shorUrl);
|
||||
message.success(t("general.actions.copied"));
|
||||
}
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
} catch {
|
||||
notification.error({
|
||||
title: t("job_payments.notifications.error.openingip")
|
||||
});
|
||||
setLoading(false);
|
||||
setLoadingSafe(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,23 @@ const getFormattedTimestamp = () =>
|
||||
|
||||
export const logger = createLogger("info", { allowClearScreen: false });
|
||||
|
||||
export default defineConfig({
|
||||
// Read HTTPS certs once (used by both server + preview)
|
||||
const httpsCerts = {
|
||||
key: await fsPromises.readFile("../certs/key.pem"),
|
||||
cert: await fsPromises.readFile("../certs/cert.pem")
|
||||
};
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
// Only enable React Compiler on build in production/test (keeps dev as fast as possible)
|
||||
const isBuild = command === "build";
|
||||
const isTestBuild =
|
||||
mode === "test" || process.env.VITE_APP_IS_TEST === "true" || process.env.VITE_APP_IS_TEST === "1";
|
||||
const enableReactCompiler =
|
||||
process.env.VITE_ENABLE_COMPILER_IN_DEV || (isBuild && (mode === "production" || isTestBuild));
|
||||
|
||||
console.log(enableReactCompiler ? "React Compiler enabled" : "React Compiler disabled");
|
||||
|
||||
return {
|
||||
base: "/",
|
||||
plugins: [
|
||||
ViteEjsPlugin((viteConfig) => ({ env: viteConfig.env })),
|
||||
@@ -101,18 +117,26 @@ export default defineConfig({
|
||||
}
|
||||
}),
|
||||
|
||||
react({
|
||||
react(
|
||||
enableReactCompiler
|
||||
? {
|
||||
babel: {
|
||||
plugins: [
|
||||
['babel-plugin-react-compiler', {
|
||||
[
|
||||
"babel-plugin-react-compiler",
|
||||
{
|
||||
// Exclude third-party drag-and-drop library from compilation
|
||||
sources: (filename) => {
|
||||
return !filename.includes('trello-board/dnd');
|
||||
return !filename.includes("trello-board/dnd");
|
||||
}
|
||||
}]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}),
|
||||
}
|
||||
: undefined
|
||||
),
|
||||
|
||||
eslint(),
|
||||
|
||||
// Sentry only for production builds (no dev overhead)
|
||||
@@ -165,20 +189,14 @@ export default defineConfig({
|
||||
}
|
||||
}
|
||||
},
|
||||
https: {
|
||||
key: await fsPromises.readFile("../certs/key.pem"),
|
||||
cert: await fsPromises.readFile("../certs/cert.pem")
|
||||
}
|
||||
https: httpsCerts
|
||||
},
|
||||
|
||||
preview: {
|
||||
port: 6000,
|
||||
host: true,
|
||||
open: true,
|
||||
https: {
|
||||
key: await fsPromises.readFile("../certs/key.pem"),
|
||||
cert: await fsPromises.readFile("../certs/cert.pem")
|
||||
},
|
||||
https: httpsCerts,
|
||||
proxy: {
|
||||
"/ws": {
|
||||
target: "ws://localhost:4000",
|
||||
@@ -272,4 +290,5 @@ export default defineConfig({
|
||||
scss: { quietDeps: true }
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user