diff --git a/apps/sn/app/components/lib/utils/cookie.tsx b/apps/sn/app/components/lib/utils/cookie.tsx new file mode 100644 index 000000000..8f5d0011b --- /dev/null +++ b/apps/sn/app/components/lib/utils/cookie.tsx @@ -0,0 +1,29 @@ +import Cookies from "js-cookie"; + +export function getCookie(name: string): string | undefined { + if (typeof window === "undefined") { + return undefined; + } + return Cookies.get(name); +} + +export function setCookie( + name: string, + value: string, + options?: Cookies.CookieAttributes, +): void { + if (typeof window === "undefined") { + return; + } + Cookies.set(name, value, options); +} + +export function removeCookie( + name: string, + options?: Cookies.CookieAttributes, +): void { + if (typeof window === "undefined") { + return; + } + Cookies.remove(name, options); +} diff --git a/apps/sn/app/components/lib/utils/fileUploadUtil.tsx b/apps/sn/app/components/lib/utils/fileUploadUtil.tsx new file mode 100644 index 000000000..4685dd336 --- /dev/null +++ b/apps/sn/app/components/lib/utils/fileUploadUtil.tsx @@ -0,0 +1,55 @@ +import { Upload, type HttpResponse } from "tus-js-client"; +import { getCookie, setCookie } from "@utils"; + +const AUTH_USER_ID = process.env.AUTH_USER_ID || ''; +const CLAIM_NAME = process.env.CLAIM_NAME || ''; +const BASE_URL = process.env.NEXT_PUBLIC_SERVER_API_URL || ''; +const END_URL = `${BASE_URL}/attach-service/api/v1/tus/upload`; + +type UploadOptions = { + handleUploadStart?: (upload: Upload) => void; + handleProgress?: (percentage: string) => void; + handleSuccess?: (upload: Upload) => void; + handleResponse?: (res: HttpResponse) => void; +}; + +export const handleUpload = (files: FileList, options?: UploadOptions) => { + let metadata = {}; + + const file = files.item(0); + if (!file) return; + metadata = { + filename: file.name, + filetype: file.type, + }; + + const upload = new Upload(file, { + endpoint: END_URL, + chunkSize: 10 * 1024 * 1024, + headers: { + [CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "", + [AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "", + }, + metadata, + onError(error) { + console.error(`Failed because: ${error}`); + }, + onProgress(bytesUploaded, bytesTotal) { + const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); + options?.handleProgress?.(percentage); + }, + onAfterResponse(req, res) { + const fileInfo = res.getHeader("X-File-Info"); + if (fileInfo === undefined || fileInfo === null) return; + + setCookie("atfl-cd-key", JSON.parse(fileInfo)?.atflCd ?? ""); + options?.handleResponse?.(res); + }, + onSuccess() { + options?.handleSuccess?.(upload); + }, + }); + + upload.start(); + options?.handleUploadStart?.(upload); +}; diff --git a/apps/sn/app/components/lib/utils/index.tsx b/apps/sn/app/components/lib/utils/index.tsx new file mode 100644 index 000000000..519afbc11 --- /dev/null +++ b/apps/sn/app/components/lib/utils/index.tsx @@ -0,0 +1,2 @@ +export { getCookie, setCookie, removeCookie } from "./cookie"; +export { handleUpload } from "./fileUploadUtil"; diff --git a/apps/sn/package.json b/apps/sn/package.json index 29f630648..42c19afa7 100644 --- a/apps/sn/package.json +++ b/apps/sn/package.json @@ -30,7 +30,8 @@ "zustand": "^5.0.3", "ol": "^7.3.0", "ol-ext": "^4.0.11", - "proj4": "^2.9.0" + "proj4": "^2.9.0", + "tus-js-client": "^4.3.1" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/apps/sn/tsconfig.json b/apps/sn/tsconfig.json index 74251f81b..5ed74c59e 100644 --- a/apps/sn/tsconfig.json +++ b/apps/sn/tsconfig.json @@ -32,7 +32,8 @@ "@common/network/*": ["../../../packages/common/network/*"], "@common/network": ["../../../packages/common/network/"], "@store": ["./store"], - "@service": ["./service"] + "@service": ["./service"], + "@utils": ["./components/lib/utils"] } }, "include": [