feat: implement local file preview and manual upload flow for Aadhar and PAN documents in SettingsTab
All checks were successful
Beta CI/CD Pipeline / build-and-test (push) Successful in 59s
Beta CI/CD Pipeline / deploy-beta (push) Successful in 9s

This commit is contained in:
vickytechkey 2026-08-28 16:13:11 +05:30
parent ca06e999e2
commit b1d2fa5753

View file

@ -15,8 +15,8 @@ export default function SettingsTab() {
emailVerified, phoneVerified, setEmailVerified, setPhoneVerified, emailVerified, phoneVerified, setEmailVerified, setPhoneVerified,
// Business Details // Business Details
gstin, setGstin, isGstinVerified, handleVerifyGstin, gstin, setGstin, isGstinVerified, handleVerifyGstin,
aadharFile, aadharS3Key, aadharUrl, aadharFile, aadharS3Key, aadharUrl, setAadharS3Key, setAadharFile,
panFile, panS3Key, panUrl, panFile, panS3Key, panUrl, setPanS3Key, setPanFile,
// Location // Location
address, setAddress address, setAddress
} = useSeller(); } = useSeller();
@ -25,6 +25,14 @@ export default function SettingsTab() {
const [saveSuccess, setSaveSuccess] = useState(false); const [saveSuccess, setSaveSuccess] = useState(false);
const [saveError, setSaveError] = useState(''); const [saveError, setSaveError] = useState('');
const [localAadhar, setLocalAadhar] = useState<File | null>(null);
const [localAadharPreview, setLocalAadharPreview] = useState<string | null>(null);
const [isUploadingAadhar, setIsUploadingAadhar] = useState(false);
const [localPan, setLocalPan] = useState<File | null>(null);
const [localPanPreview, setLocalPanPreview] = useState<string | null>(null);
const [isUploadingPan, setIsUploadingPan] = useState(false);
// OTP Verification local state // OTP Verification local state
const [emailOtpSentLocal, setEmailOtpSentLocal] = useState(false); const [emailOtpSentLocal, setEmailOtpSentLocal] = useState(false);
const [phoneOtpSentLocal, setPhoneOtpSentLocal] = useState(false); const [phoneOtpSentLocal, setPhoneOtpSentLocal] = useState(false);
@ -342,23 +350,61 @@ export default function SettingsTab() {
<div className="file has-name is-fullwidth"> <div className="file has-name is-fullwidth">
<label className="file-label"> <label className="file-label">
<input className="file-input" type="file" onChange={e => { <input className="file-input" type="file" onChange={e => {
if (e.target.files?.[0]) uploadDocument(e.target.files[0], 'aadhar'); const file = e.target.files?.[0];
if (file) {
setLocalAadhar(file);
setLocalAadharPreview(URL.createObjectURL(file));
}
}} /> }} />
<span className="file-cta"> <span className="file-cta">
<span className="file-icon"><span className="material-symbols-outlined">upload</span></span> <span className="file-icon"><span className="material-symbols-outlined">upload</span></span>
<span className="file-label">Choose Aadhar...</span> <span className="file-label">Choose Aadhar...</span>
</span> </span>
<span className="file-name">{aadharFile || aadharS3Key || 'No file uploaded'}</span> <span className="file-name">{localAadhar ? localAadhar.name : (aadharFile || aadharS3Key || 'No file uploaded')}</span>
</label> </label>
</div> </div>
{/* Add Preview Link Below */} {/* Add Preview Link Below */}
{aadharUrl && ( {localAadhar ? (
<p className="help mt-2"> <div className="mt-2 is-flex is-align-items-center" style={{ gap: '10px' }}>
<a href={aadharUrl} target="_blank" rel="noopener noreferrer"> <a href={localAadharPreview!} target="_blank" rel="noopener noreferrer" className="button is-small is-info is-light">
<span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span> <span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span>
Preview Aadhar <span>Preview Selected</span>
</a> </a>
</p> <button
type="button"
className={`button is-small is-primary ${isUploadingAadhar ? 'is-loading' : ''}`}
onClick={async () => {
setIsUploadingAadhar(true);
const s3Key = await uploadDocument(localAadhar, 'aadhar');
setAadharS3Key(s3Key);
setAadharFile(localAadhar.name);
setLocalAadhar(null);
setLocalAadharPreview(null);
setIsUploadingAadhar(false);
}}
>
Upload
</button>
<button
type="button"
className="button is-small is-danger is-light"
onClick={() => {
setLocalAadhar(null);
setLocalAadharPreview(null);
}}
>
Cancel
</button>
</div>
) : (
aadharUrl && (
<p className="help mt-2">
<a href={aadharUrl} target="_blank" rel="noopener noreferrer">
<span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span>
Preview Uploaded Aadhar
</a>
</p>
)
)} )}
</div> </div>
</div> </div>
@ -370,23 +416,61 @@ export default function SettingsTab() {
<div className="file has-name is-fullwidth"> <div className="file has-name is-fullwidth">
<label className="file-label"> <label className="file-label">
<input className="file-input" type="file" onChange={e => { <input className="file-input" type="file" onChange={e => {
if (e.target.files?.[0]) uploadDocument(e.target.files[0], 'pan'); const file = e.target.files?.[0];
if (file) {
setLocalPan(file);
setLocalPanPreview(URL.createObjectURL(file));
}
}} /> }} />
<span className="file-cta"> <span className="file-cta">
<span className="file-icon"><span className="material-symbols-outlined">upload</span></span> <span className="file-icon"><span className="material-symbols-outlined">upload</span></span>
<span className="file-label">Choose PAN...</span> <span className="file-label">Choose PAN...</span>
</span> </span>
<span className="file-name">{panFile || panS3Key || 'No file uploaded'}</span> <span className="file-name">{localPan ? localPan.name : (panFile || panS3Key || 'No file uploaded')}</span>
</label> </label>
</div> </div>
{/* Add Preview Link Below */} {/* Add Preview Link Below */}
{panUrl && ( {localPan ? (
<p className="help mt-2"> <div className="mt-2 is-flex is-align-items-center" style={{ gap: '10px' }}>
<a href={panUrl} target="_blank" rel="noopener noreferrer"> <a href={localPanPreview!} target="_blank" rel="noopener noreferrer" className="button is-small is-info is-light">
<span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span> <span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span>
Preview PAN <span>Preview Selected</span>
</a> </a>
</p> <button
type="button"
className={`button is-small is-primary ${isUploadingPan ? 'is-loading' : ''}`}
onClick={async () => {
setIsUploadingPan(true);
const s3Key = await uploadDocument(localPan, 'pan');
setPanS3Key(s3Key);
setPanFile(localPan.name);
setLocalPan(null);
setLocalPanPreview(null);
setIsUploadingPan(false);
}}
>
Upload
</button>
<button
type="button"
className="button is-small is-danger is-light"
onClick={() => {
setLocalPan(null);
setLocalPanPreview(null);
}}
>
Cancel
</button>
</div>
) : (
panUrl && (
<p className="help mt-2">
<a href={panUrl} target="_blank" rel="noopener noreferrer">
<span className="icon is-small"><i className="material-symbols-outlined" style={{ fontSize: '14px' }}>visibility</i></span>
Preview Uploaded PAN
</a>
</p>
)
)} )}
</div> </div>
</div> </div>