From 3537bd1f3a8f0e3ada90175a41b69814e11e431b Mon Sep 17 00:00:00 2001 From: smanylov Date: Fri, 2 Jan 2026 12:52:01 +0700 Subject: [PATCH] add file download --- src/app/actions/fileEntity.ts | 3 +- src/app/api/download/[id]/route.ts | 51 +++++++++++++++++++++++++++++ src/app/components/tanstakTable.tsx | 30 +++++++++++++++-- 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 src/app/api/download/[id]/route.ts diff --git a/src/app/actions/fileEntity.ts b/src/app/actions/fileEntity.ts index 92ea466..cbe9b3c 100644 --- a/src/app/actions/fileEntity.ts +++ b/src/app/actions/fileEntity.ts @@ -1,5 +1,6 @@ 'use server' +import { NextRequest, NextResponse } from 'next/server'; import { getSessionData } from '@/app/actions/session'; import { API_BASE_URL } from '@/app/actions/definitions'; @@ -42,7 +43,7 @@ export async function getUserFilesData() { } } -export async function removeUserFile(fileId : string) { +export async function removeUserFile(fileId: string) { const token = await getSessionData('token'); try { diff --git a/src/app/api/download/[id]/route.ts b/src/app/api/download/[id]/route.ts new file mode 100644 index 0000000..f302580 --- /dev/null +++ b/src/app/api/download/[id]/route.ts @@ -0,0 +1,51 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { getSessionData } from '@/app/actions/session'; +import { API_BASE_URL } from '@/app/actions/definitions'; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ id: string }> } +) { + try { + const token = await getSessionData('token'); + + if (!token) { + return NextResponse.json( + { error: 'need authorization' }, + { status: 401 } + ); + } + + const { id } = await params; + + const response = await fetch(`${API_BASE_URL}/api/v1/files/download/${id}`, { + method: 'GET', + headers: { + "Authorization": token + } + }); + + if (!response.ok) { + throw new Error(`backend error: ${response.status}`); + } + + const fileBlob = await response.blob(); + const headers = new Headers(response.headers); + + return new NextResponse(fileBlob, { + status: 200, + headers: { + 'Content-Type': headers.get('content-type') || 'application/octet-stream', + 'Content-Disposition': headers.get('content-disposition') || `attachment; filename="file-${id}"`, + 'Content-Length': headers.get('content-length') || String(fileBlob.size), + }, + }); + + } catch (error) { + console.error('download error:', error); + return NextResponse.json( + { error: 'download file error' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/src/app/components/tanstakTable.tsx b/src/app/components/tanstakTable.tsx index a31301e..9c2c5c1 100644 --- a/src/app/components/tanstakTable.tsx +++ b/src/app/components/tanstakTable.tsx @@ -128,6 +128,8 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) { const [openWindow, setOpenWindow] = useState(false); const [openWindowChildren, setOpenWindowChildren] = useState(null); + const [isFileLoading, setIsFileLoading] = useState(false); + const t = useTranslations("Global"); // Определение колонок @@ -343,6 +345,7 @@ export default function TanstakFilesTable({ fileType }: { fileType: string }) {