file upload develop
This commit is contained in:
@@ -1,21 +1,22 @@
|
|||||||
import ProtectedFilesTable from '@/app/ui/marking-page/protected-files-table';
|
|
||||||
import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
import ProtectionSummary from '@/app/ui/marking-page/protection-summary';
|
||||||
import TestSection from '@/app/ui/marking-page/test-section';
|
import PageTitle from '@/app/ui/page-title';
|
||||||
import UploadSectionFile from '@/app/components/upload-section-file';
|
import UploadSectionFile from '@/app/components/upload-section-file';
|
||||||
import { useTranslations } from 'next-intl';
|
|
||||||
import FilesTable from '@/app/ui/dashboard/files-table';
|
import FilesTable from '@/app/ui/dashboard/files-table';
|
||||||
|
import { FileExtension } from '@/app/actions/definitions';
|
||||||
|
import { getAllowedFilesExtensions } from '@/app/actions/file-upload';
|
||||||
|
|
||||||
|
const ALLOWED_EXTENSIONS: FileExtension[] = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
|
||||||
|
const FILE_TYPE = "IMAGE"
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
/* const allowedFilesExtensions = await getAllowedFilesExtensions(FILE_TYPE);
|
||||||
|
console.log(allowedFilesExtensions); */
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const t = useTranslations('Global');
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="page-title">
|
<PageTitle title="image-protection" />
|
||||||
<h1>
|
|
||||||
{t('image-protection')}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<ProtectionSummary />
|
<ProtectionSummary />
|
||||||
<UploadSectionFile fileType="IMAGE"/>
|
<UploadSectionFile fileType={FILE_TYPE} allowedExtensions={ALLOWED_EXTENSIONS} />
|
||||||
{/* <TestSection /> */}
|
{/* <TestSection /> */}
|
||||||
<FilesTable />
|
<FilesTable />
|
||||||
{/* <ProtectedFilesTable /> */}
|
{/* <ProtectedFilesTable /> */}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const SignupFormSchema = z
|
|||||||
.string()
|
.string()
|
||||||
.min(2, { error: 'register-error-name' })
|
.min(2, { error: 'register-error-name' })
|
||||||
.regex(/^[^0-9]*$/, { message: 'register-error-no-digits' })
|
.regex(/^[^0-9]*$/, { message: 'register-error-no-digits' })
|
||||||
/* .refine(
|
/* .refine(
|
||||||
(value) => !/\p{Emoji}/u.test(value),
|
(value) => !/\p{Emoji}/u.test(value),
|
||||||
{ message: 'no-emoji-allowed' }
|
{ message: 'no-emoji-allowed' }
|
||||||
) */
|
) */
|
||||||
@@ -48,7 +48,7 @@ export const SignupFormSchema = z
|
|||||||
.min(8, { error: 'register-error-password-symbols' })
|
.min(8, { error: 'register-error-password-symbols' })
|
||||||
.regex(/[a-zA-Zа-яёА-ЯЁ]/, { error: 'register-error-password-one-letter' })
|
.regex(/[a-zA-Zа-яёА-ЯЁ]/, { error: 'register-error-password-one-letter' })
|
||||||
.regex(/[0-9]/, { error: 'register-error-password-one-digit' })
|
.regex(/[0-9]/, { error: 'register-error-password-one-digit' })
|
||||||
/* .refine(
|
/* .refine(
|
||||||
(value) => !/\p{Emoji}/u.test(value),
|
(value) => !/\p{Emoji}/u.test(value),
|
||||||
{ message: 'no-emoji-allowed' }
|
{ message: 'no-emoji-allowed' }
|
||||||
) */
|
) */
|
||||||
@@ -78,6 +78,8 @@ export const loginFormSchema = z
|
|||||||
|
|
||||||
export const localDevelopmentUrl = 'http://localhost';
|
export const localDevelopmentUrl = 'http://localhost';
|
||||||
|
|
||||||
|
export type FileExtension = 'jpg' | 'jpeg' | 'png' | 'gif' | 'bmp';
|
||||||
|
|
||||||
export const testUserData = {
|
export const testUserData = {
|
||||||
fullName: 'test',
|
fullName: 'test',
|
||||||
email: 'test@mail.com',
|
email: 'test@mail.com',
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { localDevelopmentUrl } from '@/app/actions/definitions';
|
import { localDevelopmentUrl } from '@/app/actions/definitions';
|
||||||
import { getSessionData, createSession } from '@/app/actions/session';
|
import { getSessionData, createSession } from '@/app/actions/session';
|
||||||
import { number } from 'zod';
|
|
||||||
|
|
||||||
const API_BASE_URL = process.env.NODE_ENV === 'development'
|
const API_BASE_URL = process.env.NODE_ENV === 'development'
|
||||||
? localDevelopmentUrl
|
? localDevelopmentUrl
|
||||||
@@ -51,7 +50,6 @@ export async function fileUpload(messageBody: initMessageBody) {
|
|||||||
},
|
},
|
||||||
message_code: string
|
message_code: string
|
||||||
};
|
};
|
||||||
console.log(parsed);
|
|
||||||
|
|
||||||
if (parsed.message_desc === 'Operation successful') {
|
if (parsed.message_desc === 'Operation successful') {
|
||||||
return parsed.message_body;
|
return parsed.message_body;
|
||||||
@@ -69,6 +67,7 @@ export async function fileUpload(messageBody: initMessageBody) {
|
|||||||
|
|
||||||
export async function cancelUpload(udloadId: string) {
|
export async function cancelUpload(udloadId: string) {
|
||||||
console.log('cancelUpload');
|
console.log('cancelUpload');
|
||||||
|
console.log(udloadId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
@@ -114,20 +113,52 @@ export async function cancelUpload(udloadId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function chunkUpload(formData: FormData) {
|
export async function chunkUpload(formData: FormData) {
|
||||||
console.log('chunkUpload');
|
|
||||||
console.log(`${API_BASE_URL}/api/v1/files/chunk`);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/api/v1/files/chunk`, {
|
const response = await fetch(`${API_BASE_URL}/api/v1/files/chunk`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(response);
|
if (response.ok) {
|
||||||
|
let parsed = await response.json();
|
||||||
|
|
||||||
|
if (parsed.message_desc === 'Upload cancelled successfully') {
|
||||||
|
console.log('chunkUpload');
|
||||||
|
console.log(parsed.message_body);
|
||||||
|
return parsed.message_body;
|
||||||
|
} else {
|
||||||
|
console.log('error cancel chunkUpload');
|
||||||
|
throw parsed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw (`${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkChunkStatus(upload_id: string) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
version: 1,
|
||||||
|
msg_id: 20004,
|
||||||
|
message_body: {
|
||||||
|
action: 'chunks',
|
||||||
|
upload_id
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let parsed = await response.json();
|
let parsed = await response.json();
|
||||||
console.log('response.ok');
|
|
||||||
console.log(parsed);
|
console.log(parsed);
|
||||||
|
|
||||||
if (parsed.message_desc === 'Upload cancelled successfully') {
|
if (parsed.message_desc === 'Upload cancelled successfully') {
|
||||||
@@ -144,3 +175,40 @@ export async function chunkUpload(formData: FormData) {
|
|||||||
return error
|
return error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getAllowedFilesExtensions(type: string) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
version: 1,
|
||||||
|
msg_id: 20004,
|
||||||
|
message_body: {
|
||||||
|
action: 'file_extension',
|
||||||
|
file_type: type
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let parsed = await response.json();
|
||||||
|
console.log(parsed);
|
||||||
|
|
||||||
|
if (parsed.message_desc === 'Operation successful') {
|
||||||
|
return parsed.message_body.file_extension;
|
||||||
|
} else {
|
||||||
|
console.log('error cancel getAllowedFilesExtensions');
|
||||||
|
throw parsed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw (`${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
import React, { useRef, useState, useCallback, ChangeEvent, DragEvent } from 'react';
|
import React, { useRef, useState, useCallback, ChangeEvent, DragEvent } from 'react';
|
||||||
import { IconShieldAdd } from '@/app/ui/icons/icons';
|
import { IconShieldAdd } from '@/app/ui/icons/icons';
|
||||||
import { fileUpload, cancelUpload, chunkUpload } from '@/app/actions/file-upload';
|
import { fileUpload, cancelUpload, chunkUpload, checkChunkStatus } from '@/app/actions/file-upload';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
import { FileExtension } from '@/app/actions/definitions';
|
||||||
|
|
||||||
interface SelectedFile {
|
interface SelectedFile {
|
||||||
file: File;
|
file: File;
|
||||||
@@ -23,28 +25,40 @@ interface FileUploadInitResponse {
|
|||||||
status: string
|
status: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SupportedFormat = 'image/jpeg' | 'image/png' | 'image/gif' | 'image/bmp';
|
interface UploadSectionFile {
|
||||||
type FileExtension = 'jpg' | 'jpeg' | 'png' | 'gif' | 'bmp';
|
fileType: string
|
||||||
|
allowedExtensions: FileExtension[]
|
||||||
|
}
|
||||||
|
|
||||||
export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
/* type SupportedFormat = 'image/jpeg' | 'image/png' | 'image/gif' | 'image/bmp'; */
|
||||||
|
|
||||||
|
export default function UploadSectionFile({ fileType, allowedExtensions }: UploadSectionFile) {
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
const [isDragging, setIsDragging] = useState<boolean>(false);
|
const [isDragging, setIsDragging] = useState<boolean>(false);
|
||||||
const [selectedFile, setSelectedFile] = useState<SelectedFile | null>(null);
|
const [selectedFile, setSelectedFile] = useState<SelectedFile | null>(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [uploadId, setUploadId] = useState<any>(null);
|
const [uploadId, setUploadId] = useState<string | null>(null);
|
||||||
|
const [isFileUploaded, setIsFileUploaded] = useState<boolean>(false);
|
||||||
|
|
||||||
const SUPPORTED_FORMATS: SupportedFormat[] = [
|
const t = useTranslations('Global');
|
||||||
|
console.log('fileType');
|
||||||
|
console.log(allowedExtensions);
|
||||||
|
let SUPPORTED_FORMATS: string[] = []
|
||||||
|
|
||||||
|
if (fileType === "IMAGE") {
|
||||||
|
SUPPORTED_FORMATS = [
|
||||||
'image/jpeg',
|
'image/jpeg',
|
||||||
'image/png',
|
'image/png',
|
||||||
'image/gif',
|
'image/gif',
|
||||||
'image/bmp'
|
'image/bmp'
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const ALLOWED_EXTENSIONS: FileExtension[] = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
|
const ALLOWED_EXTENSIONS: FileExtension[] = allowedExtensions;
|
||||||
|
|
||||||
|
|
||||||
const validateFile = (file: File): { isValid: boolean; errorMessage?: string } => {
|
const validateFile = (file: File): { isValid: boolean; errorMessage?: string } => {
|
||||||
if (!SUPPORTED_FORMATS.includes(file.type as SupportedFormat)) {
|
if (!SUPPORTED_FORMATS.includes(file.type as string)) {
|
||||||
const extension = file.name.split('.').pop()?.toLowerCase();
|
const extension = file.name.split('.').pop()?.toLowerCase();
|
||||||
if (!extension || !ALLOWED_EXTENSIONS.includes(extension as FileExtension)) {
|
if (!extension || !ALLOWED_EXTENSIONS.includes(extension as FileExtension)) {
|
||||||
return {
|
return {
|
||||||
@@ -171,9 +185,11 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
URL.revokeObjectURL(selectedFile.preview);
|
URL.revokeObjectURL(selectedFile.preview);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await cancelUpload(uploadId);
|
if (uploadId) {
|
||||||
console.log(response);
|
await cancelUpload(uploadId);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsFileUploaded(false);
|
||||||
setSelectedFile(null);
|
setSelectedFile(null);
|
||||||
setError(null);
|
setError(null);
|
||||||
};
|
};
|
||||||
@@ -185,38 +201,21 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
extension: file.name.split('.')[1],
|
extension: file.name.split('.')[1],
|
||||||
file_size: file.file.size
|
file_size: file.file.size
|
||||||
};
|
};
|
||||||
console.log("initMessageBody");
|
|
||||||
|
|
||||||
const response = await fileUpload(initMessageBody) as FileUploadInitResponse;
|
const response = await fileUpload(initMessageBody) as FileUploadInitResponse;
|
||||||
|
|
||||||
if (response?.upload_id) {
|
if (response?.upload_id) {
|
||||||
setUploadId(response.upload_id);
|
setUploadId(response.upload_id);
|
||||||
console.log(response);
|
|
||||||
console.log(file.file);
|
|
||||||
/* {
|
|
||||||
chunk_size: 5242880
|
|
||||||
field_errors: null
|
|
||||||
file_name: "ooop.jpg"
|
|
||||||
status: "INITIATED"
|
|
||||||
total_chunks: 1
|
|
||||||
upload_id: "623261f0-f13b-4d06-8df5-365cb19d7ada"
|
|
||||||
} */
|
|
||||||
/* file.file */
|
|
||||||
const CHUNK_SIZE = response.chunk_size;
|
const CHUNK_SIZE = response.chunk_size;
|
||||||
const totalChunks = response.total_chunks;
|
const totalChunks = response.total_chunks;
|
||||||
const fileSize = file.file.size;
|
const fileSize = file.file.size;
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let chunkIndex = 0;
|
let chunkIndex = 0;
|
||||||
|
|
||||||
console.log('response.upload_id');
|
|
||||||
console.log(response.upload_id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (start < fileSize) {
|
while (start < fileSize) {
|
||||||
const end = Math.min(start + CHUNK_SIZE, fileSize);
|
const end = Math.min(start + CHUNK_SIZE, fileSize);
|
||||||
const chunk = file.file.slice(start, end);
|
const chunk = file.file.slice(start, end);
|
||||||
console.log(file.file);
|
|
||||||
console.log(chunk);
|
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('upload_id', response.upload_id);
|
formData.append('upload_id', response.upload_id);
|
||||||
@@ -224,10 +223,18 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
formData.append('chunk', chunk);
|
formData.append('chunk', chunk);
|
||||||
const chunkResponse = await chunkUpload(formData);
|
const chunkResponse = await chunkUpload(formData);
|
||||||
|
|
||||||
console.log(chunkResponse);
|
if (chunkResponse.message_desc !== 'Chunk uploaded successfully') {
|
||||||
|
throw 'Er1'
|
||||||
|
}
|
||||||
|
|
||||||
if (chunkIndex === totalChunks - 1) {
|
if (chunkIndex === totalChunks - 1) {
|
||||||
console.log('upload done');
|
const chunkStatus = await checkChunkStatus(response.upload_id);
|
||||||
|
if (chunkStatus.message_body.missing_chunks === 0) {
|
||||||
|
setUploadId(null);
|
||||||
|
setIsFileUploaded(true);
|
||||||
|
} else {
|
||||||
|
throw 'Er2'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
start = end;
|
start = end;
|
||||||
@@ -236,7 +243,8 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
|
|
||||||
console.log('File uploaded successfully');
|
console.log('File uploaded successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Upload error:', error);
|
setError('Chunk uploaded error ' + error);
|
||||||
|
console.error('Chunk upload error:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,7 +259,9 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="upload-section">
|
<div className="upload-section">
|
||||||
<h3>Загрузить изображение для защиты</h3>
|
<h3>
|
||||||
|
{t('download-for-protection', { fileType: t(fileType.toLocaleLowerCase()) })}
|
||||||
|
</h3>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`drag-drop-zone ${isDragging ? 'dragging' : ''}`}
|
className={`drag-drop-zone ${isDragging ? 'dragging' : ''}`}
|
||||||
@@ -268,12 +278,18 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconShieldAdd />
|
<IconShieldAdd />
|
||||||
<h4>Перетащите фаил сюда</h4>
|
<h4>
|
||||||
<p className="mb-2.5 text-[#6b7280]">или</p>
|
{t('drag-the-file-here')}
|
||||||
|
</h4>
|
||||||
|
<p className="mb-2.5 text-[#6b7280]">
|
||||||
|
{t('or')}
|
||||||
|
</p>
|
||||||
<input
|
<input
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
type="file"
|
type="file"
|
||||||
accept=".jpg,.jpeg,.png,.gif,.bmp"
|
accept={
|
||||||
|
ALLOWED_EXTENSIONS.map(e => `.${e}`).join(',')
|
||||||
|
}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleFileInputChange}
|
onChange={handleFileInputChange}
|
||||||
aria-label="Выбор файла для защиты"
|
aria-label="Выбор файла для защиты"
|
||||||
@@ -284,11 +300,11 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
onClick={handleButtonClick}
|
onClick={handleButtonClick}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Выбрать файлы для защиты
|
{t('select-files-to-protect')}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p className="description">
|
<p className="description">
|
||||||
Разрешение изображение: 100x100 - 10000x10000 пикселей
|
Разрешение изображение: 100x100 - 10000x10000
|
||||||
</p>
|
</p>
|
||||||
<p className="description">
|
<p className="description">
|
||||||
Размер файла: до 20 МБ
|
Размер файла: до 20 МБ
|
||||||
@@ -299,7 +315,7 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<div className="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
|
<div className="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
|
||||||
<p className="text-red-600 font-medium">❌ {error}</p>
|
<p className="text-red-600 font-medium">{error}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -308,11 +324,16 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
className="selected-file"
|
className="selected-file"
|
||||||
>
|
>
|
||||||
<div className="selected-file-file-info">
|
<div className="selected-file-file-info">
|
||||||
|
<div>
|
||||||
<p className="text-gray-700">
|
<p className="text-gray-700">
|
||||||
<span className="font-medium">Файл:</span> {selectedFile.name}
|
<span className="font-medium">
|
||||||
|
{t('file')}:
|
||||||
|
</span> {selectedFile.name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-700">
|
<p className="text-gray-700">
|
||||||
<span className="font-medium">Размер:</span> {selectedFile.size}
|
<span className="font-medium">
|
||||||
|
{t('size')}:
|
||||||
|
</span> {selectedFile.size}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-700">
|
<p className="text-gray-700">
|
||||||
<span className="font-medium">Стоимость защиты:</span> 0
|
<span className="font-medium">Стоимость защиты:</span> 0
|
||||||
@@ -321,6 +342,14 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
<span className="font-medium">Текущий баланс:</span> 0
|
<span className="font-medium">Текущий баланс:</span> 0
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
{isFileUploaded && (
|
||||||
|
<div className="font-medium text-green-600 text-2xl">
|
||||||
|
{t('file-successfully-uploaded')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
src={selectedFile.preview}
|
src={selectedFile.preview}
|
||||||
@@ -335,7 +364,7 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
onClick={handleClearFile}
|
onClick={handleClearFile}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Отмена
|
{isFileUploaded ? t('close') : t('cancel')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-confirm"
|
className="btn btn-confirm"
|
||||||
@@ -344,7 +373,22 @@ export default function UploadSectionFile({ fileType }: { fileType: string }) {
|
|||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Подтвердить защиту
|
{t('upload-file')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-cancel"
|
||||||
|
type="button"
|
||||||
|
onClick={
|
||||||
|
async () => {
|
||||||
|
if (uploadId) {
|
||||||
|
console.log('checkChunkStatus')
|
||||||
|
const response = await checkChunkStatus(uploadId);
|
||||||
|
console.log(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
dev-test-button
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -492,6 +492,8 @@
|
|||||||
|
|
||||||
&-file-info {
|
&-file-info {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uploaded-image {
|
.uploaded-image {
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
|
export default function PageTitle({ title }: { title: string }) {
|
||||||
|
const t = useTranslations('Global');
|
||||||
|
return (
|
||||||
|
<div className="page-title">
|
||||||
|
<h1>
|
||||||
|
{t(title)}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -17,7 +17,9 @@
|
|||||||
"checks": "Checks",
|
"checks": "Checks",
|
||||||
"check": "Checks",
|
"check": "Checks",
|
||||||
"videos": "Videos",
|
"videos": "Videos",
|
||||||
|
"video": "vides",
|
||||||
"audios": "Audio",
|
"audios": "Audio",
|
||||||
|
"audio": "audio",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"main": "Main",
|
"main": "Main",
|
||||||
"marking": "Marking",
|
"marking": "Marking",
|
||||||
@@ -116,7 +118,16 @@
|
|||||||
"view-all": "View all",
|
"view-all": "View all",
|
||||||
"days-ago": "days ago",
|
"days-ago": "days ago",
|
||||||
"there-are-no-files-yet": "There are no files yet",
|
"there-are-no-files-yet": "There are no files yet",
|
||||||
"add": "Add"
|
"add": "Add",
|
||||||
|
"file-successfully-uploaded": "File has been successfully uploaded",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"close": "Close",
|
||||||
|
"upload-file": "Upload file",
|
||||||
|
"or": "or",
|
||||||
|
"drag-the-file-here": "Drag the file here",
|
||||||
|
"select-files-to-protect": "Select files to protect",
|
||||||
|
"download-for-protection": "Download {fileType} for protection",
|
||||||
|
"image": "image"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "and",
|
"and": "and",
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
"checks": "Проверки",
|
"checks": "Проверки",
|
||||||
"check": "Проверок",
|
"check": "Проверок",
|
||||||
"videos": "Видео",
|
"videos": "Видео",
|
||||||
|
"video": "видео",
|
||||||
"audios": "Аудио",
|
"audios": "Аудио",
|
||||||
|
"audio": "аудио",
|
||||||
"images": "Изображения",
|
"images": "Изображения",
|
||||||
"main": "Главная",
|
"main": "Главная",
|
||||||
"marking": "Маркировка",
|
"marking": "Маркировка",
|
||||||
@@ -116,7 +118,16 @@
|
|||||||
"view-all": "Посмотреть все",
|
"view-all": "Посмотреть все",
|
||||||
"days-ago": "дней назад",
|
"days-ago": "дней назад",
|
||||||
"there-are-no-files-yet": "Файлов пока нет",
|
"there-are-no-files-yet": "Файлов пока нет",
|
||||||
"add": "Добавить"
|
"add": "Добавить",
|
||||||
|
"file-successfully-uploaded": "Файл успешно загружен",
|
||||||
|
"cancel": "Отмена",
|
||||||
|
"close": "Закрыть",
|
||||||
|
"upload-file": "Загрузить файл",
|
||||||
|
"or": "или",
|
||||||
|
"drag-the-file-here": "Перетащите файл сюда",
|
||||||
|
"select-files-to-protect": "Выбрать файлы для защиты",
|
||||||
|
"download-for-protection": "Загрузить {fileType} для защиты",
|
||||||
|
"image": "изображений"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "и",
|
"and": "и",
|
||||||
|
|||||||
Reference in New Issue
Block a user