Redirect Solved 09-10
This commit is contained in:
parent
b3beb64265
commit
a7b7be491e
|
|
@ -488,7 +488,7 @@ const ProcessStepOne = () => {
|
|||
transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&
|
||||
<div className="flex justify-between items-center">
|
||||
<h2 className=" text-lg font-medium mb-4 pt-6 text-[var(--processStepOneTextHead)]">Signers</h2>
|
||||
<div className="flex items-center mr-3">
|
||||
{/* <div className="flex items-center mr-3">
|
||||
<input
|
||||
checked={signType === SignTypeEnum.selfSign}
|
||||
onChange={(e) => handleSelfSignCb(e)}
|
||||
|
|
@ -496,7 +496,7 @@ const ProcessStepOne = () => {
|
|||
/>
|
||||
<label htmlFor="default-checkbox" className="ms-2 text-sm flex gap-1 text-slate-600">
|
||||
I AM THE ONLY SIGNER</label>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,18 +164,21 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
|||
if (res.data.length) {
|
||||
const defaultVal = res.data.filter((obj, indx) => "default" in obj && obj.default);
|
||||
|
||||
const { id, initialsBlob, signatureBlob } = defaultVal[0];
|
||||
if (defaultVal.length > 0) {
|
||||
const { id, initialsBlob, signatureBlob } = defaultVal[0];
|
||||
|
||||
if (initialsBlob && signatureBlob) {
|
||||
setSaved({
|
||||
signatureId: id,
|
||||
saveType: SaveTypeEnum.DRAW,
|
||||
save: true,
|
||||
signature: signatureBlob,
|
||||
initial: initialsBlob,
|
||||
isDefaultAndClicked: true
|
||||
});
|
||||
if (initialsBlob && signatureBlob) {
|
||||
setSaved({
|
||||
signatureId: id,
|
||||
saveType: SaveTypeEnum.DRAW,
|
||||
save: true,
|
||||
signature: signatureBlob,
|
||||
initial: initialsBlob,
|
||||
isDefaultAndClicked: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
setPreSaveSignatures(preSavedSignatures)
|
||||
}
|
||||
|
|
@ -705,28 +708,31 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
|||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="mb-6 px-4 sm:px-6">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-2">Saved Signatures</h2>
|
||||
<div className="my-4 px-4 sm:px-6">
|
||||
<h2 className="text-2xl font-semibold text-gray-900 mb-1">Saved Signatures</h2>
|
||||
<p className="text-sm text-gray-600">Select from your pre-saved signatures</p>
|
||||
</div>
|
||||
|
||||
{/* Signatures List */}
|
||||
<div className="flex-1 overflow-y-auto px-2 sm:px-6">
|
||||
<div className="space-y-4">
|
||||
{/* Horizontal Scrollable List */}
|
||||
<div className="flex-1 overflow-x-auto px-2 sm:px-6">
|
||||
<div className="flex flex-col space-x-4 max-h-[40vh] gap-2">
|
||||
{preSaveSignatures.map((signature) => (
|
||||
<div
|
||||
key={signature?.id}
|
||||
className="flex flex-col md:flex-row md:space-x-4 bg-white rounded-xl border border-gray-200 p-4 hover:shadow-lg transition-shadow duration-200"
|
||||
onClick={() => setSelectedSignature(signature?.id)}
|
||||
className={`cursor-pointer bg-white rounded-xl border p-4 w-full flex justify-between items-start transition-shadow duration-200 gap-3
|
||||
${selectedSignature === signature?.id ? 'border-blue-500 shadow-lg' : 'border-gray-200'}
|
||||
`}
|
||||
style={{ minWidth: '220px' }} // each card width
|
||||
>
|
||||
{/* Full Signature */}
|
||||
<div className="flex-1 flex flex-col space-y-2 border-l-4 border-blue-500 rounded-l-xl pl-4 md:pl-6 py-2">
|
||||
<span className="text-sm font-medium text-gray-600">Signed by:</span>
|
||||
|
||||
<div className="bg-gray-50 rounded-lg p-2 flex items-center justify-center min-h-[50px]">
|
||||
{/* Signature */}
|
||||
<div className="w-[60%] flex flex-col">
|
||||
<span className="text-sm font-medium text-gray-600 mb-1">Signed by:</span>
|
||||
<div className="w-full bg-gray-50 rounded-lg p-2 flex items-center justify-center min-h-[60px]">
|
||||
{signature?.signatureType !== 'SELECT' && signature?.signatureBlob ? (
|
||||
<img
|
||||
src={`data:${signature?.signatureMimeType};base64,${signature?.signatureBlob}`}
|
||||
className="max-h-[60px] w-full object-contain"
|
||||
className="w-full h-12 object-contain"
|
||||
alt={`${signature?.firstName ?? ''} ${signature?.lastName ?? ''} signature`}
|
||||
/>
|
||||
) : (
|
||||
|
|
@ -739,19 +745,17 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
|||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
<span className="text-xs text-gray-500 truncate">{signature?.signatureHash ?? ' '}</span>
|
||||
{/* <span className="text-xs text-gray-500 truncate mt-1 text-center w-full">{signature?.signatureHash ?? ' '}</span> */}
|
||||
</div>
|
||||
|
||||
{/* Initials */}
|
||||
<div className="flex-1 flex flex-col space-y-2 border-l-4 border-green-500 rounded-l-xl pl-4 md:pl-6 py-2 mt-4 md:mt-0">
|
||||
<span className="text-sm font-medium text-gray-600">Initials</span>
|
||||
|
||||
<div className="bg-gray-50 rounded-lg p-2 flex items-center justify-center min-h-[50px]">
|
||||
<div className="w-[40%] flex flex-col">
|
||||
<span className="text-sm font-medium text-gray-600 mb-1">Initials</span>
|
||||
<div className="bg-gray-50 rounded-lg p-1 flex items-center justify-center min-h-[40px]">
|
||||
{signature?.signatureType !== 'SELECT' && signature?.initialsBlob ? (
|
||||
<img
|
||||
src={`data:${signature?.initialsMimeType};base64,${signature?.initialsBlob}`}
|
||||
className="max-h-[60px] w-full object-contain"
|
||||
className="w-full h-10 object-contain"
|
||||
alt={`${signature?.firstName ?? ''} ${signature?.lastName ?? ''} initials`}
|
||||
/>
|
||||
) : (
|
||||
|
|
@ -764,8 +768,7 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
|||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
<span className="text-xs text-gray-500 truncate">{signature?.initialsHash ?? ' '}</span>
|
||||
{/* <span className="text-xs text-gray-500 truncate mt-1 text-center w-full">{signature?.initialsHash ?? ' '}</span> */}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -775,6 +778,7 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
|||
);
|
||||
|
||||
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import axios from "axios";
|
|||
|
||||
const api = axios.create({
|
||||
baseURL: import.meta.env.VITE_BASE_URI,
|
||||
maxRedirects: 5,
|
||||
maxRedirects: 10,
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -49,6 +49,19 @@ api.interceptors.response.use(
|
|||
if (window.location.pathname === "/login" || window.location.pathname === "/register") {
|
||||
window.location.href = "/";
|
||||
}
|
||||
|
||||
if (typeof response.data === 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
||||
// Likely a full HTML page, handle accordinglys
|
||||
window.location.href = response.request.responseURL;
|
||||
}
|
||||
|
||||
if (response && (response.status === 301 || response.status === 302)) {
|
||||
const redirectUrl = response.headers["location"];
|
||||
if (redirectUrl) {
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
async error => {
|
||||
|
|
@ -58,12 +71,13 @@ api.interceptors.response.use(
|
|||
// const res = error.response;
|
||||
|
||||
// 🔹 Handle 301/302 manually
|
||||
// if (res && (res.status === 301 || res.status === 302)) {
|
||||
// const redirectUrl = res.headers["location"];
|
||||
// if (redirectUrl) {
|
||||
// window.location.href = redirectUrl;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (error && (error.status === 301 || error.status === 302)) {
|
||||
const redirectUrl = error.headers["location"];
|
||||
if (redirectUrl) {
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent multiple refresh attempts
|
||||
// if (error.response?.status === 401 || error.response?.status === 500) {
|
||||
|
|
|
|||
|
|
@ -2,45 +2,46 @@
|
|||
import axios, { AxiosInstance } from "axios";
|
||||
|
||||
const defaultHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
"ngrok-skip-browser-warning": "69420",
|
||||
"Content-Type": "application/json",
|
||||
"ngrok-skip-browser-warning": "69420",
|
||||
};
|
||||
|
||||
const axiosInstance: AxiosInstance = axios.create({
|
||||
baseURL: import.meta.env.VITE_BASE_URI,
|
||||
withCredentials: true,
|
||||
headers: defaultHeaders,
|
||||
validateStatus: (status) => status >= 200 && status < 400,
|
||||
baseURL: import.meta.env.VITE_BASE_URI,
|
||||
withCredentials: true,
|
||||
headers: defaultHeaders,
|
||||
validateStatus: (status) => status >= 200 && status < 400,
|
||||
});
|
||||
|
||||
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response) => {
|
||||
// ✅ Handle backend "soft redirects"
|
||||
if (response?.data?.redirect) {
|
||||
const redirectUrl = response.data.redirect;
|
||||
(response) => {
|
||||
|
||||
// Use location.replace to avoid back button returning to invalid page
|
||||
window.location.replace(redirectUrl);
|
||||
// OR window.location.href = redirectUrl; if you want history entry
|
||||
if (typeof response.data === 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
||||
// Likely a full HTML page, handle accordingly
|
||||
window.location.href = response.request.responseURL;
|
||||
}
|
||||
|
||||
// Optionally return a rejected promise to stop normal handling
|
||||
return Promise.reject({ redirected: true });
|
||||
if (response && (response.status === 301 || response.status === 302)) {
|
||||
const redirectUrl = response.headers["location"];
|
||||
if (redirectUrl) {
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise just continue as normal
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
// Optionally handle backend 302 or 3xx here (if returned as error)
|
||||
if (error.response?.status === 302 && error.response?.headers?.location) {
|
||||
window.location.replace(error.response.headers.location);
|
||||
return Promise.reject({ redirected: true });
|
||||
}
|
||||
|
||||
// Pass through all other errors
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// Otherwise just continue as normal
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
// Optionally handle backend 302 or 3xx here (if returned as error)
|
||||
if (error.response?.status === 302 && error.response?.headers?.location) {
|
||||
window.location.replace(error.response.headers.location);
|
||||
return Promise.reject({ redirected: true });
|
||||
}
|
||||
|
||||
// Pass through all other errors
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default axiosInstance;
|
||||
|
|
|
|||
Loading…
Reference in New Issue