fix file verification upload

This commit is contained in:
smanylov
2026-04-27 14:58:54 +07:00
parent abc07a5e2f
commit a7c203d7a4
5 changed files with 34 additions and 100 deletions
+4
View File
@@ -230,6 +230,10 @@
display: flex;
flex-direction: column;
h3 {
margin-bottom: 10px;
}
.drag-drop-zone {
border: 2px dashed #6366f1;
border-radius: .75rem;
@@ -5,7 +5,7 @@ import { fileUpload, cancelUpload, chunkUpload, checkChunkStatus, checkOperation
import { useTranslations } from 'next-intl';
import { useNavigationBlocker } from '@/app/hooks/useNavigationBlocker';
import { useQueryClient } from '@tanstack/react-query';
import {useUserProfile} from '@/app/hooks/react-query/useUserDataInfo';
import { useUserProfile } from '@/app/hooks/react-query/useUserDataInfo';
export interface SelectedFile {
file: File;
@@ -48,9 +48,9 @@ export default function VerificationUploadSection({
const [isDragging, setIsDragging] = useState<boolean>(false);
const [selectedFiles, setSelectedFiles] = useState<SelectedFile[]>([]);
const [error, setError] = useState<string | null>(null);
const [activeUploads, setActiveUploads] = useState<Set<string>>(new Set()); // ID активных загрузок
const [activeUploads, setActiveUploads] = useState<Set<string>>(new Set());
const queryClient = useQueryClient();
const isCancelledRef = useRef<Map<string, boolean>>(new Map()); // Для отслеживания отмен по файлам
const isCancelledRef = useRef<Map<string, boolean>>(new Map());
const selectedFilesRef = useRef<SelectedFile[]>(selectedFiles);
const t = useTranslations('Global');
@@ -62,9 +62,9 @@ export default function VerificationUploadSection({
return allowedExtensions.map(e => `.${e}`).join(', ');
}, [allowedExtensions]);
const validateFile = (file: File): { isValid: boolean; errorMessage?: string } => {
const validateFile = (file: File, extension: string | undefined): { isValid: boolean; errorMessage?: string } => {
if (!allowedExtensions.includes(file.type as string)) {
const extension = file.name.split('.').pop()?.toLowerCase();
if (!extension || !allowedExtensions.includes(extension as string)) {
return {
isValid: false,
@@ -127,8 +127,8 @@ export default function VerificationUploadSection({
duplicateNames.push(file.name);
continue;
}
const validation = validateFile(file);
const extension = file.name.split('.').pop()?.toLowerCase();
const validation = validateFile(file, extension);
if (!validation.isValid) {
setError(prev => prev ? `${prev}, ${validation.errorMessage}` : validation.errorMessage || t('unknown-validation-error'));
@@ -139,7 +139,8 @@ export default function VerificationUploadSection({
width: number,
height: number,
} | undefined = undefined;
if (fileType === "image") {
if (fileType === "image" && extension !== 'pdf') {
try {
dimensions = await getImageDimensions(file) as { width: number, height: number };
if (dimensions?.width < 100 || dimensions?.height < 100 ||
@@ -224,7 +225,6 @@ export default function VerificationUploadSection({
f.uploadId !== fileId && f.name !== fileId
));
} else {
console.log('clear all')
selectedFiles.forEach(file => {
if (file.preview) {
URL.revokeObjectURL(file.preview);
@@ -247,17 +247,16 @@ export default function VerificationUploadSection({
const uploadSingleFile = async (fileInfo: SelectedFile, uploadType: 'single' | 'multi', isLastFIle: boolean): Promise<void> => {
const fileId = `${fileInfo.name}-${Date.now()}`;
isCancelledRef.current.set(fileId, false);
setError(null);
if (uploadType === 'single') {
setError(null);
/* if (uploadType === 'single') {
const priceCheck = await checkOperationPrice('checkTokensForProtect', 1, fileType);
if (!priceCheck.success) {
const errorMessage = `${t('there-are-not-enough-funds-to-protect-file', { count: priceCheck?.tokens_count })}`;
setError(errorMessage);
return;
}
}
} */
try {
setSelectedFiles(prev => prev.map(f =>
@@ -267,7 +266,7 @@ export default function VerificationUploadSection({
const extension = fileInfo.file.name.split('.').pop() || '';
const initMessageBody = {
file_name: fileInfo.file.name,
file_type: fileType,
file_type: extension === 'pdf' ? 'document' : fileType,
extension: extension,
file_size: fileInfo.file.size
};
@@ -353,21 +352,15 @@ export default function VerificationUploadSection({
if (selectedFilesRef.current.length === 0) {
return;
}
const priceCheck = await checkOperationPrice('checkTokensForProtect', selectedFilesRef.current.length, fileType);
if (priceCheck.success) {
const files = selectedFilesRef.current;
const totalFiles = files.length;
const files = selectedFilesRef.current;
const totalFiles = files.length;
for (let i = 0; i < totalFiles; i++) {
const file = files[i];
const isLastFile = i === totalFiles - 1;
for (let i = 0; i < totalFiles; i++) {
const file = files[i];
const isLastFile = i === totalFiles - 1;
await uploadSingleFile(file, 'multi', isLastFile);
}
} else {
const errorMessage = `${t('there-are-not-enough-funds-to-protect-files', { count: priceCheck?.tokens_count })}`;
setError(errorMessage);
await uploadSingleFile(file, 'multi', isLastFile);
}
}, [maxParallelUploads]);
@@ -404,7 +397,7 @@ export default function VerificationUploadSection({
return (
<div className="verefication-block" >
<h3>
Загрузка изображений удостоверения личности
{t('uploading-id-images')}
</h3>
< div
@@ -413,10 +406,6 @@ export default function VerificationUploadSection({
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
{/* <h4>
{t('drag-the-file-here')}
</h4> */}
{
fileType === "image" && (
<p className="description" >
@@ -427,18 +416,15 @@ export default function VerificationUploadSection({
<p className="description" >
{t('file-format')}: {acceptString}
</p>
{/* < p className="description" >
{t('file-size')}: {t('to')} {(maxFileSize / 1024 / 1024)} {t('mb')}
</p> */}
< input
ref={fileInputRef}
type="file"
accept={acceptString}
accept={`${acceptString}`}
style={{ display: 'none' }}
onChange={handleFileInputChange}
aria-label="Выбор файла для защиты"
multiple // Добавляем multiple для выбора нескольких файлов
multiple
/>
{
@@ -453,22 +439,6 @@ export default function VerificationUploadSection({
selectedFiles.length > 0 && (
<div className="mt-4" >
<div className="selected-file-action-panel" >
{/* <div>
<p className="selected-file-action-info" >
<span>{t('total-files')}: {selectedFiles.length}</span>
<span>{t('uploading')}: {uploadingCount}</span>
<span>{t('completed')}: {completedCount}</span>
</p>
<div className="w-full bg-gray-200 rounded-full h-2.5 mt-2">
<div
className="bg-blue-600 h-2.5 rounded-full transition-all duration-300"
style={{ width: `${getTotalProgress}%` }
}
>
</div>
</div>
</div> */}
<button
className={`btn btn-primary`}
onClick={handleStartAllUploads}
@@ -498,27 +468,6 @@ export default function VerificationUploadSection({
<p className="text-gray-700" >
<span className="font-medium" > {t('file')}: </span> {file.name}
</p>
{/* < p className="text-gray-700" >
<span className="font-medium" > {t('size')}: </span> {file.size}
</p> */}
{/* < p className="text-gray-700" >
<span className="font-medium" > {t('status')}: </span>
<span className={`ml-2 ${file.status === 'completed' ? 'text-green-600' :
file.status === 'uploading' ? 'text-blue-600' :
file.status === 'error' ? 'text-red-600' :
'text-gray-600'
}`}>
{
file.status === 'completed' ? t('completed') :
file.status === 'uploading' ? t('uploading') :
file.status === 'error' ? t('error') :
t('pending')
}
</span>
</p> */}
{
file.error && (
<p className="text-red-600 text-sm mt-1" > {file.error} </p>
@@ -534,32 +483,9 @@ export default function VerificationUploadSection({
>
</div>
</div>
{/* <span className={
`upload-progress ${file.status === 'completed' ? 'text-green-600' :
file.status === 'uploading' ? 'text-blue-600' :
'text-gray-600'
}`
}>
{file.progress} %
</span> */}
<div
className="selected-file-actions"
>
{/* {
file.status === 'pending' && (
<button
className="btn btn-confirm"
onClick={() => uploadSingleFile(file, 'single')
}
type="button"
disabled={uploadingCount >= maxParallelUploads}
>
{t('start-upload')}
</button>
)
} */}
< button
className="btn btn-cancel"
onClick={() => handleClearFile(file.uploadId || file.name)}
@@ -582,7 +508,7 @@ export default function VerificationUploadSection({
type="button"
disabled={uploadingCount > maxParallelUploads}
>
выберете документ(ы) для загрузки
{t('select-document-to-upload')}
</button>
</div>
);
@@ -40,7 +40,7 @@ export default function SettingUserVerification() {
{userData?.verifiedStatus === 'NOT_VERIFIED' || userData?.verifiedStatus === null ? (
<VerificationUploadSection
fileType="image"
allowedExtensions={allFilesExtensions.images}
allowedExtensions={[...allFilesExtensions.images, 'pdf']}
maxFileSize={allFilesExtensions.maxFileSize}
/>
) : (
+3 -1
View File
@@ -446,7 +446,9 @@
"claims": "Claims",
"complaints": "Complaints",
"recent-cases": "Recent cases",
"select-at-least-one-filter": "Select at least one filter"
"select-at-least-one-filter": "Select at least one filter",
"select-document-to-upload": "Select document(s) to upload",
"uploading-id-images": "Uploading ID images"
},
"Login-register-form": {
"and": "and",
+3 -1
View File
@@ -446,7 +446,9 @@
"claims": "Претензии",
"complaints": "Жалобы",
"recent-cases": "Недавние дела",
"select-at-least-one-filter": "Выберите хотя бы один фильтр"
"select-at-least-one-filter": "Выберите хотя бы один фильтр",
"select-document-to-upload": "Выберите документ(ы) для загрузки",
"uploading-id-images": "Загрузка изображений удостоверения личности"
},
"Login-register-form": {
"and": "и",