add file download for tracking page
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "no-copy-frontend",
|
||||
"version": "0.109.0",
|
||||
"version": "0.110.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 2999",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Providers from '@/app/providers/getQueryServer'
|
||||
import type { Metadata } from "next";
|
||||
import { NextIntlClientProvider, hasLocale } from 'next-intl';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { routing } from '@/i18n/routing';
|
||||
import { ToastProvider } from '@/app/providers/ToastProvider';
|
||||
import ClientProviders from '@/app/providers/ClientProviders';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
import "../styles/globals.css";
|
||||
import "../styles/global-styles.scss";
|
||||
@@ -30,14 +30,15 @@ export default async function RootLayout({
|
||||
}
|
||||
|
||||
return (
|
||||
<html lang={locale}>
|
||||
<html>
|
||||
<body>
|
||||
<NextIntlClientProvider>
|
||||
<Providers>
|
||||
{children}
|
||||
<ToastProvider />
|
||||
</Providers>
|
||||
</NextIntlClientProvider>
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
<NextIntlClientProvider locale={locale}>
|
||||
<ClientProviders>
|
||||
{children}
|
||||
</ClientProviders>
|
||||
</NextIntlClientProvider>
|
||||
</Suspense>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import { PdfProvider } from '@/app/contexts/PdfContext';
|
||||
import { WatchDocProviders } from '@/app/providers/ClientProviders';
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<PdfProvider>
|
||||
{children}
|
||||
</PdfProvider>
|
||||
<WatchDocProviders>
|
||||
<PdfProvider>
|
||||
{children}
|
||||
</PdfProvider>
|
||||
</WatchDocProviders>
|
||||
);
|
||||
}
|
||||
@@ -119,7 +119,7 @@ export default async function Page({ searchParams }: PageProps) {
|
||||
|
||||
<div className="watch-doc-actions">
|
||||
{response?.permissions?.DOWNLOAD && (
|
||||
<DownloadButton />
|
||||
<DownloadButton fileId={docid} fileName={response?.fileName}/>
|
||||
)}
|
||||
<CopyLinkButton />
|
||||
</div>
|
||||
|
||||
@@ -239,3 +239,26 @@ export async function fetchTrackingStats() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function downloadTrackingFile(fileId: string, fileName?: string) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/v1/files/public-download/${fileId}`, {
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw 'failed-to-download-file';
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer()
|
||||
const base64 = Buffer.from(arrayBuffer).toString('base64')
|
||||
|
||||
return {
|
||||
data: base64,
|
||||
contentType: response.headers.get('content-type') || 'application/octet-stream',
|
||||
fileName: fileName ? fileName : 'fileName'
|
||||
}
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,49 @@
|
||||
'use client';
|
||||
|
||||
import { usePdf } from '@/app/contexts/PdfContext';
|
||||
import { downloadTrackingFile } from '@/app/actions/trackingActions';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { toast } from 'sonner';
|
||||
interface DownloadButtonProps {
|
||||
fileId: string;
|
||||
fileName?: string;
|
||||
}
|
||||
|
||||
export function DownloadButton() {
|
||||
const { downloadPdf } = usePdf();
|
||||
export function DownloadButton({ fileId, fileName }: DownloadButtonProps) {
|
||||
const t = useTranslations('Global');
|
||||
|
||||
const handleDownload = async () => {
|
||||
try {
|
||||
const result = await downloadTrackingFile(fileId, fileName);
|
||||
|
||||
if (!result) {
|
||||
throw 'failed-to-download-file'
|
||||
}
|
||||
|
||||
const byteCharacters = atob(result.data);
|
||||
const byteNumbers = new Array(byteCharacters.length);
|
||||
for (let i = 0; i < byteCharacters.length; i++) {
|
||||
byteNumbers[i] = byteCharacters.charCodeAt(i)
|
||||
}
|
||||
|
||||
const byteArray = new Uint8Array(byteNumbers);
|
||||
const blob = new Blob([byteArray], { type: result.contentType });
|
||||
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = result.fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
toast.success(`${t('file-is-downloading')} - `);
|
||||
} catch (error) {
|
||||
toast.error(t('failed-to-download-file'));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button className="btn btn-out" onClick={downloadPdf}>
|
||||
<button className="btn btn-out" onClick={handleDownload}>
|
||||
Скачать документ
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
'use client';
|
||||
|
||||
import Providers from './getQueryServer';
|
||||
import { ToastProvider } from './ToastProvider';
|
||||
|
||||
export default function ClientProviders({
|
||||
children
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Providers>
|
||||
{children}
|
||||
<ToastProvider />
|
||||
</Providers>
|
||||
);
|
||||
}
|
||||
|
||||
export function WatchDocProviders({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<Providers>
|
||||
{children}
|
||||
</Providers>
|
||||
);
|
||||
}
|
||||
@@ -1,34 +1,11 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
isServer,
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import { getQueryClient } from '@/app/providers/getQueryClient';
|
||||
|
||||
/* export function makeQueryClient() {
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 60 * 1000,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
let browserQueryClient: QueryClient | undefined = undefined
|
||||
|
||||
function getQueryClient() {
|
||||
if (isServer) {
|
||||
return makeQueryClient()
|
||||
} else {
|
||||
if (!browserQueryClient) browserQueryClient = makeQueryClient()
|
||||
return browserQueryClient
|
||||
}
|
||||
} */
|
||||
|
||||
export default function Providers({ children }: { children: React.ReactNode }) {
|
||||
const queryClient = getQueryClient();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user