Skip to content

Commit

Permalink
Vault
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Nov 30, 2023
1 parent 008ba92 commit 5daad25
Show file tree
Hide file tree
Showing 14 changed files with 416 additions and 51 deletions.
5 changes: 3 additions & 2 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
"dependencies": {
"@hookform/resolvers": "^3.3.2",
"@midday/gocardless": "workspace:*",
"@midday/jobs": "workspace:*",
"@midday/kv": "workspace:*",
"@midday/location": "workspace:*",
"@midday/notification": "workspace:*",
"@midday/supabase": "workspace:*",
"@midday/ui": "workspace:*",
"@midday/jobs": "workspace:*",
"@trigger.dev/nextjs": "^2.2.7",
"@novu/headless": "^0.21.0",
"@trigger.dev/nextjs": "^2.2.7",
"@vercel/edge-config": "^0.4.1",
"@vercel/toolbar": "^0.1.5",
"@zip.js/zip.js": "^2.7.31",
"change-case": "^5.2.0",
"framer-motion": "^10.16.5",
"next": "14.0.4-canary.18",
Expand Down
25 changes: 25 additions & 0 deletions apps/dashboard/src/actions/create-folder-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use server";

import { getUser } from "@midday/supabase/cached-queries";
import { createClient } from "@midday/supabase/server";
import { createFolder } from "@midday/supabase/storage";
import { revalidateTag } from "next/cache";
import { action } from "./safe-action";
import { createFolderSchema } from "./schema";

export const createFolderAction = action(createFolderSchema, async (value) => {
const supabase = createClient();
const user = await getUser();

const { error } = await createFolder(supabase, {
bucket: "vault",
path: `${user.data.team_id}/${value.path}`,
name: value.name,
});

console.log(error);

await revalidateTag(`vault_${user.data.team_id}`);

return error;
});
29 changes: 29 additions & 0 deletions apps/dashboard/src/actions/delete-file-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use server";

import { getUser } from "@midday/supabase/cached-queries";
import { createClient } from "@midday/supabase/server";
import { deleteFolder, remove } from "@midday/supabase/storage";
import { revalidateTag } from "next/cache";
import { action } from "./safe-action";
import { deleteFileSchema } from "./schema";

export const deleteFileAction = action(deleteFileSchema, async (value) => {
const supabase = createClient();
const user = await getUser();

if (value.isFolder) {
await deleteFolder(supabase, {
bucket: "vault",
path: `${user.data.team_id}/${value.path}`,
});
}

await remove(supabase, {
bucket: "vault",
path: `${user.data.team_id}/${value.path}`,
});

await revalidateTag(`vault_${user.data.team_id}`);

return value;
});
15 changes: 15 additions & 0 deletions apps/dashboard/src/actions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,18 @@ export const exportTransactionsSchema = z.object({
from: z.coerce.date(),
to: z.coerce.date(),
});

export const deleteFileSchema = z.object({
path: z.string(),
isFolder: z.boolean().optional(),
});

export const createFolderSchema = z.object({
path: z.string(),
name: z.string(),
});

export const shareFileSchema = z.object({
filepath: z.string(),
expireIn: z.number(),
});
23 changes: 23 additions & 0 deletions apps/dashboard/src/actions/share-file-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use server";

import { getUser } from "@midday/supabase/cached-queries";
import { createClient } from "@midday/supabase/server";
import { share } from "@midday/supabase/storage";
import { action } from "./safe-action";
import { shareFileSchema } from "./schema";

export const shareFileAction = action(shareFileSchema, async (value) => {
const supabase = createClient();
const user = await getUser();

const response = await share(supabase, {
bucket: "vault",
path: `${user.data.team_id}/${value.filepath}`,
expireIn: value.expireIn,
options: {
download: true,
},
});

return response?.data?.signedUrl;
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const metadata: Metadata = {

export default function Vault({ params }) {
const disableActions = ["transactions", "inbox", "exports"].includes(
params.folders?.slice(-1)?.at(0)
params?.folders?.at(0)
);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { getUser } from "@midday/supabase/cached-queries";
import { createClient } from "@midday/supabase/server";
import { download } from "@midday/supabase/storage";

export const preferredRegion = "fra1";
export const runtime = "edge";

export async function GET(req, res) {
const supabase = createClient();
const user = await getUser();
const requestUrl = new URL(req.url);
const path = requestUrl.searchParams.get("path");
const filename = requestUrl.searchParams.get("filename");

const { data } = await supabase.storage.from("vault").download(path);
console.log(`${user.data.team_id}/${path}/${filename}`);

const { data } = await download(supabase, {
bucket: "vault",
path: `${user.data.team_id}/${path}/${filename}`,
});

const responseHeaders = new Headers(res.headers);

responseHeaders.set(
Expand Down
51 changes: 51 additions & 0 deletions apps/dashboard/src/app/api/download/zip/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createClient } from "@midday/supabase/server";
import { BlobReader, BlobWriter, ZipWriter } from "@zip.js/zip.js";

export const preferredRegion = "fra1";
export const runtime = "edge";

export async function GET(req, res) {
const promises = [];
const supabase = createClient();
const requestUrl = new URL(req.url);
const path = requestUrl.searchParams.get("path");
const filename = requestUrl.searchParams.get("filename");

files.forEach((file) => {
promises.push(
supabaseClient.storage.from(bucket).download(`${folder}/${file.name}`)
);
});

const response = await Promise.allSettled(promises);

const zipFileWriter = new BlobWriter("application/zip");
const zipWriter = new ZipWriter(zipFileWriter, { bufferedWrite: true });

const downloadedFiles = response.map((result, index) => {
if (result.status === "fulfilled") {
return {
name: files[index].name,
blob: result.value.data,
};
}
});

downloadedFiles.forEach((downloadedFile) => {
if (downloadedFile) {
zipWriter.add(downloadedFile.name, new BlobReader(downloadedFile.blob));
}
});

// const { data } = await supabase.storage.from("vault").download(path);
// const responseHeaders = new Headers(res.headers);

// responseHeaders.set(
// "Content-Disposition",
// `attachment; filename="${filename}"`
// );

// return new Response(data, {
// headers: responseHeaders,
// });
}
5 changes: 3 additions & 2 deletions apps/dashboard/src/components/attachments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useDropzone } from "react-dropzone";

const Item = ({ file, onDelete }) => {
const Item = ({ file, onDelete, id }) => {
const animations = {
initial: { opacity: 0 },
animate: { opacity: 1 },
Expand All @@ -38,7 +38,7 @@ const Item = ({ file, onDelete }) => {

<div className="flex flex-col space-y-0.5 w-80">
<a
href={`/api/download/document?path=${file.path}&filename=${file.name}`}
href={`/api/download/file?path=transactions/${id}&filename=${file.name}`}
download
className="truncate"
>
Expand Down Expand Up @@ -146,6 +146,7 @@ export function Attachments({ id, data }) {
{files.map((file, index) => (
<Item
key={file.name}
id={id}
file={file}
onDelete={() => handleOnDelete(file.id)}
/>
Expand Down
Loading

0 comments on commit 5daad25

Please sign in to comment.