-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: attachment api * feat: download attachment * feat: change status code * refactor: change api fetching * fix: create task with attachment
- Loading branch information
1 parent
71ba7ed
commit e1d7955
Showing
6 changed files
with
137 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { notFound } from 'next/navigation' | ||
import { NextRequest, NextResponse } from 'next/server' | ||
|
||
import { GetObjectCommand } from '@aws-sdk/client-s3' | ||
|
||
import checkUserPermissionOnTask from '@/lib/api/queries/checkUserPermissionOnTask' | ||
import prisma from '@/lib/prisma' | ||
import { s3Client } from '@/lib/s3Client' | ||
import { getServerUser } from '@/lib/session' | ||
import { forbidden, unauthorized } from '@/utils/apiResponse' | ||
|
||
export async function GET( | ||
_: NextRequest, | ||
{ params }: { params: { id: string } } | ||
) { | ||
const id = params.id | ||
|
||
const task = await prisma.task.findUnique({ | ||
where: { id }, | ||
select: { | ||
id: true, | ||
private: true, | ||
statement: true | ||
} | ||
}) | ||
|
||
if (!task) return notFound() | ||
|
||
if (task.private) { | ||
const user = await getServerUser() | ||
|
||
if (!user) { | ||
return unauthorized() | ||
} | ||
|
||
if (!(await checkUserPermissionOnTask(user, task.id))) { | ||
return forbidden() | ||
} | ||
} | ||
|
||
try { | ||
const response = await s3Client.send( | ||
new GetObjectCommand({ | ||
Bucket: process.env.BUCKET_NAME, | ||
Key: `statements/attachments/${id}.zip` | ||
}) | ||
) | ||
|
||
return new NextResponse(response.Body as ReadableStream, { | ||
headers: { | ||
'Content-Type': 'application/zip', | ||
'Content-Disposition': `inline; attachment; filename=${id}.zip` | ||
} | ||
}) | ||
} catch { | ||
return new NextResponse(null, { status: 204 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
'use client' | ||
|
||
import useSWR from 'swr' | ||
|
||
import zipFetcher from '@/lib/zipFetcher' | ||
import { DownloadIcon } from '@/svg/Illustrations/DownloadIcon' | ||
|
||
export const Attachment = ({ id }: { id: string }) => { | ||
const { data: attachment } = useSWR(`/api/tasks/${id}/attachment`, zipFetcher) | ||
|
||
if (!(attachment instanceof Blob)) { | ||
return null | ||
} | ||
|
||
const downloadAttachment = () => { | ||
const url = URL.createObjectURL(attachment as Blob) | ||
const a = document.createElement('a') | ||
a.href = url | ||
a.download = `${id}.zip` | ||
document.body.appendChild(a) | ||
a.click() | ||
document.body.removeChild(a) | ||
URL.revokeObjectURL(url) | ||
} | ||
|
||
return ( | ||
<div className="my-3 text-gray-500 dark:text-gray-100"> | ||
<p className="mb-1">Attachment</p> | ||
<button | ||
className="flex w-full items-center justify-between rounded-md border p-3" | ||
onClick={downloadAttachment} | ||
> | ||
<p className="w-2/3 truncate">{id}.zip</p> | ||
<DownloadIcon /> | ||
</button> | ||
<hr className="my-4 hidden md:block" /> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export default async function zipFetcher<JSON = unknown>( | ||
input: RequestInfo, | ||
init?: RequestInit | ||
): Promise<JSON | Blob> { | ||
try { | ||
const res = await fetch(input, init) | ||
|
||
if (res.headers.get('Content-Type')?.includes('application/zip')) { | ||
return res.blob() | ||
} | ||
return res.json() | ||
} catch (e) { | ||
return Promise.reject(e) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export const DownloadIcon = () => { | ||
return ( | ||
<svg | ||
width="14" | ||
height="14" | ||
viewBox="0 0 14 14" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
fill-rule="evenodd" | ||
clip-rule="evenodd" | ||
d="M2.01465 11.7202C2.01465 11.3612 2.30566 11.0702 2.66465 11.0702H10.4646C10.8236 11.0702 11.1146 11.3612 11.1146 11.7202C11.1146 12.0792 10.8236 12.3702 10.4646 12.3702H2.66465C2.30566 12.3702 2.01465 12.0792 2.01465 11.7202ZM4.15503 6.7106C4.40887 6.45675 4.82043 6.45675 5.07427 6.7106L5.91465 7.55098L5.91465 2.62021C5.91465 2.26123 6.20566 1.97021 6.56465 1.97021C6.92363 1.97021 7.21465 2.26123 7.21465 2.62021L7.21465 7.55098L8.05503 6.7106C8.30887 6.45675 8.72043 6.45675 8.97427 6.7106C9.22811 6.96444 9.22811 7.37599 8.97427 7.62983L7.02427 9.57983C6.90237 9.70173 6.73704 9.77022 6.56465 9.77022C6.39226 9.77022 6.22693 9.70173 6.10503 9.57983L4.15503 7.62983C3.90119 7.37599 3.90119 6.96444 4.15503 6.7106Z" | ||
fill="#3B82F6" | ||
/> | ||
</svg> | ||
) | ||
} |