diff --git a/app/[locale]/share/proof-of-payment/combined/[id]/not-found.tsx b/app/[locale]/share/proof-of-payment/combined/[id]/not-found.tsx
new file mode 100644
index 0000000..ce78ef3
--- /dev/null
+++ b/app/[locale]/share/proof-of-payment/combined/[id]/not-found.tsx
@@ -0,0 +1,7 @@
+export default function NotFound() {
+ return (
+
+
Proof of payment not found
+
+ );
+}
diff --git a/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx b/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx
new file mode 100644
index 0000000..820566c
--- /dev/null
+++ b/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx
@@ -0,0 +1,34 @@
+import { getDbClient } from '@/app/lib/dbClient';
+import { BillingLocation } from '@/app/lib/db-types';
+import { notFound } from 'next/navigation';
+
+export async function GET(request: Request, { params:{ id } }: { params: { id:string } }) {
+ const locationID = id;
+
+ const dbClient = await getDbClient();
+ const location = await dbClient.collection("lokacije")
+ .findOne({ _id: locationID }, {
+ projection: {
+ utilBillsProofOfPayment: 1,
+ }
+ });
+
+ if(!location?.utilBillsProofOfPayment) {
+ notFound();
+ }
+
+ // Convert fileContentsBase64 from Base64 string to binary
+ const fileContentsBuffer = Buffer.from(location.utilBillsProofOfPayment.fileContentsBase64, 'base64');
+
+ // Convert fileContentsBuffer to format that can be sent to the client
+ const fileContents = new Uint8Array(fileContentsBuffer);
+
+ return new Response(fileContents, {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/pdf',
+ 'Content-Disposition': `attachment; filename="${location.utilBillsProofOfPayment.fileName}"`,
+ 'Last-Modified': `${location.utilBillsProofOfPayment.fileLastModified}`
+ }
+ });
+}
diff --git a/app/[locale]/share/proof-of-payment/per-bill/[id]/not-found.tsx b/app/[locale]/share/proof-of-payment/per-bill/[id]/not-found.tsx
new file mode 100644
index 0000000..ce78ef3
--- /dev/null
+++ b/app/[locale]/share/proof-of-payment/per-bill/[id]/not-found.tsx
@@ -0,0 +1,7 @@
+export default function NotFound() {
+ return (
+
+
Proof of payment not found
+
+ );
+}
diff --git a/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx b/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx
new file mode 100644
index 0000000..df1c1b4
--- /dev/null
+++ b/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx
@@ -0,0 +1,48 @@
+import { getDbClient } from '@/app/lib/dbClient';
+import { BillingLocation } from '@/app/lib/db-types';
+import { notFound } from 'next/navigation';
+
+export async function GET(_request: Request, { params:{ id } }: { params: { id:string } }) {
+ // Parse locationID-billID format
+ const [locationID, billID] = id.split('-');
+
+ if (!locationID || !billID) {
+ notFound();
+ }
+
+ const dbClient = await getDbClient();
+ const location = await dbClient.collection("lokacije")
+ .findOne({ _id: locationID }, {
+ projection: {
+ // Don't load bill attachments, only proof of payment
+ "bills._id": 1,
+ "bills.proofOfPayment": 1,
+ }
+ });
+
+ if(!location) {
+ notFound();
+ }
+
+ // Find the specific bill
+ const bill = location.bills.find(b => b._id === billID);
+
+ if(!bill?.proofOfPayment) {
+ notFound();
+ }
+
+ // Convert fileContentsBase64 from Base64 string to binary
+ const fileContentsBuffer = Buffer.from(bill.proofOfPayment.fileContentsBase64, 'base64');
+
+ // Convert fileContentsBuffer to format that can be sent to the client
+ const fileContents = new Uint8Array(fileContentsBuffer);
+
+ return new Response(fileContents, {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/pdf',
+ 'Content-Disposition': `attachment; filename="${bill.proofOfPayment.fileName}"`,
+ 'Last-Modified': `${bill.proofOfPayment.fileLastModified}`
+ }
+ });
+}