Skip to content

Commit ec2b516

Browse files
admin fixes
1 parent c26ba65 commit ec2b516

File tree

4 files changed

+115
-36
lines changed

4 files changed

+115
-36
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"tailwind-merge": "^2.5.3",
5454
"tailwindcss-animate": "^1.0.7",
5555
"use-debounce": "^10.0.3",
56+
"uuid": "^10.0.0",
5657
"zod": "^3.23.3"
5758
},
5859
"devDependencies": {
@@ -65,6 +66,7 @@
6566
"@types/nodemailer": "^6.4.15",
6667
"@types/react": "^18.2.57",
6768
"@types/react-dom": "^18.2.19",
69+
"@types/uuid": "^10.0.0",
6870
"@typescript-eslint/eslint-plugin": "^7.1.1",
6971
"@typescript-eslint/parser": "^7.1.1",
7072
"eslint": "^8.57.0",

pnpm-lock.yaml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/admin/imgtopdf/route.ts

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
import { NextApiRequest, NextApiResponse } from "next";
2-
import { PDFDocument, rgb } from "pdf-lib";
2+
import { PDFDocument } from "pdf-lib";
33
import multer from "multer";
44
import fs from "fs";
55
import path from "path";
66
import { promisify } from "util";
77
import { NextResponse } from "next/server";
8-
import { writeFile } from "fs/promises";
8+
import { writeFile, unlink } from "fs/promises";
9+
import { v4 as uuidv4 } from "uuid";
10+
import { cookies } from "next/headers"; // For session tracking
911

1012
const upload = multer({ dest: "uploads/" });
11-
1213
const uploadMiddleware = promisify(upload.array("files"));
1314

15+
const COOKIE_NAME = 'session_id'; // Name of the session cookie
16+
17+
function getSessionId(req: Request): string {
18+
const sessionId = cookies().get(COOKIE_NAME)?.value;
19+
20+
if (!sessionId) {
21+
const newSessionId = uuidv4();
22+
cookies().set(COOKIE_NAME, newSessionId);
23+
return newSessionId;
24+
}
25+
26+
return sessionId;
27+
}
28+
1429
export async function POST(req: Request, res: NextApiResponse) {
1530
await uploadMiddleware(req as any, res as any);
1631

@@ -23,9 +38,9 @@ export async function POST(req: Request, res: NextApiResponse) {
2338

2439
try {
2540
const pdfDoc = await PDFDocument.create();
41+
const sessionId = getSessionId(req);
2642

2743
for (const file of files) {
28-
console.log(file);
2944
const fileBlob = new Blob([file]);
3045
const imgBytes = Buffer.from(await fileBlob.arrayBuffer());
3146
let img;
@@ -35,7 +50,7 @@ export async function POST(req: Request, res: NextApiResponse) {
3550
} else if (file.type === "image/jpeg" || file.type === "image/jpg") {
3651
img = await pdfDoc.embedJpg(imgBytes);
3752
} else {
38-
continue; // Skip unsupported file types
53+
continue;
3954
}
4055
const page = pdfDoc.addPage([img.width, img.height]);
4156
page.drawImage(img, {
@@ -47,27 +62,32 @@ export async function POST(req: Request, res: NextApiResponse) {
4762
}
4863
}
4964

50-
const pdfBytes = await pdfDoc.save();
51-
const pdfPath = path.join(process.cwd(), "public", "merged.pdf");
52-
await writeFile(pdfPath, pdfBytes);
65+
const mergedPdfBytes = await pdfDoc.save();
66+
const mergedPdfPath = path.join(process.cwd(), "public", `merged_${sessionId}.pdf`);
67+
await writeFile(mergedPdfPath, mergedPdfBytes);
68+
69+
const watermarkedPdfPath = path.join(process.cwd(), "public", `watermarked_${sessionId}.pdf`);
70+
await applyWatermark(mergedPdfBytes, watermarkedPdfPath);
5371

54-
return NextResponse.json(
55-
{ url: `/${path.basename(pdfPath)}` },
56-
{ status: 200 },
57-
);
72+
await unlink(mergedPdfPath); // Optionally delete the merged file
73+
74+
return NextResponse.json({ url: `/${path.basename(watermarkedPdfPath)}` }, { status: 200 });
5875
} catch (error) {
59-
return NextResponse.json(
60-
{ error: "Failed to process PDF" },
61-
{ status: 500 },
62-
);
76+
return NextResponse.json({ error: "Failed to process PDF" }, { status: 500 });
6377
}
6478
}
6579

6680
export async function DELETE(req: Request, res: NextApiResponse) {
67-
const filePath = path.resolve("./public/merged.pdf");
6881
try {
82+
const sessionId = cookies().get(COOKIE_NAME)?.value;
83+
if (!sessionId) {
84+
return NextResponse.json({ error: "Session not found" }, { status: 400 });
85+
}
86+
87+
const filePath = path.resolve(`./public/watermarked_${sessionId}.pdf`);
88+
6989
if (fs.existsSync(filePath)) {
70-
fs.unlinkSync(filePath);
90+
await unlink(filePath); // Delete the watermarked PDF file
7191
return NextResponse.json(
7292
{ message: "Deleted watermarked PDF file successfully" },
7393
{ status: 200 },
@@ -80,11 +100,34 @@ export async function DELETE(req: Request, res: NextApiResponse) {
80100
}
81101
} catch (error) {
82102
console.error("Error deleting PDF file:", error);
83-
return NextResponse.json(
84-
{
85-
error: "Failed to delete watermarked PDF file",
86-
},
87-
{ status: 500 },
88-
);
103+
return NextResponse.json({
104+
error: "Failed to delete watermarked PDF file",
105+
}, { status: 500 });
89106
}
90107
}
108+
109+
async function applyWatermark(pdfBytes: Uint8Array, outputPath: string) {
110+
const pdfDoc = await PDFDocument.load(pdfBytes);
111+
112+
const watermarkImage = await pdfDoc.embedJpg(fs.readFileSync(path.resolve("./public/watermark.jpg")));
113+
const pages = pdfDoc.getPages();
114+
const { width, height } = pages[0]!.getSize();
115+
116+
pages.forEach((page) => {
117+
const x = width - 80;
118+
const y = 50;
119+
const watermarkWidth = 50;
120+
const watermarkHeight = 50;
121+
122+
page.drawImage(watermarkImage, {
123+
x: x,
124+
y: y,
125+
width: watermarkWidth,
126+
height: watermarkHeight,
127+
opacity: 0.3,
128+
});
129+
});
130+
131+
const watermarkedPdfBytes = await pdfDoc.save();
132+
await writeFile(outputPath, watermarkedPdfBytes);
133+
}

src/app/api/admin/watermark/route.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
import { NextApiRequest, NextApiResponse } from "next";
2-
import { PDFDocument, rgb } from "pdf-lib";
2+
import { PDFDocument } from "pdf-lib";
33
import multer from "multer";
44
import fs from "fs";
55
import path from "path";
66
import { promisify } from "util";
77
import { NextResponse } from "next/server";
88
import { writeFile } from "fs/promises";
9+
import { v4 as uuidv4 } from "uuid";
10+
import { cookies } from "next/headers";
911

1012
const upload = multer({ dest: "uploads/" });
11-
1213
const uploadMiddleware = promisify(upload.single("file"));
1314

15+
const COOKIE_NAME = "session_id";
16+
17+
function getSessionId(req: Request): string {
18+
const sessionId = cookies().get(COOKIE_NAME)?.value;
19+
20+
if (!sessionId) {
21+
const newSessionId = uuidv4();
22+
cookies().set(COOKIE_NAME, newSessionId);
23+
return newSessionId;
24+
}
25+
26+
return sessionId;
27+
}
28+
1429
export async function POST(req: Request, res: NextApiResponse) {
1530
await uploadMiddleware(req as any, res as any);
1631

32+
const sessionId = getSessionId(req);
1733
const formData = await req.formData();
18-
1934
const file = formData.get("file");
35+
2036
if (!file) {
2137
return NextResponse.json({ error: "No files received." }, { status: 400 });
2238
}
2339

2440
try {
2541
const fileBlob = new Blob([file]);
2642
const buffer = Buffer.from(await fileBlob.arrayBuffer());
27-
2843
const pdfDoc = await PDFDocument.load(buffer);
2944

3045
const watermarkImage = await pdfDoc.embedJpg(
@@ -49,21 +64,23 @@ export async function POST(req: Request, res: NextApiResponse) {
4964
});
5065

5166
const pdfBytes = await pdfDoc.save();
52-
await writeFile(
53-
path.join(process.cwd(), "public/" + "watermarked.pdf"),
54-
pdfBytes,
55-
);
56-
return NextResponse.json({ url: "/assets/watermarked.pdf" }, {status: 200});
67+
const pdfPath = path.join(process.cwd(), `public/watermarked-${sessionId}.pdf`);
68+
69+
await writeFile(pdfPath, pdfBytes);
70+
71+
return NextResponse.json({ url: `/public/watermarked-${sessionId}.pdf` }, { status: 200 });
5772
} catch (error) {
5873
return NextResponse.json({ error: "Failed to process PDF" }, { status: 500 });
5974
}
6075
}
6176

6277
export async function DELETE(req: Request, res: NextApiResponse) {
63-
const filePath = path.resolve("./public/watermarked.pdf");
78+
const sessionId = getSessionId(req);
79+
const filePath = path.resolve(`./public/watermarked-${sessionId}.pdf`);
80+
6481
try {
6582
if (fs.existsSync(filePath)) {
66-
fs.unlinkSync(filePath);
83+
await fs.promises.unlink(filePath);
6784
return NextResponse.json(
6885
{ message: "Deleted watermarked PDF file successfully" },
6986
{ status: 200 },
@@ -78,6 +95,6 @@ export async function DELETE(req: Request, res: NextApiResponse) {
7895
console.error("Error deleting PDF file:", error);
7996
return NextResponse.json({
8097
error: "Failed to delete watermarked PDF file",
81-
}, {status: 500});
98+
}, { status: 500 });
8299
}
83100
}

0 commit comments

Comments
 (0)